diff options
Diffstat (limited to 'libcutils/strdup16to8.c')
-rw-r--r-- | libcutils/strdup16to8.c | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/libcutils/strdup16to8.c b/libcutils/strdup16to8.c new file mode 100644 index 000000000..fadaabed8 --- /dev/null +++ b/libcutils/strdup16to8.c | |||
@@ -0,0 +1,104 @@ | |||
1 | /* libs/cutils/strdup16to8.c | ||
2 | ** | ||
3 | ** Copyright 2006, The Android Open Source Project | ||
4 | ** | ||
5 | ** Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | ** you may not use this file except in compliance with the License. | ||
7 | ** You may obtain a copy of the License at | ||
8 | ** | ||
9 | ** http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | ** | ||
11 | ** Unless required by applicable law or agreed to in writing, software | ||
12 | ** distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | ** See the License for the specific language governing permissions and | ||
15 | ** limitations under the License. | ||
16 | */ | ||
17 | |||
18 | #include <cutils/jstring.h> | ||
19 | #include <assert.h> | ||
20 | #include <stdlib.h> | ||
21 | |||
22 | |||
23 | /** | ||
24 | * Given a UTF-16 string, compute the length of the corresponding UTF-8 | ||
25 | * string in bytes. | ||
26 | */ | ||
27 | extern size_t strnlen16to8(const char16_t* utf16Str, size_t len) | ||
28 | { | ||
29 | size_t utf8Len = 0; | ||
30 | |||
31 | while (len--) { | ||
32 | unsigned int uic = *utf16Str++; | ||
33 | |||
34 | if (uic > 0x07ff) | ||
35 | utf8Len += 3; | ||
36 | else if (uic > 0x7f || uic == 0) | ||
37 | utf8Len += 2; | ||
38 | else | ||
39 | utf8Len++; | ||
40 | } | ||
41 | return utf8Len; | ||
42 | } | ||
43 | |||
44 | |||
45 | /** | ||
46 | * Convert a Java-Style UTF-16 string + length to a JNI-Style UTF-8 string. | ||
47 | * | ||
48 | * This basically means: embedded \0's in the UTF-16 string are encoded | ||
49 | * as "0xc0 0x80" | ||
50 | * | ||
51 | * Make sure you allocate "utf8Str" with the result of strlen16to8() + 1, | ||
52 | * not just "len". | ||
53 | * | ||
54 | * Please note, a terminated \0 is always added, so your result will always | ||
55 | * be "strlen16to8() + 1" bytes long. | ||
56 | */ | ||
57 | extern char* strncpy16to8(char* utf8Str, const char16_t* utf16Str, size_t len) | ||
58 | { | ||
59 | char* utf8cur = utf8Str; | ||
60 | |||
61 | while (len--) { | ||
62 | unsigned int uic = *utf16Str++; | ||
63 | |||
64 | if (uic > 0x07ff) { | ||
65 | *utf8cur++ = (uic >> 12) | 0xe0; | ||
66 | *utf8cur++ = ((uic >> 6) & 0x3f) | 0x80; | ||
67 | *utf8cur++ = (uic & 0x3f) | 0x80; | ||
68 | } else if (uic > 0x7f || uic == 0) { | ||
69 | *utf8cur++ = (uic >> 6) | 0xc0; | ||
70 | *utf8cur++ = (uic & 0x3f) | 0x80; | ||
71 | } else { | ||
72 | *utf8cur++ = uic; | ||
73 | |||
74 | if (uic == 0) { | ||
75 | break; | ||
76 | } | ||
77 | } | ||
78 | } | ||
79 | |||
80 | *utf8cur = '\0'; | ||
81 | |||
82 | return utf8Str; | ||
83 | } | ||
84 | |||
85 | /** | ||
86 | * Convert a UTF-16 string to UTF-8. | ||
87 | * | ||
88 | * Make sure you allocate "dest" with the result of strblen16to8(), | ||
89 | * not just "strlen16()". | ||
90 | */ | ||
91 | char * strndup16to8 (const char16_t* s, size_t n) | ||
92 | { | ||
93 | char *ret; | ||
94 | |||
95 | if (s == NULL) { | ||
96 | return NULL; | ||
97 | } | ||
98 | |||
99 | ret = malloc(strnlen16to8(s, n) + 1); | ||
100 | |||
101 | strncpy16to8 (ret, s, n); | ||
102 | |||
103 | return ret; | ||
104 | } | ||