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