1 : /******************************************************************************
2 : * $Id: trstring.cpp 22205 2011-04-18 21:17:30Z rouault $
3 : *
4 : * Project: GML Reader
5 : * Purpose: Functions for translating back and forth between XMLCh and char.
6 : * We assume that XMLCh is a simple numeric type that we can
7 : * correspond 1:1 with char values, but that it likely is larger
8 : * than a char.
9 : * Author: Frank Warmerdam, warmerdam@pobox.com
10 : *
11 : ******************************************************************************
12 : * Copyright (c) 2002, Frank Warmerdam
13 : *
14 : * Permission is hereby granted, free of charge, to any person obtaining a
15 : * copy of this software and associated documentation files (the "Software"),
16 : * to deal in the Software without restriction, including without limitation
17 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 : * and/or sell copies of the Software, and to permit persons to whom the
19 : * Software is furnished to do so, subject to the following conditions:
20 : *
21 : * The above copyright notice and this permission notice shall be included
22 : * in all copies or substantial portions of the Software.
23 : *
24 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 : * DEALINGS IN THE SOFTWARE.
31 : ****************************************************************************/
32 :
33 : #ifdef HAVE_XERCES
34 :
35 : #include "gmlreaderp.h"
36 : #include "cpl_vsi.h"
37 : #include "cpl_conv.h"
38 : #include "cpl_string.h"
39 :
40 : /************************************************************************/
41 : /* tr_isascii() */
42 : /************************************************************************/
43 :
44 47323 : static int tr_isascii( const char * pszCString )
45 :
46 : {
47 532890 : while( *pszCString != '\0' )
48 : {
49 438244 : if( *((unsigned char *) pszCString) > 127 )
50 0 : return FALSE;
51 :
52 438244 : pszCString++;
53 : }
54 :
55 47323 : return TRUE;
56 : }
57 :
58 : /************************************************************************/
59 : /* tr_strcmp() */
60 : /************************************************************************/
61 :
62 0 : int tr_strcmp( const char *pszCString, const XMLCh *panXMLString )
63 :
64 : {
65 0 : int i = 0;
66 :
67 : /* -------------------------------------------------------------------- */
68 : /* Fast (ASCII) comparison case. */
69 : /* -------------------------------------------------------------------- */
70 0 : if( tr_isascii( pszCString ) )
71 : {
72 0 : while( pszCString[i] != 0 && panXMLString[i] != 0
73 0 : && pszCString[i] == panXMLString[i] ) {}
74 :
75 0 : if( pszCString[i] == 0 && panXMLString[i] == 0 )
76 0 : return 0;
77 0 : else if( pszCString[i] < panXMLString[i] )
78 0 : return -1;
79 : else
80 0 : return 1;
81 : }
82 :
83 : /* -------------------------------------------------------------------- */
84 : /* Translated UTF8 to XMLCh for comparison. */
85 : /* -------------------------------------------------------------------- */
86 0 : XMLCh *panFirst = (XMLCh *) CPLCalloc(strlen(pszCString)+1,sizeof(XMLCh));
87 :
88 0 : tr_strcpy( panFirst, pszCString );
89 :
90 0 : while( panFirst[i] != 0 && panXMLString[i] != 0
91 0 : && panFirst[i] == panXMLString[i] ) {}
92 :
93 0 : if( panFirst[i] == 0 && panXMLString[i] == 0 )
94 : {
95 0 : CPLFree( panFirst );
96 0 : return 0;
97 : }
98 0 : else if( panFirst[i] < panXMLString[i] )
99 : {
100 0 : CPLFree( panFirst );
101 0 : return -1;
102 : }
103 : else
104 : {
105 0 : CPLFree( panFirst );
106 0 : return 1;
107 : }
108 : }
109 :
110 : /************************************************************************/
111 : /* tr_strcpy(const char*,const XMLCh*) */
112 : /************************************************************************/
113 :
114 47323 : void tr_strcpy( XMLCh *panXMLString, const char *pszCString )
115 :
116 : {
117 : /* -------------------------------------------------------------------- */
118 : /* Simple (ASCII) case. */
119 : /* -------------------------------------------------------------------- */
120 47323 : if( tr_isascii( pszCString ) )
121 : {
122 532890 : while( *pszCString != 0 )
123 438244 : *(panXMLString++) = *(pszCString++);
124 47323 : *panXMLString = 0;
125 47323 : return;
126 : }
127 :
128 : /* -------------------------------------------------------------------- */
129 : /* Otherwise we need to do a full UTC2 to UTF-8 conversion. */
130 : /* -------------------------------------------------------------------- */
131 : int i;
132 : wchar_t *pwszUTF16;
133 :
134 0 : pwszUTF16 = CPLRecodeToWChar( pszCString, CPL_ENC_UTF8, "WCHAR_T" );
135 :
136 0 : for( i = 0; pwszUTF16[i] != 0; i++ )
137 0 : panXMLString[i] = pwszUTF16[i];
138 :
139 0 : panXMLString[i] = 0;
140 :
141 0 : CPLFree( pwszUTF16 );
142 : }
143 :
144 : /************************************************************************/
145 : /* tr_strcpy(const XMLCh*,const char*) */
146 : /************************************************************************/
147 :
148 6330020 : void tr_strcpy( char *pszCString, const XMLCh *panXMLString )
149 :
150 : {
151 6330020 : int bSimpleASCII = TRUE;
152 6330020 : const XMLCh *panXMLStringOriginal = panXMLString;
153 6330020 : char *pszCStringOriginal = pszCString;
154 :
155 88775098 : while( *panXMLString != 0 )
156 : {
157 76115058 : if( *panXMLString > 127 )
158 213 : bSimpleASCII = FALSE;
159 :
160 76115058 : *(pszCString++) = (char) *(panXMLString++);
161 : }
162 6330020 : *pszCString = 0;
163 :
164 6330020 : if( bSimpleASCII )
165 6329828 : return;
166 :
167 192 : panXMLString = panXMLStringOriginal;
168 192 : pszCString = pszCStringOriginal;
169 :
170 : /* -------------------------------------------------------------------- */
171 : /* The simple translation was wrong, because the source is not */
172 : /* all simple ASCII characters. Redo using the more expensive */
173 : /* recoding API. */
174 : /* -------------------------------------------------------------------- */
175 : int i;
176 : wchar_t *pwszSource = (wchar_t *) CPLCalloc(sizeof(wchar_t),
177 192 : tr_strlen(panXMLStringOriginal)+1 );
178 2916 : for( i = 0; panXMLString[i] != 0; i++ )
179 2724 : pwszSource[i] = panXMLString[i];
180 192 : pwszSource[i] = 0;
181 :
182 : char *pszResult = CPLRecodeFromWChar( pwszSource,
183 192 : "WCHAR_T", CPL_ENC_UTF8 );
184 :
185 192 : strcpy( pszCString, pszResult );
186 :
187 192 : CPLFree( pwszSource );
188 192 : CPLFree( pszResult );
189 : }
190 :
191 : /************************************************************************/
192 : /* tr_strlen() */
193 : /************************************************************************/
194 :
195 1792484 : int tr_strlen( const XMLCh *panXMLString )
196 :
197 : {
198 1792484 : int nLength = 0;
199 :
200 31451230 : while( *(panXMLString++) != 0 )
201 27866262 : nLength++;
202 :
203 1792484 : return nLength;
204 : }
205 :
206 : /************************************************************************/
207 : /* tr_strdup() */
208 : /************************************************************************/
209 :
210 67121 : char *tr_strdup( const XMLCh *panXMLString )
211 :
212 : {
213 : /* -------------------------------------------------------------------- */
214 : /* Compute maximum length. */
215 : /* -------------------------------------------------------------------- */
216 67121 : int i, nMaxLen = 1;
217 :
218 905517 : for( i = 0; panXMLString[i] != 0; i++ )
219 : {
220 838396 : if( panXMLString[i] < 128 )
221 838183 : nMaxLen++;
222 213 : else if( panXMLString[i] < 0x7ff )
223 213 : nMaxLen += 2;
224 : else
225 0 : nMaxLen += 4;
226 : }
227 :
228 : /* -------------------------------------------------------------------- */
229 : /* Do the translation. */
230 : /* -------------------------------------------------------------------- */
231 67121 : char *pszResult = (char *) CPLMalloc(nMaxLen);
232 67121 : tr_strcpy( pszResult, panXMLString );
233 67121 : return pszResult;
234 : }
235 :
236 : #endif // HAVE_XERCES
|