~ubuntu-branches/ubuntu/trusty/modem-manager-gui/trusty-backports

« back to all changes in this revision

Viewing changes to src/encoding.c

  • Committer: Package Import Robot
  • Author(s): Graham Inggs
  • Date: 2013-07-30 12:51:59 UTC
  • Revision ID: package-import@ubuntu.com-20130730125159-flzv882fhuzhmfmi
Tags: upstream-0.0.16
ImportĀ upstreamĀ versionĀ 0.0.16

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *      encoding.c
 
3
 *      
 
4
 *      Copyright 2012-2013 Alex <alex@linuxonly.ru>
 
5
 *      
 
6
 *      This program is free software: you can redistribute it and/or modify
 
7
 *      it under the terms of the GNU General Public License as published by
 
8
 *      the Free Software Foundation; either version 3 of the License, or
 
9
 *      (at your option) any later version.
 
10
 *      
 
11
 *      This program is distributed in the hope that it will be useful,
 
12
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *      GNU General Public License for more details.
 
15
 *      
 
16
 *      You should have received a copy of the GNU General Public License
 
17
 *      along with this program. If not, see <http://www.gnu.org/licenses/>.
 
18
 */
 
19
 
 
20
#include <glib.h>
 
21
#include <stdio.h>
 
22
#include <malloc.h>
 
23
#include <string.h>
 
24
 
 
25
static const guint gsm7_utf8_table [128] = {
 
26
        0x0040, 0xc2a3, 0x0024, 0xc2a5, 0xc3a8, 0xc3a9, 0xc3b9, 0xc3ac, 0xc3b2, 0xc387,
 
27
        0x000a, 0xc398, 0xc3b8, 0x000d, 0xc385, 0xc3a5, 0xce94, 0x005f, 0xcea6, 0xce93,
 
28
        0xce9b, 0xcea9, 0xcea0, 0xcea8, 0xcea3, 0xce98, 0xce9e, 0x00a0, 0xc386, 0xc3a6,
 
29
        0xc39f, 0xc389, 0x0020, 0x0021, 0x0022, 0x0023, 0xc2a4, 0x0025, 0x0026, 0x0027,
 
30
        0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031,
 
31
        0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b,
 
32
        0x003c, 0x003d, 0x003e, 0x003f, 0xc2a1, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045,
 
33
        0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
 
34
        0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059,
 
35
        0x005a, 0xc384, 0xc396, 0xc391, 0xc39c, 0xc2a7, 0xc2bf, 0x0061, 0x0062, 0x0063,
 
36
        0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d,
 
37
        0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
 
38
        0x0078, 0x0079, 0x007a, 0xc3a4, 0xc3b6, 0xc3b1, 0xc3bc, 0xc3a0
 
39
};
 
40
 
 
41
static const guint gsm7_utf8_ext_table [2][10] = {
 
42
        {0x00000c, 0x00005e, 0x00007b, 0x00007d, 0x00005c, 0x00005b, 0x00007e, 0x00005d, 0x00007c, 0xe282ac},
 
43
        {    0x0a,     0x14,     0x28,     0x29,     0x2f,     0x3c,     0x3d,     0x3e,     0x40,     0x65}
 
44
};
 
