/src/xpdf-4.06/xpdf/UTF8.cc
Line | Count | Source |
1 | | //======================================================================== |
2 | | // |
3 | | // UTF8.cc |
4 | | // |
5 | | // Copyright 2001-2017 Glyph & Cog, LLC |
6 | | // |
7 | | //======================================================================== |
8 | | |
9 | | #include <aconf.h> |
10 | | #include "UTF8.h" |
11 | | |
12 | 69.5k | int mapUTF8(Unicode u, char *buf, int bufSize) { |
13 | 69.5k | if (u <= 0x0000007f) { |
14 | 66.2k | if (bufSize < 1) { |
15 | 0 | return 0; |
16 | 0 | } |
17 | 66.2k | buf[0] = (char)u; |
18 | 66.2k | return 1; |
19 | 66.2k | } else if (u <= 0x000007ff) { |
20 | 1.32k | if (bufSize < 2) { |
21 | 0 | return 0; |
22 | 0 | } |
23 | 1.32k | buf[0] = (char)(0xc0 + (u >> 6)); |
24 | 1.32k | buf[1] = (char)(0x80 + (u & 0x3f)); |
25 | 1.32k | return 2; |
26 | 1.89k | } else if (u <= 0x0000ffff) { |
27 | 1.68k | if (bufSize < 3) { |
28 | 0 | return 0; |
29 | 0 | } |
30 | 1.68k | buf[0] = (char)(0xe0 + (u >> 12)); |
31 | 1.68k | buf[1] = (char)(0x80 + ((u >> 6) & 0x3f)); |
32 | 1.68k | buf[2] = (char)(0x80 + (u & 0x3f)); |
33 | 1.68k | return 3; |
34 | 1.68k | } else if (u <= 0x0010ffff) { |
35 | 65 | if (bufSize < 4) { |
36 | 0 | return 0; |
37 | 0 | } |
38 | 65 | buf[0] = (char)(0xf0 + (u >> 18)); |
39 | 65 | buf[1] = (char)(0x80 + ((u >> 12) & 0x3f)); |
40 | 65 | buf[2] = (char)(0x80 + ((u >> 6) & 0x3f)); |
41 | 65 | buf[3] = (char)(0x80 + (u & 0x3f)); |
42 | 65 | return 4; |
43 | 152 | } else { |
44 | 152 | return 0; |
45 | 152 | } |
46 | 69.5k | } |
47 | | |
48 | 0 | int mapUCS2(Unicode u, char *buf, int bufSize) { |
49 | 0 | if (u <= 0xffff) { |
50 | 0 | if (bufSize < 2) { |
51 | 0 | return 0; |
52 | 0 | } |
53 | 0 | buf[0] = (char)((u >> 8) & 0xff); |
54 | 0 | buf[1] = (char)(u & 0xff); |
55 | 0 | return 2; |
56 | 0 | } else { |
57 | 0 | return 0; |
58 | 0 | } |
59 | 0 | } |
60 | | |
61 | 5.32M | GBool getUTF8(GString *s, int *i, Unicode *u) { |
62 | 5.32M | Guchar c0, c1, c2, c3, c4, c5; |
63 | | |
64 | 5.32M | if (*i >= s->getLength()) { |
65 | 1.30k | return gFalse; |
66 | 1.30k | } |
67 | 5.32M | c0 = (Guchar)s->getChar((*i)++); |
68 | 5.32M | if (c0 < 0x80) { |
69 | 4.35M | *u = (Unicode)c0; |
70 | 4.35M | } else if (c0 < 0xe0) { |
71 | 536k | if (*i < s->getLength() && |
72 | 536k | ((c1 = (Guchar)s->getChar(*i)) & 0xc0) == 0x80) { |
73 | 145k | *i += 1; |
74 | 145k | *u = (Unicode)(((c0 & 0x1f) << 6) | |
75 | 145k | (c1 & 0x3f)); |
76 | 391k | } else { |
77 | 391k | *u = (Unicode)c0; |
78 | 391k | } |
79 | 536k | } else if (c0 < 0xf0) { |
80 | 151k | if (*i < s->getLength() - 1 && |
81 | 150k | ((c1 = (Guchar)s->getChar(*i)) & 0xc0) == 0x80 && |
82 | 19.2k | ((c2 = (Guchar)s->getChar(*i + 1)) & 0xc0) == 0x80) { |
83 | 5.54k | *i += 2; |
84 | 5.54k | *u = (Unicode)(((c0 & 0x0f) << 12) | |
85 | 5.54k | ((c1 & 0x3f) << 6) | |
86 | 5.54k | (c2 & 0x3f)); |
87 | 145k | } else { |
88 | 145k | *u = (Unicode)c0; |
89 | 145k | } |
90 | 286k | } else if (c0 < 0xf8) { |
91 | 42.6k | if (*i < s->getLength() - 2 && |
92 | 42.3k | ((c1 = (Guchar)s->getChar(*i)) & 0xc0) == 0x80 && |
93 | 16.7k | ((c2 = (Guchar)s->getChar(*i + 1)) & 0xc0) == 0x80 && |
94 | 5.19k | ((c3 = (Guchar)s->getChar(*i + 2)) & 0xc0) == 0x80) { |
95 | 4.39k | *i += 3; |
96 | 4.39k | *u = (Unicode)(((c0 & 0x07) << 18) | |
97 | 4.39k | ((c1 & 0x3f) << 12) | |
98 | 4.39k | ((c2 & 0x3f) << 6) | |
99 | 4.39k | (c3 & 0x3f)); |
100 | 38.2k | } else { |
101 | 38.2k | *u = (Unicode)c0; |
102 | 38.2k | } |
103 | 244k | } else if (c0 < 0xfc) { |
104 | 8.10k | if (*i < s->getLength() - 3 && |
105 | 7.68k | ((c1 = (Guchar)s->getChar(*i)) & 0xc0) == 0x80 && |
106 | 2.17k | ((c2 = (Guchar)s->getChar(*i + 1)) & 0xc0) == 0x80 && |
107 | 1.47k | ((c3 = (Guchar)s->getChar(*i + 2)) & 0xc0) == 0x80 && |
108 | 558 | ((c4 = (Guchar)s->getChar(*i + 3)) & 0xc0) == 0x80) { |
109 | 441 | *i += 4; |
110 | 441 | *u = (Unicode)(((c0 & 0x03) << 24) | |
111 | 441 | ((c1 & 0x3f) << 18) | |
112 | 441 | ((c2 & 0x3f) << 12) | |
113 | 441 | ((c3 & 0x3f) << 6) | |
114 | 441 | (c4 & 0x3f)); |
115 | 7.66k | } else { |
116 | 7.66k | *u = (Unicode)c0; |
117 | 7.66k | } |
118 | 235k | } else if (c0 < 0xfe) { |
119 | 44.3k | if (*i < s->getLength() - 4 && |
120 | 42.7k | ((c1 = (Guchar)s->getChar(*i)) & 0xc0) == 0x80 && |
121 | 2.52k | ((c2 = (Guchar)s->getChar(*i + 1)) & 0xc0) == 0x80 && |
122 | 1.71k | ((c3 = (Guchar)s->getChar(*i + 2)) & 0xc0) == 0x80 && |
123 | 1.54k | ((c4 = (Guchar)s->getChar(*i + 3)) & 0xc0) == 0x80 && |
124 | 1.41k | ((c5 = (Guchar)s->getChar(*i + 4)) & 0xc0) == 0x80) { |
125 | 1.19k | *i += 5; |
126 | 1.19k | *u = (Unicode)(((c0 & 0x01) << 30) | |
127 | 1.19k | ((c1 & 0x3f) << 24) | |
128 | 1.19k | ((c2 & 0x3f) << 18) | |
129 | 1.19k | ((c3 & 0x3f) << 12) | |
130 | 1.19k | ((c4 & 0x3f) << 6) | |
131 | 1.19k | (c5 & 0x3f)); |
132 | 43.1k | } else { |
133 | 43.1k | *u = (Unicode)c0; |
134 | 43.1k | } |
135 | 191k | } else { |
136 | 191k | *u = (Unicode)c0; |
137 | 191k | } |
138 | 5.32M | return gTrue; |
139 | 5.32M | } |
140 | | |
141 | 2.63M | GBool getUTF16BE(GString *s, int *i, Unicode *u) { |
142 | 2.63M | int w0, w1; |
143 | | |
144 | 2.63M | if (*i >= s->getLength() - 1) { |
145 | 31.5k | return gFalse; |
146 | 31.5k | } |
147 | 2.60M | w0 = ((s->getChar(*i) & 0xff) << 8) | (s->getChar(*i + 1) & 0xff); |
148 | 2.60M | *i += 2; |
149 | 2.60M | if (w0 < 0xd800 || w0 >= 0xe000) { |
150 | 2.54M | *u = (Unicode)w0; |
151 | 2.54M | } else { |
152 | 58.3k | if (*i < s->getLength() - 1) { |
153 | 58.0k | w1 = ((s->getChar(*i) & 0xff) << 8) | (s->getChar(*i + 1) & 0xff); |
154 | 58.0k | *i += 2; |
155 | 58.0k | *u = 0x10000 + ((w0 - 0xd800) << 10) + (w1 - 0xdc00); |
156 | 58.0k | } else { |
157 | 262 | *u = (Unicode)w0; |
158 | 262 | } |
159 | 58.3k | } |
160 | 2.60M | return gTrue; |
161 | 2.63M | } |
162 | | |
163 | 7.03M | GBool getUTF16LE(GString *s, int *i, Unicode *u) { |
164 | 7.03M | int w0, w1; |
165 | | |
166 | 7.03M | if (*i >= s->getLength() - 1) { |
167 | 3.24k | return gFalse; |
168 | 3.24k | } |
169 | 7.03M | w0 = (s->getChar(*i) & 0xff) | ((s->getChar(*i + 1) & 0xff) << 8); |
170 | 7.03M | *i += 2; |
171 | 7.03M | if (w0 < 0xd800 || w0 >= 0xe000) { |
172 | 7.02M | *u = (Unicode)w0; |
173 | 7.02M | } else { |
174 | 11.5k | if (*i < s->getLength() - 1) { |
175 | 11.1k | w1 = (s->getChar(*i) & 0xff) | ((s->getChar(*i + 1) & 0xff) << 8); |
176 | 11.1k | *i += 2; |
177 | 11.1k | *u = 0x10000 + ((w0 - 0xd800) << 10) + (w1 - 0xdc00); |
178 | 11.1k | } else { |
179 | 484 | *u = (Unicode)w0; |
180 | 484 | } |
181 | 11.5k | } |
182 | 7.03M | return gTrue; |
183 | 7.03M | } |