Remove what looks like gcc-isms.
[jra/samba/.git] / source3 / modules / CP850.c
1 /* 
2  * Conversion table for CP850 charset also known as IBM850.
3  *
4  * Copyright (C) Alexander Bokovoy              2003
5  * Conversion tables are generated using GNU libc 2.2.5's 
6  * localedata/charmaps/IBM850 table and iconvdata/gen-8bit-gap.sh script
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *  
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *  
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22
23 #include "includes.h"
24
25 struct gap
26 {
27   uint16 start;
28   uint16 end;
29   int32 idx;
30 };
31
32 static const uint16 to_ucs2[256] = {
33   [0x01] = 0x0001,
34   [0x02] = 0x0002,
35   [0x03] = 0x0003,
36   [0x04] = 0x0004,
37   [0x05] = 0x0005,
38   [0x06] = 0x0006,
39   [0x07] = 0x0007,
40   [0x08] = 0x0008,
41   [0x09] = 0x0009,
42   [0x0a] = 0x000A,
43   [0x0b] = 0x000B,
44   [0x0c] = 0x000C,
45   [0x0d] = 0x000D,
46   [0x0e] = 0x000E,
47   [0x0f] = 0x000F,
48   [0x10] = 0x0010,
49   [0x11] = 0x0011,
50   [0x12] = 0x0012,
51   [0x13] = 0x0013,
52   [0x14] = 0x0014,
53   [0x15] = 0x0015,
54   [0x16] = 0x0016,
55   [0x17] = 0x0017,
56   [0x18] = 0x0018,
57   [0x19] = 0x0019,
58   [0x1a] = 0x001A,
59   [0x1b] = 0x001B,
60   [0x1c] = 0x001C,
61   [0x1d] = 0x001D,
62   [0x1e] = 0x001E,
63   [0x1f] = 0x001F,
64   [0x20] = 0x0020,
65   [0x21] = 0x0021,
66   [0x22] = 0x0022,
67   [0x23] = 0x0023,
68   [0x24] = 0x0024,
69   [0x25] = 0x0025,
70   [0x26] = 0x0026,
71   [0x27] = 0x0027,
72   [0x28] = 0x0028,
73   [0x29] = 0x0029,
74   [0x2a] = 0x002A,
75   [0x2b] = 0x002B,
76   [0x2c] = 0x002C,
77   [0x2d] = 0x002D,
78   [0x2e] = 0x002E,
79   [0x2f] = 0x002F,
80   [0x30] = 0x0030,
81   [0x31] = 0x0031,
82   [0x32] = 0x0032,
83   [0x33] = 0x0033,
84   [0x34] = 0x0034,
85   [0x35] = 0x0035,
86   [0x36] = 0x0036,
87   [0x37] = 0x0037,
88   [0x38] = 0x0038,
89   [0x39] = 0x0039,
90   [0x3a] = 0x003A,
91   [0x3b] = 0x003B,
92   [0x3c] = 0x003C,
93   [0x3d] = 0x003D,
94   [0x3e] = 0x003E,
95   [0x3f] = 0x003F,
96   [0x40] = 0x0040,
97   [0x41] = 0x0041,
98   [0x42] = 0x0042,
99   [0x43] = 0x0043,
100   [0x44] = 0x0044,
101   [0x45] = 0x0045,
102   [0x46] = 0x0046,
103   [0x47] = 0x0047,
104   [0x48] = 0x0048,
105   [0x49] = 0x0049,
106   [0x4a] = 0x004A,
107   [0x4b] = 0x004B,
108   [0x4c] = 0x004C,
109   [0x4d] = 0x004D,
110   [0x4e] = 0x004E,
111   [0x4f] = 0x004F,
112   [0x50] = 0x0050,
113   [0x51] = 0x0051,
114   [0x52] = 0x0052,
115   [0x53] = 0x0053,
116   [0x54] = 0x0054,
117   [0x55] = 0x0055,
118   [0x56] = 0x0056,
119   [0x57] = 0x0057,
120   [0x58] = 0x0058,
121   [0x59] = 0x0059,
122   [0x5a] = 0x005A,
123   [0x5b] = 0x005B,
124   [0x5c] = 0x005C,
125   [0x5d] = 0x005D,
126   [0x5e] = 0x005E,
127   [0x5f] = 0x005F,
128   [0x60] = 0x0060,
129   [0x61] = 0x0061,
130   [0x62] = 0x0062,
131   [0x63] = 0x0063,
132   [0x64] = 0x0064,
133   [0x65] = 0x0065,
134   [0x66] = 0x0066,
135   [0x67] = 0x0067,
136   [0x68] = 0x0068,
137   [0x69] = 0x0069,
138   [0x6a] = 0x006A,
139   [0x6b] = 0x006B,
140   [0x6c] = 0x006C,
141   [0x6d] = 0x006D,
142   [0x6e] = 0x006E,
143   [0x6f] = 0x006F,
144   [0x70] = 0x0070,
145   [0x71] = 0x0071,
146   [0x72] = 0x0072,
147   [0x73] = 0x0073,
148   [0x74] = 0x0074,
149   [0x75] = 0x0075,
150   [0x76] = 0x0076,
151   [0x77] = 0x0077,
152   [0x78] = 0x0078,
153   [0x79] = 0x0079,
154   [0x7a] = 0x007A,
155   [0x7b] = 0x007B,
156   [0x7c] = 0x007C,
157   [0x7d] = 0x007D,
158   [0x7e] = 0x007E,
159   [0x7f] = 0x007F,
160   [0x80] = 0x00C7,
161   [0x81] = 0x00FC,
162   [0x82] = 0x00E9,
163   [0x83] = 0x00E2,
164   [0x84] = 0x00E4,
165   [0x85] = 0x00E0,
166   [0x86] = 0x00E5,
167   [0x87] = 0x00E7,
168   [0x88] = 0x00EA,
169   [0x89] = 0x00EB,
170   [0x8a] = 0x00E8,
171   [0x8b] = 0x00EF,
172   [0x8c] = 0x00EE,
173   [0x8d] = 0x00EC,
174   [0x8e] = 0x00C4,
175   [0x8f] = 0x00C5,
176   [0x90] = 0x00C9,
177   [0x91] = 0x00E6,
178   [0x92] = 0x00C6,
179   [0x93] = 0x00F4,
180   [0x94] = 0x00F6,
181   [0x95] = 0x00F2,
182   [0x96] = 0x00FB,
183   [0x97] = 0x00F9,
184   [0x98] = 0x00FF,
185   [0x99] = 0x00D6,
186   [0x9a] = 0x00DC,
187   [0x9b] = 0x00F8,
188   [0x9c] = 0x00A3,
189   [0x9d] = 0x00D8,
190   [0x9e] = 0x00D7,
191   [0x9f] = 0x0192,
192   [0xa0] = 0x00E1,
193   [0xa1] = 0x00ED,
194   [0xa2] = 0x00F3,
195   [0xa3] = 0x00FA,
196   [0xa4] = 0x00F1,
197   [0xa5] = 0x00D1,
198   [0xa6] = 0x00AA,
199   [0xa7] = 0x00BA,
200   [0xa8] = 0x00BF,
201   [0xa9] = 0x00AE,
202   [0xaa] = 0x00AC,
203   [0xab] = 0x00BD,
204   [0xac] = 0x00BC,
205   [0xad] = 0x00A1,
206   [0xae] = 0x00AB,
207   [0xaf] = 0x00BB,
208   [0xb0] = 0x2591,
209   [0xb1] = 0x2592,
210   [0xb2] = 0x2593,
211   [0xb3] = 0x2502,
212   [0xb4] = 0x2524,
213   [0xb5] = 0x00C1,
214   [0xb6] = 0x00C2,
215   [0xb7] = 0x00C0,
216   [0xb8] = 0x00A9,
217   [0xb9] = 0x2563,
218   [0xba] = 0x2551,
219   [0xbb] = 0x2557,
220   [0xbc] = 0x255D,
221   [0xbd] = 0x00A2,
222   [0xbe] = 0x00A5,
223   [0xbf] = 0x2510,
224   [0xc0] = 0x2514,
225   [0xc1] = 0x2534,
226   [0xc2] = 0x252C,
227   [0xc3] = 0x251C,
228   [0xc4] = 0x2500,
229   [0xc5] = 0x253C,
230   [0xc6] = 0x00E3,
231   [0xc7] = 0x00C3,
232   [0xc8] = 0x255A,
233   [0xc9] = 0x2554,
234   [0xca] = 0x2569,
235   [0xcb] = 0x2566,
236   [0xcc] = 0x2560,
237   [0xcd] = 0x2550,
238   [0xce] = 0x256C,
239   [0xcf] = 0x00A4,
240   [0xd0] = 0x00F0,
241   [0xd1] = 0x00D0,
242   [0xd2] = 0x00CA,
243   [0xd3] = 0x00CB,
244   [0xd4] = 0x00C8,
245   [0xd5] = 0x0131,
246   [0xd6] = 0x00CD,
247   [0xd7] = 0x00CE,
248   [0xd8] = 0x00CF,
249   [0xd9] = 0x2518,
250   [0xda] = 0x250C,
251   [0xdb] = 0x2588,
252   [0xdc] = 0x2584,
253   [0xdd] = 0x00A6,
254   [0xde] = 0x00CC,
255   [0xdf] = 0x2580,
256   [0xe0] = 0x00D3,
257   [0xe1] = 0x00DF,
258   [0xe2] = 0x00D4,
259   [0xe3] = 0x00D2,
260   [0xe4] = 0x00F5,
261   [0xe5] = 0x00D5,
262   [0xe6] = 0x00B5,
263   [0xe7] = 0x00FE,
264   [0xe8] = 0x00DE,
265   [0xe9] = 0x00DA,
266   [0xea] = 0x00DB,
267   [0xeb] = 0x00D9,
268   [0xec] = 0x00FD,
269   [0xed] = 0x00DD,
270   [0xee] = 0x00AF,
271   [0xef] = 0x00B4,
272   [0xf0] = 0x00AD,
273   [0xf1] = 0x00B1,
274   [0xf2] = 0x2017,
275   [0xf3] = 0x00BE,
276   [0xf4] = 0x00B6,
277   [0xf5] = 0x00A7,
278   [0xf6] = 0x00F7,
279   [0xf7] = 0x00B8,
280   [0xf8] = 0x00B0,
281   [0xf9] = 0x00A8,
282   [0xfa] = 0x00B7,
283   [0xfb] = 0x00B9,
284   [0xfc] = 0x00B3,
285   [0xfd] = 0x00B2,
286   [0xfe] = 0x25A0,
287   [0xff] = 0x00A0,
288 };
289
290 static const struct gap from_idx[] = {
291     /* start, end, idx */
292   { 0x0000, 0x007f, 0 },
293   { 0x00a0, 0x00ff, -32 },
294   { 0x0131, 0x0131, -81 },
295   { 0x0192, 0x0192, -177 },
296   { 0x2017, 0x2017, -7989 },
297   { 0x2500, 0x2502, -9245 },
298   { 0x250c, 0x251c, -9254 },
299   { 0x2524, 0x2524, -9261 },
300   { 0x252c, 0x252c, -9268 },
301   { 0x2534, 0x2534, -9275 },
302   { 0x253c, 0x253c, -9282 },
303   { 0x2550, 0x256c, -9301 },
304   { 0x2580, 0x2588, -9320 },
305   { 0x2591, 0x2593, -9328 },
306   { 0x25a0, 0x25a0, -9340 },
307   { 0xffff, 0xffff, 0 }
308 };
309 static const unsigned char from_ucs2[] = {
310
311   '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
312   '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f',
313   '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17',
314   '\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f',
315   '\x20', '\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27',
316   '\x28', '\x29', '\x2a', '\x2b', '\x2c', '\x2d', '\x2e', '\x2f',
317   '\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37',
318   '\x38', '\x39', '\x3a', '\x3b', '\x3c', '\x3d', '\x3e', '\x3f',
319   '\x40', '\x41', '\x42', '\x43', '\x44', '\x45', '\x46', '\x47',
320   '\x48', '\x49', '\x4a', '\x4b', '\x4c', '\x4d', '\x4e', '\x4f',
321   '\x50', '\x51', '\x52', '\x53', '\x54', '\x55', '\x56', '\x57',
322   '\x58', '\x59', '\x5a', '\x5b', '\x5c', '\x5d', '\x5e', '\x5f',
323   '\x60', '\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67',
324   '\x68', '\x69', '\x6a', '\x6b', '\x6c', '\x6d', '\x6e', '\x6f',
325   '\x70', '\x71', '\x72', '\x73', '\x74', '\x75', '\x76', '\x77',
326   '\x78', '\x79', '\x7a', '\x7b', '\x7c', '\x7d', '\x7e', '\x7f',
327   '\xff', '\xad', '\xbd', '\x9c', '\xcf', '\xbe', '\xdd', '\xf5',
328   '\xf9', '\xb8', '\xa6', '\xae', '\xaa', '\xf0', '\xa9', '\xee',
329   '\xf8', '\xf1', '\xfd', '\xfc', '\xef', '\xe6', '\xf4', '\xfa',
330   '\xf7', '\xfb', '\xa7', '\xaf', '\xac', '\xab', '\xf3', '\xa8',
331   '\xb7', '\xb5', '\xb6', '\xc7', '\x8e', '\x8f', '\x92', '\x80',
332   '\xd4', '\x90', '\xd2', '\xd3', '\xde', '\xd6', '\xd7', '\xd8',
333   '\xd1', '\xa5', '\xe3', '\xe0', '\xe2', '\xe5', '\x99', '\x9e',
334   '\x9d', '\xeb', '\xe9', '\xea', '\x9a', '\xed', '\xe8', '\xe1',
335   '\x85', '\xa0', '\x83', '\xc6', '\x84', '\x86', '\x91', '\x87',
336   '\x8a', '\x82', '\x88', '\x89', '\x8d', '\xa1', '\x8c', '\x8b',
337   '\xd0', '\xa4', '\x95', '\xa2', '\x93', '\xe4', '\x94', '\xf6',
338   '\x9b', '\x97', '\xa3', '\x96', '\x81', '\xec', '\xe7', '\x98',
339   '\xd5', '\x9f', '\xf2', '\xc4', '\x00', '\xb3', '\xda', '\x00',
340   '\x00', '\x00', '\xbf', '\x00', '\x00', '\x00', '\xc0', '\x00',
341   '\x00', '\x00', '\xd9', '\x00', '\x00', '\x00', '\xc3', '\xb4',
342   '\xc2', '\xc1', '\xc5', '\xcd', '\xba', '\x00', '\x00', '\xc9',
343   '\x00', '\x00', '\xbb', '\x00', '\x00', '\xc8', '\x00', '\x00',
344   '\xbc', '\x00', '\x00', '\xcc', '\x00', '\x00', '\xb9', '\x00',
345   '\x00', '\xcb', '\x00', '\x00', '\xca', '\x00', '\x00', '\xce',
346   '\xdf', '\x00', '\x00', '\x00', '\xdc', '\x00', '\x00', '\x00',
347   '\xdb', '\xb0', '\xb1', '\xb2', '\xfe',
348 };
349
350
351 static size_t CP850_push(void *cd, char **inbuf, size_t *inbytesleft,
352                          char **outbuf, size_t *outbytesleft)
353 {
354         while (*inbytesleft >= 2 && *outbytesleft >= 1) {
355                 int i;
356                 int done = 0;
357                 
358                 uint16 ch = SVAL(*inbuf,0);
359                 
360                 for (i=0; from_idx[i].start != 0xffff; i++) {
361                         if ((from_idx[i].start <= ch) && (from_idx[i].end >= ch)) {
362                                 ((unsigned char*)(*outbuf))[0] = from_ucs2[from_idx[i].idx+ch];
363                                 (*inbytesleft) -= 2;
364                                 (*outbytesleft) -= 1;
365                                 (*inbuf)  += 2;
366                                 (*outbuf) += 1;
367                                 done = 1;
368                                 break;
369                         }
370                 }
371                 if (!done) {
372                         errno = EINVAL;
373                         return -1;
374                 }
375                 
376         }
377
378         if (*inbytesleft == 1) {
379                 errno = EINVAL;
380                 return -1;
381         }
382
383         if (*inbytesleft > 1) {
384                 errno = E2BIG;
385                 return -1;
386         }
387         
388         return 0;
389 }
390
391 static size_t CP850_pull(void *cd, char **inbuf, size_t *inbytesleft,
392                          char **outbuf, size_t *outbytesleft)
393 {
394         while (*inbytesleft >= 1 && *outbytesleft >= 2) {
395                 *(uint16*)(*outbuf) = to_ucs2[((unsigned char*)(*inbuf))[0]];
396                 (*inbytesleft)  -= 1;
397                 (*outbytesleft) -= 2;
398                 (*inbuf)  += 1;
399                 (*outbuf) += 2;
400         }
401
402         if (*inbytesleft > 0) {
403                 errno = E2BIG;
404                 return -1;
405         }
406         
407         return 0;
408 }
409
410 struct charset_functions CP850_functions = {"CP850", CP850_pull, CP850_push};
411
412 NTSTATUS charset_CP850_init(void)
413 {
414         return smb_register_charset(&CP850_functions);
415 }