45
 
 
46
static const gchar hextable[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
 
47
 
 
48
 
 
49
static guint hex_to_dec(const guchar *input, gsize number);
 
50
 
 
51
 
 
52
static guint hex_to_dec(const guchar *input, gsize number)
 
53
{
 
54
        guint  k, b, value;
 
55
        gint hexptr;
 
56
        
 
57
        if ((input == NULL) || ((input != NULL) && (input[0] == '\0')) || (number == 0)) return 0;
 
58
        
 
59
        value = 0;
 
60
        k = 1;
 
61
        
 
62
        for (hexptr = (number-1); hexptr >= 0; hexptr--) {
 
63
                switch (input[hexptr]) {
 
64
                        case '0': b = 0; break;
 
65
                        case '1': b = 1; break;
 
66
                        case '2': b = 2; break;
 
67
                        case '3': b = 3; break;
 
68
                        case '4': b = 4; break;
 
69
                        case '5': b = 5; break;
 
70
                        case '6': b = 6; break;
 
71
                        case '7': b = 7; break;
 
72
                        case '8': b = 8; break;
 
73
                        case '9': b = 9; break;
 
74
                        case 'a':
 
75
                        case 'A': b = 10; break;
 
76
                        case 'b':
 
77
                        case 'B': b = 11; break;
 
78
                        case 'c':
 
79
                        case 'C': b = 12; break;
 
80
                        case 'd':
 
81
                        case 'D': b = 13; break;
 
82
                        case 'e':
 
83
                        case 'E': b = 14; break;
 
84
                        case 'f':
 
85
                        case 'F': b = 15; break;
 
86
                        default: b = 0; break;
 
87
                }
 
88
                value = value + b*k;
 
89
                k *= 16;
 
90
        }
 
91
        
 
92
        
 
93
        return value;
 
94
}
 
95
 
 
96
guchar *utf8_to_ucs2(const guchar *input, gsize ilength, gsize *olength)
 
97
{
 
98
        guchar *output, *routput;
 
99
        guint iptr, optr;
 
100
        gushort value;
 
101
                
 
102
        if ((input == NULL) || (ilength == 0) || (olength == NULL)) return NULL;
 
103
        
 
104
        if (input[0] == '\0') return NULL;
 
105
        
 
106
        output = g_malloc0(ilength*2+1);
 
107
        
 
108
        if (output == NULL) return NULL;
 
109
        
 
110
        iptr = 0; optr = 0;
 
111
        
 
112
        while (iptr < ilength) {
 
113
                if (input[iptr] < 0x80) {
 
114
                        value = input[iptr];
 
115
                        output[optr] = '0';
 
116
                        output[optr+1] = '0';
 
117
                        output[optr+2] = hextable[(guchar)(value & 0xff)/16];
 
118
                        output[optr+3] = hextable[(guchar)(value & 0xff)%16];
 
119
                        iptr += 1;
 
120
                        optr += 4;
 
121
                }
 
122
                
 
123
                if ((input[iptr] & 0xE0) == 0xE0) {
 
124
                        if (!((input[iptr+1] == 0) || (input[iptr+2] == 0))) {
 
125
                                value = ((input[iptr] & 0x0F) << 12) | ((input[iptr+1] & 0x3F) << 6) | (input[iptr+2] & 0x3F);
 
126
                                output[optr] = hextable[(guchar)((value >> 8) & 0xff)/16];
 
127
                                output[optr+1] = hextable[(guchar)((value >> 8) & 0xff)%16];
 
128
                                output[optr+2] = hextable[(guchar)(value & 0xff)/16];
 
129
                                output[optr+3] = hextable[(guchar)(value & 0xff)%16];
 
130
                                optr += 4;
 
131
                        }
 
132
                        
 
133
                        iptr += 3;
 
134
                }
 
135
                
 
136
                if ((input[0] & 0xC0) == 0xC0) {
 
137
                        if (input[1] != 0) {
 
138
                                value = ((input[iptr] & 0x1F) << 6) | (input[iptr+1] & 0x3F);
 
139
                                output[optr] = hextable[(guchar)((value >> 8) & 0xff)/16];
 
140
                                output[optr+1] = hextable[(guchar)((value >> 8) & 0xff)%16];
 
141
                                output[optr+2] = hextable[(guchar)(value & 0xff)/16];
 
142
                                output[optr+3] = hextable[(guchar)(value & 0xff)%16];
 
143
                                optr += 4;
 
144
                        }
 
145
                        
 
146
                        iptr += 2;
 
147
                }
 
148
        }
 
149
        
 
150
        output[optr] = '\0';
 
151
        
 
152
        routput = g_realloc(output, optr+1);
 
153
        
 
154
        if (routput != NULL) output = routput;
 
155
        
 
156
        *olength = optr;
 
157
        
 
158
        return output;
 
159
}
 
160
 
 
161
guchar *ucs2_to_utf8(const guchar *input, gsize ilength, gsize *olength)
 
162
{
 
163
        guchar *output, *routput;
 
164
        guint iptr, optr;
 
165
        guint value;
 
166
        
 
167
        if ((input == NULL) || (ilength == 0) || (olength == NULL)) return NULL;
 
168
        
 
169
        if ((input[0] == '\0') || (ilength%4 != 0)) return NULL;
 
170
        
 
171
        output = g_malloc0(ilength*2+1);
 
172
        
 
173
        iptr = 0; optr = 0;
 
174
        
 
175
        while (iptr < ilength) {
 
176
                value = hex_to_dec(input+iptr, 4);
 
177
                
 
178
                if (value < 0x80) {
 
179
                        if ((value <= 0x20) && (value != 0x0A) && (value != 0x0D)) {
 
180
                                output[optr] = 0x20;
 
181
                        } else {
 
182
                                output[optr] = value;
 
183
                        }
 
184
                        optr += 1;
 
185
                }
 
186
                
 
187
                if ((value >= 0x80) && (value < 0x800)) {
 
188
                        output[optr] = (value >> 6) | 0xC0;
 
189
                        output[optr+1] = (value & 0x3F) | 0x80;
 
190
                        optr += 2;
 
191
                }
 
192
                
 
193
                if ((value >= 0x800) && (value < 0xFFFF)) {
 
194
                        output[optr] = ((value >> 12)) | 0xE0;
 
195
                        output[optr+1] = ((value >> 6) & 0x3F) | 0x80;
 
196
                        output[optr+2] = ((value) & 0x3F) | 0x80;
 
197
                        optr += 3;
 
198
                }
 
199
                
 
200
                iptr += 4;
 
201
        }
 
202
        
 
203
        output[optr] = '\0';
 
204
        
 
205
        routput = g_realloc(output, optr+1);
 
206
        
 
207
        if (routput != NULL) output = routput;
 
208
        
 
209
        *olength = optr;
 
210
        
 
211
        return output;
 
212
 
213
 
 
214
guchar *utf8_to_gsm7(const guchar *input, gsize ilength, gsize *olength)
 
215
{
 
216
        guchar *output, *routput;
 
217
        guint iptr, optr;
 
218
        gushort x, value;
 
219
        
 
220
        if ((input == NULL) || (ilength == 0) || (olength == NULL)) return NULL;
 
221
        
 
222
        output = g_malloc0(ilength*2+1);
 
223
        
 
224
        if (output == NULL) return NULL;
 
225
        
 
226
        iptr = 0; optr = 0;
 
227
        
 
228
        while (iptr < ilength) {
 
229
                x = (iptr % 8) + 1;
 
230
                if (x < 8) {
 
231
                        if ((iptr + 1) == ilength) {
 
232
                                value = (input[iptr] >> (iptr % 8)) & 0xff;
 
233
                                output[optr] = hextable[(guchar)(value & 0xff)/16];
 
234
                                output[optr+1] = hextable[(guchar)(value & 0xff)%16];
 
235
                                optr += 2;
 
236
                        } else {
 
237
                                value = (((input[iptr] >> (x - 1)) | (input[iptr+1] << (8 - x))) & 0xff) & 0xff;
 
238
                                output[optr] = hextable[(guchar)(value & 0xff)/16];
 
239
                                output[optr+1] = hextable[(guchar)(value & 0xff)%16];
 
240
                                optr += 2;
 
241
                        }
 
242
                }
 
243
                iptr++;
 
244
        }
 
245
        
 
246
        output[optr] = '\0';
 
247
        
 
248
        routput = g_realloc(output, optr+1);
 
249
        
 
250
        if (routput != NULL) output = routput;
 
251
        
 
252
        *olength = optr;
 
253
        
 
254
        return output;
 
255
}
 
256
 
 
257
guchar *gsm7_to_utf8(const guchar *input, gsize ilength, gsize *olength)
 
258
{
 
259
        guchar *output, *routput;
 
260
        guint iptr, optr;
 
261
        guint value, current, mask, next, left;
 
262
        
 
263
        if ((input == NULL) || (ilength == 0) || (olength == NULL)) return NULL;
 
264
        
 
265
        if ((input[0] == '\0') || (ilength%2 != 0)) return NULL;
 
266
        
 
267
        output = g_malloc0(ilength*4+1);
 
268
        
 
269
        if (output == NULL) return NULL;
 
270
        
 
271
        left = 7;
 
272
        mask = 0x7F;
 
273
        next = 0;
 
274
        
 
275
        iptr = 0; optr = 0;
 
276
        
 
277
        while (iptr < ilength) {
 
278
                if (mask != 0) {
 
279
                        value = hex_to_dec(input+iptr, 2);
 
280
                        current = (((value & mask) << (7 - left)) | next);
 
281
                        next = (value & (~mask)) >> left;
 
282
                        output[optr] = current;
 
283
                        optr += 1;
 
284
                        mask >>= 1;
 
285
                        left -= 1;
 
286
                        iptr += 2;
 
287
                } else {
 
288
                        output[optr] = next;
 
289
                        optr += 1;
 
290
                        left = 7;
 
291
                        mask = 0x7F;
 
292
                        next = 0;
 
293
                }
 
294
        }
 
295
        
 
296
        output[optr] = '\0';
 
297
        
 
298
        routput = g_realloc(output, optr+1);
 
299
        
 
300
        if (routput != NULL) output = routput;
 
301
        
 
302
        *olength = optr;
 
303
        
 
304
        return output;
 
305
}
 
306
 
 
307
guchar *utf8_map_gsm7(const guchar *input, gsize ilength, gsize *olength)
 
308
{
 
309
        guchar *output, *routput;
 
310
        guint iptr, optr;
 
311
        guint value;
 
312
        guint i;
 
313
        gboolean detected, found;
 
314
        
 
315
        if ((input == NULL) || (ilength == 0) || (olength == NULL)) return NULL;
 
316
        
 
317
        if (input[0] == '\0') return NULL;
 
318
        
 
319
        output = g_malloc0(ilength*2+1);
 
320
        
 
321
        if (output == NULL) return NULL;
 
322
        
 
323
        iptr = 0; optr = 0;
 
324
        
 
325
        while (iptr < ilength) {
 
326
                detected = FALSE;
 
327
                if (input[iptr] <= 127) {
 
328
                        value = input[iptr];
 
329
                        detected = TRUE;
 
330
                        iptr += 1;
 
331
                } else if ((input[iptr] >= 194) && (input[iptr] <= 223)) {
 
332
                        value = (((input[iptr] << 8) & 0xff00) | input[iptr+1]) & 0xffff;
 
333
                        detected = TRUE;
 
334
                        iptr += 2;
 
335
                } else if ((input[iptr] >= 224) && (input[iptr] <= 239)) {
 
336
                        value = ((((input[iptr] << 16) & 0xff0000) | (input[iptr+1] << 8) & 0x00ff00) | input[iptr+2]) & 0xffffff;
 
337
                        detected = TRUE;
 
338
                        iptr += 3;
 
339
                }  else if ((input[iptr] >= 240) && (input[iptr] <= 244)) {
 
340
                        value = (((((input[iptr] << 24) & 0xff000000) | (input[iptr+1] << 16) & 0x00ff0000) | (input[iptr+2] << 8) & 0x0000ff00) | input[iptr+3]) & 0xffffffff;
 
341
                        detected = TRUE;
 
342
                        iptr += 4;
 
343
                } 
 
344
                
 
345
                if (detected) {
 
346
                        found = FALSE;
 
347
                        for (i=0; i<10; i++) {
 
348
                                if (gsm7_utf8_ext_table[0][i] == value) {
 
349
                                        output[optr] = 0x1b;
 
350
                                        output[optr+1] = (unsigned char)gsm7_utf8_ext_table[1][i];
 
351
                                        optr += 2;
 
352
                                        found = TRUE;
 
353
                                }
 
354
                        }
 
355
                        
 
356
                        if (!found) {
 
357
                                for (i=0; i<128; i++) {
 
358
                                        if (gsm7_utf8_table[i] == value) {
 
359
                                                output[optr] = (unsigned char)i;
 
360
                                                optr += 1;
 
361
                                                found = TRUE;
 
362
                                        }
 
363
                                }
 
364
                        }
 
365
                        
 
366
                        if (!found) {
 
367
                                output[optr] = 0x3f;
 
368
                                optr += 1;
 
369
                        }
 
370
                }
 
371
                
 
372
        }
 
373
        
 
374
        output[optr] = '\0';
 
375
        
 
376
        routput = g_realloc(output, optr+1);
 
377
        
 
378
        if (routput != NULL) output = routput;
 
379
        
 
380
        *olength = optr;
 
381
        
 
382
        return output;
 
383
}
 
384
 
 
385
guchar *bcd_to_utf8_ascii_part(const guchar *input, gsize ilength, gsize *olength)
 
386
{
 
387
        guchar *output, *routput;
 
388
        guint iptr, optr;
 
389
        guchar value;
 
390
        guchar buf[4];
 
391
        
 
392
        if ((input == NULL) || (ilength == 0) || (olength == NULL)) return NULL;
 
393
        
 
394
        if (input[0] == '\0') return NULL;
 
395
        
 
396
        //Test if number decoded correctly
 
397
        for (iptr=0; iptr<ilength; iptr++) {
 
398
                value = tolower(input[iptr]);
 
399
                if (((!isdigit(value)) && (value != 'a') && (value != 'b') && (value != 'c') && (value != '*') && (value != '#')) || (ilength <= 6)) {
 
400
                        output = g_strdup(input);
 
401
                        *olength = ilength;
 
402
                        return output;
 
403
                }
 
404
        }
 
405
        
 
406
        output = g_malloc0(ilength);
 
407
        
 
408
        if (output == NULL) return NULL;
 
409
        
 
410
        iptr = 0;
 
411
        optr = 0;
 
412
        
 
413
        //Decode characters in range 32 ... 127
 
414
        while (iptr < ilength) {
 
415
                memset(buf, 0, sizeof(buf)); 
 
416
                if (isdigit(input[iptr])) {
 
417
                        if ((input[iptr] == '1') && (ilength - iptr >= 3))  {
 
418
                                strncpy(buf, input+iptr, 3);
 
419
                                value = (unsigned char)atoi(buf);
 
420
                                if (value <= 127) {
 
421
                                        output[optr] = value;
 
422
                                        optr++;
 
423
                                }
 
424
                                iptr += 3;
 
425
                        } else if (ilength - iptr >= 2) {
 
426
                                strncpy(buf, input+iptr, 2);
 
427
                                value = (unsigned char)atoi(buf);
 
428
                                if (value >= 32) {
 
429
                                        output[optr] = value;
 
430
                                        optr++;
 
431
                                }
 
432
                                iptr += 2;
 
433
                        } else {
 
434
                                output[optr] = '?';
 
435
                                optr++;
 
436
                                iptr++;
 
437
                        }
 
438
                } else {
 
439
                        break;
 
440
                }
 
441
        }
 
442
        
 
443
        output[optr] = '\0';
 
444
        
 
445
        routput = g_realloc(output, optr+1);
 
446
        
 
447
        if (routput != NULL) output = routput;
 
448
        
 
449
        *olength = optr;
 
450
        
 
451
        return output;
 
452
}
 
453
 
 
454
gchar *encoding_unescape_xml_markup(const gchar *srcstr, gsize srclen)
 
455
{
 
456
        guint iptr, optr, newlen, charleft;
 
457
        gchar *unescaped;
 
458
        
 
459
        /*XML escape characters:
 
460
         "&lt;", "&gt;", "&amp;", "&quot;", "&apos;", "&#xD;", "&#x9;", "&#xA;"
 
461
         '<',    '>',    '&',     '\"',     '\'',     '\r',    '\t',    '\n'
 
462
        */
 
463
        
 
464
        if ((srcstr == NULL) || (srclen == 0)) return NULL;
 
465
        
 
466
        iptr = 0;
 
467
        newlen = 0;
 
468
        
 
469
        while (iptr < srclen) {
 
470
                if (srcstr[iptr] == '&') {
 
471
                        charleft = srclen - iptr - 1;
 
472
                        if (charleft >= 3) {
 
473
                                if ((charleft >= 5) && (srcstr[iptr+1] == 'q') && (srcstr[iptr+2] == 'u') && (srcstr[iptr+3] == 'o') && (srcstr[iptr+4] == 't') && (srcstr[iptr+5] == ';')) {
 
474
                                        newlen += 1;
 
475
                                        iptr += 6;
 
476
                                } else if ((charleft >= 5) && (srcstr[iptr+1] == 'a') && (srcstr[iptr+2] == 'p') && (srcstr[iptr+3] == 'o') && (srcstr[iptr+4] == 's') && (srcstr[iptr+5] == ';')) {
 
477
                                        newlen += 1;
 
478
                                        iptr += 6;
 
479
                                } else if ((charleft >= 4) && (srcstr[iptr+1] == 'a') && (srcstr[iptr+2] == 'm') && (srcstr[iptr+3] == 'p') && (srcstr[iptr+4] == ';')) {
 
480
                                        newlen += 1;
 
481
                                        iptr += 5;
 
482
                                } else if ((charleft >= 4) && (srcstr[iptr+1] == '#') && (srcstr[iptr+2] == 'x') && (srcstr[iptr+3] == 'D') && (srcstr[iptr+4] == ';')) {
 
483
                                        newlen += 1;
 
484
                                        iptr += 5;
 
485
                                } else if ((charleft >= 4) && (srcstr[iptr+1] == '#') && (srcstr[iptr+2] == 'x') && (srcstr[iptr+3] == '9') && (srcstr[iptr+4] == ';')) {
 
486
                                        newlen += 1;
 
487
                                        iptr += 5;
 
488
                                } else if ((charleft >= 4) && (srcstr[iptr+1] == '#') && (srcstr[iptr+2] == 'x') && (srcstr[iptr+3] == 'A') && (srcstr[iptr+4] == ';')) {
 
489
                                        newlen += 1;
 
490
                                        iptr += 5;
 
491
                                } else if ((charleft >= 3) && (srcstr[iptr+1] == 'l') && (srcstr[iptr+2] == 't') && (srcstr[iptr+3] == ';')) {
 
492
                                        newlen += 1;
 
493
                                        iptr += 4;
 
494
                                } else if ((charleft >= 3) && (srcstr[iptr+1] == 'g') && (srcstr[iptr+2] == 't') && (srcstr[iptr+3] == ';')) {
 
495
                                        newlen += 1;
 
496
                                        iptr += 4;
 
497
                                } else {
 
498
                                        newlen += 1;
 
499
                                        iptr += 1;
 
500
                                }
 
501
                        } else {
 
502
                                newlen += 1;
 
503
                                iptr += 1;
 
504
                        }
 
505
                } else {
 
506
                        newlen += 1;
 
507
                        iptr += 1;
 
508
                }
 
509
        }
 
510
        
 
511
        unescaped = g_malloc0(newlen+1);
 
512
        
 
513
        iptr = 0;
 
514
        optr = 0;
 
515
        newlen = 0;
 
516
        
 
517
        while (iptr < srclen) {
 
518
                if (srcstr[iptr] == '&') {
 
519
                        charleft = srclen - iptr - 1;
 
520
                        if (charleft >= 3) {
 
521
                                if ((charleft >= 5) && (srcstr[iptr+1] == 'q') && (srcstr[iptr+2] == 'u') && (srcstr[iptr+3] == 'o') && (srcstr[iptr+4] == 't') && (srcstr[iptr+5] == ';')) {
 
522
                                        unescaped[optr] = '\"';
 
523
                                        optr += 1;
 
524
                                        iptr += 6;
 
525
                                } else if ((charleft >= 5) && (srcstr[iptr+1] == 'a') && (srcstr[iptr+2] == 'p') && (srcstr[iptr+3] == 'o') && (srcstr[iptr+4] == 's') && (srcstr[iptr+5] == ';')) {
 
526
                                        unescaped[optr] = '\'';
 
527
                                        optr += 1;
 
528
                                        iptr += 6;
 
529
                                } else if ((charleft >= 4) && (srcstr[iptr+1] == 'a') && (srcstr[iptr+2] == 'm') && (srcstr[iptr+3] == 'p') && (srcstr[iptr+4] == ';')) {
 
530
                                        unescaped[optr] = '&';
 
531
                                        optr += 1;
 
532
                                        iptr += 5;
 
533
                                } else if ((charleft >= 4) && (srcstr[iptr+1] == '#') && (srcstr[iptr+2] == 'x') && (srcstr[iptr+3] == 'D') && (srcstr[iptr+4] == ';')) {
 
534
                                        unescaped[optr] = '\r';
 
535
                                        optr += 1;
 
536
                                        iptr += 5;
 
537
                                } else if ((charleft >= 4) && (srcstr[iptr+1] == '#') && (srcstr[iptr+2] == 'x') && (srcstr[iptr+3] == '9') && (srcstr[iptr+4] == ';')) {
 
538
                                        unescaped[optr] = '\t';
 
539
                                        optr += 1;
 
540
                                        iptr += 5;
 
541
                                } else if ((charleft >= 4) && (srcstr[iptr+1] == '#') && (srcstr[iptr+2] == 'x') && (srcstr[iptr+3] == 'A') && (srcstr[iptr+4] == ';')) {
 
542
                                        unescaped[optr] = '\n';
 
543
                                        optr += 1;
 
544
                                        iptr += 5;
 
545
                                } else if ((charleft >= 3) && (srcstr[iptr+1] == 'l') && (srcstr[iptr+2] == 't') && (srcstr[iptr+3] == ';')) {
 
546
                                        unescaped[optr] = '<';
 
547
                                        optr += 1;
 
548
                                        iptr += 4;
 
549
                                } else if ((charleft >= 3) && (srcstr[iptr+1] == 'g') && (srcstr[iptr+2] == 't') && (srcstr[iptr+3] == ';')) {
 
550
                                        unescaped[optr] = '>';
 
551
                                        optr += 1;
 
552
                                        iptr += 4;
 
553
                                } else {
 
554
                                        unescaped[optr] = srcstr[iptr];
 
555
                                        optr += 1;
 
556
                                        iptr += 1;
 
557
                                }
 
558
                                
 
559
                        } else {
 
560
                                unescaped[optr] = srcstr[iptr];
 
561
                                optr += 1;
 
562
                                iptr += 1;
 
563
                        }
 
564
                } else {
 
565
                        unescaped[optr] = srcstr[iptr];
 
566
                        optr += 1;
 
567
                        iptr += 1;
 
568
                }
 
569
        }
 
570
        
 
571
        return unescaped;
 
572
}
 
573
 
 
574
gchar *encoding_clear_special_symbols(gchar *srcstr, gsize srclen)
 
575
{
 
576
        guint iptr;
 
577
        
 
578
        if ((srcstr == NULL) || (srclen == 0)) return NULL;
 
579
        
 
580
        iptr = 0;
 
581
        
 
582
        while (iptr < srclen) {
 
583
                if (srcstr[iptr] > 0) {
 
584
                        if ((srcstr[iptr] == '\n') || (srcstr[iptr] == '\r') || (srcstr[iptr] == '\t')) {
 
585
                                srcstr[iptr] = ' ';
 
586
                        }
 
587
                        iptr += 1;
 
588
                } else {
 
589
                        switch (srcstr[iptr] & 0xF0) {
 
590
                                case 0xE0:
 
591
                                        iptr += 3;
 
592
                                        break;
 
593
                                case 0xF0:
 
594
                                        iptr += 4;
 
595
                                        break;
 
596
                                default:
 
597
                                        iptr += 2;
 
598
                                        break;
 
599
                        }
 
600
                }
 
601
        }
 
602
        
 
603
        return srcstr;
 
604
}