FreeCalypso > hg > sms-coding-utils
annotate libcoding/utf8_decode2.c @ 28:6e925aa54727
libcoding: more sensible naming of GSM time
encoding and decoding modules
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 13 Jun 2024 02:32:11 +0000 |
parents | e56bb9f09ff1 |
children |
rev | line source |
---|---|
0
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
1 /* |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
2 * This library module implements the function for converting UTF-8 input |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
3 * to UCS-2 in outgoing SMS composition. |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
4 */ |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
5 |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
6 #include <sys/types.h> |
23
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
7 #include <ctype.h> |
0
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
8 |
23
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
9 static int |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
10 handle_escape(ipp, outp) |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
11 u_char **ipp; |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
12 unsigned *outp; |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
13 { |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
14 unsigned c, n, acc; |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
15 |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
16 c = *(*ipp)++; |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
17 switch (c) { |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
18 case '"': |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
19 case '\\': |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
20 *outp = c; |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
21 return(0); |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
22 case 'n': |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
23 *outp = '\n'; |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
24 return(0); |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
25 case 'r': |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
26 *outp = '\r'; |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
27 return(0); |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
28 case 'u': |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
29 acc = 0; |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
30 for (n = 0; n < 4; n++) { |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
31 c = *(*ipp)++; |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
32 if (!isxdigit(c)) |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
33 return(-3); |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
34 acc <<= 4; |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
35 acc |= decode_hex_digit(c); |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
36 } |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
37 *outp = acc; |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
38 return(0); |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
39 default: |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
40 return(-3); |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
41 } |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
42 } |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
43 |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
44 utf8_to_ucs2(inbuf, outbuf, outmax, outlenp, allow_escape) |
0
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
45 u_char *inbuf; |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
46 u_short *outbuf; |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
47 unsigned outmax, *outlenp; |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
48 { |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
49 u_char *ip = inbuf; |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
50 u_short *op = outbuf; |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
51 unsigned outcnt = 0, c, n, uni; |
23
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
52 int rc; |
0
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
53 |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
54 while (c = *ip++) { |
23
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
55 if (c == '\\' && allow_escape) { |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
56 rc = handle_escape(&ip, &uni); |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
57 if (rc < 0) |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
58 return(rc); |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
59 goto gotuni; |
e56bb9f09ff1
sms-encode-text: port over -e option from fcup-smsend
Mychaela Falconia <falcon@freecalypso.org>
parents:
0
diff
changeset
|
60 } |
0
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
61 if (c < 0x80) { |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
62 uni = c; |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
63 goto gotuni; |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
64 } |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
65 if (c < 0xC0 || c > 0xEF) |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
66 return(-1); |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
67 uni = c & 0x1F; |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
68 if (c >= 0xE0) |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
69 n = 2; |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
70 else |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
71 n = 1; |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
72 for (; n; n--) { |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
73 c = *ip++; |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
74 if (c < 0x80 || c > 0xBF) |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
75 return(-1); |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
76 uni <<= 6; |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
77 uni |= c & 0x3F; |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
78 } |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
79 gotuni: if (outcnt >= outmax) |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
80 return(-2); |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
81 *op++ = uni; |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
82 outcnt++; |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
83 } |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
84 *outlenp = outcnt; |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
85 return(0); |
2d0082216916
libcoding: beginning with a subset of uptools version
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
86 } |