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