FreeCalypso > hg > freecalypso-tools
comparison uptools/libcoding/gsm7_decode.c @ 802:1c599681fd60
pcm-sms-decode & sms-pdu-decode: revamp bad char decoding
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 25 Mar 2021 02:58:30 +0000 |
parents | 978571e23318 |
children | 5637794913a8 |
comparison
equal
deleted
inserted
replaced
801:da724c67159d | 802:1c599681fd60 |
---|---|
2 * This library module implements the decoding of GSM7-encoded data | 2 * This library module implements the decoding of GSM7-encoded data |
3 * into ASCII, ISO 8859-1 or UTF-8. | 3 * into ASCII, ISO 8859-1 or UTF-8. |
4 */ | 4 */ |
5 | 5 |
6 #include <sys/types.h> | 6 #include <sys/types.h> |
7 #include <stdio.h> | |
7 | 8 |
8 extern u_short gsm7_decode_table[128]; | 9 extern u_short gsm7_decode_table[128]; |
9 extern u_short gsm7ext_decode_table[128]; | 10 extern u_short gsm7ext_decode_table[128]; |
10 | 11 |
11 gsm7_to_ascii_or_ext(inbuf, inlen, outbuf, outlenp, ascii_ext, newline_ok, errp) | 12 gsm7_to_ascii_or_ext(inbuf, inlen, outbuf, outlenp, ascii_ext, newline_ok, errp) |
12 u_char *inbuf, *outbuf; | 13 u_char *inbuf, *outbuf; |
13 unsigned inlen, *outlenp, *errp; | 14 unsigned inlen, *outlenp, *errp; |
14 { | 15 { |
15 u_char *inp, *endp, *outp; | 16 u_char *inp, *endp, *outp; |
16 unsigned errcnt = 0; | |
17 unsigned gsm, uni; | 17 unsigned gsm, uni; |
18 int is_ext; | |
18 | 19 |
19 inp = inbuf; | 20 inp = inbuf; |
20 endp = inbuf + inlen; | 21 endp = inbuf + inlen; |
21 outp = outbuf; | 22 outp = outbuf; |
22 while (inp < endp) { | 23 while (inp < endp) { |
23 gsm = *inp++; | 24 gsm = *inp++; |
24 if (gsm == 0x1B && inp < endp) | 25 if (gsm == 0x1B && inp < endp && *inp != 0x1B && *inp != '\n' |
25 uni = gsm7ext_decode_table[*inp++]; | 26 && *inp != '\r') { |
26 else | 27 gsm = *inp++; |
28 uni = gsm7ext_decode_table[gsm]; | |
29 if (uni == '\\') { | |
30 *outp++ = '\\'; | |
31 *outp++ = '\\'; | |
32 continue; | |
33 } | |
34 is_ext = 1; | |
35 } else { | |
36 switch (gsm) { | |
37 case 0x1B: | |
38 *outp++ = '\\'; | |
39 *outp++ = 'e'; | |
40 continue; | |
41 case '\n': | |
42 if (newline_ok) | |
43 *outp++ = '\n'; | |
44 else { | |
45 *outp++ = '\\'; | |
46 *outp++ = 'n'; | |
47 } | |
48 continue; | |
49 case '\r': | |
50 *outp++ = '\\'; | |
51 *outp++ = 'r'; | |
52 continue; | |
53 } | |
27 uni = gsm7_decode_table[gsm]; | 54 uni = gsm7_decode_table[gsm]; |
28 if (uni == '\r') { | 55 is_ext = 0; |
29 *outp++ = '\\'; | 56 } |
30 *outp++ = 'r'; | 57 if (!uni || !is_decoded_char_ok(uni, ascii_ext)) { |
31 errcnt++; | 58 if (is_ext) { |
32 } else if (uni == '\n') { | |
33 if (newline_ok) | |
34 *outp++ = '\n'; | |
35 else { | |
36 *outp++ = '\\'; | 59 *outp++ = '\\'; |
37 *outp++ = 'n'; | 60 *outp++ = 'e'; |
38 errcnt++; | |
39 } | 61 } |
40 } else if (!uni || !is_decoded_char_ok(uni, ascii_ext)) { | 62 sprintf(outp, "\\%02X", gsm); |
41 *outp++ = '?'; | 63 outp += 3; |
42 errcnt++; | |
43 } else if (ascii_ext == 2) | 64 } else if (ascii_ext == 2) |
44 outp += emit_utf8_char(uni, outp); | 65 outp += emit_utf8_char(uni, outp); |
45 else | 66 else |
46 *outp++ = uni; | 67 *outp++ = uni; |
47 } | 68 } |
48 *outp = '\0'; | 69 *outp = '\0'; |
49 if (outlenp) | 70 if (outlenp) |
50 *outlenp = outp - outbuf; | 71 *outlenp = outp - outbuf; |
51 if (errp) | 72 if (errp) |
52 *errp = errcnt; | 73 *errp = 0; |
53 } | 74 } |