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

Last change on this file since 95 was 40, checked in by Eugene Romanenko, 16 years ago

implemented 'select all', fixes for crash in libc memanager

File size: 9.2 KB
Line 
1/* ***** BEGIN LICENSE BLOCK *****
2 * Version: CDDL 1.0/LGPL 2.1
3 *
4 * The contents of this file are subject to the COMMON DEVELOPMENT AND
5 * DISTRIBUTION LICENSE (CDDL) Version 1.0 (the "License"); you may not use
6 * this file except in compliance with the License. You may obtain a copy of
7 * the License at http://www.sun.com/cddl/
8 *
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
13 *
14 * The Initial Developer of the Original Code is
15 * Eugene Romanenko, netlabs.org.
16 * Portions created by the Initial Developer are Copyright (C) 2006
17 * the Initial Developer. All Rights Reserved.
18 *
19 * Contributor(s):
20 *
21 * Alternatively, the contents of this file may be used under the terms of
22 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
23 * in which case the provisions of the LGPL are applicable instead of those
24 * above. If you wish to allow use of your version of this file only under the
25 * terms of the LGPL, and not to allow others to use your version of this file
26 * under the terms of the CDDL, indicate your decision by deleting the
27 * provisions above and replace them with the notice and other provisions
28 * required by the LGPL. If you do not delete the provisions above, a recipient
29 * may use your version of this file under the terms of any one of the CDDL
30 * or the LGPL.
31 *
32 * ***** END LICENSE BLOCK ***** */
33
34
35#define INCL_DOS
36#include <os2.h>
37
38#include <string.h>
39#include <malloc.h>
40#include <stdio.h>
41
42#include <uconv.h>
43
44
45class cpconv
46{
47    protected:
48        int  err;
49        void *objtoucs;
50        void *objfromucs;
51    public:
52        cpconv( int cpfrom, int cpto = 0 );
53        cpconv( UniChar *cpfrom, UniChar *cpto );
54        ~cpconv();
55        int conv( int chfrom );
56        int conv( const char **in, size_t *in_left, char **out, size_t *out_left );
57};
58
59cpconv::cpconv( UniChar *cpfrom, UniChar *cpto )
60{
61    err = 0;
62    int         rc = ULS_SUCCESS;
63
64    rc = UniCreateUconvObject( cpfrom, &objtoucs );
65    if (rc != ULS_SUCCESS)
66    {
67        err = 1;
68        return;
69    }
70
71    uconv_attribute_t attr;
72    UniQueryUconvObject(objtoucs, &attr, sizeof(attr), NULL, NULL, NULL);
73    attr.converttype &= ~(CVTTYPE_CTRL7F | CVTTYPE_PATH);
74    UniSetUconvObject(objtoucs, &attr);
75
76    rc = UniCreateUconvObject( cpto, &objfromucs );
77    if (rc != ULS_SUCCESS)
78    {
79        UniFreeUconvObject( objtoucs );
80        err = 1;
81        return;
82    }
83    UniQueryUconvObject(objfromucs, &attr, sizeof(uconv_attribute_t), NULL, NULL, NULL);
84    attr.options = UCONV_OPTION_SUBSTITUTE_BOTH;
85    UniSetUconvObject(objfromucs, &attr);
86}
87
88cpconv::cpconv( int cpfrom, int cpto )
89{
90    err = 0;
91
92    UniChar     ucs_code_page[12];
93    size_t      num_elems = 12;
94    int         rc = ULS_SUCCESS;
95
96    rc = UniMapCpToUcsCp(cpfrom, ucs_code_page, num_elems);
97    if (rc != ULS_SUCCESS)
98    {
99        err = 1;
100        return;
101    }
102
103    rc = UniCreateUconvObject(ucs_code_page, &objtoucs);
104    if (rc != ULS_SUCCESS)
105    {
106        err = 1;
107        return;
108    }
109
110    uconv_attribute_t attr;
111    UniQueryUconvObject(objtoucs, &attr, sizeof(attr), NULL, NULL, NULL);
112    attr.converttype &= ~(CVTTYPE_CTRL7F | CVTTYPE_PATH);
113    UniSetUconvObject(objtoucs, &attr);
114
115    rc = UniMapCpToUcsCp(cpto, ucs_code_page, num_elems);
116    if (rc != ULS_SUCCESS)
117    {
118        UniFreeUconvObject( objtoucs );
119        err = 1;
120        return;
121    }
122
123    rc = UniCreateUconvObject(ucs_code_page, &objfromucs);
124    if (rc != ULS_SUCCESS)
125    {
126        UniFreeUconvObject( objtoucs );
127        err = 1;
128        return;
129    }
130    UniQueryUconvObject(objfromucs, &attr, sizeof(uconv_attribute_t), NULL, NULL, NULL);
131    attr.options = UCONV_OPTION_SUBSTITUTE_BOTH;
132    UniSetUconvObject(objfromucs, &attr);
133}
134
135cpconv::~cpconv()
136{
137    if ( !err )
138    {
139        UniFreeUconvObject( objtoucs );
140        UniFreeUconvObject( objfromucs );
141    }
142}
143
144// convert one char
145int cpconv::conv( int chfrom )
146{
147    int rc = ULS_SUCCESS;
148    size_t ns = 0;
149    int chto = 0;
150
151    if ( err )  return chfrom;
152
153    size_t len = 1;
154    UniChar unichar;
155    UniChar *punichar = &unichar;
156    void *pchfrom = &chfrom;
157    void *pchto = &chto;
158
159    rc = UniUconvToUcs( objtoucs, &pchfrom, &len, &punichar, &len, &ns);
160    if ( rc != ULS_SUCCESS )  return chfrom;
161
162    len = 1;
163    punichar = &unichar;
164    ns = 0;
165    rc = UniUconvFromUcs( objfromucs, &punichar, &len, &pchto, &len, &ns);
166    if ( rc != ULS_SUCCESS )  return chfrom;
167
168    return chto;
169}
170
171int cpconv::conv( const char **in, size_t *in_left, char **out, size_t *out_left )
172{
173    int       rc;
174    size_t    sl;
175    size_t    nonid;
176    UniChar  *ucs;
177    UniChar  *orig_ucs;
178    size_t    retval = 0;
179
180    if (!in || !*in) {
181        return 0;
182    }
183
184    sl =  *in_left;
185    //ucs = new UniChar[ sl ];
186    // have crashes in libc memmanager due to frequent alloc/free
187    // use system malloc routines as workaround
188    DosAllocMem( (PPVOID)&ucs, sl * sizeof( UniChar ), fALLOC );
189    orig_ucs = ucs;
190
191    rc = UniUconvToUcs( objtoucs, (void **)in, in_left, &ucs, &sl, &retval );
192    if ( rc != 0 ) {
193        //delete ucs;
194        DosFreeMem( ucs );
195        err = 1;
196        return -1;
197    }
198
199    sl = ucs - orig_ucs;
200    ucs = orig_ucs;
201    rc = UniUconvFromUcs( objfromucs, &ucs, &sl, (void **)out, out_left, &nonid );
202    //delete ucs;
203    DosFreeMem( ucs );
204
205    if ( rc != 0 ) {
206        err = 1;
207        return -1;
208    }
209
210    retval += nonid;
211    return 0;
212}
213
214extern "C" LONG APIENTRY cnvUniToUTF8( const char **in, unsigned *in_left,
215                                       char **out, unsigned *out_left )
216{
217    cpconv c( 1200, 1208 );
218    return c.conv( in, in_left, out, out_left );
219}
220
221extern "C" LONG APIENTRY cnvUniBEToUTF8( const char **in, unsigned *in_left,
222                                         char **out, unsigned *out_left )
223{
224    cpconv c( (UniChar *)(L"UCS-2@endian=big"), (UniChar *)(L"UTF-8") );
225    return c.conv( in, in_left, out, out_left );
226}
227
228extern "C" LONG APIENTRY cnvUTF8ToUni( const char **in, unsigned *in_left,
229                                       char **out, unsigned *out_left )
230{
231    cpconv c( 1208, 1200 );
232    return c.conv( in, in_left, out, out_left );
233}
234
235
236// Converts special non-ascii chars to suitable ascii chars
237static void convSpchars( UniChar *uni )
238{
239    while ( *uni )
240    {
241        switch ( *uni )
242        {
243            case 0x2018:
244            case 0x2019:
245            case 0x2032:
246                *uni = 0x0027;
247                break;
248            case 0x201C:
249            case 0x201D:
250            case 0x00AB:
251            case 0x00BB:
252                *uni = 0x0022;
253                break;
254            case 0x2014:
255                *uni = 0x002D;
256                break;
257        }
258        *uni++;
259    }
260}
261
262
263extern "C" LONG APIENTRY cnvUTF8ToSys( const char **in, unsigned *in_left,
264                                       char **out, unsigned *out_left )
265{
266    unsigned ulen = ( (*in_left) * 2 ) + 2;
267    char *uni = new char[ ulen ];
268    memset( uni, 0, ulen );
269    char *savuni = uni;
270    unsigned savulen = ulen;
271    cnvUTF8ToUni( in, in_left, &uni, &ulen );
272    uni = savuni;
273    ulen = savulen;
274    convSpchars( (UniChar *)uni );
275    cpconv c( 1200 );
276    LONG rc = c.conv( (const char **)&uni, &ulen, out, out_left );
277    uni = savuni;
278    delete uni;
279    return rc;
280}
281
282extern "C" LONG APIENTRY cnvUniBEToSys( const char **in, unsigned *in_left,
283                                         char **out, unsigned *out_left )
284{
285    unsigned ulen = ( (*in_left) * 2 ) + 2;
286    char *uni = new char[ ulen ];
287    memset( uni, 0, ulen );
288    char *savuni = uni;
289    unsigned savulen = ulen;
290    cpconv c1( (UniChar *)(L"UCS-2@endian=big"), (UniChar *)(L"UCS-2") );
291    c1.conv( in, in_left, &uni, &ulen );
292    uni = savuni;
293    ulen = savulen;
294    convSpchars( (UniChar *)uni );
295    cpconv c2( 1200 );
296    LONG rc = c2.conv( (const char **)&uni, &ulen, out, out_left );
297    uni = savuni;
298    delete uni;
299    return rc;
300}
301
302extern "C" LONG APIENTRY cnvUniToSys( const char **in, unsigned *in_left,
303                                      char **out, unsigned *out_left )
304{
305    convSpchars( (UniChar *)in );
306    cpconv c( 1200 );
307    return c.conv( (const char **)&in, in_left, out, out_left );
308}
309
310extern "C" LONG APIENTRY cnvSysToUCS2( const char **in, unsigned *in_left,
311                                       char **out, unsigned *out_left )
312{
313    cpconv c( (UniChar *)(L""), (UniChar *)(L"UCS-2") );
314    return c.conv( in, in_left, out, out_left );
315}
316
317
318// test
319/*void main()
320{
321    const char *testutf8 = "test UTF-8  ’¥áâ! à®¢¥àª !";
322    char buf[ 100 ];
323    memset( buf, 0, sizeof( buf ) );
324    char *bufsav = buf;
325    char *buf1 = buf;
326    unsigned in_len = strlen( testutf8 );
327    unsigned out_len = sizeof( buf );
328
329    cnvUTF8ToUCS4( &testutf8, &in_len, &buf1, &out_len );
330
331    for ( int i = 0; i<100; i++ )
332    {
333        printf( ":%d:", (int)bufsav[i] );
334    }
335    printf( "\n" );
336}
337*/
Note: See TracBrowser for help on using the repository browser.