source: trunk/Lucide/SOURCE/plugins/ludoc/cpconv.cpp @ 2

Last change on this file since 2 was 2, checked in by Eugene Romanenko, 15 years ago

First import

File size: 8.4 KB
Line 
1#include <os2.h>
2
3#include <string.h>
4#include <malloc.h>
5#include <stdio.h>
6
7#include <uconv.h>
8
9
10class cpconv
11{
12    protected:
13        int  err;
14        void *objtoucs;
15        void *objfromucs;
16    public:
17        cpconv( int cpfrom, int cpto = 0 );
18        cpconv( UniChar *cpfrom, UniChar *cpto );
19        ~cpconv();
20        int conv( int chfrom );
21        int conv( const char **in, size_t *in_left, char **out, size_t *out_left );
22};
23
24cpconv::cpconv( UniChar *cpfrom, UniChar *cpto )
25{
26    err = 0;
27    int         rc = ULS_SUCCESS;
28
29    rc = UniCreateUconvObject( cpfrom, &objtoucs );
30    if (rc != ULS_SUCCESS)
31    {
32        err = 1;
33        return;
34    }
35
36    uconv_attribute_t attr;
37    UniQueryUconvObject(objtoucs, &attr, sizeof(attr), NULL, NULL, NULL);
38    attr.converttype &= ~(CVTTYPE_CTRL7F | CVTTYPE_PATH);
39    UniSetUconvObject(objtoucs, &attr);
40
41    rc = UniCreateUconvObject( cpto, &objfromucs );
42    if (rc != ULS_SUCCESS)
43    {
44        UniFreeUconvObject( objtoucs );
45        err = 1;
46        return;
47    }
48    UniQueryUconvObject(objfromucs, &attr, sizeof(uconv_attribute_t), NULL, NULL, NULL);
49    attr.options = UCONV_OPTION_SUBSTITUTE_BOTH;
50    UniSetUconvObject(objfromucs, &attr);
51}
52
53cpconv::cpconv( int cpfrom, int cpto )
54{
55    err = 0;
56
57    UniChar     ucs_code_page[12];
58    size_t      num_elems = 12;
59    int         rc = ULS_SUCCESS;
60
61    rc = UniMapCpToUcsCp(cpfrom, ucs_code_page, num_elems);
62    if (rc != ULS_SUCCESS)
63    {
64        err = 1;
65        return;
66    }
67
68    rc = UniCreateUconvObject(ucs_code_page, &objtoucs);
69    if (rc != ULS_SUCCESS)
70    {
71        err = 1;
72        return;
73    }
74
75    uconv_attribute_t attr;
76    UniQueryUconvObject(objtoucs, &attr, sizeof(attr), NULL, NULL, NULL);
77    attr.converttype &= ~(CVTTYPE_CTRL7F | CVTTYPE_PATH);
78    UniSetUconvObject(objtoucs, &attr);
79
80    rc = UniMapCpToUcsCp(cpto, ucs_code_page, num_elems);
81    if (rc != ULS_SUCCESS)
82    {
83        UniFreeUconvObject( objtoucs );
84        err = 1;
85        return;
86    }
87
88    rc = UniCreateUconvObject(ucs_code_page, &objfromucs);
89    if (rc != ULS_SUCCESS)
90    {
91        UniFreeUconvObject( objtoucs );
92        err = 1;
93        return;
94    }
95    UniQueryUconvObject(objfromucs, &attr, sizeof(uconv_attribute_t), NULL, NULL, NULL);
96    attr.options = UCONV_OPTION_SUBSTITUTE_BOTH;
97    UniSetUconvObject(objfromucs, &attr);
98}
99
100cpconv::~cpconv()
101{
102    if ( !err )
103    {
104        UniFreeUconvObject( objtoucs );
105        UniFreeUconvObject( objfromucs );
106    }
107}
108
109int cpconv::conv( int chfrom )
110{
111    int rc = ULS_SUCCESS;
112    size_t ns = 0;
113    int chto = 0;
114
115    if ( err )  return chfrom;
116
117    size_t len = 1;
118    UniChar unichar;
119    UniChar *punichar = &unichar;
120    void *pchfrom = &chfrom;
121    void *pchto = &chto;
122
123    rc = UniUconvToUcs( objtoucs, &pchfrom, &len, &punichar, &len, &ns);
124    if ( rc != ULS_SUCCESS )  return chfrom;
125
126    len = 1;
127    punichar = &unichar;
128    ns = 0;
129    rc = UniUconvFromUcs( objfromucs, &punichar, &len, &pchto, &len, &ns);
130    if ( rc != ULS_SUCCESS )  return chfrom;
131
132    return chto;
133}
134
135int cpconv::conv( const char **in, size_t *in_left, char **out, size_t *out_left )
136{
137    int       rc;
138    size_t    sl;
139    size_t    nonid;
140    UniChar  *ucs;
141    UniChar  *orig_ucs;
142    size_t    retval = 0;
143
144  /* The caller wish to initate the conversion state and/or write initial
145     shift prefix (or something like that) to the output buffer. */
146  if (!in || !*in)
147    {
148      if (!out || !*out || !out_left || !*out_left)
149        /* do nothing since we don't have any shift state in the iconv_t. */
150        return 0;
151
152      /** @todo We don't have any shift state I or so, so what to do now?
153       *        Let's do nothing till we have anyone complaining about his DBCS
154       *        stuff not working 100%, and accept patches for that guy.
155       *        Perhaps try call UniUconvFromUcs(conv->to, and some empty input buffer or so...
156       */
157      return 0;
158    }
159
160  sl =  *in_left;
161  ucs = (UniChar *) alloca (sl * sizeof (UniChar));
162  orig_ucs = ucs;
163
164  rc = UniUconvToUcs (objtoucs, (void **)in, in_left, &ucs, &sl, &retval);
165  if (rc)
166    goto error;
167  sl = ucs - orig_ucs;
168  ucs = orig_ucs;
169  /* UniUconvFromUcs will stop at first null byte (huh? indeed?)
170     while we want ALL the bytes converted.  */
171#if 1
172  rc = UniUconvFromUcs (objfromucs, &ucs, &sl, (void **)out, out_left, &nonid);
173  if (rc)
174    goto error;
175  retval += nonid;
176#else
177  while (sl)
178    {
179      size_t usl = 0;
180      while (sl && (ucs[usl] != 0))
181        usl++, sl--;
182      rc = UniUconvFromUcs (objfromucs, &ucs, &usl, (void **)out, out_left, &nonid);
183      if (rc)
184        goto error;
185      retval += nonid;
186      if (sl && *out_left)
187        {
188          *(*out)++ = 0;
189          (*out_left)--;
190          ucs++; sl--;
191        }
192    }
193#endif
194  return 0;
195
196error:
197    err = 1;
198  return -1;
199}
200
201extern "C" LONG APIENTRY cnvUniToUTF8( const char **in, unsigned *in_left,
202                                       char **out, unsigned *out_left )
203{
204    cpconv c( 1200, 1208 );
205    return c.conv( in, in_left, out, out_left );
206}
207
208extern "C" LONG APIENTRY cnvUniBEToUTF8( const char **in, unsigned *in_left,
209                                         char **out, unsigned *out_left )
210{
211    cpconv c( (UniChar *)(L"UCS-2@endian=big"), (UniChar *)(L"UTF-8") );
212    return c.conv( in, in_left, out, out_left );
213}
214
215extern "C" LONG APIENTRY cnvUTF8ToUni( const char **in, unsigned *in_left,
216                                       char **out, unsigned *out_left )
217{
218    cpconv c( 1208, 1200 );
219    return c.conv( in, in_left, out, out_left );
220}
221
222
223static void convSpchars( UniChar *uni )
224{
225    while ( *uni )
226    {
227//printf( ":%x:", *uni );
228        switch ( *uni )
229        {
230            case 0x2018:
231            case 0x2019:
232            case 0x2032:
233                *uni = 0x0027;
234                break;
235            case 0x201C:
236            case 0x201D:
237            case 0x00AB:
238            case 0x00BB:
239                *uni = 0x0022;
240                break;
241            case 0x2014:
242                *uni = 0x002D;
243                break;
244        }
245        *uni++;
246    }
247//printf( "\n" );   
248}
249
250
251extern "C" LONG APIENTRY cnvUTF8ToSys( const char **in, unsigned *in_left,
252                                       char **out, unsigned *out_left )
253{
254    unsigned ulen = ( (*in_left) * 2 ) + 2;
255    char *uni = new char[ ulen ];
256    memset( uni, 0, ulen );
257    char *savuni = uni;
258    unsigned savulen = ulen;
259    cnvUTF8ToUni( in, in_left, &uni, &ulen );
260    uni = savuni;
261    ulen = savulen;
262    convSpchars( (UniChar *)uni );
263    cpconv c( 1200 );
264    LONG rc = c.conv( (const char **)&uni, &ulen, out, out_left );
265    uni = savuni;
266    delete uni;
267    return rc;
268}
269
270extern "C" LONG APIENTRY cnvUniBEToSys( const char **in, unsigned *in_left,
271                                         char **out, unsigned *out_left )
272{
273    unsigned ulen = ( (*in_left) * 2 ) + 2;
274    char *uni = new char[ ulen ];
275    memset( uni, 0, ulen );
276    char *savuni = uni;
277    unsigned savulen = ulen;
278    cpconv c1( (UniChar *)(L"UCS-2@endian=big"), (UniChar *)(L"UCS-2") );
279    c1.conv( in, in_left, &uni, &ulen );
280    uni = savuni;
281    ulen = savulen;
282    convSpchars( (UniChar *)uni );
283    cpconv c2( 1200 );
284    LONG rc = c2.conv( (const char **)&uni, &ulen, out, out_left );
285    uni = savuni;
286    delete uni;
287    return rc;
288}
289
290extern "C" LONG APIENTRY cnvUniToSys( const char **in, unsigned *in_left,
291                                      char **out, unsigned *out_left )
292{
293    convSpchars( (UniChar *)in );
294    cpconv c( 1200 );
295    return c.conv( (const char **)&in, in_left, out, out_left );
296}
297
298extern "C" LONG APIENTRY cnvSysToUCS2( const char **in, unsigned *in_left,
299                                       char **out, unsigned *out_left )
300{
301    cpconv c( (UniChar *)(L""), (UniChar *)(L"UCS-2") );
302    return c.conv( in, in_left, out, out_left );
303}
304
305
306// test
307/*void main()
308{
309        const char *testutf8 = "test UTF-8  ’¥áâ! à®¢¥àª !";
310        char buf[ 100 ];
311        memset( buf, 0, sizeof( buf ) );
312        char *bufsav = buf;
313        char *buf1 = buf;
314        unsigned in_len = strlen( testutf8 );
315        unsigned out_len = sizeof( buf );
316       
317        cnvUTF8ToUCS4( &testutf8, &in_len, &buf1, &out_len );
318       
319        for ( int i = 0; i<100; i++ )
320        {
321                printf( ":%d:", (int)bufsav[i] );
322        }
323        printf( "\n" );
324}
325*/
Note: See TracBrowser for help on using the repository browser.