1 // (c) 2001,2004 by Max Alekseyev
2 // ver. 2.1
3
4 #include <stddef.h>
5
6 #define INCL_DOSMODULEMGR
7 #include <os2.h>
8
9 typedef void* UconvObject;
10 typedef unsigned short UniChar;
11
12 int uni_init(int codepage);
13
14 int uni_done();
15
16 int uni_toucs( /* translate to Unicode */
17 char*, /* I - input string */
18 size_t, /* I - length of input string (chars) */
19 UniChar*, /* O - output Unicode string */
20 size_t* ); /* O - length of output string (UniChars) */
21
22 int uni_fromucs( /* translate from Unicode */
23 UniChar*, /* I - input Unicode string */
24 size_t, /* I - length of input string (UniChars) */
25 char*, /* O - output string */
26 size_t* ); /* O - length of output string (chars) */
27
28 /* IMPLEMENTATION */
29
30 static int (*uniMapCpToUcsCp) (
31 unsigned long, /* I - Codepage to convert */
32 UniChar*, /* O - Output buffer */
33 size_t ); /* I - UniChars in output buffer */
34
35 static int (*uniCreateUconvObject) (
36 UniChar*, /* I - Unicode name of uconv table */
37 UconvObject* );/* O - Uconv object handle */
38
39 static int (*uniFreeUconvObject) (
40 UconvObject ); /* I - Uconv object handle */
41
42 static int (*uniUconvToUcs) (
43 UconvObject, /* I - Uconv object handle */
44 void**, /* IO - Input buffer */
45 size_t*, /* IO - Input buffer size (bytes) */
46 UniChar**, /* IO - Output buffer size */
47 size_t*, /* IO - Output size (chars) */
48 size_t* ); /* IO - Substitution count */
49
50 static int (*uniUconvFromUcs) (
51 UconvObject, /* I - Uconv object handle */
52 UniChar**, /* IO - Input buffer */
53 size_t*, /* IO - Input buffer size (bytes) */
54 void**, /* IO - Output buffer size */
55 size_t*, /* IO - Output size (chars) */
56 size_t* ); /* IO - Substitution count */
57
58 static int uni_ready = 0;
59 static HMODULE uni_UCONV;
60 static UconvObject uni_obj;
61
uni_init(int codepage)62 int uni_init(int codepage) {
63 UniChar unistr[256];
64
65 uni_ready = 0;
66
67 if(!&DosLoadModule) {
68 /* DOS enviroment detected */
69 return -1;
70 }
71
72 if( DosLoadModule(0,0,(PCSZ)"UCONV",&uni_UCONV) ) {
73 /* no Unicode API found (obsolete OS/2 version) */
74 return -2;
75 }
76
77 if( !DosQueryProcAddr(uni_UCONV,0,(PCSZ)"UniMapCpToUcsCp", (PPFN)&uniMapCpToUcsCp ) &&
78 !DosQueryProcAddr(uni_UCONV,0,(PCSZ)"UniUconvToUcs", (PPFN)&uniUconvToUcs ) &&
79 !DosQueryProcAddr(uni_UCONV,0,(PCSZ)"UniUconvFromUcs", (PPFN)&uniUconvFromUcs ) &&
80 !DosQueryProcAddr(uni_UCONV,0,(PCSZ)"UniCreateUconvObject",(PPFN)&uniCreateUconvObject) &&
81 !DosQueryProcAddr(uni_UCONV,0,(PCSZ)"UniFreeUconvObject", (PPFN)&uniFreeUconvObject )
82 ) {
83 unistr[0] = 0;
84 if( (!codepage || !uniMapCpToUcsCp(codepage, unistr, 256)) && !uniCreateUconvObject(unistr,&uni_obj) ) {
85 uni_ready = 1;
86 return 0;
87 }
88 }
89 DosFreeModule(uni_UCONV);
90 return -2;
91 }
92
uni_toucs(char * src,size_t srclen,UniChar * dst,size_t * dstlen)93 int uni_toucs(char* src, size_t srclen, UniChar* dst, size_t* dstlen) {
94 size_t srcbytes, srcsize, dstsize, subsc=0;
95
96 if(!uni_ready) return -1;
97
98 dstsize = srcbytes = srclen * sizeof(UniChar);
99
100 if( uniUconvToUcs(uni_obj,(void**)&src,&srclen,&dst,&dstsize,&subsc) ) {
101 return -1;
102 }
103 *dstlen = srcbytes - dstsize;
104 return 0;
105 }
106
uni_fromucs(UniChar * src,size_t srclen,char * dst,size_t * dstlen)107 int uni_fromucs(UniChar* src, size_t srclen, char* dst, size_t* dstlen) {
108 size_t srcbytes, srcsize, dstsize, subsc=0;
109
110 if(!uni_ready) return -1;
111
112 dstsize = srcbytes = *dstlen;
113
114 if( uniUconvFromUcs(uni_obj,&src,&srclen,(void**)&dst,&dstsize,&subsc) ) {
115 return -1;
116 }
117 *dstlen = srcbytes - dstsize;
118 return 0;
119 }
120
uni_done()121 int uni_done() {
122 if( uni_ready ) {
123 uniFreeUconvObject(uni_obj);
124 DosFreeModule(uni_UCONV);
125 uni_ready = 0;
126 }
127 return 0;
128 }
129