]> granicus.if.org Git - postgresql/blob - src/backend/utils/mb/mbutils.c
Move some system includes into c.h, and remove duplicates.
[postgresql] / src / backend / utils / mb / mbutils.c
1 /*
2  * This file contains public functions for conversion between
3  * client encoding and server internal encoding.
4  * (currently mule internal code (mic) is used)
5  * Tatsuo Ishii
6  * $Id: mbutils.c,v 1.8 1999/07/17 20:18:10 momjian Exp $ */
7
8
9 #include "postgres.h"
10 #include "miscadmin.h"
11 #include "mb/pg_wchar.h"
12
13 static int      client_encoding = -1;
14 static void (*client_to_mic) ();/* something to MIC */
15 static void (*client_from_mic) ();              /* MIC to something */
16 static void (*server_to_mic) ();/* something to MIC */
17 static void (*server_from_mic) ();              /* MIC to something */
18
19 /*
20  * find encoding table entry by encoding
21  */
22 static pg_encoding_conv_tbl *
23 get_enc_ent(int encoding)
24 {
25         pg_encoding_conv_tbl *p = pg_conv_tbl;
26
27         for (; p->encoding >= 0; p++)
28         {
29                 if (p->encoding == encoding)
30                         return (p);
31         }
32         return (0);
33 }
34
35 /*
36  * set the client encoding. if client/server encoding is
37  * not supported, returns -1
38  */
39 int
40 pg_set_client_encoding(int encoding)
41 {
42         int                     current_server_encoding = GetDatabaseEncoding();
43
44         client_encoding = encoding;
45
46         if (client_encoding == current_server_encoding)
47         {                                                       /* server == client? */
48                 client_to_mic = client_from_mic = 0;
49                 server_to_mic = server_from_mic = 0;
50         }
51         else if (current_server_encoding == MULE_INTERNAL)
52         {                                                       /* server == MULE_INETRNAL? */
53                 client_to_mic = get_enc_ent(encoding)->to_mic;
54                 client_from_mic = get_enc_ent(encoding)->from_mic;
55                 server_to_mic = server_from_mic = 0;
56                 if (client_to_mic == 0 || client_from_mic == 0)
57                         return (-1);
58         }
59         else if (encoding == MULE_INTERNAL)
60         {                                                       /* client == MULE_INETRNAL? */
61                 client_to_mic = client_from_mic = 0;
62                 server_to_mic = get_enc_ent(current_server_encoding)->to_mic;
63                 server_from_mic = get_enc_ent(current_server_encoding)->from_mic;
64                 if (server_to_mic == 0 || server_from_mic == 0)
65                         return (-1);
66         }
67         else
68         {
69                 client_to_mic = get_enc_ent(encoding)->to_mic;
70                 client_from_mic = get_enc_ent(encoding)->from_mic;
71                 server_to_mic = get_enc_ent(current_server_encoding)->to_mic;
72                 server_from_mic = get_enc_ent(current_server_encoding)->from_mic;
73                 if (client_to_mic == 0 || client_from_mic == 0)
74                         return (-1);
75                 if (server_to_mic == 0 || server_from_mic == 0)
76                         return (-1);
77         }
78         return (0);
79 }
80
81 /*
82  * returns the current client encoding
83  */
84 int
85 pg_get_client_encoding()
86 {
87         if (client_encoding == -1)
88         {
89                 /* this is the first time */
90                 client_encoding = GetDatabaseEncoding();
91         }
92         return (client_encoding);
93 }
94
95 /*
96  * convert client encoding to server encoding. if server_encoding ==
97  * client_encoding or no conversion function exists,
98  * returns s. So be careful.
99  */
100 unsigned char *
101 pg_client_to_server(unsigned char *s, int len)
102 {
103         static unsigned char b1[MAX_PARSE_BUFFER * 4];          /* is this enough? */
104         static unsigned char b2[MAX_PARSE_BUFFER * 4];          /* is this enough? */
105         unsigned char *p = s;
106
107         if (client_encoding == GetDatabaseEncoding())
108                 return (p);
109         if (client_to_mic)
110         {
111                 (*client_to_mic) (s, b1, len);
112                 len = strlen(b1);
113                 p = b1;
114         }
115         if (server_from_mic)
116         {
117                 (*server_from_mic) (p, b2, len);
118                 p = b2;
119         }
120         return (p);
121 }
122
123 /*
124  * convert server encoding to client encoding. if server_encoding ==
125  * client_encoding or no conversion function exists,
126  * returns s. So be careful.
127  */
128 unsigned char *
129 pg_server_to_client(unsigned char *s, int len)
130 {
131         static unsigned char b1[MAX_PARSE_BUFFER * 4];          /* is this enough? */
132         static unsigned char b2[MAX_PARSE_BUFFER * 4];          /* is this enough? */
133         unsigned char *p = s;
134
135         if (client_encoding == GetDatabaseEncoding())
136                 return (p);
137         if (server_to_mic)
138         {
139                 (*server_to_mic) (s, b1, len);
140                 len = strlen(b1);
141                 p = b1;
142         }
143         if (client_from_mic)
144         {
145                 (*client_from_mic) (p, b2, len);
146                 p = b2;
147         }
148         return (p);
149 }
150
151 /* convert a multi-byte string to a wchar */
152 void
153 pg_mb2wchar(const unsigned char *from, pg_wchar * to)
154 {
155         (*pg_wchar_table[GetDatabaseEncoding()].mb2wchar_with_len) (from, to, strlen(from));
156 }
157
158 /* convert a multi-byte string to a wchar with a limited length */
159 void
160 pg_mb2wchar_with_len(const unsigned char *from, pg_wchar * to, int len)
161 {
162         (*pg_wchar_table[GetDatabaseEncoding()].mb2wchar_with_len) (from, to, len);
163 }
164
165 /* returns the byte length of a multi-byte word */
166 int
167 pg_mblen(const unsigned char *mbstr)
168 {
169         return ((*pg_wchar_table[GetDatabaseEncoding()].mblen) (mbstr));
170 }
171
172 /* returns the length (counted as a wchar) of a multi-byte string */
173 int
174 pg_mbstrlen(const unsigned char *mbstr)
175 {
176         int                     len = 0;
177
178         while (*mbstr)
179         {
180                 mbstr += pg_mblen(mbstr);
181                 len++;
182         }
183         return (len);
184 }
185
186 /* returns the length (counted as a wchar) of a multi-byte string
187    (not necessarily  NULL terminated) */
188 int
189 pg_mbstrlen_with_len(const unsigned char *mbstr, int limit)
190 {
191         int                     len = 0;
192         int                     l;
193
194         while (*mbstr && limit > 0)
195         {
196                 l = pg_mblen(mbstr);
197                 limit -= l;
198                 mbstr += l;
199                 len++;
200         }
201         return (len);
202 }
203
204 /*
205  * returns the length of a multi-byte string
206  * (not necessarily  NULL terminated)
207  * that is not longer than limit.
208  * this function does not break multi-byte word boundary.
209  */
210 int
211 pg_mbcliplen(const unsigned char *mbstr, int len, int limit)
212 {
213         int                     clen = 0;
214         int                     l;
215
216         while (*mbstr && len > 0)
217         {
218                 l = pg_mblen(mbstr);
219                 if ((clen + l) > limit)
220                         break;
221                 clen += l;
222                 if (clen == limit)
223                         break;
224                 len -= l;
225                 mbstr += l;
226         }
227         return (clen);
228 }
229
230 /*
231  * fuctions for utils/init
232  */
233 static int      DatabaseEncoding = MULTIBYTE;
234 void
235 SetDatabaseEncoding(int encoding)
236 {
237         DatabaseEncoding = encoding;
238 }
239
240 int
241 GetDatabaseEncoding()
242 {
243         return (DatabaseEncoding);
244 }
245
246 /* for builtin-function */
247 const char *
248 getdatabaseencoding()
249 {
250         return (pg_encoding_to_char(DatabaseEncoding));
251 }
252
253 /* set and get template1 database encoding */
254 static int      templateEncoding;
255 void
256 SetTemplateEncoding(int encoding)
257 {
258         templateEncoding = encoding;
259 }
260
261 int
262 GetTemplateEncoding()
263 {
264         return (templateEncoding);
265 }