1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <string>
6 #include <string_view>
7
8 #include "base/android/jni_android.h"
9 #include "base/android/jni_string.h"
10 #include "net/base/net_string_util.h"
11
12 // Must come after all headers that specialize FromJniType() / ToJniType().
13 #include "net/net_jni_headers/NetStringUtil_jni.h"
14
15 using base::android::ScopedJavaLocalRef;
16
17 namespace net {
18
19 namespace {
20
21 // Attempts to convert |text| encoded in |charset| to a jstring (Java unicode
22 // string). Returns the result jstring, or NULL on failure.
ConvertToJstring(std::string_view text,const char * charset)23 ScopedJavaLocalRef<jstring> ConvertToJstring(std::string_view text,
24 const char* charset) {
25 JNIEnv* env = base::android::AttachCurrentThread();
26 ScopedJavaLocalRef<jobject> java_byte_buffer(
27 env,
28 env->NewDirectByteBuffer(const_cast<char*>(text.data()), text.length()));
29 base::android::CheckException(env);
30 base::android::ScopedJavaLocalRef<jstring> java_charset =
31 base::android::ConvertUTF8ToJavaString(env, std::string_view(charset));
32 ScopedJavaLocalRef<jstring> java_result =
33 android::Java_NetStringUtil_convertToUnicode(env, java_byte_buffer,
34 java_charset);
35 return java_result;
36 }
37
38 // Attempts to convert |text| encoded in |charset| to a jstring (Java unicode
39 // string) and then normalizes the string. Returns the result jstring, or NULL
40 // on failure.
ConvertToNormalizedJstring(std::string_view text,const char * charset)41 ScopedJavaLocalRef<jstring> ConvertToNormalizedJstring(std::string_view text,
42 const char* charset) {
43 JNIEnv* env = base::android::AttachCurrentThread();
44 ScopedJavaLocalRef<jobject> java_byte_buffer(
45 env,
46 env->NewDirectByteBuffer(const_cast<char*>(text.data()), text.length()));
47 base::android::CheckException(env);
48 base::android::ScopedJavaLocalRef<jstring> java_charset =
49 base::android::ConvertUTF8ToJavaString(env, std::string_view(charset));
50 ScopedJavaLocalRef<jstring> java_result =
51 android::Java_NetStringUtil_convertToUnicodeAndNormalize(
52 env, java_byte_buffer, java_charset);
53 return java_result;
54 }
55
56 // Converts |text| encoded in |charset| to a jstring (Java unicode string).
57 // Any characters that can not be converted are replaced with U+FFFD.
ConvertToJstringWithSubstitutions(std::string_view text,const char * charset)58 ScopedJavaLocalRef<jstring> ConvertToJstringWithSubstitutions(
59 std::string_view text,
60 const char* charset) {
61 JNIEnv* env = base::android::AttachCurrentThread();
62 ScopedJavaLocalRef<jobject> java_byte_buffer(
63 env,
64 env->NewDirectByteBuffer(const_cast<char*>(text.data()), text.length()));
65 base::android::CheckException(env);
66 base::android::ScopedJavaLocalRef<jstring> java_charset =
67 base::android::ConvertUTF8ToJavaString(env, std::string_view(charset));
68 ScopedJavaLocalRef<jstring> java_result =
69 android::Java_NetStringUtil_convertToUnicodeWithSubstitutions(
70 env, java_byte_buffer, java_charset);
71 return java_result;
72 }
73
74 } // namespace
75
76 // This constant cannot be defined as const char[] because it is initialized
77 // by base::kCodepageLatin1 (which is const char[]) in net_string_util_icu.cc.
78 const char* const kCharsetLatin1 = "ISO-8859-1";
79
ConvertToUtf8(std::string_view text,const char * charset,std::string * output)80 bool ConvertToUtf8(std::string_view text,
81 const char* charset,
82 std::string* output) {
83 output->clear();
84 ScopedJavaLocalRef<jstring> java_result = ConvertToJstring(text, charset);
85 if (java_result.is_null())
86 return false;
87 *output = base::android::ConvertJavaStringToUTF8(java_result);
88 return true;
89 }
90
ConvertToUtf8AndNormalize(std::string_view text,const char * charset,std::string * output)91 bool ConvertToUtf8AndNormalize(std::string_view text,
92 const char* charset,
93 std::string* output) {
94 output->clear();
95 ScopedJavaLocalRef<jstring> java_result = ConvertToNormalizedJstring(
96 text, charset);
97 if (java_result.is_null())
98 return false;
99 *output = base::android::ConvertJavaStringToUTF8(java_result);
100 return true;
101 }
102
ConvertToUTF16(std::string_view text,const char * charset,std::u16string * output)103 bool ConvertToUTF16(std::string_view text,
104 const char* charset,
105 std::u16string* output) {
106 output->clear();
107 ScopedJavaLocalRef<jstring> java_result = ConvertToJstring(text, charset);
108 if (java_result.is_null())
109 return false;
110 *output = base::android::ConvertJavaStringToUTF16(java_result);
111 return true;
112 }
113
ConvertToUTF16WithSubstitutions(std::string_view text,const char * charset,std::u16string * output)114 bool ConvertToUTF16WithSubstitutions(std::string_view text,
115 const char* charset,
116 std::u16string* output) {
117 output->clear();
118 ScopedJavaLocalRef<jstring> java_result =
119 ConvertToJstringWithSubstitutions(text, charset);
120 if (java_result.is_null())
121 return false;
122 *output = base::android::ConvertJavaStringToUTF16(java_result);
123 return true;
124 }
125
ToUpperUsingLocale(std::u16string_view str,std::u16string * output)126 bool ToUpperUsingLocale(std::u16string_view str, std::u16string* output) {
127 output->clear();
128 JNIEnv* env = base::android::AttachCurrentThread();
129 ScopedJavaLocalRef<jstring> java_new_str(
130 env,
131 env->NewString(reinterpret_cast<const jchar*>(str.data()), str.length()));
132 if (java_new_str.is_null())
133 return false;
134 ScopedJavaLocalRef<jstring> java_result =
135 android::Java_NetStringUtil_toUpperCase(env, java_new_str);
136 if (java_result.is_null())
137 return false;
138 *output = base::android::ConvertJavaStringToUTF16(java_result);
139 return true;
140 }
141
142 } // namespace net
143