1 /*
2   Simple DirectMedia Layer
3   Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
4 
5   This software is provided 'as-is', without any express or implied
6   warranty.  In no event will the authors be held liable for any damages
7   arising from the use of this software.
8 
9   Permission is granted to anyone to use this software for any purpose,
10   including commercial applications, and to alter it and redistribute it
11   freely, subject to the following restrictions:
12 
13   1. The origin of this software must not be misrepresented; you must not
14      claim that you wrote the original software. If you use this software
15      in a product, an acknowledgment in the product documentation would be
16      appreciated but is not required.
17   2. Altered source versions must be plainly marked as such, and must not be
18      misrepresented as being the original software.
19   3. This notice may not be removed or altered from any source distribution.
20 */
21 
22 #define INCL_DOSNLS
23 #define INCL_DOSERRORS
24 #include <os2.h>
25 
26 #include "os2cp.h"
27 
28 #ifndef GENICONV_STANDALONE
29 #include "../../../SDL_internal.h"
30 #else
31 #include <string.h>
32 #include <ctype.h>
33 #define SDL_isspace isspace
34 #define SDL_strchr strchr
35 #define SDL_memcpy memcpy
36 #define SDL_strupr strupr
37 #define SDL_strcmp strcmp
38 #endif
39 
40 typedef struct _CP2NAME {
41   ULONG ulCode;
42   PSZ  pszName;
43 } CP2NAME;
44 
45 typedef struct _NAME2CP {
46   PSZ  pszName;
47   ULONG ulCode;
48 } NAME2CP;
49 
50 static CP2NAME aCP2Name[] = {
51   {367, "ANSI_X3.4-1968"},
52   {813, "ECMA-118"},
53   {819, "CP819"},
54   {850, "850"},
55   {862, "862"},
56   {866, "866"},
57   {874, "ISO-IR-166"},
58   {878, "KOI8-R"},
59   {896, "JISX0201-1976"},
60   {901, "ISO-8859-13"},
61   {912, "ISO-8859-2"},
62   {913, "ISO-8859-3"},
63   {914, "ISO-8859-4"},
64   {915, "CYRILLIC"},
65   {920, "ISO-8859-9"},
66   {923, "ISO-8859-15"},
67   {943, "MS_KANJI"},
68   {954, "EUC-JP"},
69   {964, "EUC-TW"},
70   {970, "EUC-KR"},
71   {1051, "HP-ROMAN8"},
72   {1089, "ARABIC"},
73   {1129, "VISCII"},
74   {1168, "KOI8-U"},
75   {1200, "ISO-10646-UCS-2"},
76   {1202, "UTF-16LE"},
77   {1204, "UCS-2BE"},
78   {1208, "UTF-8"},
79   {1232, "UTF-32BE"},
80   {1234, "UTF-32LE"},
81   {1236, "ISO-10646-UCS-4"},
82   {1250, "CP1250"},
83   {1251, "CP1251"},
84   {1252, "CP1252"},
85   {1253, "CP1253"},
86   {1254, "CP1254"},
87   {1255, "CP1255"},
88   {1256, "CP1256"},
89   {1257, "CP1257"},
90   {1275, "MAC"},
91   {1383, "CN-GB"},
92   {1386, "GBK"},
93   {1392, "GB18030"},
94   {62210, "HEBREW"}
95 };
96 
97 static NAME2CP aName2CP[] = {
98   {"850", 850},
99   {"862", 862},
100   {"866", 866},
101   {"ANSI_X3.4-1968", 367},
102   {"ANSI_X3.4-1986", 367},
103   {"ARABIC", 1089},
104   {"ASCII", 367},
105   {"ASMO-708", 1089},
106   {"CN-GB", 1383},
107   {"CP1250", 1250},
108   {"CP1251", 1251},
109   {"CP1252", 1252},
110   {"CP1253", 1253},
111   {"CP1254", 1254},
112   {"CP1255", 1255},
113   {"CP1256", 1256},
114   {"CP1257", 1257},
115   {"CP367", 367},
116   {"CP819", 819},
117   {"CP850", 850},
118   {"CP862", 862},
119   {"CP866", 866},
120   {"CP936", 1386},
121   {"CSASCII", 367},
122   {"CSEUCKR", 970},
123   {"CSEUCPKDFMTJAPANESE", 954},
124   {"CSEUCTW", 964},
125   {"CSGB2312", 1383},
126   {"CSHALFWIDTHKATAKANA", 896},
127   {"CSHPROMAN8", 1051},
128   {"CSIBM866", 866},
129   {"CSISOLATIN1", 819},
130   {"CSISOLATIN2", 912},
131   {"CSISOLATIN3", 913},
132   {"CSISOLATIN4", 914},
133   {"CSISOLATIN5", 920},
134   {"CSISOLATINARABIC", 1089},
135   {"CSISOLATINCYRILLIC", 915},
136   {"CSISOLATINGREEK", 813},
137   {"CSISOLATINHEBREW", 62210},
138   {"CSKOI8R", 878},
139   {"CSKSC56011987", 970},
140   {"CSMACINTOSH", 1275},
141   {"CSPC850MULTILINGUAL", 850},
142   {"CSPC862LATINHEBREW", 862},
143   {"CSSHIFTJIS", 943},
144   {"CSUCS4", 1236},
145   {"CSUNICODE", 1200},
146   {"CSUNICODE11", 1204},
147   {"CSVISCII", 1129},
148   {"CYRILLIC", 915},
149   {"ECMA-114", 1089},
150   {"ECMA-118", 813},
151   {"ELOT_928", 813},
152   {"EUC-CN", 1383},
153   {"EUC-JP", 954},
154   {"EUC-KR", 970},
155   {"EUC-TW", 964},
156   {"EUCCN", 1383},
157   {"EUCJP", 954},
158   {"EUCKR", 970},
159   {"EUCTW", 964},
160   {"EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE", 954},
161   {"GB18030", 1392},
162   {"GB2312", 1383},
163   {"GBK", 1386},
164   {"GREEK", 813},
165   {"GREEK8", 813},
166   {"HEBREW", 62210},
167   {"HP-ROMAN8", 1051},
168   {"IBM367", 367},
169   {"IBM819", 819},
170   {"IBM850", 850},
171   {"IBM862", 862},
172   {"IBM866", 866},
173   {"ISO-10646-UCS-2", 1200},
174   {"ISO-10646-UCS-4", 1236},
175   {"ISO-8859-1", 819},
176   {"ISO-8859-13", 901},
177   {"ISO-8859-15", 923},
178   {"ISO-8859-2", 912},
179   {"ISO-8859-3", 913},
180   {"ISO-8859-4", 914},
181   {"ISO-8859-5", 915},
182   {"ISO-8859-6", 1089},
183   {"ISO-8859-7", 813},
184   {"ISO-8859-8", 62210},
185   {"ISO-8859-9", 920},
186   {"ISO-IR-100", 819},
187   {"ISO-IR-101", 912},
188   {"ISO-IR-109", 913},
189   {"ISO-IR-110", 914},
190   {"ISO-IR-126", 813},
191   {"ISO-IR-127", 1089},
192   {"ISO-IR-138", 62210},
193   {"ISO-IR-144", 915},
194   {"ISO-IR-148", 920},
195   {"ISO-IR-149", 970},
196   {"ISO-IR-166", 874},
197   {"ISO-IR-179", 901},
198   {"ISO-IR-203", 923},
199   {"ISO-IR-6", 367},
200   {"ISO646-US", 367},
201   {"ISO8859-1", 819},
202   {"ISO8859-13", 901},
203   {"ISO8859-15", 923},
204   {"ISO8859-2", 912},
205   {"ISO8859-3", 913},
206   {"ISO8859-4", 914},
207   {"ISO8859-5", 915},
208   {"ISO8859-6", 1089},
209   {"ISO8859-7", 813},
210   {"ISO8859-8", 62210},
211   {"ISO8859-9", 920},
212   {"ISO_646.IRV:1991", 367},
213   {"ISO_8859-1", 819},
214   {"ISO_8859-13", 901},
215   {"ISO_8859-15", 923},
216   {"ISO_8859-15:1998", 923},
217   {"ISO_8859-1:1987", 819},
218   {"ISO_8859-2", 912},
219   {"ISO_8859-2:1987", 912},
220   {"ISO_8859-3", 913},
221   {"ISO_8859-3:1988", 913},
222   {"ISO_8859-4", 914},
223   {"ISO_8859-4:1988", 914},
224   {"ISO_8859-5", 915},
225   {"ISO_8859-5:1988", 915},
226   {"ISO_8859-6", 1089},
227   {"ISO_8859-6:1987", 1089},
228   {"ISO_8859-7", 813},
229   {"ISO_8859-7:1987", 813},
230   {"ISO_8859-7:2003", 813},
231   {"ISO_8859-8", 62210},
232   {"ISO_8859-8:1988", 62210},
233   {"ISO_8859-9", 920},
234   {"ISO_8859-9:1989", 920},
235   {"JISX0201-1976", 896},
236   {"JIS_X0201", 896},
237   {"KOI8-R", 878},
238   {"KOI8-U", 1168},
239   {"KOREAN", 970},
240   {"KSC_5601", 970},
241   {"KS_C_5601-1987", 970},
242   {"KS_C_5601-1989", 970},
243   {"L1", 819},
244   {"L2", 912},
245   {"L3", 913},
246   {"L4", 914},
247   {"L5", 920},
248   {"L7", 901},
249   {"LATIN-9", 923},
250   {"LATIN1", 819},
251   {"LATIN2", 912},
252   {"LATIN3", 913},
253   {"LATIN4", 914},
254   {"LATIN5", 920},
255   {"LATIN7", 901},
256   {"MAC", 1275},
257   {"MACINTOSH", 1275},
258   {"MACROMAN", 1275},
259   {"MS-ANSI", 1252},
260   {"MS-ARAB", 1256},
261   {"MS-CYRL", 1251},
262   {"MS-EE", 1250},
263   {"MS-GREEK", 1253},
264   {"MS-HEBR", 1255},
265   {"MS-TURK", 1254},
266   {"MS936", 1386},
267   {"MS_KANJI", 943},
268   {"R8", 1051},
269   {"ROMAN8", 1051},
270   {"SHIFT-JIS", 943},
271   {"SHIFT_JIS", 943},
272   {"SJIS", 943},
273   {"TIS-620", 874},
274   {"TIS620", 874},
275   {"TIS620-0", 874},
276   {"TIS620.2529-1", 874},
277   {"TIS620.2533-0", 874},
278   {"TIS620.2533-1", 874},
279   {"UCS-2", 1200},
280   {"UCS-2BE", 1204},
281   {"UCS-4", 1236},
282   {"UNICODE-1-1", 1204},
283   {"UNICODEBIG", 1204},
284   {"US", 367},
285   {"US-ASCII", 367},
286   {"UTF-16", 1204},
287   {"UTF-16BE", 1200},
288   {"UTF-16LE", 1202},
289   {"UTF-32", 1236},
290   {"UTF-32BE", 1232},
291   {"UTF-32LE", 1234},
292   {"UTF-8", 1208},
293   {"VISCII", 1129},
294   {"VISCII1.1-1", 1129},
295   {"WINBALTRIM", 1257},
296   {"WINDOWS-1250", 1250},
297   {"WINDOWS-1251", 1251},
298   {"WINDOWS-1252", 1252},
299   {"WINDOWS-1253", 1253},
300   {"WINDOWS-1254", 1254},
301   {"WINDOWS-1255", 1255},
302   {"WINDOWS-1256", 1256},
303   {"WINDOWS-1257", 1257},
304   {"WINDOWS-936", 1386},
305   {"X0201", 896}
306 };
307 
os2cpToName(unsigned long cp)308 char *os2cpToName(unsigned long cp)
309 {
310     ULONG ulLo = 0;
311     ULONG ulHi = (sizeof(aCP2Name) / sizeof(struct _CP2NAME)) - 1;
312     ULONG ulNext;
313     LONG  lFound = -1;
314 
315     if (cp == SYSTEM_CP) {
316         ULONG aulCP[3];
317         ULONG cCP;
318 
319         if (DosQueryCp(sizeof(aulCP), aulCP, &cCP) != NO_ERROR)
320             return NULL;
321 
322         cp = aulCP[0];
323     }
324 
325     if (aCP2Name[0].ulCode > cp || aCP2Name[ulHi].ulCode < cp)
326         return NULL;
327 
328     if (aCP2Name[0].ulCode == cp)
329         return aCP2Name[0].pszName;
330 
331     if (aCP2Name[ulHi].ulCode == cp)
332         return aCP2Name[ulHi].pszName;
333 
334     while ((ulHi - ulLo) > 1) {
335         ulNext = (ulLo + ulHi) / 2;
336 
337         if (aCP2Name[ulNext].ulCode < cp)
338             ulLo = ulNext;
339         else if (aCP2Name[ulNext].ulCode > cp)
340             ulHi = ulNext;
341         else {
342             lFound = ulNext;
343             break;
344         }
345     }
346 
347     return (lFound == -1)? NULL : aCP2Name[lFound].pszName;
348 }
349 
os2cpFromName(char * cp)350 unsigned long os2cpFromName(char *cp)
351 {
352     ULONG ulLo = 0;
353     ULONG ulHi = (sizeof(aName2CP) / sizeof(struct _NAME2CP)) - 1;
354     ULONG ulNext;
355     LONG  lFound = -1;
356     LONG  lCmp;
357     PCHAR pcEnd;
358     CHAR  acBuf[64];
359 
360     if (cp == NULL) {
361         ULONG aulCP[3];
362         ULONG cCP;
363 
364         return (DosQueryCp(sizeof(aulCP), aulCP, &cCP) != NO_ERROR)? 0 : aulCP[0];
365     }
366 
367     while (SDL_isspace(*cp))
368         cp++;
369 
370     pcEnd = SDL_strchr(cp, ' ');
371     if (pcEnd == NULL)
372         pcEnd = SDL_strchr(cp, '\0');
373 
374     ulNext = pcEnd - cp;
375     if (ulNext >= sizeof(acBuf))
376         return 0;
377 
378     SDL_memcpy(acBuf, cp, ulNext);
379     acBuf[ulNext] = '\0';
380     SDL_strupr(acBuf);
381 
382     lCmp = SDL_strcmp(aName2CP[0].pszName, acBuf);
383     if (lCmp > 0)
384         return 0;
385     else if (lCmp == 0)
386         return aName2CP[0].ulCode;
387 
388     lCmp = SDL_strcmp(aName2CP[ulHi].pszName, acBuf);
389     if (lCmp < 0)
390         return 0;
391     else if (lCmp == 0)
392         return aName2CP[ulHi].ulCode;
393 
394     while ((ulHi - ulLo) > 1) {
395         ulNext = (ulLo + ulHi) / 2;
396 
397         lCmp = SDL_strcmp(aName2CP[ulNext].pszName, acBuf);
398         if (lCmp < 0)
399             ulLo = ulNext;
400         else if (lCmp > 0)
401             ulHi = ulNext;
402         else {
403             lFound = ulNext;
404             break;
405         }
406     }
407 
408     return (lFound == -1)? 0 : aName2CP[lFound].ulCode;
409 }
410 
411 /* vi: set ts=4 sw=4 expandtab: */
412