ReactOS 0.4.17-dev-923-g4c9a150
utf8.c
Go to the documentation of this file.
1/*
2 * Copyright 2000 Alexandre Julliard
3 * Copyright 2019 Zhiyi Zhang for CodeWeavers
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 */
19
20#include "vkd3d_memory.h"
21#include "vkd3d_utf8.h"
22
23#include <inttypes.h>
24
26{
27 /* 0x00-0x7f: 1 byte */
28 if (c < 0x80)
29 return 1;
30 /* 0x80-0x7ff: 2 bytes */
31 if (c < 0x800)
32 return 2;
33 /* 0x800-0xffff: 3 bytes */
34 if (c < 0x10000)
35 return 3;
36 /* 0x10000-0x10ffff: 4 bytes */
37 return 4;
38}
39
40static void vkd3d_utf8_append(char **dst, uint32_t c)
41{
42 char *d = *dst;
43
44 /* 0x00-0x7f: 1 byte */
45 if (c < 0x80)
46 {
47 d[0] = c;
48 *dst += 1;
49 return;
50 }
51
52 /* 0x80-0x7ff: 2 bytes */
53 if (c < 0x800)
54 {
55 d[1] = 0x80 | (c & 0x3f);
56 c >>= 6;
57 d[0] = 0xc0 | c;
58 *dst += 2;
59 return;
60 }
61
62 /* 0x800-0xffff: 3 bytes */
63 if (c < 0x10000) /* 0x800-0xffff: 3 bytes */
64 {
65 d[2] = 0x80 | (c & 0x3f);
66 c >>= 6;
67 d[1] = 0x80 | (c & 0x3f);
68 c >>= 6;
69 d[0] = 0xe0 | c;
70 *dst += 3;
71 return;
72 }
73
74 /* 0x10000-0x10ffff: 4 bytes */
75 d[3] = 0x80 | (c & 0x3f);
76 c >>= 6;
77 d[2] = 0x80 | (c & 0x3f);
78 c >>= 6;
79 d[1] = 0x80 | (c & 0x3f);
80 c >>= 6;
81 d[0] = 0xf0 | c;
82 *dst += 4;
83}
84
86{
87 const uint16_t *s = *src;
88
89 if (s[0] < 0xd800 || s[0] > 0xdfff) /* Not a surrogate pair. */
90 {
91 *src += 1;
92 return s[0];
93 }
94
95 if (s[0] > 0xdbff /* Invalid high surrogate. */
96 || s[1] < 0xdc00 || s[1] > 0xdfff) /* Invalid low surrogate. */
97 {
98 *src += 1;
99 return 0;
100 }
101
102 *src += 2;
103 return 0x10000 + ((s[0] & 0x3ff) << 10) + (s[1] & 0x3ff);
104}
105
106static char *vkd3d_strdup_w16_utf8(const uint16_t *wstr)
107{
108 const uint16_t *src = wstr;
109 size_t dst_size = 0;
110 char *dst, *utf8;
111 uint32_t c;
112
113 while (*src)
114 {
115 if (!(c = vkd3d_utf16_read(&src)))
116 continue;
117 dst_size += vkd3d_utf8_len(c);
118 }
119 ++dst_size;
120
121 if (!(dst = vkd3d_malloc(dst_size)))
122 return NULL;
123
124 utf8 = dst;
125 src = wstr;
126 while (*src)
127 {
128 if (!(c = vkd3d_utf16_read(&src)))
129 continue;
131 }
132 *utf8 = 0;
133
134 return dst;
135}
136
137static char *vkd3d_strdup_w32_utf8(const uint32_t *wstr)
138{
139 const uint32_t *src = wstr;
140 size_t dst_size = 0;
141 char *dst, *utf8;
142
143 while (*src)
144 dst_size += vkd3d_utf8_len(*src++);
145 ++dst_size;
146
147 if (!(dst = vkd3d_malloc(dst_size)))
148 return NULL;
149
150 utf8 = dst;
151 src = wstr;
152 while (*src)
154 *utf8 = 0;
155
156 return dst;
157}
158
159char *vkd3d_strdup_w_utf8(const WCHAR *wstr, size_t wchar_size)
160{
161 if (wchar_size == 2)
162 return vkd3d_strdup_w16_utf8((const uint16_t *)wstr);
163 return vkd3d_strdup_w32_utf8((const uint32_t *)wstr);
164}
#define NULL
Definition: types.h:112
UINT32 uint32_t
Definition: types.h:75
unsigned short uint16_t
Definition: stdint.h:35
GLdouble s
Definition: gl.h:2039
GLenum src
Definition: glext.h:6340
const GLubyte * c
Definition: glext.h:8905
GLenum GLenum dst
Definition: glext.h:6340
#define d
Definition: ke_i.h:81
#define c
Definition: ke_i.h:80
static uint32_t vkd3d_utf16_read(const uint16_t **src)
Definition: utf8.c:85
static size_t vkd3d_utf8_len(uint32_t c)
Definition: utf8.c:25
static char * vkd3d_strdup_w16_utf8(const uint16_t *wstr)
Definition: utf8.c:106
static void vkd3d_utf8_append(char **dst, uint32_t c)
Definition: utf8.c:40
char * vkd3d_strdup_w_utf8(const WCHAR *wstr, size_t wchar_size)
Definition: utf8.c:159
static char * vkd3d_strdup_w32_utf8(const uint32_t *wstr)
Definition: utf8.c:137
short WCHAR
Definition: pedump.c:58
static void * vkd3d_malloc(size_t size)
Definition: vkd3d_memory.h:28