Line data Source code
1 : /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
2 : * Copyright (C) 2010 Frediano Ziglio
3 : *
4 : * This library is free software; you can redistribute it and/or
5 : * modify it under the terms of the GNU Library General Public
6 : * License as published by the Free Software Foundation; either
7 : * version 2 of the License, or (at your option) any later version.
8 : *
9 : * This library is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 : * Library General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU Library General Public
15 : * License along with this library; if not, write to the
16 : * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 : * Boston, MA 02111-1307, USA.
18 : */
19 : #define TDS_DONT_DEFINE_DEFAULT_FUNCTIONS
20 : #include "common.h"
21 :
22 : #include <ctype.h>
23 : #include <assert.h>
24 :
25 : int utf8_max_len = 0;
26 :
27 : int
28 35288 : get_unichar(const char **psrc)
29 : {
30 35288 : const char *src = *psrc;
31 : int n;
32 :
33 35288 : if (!*src) return -1;
34 :
35 66672 : if (src[0] == '&' && src[1] == '#') {
36 : char *end;
37 32520 : int radix = 10;
38 :
39 32520 : if (toupper(src[2]) == 'X') {
40 18096 : radix = 16;
41 18096 : ++src;
42 : }
43 32520 : n = (int) strtol(src+2, &end, radix);
44 32520 : assert(*end == ';' && n > 0 && n < 0x10000);
45 32520 : src = end + 1;
46 : } else {
47 1632 : n = (unsigned char) *src++;
48 : }
49 34152 : *psrc = src;
50 34152 : return n;
51 : }
52 :
53 : char *
54 1136 : to_utf8(const char *src, char *dest)
55 : {
56 1136 : unsigned char *p = (unsigned char *) dest;
57 1136 : int len = 0, n;
58 :
59 36424 : while ((n=get_unichar(&src)) > 0) {
60 34152 : if (n >= 0x2000) {
61 31464 : *p++ = 0xe0 | ((n >> 12) & 0xf);
62 31464 : *p++ = 0x80 | ((n >> 6) & 0x3f);
63 31464 : *p++ = 0x80 | (n & 0x3f);
64 2688 : } else if (n >= 0x80) {
65 1056 : *p++ = 0xc0 | ((n >> 6) & 0x1f);
66 1056 : *p++ = 0x80 | (n & 0x3f);
67 : } else {
68 1632 : *p++ = (unsigned char) n;
69 : }
70 34152 : ++len;
71 : }
72 1136 : if (len > utf8_max_len)
73 392 : utf8_max_len = len;
74 1136 : *p = 0;
75 1136 : return dest;
76 : }
77 :
|