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

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

fixed crash on copying large block of text to clipboard

File size: 9.0 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#include <os2.h>
36
37#include <string.h>
38#include <malloc.h>
39#include <stdio.h>
40
41#include <uconv.h>
42
43
44class cpconv
45{
46    protected:
47        int  err;
48        void *objtoucs;
49        void *objfromucs;
50    public:
51        cpconv( int cpfrom, int cpto = 0 );
52        cpconv( UniChar *cpfrom, UniChar *cpto );
53        ~cpconv();
54        int conv( int chfrom );
55        int conv( const char **in, size_t *in_left, char **out, size_t *out_left );
56};
57
58cpconv::cpconv( UniChar *cpfrom, UniChar *cpto )
59{
60    err = 0;
61    int         rc = ULS_SUCCESS;
62
63    rc = UniCreateUconvObject( cpfrom, &objtoucs );
64    if (rc != ULS_SUCCESS)
65    {
66        err = 1;
67        return;
68    }
69
70    uconv_attribute_t attr;
71    UniQueryUconvObject(objtoucs, &attr, sizeof(attr), NULL, NULL, NULL);
72    attr.converttype &= ~(CVTTYPE_CTRL7F | CVTTYPE_PATH);
73    UniSetUconvObject(objtoucs, &attr);
74
75    rc = UniCreateUconvObject( cpto, &objfromucs );
76    if (rc != ULS_SUCCESS)
77    {
78        UniFreeUconvObject( objtoucs );
79        err = 1;
80        return;
81    }
82    UniQueryUconvObject(objfromucs, &attr, sizeof(uconv_attribute_t), NULL, NULL, NULL);
83    attr.options = UCONV_OPTION_SUBSTITUTE_BOTH;
84    UniSetUconvObject(objfromucs, &attr);
85}
86
87cpconv::cpconv( int cpfrom, int cpto )
88{
89    err = 0;
90
91    UniChar     ucs_code_page[12];
92    size_t      num_elems = 12;
93    int         rc = ULS_SUCCESS;
94
95    rc = UniMapCpToUcsCp(cpfrom, ucs_code_page, num_elems);
96    if (rc != ULS_SUCCESS)
97    {
98        err = 1;
99        return;
100    }
101
102    rc = UniCreateUconvObject(ucs_code_page, &objtoucs);
103    if (rc != ULS_SUCCESS)
104    {
105        err = 1;
106        return;
107    }
108
109    uconv_attribute_t attr;
110    UniQueryUconvObject(objtoucs, &attr, sizeof(attr), NULL, NULL, NULL);
111    attr.converttype &= ~(CVTTYPE_CTRL7F | CVTTYPE_PATH);
112    UniSetUconvObject(objtoucs, &attr);
113
114    rc = UniMapCpToUcsCp(cpto, ucs_code_page, num_elems);
115    if (rc != ULS_SUCCESS)
116    {
117        UniFreeUconvObject( objtoucs );
118        err = 1;
119        return;
120    }
121
122    rc = UniCreateUconvObject(ucs_code_page, &objfromucs);
123    if (rc != ULS_SUCCESS)
124    {
125        UniFreeUconvObject( objtoucs );
126        err = 1;
127        return;
128    }
129    UniQueryUconvObject(objfromucs, &attr, sizeof(uconv_attribute_t), NULL, NULL, NULL);
130    attr.options = UCONV_OPTION_SUBSTITUTE_BOTH;
131    UniSetUconvObject(objfromucs, &attr);
132}
133
134cpconv::~cpconv()
135{
136    if ( !err )
137    {
138        UniFreeUconvObject( objtoucs );
139        UniFreeUconvObject( objfromucs );
140    }
141}
142
143// convert one char
144int cpconv::conv( int chfrom )
145{
146    int rc = ULS_SUCCESS;
147    size_t ns = 0;
148    int chto = 0;
149
150    if ( err )  return chfrom;
151
152    size_t len = 1;
153    UniChar unichar;
154    UniChar *punichar = &unichar;
155    void *pchfrom = &chfrom;
156    void *pchto = &chto;
157
158    rc = UniUconvToUcs( objtoucs, &pchfrom, &len, &punichar, &len, &ns);
159    if ( rc != ULS_SUCCESS )  return chfrom;
160
161    len = 1;
162    punichar = &unichar;
163    ns = 0;
164    rc = UniUconvFromUcs( objfromucs, &punichar, &len, &pchto, &len, &ns);
165    if ( rc != ULS_SUCCESS )  return chfrom;
166
167    return chto;
168}
169
170int cpconv::conv( const char **in, size_t *in_left, char **out, size_t *out_left )
171{
172    int       rc;
173    size_t    sl;
174    size_t    nonid;
175    UniChar  *ucs;
176    UniChar  *orig_ucs;
177    size_t    retval = 0;
178
179    if (!in || !*in) {
180        return 0;
181    }
182
183    sl =  *in_left;
184    ucs = new UniChar[ sl ];
185    orig_ucs = ucs;
186
187    rc = UniUconvToUcs( objtoucs, (void **)in, in_left, &ucs, &sl, &retval );
188    if ( rc != 0 ) {
189        delete ucs;
190        err = 1;
191        return -1;
192    }
193
194    sl = ucs - orig_ucs;
195    ucs = orig_ucs;
196    rc = UniUconvFromUcs( objfromucs, &ucs, &sl, (void **)out, out_left, &nonid );
197    delete ucs;
198
199    if ( rc != 0 ) {
200        err = 1;
201        return -1;
202    }
203
204    retval += nonid;
205    return 0;
206}
207
208extern "C" LONG APIENTRY cnvUniToUTF8( const char **in, unsigned *in_left,
209                                       char **out, unsigned *out_left )
210{
211    cpconv c( 1200, 1208 );
212    return c.conv( in, in_left, out, out_left );
213}
214
215extern "C" LONG APIENTRY cnvUniBEToUTF8( const char **in, unsigned *in_left,
216                                         char **out, unsigned *out_left )
217{
218    cpconv c( (UniChar *)(L"UCS-2@endian=big"), (UniChar *)(L"UTF-8") );
219    return c.conv( in, in_left, out, out_left );
220}
221
222extern "C" LONG APIENTRY cnvUTF8ToUni( const char **in, unsigned *in_left,
223                                       char **out, unsigned *out_left )
224{
225    cpconv c( 1208, 1200 );
226    return c.conv( in, in_left, out, out_left );
227}
228
229
230// Converts special non-ascii chars to suitable ascii chars
231static void convSpchars( UniChar *uni )
232{
233    while ( *uni )
234    {
235        switch ( *uni )
236        {
237            case 0x2018:
238            case 0x2019:
239            case 0x2032:
240                *uni = 0x0027;
241                break;
242            case 0x201C:
243            case 0x201D:
244            case 0x00AB:
245            case 0x00BB:
246                *uni = 0x0022;
247                break;
248            case 0x2014:
249                *uni = 0x002D;
250                break;
251        }
252        *uni++;
253    }
254}
255
256
257extern "C" LONG APIENTRY cnvUTF8ToSys( const char **in, unsigned *in_left,
258                                       char **out, unsigned *out_left )
259{
260    unsigned ulen = ( (*in_left) * 2 ) + 2;
261    char *uni = new char[ ulen ];
262    memset( uni, 0, ulen );
263    char *savuni = uni;
264    unsigned savulen = ulen;
265    cnvUTF8ToUni( in, in_left, &uni, &ulen );
266    uni = savuni;
267    ulen = savulen;
268    convSpchars( (UniChar *)uni );
269    cpconv c( 1200 );
270    LONG rc = c.conv( (const char **)&uni, &ulen, out, out_left );
271    uni = savuni;
272    delete uni;
273    return rc;
274}
275
276extern "C" LONG APIENTRY cnvUniBEToSys( const char **in, unsigned *in_left,
277                                         char **out, unsigned *out_left )
278{
279    unsigned ulen = ( (*in_left) * 2 ) + 2;
280    char *uni = new char[ ulen ];
281    memset( uni, 0, ulen );
282    char *savuni = uni;
283    unsigned savulen = ulen;
284    cpconv c1( (UniChar *)(L"UCS-2@endian=big"), (UniChar *)(L"UCS-2") );
285    c1.conv( in, in_left, &uni, &ulen );
286    uni = savuni;
287    ulen = savulen;
288    convSpchars( (UniChar *)uni );
289    cpconv c2( 1200 );
290    LONG rc = c2.conv( (const char **)&uni, &ulen, out, out_left );
291    uni = savuni;
292    delete uni;
293    return rc;
294}
295
296extern "C" LONG APIENTRY cnvUniToSys( const char **in, unsigned *in_left,
297                                      char **out, unsigned *out_left )
298{
299    convSpchars( (UniChar *)in );
300    cpconv c( 1200 );
301    return c.conv( (const char **)&in, in_left, out, out_left );
302}
303
304extern "C" LONG APIENTRY cnvSysToUCS2( const char **in, unsigned *in_left,
305                                       char **out, unsigned *out_left )
306{
307    cpconv c( (UniChar *)(L""), (UniChar *)(L"UCS-2") );
308    return c.conv( in, in_left, out, out_left );
309}
310
311
312// test
313/*void main()
314{
315    const char *testutf8 = "test UTF-8  ’¥áâ! à®¢¥àª !";
316    char buf[ 100 ];
317    memset( buf, 0, sizeof( buf ) );
318    char *bufsav = buf;
319    char *buf1 = buf;
320    unsigned in_len = strlen( testutf8 );
321    unsigned out_len = sizeof( buf );
322
323    cnvUTF8ToUCS4( &testutf8, &in_len, &buf1, &out_len );
324
325    for ( int i = 0; i<100; i++ )
326    {
327        printf( ":%d:", (int)bufsav[i] );
328    }
329    printf( "\n" );
330}
331*/
Note: See TracBrowser for help on using the repository browser.