1 : /******************************************************************************
2 : * $Id: trstring.cpp 16785 2009-04-17 10:07:28Z chaitanya $
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 : #include "gmlreaderp.h"
34 : #include "cpl_vsi.h"
35 : #include "cpl_conv.h"
36 : #include "cpl_string.h"
37 :
38 : /************************************************************************/
39 : /* tr_isascii() */
40 : /************************************************************************/
41 :
42 79780 : static int tr_isascii( const char * pszCString )
43 :
44 : {
45 890352 : while( *pszCString != '\0' )
46 : {
47 730792 : if( *((unsigned char *) pszCString) > 127 )
48 0 : return FALSE;
49 :
50 730792 : pszCString++;
51 : }
52 :
53 79780 : return TRUE;
54 : }
55 :
56 : /************************************************************************/
57 : /* tr_strcmp() */
58 : /************************************************************************/
59 :
60 0 : int tr_strcmp( const char *pszCString, const XMLCh *panXMLString )
61 :
62 : {
63 0 : int i = 0;
64 :
65 : /* -------------------------------------------------------------------- */
66 : /* Fast (ASCII) comparison case. */
67 : /* -------------------------------------------------------------------- */
68 0 : if( tr_isascii( pszCString ) )
69 : {
70 0 : while( pszCString[i] != 0 && panXMLString[i] != 0
71 : && pszCString[i] == panXMLString[i] ) {}
72 :
73 0 : if( pszCString[i] == 0 && panXMLString[i] == 0 )
74 0 : return 0;
75 0 : else if( pszCString[i] < panXMLString[i] )
76 0 : return -1;
77 : else
78 0 : return 1;
79 : }
80 :
81 : /* -------------------------------------------------------------------- */
82 : /* Translated UTF8 to XMLCh for comparison. */
83 : /* -------------------------------------------------------------------- */
84 0 : XMLCh *panFirst = (XMLCh *) CPLCalloc(strlen(pszCString)+1,sizeof(XMLCh));
85 :
86 0 : tr_strcpy( panFirst, pszCString );
87 :
88 0 : while( panFirst[i] != 0 && panXMLString[i] != 0
89 : && panFirst[i] == panXMLString[i] ) {}
90 :
91 0 : if( panFirst[i] == 0 && panXMLString[i] == 0 )
92 : {
93 0 : CPLFree( panFirst );
94 0 : return 0;
95 : }
96 0 : else if( panFirst[i] < panXMLString[i] )
97 : {
98 0 : CPLFree( panFirst );
99 0 : return -1;
100 : }
101 : else
102 : {
103 0 : CPLFree( panFirst );
104 0 : return 1;
105 : }
106 : }
107 :
108 : /************************************************************************/
109 : /* tr_strcpy(const char*,const XMLCh*) */
110 : /************************************************************************/
111 :
112 79780 : void tr_strcpy( XMLCh *panXMLString, const char *pszCString )
113 :
114 : {
115 : /* -------------------------------------------------------------------- */
116 : /* Simple (ASCII) case. */
117 : /* -------------------------------------------------------------------- */
118 79780 : if( tr_isascii( pszCString ) )
119 : {
120 890352 : while( *pszCString != 0 )
121 730792 : *(panXMLString++) = *(pszCString++);
122 79780 : *panXMLString = 0;
123 79780 : return;
124 : }
125 :
126 : /* -------------------------------------------------------------------- */
127 : /* Otherwise we need to do a full UTC2 to UTF-8 conversion. */
128 : /* -------------------------------------------------------------------- */
129 : int i;
130 : wchar_t *pwszUTF16;
131 :
132 0 : pwszUTF16 = CPLRecodeToWChar( pszCString, CPL_ENC_UTF8, CPL_ENC_UTF16 );
133 :
134 0 : for( i = 0; pwszUTF16[i] != 0; i++ )
135 0 : panXMLString[i] = pwszUTF16[i];
136 :
137 0 : panXMLString[i] = 0;
138 :
139 0 : CPLFree( pwszUTF16 );
140 : }
141 :
142 : /************************************************************************/
143 : /* tr_strcpy(const XMLCh*,const char*) */
144 : /************************************************************************/
145 :
146 5611207 : void tr_strcpy( char *pszCString, const XMLCh *panXMLString )
147 :
148 : {
149 5611207 : int bSimpleASCII = TRUE;
150 5611207 : const XMLCh *panXMLStringOriginal = panXMLString;
151 5611207 : char *pszCStringOriginal = pszCString;
152 :
153 51086906 : while( *panXMLString != 0 )
154 : {
155 39864492 : if( *panXMLString > 127 )
156 425 : bSimpleASCII = FALSE;
157 :
158 39864492 : *(pszCString++) = (char) *(panXMLString++);
159 : }
160 5611207 : *pszCString = 0;
161 :
162 5611207 : if( bSimpleASCII )
163 5610824 : return;
164 :
165 383 : panXMLString = panXMLStringOriginal;
166 383 : pszCString = pszCStringOriginal;
167 :
168 : /* -------------------------------------------------------------------- */
169 : /* The simple translation was wrong, because the source is not */
170 : /* all simple ASCII characters. Redo using the more expensive */
171 : /* recoding API. */
172 : /* -------------------------------------------------------------------- */
173 : int i;
174 : wchar_t *pwszSource = (wchar_t *) CPLCalloc(sizeof(wchar_t),
175 383 : tr_strlen(panXMLStringOriginal)+1 );
176 5817 : for( i = 0; panXMLString[i] != 0; i++ )
177 5434 : pwszSource[i] = panXMLString[i];
178 383 : pwszSource[i] = 0;
179 :
180 : char *pszResult = CPLRecodeFromWChar( pwszSource,
181 383 : CPL_ENC_UTF16, CPL_ENC_UTF8 );
182 :
183 383 : strcpy( pszCString, pszResult );
184 :
185 383 : CPLFree( pwszSource );
186 383 : CPLFree( pszResult );
187 : }
188 :
189 : /************************************************************************/
190 : /* tr_strlen() */
191 : /************************************************************************/
192 :
193 3447544 : int tr_strlen( const XMLCh *panXMLString )
194 :
195 : {
196 3447544 : int nLength = 0;
197 :
198 27419254 : while( *(panXMLString++) != 0 )
199 20524166 : nLength++;
200 :
201 3447544 : return nLength;
202 : }
203 :
204 : /************************************************************************/
205 : /* tr_strdup() */
206 : /************************************************************************/
207 :
208 81327 : char *tr_strdup( const XMLCh *panXMLString )
209 :
210 : {
211 : /* -------------------------------------------------------------------- */
212 : /* Compute maximum length. */
213 : /* -------------------------------------------------------------------- */
214 81327 : int i, nMaxLen = 1;
215 :
216 1070331 : for( i = 0; panXMLString[i] != 0; i++ )
217 : {
218 989004 : if( panXMLString[i] < 128 )
219 988579 : nMaxLen++;
220 425 : else if( panXMLString[i] < 0x7ff )
221 425 : nMaxLen += 2;
222 : else
223 0 : nMaxLen += 4;
224 : }
225 :
226 : /* -------------------------------------------------------------------- */
227 : /* Do the translation. */
228 : /* -------------------------------------------------------------------- */
229 81327 : char *pszResult = (char *) CPLMalloc(nMaxLen);
230 81327 : tr_strcpy( pszResult, panXMLString );
231 81327 : return pszResult;
232 : }
|