1*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
2*fd1fabb7SAndroid Build Coastguard Worker // Copyright 2006-2007 Adobe Systems Incorporated
3*fd1fabb7SAndroid Build Coastguard Worker // All Rights Reserved.
4*fd1fabb7SAndroid Build Coastguard Worker //
5*fd1fabb7SAndroid Build Coastguard Worker // NOTICE: Adobe permits you to use, modify, and distribute this file in
6*fd1fabb7SAndroid Build Coastguard Worker // accordance with the terms of the Adobe license agreement accompanying it.
7*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
8*fd1fabb7SAndroid Build Coastguard Worker
9*fd1fabb7SAndroid Build Coastguard Worker /* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_string.cpp#2 $ */
10*fd1fabb7SAndroid Build Coastguard Worker /* $DateTime: 2012/07/31 22:04:34 $ */
11*fd1fabb7SAndroid Build Coastguard Worker /* $Change: 840853 $ */
12*fd1fabb7SAndroid Build Coastguard Worker /* $Author: tknoll $ */
13*fd1fabb7SAndroid Build Coastguard Worker
14*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
15*fd1fabb7SAndroid Build Coastguard Worker
16*fd1fabb7SAndroid Build Coastguard Worker #include "dng_string.h"
17*fd1fabb7SAndroid Build Coastguard Worker
18*fd1fabb7SAndroid Build Coastguard Worker #include "dng_assertions.h"
19*fd1fabb7SAndroid Build Coastguard Worker #include "dng_exceptions.h"
20*fd1fabb7SAndroid Build Coastguard Worker #include "dng_flags.h"
21*fd1fabb7SAndroid Build Coastguard Worker #include "dng_mutex.h"
22*fd1fabb7SAndroid Build Coastguard Worker #include "dng_utils.h"
23*fd1fabb7SAndroid Build Coastguard Worker #include "dng_safe_arithmetic.h"
24*fd1fabb7SAndroid Build Coastguard Worker
25*fd1fabb7SAndroid Build Coastguard Worker #if qMacOS
26*fd1fabb7SAndroid Build Coastguard Worker #include <TargetConditionals.h>
27*fd1fabb7SAndroid Build Coastguard Worker #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
28*fd1fabb7SAndroid Build Coastguard Worker #include <MobileCoreServices/MobileCoreServices.h>
29*fd1fabb7SAndroid Build Coastguard Worker #else
30*fd1fabb7SAndroid Build Coastguard Worker #include <CoreServices/CoreServices.h>
31*fd1fabb7SAndroid Build Coastguard Worker #endif // TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
32*fd1fabb7SAndroid Build Coastguard Worker #endif // qMacOS
33*fd1fabb7SAndroid Build Coastguard Worker
34*fd1fabb7SAndroid Build Coastguard Worker #if qWinOS
35*fd1fabb7SAndroid Build Coastguard Worker #include <windows.h>
36*fd1fabb7SAndroid Build Coastguard Worker #endif
37*fd1fabb7SAndroid Build Coastguard Worker
38*fd1fabb7SAndroid Build Coastguard Worker #if qiPhone || qAndroid || qLinux
39*fd1fabb7SAndroid Build Coastguard Worker #include <ctype.h> // for isdigit
40*fd1fabb7SAndroid Build Coastguard Worker #endif
41*fd1fabb7SAndroid Build Coastguard Worker
42*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
43*fd1fabb7SAndroid Build Coastguard Worker
44*fd1fabb7SAndroid Build Coastguard Worker const uint32 kREPLACEMENT_CHARACTER = 0x0000FFFD;
45*fd1fabb7SAndroid Build Coastguard Worker
46*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
47*fd1fabb7SAndroid Build Coastguard Worker
48*fd1fabb7SAndroid Build Coastguard Worker // Returns the length of the zero-terminated string 's'. Throws a dng_exception
49*fd1fabb7SAndroid Build Coastguard Worker // if the length of 's' is too large to be represented as a uint32_t.
strlenAsUint32(const char * s)50*fd1fabb7SAndroid Build Coastguard Worker static uint32 strlenAsUint32(const char *s)
51*fd1fabb7SAndroid Build Coastguard Worker {
52*fd1fabb7SAndroid Build Coastguard Worker
53*fd1fabb7SAndroid Build Coastguard Worker uint32 lengthAsUint32 = 0;
54*fd1fabb7SAndroid Build Coastguard Worker ConvertUnsigned(strlen(s), &lengthAsUint32);
55*fd1fabb7SAndroid Build Coastguard Worker
56*fd1fabb7SAndroid Build Coastguard Worker return lengthAsUint32;
57*fd1fabb7SAndroid Build Coastguard Worker
58*fd1fabb7SAndroid Build Coastguard Worker }
59*fd1fabb7SAndroid Build Coastguard Worker
60*fd1fabb7SAndroid Build Coastguard Worker // Checks whether there is enough space left in the buffer pointed to by
61*fd1fabb7SAndroid Build Coastguard Worker // 'currentPos' to write at least 'space' elements of type T (to positions
62*fd1fabb7SAndroid Build Coastguard Worker // currentPos[0] through currentPos[space - 1]. Throws a dng_exception if there
63*fd1fabb7SAndroid Build Coastguard Worker // is not enough space left in the buffer.
64*fd1fabb7SAndroid Build Coastguard Worker // 'bufferEnd' should point one element beyond the end of the buffer. For
65*fd1fabb7SAndroid Build Coastguard Worker // example, if the buffer is "T buffer[3];", then bufferEnd should point to
66*fd1fabb7SAndroid Build Coastguard Worker // T + 3.
67*fd1fabb7SAndroid Build Coastguard Worker template <class T>
CheckSpaceLeftInBuffer(const T * currentPos,const T * bufferEnd,size_t space)68*fd1fabb7SAndroid Build Coastguard Worker static void CheckSpaceLeftInBuffer(const T *currentPos,
69*fd1fabb7SAndroid Build Coastguard Worker const T *bufferEnd,
70*fd1fabb7SAndroid Build Coastguard Worker size_t space)
71*fd1fabb7SAndroid Build Coastguard Worker {
72*fd1fabb7SAndroid Build Coastguard Worker
73*fd1fabb7SAndroid Build Coastguard Worker if (bufferEnd < currentPos || static_cast<size_t>(bufferEnd - currentPos) < space)
74*fd1fabb7SAndroid Build Coastguard Worker {
75*fd1fabb7SAndroid Build Coastguard Worker ThrowMemoryFull ("Buffer overrun");
76*fd1fabb7SAndroid Build Coastguard Worker }
77*fd1fabb7SAndroid Build Coastguard Worker
78*fd1fabb7SAndroid Build Coastguard Worker }
79*fd1fabb7SAndroid Build Coastguard Worker
80*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
81*fd1fabb7SAndroid Build Coastguard Worker
82*fd1fabb7SAndroid Build Coastguard Worker // Throws an exception to notify the user of code that has not been security
83*fd1fabb7SAndroid Build Coastguard Worker // hardened and prevent execution of that code.
84*fd1fabb7SAndroid Build Coastguard Worker //
85*fd1fabb7SAndroid Build Coastguard Worker // Though the DNG SDK in general has been security-hardened, this does not apply
86*fd1fabb7SAndroid Build Coastguard Worker // to the following Mac-OS- and Windows-specific functions. Calls to
87*fd1fabb7SAndroid Build Coastguard Worker // ThrowNotHardened() have been added to these functions to alert callers of
88*fd1fabb7SAndroid Build Coastguard Worker // this fact.
89*fd1fabb7SAndroid Build Coastguard Worker //
90*fd1fabb7SAndroid Build Coastguard Worker // If you're trying to use a function that calls ThrowNotHardened(), you need to
91*fd1fabb7SAndroid Build Coastguard Worker // fix the security issues noted in the comment next to the ThrowNotHardened()
92*fd1fabb7SAndroid Build Coastguard Worker // call. Once you have fixed these issues, obtain a security review for the
93*fd1fabb7SAndroid Build Coastguard Worker // fixes. This may require fuzzing of the modified code on the target platform.
ThrowNotHardened()94*fd1fabb7SAndroid Build Coastguard Worker static void ThrowNotHardened()
95*fd1fabb7SAndroid Build Coastguard Worker {
96*fd1fabb7SAndroid Build Coastguard Worker ThrowProgramError ("This function has not been security-hardened");
97*fd1fabb7SAndroid Build Coastguard Worker }
98*fd1fabb7SAndroid Build Coastguard Worker
99*fd1fabb7SAndroid Build Coastguard Worker #if qMacOS
100*fd1fabb7SAndroid Build Coastguard Worker #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
101*fd1fabb7SAndroid Build Coastguard Worker
Extract_SystemEncoding(const dng_string & dngString,dng_memory_data & buffer)102*fd1fabb7SAndroid Build Coastguard Worker static uint32 Extract_SystemEncoding (const dng_string &dngString,
103*fd1fabb7SAndroid Build Coastguard Worker dng_memory_data &buffer)
104*fd1fabb7SAndroid Build Coastguard Worker {
105*fd1fabb7SAndroid Build Coastguard Worker // TODO: Needs implementation.
106*fd1fabb7SAndroid Build Coastguard Worker ThrowProgramError ("Extract_SystemEncoding() not implemented on iOS");
107*fd1fabb7SAndroid Build Coastguard Worker return 0;
108*fd1fabb7SAndroid Build Coastguard Worker }
109*fd1fabb7SAndroid Build Coastguard Worker
Assign_SystemEncoding(dng_string & dngString,const char * otherString)110*fd1fabb7SAndroid Build Coastguard Worker static void Assign_SystemEncoding (dng_string &dngString,
111*fd1fabb7SAndroid Build Coastguard Worker const char *otherString)
112*fd1fabb7SAndroid Build Coastguard Worker {
113*fd1fabb7SAndroid Build Coastguard Worker // TODO: Needs implementation.
114*fd1fabb7SAndroid Build Coastguard Worker ThrowProgramError ("Assign_SystemEncoding() not implemented on iOS");
115*fd1fabb7SAndroid Build Coastguard Worker
116*fd1fabb7SAndroid Build Coastguard Worker }
117*fd1fabb7SAndroid Build Coastguard Worker
Assign_JIS_X208_1990(dng_string & dngString,const char * otherString)118*fd1fabb7SAndroid Build Coastguard Worker static void Assign_JIS_X208_1990 (dng_string &dngString,
119*fd1fabb7SAndroid Build Coastguard Worker const char *otherString)
120*fd1fabb7SAndroid Build Coastguard Worker {
121*fd1fabb7SAndroid Build Coastguard Worker // TODO: Needs implementation.
122*fd1fabb7SAndroid Build Coastguard Worker ThrowProgramError ("Assign_JIS_X208_1990() not implemented on iOS");
123*fd1fabb7SAndroid Build Coastguard Worker }
124*fd1fabb7SAndroid Build Coastguard Worker
125*fd1fabb7SAndroid Build Coastguard Worker #else
126*fd1fabb7SAndroid Build Coastguard Worker
Assign_Multibyte(dng_string & dngString,const char * otherString,TextEncoding encoding)127*fd1fabb7SAndroid Build Coastguard Worker static void Assign_Multibyte (dng_string &dngString,
128*fd1fabb7SAndroid Build Coastguard Worker const char *otherString,
129*fd1fabb7SAndroid Build Coastguard Worker TextEncoding encoding)
130*fd1fabb7SAndroid Build Coastguard Worker {
131*fd1fabb7SAndroid Build Coastguard Worker
132*fd1fabb7SAndroid Build Coastguard Worker // This function contains security-vulnerable code. Do not use.
133*fd1fabb7SAndroid Build Coastguard Worker // The particular vulnerabilities are:
134*fd1fabb7SAndroid Build Coastguard Worker // - Casting the result of strlen() to a uint32 may case truncation. (Use
135*fd1fabb7SAndroid Build Coastguard Worker // strlenAsUint32() instead.)
136*fd1fabb7SAndroid Build Coastguard Worker // - The computation of aBufSize and the subsequent addition of 1 in the
137*fd1fabb7SAndroid Build Coastguard Worker // call to the dng_memory_data constructor may wrap around.
138*fd1fabb7SAndroid Build Coastguard Worker ThrowNotHardened();
139*fd1fabb7SAndroid Build Coastguard Worker
140*fd1fabb7SAndroid Build Coastguard Worker uint32 aSize = (uint32) strlen (otherString);
141*fd1fabb7SAndroid Build Coastguard Worker
142*fd1fabb7SAndroid Build Coastguard Worker if (aSize > 0)
143*fd1fabb7SAndroid Build Coastguard Worker {
144*fd1fabb7SAndroid Build Coastguard Worker
145*fd1fabb7SAndroid Build Coastguard Worker uint32 aBufSize = aSize * 6 + 256;
146*fd1fabb7SAndroid Build Coastguard Worker
147*fd1fabb7SAndroid Build Coastguard Worker dng_memory_data aBuf (aBufSize + 1);
148*fd1fabb7SAndroid Build Coastguard Worker
149*fd1fabb7SAndroid Build Coastguard Worker UnicodeMapping aMapping;
150*fd1fabb7SAndroid Build Coastguard Worker
151*fd1fabb7SAndroid Build Coastguard Worker aMapping.unicodeEncoding = ::CreateTextEncoding (kTextEncodingUnicodeV3_0,
152*fd1fabb7SAndroid Build Coastguard Worker kUnicodeNoSubset,
153*fd1fabb7SAndroid Build Coastguard Worker kUnicodeUTF8Format);
154*fd1fabb7SAndroid Build Coastguard Worker
155*fd1fabb7SAndroid Build Coastguard Worker aMapping.otherEncoding = encoding;
156*fd1fabb7SAndroid Build Coastguard Worker aMapping.mappingVersion = kUnicodeUseLatestMapping;
157*fd1fabb7SAndroid Build Coastguard Worker
158*fd1fabb7SAndroid Build Coastguard Worker TextToUnicodeInfo aInfo = NULL;
159*fd1fabb7SAndroid Build Coastguard Worker
160*fd1fabb7SAndroid Build Coastguard Worker if (::CreateTextToUnicodeInfo (&aMapping, &aInfo) == noErr)
161*fd1fabb7SAndroid Build Coastguard Worker {
162*fd1fabb7SAndroid Build Coastguard Worker
163*fd1fabb7SAndroid Build Coastguard Worker ByteCount aInput = 0;
164*fd1fabb7SAndroid Build Coastguard Worker ByteCount aOutput = 0;
165*fd1fabb7SAndroid Build Coastguard Worker
166*fd1fabb7SAndroid Build Coastguard Worker ::ConvertFromTextToUnicode (aInfo,
167*fd1fabb7SAndroid Build Coastguard Worker aSize,
168*fd1fabb7SAndroid Build Coastguard Worker otherString,
169*fd1fabb7SAndroid Build Coastguard Worker kUnicodeUseFallbacksMask |
170*fd1fabb7SAndroid Build Coastguard Worker kUnicodeLooseMappingsMask,
171*fd1fabb7SAndroid Build Coastguard Worker 0,
172*fd1fabb7SAndroid Build Coastguard Worker NULL,
173*fd1fabb7SAndroid Build Coastguard Worker NULL,
174*fd1fabb7SAndroid Build Coastguard Worker NULL,
175*fd1fabb7SAndroid Build Coastguard Worker aBufSize,
176*fd1fabb7SAndroid Build Coastguard Worker &aInput,
177*fd1fabb7SAndroid Build Coastguard Worker &aOutput,
178*fd1fabb7SAndroid Build Coastguard Worker (UniChar *) aBuf.Buffer ());
179*fd1fabb7SAndroid Build Coastguard Worker
180*fd1fabb7SAndroid Build Coastguard Worker ::DisposeTextToUnicodeInfo (&aInfo);
181*fd1fabb7SAndroid Build Coastguard Worker
182*fd1fabb7SAndroid Build Coastguard Worker if (aOutput > 0 && aOutput <= aBufSize)
183*fd1fabb7SAndroid Build Coastguard Worker {
184*fd1fabb7SAndroid Build Coastguard Worker
185*fd1fabb7SAndroid Build Coastguard Worker char *aBufChar = aBuf.Buffer_char ();
186*fd1fabb7SAndroid Build Coastguard Worker
187*fd1fabb7SAndroid Build Coastguard Worker aBufChar [aOutput] = 0;
188*fd1fabb7SAndroid Build Coastguard Worker
189*fd1fabb7SAndroid Build Coastguard Worker dngString.Set (aBufChar);
190*fd1fabb7SAndroid Build Coastguard Worker
191*fd1fabb7SAndroid Build Coastguard Worker return;
192*fd1fabb7SAndroid Build Coastguard Worker
193*fd1fabb7SAndroid Build Coastguard Worker }
194*fd1fabb7SAndroid Build Coastguard Worker
195*fd1fabb7SAndroid Build Coastguard Worker }
196*fd1fabb7SAndroid Build Coastguard Worker
197*fd1fabb7SAndroid Build Coastguard Worker }
198*fd1fabb7SAndroid Build Coastguard Worker
199*fd1fabb7SAndroid Build Coastguard Worker dngString.Clear ();
200*fd1fabb7SAndroid Build Coastguard Worker
201*fd1fabb7SAndroid Build Coastguard Worker }
202*fd1fabb7SAndroid Build Coastguard Worker
Extract_Multibyte(const dng_string & dngString,dng_memory_data & buffer,TextEncoding encoding)203*fd1fabb7SAndroid Build Coastguard Worker static uint32 Extract_Multibyte (const dng_string &dngString,
204*fd1fabb7SAndroid Build Coastguard Worker dng_memory_data &buffer,
205*fd1fabb7SAndroid Build Coastguard Worker TextEncoding encoding)
206*fd1fabb7SAndroid Build Coastguard Worker {
207*fd1fabb7SAndroid Build Coastguard Worker
208*fd1fabb7SAndroid Build Coastguard Worker // This function contains security-vulnerable code. Do not use.
209*fd1fabb7SAndroid Build Coastguard Worker // The particular vulnerabilities are:
210*fd1fabb7SAndroid Build Coastguard Worker // - The computation of aBufSize may wrap around.
211*fd1fabb7SAndroid Build Coastguard Worker // - The computation of the argument to buffer.Allocate() may overflow; the
212*fd1fabb7SAndroid Build Coastguard Worker // conversion to uint32 is also problematic.
213*fd1fabb7SAndroid Build Coastguard Worker // - The signed-to-unsigned conversion in the return statement "
214*fd1fabb7SAndroid Build Coastguard Worker // return (uint32) aOutput;" may be problematic.
215*fd1fabb7SAndroid Build Coastguard Worker ThrowNotHardened();
216*fd1fabb7SAndroid Build Coastguard Worker
217*fd1fabb7SAndroid Build Coastguard Worker uint32 aSize = dngString.Length ();
218*fd1fabb7SAndroid Build Coastguard Worker
219*fd1fabb7SAndroid Build Coastguard Worker if (aSize > 0)
220*fd1fabb7SAndroid Build Coastguard Worker {
221*fd1fabb7SAndroid Build Coastguard Worker
222*fd1fabb7SAndroid Build Coastguard Worker uint32 aBufSize = (aSize * 2) + 256;
223*fd1fabb7SAndroid Build Coastguard Worker
224*fd1fabb7SAndroid Build Coastguard Worker dng_memory_data tempBuffer (aBufSize);
225*fd1fabb7SAndroid Build Coastguard Worker
226*fd1fabb7SAndroid Build Coastguard Worker UnicodeMapping aMapping;
227*fd1fabb7SAndroid Build Coastguard Worker
228*fd1fabb7SAndroid Build Coastguard Worker aMapping.unicodeEncoding = ::CreateTextEncoding (kTextEncodingUnicodeV3_0,
229*fd1fabb7SAndroid Build Coastguard Worker kUnicodeNoSubset,
230*fd1fabb7SAndroid Build Coastguard Worker kUnicodeUTF8Format);
231*fd1fabb7SAndroid Build Coastguard Worker
232*fd1fabb7SAndroid Build Coastguard Worker aMapping.otherEncoding = encoding;
233*fd1fabb7SAndroid Build Coastguard Worker aMapping.mappingVersion = kUnicodeUseLatestMapping;
234*fd1fabb7SAndroid Build Coastguard Worker
235*fd1fabb7SAndroid Build Coastguard Worker UnicodeToTextInfo aInfo = NULL;
236*fd1fabb7SAndroid Build Coastguard Worker
237*fd1fabb7SAndroid Build Coastguard Worker if (::CreateUnicodeToTextInfo (&aMapping, &aInfo) == noErr)
238*fd1fabb7SAndroid Build Coastguard Worker {
239*fd1fabb7SAndroid Build Coastguard Worker
240*fd1fabb7SAndroid Build Coastguard Worker ByteCount aInput = 0;
241*fd1fabb7SAndroid Build Coastguard Worker ByteCount aOutput = 0;
242*fd1fabb7SAndroid Build Coastguard Worker
243*fd1fabb7SAndroid Build Coastguard Worker ::ConvertFromUnicodeToText (aInfo,
244*fd1fabb7SAndroid Build Coastguard Worker aSize,
245*fd1fabb7SAndroid Build Coastguard Worker (const UniChar *) dngString.Get (),
246*fd1fabb7SAndroid Build Coastguard Worker kUnicodeUseFallbacksMask |
247*fd1fabb7SAndroid Build Coastguard Worker kUnicodeLooseMappingsMask |
248*fd1fabb7SAndroid Build Coastguard Worker kUnicodeDefaultDirectionMask,
249*fd1fabb7SAndroid Build Coastguard Worker 0,
250*fd1fabb7SAndroid Build Coastguard Worker NULL,
251*fd1fabb7SAndroid Build Coastguard Worker NULL,
252*fd1fabb7SAndroid Build Coastguard Worker NULL,
253*fd1fabb7SAndroid Build Coastguard Worker aBufSize,
254*fd1fabb7SAndroid Build Coastguard Worker &aInput,
255*fd1fabb7SAndroid Build Coastguard Worker &aOutput,
256*fd1fabb7SAndroid Build Coastguard Worker tempBuffer.Buffer_char ());
257*fd1fabb7SAndroid Build Coastguard Worker
258*fd1fabb7SAndroid Build Coastguard Worker ::DisposeUnicodeToTextInfo (&aInfo);
259*fd1fabb7SAndroid Build Coastguard Worker
260*fd1fabb7SAndroid Build Coastguard Worker if (aOutput > 0)
261*fd1fabb7SAndroid Build Coastguard Worker {
262*fd1fabb7SAndroid Build Coastguard Worker
263*fd1fabb7SAndroid Build Coastguard Worker buffer.Allocate ((uint32) (aOutput + 1));
264*fd1fabb7SAndroid Build Coastguard Worker
265*fd1fabb7SAndroid Build Coastguard Worker memcpy (buffer.Buffer (),
266*fd1fabb7SAndroid Build Coastguard Worker tempBuffer.Buffer (),
267*fd1fabb7SAndroid Build Coastguard Worker aOutput);
268*fd1fabb7SAndroid Build Coastguard Worker
269*fd1fabb7SAndroid Build Coastguard Worker buffer.Buffer_char () [aOutput] = 0;
270*fd1fabb7SAndroid Build Coastguard Worker
271*fd1fabb7SAndroid Build Coastguard Worker return (uint32) aOutput;
272*fd1fabb7SAndroid Build Coastguard Worker
273*fd1fabb7SAndroid Build Coastguard Worker }
274*fd1fabb7SAndroid Build Coastguard Worker
275*fd1fabb7SAndroid Build Coastguard Worker }
276*fd1fabb7SAndroid Build Coastguard Worker
277*fd1fabb7SAndroid Build Coastguard Worker }
278*fd1fabb7SAndroid Build Coastguard Worker
279*fd1fabb7SAndroid Build Coastguard Worker buffer.Allocate (1);
280*fd1fabb7SAndroid Build Coastguard Worker
281*fd1fabb7SAndroid Build Coastguard Worker buffer.Buffer_char () [0] = 0;
282*fd1fabb7SAndroid Build Coastguard Worker
283*fd1fabb7SAndroid Build Coastguard Worker return 0;
284*fd1fabb7SAndroid Build Coastguard Worker
285*fd1fabb7SAndroid Build Coastguard Worker }
286*fd1fabb7SAndroid Build Coastguard Worker
Assign_SystemEncoding(dng_string & dngString,const char * otherString)287*fd1fabb7SAndroid Build Coastguard Worker static void Assign_SystemEncoding (dng_string &dngString,
288*fd1fabb7SAndroid Build Coastguard Worker const char *otherString)
289*fd1fabb7SAndroid Build Coastguard Worker {
290*fd1fabb7SAndroid Build Coastguard Worker
291*fd1fabb7SAndroid Build Coastguard Worker TextEncoding aEncoding;
292*fd1fabb7SAndroid Build Coastguard Worker
293*fd1fabb7SAndroid Build Coastguard Worker ::UpgradeScriptInfoToTextEncoding (smSystemScript,
294*fd1fabb7SAndroid Build Coastguard Worker kTextLanguageDontCare,
295*fd1fabb7SAndroid Build Coastguard Worker kTextRegionDontCare,
296*fd1fabb7SAndroid Build Coastguard Worker NULL,
297*fd1fabb7SAndroid Build Coastguard Worker &aEncoding);
298*fd1fabb7SAndroid Build Coastguard Worker
299*fd1fabb7SAndroid Build Coastguard Worker Assign_Multibyte (dngString,
300*fd1fabb7SAndroid Build Coastguard Worker otherString,
301*fd1fabb7SAndroid Build Coastguard Worker aEncoding);
302*fd1fabb7SAndroid Build Coastguard Worker
303*fd1fabb7SAndroid Build Coastguard Worker }
304*fd1fabb7SAndroid Build Coastguard Worker
Extract_SystemEncoding(const dng_string & dngString,dng_memory_data & buffer)305*fd1fabb7SAndroid Build Coastguard Worker static uint32 Extract_SystemEncoding (const dng_string &dngString,
306*fd1fabb7SAndroid Build Coastguard Worker dng_memory_data &buffer)
307*fd1fabb7SAndroid Build Coastguard Worker {
308*fd1fabb7SAndroid Build Coastguard Worker
309*fd1fabb7SAndroid Build Coastguard Worker TextEncoding aEncoding;
310*fd1fabb7SAndroid Build Coastguard Worker
311*fd1fabb7SAndroid Build Coastguard Worker ::UpgradeScriptInfoToTextEncoding (smSystemScript,
312*fd1fabb7SAndroid Build Coastguard Worker kTextLanguageDontCare,
313*fd1fabb7SAndroid Build Coastguard Worker kTextRegionDontCare,
314*fd1fabb7SAndroid Build Coastguard Worker NULL,
315*fd1fabb7SAndroid Build Coastguard Worker &aEncoding);
316*fd1fabb7SAndroid Build Coastguard Worker
317*fd1fabb7SAndroid Build Coastguard Worker return Extract_Multibyte (dngString,
318*fd1fabb7SAndroid Build Coastguard Worker buffer,
319*fd1fabb7SAndroid Build Coastguard Worker aEncoding);
320*fd1fabb7SAndroid Build Coastguard Worker
321*fd1fabb7SAndroid Build Coastguard Worker }
322*fd1fabb7SAndroid Build Coastguard Worker
Assign_JIS_X208_1990(dng_string & dngString,const char * otherString)323*fd1fabb7SAndroid Build Coastguard Worker static void Assign_JIS_X208_1990 (dng_string &dngString,
324*fd1fabb7SAndroid Build Coastguard Worker const char *otherString)
325*fd1fabb7SAndroid Build Coastguard Worker {
326*fd1fabb7SAndroid Build Coastguard Worker
327*fd1fabb7SAndroid Build Coastguard Worker Assign_Multibyte (dngString,
328*fd1fabb7SAndroid Build Coastguard Worker otherString,
329*fd1fabb7SAndroid Build Coastguard Worker kTextEncodingJIS_X0208_90);
330*fd1fabb7SAndroid Build Coastguard Worker
331*fd1fabb7SAndroid Build Coastguard Worker }
332*fd1fabb7SAndroid Build Coastguard Worker
333*fd1fabb7SAndroid Build Coastguard Worker #endif // TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
334*fd1fabb7SAndroid Build Coastguard Worker #endif // qMacOS
335*fd1fabb7SAndroid Build Coastguard Worker
336*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
337*fd1fabb7SAndroid Build Coastguard Worker
338*fd1fabb7SAndroid Build Coastguard Worker #if qWinOS
339*fd1fabb7SAndroid Build Coastguard Worker
Assign_Multibyte(dng_string & dngString,const char * otherString,UINT encoding)340*fd1fabb7SAndroid Build Coastguard Worker static void Assign_Multibyte (dng_string &dngString,
341*fd1fabb7SAndroid Build Coastguard Worker const char *otherString,
342*fd1fabb7SAndroid Build Coastguard Worker UINT encoding)
343*fd1fabb7SAndroid Build Coastguard Worker {
344*fd1fabb7SAndroid Build Coastguard Worker
345*fd1fabb7SAndroid Build Coastguard Worker // This function contains security-vulnerable code. Do not use.
346*fd1fabb7SAndroid Build Coastguard Worker // The particular vulnerabilities are:
347*fd1fabb7SAndroid Build Coastguard Worker // - Converting the return value of strlen() to int may cause overflow.
348*fd1fabb7SAndroid Build Coastguard Worker // - The computation of aBufChars and of the argument to the dng_memory_data
349*fd1fabb7SAndroid Build Coastguard Worker // constructor may overflow. Additionally, there is an implicit
350*fd1fabb7SAndroid Build Coastguard Worker // signed-to-unsigned conversion in the call to the dng_memory_data
351*fd1fabb7SAndroid Build Coastguard Worker // constructor.
352*fd1fabb7SAndroid Build Coastguard Worker ThrowNotHardened();
353*fd1fabb7SAndroid Build Coastguard Worker
354*fd1fabb7SAndroid Build Coastguard Worker DNG_ASSERT (sizeof (WCHAR) == 2, "WCHAR must be 2 bytes");
355*fd1fabb7SAndroid Build Coastguard Worker
356*fd1fabb7SAndroid Build Coastguard Worker int aSize = (int) strlen (otherString);
357*fd1fabb7SAndroid Build Coastguard Worker
358*fd1fabb7SAndroid Build Coastguard Worker if (aSize > 0)
359*fd1fabb7SAndroid Build Coastguard Worker {
360*fd1fabb7SAndroid Build Coastguard Worker
361*fd1fabb7SAndroid Build Coastguard Worker int aBufChars = aSize * 3 + 128;
362*fd1fabb7SAndroid Build Coastguard Worker
363*fd1fabb7SAndroid Build Coastguard Worker dng_memory_data aBuf ((aBufChars + 1) << 1);
364*fd1fabb7SAndroid Build Coastguard Worker
365*fd1fabb7SAndroid Build Coastguard Worker int aResult = ::MultiByteToWideChar (encoding,
366*fd1fabb7SAndroid Build Coastguard Worker 0,
367*fd1fabb7SAndroid Build Coastguard Worker otherString,
368*fd1fabb7SAndroid Build Coastguard Worker aSize,
369*fd1fabb7SAndroid Build Coastguard Worker (WCHAR *) aBuf.Buffer (),
370*fd1fabb7SAndroid Build Coastguard Worker aBufChars);
371*fd1fabb7SAndroid Build Coastguard Worker
372*fd1fabb7SAndroid Build Coastguard Worker if (aResult > 0 && aResult <= aBufChars)
373*fd1fabb7SAndroid Build Coastguard Worker {
374*fd1fabb7SAndroid Build Coastguard Worker
375*fd1fabb7SAndroid Build Coastguard Worker uint16 * aUTF16 = aBuf.Buffer_uint16 ();
376*fd1fabb7SAndroid Build Coastguard Worker
377*fd1fabb7SAndroid Build Coastguard Worker aUTF16 [aResult] = 0;
378*fd1fabb7SAndroid Build Coastguard Worker
379*fd1fabb7SAndroid Build Coastguard Worker dngString.Set_UTF16 (aUTF16);
380*fd1fabb7SAndroid Build Coastguard Worker
381*fd1fabb7SAndroid Build Coastguard Worker return;
382*fd1fabb7SAndroid Build Coastguard Worker
383*fd1fabb7SAndroid Build Coastguard Worker }
384*fd1fabb7SAndroid Build Coastguard Worker
385*fd1fabb7SAndroid Build Coastguard Worker }
386*fd1fabb7SAndroid Build Coastguard Worker
387*fd1fabb7SAndroid Build Coastguard Worker dngString.Clear ();
388*fd1fabb7SAndroid Build Coastguard Worker
389*fd1fabb7SAndroid Build Coastguard Worker }
390*fd1fabb7SAndroid Build Coastguard Worker
Extract_Multibyte(const dng_string & dngString,dng_memory_data & buffer,UINT encoding)391*fd1fabb7SAndroid Build Coastguard Worker static uint32 Extract_Multibyte (const dng_string &dngString,
392*fd1fabb7SAndroid Build Coastguard Worker dng_memory_data &buffer,
393*fd1fabb7SAndroid Build Coastguard Worker UINT encoding)
394*fd1fabb7SAndroid Build Coastguard Worker {
395*fd1fabb7SAndroid Build Coastguard Worker
396*fd1fabb7SAndroid Build Coastguard Worker // This function contains security-vulnerable code. Do not use.
397*fd1fabb7SAndroid Build Coastguard Worker // The particular vulnerabilities are:
398*fd1fabb7SAndroid Build Coastguard Worker // - Converting the return value of dngString.Get_UTF16() may cause
399*fd1fabb7SAndroid Build Coastguard Worker // overflow.
400*fd1fabb7SAndroid Build Coastguard Worker // - The computation of dBufSize may overflow.
401*fd1fabb7SAndroid Build Coastguard Worker // - The calls to the dng_memory_data constructor and to buffer.Allocate()
402*fd1fabb7SAndroid Build Coastguard Worker // trigger implicit conversions of int to uint32 that may be problematic.
403*fd1fabb7SAndroid Build Coastguard Worker // - The memcpy() call triggers an implicit conversion of aResult to a
404*fd1fabb7SAndroid Build Coastguard Worker // size_t, which may be problematic.
405*fd1fabb7SAndroid Build Coastguard Worker // - The conversion of aResult to a uint32 in the return statement may be
406*fd1fabb7SAndroid Build Coastguard Worker // problematic.
407*fd1fabb7SAndroid Build Coastguard Worker ThrowNotHardened();
408*fd1fabb7SAndroid Build Coastguard Worker
409*fd1fabb7SAndroid Build Coastguard Worker DNG_ASSERT (sizeof (WCHAR) == 2, "WCHAR must be 2 bytes");
410*fd1fabb7SAndroid Build Coastguard Worker
411*fd1fabb7SAndroid Build Coastguard Worker dng_memory_data sBuffer;
412*fd1fabb7SAndroid Build Coastguard Worker
413*fd1fabb7SAndroid Build Coastguard Worker int aCount = dngString.Get_UTF16 (sBuffer);
414*fd1fabb7SAndroid Build Coastguard Worker
415*fd1fabb7SAndroid Build Coastguard Worker int dBufSize = aCount * 2 + 256;
416*fd1fabb7SAndroid Build Coastguard Worker
417*fd1fabb7SAndroid Build Coastguard Worker dng_memory_data dBuffer (dBufSize);
418*fd1fabb7SAndroid Build Coastguard Worker
419*fd1fabb7SAndroid Build Coastguard Worker int aResult = ::WideCharToMultiByte (encoding,
420*fd1fabb7SAndroid Build Coastguard Worker 0,
421*fd1fabb7SAndroid Build Coastguard Worker (WCHAR *) sBuffer.Buffer (),
422*fd1fabb7SAndroid Build Coastguard Worker aCount,
423*fd1fabb7SAndroid Build Coastguard Worker dBuffer.Buffer_char (),
424*fd1fabb7SAndroid Build Coastguard Worker dBufSize,
425*fd1fabb7SAndroid Build Coastguard Worker NULL,
426*fd1fabb7SAndroid Build Coastguard Worker NULL);
427*fd1fabb7SAndroid Build Coastguard Worker
428*fd1fabb7SAndroid Build Coastguard Worker if (aResult < 0)
429*fd1fabb7SAndroid Build Coastguard Worker aResult = 0;
430*fd1fabb7SAndroid Build Coastguard Worker
431*fd1fabb7SAndroid Build Coastguard Worker buffer.Allocate (aResult + 1);
432*fd1fabb7SAndroid Build Coastguard Worker
433*fd1fabb7SAndroid Build Coastguard Worker memcpy (buffer.Buffer (),
434*fd1fabb7SAndroid Build Coastguard Worker dBuffer.Buffer (),
435*fd1fabb7SAndroid Build Coastguard Worker aResult);
436*fd1fabb7SAndroid Build Coastguard Worker
437*fd1fabb7SAndroid Build Coastguard Worker buffer.Buffer_char () [aResult] = 0;
438*fd1fabb7SAndroid Build Coastguard Worker
439*fd1fabb7SAndroid Build Coastguard Worker return (uint32) aResult;
440*fd1fabb7SAndroid Build Coastguard Worker
441*fd1fabb7SAndroid Build Coastguard Worker }
442*fd1fabb7SAndroid Build Coastguard Worker
Assign_SystemEncoding(dng_string & dngString,const char * otherString)443*fd1fabb7SAndroid Build Coastguard Worker static void Assign_SystemEncoding (dng_string &dngString,
444*fd1fabb7SAndroid Build Coastguard Worker const char *otherString)
445*fd1fabb7SAndroid Build Coastguard Worker {
446*fd1fabb7SAndroid Build Coastguard Worker
447*fd1fabb7SAndroid Build Coastguard Worker Assign_Multibyte (dngString,
448*fd1fabb7SAndroid Build Coastguard Worker otherString,
449*fd1fabb7SAndroid Build Coastguard Worker ::GetACP ());
450*fd1fabb7SAndroid Build Coastguard Worker
451*fd1fabb7SAndroid Build Coastguard Worker }
452*fd1fabb7SAndroid Build Coastguard Worker
Extract_SystemEncoding(const dng_string & dngString,dng_memory_data & buffer)453*fd1fabb7SAndroid Build Coastguard Worker static uint32 Extract_SystemEncoding (const dng_string &dngString,
454*fd1fabb7SAndroid Build Coastguard Worker dng_memory_data &buffer)
455*fd1fabb7SAndroid Build Coastguard Worker {
456*fd1fabb7SAndroid Build Coastguard Worker
457*fd1fabb7SAndroid Build Coastguard Worker return Extract_Multibyte (dngString,
458*fd1fabb7SAndroid Build Coastguard Worker buffer,
459*fd1fabb7SAndroid Build Coastguard Worker ::GetACP ());
460*fd1fabb7SAndroid Build Coastguard Worker
461*fd1fabb7SAndroid Build Coastguard Worker }
462*fd1fabb7SAndroid Build Coastguard Worker
Assign_JIS_X208_1990(dng_string & dngString,const char * otherString)463*fd1fabb7SAndroid Build Coastguard Worker static void Assign_JIS_X208_1990 (dng_string &dngString,
464*fd1fabb7SAndroid Build Coastguard Worker const char *otherString)
465*fd1fabb7SAndroid Build Coastguard Worker {
466*fd1fabb7SAndroid Build Coastguard Worker
467*fd1fabb7SAndroid Build Coastguard Worker // From MSDN documentation: 20932 = JIS X 0208-1990 & 0121-1990
468*fd1fabb7SAndroid Build Coastguard Worker
469*fd1fabb7SAndroid Build Coastguard Worker const UINT kJIS = 20932;
470*fd1fabb7SAndroid Build Coastguard Worker
471*fd1fabb7SAndroid Build Coastguard Worker Assign_Multibyte (dngString,
472*fd1fabb7SAndroid Build Coastguard Worker otherString,
473*fd1fabb7SAndroid Build Coastguard Worker kJIS);
474*fd1fabb7SAndroid Build Coastguard Worker
475*fd1fabb7SAndroid Build Coastguard Worker }
476*fd1fabb7SAndroid Build Coastguard Worker
477*fd1fabb7SAndroid Build Coastguard Worker #endif
478*fd1fabb7SAndroid Build Coastguard Worker
479*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
480*fd1fabb7SAndroid Build Coastguard Worker
IsASCII(const char * s)481*fd1fabb7SAndroid Build Coastguard Worker static bool IsASCII (const char *s)
482*fd1fabb7SAndroid Build Coastguard Worker {
483*fd1fabb7SAndroid Build Coastguard Worker
484*fd1fabb7SAndroid Build Coastguard Worker if (!s)
485*fd1fabb7SAndroid Build Coastguard Worker {
486*fd1fabb7SAndroid Build Coastguard Worker
487*fd1fabb7SAndroid Build Coastguard Worker return true;
488*fd1fabb7SAndroid Build Coastguard Worker
489*fd1fabb7SAndroid Build Coastguard Worker }
490*fd1fabb7SAndroid Build Coastguard Worker
491*fd1fabb7SAndroid Build Coastguard Worker while (true)
492*fd1fabb7SAndroid Build Coastguard Worker {
493*fd1fabb7SAndroid Build Coastguard Worker
494*fd1fabb7SAndroid Build Coastguard Worker uint8 c = (uint8) *(s++);
495*fd1fabb7SAndroid Build Coastguard Worker
496*fd1fabb7SAndroid Build Coastguard Worker if (c == 0)
497*fd1fabb7SAndroid Build Coastguard Worker {
498*fd1fabb7SAndroid Build Coastguard Worker
499*fd1fabb7SAndroid Build Coastguard Worker break;
500*fd1fabb7SAndroid Build Coastguard Worker
501*fd1fabb7SAndroid Build Coastguard Worker }
502*fd1fabb7SAndroid Build Coastguard Worker
503*fd1fabb7SAndroid Build Coastguard Worker if (c & 0x80)
504*fd1fabb7SAndroid Build Coastguard Worker {
505*fd1fabb7SAndroid Build Coastguard Worker
506*fd1fabb7SAndroid Build Coastguard Worker return false;
507*fd1fabb7SAndroid Build Coastguard Worker
508*fd1fabb7SAndroid Build Coastguard Worker }
509*fd1fabb7SAndroid Build Coastguard Worker
510*fd1fabb7SAndroid Build Coastguard Worker }
511*fd1fabb7SAndroid Build Coastguard Worker
512*fd1fabb7SAndroid Build Coastguard Worker return true;
513*fd1fabb7SAndroid Build Coastguard Worker
514*fd1fabb7SAndroid Build Coastguard Worker }
515*fd1fabb7SAndroid Build Coastguard Worker
516*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
517*fd1fabb7SAndroid Build Coastguard Worker
dng_string()518*fd1fabb7SAndroid Build Coastguard Worker dng_string::dng_string ()
519*fd1fabb7SAndroid Build Coastguard Worker
520*fd1fabb7SAndroid Build Coastguard Worker : fData ()
521*fd1fabb7SAndroid Build Coastguard Worker
522*fd1fabb7SAndroid Build Coastguard Worker {
523*fd1fabb7SAndroid Build Coastguard Worker
524*fd1fabb7SAndroid Build Coastguard Worker }
525*fd1fabb7SAndroid Build Coastguard Worker
526*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
527*fd1fabb7SAndroid Build Coastguard Worker
dng_string(const dng_string & s)528*fd1fabb7SAndroid Build Coastguard Worker dng_string::dng_string (const dng_string &s)
529*fd1fabb7SAndroid Build Coastguard Worker
530*fd1fabb7SAndroid Build Coastguard Worker : fData ()
531*fd1fabb7SAndroid Build Coastguard Worker
532*fd1fabb7SAndroid Build Coastguard Worker {
533*fd1fabb7SAndroid Build Coastguard Worker
534*fd1fabb7SAndroid Build Coastguard Worker Set (s.Get ());
535*fd1fabb7SAndroid Build Coastguard Worker
536*fd1fabb7SAndroid Build Coastguard Worker }
537*fd1fabb7SAndroid Build Coastguard Worker
538*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
539*fd1fabb7SAndroid Build Coastguard Worker
operator =(const dng_string & s)540*fd1fabb7SAndroid Build Coastguard Worker dng_string & dng_string::operator= (const dng_string &s)
541*fd1fabb7SAndroid Build Coastguard Worker {
542*fd1fabb7SAndroid Build Coastguard Worker
543*fd1fabb7SAndroid Build Coastguard Worker if (this != &s)
544*fd1fabb7SAndroid Build Coastguard Worker {
545*fd1fabb7SAndroid Build Coastguard Worker
546*fd1fabb7SAndroid Build Coastguard Worker Set (s.Get ());
547*fd1fabb7SAndroid Build Coastguard Worker
548*fd1fabb7SAndroid Build Coastguard Worker }
549*fd1fabb7SAndroid Build Coastguard Worker
550*fd1fabb7SAndroid Build Coastguard Worker return *this;
551*fd1fabb7SAndroid Build Coastguard Worker
552*fd1fabb7SAndroid Build Coastguard Worker }
553*fd1fabb7SAndroid Build Coastguard Worker
554*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
555*fd1fabb7SAndroid Build Coastguard Worker
~dng_string()556*fd1fabb7SAndroid Build Coastguard Worker dng_string::~dng_string ()
557*fd1fabb7SAndroid Build Coastguard Worker {
558*fd1fabb7SAndroid Build Coastguard Worker
559*fd1fabb7SAndroid Build Coastguard Worker }
560*fd1fabb7SAndroid Build Coastguard Worker
561*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
562*fd1fabb7SAndroid Build Coastguard Worker
Get() const563*fd1fabb7SAndroid Build Coastguard Worker const char * dng_string::Get () const
564*fd1fabb7SAndroid Build Coastguard Worker {
565*fd1fabb7SAndroid Build Coastguard Worker
566*fd1fabb7SAndroid Build Coastguard Worker if (fData.Buffer ())
567*fd1fabb7SAndroid Build Coastguard Worker {
568*fd1fabb7SAndroid Build Coastguard Worker
569*fd1fabb7SAndroid Build Coastguard Worker return fData.Buffer_char ();
570*fd1fabb7SAndroid Build Coastguard Worker
571*fd1fabb7SAndroid Build Coastguard Worker }
572*fd1fabb7SAndroid Build Coastguard Worker
573*fd1fabb7SAndroid Build Coastguard Worker return "";
574*fd1fabb7SAndroid Build Coastguard Worker
575*fd1fabb7SAndroid Build Coastguard Worker }
576*fd1fabb7SAndroid Build Coastguard Worker
577*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
578*fd1fabb7SAndroid Build Coastguard Worker
IsASCII() const579*fd1fabb7SAndroid Build Coastguard Worker bool dng_string::IsASCII () const
580*fd1fabb7SAndroid Build Coastguard Worker {
581*fd1fabb7SAndroid Build Coastguard Worker
582*fd1fabb7SAndroid Build Coastguard Worker return ::IsASCII (Get ());
583*fd1fabb7SAndroid Build Coastguard Worker
584*fd1fabb7SAndroid Build Coastguard Worker }
585*fd1fabb7SAndroid Build Coastguard Worker
586*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
587*fd1fabb7SAndroid Build Coastguard Worker
Set(const char * s)588*fd1fabb7SAndroid Build Coastguard Worker void dng_string::Set (const char *s)
589*fd1fabb7SAndroid Build Coastguard Worker {
590*fd1fabb7SAndroid Build Coastguard Worker
591*fd1fabb7SAndroid Build Coastguard Worker // Measure the new length.
592*fd1fabb7SAndroid Build Coastguard Worker
593*fd1fabb7SAndroid Build Coastguard Worker uint32 newLen = (s != NULL ? strlenAsUint32 (s) : 0);
594*fd1fabb7SAndroid Build Coastguard Worker
595*fd1fabb7SAndroid Build Coastguard Worker // If it is a NULL string, then clear the buffer.
596*fd1fabb7SAndroid Build Coastguard Worker
597*fd1fabb7SAndroid Build Coastguard Worker if (newLen == 0)
598*fd1fabb7SAndroid Build Coastguard Worker {
599*fd1fabb7SAndroid Build Coastguard Worker
600*fd1fabb7SAndroid Build Coastguard Worker fData.Clear ();
601*fd1fabb7SAndroid Build Coastguard Worker
602*fd1fabb7SAndroid Build Coastguard Worker }
603*fd1fabb7SAndroid Build Coastguard Worker
604*fd1fabb7SAndroid Build Coastguard Worker // Else we need to copy the bytes.
605*fd1fabb7SAndroid Build Coastguard Worker
606*fd1fabb7SAndroid Build Coastguard Worker else
607*fd1fabb7SAndroid Build Coastguard Worker {
608*fd1fabb7SAndroid Build Coastguard Worker
609*fd1fabb7SAndroid Build Coastguard Worker uint32 oldLen = Length ();
610*fd1fabb7SAndroid Build Coastguard Worker
611*fd1fabb7SAndroid Build Coastguard Worker // We might be setting this string to a sub-string of itself,
612*fd1fabb7SAndroid Build Coastguard Worker // so don't reallocate the data unless the string is getting
613*fd1fabb7SAndroid Build Coastguard Worker // longer.
614*fd1fabb7SAndroid Build Coastguard Worker
615*fd1fabb7SAndroid Build Coastguard Worker if (newLen > oldLen)
616*fd1fabb7SAndroid Build Coastguard Worker {
617*fd1fabb7SAndroid Build Coastguard Worker
618*fd1fabb7SAndroid Build Coastguard Worker fData.Clear ();
619*fd1fabb7SAndroid Build Coastguard Worker
620*fd1fabb7SAndroid Build Coastguard Worker fData.Allocate (SafeUint32Add (newLen, 1));
621*fd1fabb7SAndroid Build Coastguard Worker
622*fd1fabb7SAndroid Build Coastguard Worker }
623*fd1fabb7SAndroid Build Coastguard Worker
624*fd1fabb7SAndroid Build Coastguard Worker char *d = fData.Buffer_char ();
625*fd1fabb7SAndroid Build Coastguard Worker
626*fd1fabb7SAndroid Build Coastguard Worker for (uint32 k = 0; k <= newLen; k++)
627*fd1fabb7SAndroid Build Coastguard Worker {
628*fd1fabb7SAndroid Build Coastguard Worker
629*fd1fabb7SAndroid Build Coastguard Worker d [k] = s [k];
630*fd1fabb7SAndroid Build Coastguard Worker
631*fd1fabb7SAndroid Build Coastguard Worker }
632*fd1fabb7SAndroid Build Coastguard Worker
633*fd1fabb7SAndroid Build Coastguard Worker }
634*fd1fabb7SAndroid Build Coastguard Worker
635*fd1fabb7SAndroid Build Coastguard Worker }
636*fd1fabb7SAndroid Build Coastguard Worker
637*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
638*fd1fabb7SAndroid Build Coastguard Worker
Set_ASCII(const char * s)639*fd1fabb7SAndroid Build Coastguard Worker void dng_string::Set_ASCII (const char *s)
640*fd1fabb7SAndroid Build Coastguard Worker {
641*fd1fabb7SAndroid Build Coastguard Worker
642*fd1fabb7SAndroid Build Coastguard Worker if (::IsASCII (s))
643*fd1fabb7SAndroid Build Coastguard Worker {
644*fd1fabb7SAndroid Build Coastguard Worker
645*fd1fabb7SAndroid Build Coastguard Worker Set (s);
646*fd1fabb7SAndroid Build Coastguard Worker
647*fd1fabb7SAndroid Build Coastguard Worker }
648*fd1fabb7SAndroid Build Coastguard Worker
649*fd1fabb7SAndroid Build Coastguard Worker else
650*fd1fabb7SAndroid Build Coastguard Worker {
651*fd1fabb7SAndroid Build Coastguard Worker
652*fd1fabb7SAndroid Build Coastguard Worker Set_SystemEncoding (s);
653*fd1fabb7SAndroid Build Coastguard Worker
654*fd1fabb7SAndroid Build Coastguard Worker }
655*fd1fabb7SAndroid Build Coastguard Worker
656*fd1fabb7SAndroid Build Coastguard Worker }
657*fd1fabb7SAndroid Build Coastguard Worker
658*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
659*fd1fabb7SAndroid Build Coastguard Worker
Set_UTF8(const char * s)660*fd1fabb7SAndroid Build Coastguard Worker void dng_string::Set_UTF8 (const char *s)
661*fd1fabb7SAndroid Build Coastguard Worker {
662*fd1fabb7SAndroid Build Coastguard Worker
663*fd1fabb7SAndroid Build Coastguard Worker uint32 len = strlenAsUint32 (s);
664*fd1fabb7SAndroid Build Coastguard Worker
665*fd1fabb7SAndroid Build Coastguard Worker const char *sEnd = s + len;
666*fd1fabb7SAndroid Build Coastguard Worker
667*fd1fabb7SAndroid Build Coastguard Worker // Worst case expansion is 1-byte characters expanding to
668*fd1fabb7SAndroid Build Coastguard Worker // replacement character, which requires 3 bytes.
669*fd1fabb7SAndroid Build Coastguard Worker
670*fd1fabb7SAndroid Build Coastguard Worker const uint32 destBufferLength = SafeUint32Add (SafeUint32Mult (len, 3), 1);
671*fd1fabb7SAndroid Build Coastguard Worker dng_memory_data buffer (destBufferLength);
672*fd1fabb7SAndroid Build Coastguard Worker
673*fd1fabb7SAndroid Build Coastguard Worker uint8 *d = buffer.Buffer_uint8 ();
674*fd1fabb7SAndroid Build Coastguard Worker uint8 * const destEnd = d + destBufferLength;
675*fd1fabb7SAndroid Build Coastguard Worker
676*fd1fabb7SAndroid Build Coastguard Worker while (s < sEnd)
677*fd1fabb7SAndroid Build Coastguard Worker {
678*fd1fabb7SAndroid Build Coastguard Worker
679*fd1fabb7SAndroid Build Coastguard Worker uint32 aChar = DecodeUTF8 (s, (uint32) (sEnd - s));
680*fd1fabb7SAndroid Build Coastguard Worker
681*fd1fabb7SAndroid Build Coastguard Worker if (aChar > 0x7FFFFFFF)
682*fd1fabb7SAndroid Build Coastguard Worker {
683*fd1fabb7SAndroid Build Coastguard Worker aChar = kREPLACEMENT_CHARACTER;
684*fd1fabb7SAndroid Build Coastguard Worker }
685*fd1fabb7SAndroid Build Coastguard Worker
686*fd1fabb7SAndroid Build Coastguard Worker #if qDNGValidate
687*fd1fabb7SAndroid Build Coastguard Worker
688*fd1fabb7SAndroid Build Coastguard Worker if (aChar == kREPLACEMENT_CHARACTER)
689*fd1fabb7SAndroid Build Coastguard Worker {
690*fd1fabb7SAndroid Build Coastguard Worker ReportWarning ("Expected UTF-8 value is not valid UTF-8 (or contains a kREPLACEMENT_CHARACTER)");
691*fd1fabb7SAndroid Build Coastguard Worker }
692*fd1fabb7SAndroid Build Coastguard Worker
693*fd1fabb7SAndroid Build Coastguard Worker #endif
694*fd1fabb7SAndroid Build Coastguard Worker
695*fd1fabb7SAndroid Build Coastguard Worker if (aChar < 0x00000080)
696*fd1fabb7SAndroid Build Coastguard Worker {
697*fd1fabb7SAndroid Build Coastguard Worker CheckSpaceLeftInBuffer (d, destEnd, 1);
698*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) aChar;
699*fd1fabb7SAndroid Build Coastguard Worker }
700*fd1fabb7SAndroid Build Coastguard Worker
701*fd1fabb7SAndroid Build Coastguard Worker else if (aChar < 0x00000800)
702*fd1fabb7SAndroid Build Coastguard Worker {
703*fd1fabb7SAndroid Build Coastguard Worker CheckSpaceLeftInBuffer (d, destEnd, 2);
704*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) ((aChar >> 6) | 0x000000C0);
705*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) ((aChar & 0x0000003F) | 0x00000080);
706*fd1fabb7SAndroid Build Coastguard Worker }
707*fd1fabb7SAndroid Build Coastguard Worker
708*fd1fabb7SAndroid Build Coastguard Worker else if (aChar < 0x00010000)
709*fd1fabb7SAndroid Build Coastguard Worker {
710*fd1fabb7SAndroid Build Coastguard Worker CheckSpaceLeftInBuffer (d, destEnd, 3);
711*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) ( (aChar >> 12) | 0x000000E0);
712*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) (((aChar >> 6) & 0x0000003F) | 0x00000080);
713*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) ( (aChar & 0x0000003F) | 0x00000080);
714*fd1fabb7SAndroid Build Coastguard Worker }
715*fd1fabb7SAndroid Build Coastguard Worker
716*fd1fabb7SAndroid Build Coastguard Worker else if (aChar < 0x00200000)
717*fd1fabb7SAndroid Build Coastguard Worker {
718*fd1fabb7SAndroid Build Coastguard Worker CheckSpaceLeftInBuffer (d, destEnd, 4);
719*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) ( (aChar >> 18) | 0x000000F0);
720*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) (((aChar >> 12) & 0x0000003F) | 0x00000080);
721*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) (((aChar >> 6) & 0x0000003F) | 0x00000080);
722*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) ( (aChar & 0x0000003F) | 0x00000080);
723*fd1fabb7SAndroid Build Coastguard Worker }
724*fd1fabb7SAndroid Build Coastguard Worker
725*fd1fabb7SAndroid Build Coastguard Worker else if (aChar < 0x04000000)
726*fd1fabb7SAndroid Build Coastguard Worker {
727*fd1fabb7SAndroid Build Coastguard Worker CheckSpaceLeftInBuffer (d, destEnd, 5);
728*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) ( (aChar >> 24) | 0x000000F8);
729*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) (((aChar >> 18) & 0x0000003F) | 0x00000080);
730*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) (((aChar >> 12) & 0x0000003F) | 0x00000080);
731*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) (((aChar >> 6) & 0x0000003F) | 0x00000080);
732*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) ( (aChar & 0x0000003F) | 0x00000080);
733*fd1fabb7SAndroid Build Coastguard Worker }
734*fd1fabb7SAndroid Build Coastguard Worker
735*fd1fabb7SAndroid Build Coastguard Worker else
736*fd1fabb7SAndroid Build Coastguard Worker {
737*fd1fabb7SAndroid Build Coastguard Worker CheckSpaceLeftInBuffer (d, destEnd, 6);
738*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) ( (aChar >> 30) | 0x000000FC);
739*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) (((aChar >> 24) & 0x0000003F) | 0x00000080);
740*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) (((aChar >> 18) & 0x0000003F) | 0x00000080);
741*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) (((aChar >> 12) & 0x0000003F) | 0x00000080);
742*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) (((aChar >> 6) & 0x0000003F) | 0x00000080);
743*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) ( (aChar & 0x0000003F) | 0x00000080);
744*fd1fabb7SAndroid Build Coastguard Worker }
745*fd1fabb7SAndroid Build Coastguard Worker
746*fd1fabb7SAndroid Build Coastguard Worker }
747*fd1fabb7SAndroid Build Coastguard Worker
748*fd1fabb7SAndroid Build Coastguard Worker CheckSpaceLeftInBuffer (d, destEnd, 1);
749*fd1fabb7SAndroid Build Coastguard Worker *d = 0;
750*fd1fabb7SAndroid Build Coastguard Worker
751*fd1fabb7SAndroid Build Coastguard Worker Set (buffer.Buffer_char ());
752*fd1fabb7SAndroid Build Coastguard Worker
753*fd1fabb7SAndroid Build Coastguard Worker }
754*fd1fabb7SAndroid Build Coastguard Worker
755*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
756*fd1fabb7SAndroid Build Coastguard Worker
Get_SystemEncoding(dng_memory_data & buffer) const757*fd1fabb7SAndroid Build Coastguard Worker uint32 dng_string::Get_SystemEncoding (dng_memory_data &buffer) const
758*fd1fabb7SAndroid Build Coastguard Worker {
759*fd1fabb7SAndroid Build Coastguard Worker
760*fd1fabb7SAndroid Build Coastguard Worker if (IsASCII ())
761*fd1fabb7SAndroid Build Coastguard Worker {
762*fd1fabb7SAndroid Build Coastguard Worker
763*fd1fabb7SAndroid Build Coastguard Worker uint32 len = Length ();
764*fd1fabb7SAndroid Build Coastguard Worker
765*fd1fabb7SAndroid Build Coastguard Worker const uint32 destBufferLength = SafeUint32Add (len, 1);
766*fd1fabb7SAndroid Build Coastguard Worker buffer.Allocate (destBufferLength);
767*fd1fabb7SAndroid Build Coastguard Worker
768*fd1fabb7SAndroid Build Coastguard Worker memcpy (buffer.Buffer (), Get (), destBufferLength);
769*fd1fabb7SAndroid Build Coastguard Worker
770*fd1fabb7SAndroid Build Coastguard Worker return len;
771*fd1fabb7SAndroid Build Coastguard Worker
772*fd1fabb7SAndroid Build Coastguard Worker }
773*fd1fabb7SAndroid Build Coastguard Worker
774*fd1fabb7SAndroid Build Coastguard Worker else
775*fd1fabb7SAndroid Build Coastguard Worker {
776*fd1fabb7SAndroid Build Coastguard Worker
777*fd1fabb7SAndroid Build Coastguard Worker #if qMacOS || qWinOS
778*fd1fabb7SAndroid Build Coastguard Worker
779*fd1fabb7SAndroid Build Coastguard Worker return Extract_SystemEncoding (*this, buffer);
780*fd1fabb7SAndroid Build Coastguard Worker
781*fd1fabb7SAndroid Build Coastguard Worker #else
782*fd1fabb7SAndroid Build Coastguard Worker
783*fd1fabb7SAndroid Build Coastguard Worker // Fallback logic to force the string to ASCII.
784*fd1fabb7SAndroid Build Coastguard Worker
785*fd1fabb7SAndroid Build Coastguard Worker dng_string temp (*this);
786*fd1fabb7SAndroid Build Coastguard Worker
787*fd1fabb7SAndroid Build Coastguard Worker temp.ForceASCII ();
788*fd1fabb7SAndroid Build Coastguard Worker
789*fd1fabb7SAndroid Build Coastguard Worker return temp.Get_SystemEncoding (buffer);
790*fd1fabb7SAndroid Build Coastguard Worker
791*fd1fabb7SAndroid Build Coastguard Worker #endif
792*fd1fabb7SAndroid Build Coastguard Worker
793*fd1fabb7SAndroid Build Coastguard Worker }
794*fd1fabb7SAndroid Build Coastguard Worker
795*fd1fabb7SAndroid Build Coastguard Worker }
796*fd1fabb7SAndroid Build Coastguard Worker
797*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
798*fd1fabb7SAndroid Build Coastguard Worker
Set_SystemEncoding(const char * s)799*fd1fabb7SAndroid Build Coastguard Worker void dng_string::Set_SystemEncoding (const char *s)
800*fd1fabb7SAndroid Build Coastguard Worker {
801*fd1fabb7SAndroid Build Coastguard Worker
802*fd1fabb7SAndroid Build Coastguard Worker if (::IsASCII (s))
803*fd1fabb7SAndroid Build Coastguard Worker {
804*fd1fabb7SAndroid Build Coastguard Worker
805*fd1fabb7SAndroid Build Coastguard Worker Set (s);
806*fd1fabb7SAndroid Build Coastguard Worker
807*fd1fabb7SAndroid Build Coastguard Worker }
808*fd1fabb7SAndroid Build Coastguard Worker
809*fd1fabb7SAndroid Build Coastguard Worker else
810*fd1fabb7SAndroid Build Coastguard Worker {
811*fd1fabb7SAndroid Build Coastguard Worker
812*fd1fabb7SAndroid Build Coastguard Worker #if qMacOS || qWinOS
813*fd1fabb7SAndroid Build Coastguard Worker
814*fd1fabb7SAndroid Build Coastguard Worker Assign_SystemEncoding (*this, s);
815*fd1fabb7SAndroid Build Coastguard Worker
816*fd1fabb7SAndroid Build Coastguard Worker #else
817*fd1fabb7SAndroid Build Coastguard Worker
818*fd1fabb7SAndroid Build Coastguard Worker // Fallback logic that just grabs the ASCII characters and
819*fd1fabb7SAndroid Build Coastguard Worker // ignores the non-ASCII characters.
820*fd1fabb7SAndroid Build Coastguard Worker
821*fd1fabb7SAndroid Build Coastguard Worker uint32 len = strlenAsUint32 (s);
822*fd1fabb7SAndroid Build Coastguard Worker
823*fd1fabb7SAndroid Build Coastguard Worker const uint32 destBufferLength = SafeUint32Add (len, 1);
824*fd1fabb7SAndroid Build Coastguard Worker dng_memory_data buffer (destBufferLength);
825*fd1fabb7SAndroid Build Coastguard Worker
826*fd1fabb7SAndroid Build Coastguard Worker uint8 *d = buffer.Buffer_uint8 ();
827*fd1fabb7SAndroid Build Coastguard Worker uint8 * const destEnd = d + destBufferLength;
828*fd1fabb7SAndroid Build Coastguard Worker
829*fd1fabb7SAndroid Build Coastguard Worker while (*s)
830*fd1fabb7SAndroid Build Coastguard Worker {
831*fd1fabb7SAndroid Build Coastguard Worker
832*fd1fabb7SAndroid Build Coastguard Worker uint8 c = (uint8) *(s++);
833*fd1fabb7SAndroid Build Coastguard Worker
834*fd1fabb7SAndroid Build Coastguard Worker if ((c & 0x80) == 0)
835*fd1fabb7SAndroid Build Coastguard Worker {
836*fd1fabb7SAndroid Build Coastguard Worker
837*fd1fabb7SAndroid Build Coastguard Worker CheckSpaceLeftInBuffer (d, destEnd, 1);
838*fd1fabb7SAndroid Build Coastguard Worker *(d++) = c;
839*fd1fabb7SAndroid Build Coastguard Worker
840*fd1fabb7SAndroid Build Coastguard Worker }
841*fd1fabb7SAndroid Build Coastguard Worker
842*fd1fabb7SAndroid Build Coastguard Worker }
843*fd1fabb7SAndroid Build Coastguard Worker
844*fd1fabb7SAndroid Build Coastguard Worker CheckSpaceLeftInBuffer (d, destEnd, 1);
845*fd1fabb7SAndroid Build Coastguard Worker *d = 0;
846*fd1fabb7SAndroid Build Coastguard Worker
847*fd1fabb7SAndroid Build Coastguard Worker Set (buffer.Buffer_char ());
848*fd1fabb7SAndroid Build Coastguard Worker
849*fd1fabb7SAndroid Build Coastguard Worker #endif
850*fd1fabb7SAndroid Build Coastguard Worker
851*fd1fabb7SAndroid Build Coastguard Worker }
852*fd1fabb7SAndroid Build Coastguard Worker
853*fd1fabb7SAndroid Build Coastguard Worker }
854*fd1fabb7SAndroid Build Coastguard Worker
855*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
856*fd1fabb7SAndroid Build Coastguard Worker
ValidSystemEncoding() const857*fd1fabb7SAndroid Build Coastguard Worker bool dng_string::ValidSystemEncoding () const
858*fd1fabb7SAndroid Build Coastguard Worker {
859*fd1fabb7SAndroid Build Coastguard Worker
860*fd1fabb7SAndroid Build Coastguard Worker if (IsASCII ())
861*fd1fabb7SAndroid Build Coastguard Worker {
862*fd1fabb7SAndroid Build Coastguard Worker
863*fd1fabb7SAndroid Build Coastguard Worker return true;
864*fd1fabb7SAndroid Build Coastguard Worker
865*fd1fabb7SAndroid Build Coastguard Worker }
866*fd1fabb7SAndroid Build Coastguard Worker
867*fd1fabb7SAndroid Build Coastguard Worker dng_memory_data buffer;
868*fd1fabb7SAndroid Build Coastguard Worker
869*fd1fabb7SAndroid Build Coastguard Worker Get_SystemEncoding (buffer);
870*fd1fabb7SAndroid Build Coastguard Worker
871*fd1fabb7SAndroid Build Coastguard Worker dng_string temp;
872*fd1fabb7SAndroid Build Coastguard Worker
873*fd1fabb7SAndroid Build Coastguard Worker temp.Set_SystemEncoding (buffer.Buffer_char ());
874*fd1fabb7SAndroid Build Coastguard Worker
875*fd1fabb7SAndroid Build Coastguard Worker return (*this == temp);
876*fd1fabb7SAndroid Build Coastguard Worker
877*fd1fabb7SAndroid Build Coastguard Worker }
878*fd1fabb7SAndroid Build Coastguard Worker
879*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
880*fd1fabb7SAndroid Build Coastguard Worker
Set_JIS_X208_1990(const char * s)881*fd1fabb7SAndroid Build Coastguard Worker void dng_string::Set_JIS_X208_1990 (const char *s)
882*fd1fabb7SAndroid Build Coastguard Worker {
883*fd1fabb7SAndroid Build Coastguard Worker
884*fd1fabb7SAndroid Build Coastguard Worker if (::IsASCII (s))
885*fd1fabb7SAndroid Build Coastguard Worker {
886*fd1fabb7SAndroid Build Coastguard Worker
887*fd1fabb7SAndroid Build Coastguard Worker Set (s);
888*fd1fabb7SAndroid Build Coastguard Worker
889*fd1fabb7SAndroid Build Coastguard Worker }
890*fd1fabb7SAndroid Build Coastguard Worker
891*fd1fabb7SAndroid Build Coastguard Worker else
892*fd1fabb7SAndroid Build Coastguard Worker {
893*fd1fabb7SAndroid Build Coastguard Worker
894*fd1fabb7SAndroid Build Coastguard Worker #if qMacOS || qWinOS
895*fd1fabb7SAndroid Build Coastguard Worker
896*fd1fabb7SAndroid Build Coastguard Worker Assign_JIS_X208_1990 (*this, s);
897*fd1fabb7SAndroid Build Coastguard Worker
898*fd1fabb7SAndroid Build Coastguard Worker #else
899*fd1fabb7SAndroid Build Coastguard Worker
900*fd1fabb7SAndroid Build Coastguard Worker // Fallback to the ASCII extraction logic.
901*fd1fabb7SAndroid Build Coastguard Worker
902*fd1fabb7SAndroid Build Coastguard Worker Set_SystemEncoding (s);
903*fd1fabb7SAndroid Build Coastguard Worker
904*fd1fabb7SAndroid Build Coastguard Worker #endif
905*fd1fabb7SAndroid Build Coastguard Worker
906*fd1fabb7SAndroid Build Coastguard Worker }
907*fd1fabb7SAndroid Build Coastguard Worker
908*fd1fabb7SAndroid Build Coastguard Worker }
909*fd1fabb7SAndroid Build Coastguard Worker
910*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
911*fd1fabb7SAndroid Build Coastguard Worker
DecodeUTF8(const char * & s,uint32 maxBytes,bool * isValid)912*fd1fabb7SAndroid Build Coastguard Worker uint32 dng_string::DecodeUTF8 (const char *&s,
913*fd1fabb7SAndroid Build Coastguard Worker uint32 maxBytes,
914*fd1fabb7SAndroid Build Coastguard Worker bool *isValid)
915*fd1fabb7SAndroid Build Coastguard Worker {
916*fd1fabb7SAndroid Build Coastguard Worker
917*fd1fabb7SAndroid Build Coastguard Worker static const uint8 gUTF8Bytes [256] =
918*fd1fabb7SAndroid Build Coastguard Worker {
919*fd1fabb7SAndroid Build Coastguard Worker 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
920*fd1fabb7SAndroid Build Coastguard Worker 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
921*fd1fabb7SAndroid Build Coastguard Worker 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
922*fd1fabb7SAndroid Build Coastguard Worker 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
923*fd1fabb7SAndroid Build Coastguard Worker 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
924*fd1fabb7SAndroid Build Coastguard Worker 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
925*fd1fabb7SAndroid Build Coastguard Worker 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
926*fd1fabb7SAndroid Build Coastguard Worker 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0
927*fd1fabb7SAndroid Build Coastguard Worker };
928*fd1fabb7SAndroid Build Coastguard Worker
929*fd1fabb7SAndroid Build Coastguard Worker if (isValid)
930*fd1fabb7SAndroid Build Coastguard Worker {
931*fd1fabb7SAndroid Build Coastguard Worker *isValid = true;
932*fd1fabb7SAndroid Build Coastguard Worker }
933*fd1fabb7SAndroid Build Coastguard Worker
934*fd1fabb7SAndroid Build Coastguard Worker const uint8 *nBuf = (const uint8 *) s;
935*fd1fabb7SAndroid Build Coastguard Worker
936*fd1fabb7SAndroid Build Coastguard Worker uint32 aChar = nBuf [0];
937*fd1fabb7SAndroid Build Coastguard Worker
938*fd1fabb7SAndroid Build Coastguard Worker uint32 aSize = gUTF8Bytes [aChar];
939*fd1fabb7SAndroid Build Coastguard Worker
940*fd1fabb7SAndroid Build Coastguard Worker if (aSize > maxBytes)
941*fd1fabb7SAndroid Build Coastguard Worker {
942*fd1fabb7SAndroid Build Coastguard Worker
943*fd1fabb7SAndroid Build Coastguard Worker s += maxBytes;
944*fd1fabb7SAndroid Build Coastguard Worker
945*fd1fabb7SAndroid Build Coastguard Worker if (isValid)
946*fd1fabb7SAndroid Build Coastguard Worker {
947*fd1fabb7SAndroid Build Coastguard Worker *isValid = false;
948*fd1fabb7SAndroid Build Coastguard Worker }
949*fd1fabb7SAndroid Build Coastguard Worker
950*fd1fabb7SAndroid Build Coastguard Worker return kREPLACEMENT_CHARACTER;
951*fd1fabb7SAndroid Build Coastguard Worker
952*fd1fabb7SAndroid Build Coastguard Worker }
953*fd1fabb7SAndroid Build Coastguard Worker
954*fd1fabb7SAndroid Build Coastguard Worker s += aSize;
955*fd1fabb7SAndroid Build Coastguard Worker
956*fd1fabb7SAndroid Build Coastguard Worker for (uint32 extra = 1; extra < aSize; extra++)
957*fd1fabb7SAndroid Build Coastguard Worker {
958*fd1fabb7SAndroid Build Coastguard Worker
959*fd1fabb7SAndroid Build Coastguard Worker if ((nBuf [extra] & 0xC0) != 0x80)
960*fd1fabb7SAndroid Build Coastguard Worker {
961*fd1fabb7SAndroid Build Coastguard Worker
962*fd1fabb7SAndroid Build Coastguard Worker if (isValid)
963*fd1fabb7SAndroid Build Coastguard Worker {
964*fd1fabb7SAndroid Build Coastguard Worker *isValid = false;
965*fd1fabb7SAndroid Build Coastguard Worker }
966*fd1fabb7SAndroid Build Coastguard Worker
967*fd1fabb7SAndroid Build Coastguard Worker return kREPLACEMENT_CHARACTER;
968*fd1fabb7SAndroid Build Coastguard Worker
969*fd1fabb7SAndroid Build Coastguard Worker }
970*fd1fabb7SAndroid Build Coastguard Worker
971*fd1fabb7SAndroid Build Coastguard Worker }
972*fd1fabb7SAndroid Build Coastguard Worker
973*fd1fabb7SAndroid Build Coastguard Worker switch (aSize)
974*fd1fabb7SAndroid Build Coastguard Worker {
975*fd1fabb7SAndroid Build Coastguard Worker
976*fd1fabb7SAndroid Build Coastguard Worker case 0:
977*fd1fabb7SAndroid Build Coastguard Worker {
978*fd1fabb7SAndroid Build Coastguard Worker
979*fd1fabb7SAndroid Build Coastguard Worker s++; // Don't get stuck in infinite loop
980*fd1fabb7SAndroid Build Coastguard Worker
981*fd1fabb7SAndroid Build Coastguard Worker if (isValid)
982*fd1fabb7SAndroid Build Coastguard Worker {
983*fd1fabb7SAndroid Build Coastguard Worker *isValid = false;
984*fd1fabb7SAndroid Build Coastguard Worker }
985*fd1fabb7SAndroid Build Coastguard Worker
986*fd1fabb7SAndroid Build Coastguard Worker return kREPLACEMENT_CHARACTER;
987*fd1fabb7SAndroid Build Coastguard Worker
988*fd1fabb7SAndroid Build Coastguard Worker }
989*fd1fabb7SAndroid Build Coastguard Worker
990*fd1fabb7SAndroid Build Coastguard Worker case 1:
991*fd1fabb7SAndroid Build Coastguard Worker {
992*fd1fabb7SAndroid Build Coastguard Worker
993*fd1fabb7SAndroid Build Coastguard Worker return aChar;
994*fd1fabb7SAndroid Build Coastguard Worker
995*fd1fabb7SAndroid Build Coastguard Worker }
996*fd1fabb7SAndroid Build Coastguard Worker
997*fd1fabb7SAndroid Build Coastguard Worker case 2:
998*fd1fabb7SAndroid Build Coastguard Worker {
999*fd1fabb7SAndroid Build Coastguard Worker
1000*fd1fabb7SAndroid Build Coastguard Worker aChar = ((aChar << 6) + nBuf [1]) - (uint32) 0x00003080UL;
1001*fd1fabb7SAndroid Build Coastguard Worker
1002*fd1fabb7SAndroid Build Coastguard Worker break;
1003*fd1fabb7SAndroid Build Coastguard Worker
1004*fd1fabb7SAndroid Build Coastguard Worker }
1005*fd1fabb7SAndroid Build Coastguard Worker
1006*fd1fabb7SAndroid Build Coastguard Worker case 3:
1007*fd1fabb7SAndroid Build Coastguard Worker {
1008*fd1fabb7SAndroid Build Coastguard Worker
1009*fd1fabb7SAndroid Build Coastguard Worker aChar = ((((aChar << 6) + nBuf [1])
1010*fd1fabb7SAndroid Build Coastguard Worker << 6) + nBuf [2]) - (uint32) 0x000E2080UL;
1011*fd1fabb7SAndroid Build Coastguard Worker
1012*fd1fabb7SAndroid Build Coastguard Worker break;
1013*fd1fabb7SAndroid Build Coastguard Worker
1014*fd1fabb7SAndroid Build Coastguard Worker }
1015*fd1fabb7SAndroid Build Coastguard Worker
1016*fd1fabb7SAndroid Build Coastguard Worker case 4:
1017*fd1fabb7SAndroid Build Coastguard Worker {
1018*fd1fabb7SAndroid Build Coastguard Worker
1019*fd1fabb7SAndroid Build Coastguard Worker aChar = ((((((aChar << 6) + nBuf [1])
1020*fd1fabb7SAndroid Build Coastguard Worker << 6) + nBuf [2])
1021*fd1fabb7SAndroid Build Coastguard Worker << 6) + nBuf [3]) - (uint32) 0x03C82080UL;
1022*fd1fabb7SAndroid Build Coastguard Worker
1023*fd1fabb7SAndroid Build Coastguard Worker break;
1024*fd1fabb7SAndroid Build Coastguard Worker
1025*fd1fabb7SAndroid Build Coastguard Worker }
1026*fd1fabb7SAndroid Build Coastguard Worker }
1027*fd1fabb7SAndroid Build Coastguard Worker
1028*fd1fabb7SAndroid Build Coastguard Worker if (aChar < 0x7F || aChar > 0x0010FFFF)
1029*fd1fabb7SAndroid Build Coastguard Worker {
1030*fd1fabb7SAndroid Build Coastguard Worker
1031*fd1fabb7SAndroid Build Coastguard Worker if (isValid)
1032*fd1fabb7SAndroid Build Coastguard Worker {
1033*fd1fabb7SAndroid Build Coastguard Worker *isValid = false;
1034*fd1fabb7SAndroid Build Coastguard Worker }
1035*fd1fabb7SAndroid Build Coastguard Worker
1036*fd1fabb7SAndroid Build Coastguard Worker return kREPLACEMENT_CHARACTER;
1037*fd1fabb7SAndroid Build Coastguard Worker
1038*fd1fabb7SAndroid Build Coastguard Worker }
1039*fd1fabb7SAndroid Build Coastguard Worker
1040*fd1fabb7SAndroid Build Coastguard Worker return aChar;
1041*fd1fabb7SAndroid Build Coastguard Worker
1042*fd1fabb7SAndroid Build Coastguard Worker }
1043*fd1fabb7SAndroid Build Coastguard Worker
1044*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1045*fd1fabb7SAndroid Build Coastguard Worker
IsUTF8(const char * s)1046*fd1fabb7SAndroid Build Coastguard Worker bool dng_string::IsUTF8 (const char *s)
1047*fd1fabb7SAndroid Build Coastguard Worker {
1048*fd1fabb7SAndroid Build Coastguard Worker
1049*fd1fabb7SAndroid Build Coastguard Worker uint32 len = strlenAsUint32 (s);
1050*fd1fabb7SAndroid Build Coastguard Worker
1051*fd1fabb7SAndroid Build Coastguard Worker const char *sEnd = s + len;
1052*fd1fabb7SAndroid Build Coastguard Worker
1053*fd1fabb7SAndroid Build Coastguard Worker while (s < sEnd)
1054*fd1fabb7SAndroid Build Coastguard Worker {
1055*fd1fabb7SAndroid Build Coastguard Worker
1056*fd1fabb7SAndroid Build Coastguard Worker bool isValid = true;
1057*fd1fabb7SAndroid Build Coastguard Worker
1058*fd1fabb7SAndroid Build Coastguard Worker (void) DecodeUTF8 (s, (uint32) (sEnd - s), &isValid);
1059*fd1fabb7SAndroid Build Coastguard Worker
1060*fd1fabb7SAndroid Build Coastguard Worker if (!isValid)
1061*fd1fabb7SAndroid Build Coastguard Worker {
1062*fd1fabb7SAndroid Build Coastguard Worker return false;
1063*fd1fabb7SAndroid Build Coastguard Worker }
1064*fd1fabb7SAndroid Build Coastguard Worker
1065*fd1fabb7SAndroid Build Coastguard Worker }
1066*fd1fabb7SAndroid Build Coastguard Worker
1067*fd1fabb7SAndroid Build Coastguard Worker return true;
1068*fd1fabb7SAndroid Build Coastguard Worker
1069*fd1fabb7SAndroid Build Coastguard Worker }
1070*fd1fabb7SAndroid Build Coastguard Worker
1071*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1072*fd1fabb7SAndroid Build Coastguard Worker
Set_UTF8_or_System(const char * s)1073*fd1fabb7SAndroid Build Coastguard Worker void dng_string::Set_UTF8_or_System (const char *s)
1074*fd1fabb7SAndroid Build Coastguard Worker {
1075*fd1fabb7SAndroid Build Coastguard Worker
1076*fd1fabb7SAndroid Build Coastguard Worker if (::IsASCII (s))
1077*fd1fabb7SAndroid Build Coastguard Worker {
1078*fd1fabb7SAndroid Build Coastguard Worker
1079*fd1fabb7SAndroid Build Coastguard Worker Set (s);
1080*fd1fabb7SAndroid Build Coastguard Worker
1081*fd1fabb7SAndroid Build Coastguard Worker }
1082*fd1fabb7SAndroid Build Coastguard Worker
1083*fd1fabb7SAndroid Build Coastguard Worker else if (IsUTF8 (s))
1084*fd1fabb7SAndroid Build Coastguard Worker {
1085*fd1fabb7SAndroid Build Coastguard Worker
1086*fd1fabb7SAndroid Build Coastguard Worker Set_UTF8 (s);
1087*fd1fabb7SAndroid Build Coastguard Worker
1088*fd1fabb7SAndroid Build Coastguard Worker }
1089*fd1fabb7SAndroid Build Coastguard Worker
1090*fd1fabb7SAndroid Build Coastguard Worker else
1091*fd1fabb7SAndroid Build Coastguard Worker {
1092*fd1fabb7SAndroid Build Coastguard Worker
1093*fd1fabb7SAndroid Build Coastguard Worker Set_SystemEncoding (s);
1094*fd1fabb7SAndroid Build Coastguard Worker
1095*fd1fabb7SAndroid Build Coastguard Worker }
1096*fd1fabb7SAndroid Build Coastguard Worker
1097*fd1fabb7SAndroid Build Coastguard Worker }
1098*fd1fabb7SAndroid Build Coastguard Worker
1099*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1100*fd1fabb7SAndroid Build Coastguard Worker
Get_UTF16(dng_memory_data & buffer) const1101*fd1fabb7SAndroid Build Coastguard Worker uint32 dng_string::Get_UTF16 (dng_memory_data &buffer) const
1102*fd1fabb7SAndroid Build Coastguard Worker {
1103*fd1fabb7SAndroid Build Coastguard Worker
1104*fd1fabb7SAndroid Build Coastguard Worker uint32 count = 0;
1105*fd1fabb7SAndroid Build Coastguard Worker
1106*fd1fabb7SAndroid Build Coastguard Worker const char *sPtr = Get ();
1107*fd1fabb7SAndroid Build Coastguard Worker
1108*fd1fabb7SAndroid Build Coastguard Worker while (*sPtr)
1109*fd1fabb7SAndroid Build Coastguard Worker {
1110*fd1fabb7SAndroid Build Coastguard Worker
1111*fd1fabb7SAndroid Build Coastguard Worker uint32 x = DecodeUTF8 (sPtr);
1112*fd1fabb7SAndroid Build Coastguard Worker
1113*fd1fabb7SAndroid Build Coastguard Worker if (x <= 0x0000FFFF ||
1114*fd1fabb7SAndroid Build Coastguard Worker x > 0x0010FFFF)
1115*fd1fabb7SAndroid Build Coastguard Worker {
1116*fd1fabb7SAndroid Build Coastguard Worker
1117*fd1fabb7SAndroid Build Coastguard Worker count = SafeUint32Add (count, 1);
1118*fd1fabb7SAndroid Build Coastguard Worker
1119*fd1fabb7SAndroid Build Coastguard Worker }
1120*fd1fabb7SAndroid Build Coastguard Worker
1121*fd1fabb7SAndroid Build Coastguard Worker else
1122*fd1fabb7SAndroid Build Coastguard Worker {
1123*fd1fabb7SAndroid Build Coastguard Worker
1124*fd1fabb7SAndroid Build Coastguard Worker count = SafeUint32Add (count, 2);
1125*fd1fabb7SAndroid Build Coastguard Worker
1126*fd1fabb7SAndroid Build Coastguard Worker }
1127*fd1fabb7SAndroid Build Coastguard Worker
1128*fd1fabb7SAndroid Build Coastguard Worker }
1129*fd1fabb7SAndroid Build Coastguard Worker
1130*fd1fabb7SAndroid Build Coastguard Worker const uint32 destBufferLength = SafeUint32Add (count, 1);
1131*fd1fabb7SAndroid Build Coastguard Worker buffer.Allocate (destBufferLength, sizeof (uint16));
1132*fd1fabb7SAndroid Build Coastguard Worker
1133*fd1fabb7SAndroid Build Coastguard Worker uint16 *dPtr = buffer.Buffer_uint16 ();
1134*fd1fabb7SAndroid Build Coastguard Worker uint16 * const destEnd = dPtr + destBufferLength;
1135*fd1fabb7SAndroid Build Coastguard Worker
1136*fd1fabb7SAndroid Build Coastguard Worker sPtr = Get ();
1137*fd1fabb7SAndroid Build Coastguard Worker
1138*fd1fabb7SAndroid Build Coastguard Worker while (*sPtr)
1139*fd1fabb7SAndroid Build Coastguard Worker {
1140*fd1fabb7SAndroid Build Coastguard Worker
1141*fd1fabb7SAndroid Build Coastguard Worker uint32 x = DecodeUTF8 (sPtr);
1142*fd1fabb7SAndroid Build Coastguard Worker
1143*fd1fabb7SAndroid Build Coastguard Worker if (x <= 0x0000FFFF)
1144*fd1fabb7SAndroid Build Coastguard Worker {
1145*fd1fabb7SAndroid Build Coastguard Worker
1146*fd1fabb7SAndroid Build Coastguard Worker CheckSpaceLeftInBuffer (dPtr, destEnd, 1);
1147*fd1fabb7SAndroid Build Coastguard Worker *(dPtr++) = (uint16) x;
1148*fd1fabb7SAndroid Build Coastguard Worker
1149*fd1fabb7SAndroid Build Coastguard Worker }
1150*fd1fabb7SAndroid Build Coastguard Worker
1151*fd1fabb7SAndroid Build Coastguard Worker else if (x > 0x0010FFFF)
1152*fd1fabb7SAndroid Build Coastguard Worker {
1153*fd1fabb7SAndroid Build Coastguard Worker
1154*fd1fabb7SAndroid Build Coastguard Worker CheckSpaceLeftInBuffer (dPtr, destEnd, 1);
1155*fd1fabb7SAndroid Build Coastguard Worker *(dPtr++) = (uint16) kREPLACEMENT_CHARACTER;
1156*fd1fabb7SAndroid Build Coastguard Worker
1157*fd1fabb7SAndroid Build Coastguard Worker }
1158*fd1fabb7SAndroid Build Coastguard Worker
1159*fd1fabb7SAndroid Build Coastguard Worker else
1160*fd1fabb7SAndroid Build Coastguard Worker {
1161*fd1fabb7SAndroid Build Coastguard Worker
1162*fd1fabb7SAndroid Build Coastguard Worker x -= 0x00010000;
1163*fd1fabb7SAndroid Build Coastguard Worker
1164*fd1fabb7SAndroid Build Coastguard Worker CheckSpaceLeftInBuffer (dPtr, destEnd, 2);
1165*fd1fabb7SAndroid Build Coastguard Worker *(dPtr++) = (uint16) ((x >> 10 ) + 0x0000D800);
1166*fd1fabb7SAndroid Build Coastguard Worker *(dPtr++) = (uint16) ((x & 0x000003FF) + 0x0000DC00);
1167*fd1fabb7SAndroid Build Coastguard Worker
1168*fd1fabb7SAndroid Build Coastguard Worker }
1169*fd1fabb7SAndroid Build Coastguard Worker
1170*fd1fabb7SAndroid Build Coastguard Worker }
1171*fd1fabb7SAndroid Build Coastguard Worker
1172*fd1fabb7SAndroid Build Coastguard Worker CheckSpaceLeftInBuffer (dPtr, destEnd, 1);
1173*fd1fabb7SAndroid Build Coastguard Worker *dPtr = 0;
1174*fd1fabb7SAndroid Build Coastguard Worker
1175*fd1fabb7SAndroid Build Coastguard Worker return count;
1176*fd1fabb7SAndroid Build Coastguard Worker
1177*fd1fabb7SAndroid Build Coastguard Worker }
1178*fd1fabb7SAndroid Build Coastguard Worker
1179*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1180*fd1fabb7SAndroid Build Coastguard Worker
Set_UTF16(const uint16 * s)1181*fd1fabb7SAndroid Build Coastguard Worker void dng_string::Set_UTF16 (const uint16 *s)
1182*fd1fabb7SAndroid Build Coastguard Worker {
1183*fd1fabb7SAndroid Build Coastguard Worker
1184*fd1fabb7SAndroid Build Coastguard Worker if (!s)
1185*fd1fabb7SAndroid Build Coastguard Worker {
1186*fd1fabb7SAndroid Build Coastguard Worker Clear ();
1187*fd1fabb7SAndroid Build Coastguard Worker return;
1188*fd1fabb7SAndroid Build Coastguard Worker }
1189*fd1fabb7SAndroid Build Coastguard Worker
1190*fd1fabb7SAndroid Build Coastguard Worker bool swap = false;
1191*fd1fabb7SAndroid Build Coastguard Worker
1192*fd1fabb7SAndroid Build Coastguard Worker if (s [0] == 0xFFFE) // Swapped byte order marker
1193*fd1fabb7SAndroid Build Coastguard Worker {
1194*fd1fabb7SAndroid Build Coastguard Worker swap = true;
1195*fd1fabb7SAndroid Build Coastguard Worker s++;
1196*fd1fabb7SAndroid Build Coastguard Worker }
1197*fd1fabb7SAndroid Build Coastguard Worker
1198*fd1fabb7SAndroid Build Coastguard Worker else if (s [0] == 0xFEFF) // Non-swapped byte order marker
1199*fd1fabb7SAndroid Build Coastguard Worker {
1200*fd1fabb7SAndroid Build Coastguard Worker s++;
1201*fd1fabb7SAndroid Build Coastguard Worker }
1202*fd1fabb7SAndroid Build Coastguard Worker
1203*fd1fabb7SAndroid Build Coastguard Worker uint32 length16 = 0;
1204*fd1fabb7SAndroid Build Coastguard Worker
1205*fd1fabb7SAndroid Build Coastguard Worker while (s [length16] != 0)
1206*fd1fabb7SAndroid Build Coastguard Worker {
1207*fd1fabb7SAndroid Build Coastguard Worker length16 = SafeUint32Add (length16, 1);
1208*fd1fabb7SAndroid Build Coastguard Worker }
1209*fd1fabb7SAndroid Build Coastguard Worker
1210*fd1fabb7SAndroid Build Coastguard Worker const uint16 *sEnd = s + length16;
1211*fd1fabb7SAndroid Build Coastguard Worker
1212*fd1fabb7SAndroid Build Coastguard Worker const uint32 destBufferSize =
1213*fd1fabb7SAndroid Build Coastguard Worker SafeUint32Add (SafeUint32Mult (length16, 6), 1);
1214*fd1fabb7SAndroid Build Coastguard Worker dng_memory_data buffer (destBufferSize);
1215*fd1fabb7SAndroid Build Coastguard Worker
1216*fd1fabb7SAndroid Build Coastguard Worker uint8 *d = buffer.Buffer_uint8 ();
1217*fd1fabb7SAndroid Build Coastguard Worker uint8 * const destEnd = d + destBufferSize;
1218*fd1fabb7SAndroid Build Coastguard Worker
1219*fd1fabb7SAndroid Build Coastguard Worker while (s < sEnd)
1220*fd1fabb7SAndroid Build Coastguard Worker {
1221*fd1fabb7SAndroid Build Coastguard Worker
1222*fd1fabb7SAndroid Build Coastguard Worker uint32 aChar = *s++;
1223*fd1fabb7SAndroid Build Coastguard Worker
1224*fd1fabb7SAndroid Build Coastguard Worker if (swap)
1225*fd1fabb7SAndroid Build Coastguard Worker {
1226*fd1fabb7SAndroid Build Coastguard Worker aChar = ((aChar << 8) | (aChar >> 8)) & 0x0000FFFF;
1227*fd1fabb7SAndroid Build Coastguard Worker }
1228*fd1fabb7SAndroid Build Coastguard Worker
1229*fd1fabb7SAndroid Build Coastguard Worker if ((aChar >= 0x0000D800) && (aChar <= 0x0000DBFF) && (s < sEnd))
1230*fd1fabb7SAndroid Build Coastguard Worker {
1231*fd1fabb7SAndroid Build Coastguard Worker
1232*fd1fabb7SAndroid Build Coastguard Worker uint32 aLow = *s;
1233*fd1fabb7SAndroid Build Coastguard Worker
1234*fd1fabb7SAndroid Build Coastguard Worker if (swap)
1235*fd1fabb7SAndroid Build Coastguard Worker {
1236*fd1fabb7SAndroid Build Coastguard Worker aLow = ((aLow << 8) | (aLow >> 8)) & 0x0000FFFF;
1237*fd1fabb7SAndroid Build Coastguard Worker }
1238*fd1fabb7SAndroid Build Coastguard Worker
1239*fd1fabb7SAndroid Build Coastguard Worker if ((aLow >= 0x0000DC00) && (aLow <= 0x0000DFFF))
1240*fd1fabb7SAndroid Build Coastguard Worker {
1241*fd1fabb7SAndroid Build Coastguard Worker
1242*fd1fabb7SAndroid Build Coastguard Worker aChar = ((aChar - 0x0000D800) << 10) +
1243*fd1fabb7SAndroid Build Coastguard Worker (aLow - 0x0000DC00) +
1244*fd1fabb7SAndroid Build Coastguard Worker 0x00010000;
1245*fd1fabb7SAndroid Build Coastguard Worker
1246*fd1fabb7SAndroid Build Coastguard Worker s++;
1247*fd1fabb7SAndroid Build Coastguard Worker
1248*fd1fabb7SAndroid Build Coastguard Worker }
1249*fd1fabb7SAndroid Build Coastguard Worker
1250*fd1fabb7SAndroid Build Coastguard Worker }
1251*fd1fabb7SAndroid Build Coastguard Worker
1252*fd1fabb7SAndroid Build Coastguard Worker if (aChar > 0x7FFFFFFF)
1253*fd1fabb7SAndroid Build Coastguard Worker {
1254*fd1fabb7SAndroid Build Coastguard Worker aChar = kREPLACEMENT_CHARACTER;
1255*fd1fabb7SAndroid Build Coastguard Worker }
1256*fd1fabb7SAndroid Build Coastguard Worker
1257*fd1fabb7SAndroid Build Coastguard Worker if (aChar < 0x00000080)
1258*fd1fabb7SAndroid Build Coastguard Worker {
1259*fd1fabb7SAndroid Build Coastguard Worker CheckSpaceLeftInBuffer (d, destEnd, 1);
1260*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) aChar;
1261*fd1fabb7SAndroid Build Coastguard Worker }
1262*fd1fabb7SAndroid Build Coastguard Worker
1263*fd1fabb7SAndroid Build Coastguard Worker else if (aChar < 0x00000800)
1264*fd1fabb7SAndroid Build Coastguard Worker {
1265*fd1fabb7SAndroid Build Coastguard Worker CheckSpaceLeftInBuffer (d, destEnd, 2);
1266*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) ((aChar >> 6) | 0x000000C0);
1267*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) ((aChar & 0x0000003F) | 0x00000080);
1268*fd1fabb7SAndroid Build Coastguard Worker }
1269*fd1fabb7SAndroid Build Coastguard Worker
1270*fd1fabb7SAndroid Build Coastguard Worker else if (aChar < 0x00010000)
1271*fd1fabb7SAndroid Build Coastguard Worker {
1272*fd1fabb7SAndroid Build Coastguard Worker CheckSpaceLeftInBuffer (d, destEnd, 3);
1273*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) ( (aChar >> 12) | 0x000000E0);
1274*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) (((aChar >> 6) & 0x0000003F) | 0x00000080);
1275*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) ( (aChar & 0x0000003F) | 0x00000080);
1276*fd1fabb7SAndroid Build Coastguard Worker }
1277*fd1fabb7SAndroid Build Coastguard Worker
1278*fd1fabb7SAndroid Build Coastguard Worker else if (aChar < 0x00200000)
1279*fd1fabb7SAndroid Build Coastguard Worker {
1280*fd1fabb7SAndroid Build Coastguard Worker CheckSpaceLeftInBuffer (d, destEnd, 4);
1281*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) ( (aChar >> 18) | 0x000000F0);
1282*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) (((aChar >> 12) & 0x0000003F) | 0x00000080);
1283*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) (((aChar >> 6) & 0x0000003F) | 0x00000080);
1284*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) ( (aChar & 0x0000003F) | 0x00000080);
1285*fd1fabb7SAndroid Build Coastguard Worker }
1286*fd1fabb7SAndroid Build Coastguard Worker
1287*fd1fabb7SAndroid Build Coastguard Worker else if (aChar < 0x04000000)
1288*fd1fabb7SAndroid Build Coastguard Worker {
1289*fd1fabb7SAndroid Build Coastguard Worker CheckSpaceLeftInBuffer (d, destEnd, 5);
1290*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) ( (aChar >> 24) | 0x000000F8);
1291*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) (((aChar >> 18) & 0x0000003F) | 0x00000080);
1292*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) (((aChar >> 12) & 0x0000003F) | 0x00000080);
1293*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) (((aChar >> 6) & 0x0000003F) | 0x00000080);
1294*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) ( (aChar & 0x0000003F) | 0x00000080);
1295*fd1fabb7SAndroid Build Coastguard Worker }
1296*fd1fabb7SAndroid Build Coastguard Worker
1297*fd1fabb7SAndroid Build Coastguard Worker else
1298*fd1fabb7SAndroid Build Coastguard Worker {
1299*fd1fabb7SAndroid Build Coastguard Worker CheckSpaceLeftInBuffer (d, destEnd, 6);
1300*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) ( (aChar >> 30) | 0x000000FC);
1301*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) (((aChar >> 24) & 0x0000003F) | 0x00000080);
1302*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) (((aChar >> 18) & 0x0000003F) | 0x00000080);
1303*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) (((aChar >> 12) & 0x0000003F) | 0x00000080);
1304*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) (((aChar >> 6) & 0x0000003F) | 0x00000080);
1305*fd1fabb7SAndroid Build Coastguard Worker *(d++) = (uint8) ( (aChar & 0x0000003F) | 0x00000080);
1306*fd1fabb7SAndroid Build Coastguard Worker }
1307*fd1fabb7SAndroid Build Coastguard Worker
1308*fd1fabb7SAndroid Build Coastguard Worker }
1309*fd1fabb7SAndroid Build Coastguard Worker
1310*fd1fabb7SAndroid Build Coastguard Worker CheckSpaceLeftInBuffer (d, destEnd, 1);
1311*fd1fabb7SAndroid Build Coastguard Worker *d = 0;
1312*fd1fabb7SAndroid Build Coastguard Worker
1313*fd1fabb7SAndroid Build Coastguard Worker Set (buffer.Buffer_char ());
1314*fd1fabb7SAndroid Build Coastguard Worker
1315*fd1fabb7SAndroid Build Coastguard Worker }
1316*fd1fabb7SAndroid Build Coastguard Worker
1317*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1318*fd1fabb7SAndroid Build Coastguard Worker
Clear()1319*fd1fabb7SAndroid Build Coastguard Worker void dng_string::Clear ()
1320*fd1fabb7SAndroid Build Coastguard Worker {
1321*fd1fabb7SAndroid Build Coastguard Worker
1322*fd1fabb7SAndroid Build Coastguard Worker Set (NULL);
1323*fd1fabb7SAndroid Build Coastguard Worker
1324*fd1fabb7SAndroid Build Coastguard Worker }
1325*fd1fabb7SAndroid Build Coastguard Worker
1326*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1327*fd1fabb7SAndroid Build Coastguard Worker
Truncate(uint32 maxBytes)1328*fd1fabb7SAndroid Build Coastguard Worker void dng_string::Truncate (uint32 maxBytes)
1329*fd1fabb7SAndroid Build Coastguard Worker {
1330*fd1fabb7SAndroid Build Coastguard Worker
1331*fd1fabb7SAndroid Build Coastguard Worker uint32 len = Length ();
1332*fd1fabb7SAndroid Build Coastguard Worker
1333*fd1fabb7SAndroid Build Coastguard Worker if (len > maxBytes)
1334*fd1fabb7SAndroid Build Coastguard Worker {
1335*fd1fabb7SAndroid Build Coastguard Worker
1336*fd1fabb7SAndroid Build Coastguard Worker uint8 *s = fData.Buffer_uint8 ();
1337*fd1fabb7SAndroid Build Coastguard Worker
1338*fd1fabb7SAndroid Build Coastguard Worker // Don't truncate on an extension character. Extensions characters
1339*fd1fabb7SAndroid Build Coastguard Worker // in UTF-8 have the 0x80 bit set and the 0x40 bit clear.
1340*fd1fabb7SAndroid Build Coastguard Worker
1341*fd1fabb7SAndroid Build Coastguard Worker while (maxBytes > 0 && ((s [maxBytes]) & 0xC0) == 0x80)
1342*fd1fabb7SAndroid Build Coastguard Worker {
1343*fd1fabb7SAndroid Build Coastguard Worker
1344*fd1fabb7SAndroid Build Coastguard Worker maxBytes--;
1345*fd1fabb7SAndroid Build Coastguard Worker
1346*fd1fabb7SAndroid Build Coastguard Worker }
1347*fd1fabb7SAndroid Build Coastguard Worker
1348*fd1fabb7SAndroid Build Coastguard Worker s [maxBytes] = 0;
1349*fd1fabb7SAndroid Build Coastguard Worker
1350*fd1fabb7SAndroid Build Coastguard Worker }
1351*fd1fabb7SAndroid Build Coastguard Worker
1352*fd1fabb7SAndroid Build Coastguard Worker }
1353*fd1fabb7SAndroid Build Coastguard Worker
1354*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1355*fd1fabb7SAndroid Build Coastguard Worker
TrimTrailingBlanks()1356*fd1fabb7SAndroid Build Coastguard Worker bool dng_string::TrimTrailingBlanks ()
1357*fd1fabb7SAndroid Build Coastguard Worker {
1358*fd1fabb7SAndroid Build Coastguard Worker
1359*fd1fabb7SAndroid Build Coastguard Worker bool didTrim = false;
1360*fd1fabb7SAndroid Build Coastguard Worker
1361*fd1fabb7SAndroid Build Coastguard Worker if (fData.Buffer ())
1362*fd1fabb7SAndroid Build Coastguard Worker {
1363*fd1fabb7SAndroid Build Coastguard Worker
1364*fd1fabb7SAndroid Build Coastguard Worker char *s = fData.Buffer_char ();
1365*fd1fabb7SAndroid Build Coastguard Worker
1366*fd1fabb7SAndroid Build Coastguard Worker uint32 len = strlenAsUint32 (s);
1367*fd1fabb7SAndroid Build Coastguard Worker
1368*fd1fabb7SAndroid Build Coastguard Worker while (len > 0 && s [len - 1] == ' ')
1369*fd1fabb7SAndroid Build Coastguard Worker {
1370*fd1fabb7SAndroid Build Coastguard Worker len--;
1371*fd1fabb7SAndroid Build Coastguard Worker didTrim = true;
1372*fd1fabb7SAndroid Build Coastguard Worker }
1373*fd1fabb7SAndroid Build Coastguard Worker
1374*fd1fabb7SAndroid Build Coastguard Worker s [len] = 0;
1375*fd1fabb7SAndroid Build Coastguard Worker
1376*fd1fabb7SAndroid Build Coastguard Worker }
1377*fd1fabb7SAndroid Build Coastguard Worker
1378*fd1fabb7SAndroid Build Coastguard Worker return didTrim;
1379*fd1fabb7SAndroid Build Coastguard Worker
1380*fd1fabb7SAndroid Build Coastguard Worker }
1381*fd1fabb7SAndroid Build Coastguard Worker
1382*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1383*fd1fabb7SAndroid Build Coastguard Worker
TrimLeadingBlanks()1384*fd1fabb7SAndroid Build Coastguard Worker bool dng_string::TrimLeadingBlanks ()
1385*fd1fabb7SAndroid Build Coastguard Worker {
1386*fd1fabb7SAndroid Build Coastguard Worker
1387*fd1fabb7SAndroid Build Coastguard Worker bool didTrim = false;
1388*fd1fabb7SAndroid Build Coastguard Worker
1389*fd1fabb7SAndroid Build Coastguard Worker const char *s = Get ();
1390*fd1fabb7SAndroid Build Coastguard Worker
1391*fd1fabb7SAndroid Build Coastguard Worker while (*s == ' ')
1392*fd1fabb7SAndroid Build Coastguard Worker {
1393*fd1fabb7SAndroid Build Coastguard Worker s++;
1394*fd1fabb7SAndroid Build Coastguard Worker didTrim = true;
1395*fd1fabb7SAndroid Build Coastguard Worker }
1396*fd1fabb7SAndroid Build Coastguard Worker
1397*fd1fabb7SAndroid Build Coastguard Worker if (didTrim)
1398*fd1fabb7SAndroid Build Coastguard Worker {
1399*fd1fabb7SAndroid Build Coastguard Worker Set (s);
1400*fd1fabb7SAndroid Build Coastguard Worker }
1401*fd1fabb7SAndroid Build Coastguard Worker
1402*fd1fabb7SAndroid Build Coastguard Worker return didTrim;
1403*fd1fabb7SAndroid Build Coastguard Worker
1404*fd1fabb7SAndroid Build Coastguard Worker }
1405*fd1fabb7SAndroid Build Coastguard Worker
1406*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1407*fd1fabb7SAndroid Build Coastguard Worker
IsEmpty() const1408*fd1fabb7SAndroid Build Coastguard Worker bool dng_string::IsEmpty () const
1409*fd1fabb7SAndroid Build Coastguard Worker {
1410*fd1fabb7SAndroid Build Coastguard Worker
1411*fd1fabb7SAndroid Build Coastguard Worker const char *s = Get ();
1412*fd1fabb7SAndroid Build Coastguard Worker
1413*fd1fabb7SAndroid Build Coastguard Worker return *s == 0;
1414*fd1fabb7SAndroid Build Coastguard Worker
1415*fd1fabb7SAndroid Build Coastguard Worker }
1416*fd1fabb7SAndroid Build Coastguard Worker
1417*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1418*fd1fabb7SAndroid Build Coastguard Worker
Length() const1419*fd1fabb7SAndroid Build Coastguard Worker uint32 dng_string::Length () const
1420*fd1fabb7SAndroid Build Coastguard Worker {
1421*fd1fabb7SAndroid Build Coastguard Worker
1422*fd1fabb7SAndroid Build Coastguard Worker const char *s = Get ();
1423*fd1fabb7SAndroid Build Coastguard Worker
1424*fd1fabb7SAndroid Build Coastguard Worker return strlenAsUint32 (s);
1425*fd1fabb7SAndroid Build Coastguard Worker
1426*fd1fabb7SAndroid Build Coastguard Worker }
1427*fd1fabb7SAndroid Build Coastguard Worker
1428*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1429*fd1fabb7SAndroid Build Coastguard Worker
operator ==(const dng_string & s) const1430*fd1fabb7SAndroid Build Coastguard Worker bool dng_string::operator== (const dng_string &s) const
1431*fd1fabb7SAndroid Build Coastguard Worker {
1432*fd1fabb7SAndroid Build Coastguard Worker
1433*fd1fabb7SAndroid Build Coastguard Worker const char *s1 = Get ();
1434*fd1fabb7SAndroid Build Coastguard Worker const char *s2 = s.Get ();
1435*fd1fabb7SAndroid Build Coastguard Worker
1436*fd1fabb7SAndroid Build Coastguard Worker return strcmp (s1, s2) == 0;
1437*fd1fabb7SAndroid Build Coastguard Worker
1438*fd1fabb7SAndroid Build Coastguard Worker }
1439*fd1fabb7SAndroid Build Coastguard Worker
1440*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1441*fd1fabb7SAndroid Build Coastguard Worker
Matches(const char * t,const char * s,bool case_sensitive)1442*fd1fabb7SAndroid Build Coastguard Worker bool dng_string::Matches (const char *t,
1443*fd1fabb7SAndroid Build Coastguard Worker const char *s,
1444*fd1fabb7SAndroid Build Coastguard Worker bool case_sensitive)
1445*fd1fabb7SAndroid Build Coastguard Worker {
1446*fd1fabb7SAndroid Build Coastguard Worker
1447*fd1fabb7SAndroid Build Coastguard Worker while (*s != 0)
1448*fd1fabb7SAndroid Build Coastguard Worker {
1449*fd1fabb7SAndroid Build Coastguard Worker
1450*fd1fabb7SAndroid Build Coastguard Worker char c1 = *(s++);
1451*fd1fabb7SAndroid Build Coastguard Worker char c2 = *(t++);
1452*fd1fabb7SAndroid Build Coastguard Worker
1453*fd1fabb7SAndroid Build Coastguard Worker if (!case_sensitive)
1454*fd1fabb7SAndroid Build Coastguard Worker {
1455*fd1fabb7SAndroid Build Coastguard Worker c1 = ForceUppercase (c1);
1456*fd1fabb7SAndroid Build Coastguard Worker c2 = ForceUppercase (c2);
1457*fd1fabb7SAndroid Build Coastguard Worker }
1458*fd1fabb7SAndroid Build Coastguard Worker
1459*fd1fabb7SAndroid Build Coastguard Worker if (c1 != c2)
1460*fd1fabb7SAndroid Build Coastguard Worker {
1461*fd1fabb7SAndroid Build Coastguard Worker return false;
1462*fd1fabb7SAndroid Build Coastguard Worker }
1463*fd1fabb7SAndroid Build Coastguard Worker
1464*fd1fabb7SAndroid Build Coastguard Worker }
1465*fd1fabb7SAndroid Build Coastguard Worker
1466*fd1fabb7SAndroid Build Coastguard Worker return (*t == 0);
1467*fd1fabb7SAndroid Build Coastguard Worker
1468*fd1fabb7SAndroid Build Coastguard Worker }
1469*fd1fabb7SAndroid Build Coastguard Worker
1470*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1471*fd1fabb7SAndroid Build Coastguard Worker
Matches(const char * s,bool case_sensitive) const1472*fd1fabb7SAndroid Build Coastguard Worker bool dng_string::Matches (const char *s,
1473*fd1fabb7SAndroid Build Coastguard Worker bool case_sensitive) const
1474*fd1fabb7SAndroid Build Coastguard Worker {
1475*fd1fabb7SAndroid Build Coastguard Worker
1476*fd1fabb7SAndroid Build Coastguard Worker return dng_string::Matches (Get (), s, case_sensitive);
1477*fd1fabb7SAndroid Build Coastguard Worker
1478*fd1fabb7SAndroid Build Coastguard Worker }
1479*fd1fabb7SAndroid Build Coastguard Worker
1480*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1481*fd1fabb7SAndroid Build Coastguard Worker
StartsWith(const char * s,bool case_sensitive) const1482*fd1fabb7SAndroid Build Coastguard Worker bool dng_string::StartsWith (const char *s,
1483*fd1fabb7SAndroid Build Coastguard Worker bool case_sensitive) const
1484*fd1fabb7SAndroid Build Coastguard Worker {
1485*fd1fabb7SAndroid Build Coastguard Worker
1486*fd1fabb7SAndroid Build Coastguard Worker const char *t = Get ();
1487*fd1fabb7SAndroid Build Coastguard Worker
1488*fd1fabb7SAndroid Build Coastguard Worker while (*s != 0)
1489*fd1fabb7SAndroid Build Coastguard Worker {
1490*fd1fabb7SAndroid Build Coastguard Worker
1491*fd1fabb7SAndroid Build Coastguard Worker char c1 = *(s++);
1492*fd1fabb7SAndroid Build Coastguard Worker char c2 = *(t++);
1493*fd1fabb7SAndroid Build Coastguard Worker
1494*fd1fabb7SAndroid Build Coastguard Worker if (!case_sensitive)
1495*fd1fabb7SAndroid Build Coastguard Worker {
1496*fd1fabb7SAndroid Build Coastguard Worker c1 = ForceUppercase (c1);
1497*fd1fabb7SAndroid Build Coastguard Worker c2 = ForceUppercase (c2);
1498*fd1fabb7SAndroid Build Coastguard Worker }
1499*fd1fabb7SAndroid Build Coastguard Worker
1500*fd1fabb7SAndroid Build Coastguard Worker if (c1 != c2)
1501*fd1fabb7SAndroid Build Coastguard Worker {
1502*fd1fabb7SAndroid Build Coastguard Worker return false;
1503*fd1fabb7SAndroid Build Coastguard Worker }
1504*fd1fabb7SAndroid Build Coastguard Worker
1505*fd1fabb7SAndroid Build Coastguard Worker }
1506*fd1fabb7SAndroid Build Coastguard Worker
1507*fd1fabb7SAndroid Build Coastguard Worker return true;
1508*fd1fabb7SAndroid Build Coastguard Worker
1509*fd1fabb7SAndroid Build Coastguard Worker }
1510*fd1fabb7SAndroid Build Coastguard Worker
1511*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1512*fd1fabb7SAndroid Build Coastguard Worker
EndsWith(const char * s,bool case_sensitive) const1513*fd1fabb7SAndroid Build Coastguard Worker bool dng_string::EndsWith (const char *s,
1514*fd1fabb7SAndroid Build Coastguard Worker bool case_sensitive) const
1515*fd1fabb7SAndroid Build Coastguard Worker {
1516*fd1fabb7SAndroid Build Coastguard Worker
1517*fd1fabb7SAndroid Build Coastguard Worker uint32 len1 = Length ();
1518*fd1fabb7SAndroid Build Coastguard Worker
1519*fd1fabb7SAndroid Build Coastguard Worker uint32 len2 = strlenAsUint32 (s);
1520*fd1fabb7SAndroid Build Coastguard Worker
1521*fd1fabb7SAndroid Build Coastguard Worker if (len1 < len2)
1522*fd1fabb7SAndroid Build Coastguard Worker {
1523*fd1fabb7SAndroid Build Coastguard Worker return false;
1524*fd1fabb7SAndroid Build Coastguard Worker }
1525*fd1fabb7SAndroid Build Coastguard Worker
1526*fd1fabb7SAndroid Build Coastguard Worker const char *t = Get () + (len1 - len2);
1527*fd1fabb7SAndroid Build Coastguard Worker
1528*fd1fabb7SAndroid Build Coastguard Worker while (*s != 0)
1529*fd1fabb7SAndroid Build Coastguard Worker {
1530*fd1fabb7SAndroid Build Coastguard Worker
1531*fd1fabb7SAndroid Build Coastguard Worker char c1 = *(s++);
1532*fd1fabb7SAndroid Build Coastguard Worker char c2 = *(t++);
1533*fd1fabb7SAndroid Build Coastguard Worker
1534*fd1fabb7SAndroid Build Coastguard Worker if (!case_sensitive)
1535*fd1fabb7SAndroid Build Coastguard Worker {
1536*fd1fabb7SAndroid Build Coastguard Worker c1 = ForceUppercase (c1);
1537*fd1fabb7SAndroid Build Coastguard Worker c2 = ForceUppercase (c2);
1538*fd1fabb7SAndroid Build Coastguard Worker }
1539*fd1fabb7SAndroid Build Coastguard Worker
1540*fd1fabb7SAndroid Build Coastguard Worker if (c1 != c2)
1541*fd1fabb7SAndroid Build Coastguard Worker {
1542*fd1fabb7SAndroid Build Coastguard Worker return false;
1543*fd1fabb7SAndroid Build Coastguard Worker }
1544*fd1fabb7SAndroid Build Coastguard Worker
1545*fd1fabb7SAndroid Build Coastguard Worker }
1546*fd1fabb7SAndroid Build Coastguard Worker
1547*fd1fabb7SAndroid Build Coastguard Worker return true;
1548*fd1fabb7SAndroid Build Coastguard Worker
1549*fd1fabb7SAndroid Build Coastguard Worker }
1550*fd1fabb7SAndroid Build Coastguard Worker
1551*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1552*fd1fabb7SAndroid Build Coastguard Worker
Contains(const char * s,bool case_sensitive,int32 * match_offset) const1553*fd1fabb7SAndroid Build Coastguard Worker bool dng_string::Contains (const char *s,
1554*fd1fabb7SAndroid Build Coastguard Worker bool case_sensitive,
1555*fd1fabb7SAndroid Build Coastguard Worker int32 *match_offset) const
1556*fd1fabb7SAndroid Build Coastguard Worker {
1557*fd1fabb7SAndroid Build Coastguard Worker
1558*fd1fabb7SAndroid Build Coastguard Worker if (match_offset)
1559*fd1fabb7SAndroid Build Coastguard Worker {
1560*fd1fabb7SAndroid Build Coastguard Worker *match_offset = -1;
1561*fd1fabb7SAndroid Build Coastguard Worker }
1562*fd1fabb7SAndroid Build Coastguard Worker
1563*fd1fabb7SAndroid Build Coastguard Worker uint32 len1 = Length ();
1564*fd1fabb7SAndroid Build Coastguard Worker
1565*fd1fabb7SAndroid Build Coastguard Worker uint32 len2 = strlenAsUint32 (s);
1566*fd1fabb7SAndroid Build Coastguard Worker
1567*fd1fabb7SAndroid Build Coastguard Worker if (len1 < len2)
1568*fd1fabb7SAndroid Build Coastguard Worker {
1569*fd1fabb7SAndroid Build Coastguard Worker return false;
1570*fd1fabb7SAndroid Build Coastguard Worker }
1571*fd1fabb7SAndroid Build Coastguard Worker
1572*fd1fabb7SAndroid Build Coastguard Worker uint32 offsets = len1 - len2;
1573*fd1fabb7SAndroid Build Coastguard Worker
1574*fd1fabb7SAndroid Build Coastguard Worker for (uint32 offset = 0; offset <= offsets; offset++)
1575*fd1fabb7SAndroid Build Coastguard Worker {
1576*fd1fabb7SAndroid Build Coastguard Worker
1577*fd1fabb7SAndroid Build Coastguard Worker const char *ss = s;
1578*fd1fabb7SAndroid Build Coastguard Worker const char *tt = Get () + offset;
1579*fd1fabb7SAndroid Build Coastguard Worker
1580*fd1fabb7SAndroid Build Coastguard Worker while (*ss != 0)
1581*fd1fabb7SAndroid Build Coastguard Worker {
1582*fd1fabb7SAndroid Build Coastguard Worker
1583*fd1fabb7SAndroid Build Coastguard Worker char c1 = *(ss++);
1584*fd1fabb7SAndroid Build Coastguard Worker char c2 = *(tt++);
1585*fd1fabb7SAndroid Build Coastguard Worker
1586*fd1fabb7SAndroid Build Coastguard Worker if (!case_sensitive)
1587*fd1fabb7SAndroid Build Coastguard Worker {
1588*fd1fabb7SAndroid Build Coastguard Worker c1 = ForceUppercase (c1);
1589*fd1fabb7SAndroid Build Coastguard Worker c2 = ForceUppercase (c2);
1590*fd1fabb7SAndroid Build Coastguard Worker }
1591*fd1fabb7SAndroid Build Coastguard Worker
1592*fd1fabb7SAndroid Build Coastguard Worker if (c1 != c2)
1593*fd1fabb7SAndroid Build Coastguard Worker {
1594*fd1fabb7SAndroid Build Coastguard Worker goto tryNextOffset;
1595*fd1fabb7SAndroid Build Coastguard Worker }
1596*fd1fabb7SAndroid Build Coastguard Worker
1597*fd1fabb7SAndroid Build Coastguard Worker }
1598*fd1fabb7SAndroid Build Coastguard Worker
1599*fd1fabb7SAndroid Build Coastguard Worker if (match_offset)
1600*fd1fabb7SAndroid Build Coastguard Worker {
1601*fd1fabb7SAndroid Build Coastguard Worker *match_offset = offset;
1602*fd1fabb7SAndroid Build Coastguard Worker }
1603*fd1fabb7SAndroid Build Coastguard Worker
1604*fd1fabb7SAndroid Build Coastguard Worker return true;
1605*fd1fabb7SAndroid Build Coastguard Worker
1606*fd1fabb7SAndroid Build Coastguard Worker tryNextOffset: ;
1607*fd1fabb7SAndroid Build Coastguard Worker
1608*fd1fabb7SAndroid Build Coastguard Worker }
1609*fd1fabb7SAndroid Build Coastguard Worker
1610*fd1fabb7SAndroid Build Coastguard Worker return false;
1611*fd1fabb7SAndroid Build Coastguard Worker
1612*fd1fabb7SAndroid Build Coastguard Worker }
1613*fd1fabb7SAndroid Build Coastguard Worker
1614*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1615*fd1fabb7SAndroid Build Coastguard Worker
Replace(const char * old_string,const char * new_string,bool case_sensitive)1616*fd1fabb7SAndroid Build Coastguard Worker bool dng_string::Replace (const char *old_string,
1617*fd1fabb7SAndroid Build Coastguard Worker const char *new_string,
1618*fd1fabb7SAndroid Build Coastguard Worker bool case_sensitive)
1619*fd1fabb7SAndroid Build Coastguard Worker {
1620*fd1fabb7SAndroid Build Coastguard Worker
1621*fd1fabb7SAndroid Build Coastguard Worker int32 match_offset = -1;
1622*fd1fabb7SAndroid Build Coastguard Worker
1623*fd1fabb7SAndroid Build Coastguard Worker if (Contains (old_string,
1624*fd1fabb7SAndroid Build Coastguard Worker case_sensitive,
1625*fd1fabb7SAndroid Build Coastguard Worker &match_offset))
1626*fd1fabb7SAndroid Build Coastguard Worker {
1627*fd1fabb7SAndroid Build Coastguard Worker
1628*fd1fabb7SAndroid Build Coastguard Worker uint32 len1 = Length ();
1629*fd1fabb7SAndroid Build Coastguard Worker
1630*fd1fabb7SAndroid Build Coastguard Worker uint32 len2 = strlenAsUint32 (old_string);
1631*fd1fabb7SAndroid Build Coastguard Worker uint32 len3 = strlenAsUint32 (new_string);
1632*fd1fabb7SAndroid Build Coastguard Worker
1633*fd1fabb7SAndroid Build Coastguard Worker if (len2 == len3)
1634*fd1fabb7SAndroid Build Coastguard Worker {
1635*fd1fabb7SAndroid Build Coastguard Worker
1636*fd1fabb7SAndroid Build Coastguard Worker strncpy (fData.Buffer_char () + match_offset,
1637*fd1fabb7SAndroid Build Coastguard Worker new_string,
1638*fd1fabb7SAndroid Build Coastguard Worker len3);
1639*fd1fabb7SAndroid Build Coastguard Worker
1640*fd1fabb7SAndroid Build Coastguard Worker }
1641*fd1fabb7SAndroid Build Coastguard Worker
1642*fd1fabb7SAndroid Build Coastguard Worker else if (len2 > len3)
1643*fd1fabb7SAndroid Build Coastguard Worker {
1644*fd1fabb7SAndroid Build Coastguard Worker
1645*fd1fabb7SAndroid Build Coastguard Worker strncpy (fData.Buffer_char () + match_offset,
1646*fd1fabb7SAndroid Build Coastguard Worker new_string,
1647*fd1fabb7SAndroid Build Coastguard Worker len3);
1648*fd1fabb7SAndroid Build Coastguard Worker
1649*fd1fabb7SAndroid Build Coastguard Worker const char *s = fData.Buffer_char () + match_offset + len2;
1650*fd1fabb7SAndroid Build Coastguard Worker char *d = fData.Buffer_char () + match_offset + len3;
1651*fd1fabb7SAndroid Build Coastguard Worker
1652*fd1fabb7SAndroid Build Coastguard Worker uint32 extra = len1 - match_offset - len2 + 1; // + 1 for NULL termination
1653*fd1fabb7SAndroid Build Coastguard Worker
1654*fd1fabb7SAndroid Build Coastguard Worker for (uint32 j = 0; j < extra; j++)
1655*fd1fabb7SAndroid Build Coastguard Worker {
1656*fd1fabb7SAndroid Build Coastguard Worker *(d++) = *(s++);
1657*fd1fabb7SAndroid Build Coastguard Worker }
1658*fd1fabb7SAndroid Build Coastguard Worker
1659*fd1fabb7SAndroid Build Coastguard Worker }
1660*fd1fabb7SAndroid Build Coastguard Worker
1661*fd1fabb7SAndroid Build Coastguard Worker else
1662*fd1fabb7SAndroid Build Coastguard Worker {
1663*fd1fabb7SAndroid Build Coastguard Worker
1664*fd1fabb7SAndroid Build Coastguard Worker // "len1 - len2" cannot wrap around because we know that if this
1665*fd1fabb7SAndroid Build Coastguard Worker // string contains old_string, len1 >= len2 must hold.
1666*fd1fabb7SAndroid Build Coastguard Worker dng_memory_data tempBuffer (
1667*fd1fabb7SAndroid Build Coastguard Worker SafeUint32Add (SafeUint32Add (len1 - len2, len3), 1));
1668*fd1fabb7SAndroid Build Coastguard Worker
1669*fd1fabb7SAndroid Build Coastguard Worker if (match_offset)
1670*fd1fabb7SAndroid Build Coastguard Worker {
1671*fd1fabb7SAndroid Build Coastguard Worker
1672*fd1fabb7SAndroid Build Coastguard Worker strncpy (tempBuffer.Buffer_char (),
1673*fd1fabb7SAndroid Build Coastguard Worker fData .Buffer_char (),
1674*fd1fabb7SAndroid Build Coastguard Worker match_offset);
1675*fd1fabb7SAndroid Build Coastguard Worker
1676*fd1fabb7SAndroid Build Coastguard Worker }
1677*fd1fabb7SAndroid Build Coastguard Worker
1678*fd1fabb7SAndroid Build Coastguard Worker if (len3)
1679*fd1fabb7SAndroid Build Coastguard Worker {
1680*fd1fabb7SAndroid Build Coastguard Worker
1681*fd1fabb7SAndroid Build Coastguard Worker strncpy (tempBuffer.Buffer_char () + match_offset,
1682*fd1fabb7SAndroid Build Coastguard Worker new_string,
1683*fd1fabb7SAndroid Build Coastguard Worker len3);
1684*fd1fabb7SAndroid Build Coastguard Worker
1685*fd1fabb7SAndroid Build Coastguard Worker }
1686*fd1fabb7SAndroid Build Coastguard Worker
1687*fd1fabb7SAndroid Build Coastguard Worker uint32 extra = len1 - match_offset - len2 + 1; // + 1 for NULL termination
1688*fd1fabb7SAndroid Build Coastguard Worker
1689*fd1fabb7SAndroid Build Coastguard Worker strncpy (tempBuffer.Buffer_char () + match_offset + len3,
1690*fd1fabb7SAndroid Build Coastguard Worker fData .Buffer_char () + match_offset + len2,
1691*fd1fabb7SAndroid Build Coastguard Worker extra);
1692*fd1fabb7SAndroid Build Coastguard Worker
1693*fd1fabb7SAndroid Build Coastguard Worker Set (tempBuffer.Buffer_char ());
1694*fd1fabb7SAndroid Build Coastguard Worker
1695*fd1fabb7SAndroid Build Coastguard Worker }
1696*fd1fabb7SAndroid Build Coastguard Worker
1697*fd1fabb7SAndroid Build Coastguard Worker return true;
1698*fd1fabb7SAndroid Build Coastguard Worker
1699*fd1fabb7SAndroid Build Coastguard Worker }
1700*fd1fabb7SAndroid Build Coastguard Worker
1701*fd1fabb7SAndroid Build Coastguard Worker return false;
1702*fd1fabb7SAndroid Build Coastguard Worker
1703*fd1fabb7SAndroid Build Coastguard Worker }
1704*fd1fabb7SAndroid Build Coastguard Worker
1705*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1706*fd1fabb7SAndroid Build Coastguard Worker
TrimLeading(const char * s,bool case_sensitive)1707*fd1fabb7SAndroid Build Coastguard Worker bool dng_string::TrimLeading (const char *s,
1708*fd1fabb7SAndroid Build Coastguard Worker bool case_sensitive)
1709*fd1fabb7SAndroid Build Coastguard Worker {
1710*fd1fabb7SAndroid Build Coastguard Worker
1711*fd1fabb7SAndroid Build Coastguard Worker if (StartsWith (s, case_sensitive))
1712*fd1fabb7SAndroid Build Coastguard Worker {
1713*fd1fabb7SAndroid Build Coastguard Worker
1714*fd1fabb7SAndroid Build Coastguard Worker Set (Get () + strlenAsUint32 (s));
1715*fd1fabb7SAndroid Build Coastguard Worker
1716*fd1fabb7SAndroid Build Coastguard Worker return true;
1717*fd1fabb7SAndroid Build Coastguard Worker
1718*fd1fabb7SAndroid Build Coastguard Worker }
1719*fd1fabb7SAndroid Build Coastguard Worker
1720*fd1fabb7SAndroid Build Coastguard Worker return false;
1721*fd1fabb7SAndroid Build Coastguard Worker
1722*fd1fabb7SAndroid Build Coastguard Worker }
1723*fd1fabb7SAndroid Build Coastguard Worker
1724*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1725*fd1fabb7SAndroid Build Coastguard Worker
Append(const char * s)1726*fd1fabb7SAndroid Build Coastguard Worker void dng_string::Append (const char *s)
1727*fd1fabb7SAndroid Build Coastguard Worker {
1728*fd1fabb7SAndroid Build Coastguard Worker
1729*fd1fabb7SAndroid Build Coastguard Worker uint32 len2 = strlenAsUint32 (s);
1730*fd1fabb7SAndroid Build Coastguard Worker
1731*fd1fabb7SAndroid Build Coastguard Worker if (len2)
1732*fd1fabb7SAndroid Build Coastguard Worker {
1733*fd1fabb7SAndroid Build Coastguard Worker
1734*fd1fabb7SAndroid Build Coastguard Worker uint32 len1 = Length ();
1735*fd1fabb7SAndroid Build Coastguard Worker
1736*fd1fabb7SAndroid Build Coastguard Worker dng_memory_data temp (SafeUint32Add (SafeUint32Add (len1, len2), 1));
1737*fd1fabb7SAndroid Build Coastguard Worker
1738*fd1fabb7SAndroid Build Coastguard Worker char *buffer = temp.Buffer_char ();
1739*fd1fabb7SAndroid Build Coastguard Worker
1740*fd1fabb7SAndroid Build Coastguard Worker if (len1)
1741*fd1fabb7SAndroid Build Coastguard Worker {
1742*fd1fabb7SAndroid Build Coastguard Worker memcpy (buffer, Get (), len1);
1743*fd1fabb7SAndroid Build Coastguard Worker }
1744*fd1fabb7SAndroid Build Coastguard Worker
1745*fd1fabb7SAndroid Build Coastguard Worker memcpy (buffer + len1, s, len2 + 1);
1746*fd1fabb7SAndroid Build Coastguard Worker
1747*fd1fabb7SAndroid Build Coastguard Worker Set (buffer);
1748*fd1fabb7SAndroid Build Coastguard Worker
1749*fd1fabb7SAndroid Build Coastguard Worker }
1750*fd1fabb7SAndroid Build Coastguard Worker
1751*fd1fabb7SAndroid Build Coastguard Worker }
1752*fd1fabb7SAndroid Build Coastguard Worker
1753*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1754*fd1fabb7SAndroid Build Coastguard Worker
SetUppercase()1755*fd1fabb7SAndroid Build Coastguard Worker void dng_string::SetUppercase ()
1756*fd1fabb7SAndroid Build Coastguard Worker {
1757*fd1fabb7SAndroid Build Coastguard Worker
1758*fd1fabb7SAndroid Build Coastguard Worker if (fData.Buffer ())
1759*fd1fabb7SAndroid Build Coastguard Worker {
1760*fd1fabb7SAndroid Build Coastguard Worker
1761*fd1fabb7SAndroid Build Coastguard Worker uint32 len = Length ();
1762*fd1fabb7SAndroid Build Coastguard Worker
1763*fd1fabb7SAndroid Build Coastguard Worker char *dPtr = fData.Buffer_char ();
1764*fd1fabb7SAndroid Build Coastguard Worker
1765*fd1fabb7SAndroid Build Coastguard Worker for (uint32 j = 0; j < len; j++)
1766*fd1fabb7SAndroid Build Coastguard Worker {
1767*fd1fabb7SAndroid Build Coastguard Worker
1768*fd1fabb7SAndroid Build Coastguard Worker char c = dPtr [j];
1769*fd1fabb7SAndroid Build Coastguard Worker
1770*fd1fabb7SAndroid Build Coastguard Worker if (c >= 'a' && c <= 'z')
1771*fd1fabb7SAndroid Build Coastguard Worker {
1772*fd1fabb7SAndroid Build Coastguard Worker
1773*fd1fabb7SAndroid Build Coastguard Worker dPtr [j] = c - 'a' + 'A';
1774*fd1fabb7SAndroid Build Coastguard Worker
1775*fd1fabb7SAndroid Build Coastguard Worker }
1776*fd1fabb7SAndroid Build Coastguard Worker
1777*fd1fabb7SAndroid Build Coastguard Worker }
1778*fd1fabb7SAndroid Build Coastguard Worker
1779*fd1fabb7SAndroid Build Coastguard Worker }
1780*fd1fabb7SAndroid Build Coastguard Worker
1781*fd1fabb7SAndroid Build Coastguard Worker }
1782*fd1fabb7SAndroid Build Coastguard Worker
1783*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1784*fd1fabb7SAndroid Build Coastguard Worker
SetLowercase()1785*fd1fabb7SAndroid Build Coastguard Worker void dng_string::SetLowercase ()
1786*fd1fabb7SAndroid Build Coastguard Worker {
1787*fd1fabb7SAndroid Build Coastguard Worker
1788*fd1fabb7SAndroid Build Coastguard Worker if (fData.Buffer ())
1789*fd1fabb7SAndroid Build Coastguard Worker {
1790*fd1fabb7SAndroid Build Coastguard Worker
1791*fd1fabb7SAndroid Build Coastguard Worker uint32 len = Length ();
1792*fd1fabb7SAndroid Build Coastguard Worker
1793*fd1fabb7SAndroid Build Coastguard Worker char *dPtr = fData.Buffer_char ();
1794*fd1fabb7SAndroid Build Coastguard Worker
1795*fd1fabb7SAndroid Build Coastguard Worker for (uint32 j = 0; j < len; j++)
1796*fd1fabb7SAndroid Build Coastguard Worker {
1797*fd1fabb7SAndroid Build Coastguard Worker
1798*fd1fabb7SAndroid Build Coastguard Worker char c = dPtr [j];
1799*fd1fabb7SAndroid Build Coastguard Worker
1800*fd1fabb7SAndroid Build Coastguard Worker if (c >= 'A' && c <= 'Z')
1801*fd1fabb7SAndroid Build Coastguard Worker {
1802*fd1fabb7SAndroid Build Coastguard Worker
1803*fd1fabb7SAndroid Build Coastguard Worker dPtr [j] = c - 'A' + 'a';
1804*fd1fabb7SAndroid Build Coastguard Worker
1805*fd1fabb7SAndroid Build Coastguard Worker }
1806*fd1fabb7SAndroid Build Coastguard Worker
1807*fd1fabb7SAndroid Build Coastguard Worker }
1808*fd1fabb7SAndroid Build Coastguard Worker
1809*fd1fabb7SAndroid Build Coastguard Worker }
1810*fd1fabb7SAndroid Build Coastguard Worker
1811*fd1fabb7SAndroid Build Coastguard Worker }
1812*fd1fabb7SAndroid Build Coastguard Worker
1813*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1814*fd1fabb7SAndroid Build Coastguard Worker
SetLineEndings(char ending)1815*fd1fabb7SAndroid Build Coastguard Worker void dng_string::SetLineEndings (char ending)
1816*fd1fabb7SAndroid Build Coastguard Worker {
1817*fd1fabb7SAndroid Build Coastguard Worker
1818*fd1fabb7SAndroid Build Coastguard Worker if (fData.Buffer ())
1819*fd1fabb7SAndroid Build Coastguard Worker {
1820*fd1fabb7SAndroid Build Coastguard Worker
1821*fd1fabb7SAndroid Build Coastguard Worker const char *sPtr = fData.Buffer_char ();
1822*fd1fabb7SAndroid Build Coastguard Worker char *dPtr = fData.Buffer_char ();
1823*fd1fabb7SAndroid Build Coastguard Worker
1824*fd1fabb7SAndroid Build Coastguard Worker while (*sPtr)
1825*fd1fabb7SAndroid Build Coastguard Worker {
1826*fd1fabb7SAndroid Build Coastguard Worker
1827*fd1fabb7SAndroid Build Coastguard Worker char c = *(sPtr++);
1828*fd1fabb7SAndroid Build Coastguard Worker
1829*fd1fabb7SAndroid Build Coastguard Worker char nc = sPtr [0];
1830*fd1fabb7SAndroid Build Coastguard Worker
1831*fd1fabb7SAndroid Build Coastguard Worker if ((c == '\r' && nc == '\n') ||
1832*fd1fabb7SAndroid Build Coastguard Worker (c == '\n' && nc == '\r'))
1833*fd1fabb7SAndroid Build Coastguard Worker {
1834*fd1fabb7SAndroid Build Coastguard Worker
1835*fd1fabb7SAndroid Build Coastguard Worker sPtr++;
1836*fd1fabb7SAndroid Build Coastguard Worker
1837*fd1fabb7SAndroid Build Coastguard Worker if (ending)
1838*fd1fabb7SAndroid Build Coastguard Worker {
1839*fd1fabb7SAndroid Build Coastguard Worker *(dPtr++) = ending;
1840*fd1fabb7SAndroid Build Coastguard Worker }
1841*fd1fabb7SAndroid Build Coastguard Worker
1842*fd1fabb7SAndroid Build Coastguard Worker }
1843*fd1fabb7SAndroid Build Coastguard Worker
1844*fd1fabb7SAndroid Build Coastguard Worker else if (c == '\n' ||
1845*fd1fabb7SAndroid Build Coastguard Worker c == '\r')
1846*fd1fabb7SAndroid Build Coastguard Worker {
1847*fd1fabb7SAndroid Build Coastguard Worker
1848*fd1fabb7SAndroid Build Coastguard Worker if (ending)
1849*fd1fabb7SAndroid Build Coastguard Worker {
1850*fd1fabb7SAndroid Build Coastguard Worker *(dPtr++) = ending;
1851*fd1fabb7SAndroid Build Coastguard Worker }
1852*fd1fabb7SAndroid Build Coastguard Worker
1853*fd1fabb7SAndroid Build Coastguard Worker }
1854*fd1fabb7SAndroid Build Coastguard Worker
1855*fd1fabb7SAndroid Build Coastguard Worker else
1856*fd1fabb7SAndroid Build Coastguard Worker {
1857*fd1fabb7SAndroid Build Coastguard Worker
1858*fd1fabb7SAndroid Build Coastguard Worker *(dPtr++) = c;
1859*fd1fabb7SAndroid Build Coastguard Worker
1860*fd1fabb7SAndroid Build Coastguard Worker }
1861*fd1fabb7SAndroid Build Coastguard Worker
1862*fd1fabb7SAndroid Build Coastguard Worker }
1863*fd1fabb7SAndroid Build Coastguard Worker
1864*fd1fabb7SAndroid Build Coastguard Worker *dPtr = 0;
1865*fd1fabb7SAndroid Build Coastguard Worker
1866*fd1fabb7SAndroid Build Coastguard Worker }
1867*fd1fabb7SAndroid Build Coastguard Worker
1868*fd1fabb7SAndroid Build Coastguard Worker }
1869*fd1fabb7SAndroid Build Coastguard Worker
1870*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1871*fd1fabb7SAndroid Build Coastguard Worker
StripLowASCII()1872*fd1fabb7SAndroid Build Coastguard Worker void dng_string::StripLowASCII ()
1873*fd1fabb7SAndroid Build Coastguard Worker {
1874*fd1fabb7SAndroid Build Coastguard Worker
1875*fd1fabb7SAndroid Build Coastguard Worker if (fData.Buffer ())
1876*fd1fabb7SAndroid Build Coastguard Worker {
1877*fd1fabb7SAndroid Build Coastguard Worker
1878*fd1fabb7SAndroid Build Coastguard Worker const char *sPtr = fData.Buffer_char ();
1879*fd1fabb7SAndroid Build Coastguard Worker char *dPtr = fData.Buffer_char ();
1880*fd1fabb7SAndroid Build Coastguard Worker
1881*fd1fabb7SAndroid Build Coastguard Worker while (*sPtr)
1882*fd1fabb7SAndroid Build Coastguard Worker {
1883*fd1fabb7SAndroid Build Coastguard Worker
1884*fd1fabb7SAndroid Build Coastguard Worker char c = *(sPtr++);
1885*fd1fabb7SAndroid Build Coastguard Worker
1886*fd1fabb7SAndroid Build Coastguard Worker if (c == '\r' || c == '\n' || (uint8) c >= ' ')
1887*fd1fabb7SAndroid Build Coastguard Worker {
1888*fd1fabb7SAndroid Build Coastguard Worker
1889*fd1fabb7SAndroid Build Coastguard Worker *(dPtr++) = c;
1890*fd1fabb7SAndroid Build Coastguard Worker
1891*fd1fabb7SAndroid Build Coastguard Worker }
1892*fd1fabb7SAndroid Build Coastguard Worker
1893*fd1fabb7SAndroid Build Coastguard Worker }
1894*fd1fabb7SAndroid Build Coastguard Worker
1895*fd1fabb7SAndroid Build Coastguard Worker *dPtr = 0;
1896*fd1fabb7SAndroid Build Coastguard Worker
1897*fd1fabb7SAndroid Build Coastguard Worker }
1898*fd1fabb7SAndroid Build Coastguard Worker
1899*fd1fabb7SAndroid Build Coastguard Worker }
1900*fd1fabb7SAndroid Build Coastguard Worker
1901*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1902*fd1fabb7SAndroid Build Coastguard Worker
NormalizeAsCommaSeparatedNumbers()1903*fd1fabb7SAndroid Build Coastguard Worker void dng_string::NormalizeAsCommaSeparatedNumbers ()
1904*fd1fabb7SAndroid Build Coastguard Worker {
1905*fd1fabb7SAndroid Build Coastguard Worker
1906*fd1fabb7SAndroid Build Coastguard Worker if (fData.Buffer ())
1907*fd1fabb7SAndroid Build Coastguard Worker {
1908*fd1fabb7SAndroid Build Coastguard Worker
1909*fd1fabb7SAndroid Build Coastguard Worker const char *sPtr = fData.Buffer_char ();
1910*fd1fabb7SAndroid Build Coastguard Worker char *dPtr = fData.Buffer_char ();
1911*fd1fabb7SAndroid Build Coastguard Worker
1912*fd1fabb7SAndroid Build Coastguard Worker bool commaInserted = false;
1913*fd1fabb7SAndroid Build Coastguard Worker
1914*fd1fabb7SAndroid Build Coastguard Worker while (*sPtr)
1915*fd1fabb7SAndroid Build Coastguard Worker {
1916*fd1fabb7SAndroid Build Coastguard Worker
1917*fd1fabb7SAndroid Build Coastguard Worker uint32 c = DecodeUTF8 (sPtr);
1918*fd1fabb7SAndroid Build Coastguard Worker
1919*fd1fabb7SAndroid Build Coastguard Worker // Support number formats such as "3", "+3.0", "-3.1416", "314.16e-2",
1920*fd1fabb7SAndroid Build Coastguard Worker // "0.31416E1", but no hex/octal number representations.
1921*fd1fabb7SAndroid Build Coastguard Worker
1922*fd1fabb7SAndroid Build Coastguard Worker if (isdigit ((int) c) || c == '.' || c == '-' || c == '+' || c == 'e' || c == 'E')
1923*fd1fabb7SAndroid Build Coastguard Worker {
1924*fd1fabb7SAndroid Build Coastguard Worker
1925*fd1fabb7SAndroid Build Coastguard Worker *(dPtr++) = (char) c;
1926*fd1fabb7SAndroid Build Coastguard Worker
1927*fd1fabb7SAndroid Build Coastguard Worker if (commaInserted)
1928*fd1fabb7SAndroid Build Coastguard Worker {
1929*fd1fabb7SAndroid Build Coastguard Worker
1930*fd1fabb7SAndroid Build Coastguard Worker commaInserted = false;
1931*fd1fabb7SAndroid Build Coastguard Worker
1932*fd1fabb7SAndroid Build Coastguard Worker }
1933*fd1fabb7SAndroid Build Coastguard Worker
1934*fd1fabb7SAndroid Build Coastguard Worker }
1935*fd1fabb7SAndroid Build Coastguard Worker
1936*fd1fabb7SAndroid Build Coastguard Worker else if (!commaInserted)
1937*fd1fabb7SAndroid Build Coastguard Worker {
1938*fd1fabb7SAndroid Build Coastguard Worker
1939*fd1fabb7SAndroid Build Coastguard Worker *(dPtr++) = ',';
1940*fd1fabb7SAndroid Build Coastguard Worker
1941*fd1fabb7SAndroid Build Coastguard Worker commaInserted = true;
1942*fd1fabb7SAndroid Build Coastguard Worker
1943*fd1fabb7SAndroid Build Coastguard Worker }
1944*fd1fabb7SAndroid Build Coastguard Worker
1945*fd1fabb7SAndroid Build Coastguard Worker }
1946*fd1fabb7SAndroid Build Coastguard Worker
1947*fd1fabb7SAndroid Build Coastguard Worker *dPtr = 0;
1948*fd1fabb7SAndroid Build Coastguard Worker
1949*fd1fabb7SAndroid Build Coastguard Worker }
1950*fd1fabb7SAndroid Build Coastguard Worker
1951*fd1fabb7SAndroid Build Coastguard Worker }
1952*fd1fabb7SAndroid Build Coastguard Worker
1953*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
1954*fd1fabb7SAndroid Build Coastguard Worker
1955*fd1fabb7SAndroid Build Coastguard Worker // Unicode to low-ASCII strings table.
1956*fd1fabb7SAndroid Build Coastguard Worker
1957*fd1fabb7SAndroid Build Coastguard Worker struct UnicodeToLowASCIIEntry
1958*fd1fabb7SAndroid Build Coastguard Worker {
1959*fd1fabb7SAndroid Build Coastguard Worker uint32 unicode;
1960*fd1fabb7SAndroid Build Coastguard Worker const char *ascii;
1961*fd1fabb7SAndroid Build Coastguard Worker };
1962*fd1fabb7SAndroid Build Coastguard Worker
1963*fd1fabb7SAndroid Build Coastguard Worker static const UnicodeToLowASCIIEntry kUnicodeToLowASCII [] =
1964*fd1fabb7SAndroid Build Coastguard Worker {
1965*fd1fabb7SAndroid Build Coastguard Worker { 0x00A0, " " },
1966*fd1fabb7SAndroid Build Coastguard Worker { 0x00A1, "!" },
1967*fd1fabb7SAndroid Build Coastguard Worker { 0x00A9, "(C)" },
1968*fd1fabb7SAndroid Build Coastguard Worker { 0x00AA, "a" },
1969*fd1fabb7SAndroid Build Coastguard Worker { 0x00AB, "<<" },
1970*fd1fabb7SAndroid Build Coastguard Worker { 0x00AC, "!" },
1971*fd1fabb7SAndroid Build Coastguard Worker { 0x00AE, "(R)" },
1972*fd1fabb7SAndroid Build Coastguard Worker { 0x00B0, "dg" },
1973*fd1fabb7SAndroid Build Coastguard Worker { 0x00B1, "+-" },
1974*fd1fabb7SAndroid Build Coastguard Worker { 0x00B7, "." },
1975*fd1fabb7SAndroid Build Coastguard Worker { 0x00BA, "o" },
1976*fd1fabb7SAndroid Build Coastguard Worker { 0x00BB, ">>" },
1977*fd1fabb7SAndroid Build Coastguard Worker { 0x00BF, "?" },
1978*fd1fabb7SAndroid Build Coastguard Worker { 0x00C0, "A" },
1979*fd1fabb7SAndroid Build Coastguard Worker { 0x00C1, "A" },
1980*fd1fabb7SAndroid Build Coastguard Worker { 0x00C2, "A" },
1981*fd1fabb7SAndroid Build Coastguard Worker { 0x00C3, "A" },
1982*fd1fabb7SAndroid Build Coastguard Worker { 0x00C4, "A" },
1983*fd1fabb7SAndroid Build Coastguard Worker { 0x00C5, "A" },
1984*fd1fabb7SAndroid Build Coastguard Worker { 0x00C6, "AE" },
1985*fd1fabb7SAndroid Build Coastguard Worker { 0x00C7, "C" },
1986*fd1fabb7SAndroid Build Coastguard Worker { 0x00C8, "E" },
1987*fd1fabb7SAndroid Build Coastguard Worker { 0x00C9, "E" },
1988*fd1fabb7SAndroid Build Coastguard Worker { 0x00CA, "E" },
1989*fd1fabb7SAndroid Build Coastguard Worker { 0x00CB, "E" },
1990*fd1fabb7SAndroid Build Coastguard Worker { 0x00CC, "I" },
1991*fd1fabb7SAndroid Build Coastguard Worker { 0x00CD, "I" },
1992*fd1fabb7SAndroid Build Coastguard Worker { 0x00CE, "I" },
1993*fd1fabb7SAndroid Build Coastguard Worker { 0x00CF, "I" },
1994*fd1fabb7SAndroid Build Coastguard Worker { 0x00D1, "N" },
1995*fd1fabb7SAndroid Build Coastguard Worker { 0x00D2, "O" },
1996*fd1fabb7SAndroid Build Coastguard Worker { 0x00D3, "O" },
1997*fd1fabb7SAndroid Build Coastguard Worker { 0x00D4, "O" },
1998*fd1fabb7SAndroid Build Coastguard Worker { 0x00D5, "O" },
1999*fd1fabb7SAndroid Build Coastguard Worker { 0x00D6, "O" },
2000*fd1fabb7SAndroid Build Coastguard Worker { 0x00D8, "O" },
2001*fd1fabb7SAndroid Build Coastguard Worker { 0x00D9, "U" },
2002*fd1fabb7SAndroid Build Coastguard Worker { 0x00DA, "U" },
2003*fd1fabb7SAndroid Build Coastguard Worker { 0x00DB, "U" },
2004*fd1fabb7SAndroid Build Coastguard Worker { 0x00DC, "U" },
2005*fd1fabb7SAndroid Build Coastguard Worker { 0x00DD, "Y" },
2006*fd1fabb7SAndroid Build Coastguard Worker { 0x00E0, "a" },
2007*fd1fabb7SAndroid Build Coastguard Worker { 0x00E1, "a" },
2008*fd1fabb7SAndroid Build Coastguard Worker { 0x00E2, "a" },
2009*fd1fabb7SAndroid Build Coastguard Worker { 0x00E3, "a" },
2010*fd1fabb7SAndroid Build Coastguard Worker { 0x00E4, "a" },
2011*fd1fabb7SAndroid Build Coastguard Worker { 0x00E5, "a" },
2012*fd1fabb7SAndroid Build Coastguard Worker { 0x00E6, "ae" },
2013*fd1fabb7SAndroid Build Coastguard Worker { 0x00E7, "c" },
2014*fd1fabb7SAndroid Build Coastguard Worker { 0x00E8, "e" },
2015*fd1fabb7SAndroid Build Coastguard Worker { 0x00E9, "e" },
2016*fd1fabb7SAndroid Build Coastguard Worker { 0x00EA, "e" },
2017*fd1fabb7SAndroid Build Coastguard Worker { 0x00EB, "e" },
2018*fd1fabb7SAndroid Build Coastguard Worker { 0x00EC, "i" },
2019*fd1fabb7SAndroid Build Coastguard Worker { 0x00ED, "i" },
2020*fd1fabb7SAndroid Build Coastguard Worker { 0x00EE, "i" },
2021*fd1fabb7SAndroid Build Coastguard Worker { 0x00EF, "i" },
2022*fd1fabb7SAndroid Build Coastguard Worker { 0x00F1, "n" },
2023*fd1fabb7SAndroid Build Coastguard Worker { 0x00F2, "o" },
2024*fd1fabb7SAndroid Build Coastguard Worker { 0x00F3, "o" },
2025*fd1fabb7SAndroid Build Coastguard Worker { 0x00F4, "o" },
2026*fd1fabb7SAndroid Build Coastguard Worker { 0x00F5, "o" },
2027*fd1fabb7SAndroid Build Coastguard Worker { 0x00F6, "o" },
2028*fd1fabb7SAndroid Build Coastguard Worker { 0x00F7, "/" },
2029*fd1fabb7SAndroid Build Coastguard Worker { 0x00F8, "o" },
2030*fd1fabb7SAndroid Build Coastguard Worker { 0x00F9, "u" },
2031*fd1fabb7SAndroid Build Coastguard Worker { 0x00FA, "u" },
2032*fd1fabb7SAndroid Build Coastguard Worker { 0x00FB, "u" },
2033*fd1fabb7SAndroid Build Coastguard Worker { 0x00FC, "u" },
2034*fd1fabb7SAndroid Build Coastguard Worker { 0x00FD, "y" },
2035*fd1fabb7SAndroid Build Coastguard Worker { 0x00FF, "y" },
2036*fd1fabb7SAndroid Build Coastguard Worker { 0x0131, "i" },
2037*fd1fabb7SAndroid Build Coastguard Worker { 0x0152, "OE" },
2038*fd1fabb7SAndroid Build Coastguard Worker { 0x0153, "oe" },
2039*fd1fabb7SAndroid Build Coastguard Worker { 0x0178, "Y" },
2040*fd1fabb7SAndroid Build Coastguard Worker { 0x2013, "-" },
2041*fd1fabb7SAndroid Build Coastguard Worker { 0x2014, "-" },
2042*fd1fabb7SAndroid Build Coastguard Worker { 0x2018, "'" },
2043*fd1fabb7SAndroid Build Coastguard Worker { 0x2019, "'" },
2044*fd1fabb7SAndroid Build Coastguard Worker { 0x201A, "," },
2045*fd1fabb7SAndroid Build Coastguard Worker { 0x201C, "\"" },
2046*fd1fabb7SAndroid Build Coastguard Worker { 0x201D, "\"" },
2047*fd1fabb7SAndroid Build Coastguard Worker { 0x201E, ",," },
2048*fd1fabb7SAndroid Build Coastguard Worker { 0x2022, "." },
2049*fd1fabb7SAndroid Build Coastguard Worker { 0x2026, "..." },
2050*fd1fabb7SAndroid Build Coastguard Worker { 0x2039, "<" },
2051*fd1fabb7SAndroid Build Coastguard Worker { 0x203A, ">" },
2052*fd1fabb7SAndroid Build Coastguard Worker { 0x2044, "/" },
2053*fd1fabb7SAndroid Build Coastguard Worker { 0x2122, "TM" },
2054*fd1fabb7SAndroid Build Coastguard Worker { 0x2206, "d" },
2055*fd1fabb7SAndroid Build Coastguard Worker { 0x2211, "S" },
2056*fd1fabb7SAndroid Build Coastguard Worker { 0x2260, "!=" },
2057*fd1fabb7SAndroid Build Coastguard Worker { 0x2264, "<=" },
2058*fd1fabb7SAndroid Build Coastguard Worker { 0x2265, ">=" },
2059*fd1fabb7SAndroid Build Coastguard Worker { 0x2318, "#" },
2060*fd1fabb7SAndroid Build Coastguard Worker { 0xFB01, "fi" },
2061*fd1fabb7SAndroid Build Coastguard Worker { 0xFB02, "fl" }
2062*fd1fabb7SAndroid Build Coastguard Worker };
2063*fd1fabb7SAndroid Build Coastguard Worker
2064*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
2065*fd1fabb7SAndroid Build Coastguard Worker
ForceASCII()2066*fd1fabb7SAndroid Build Coastguard Worker void dng_string::ForceASCII ()
2067*fd1fabb7SAndroid Build Coastguard Worker {
2068*fd1fabb7SAndroid Build Coastguard Worker
2069*fd1fabb7SAndroid Build Coastguard Worker if (!IsASCII ())
2070*fd1fabb7SAndroid Build Coastguard Worker {
2071*fd1fabb7SAndroid Build Coastguard Worker
2072*fd1fabb7SAndroid Build Coastguard Worker uint32 tempBufferSize =
2073*fd1fabb7SAndroid Build Coastguard Worker SafeUint32Add (SafeUint32Mult(Length(), 3), 1);
2074*fd1fabb7SAndroid Build Coastguard Worker dng_memory_data tempBuffer (tempBufferSize);
2075*fd1fabb7SAndroid Build Coastguard Worker
2076*fd1fabb7SAndroid Build Coastguard Worker char *dPtr = tempBuffer.Buffer_char ();
2077*fd1fabb7SAndroid Build Coastguard Worker char * const destEnd = dPtr + tempBufferSize;
2078*fd1fabb7SAndroid Build Coastguard Worker
2079*fd1fabb7SAndroid Build Coastguard Worker const char *sPtr = Get ();
2080*fd1fabb7SAndroid Build Coastguard Worker
2081*fd1fabb7SAndroid Build Coastguard Worker while (*sPtr)
2082*fd1fabb7SAndroid Build Coastguard Worker {
2083*fd1fabb7SAndroid Build Coastguard Worker
2084*fd1fabb7SAndroid Build Coastguard Worker uint32 x = DecodeUTF8 (sPtr);
2085*fd1fabb7SAndroid Build Coastguard Worker
2086*fd1fabb7SAndroid Build Coastguard Worker if (x <= 0x007F)
2087*fd1fabb7SAndroid Build Coastguard Worker {
2088*fd1fabb7SAndroid Build Coastguard Worker
2089*fd1fabb7SAndroid Build Coastguard Worker CheckSpaceLeftInBuffer (dPtr, destEnd, 1);
2090*fd1fabb7SAndroid Build Coastguard Worker *(dPtr++) = (char) x;
2091*fd1fabb7SAndroid Build Coastguard Worker
2092*fd1fabb7SAndroid Build Coastguard Worker }
2093*fd1fabb7SAndroid Build Coastguard Worker
2094*fd1fabb7SAndroid Build Coastguard Worker else
2095*fd1fabb7SAndroid Build Coastguard Worker {
2096*fd1fabb7SAndroid Build Coastguard Worker
2097*fd1fabb7SAndroid Build Coastguard Worker const char *ascii = NULL;
2098*fd1fabb7SAndroid Build Coastguard Worker
2099*fd1fabb7SAndroid Build Coastguard Worker const uint32 kTableEntrys = sizeof (kUnicodeToLowASCII ) /
2100*fd1fabb7SAndroid Build Coastguard Worker sizeof (kUnicodeToLowASCII [0]);
2101*fd1fabb7SAndroid Build Coastguard Worker
2102*fd1fabb7SAndroid Build Coastguard Worker for (uint32 entry = 0; entry < kTableEntrys; entry++)
2103*fd1fabb7SAndroid Build Coastguard Worker {
2104*fd1fabb7SAndroid Build Coastguard Worker
2105*fd1fabb7SAndroid Build Coastguard Worker if (kUnicodeToLowASCII [entry] . unicode == x)
2106*fd1fabb7SAndroid Build Coastguard Worker {
2107*fd1fabb7SAndroid Build Coastguard Worker
2108*fd1fabb7SAndroid Build Coastguard Worker ascii = kUnicodeToLowASCII [entry] . ascii;
2109*fd1fabb7SAndroid Build Coastguard Worker
2110*fd1fabb7SAndroid Build Coastguard Worker break;
2111*fd1fabb7SAndroid Build Coastguard Worker
2112*fd1fabb7SAndroid Build Coastguard Worker }
2113*fd1fabb7SAndroid Build Coastguard Worker
2114*fd1fabb7SAndroid Build Coastguard Worker }
2115*fd1fabb7SAndroid Build Coastguard Worker
2116*fd1fabb7SAndroid Build Coastguard Worker if (ascii)
2117*fd1fabb7SAndroid Build Coastguard Worker {
2118*fd1fabb7SAndroid Build Coastguard Worker
2119*fd1fabb7SAndroid Build Coastguard Worker while (*ascii)
2120*fd1fabb7SAndroid Build Coastguard Worker {
2121*fd1fabb7SAndroid Build Coastguard Worker
2122*fd1fabb7SAndroid Build Coastguard Worker CheckSpaceLeftInBuffer (dPtr, destEnd, 1);
2123*fd1fabb7SAndroid Build Coastguard Worker *(dPtr++) = *(ascii++);
2124*fd1fabb7SAndroid Build Coastguard Worker
2125*fd1fabb7SAndroid Build Coastguard Worker }
2126*fd1fabb7SAndroid Build Coastguard Worker
2127*fd1fabb7SAndroid Build Coastguard Worker }
2128*fd1fabb7SAndroid Build Coastguard Worker
2129*fd1fabb7SAndroid Build Coastguard Worker else
2130*fd1fabb7SAndroid Build Coastguard Worker {
2131*fd1fabb7SAndroid Build Coastguard Worker
2132*fd1fabb7SAndroid Build Coastguard Worker CheckSpaceLeftInBuffer (dPtr, destEnd, 1);
2133*fd1fabb7SAndroid Build Coastguard Worker *(dPtr++) ='?';
2134*fd1fabb7SAndroid Build Coastguard Worker
2135*fd1fabb7SAndroid Build Coastguard Worker }
2136*fd1fabb7SAndroid Build Coastguard Worker
2137*fd1fabb7SAndroid Build Coastguard Worker }
2138*fd1fabb7SAndroid Build Coastguard Worker
2139*fd1fabb7SAndroid Build Coastguard Worker }
2140*fd1fabb7SAndroid Build Coastguard Worker
2141*fd1fabb7SAndroid Build Coastguard Worker CheckSpaceLeftInBuffer (dPtr, destEnd, 1);
2142*fd1fabb7SAndroid Build Coastguard Worker *dPtr = 0;
2143*fd1fabb7SAndroid Build Coastguard Worker
2144*fd1fabb7SAndroid Build Coastguard Worker Set (tempBuffer.Buffer_char ());
2145*fd1fabb7SAndroid Build Coastguard Worker
2146*fd1fabb7SAndroid Build Coastguard Worker }
2147*fd1fabb7SAndroid Build Coastguard Worker
2148*fd1fabb7SAndroid Build Coastguard Worker }
2149*fd1fabb7SAndroid Build Coastguard Worker
2150*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
2151*fd1fabb7SAndroid Build Coastguard Worker
2152*fd1fabb7SAndroid Build Coastguard Worker static dng_mutex gProtectUCCalls ("gProtectUCCalls");
2153*fd1fabb7SAndroid Build Coastguard Worker
2154*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
2155*fd1fabb7SAndroid Build Coastguard Worker
Compare(const dng_string & s) const2156*fd1fabb7SAndroid Build Coastguard Worker int32 dng_string::Compare (const dng_string &s) const
2157*fd1fabb7SAndroid Build Coastguard Worker {
2158*fd1fabb7SAndroid Build Coastguard Worker
2159*fd1fabb7SAndroid Build Coastguard Worker #if qMacOS
2160*fd1fabb7SAndroid Build Coastguard Worker #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
2161*fd1fabb7SAndroid Build Coastguard Worker
2162*fd1fabb7SAndroid Build Coastguard Worker // TODO: Needs implementation.
2163*fd1fabb7SAndroid Build Coastguard Worker ThrowProgramError ("Compare() not implemented on iOS");
2164*fd1fabb7SAndroid Build Coastguard Worker return 0;
2165*fd1fabb7SAndroid Build Coastguard Worker
2166*fd1fabb7SAndroid Build Coastguard Worker #else
2167*fd1fabb7SAndroid Build Coastguard Worker
2168*fd1fabb7SAndroid Build Coastguard Worker {
2169*fd1fabb7SAndroid Build Coastguard Worker
2170*fd1fabb7SAndroid Build Coastguard Worker dng_memory_data aStrA;
2171*fd1fabb7SAndroid Build Coastguard Worker dng_memory_data aStrB;
2172*fd1fabb7SAndroid Build Coastguard Worker
2173*fd1fabb7SAndroid Build Coastguard Worker uint32 aLenA = this->Get_UTF16 (aStrA);
2174*fd1fabb7SAndroid Build Coastguard Worker uint32 aLenB = s .Get_UTF16 (aStrB);
2175*fd1fabb7SAndroid Build Coastguard Worker
2176*fd1fabb7SAndroid Build Coastguard Worker if (aLenA > 0)
2177*fd1fabb7SAndroid Build Coastguard Worker {
2178*fd1fabb7SAndroid Build Coastguard Worker
2179*fd1fabb7SAndroid Build Coastguard Worker if (aLenB > 0)
2180*fd1fabb7SAndroid Build Coastguard Worker {
2181*fd1fabb7SAndroid Build Coastguard Worker
2182*fd1fabb7SAndroid Build Coastguard Worker // For some Mac OS versions anyway, UCCompareTextDefault is not
2183*fd1fabb7SAndroid Build Coastguard Worker // thread safe.
2184*fd1fabb7SAndroid Build Coastguard Worker
2185*fd1fabb7SAndroid Build Coastguard Worker dng_lock_mutex lockMutex (&gProtectUCCalls);
2186*fd1fabb7SAndroid Build Coastguard Worker
2187*fd1fabb7SAndroid Build Coastguard Worker UCCollateOptions aOptions = kUCCollateStandardOptions |
2188*fd1fabb7SAndroid Build Coastguard Worker kUCCollatePunctuationSignificantMask;
2189*fd1fabb7SAndroid Build Coastguard Worker
2190*fd1fabb7SAndroid Build Coastguard Worker SInt32 aOrder = -1;
2191*fd1fabb7SAndroid Build Coastguard Worker
2192*fd1fabb7SAndroid Build Coastguard Worker Boolean aEqual = false;
2193*fd1fabb7SAndroid Build Coastguard Worker
2194*fd1fabb7SAndroid Build Coastguard Worker OSStatus searchStatus = ::UCCompareTextDefault (aOptions,
2195*fd1fabb7SAndroid Build Coastguard Worker aStrA.Buffer_uint16 (),
2196*fd1fabb7SAndroid Build Coastguard Worker aLenA,
2197*fd1fabb7SAndroid Build Coastguard Worker aStrB.Buffer_uint16 (),
2198*fd1fabb7SAndroid Build Coastguard Worker aLenB,
2199*fd1fabb7SAndroid Build Coastguard Worker &aEqual,
2200*fd1fabb7SAndroid Build Coastguard Worker &aOrder);
2201*fd1fabb7SAndroid Build Coastguard Worker
2202*fd1fabb7SAndroid Build Coastguard Worker if (searchStatus == noErr)
2203*fd1fabb7SAndroid Build Coastguard Worker {
2204*fd1fabb7SAndroid Build Coastguard Worker
2205*fd1fabb7SAndroid Build Coastguard Worker if (aEqual || (aOrder == 0))
2206*fd1fabb7SAndroid Build Coastguard Worker {
2207*fd1fabb7SAndroid Build Coastguard Worker return 0;
2208*fd1fabb7SAndroid Build Coastguard Worker }
2209*fd1fabb7SAndroid Build Coastguard Worker
2210*fd1fabb7SAndroid Build Coastguard Worker else
2211*fd1fabb7SAndroid Build Coastguard Worker {
2212*fd1fabb7SAndroid Build Coastguard Worker return (aOrder > 0) ? 1 : -1;
2213*fd1fabb7SAndroid Build Coastguard Worker }
2214*fd1fabb7SAndroid Build Coastguard Worker
2215*fd1fabb7SAndroid Build Coastguard Worker }
2216*fd1fabb7SAndroid Build Coastguard Worker
2217*fd1fabb7SAndroid Build Coastguard Worker else
2218*fd1fabb7SAndroid Build Coastguard Worker {
2219*fd1fabb7SAndroid Build Coastguard Worker
2220*fd1fabb7SAndroid Build Coastguard Worker DNG_REPORT ("UCCompareTextDefault failed");
2221*fd1fabb7SAndroid Build Coastguard Worker
2222*fd1fabb7SAndroid Build Coastguard Worker return -1;
2223*fd1fabb7SAndroid Build Coastguard Worker
2224*fd1fabb7SAndroid Build Coastguard Worker }
2225*fd1fabb7SAndroid Build Coastguard Worker
2226*fd1fabb7SAndroid Build Coastguard Worker }
2227*fd1fabb7SAndroid Build Coastguard Worker
2228*fd1fabb7SAndroid Build Coastguard Worker else
2229*fd1fabb7SAndroid Build Coastguard Worker {
2230*fd1fabb7SAndroid Build Coastguard Worker return 1;
2231*fd1fabb7SAndroid Build Coastguard Worker }
2232*fd1fabb7SAndroid Build Coastguard Worker
2233*fd1fabb7SAndroid Build Coastguard Worker }
2234*fd1fabb7SAndroid Build Coastguard Worker
2235*fd1fabb7SAndroid Build Coastguard Worker else
2236*fd1fabb7SAndroid Build Coastguard Worker {
2237*fd1fabb7SAndroid Build Coastguard Worker
2238*fd1fabb7SAndroid Build Coastguard Worker if (aLenB > 0)
2239*fd1fabb7SAndroid Build Coastguard Worker {
2240*fd1fabb7SAndroid Build Coastguard Worker return -1;
2241*fd1fabb7SAndroid Build Coastguard Worker }
2242*fd1fabb7SAndroid Build Coastguard Worker
2243*fd1fabb7SAndroid Build Coastguard Worker else
2244*fd1fabb7SAndroid Build Coastguard Worker {
2245*fd1fabb7SAndroid Build Coastguard Worker return 0;
2246*fd1fabb7SAndroid Build Coastguard Worker }
2247*fd1fabb7SAndroid Build Coastguard Worker
2248*fd1fabb7SAndroid Build Coastguard Worker }
2249*fd1fabb7SAndroid Build Coastguard Worker
2250*fd1fabb7SAndroid Build Coastguard Worker }
2251*fd1fabb7SAndroid Build Coastguard Worker
2252*fd1fabb7SAndroid Build Coastguard Worker #endif // TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
2253*fd1fabb7SAndroid Build Coastguard Worker
2254*fd1fabb7SAndroid Build Coastguard Worker #elif qWinOS
2255*fd1fabb7SAndroid Build Coastguard Worker
2256*fd1fabb7SAndroid Build Coastguard Worker {
2257*fd1fabb7SAndroid Build Coastguard Worker
2258*fd1fabb7SAndroid Build Coastguard Worker dng_memory_data aStrA;
2259*fd1fabb7SAndroid Build Coastguard Worker dng_memory_data aStrB;
2260*fd1fabb7SAndroid Build Coastguard Worker
2261*fd1fabb7SAndroid Build Coastguard Worker uint32 aLenA = this->Get_UTF16 (aStrA);
2262*fd1fabb7SAndroid Build Coastguard Worker uint32 aLenB = s .Get_UTF16 (aStrB);
2263*fd1fabb7SAndroid Build Coastguard Worker
2264*fd1fabb7SAndroid Build Coastguard Worker if (aLenA > 0)
2265*fd1fabb7SAndroid Build Coastguard Worker {
2266*fd1fabb7SAndroid Build Coastguard Worker
2267*fd1fabb7SAndroid Build Coastguard Worker if (aLenB > 0)
2268*fd1fabb7SAndroid Build Coastguard Worker {
2269*fd1fabb7SAndroid Build Coastguard Worker
2270*fd1fabb7SAndroid Build Coastguard Worker LCID locale = LOCALE_SYSTEM_DEFAULT;
2271*fd1fabb7SAndroid Build Coastguard Worker
2272*fd1fabb7SAndroid Build Coastguard Worker DWORD aFlags = NORM_IGNOREWIDTH;
2273*fd1fabb7SAndroid Build Coastguard Worker
2274*fd1fabb7SAndroid Build Coastguard Worker int aOrder = ::CompareStringW (locale,
2275*fd1fabb7SAndroid Build Coastguard Worker aFlags,
2276*fd1fabb7SAndroid Build Coastguard Worker (const WCHAR *) aStrA.Buffer_uint16 (),
2277*fd1fabb7SAndroid Build Coastguard Worker aLenA,
2278*fd1fabb7SAndroid Build Coastguard Worker (const WCHAR *) aStrB.Buffer_uint16 (),
2279*fd1fabb7SAndroid Build Coastguard Worker aLenB);
2280*fd1fabb7SAndroid Build Coastguard Worker
2281*fd1fabb7SAndroid Build Coastguard Worker if (aOrder == CSTR_EQUAL)
2282*fd1fabb7SAndroid Build Coastguard Worker {
2283*fd1fabb7SAndroid Build Coastguard Worker return 0;
2284*fd1fabb7SAndroid Build Coastguard Worker }
2285*fd1fabb7SAndroid Build Coastguard Worker
2286*fd1fabb7SAndroid Build Coastguard Worker else if (aOrder == CSTR_GREATER_THAN)
2287*fd1fabb7SAndroid Build Coastguard Worker {
2288*fd1fabb7SAndroid Build Coastguard Worker return 1;
2289*fd1fabb7SAndroid Build Coastguard Worker }
2290*fd1fabb7SAndroid Build Coastguard Worker
2291*fd1fabb7SAndroid Build Coastguard Worker else
2292*fd1fabb7SAndroid Build Coastguard Worker {
2293*fd1fabb7SAndroid Build Coastguard Worker return -1;
2294*fd1fabb7SAndroid Build Coastguard Worker }
2295*fd1fabb7SAndroid Build Coastguard Worker
2296*fd1fabb7SAndroid Build Coastguard Worker }
2297*fd1fabb7SAndroid Build Coastguard Worker
2298*fd1fabb7SAndroid Build Coastguard Worker else
2299*fd1fabb7SAndroid Build Coastguard Worker {
2300*fd1fabb7SAndroid Build Coastguard Worker return 1;
2301*fd1fabb7SAndroid Build Coastguard Worker }
2302*fd1fabb7SAndroid Build Coastguard Worker
2303*fd1fabb7SAndroid Build Coastguard Worker }
2304*fd1fabb7SAndroid Build Coastguard Worker
2305*fd1fabb7SAndroid Build Coastguard Worker else
2306*fd1fabb7SAndroid Build Coastguard Worker {
2307*fd1fabb7SAndroid Build Coastguard Worker
2308*fd1fabb7SAndroid Build Coastguard Worker if (aLenB > 0)
2309*fd1fabb7SAndroid Build Coastguard Worker {
2310*fd1fabb7SAndroid Build Coastguard Worker return -1;
2311*fd1fabb7SAndroid Build Coastguard Worker }
2312*fd1fabb7SAndroid Build Coastguard Worker else
2313*fd1fabb7SAndroid Build Coastguard Worker {
2314*fd1fabb7SAndroid Build Coastguard Worker return 0;
2315*fd1fabb7SAndroid Build Coastguard Worker }
2316*fd1fabb7SAndroid Build Coastguard Worker
2317*fd1fabb7SAndroid Build Coastguard Worker }
2318*fd1fabb7SAndroid Build Coastguard Worker
2319*fd1fabb7SAndroid Build Coastguard Worker }
2320*fd1fabb7SAndroid Build Coastguard Worker
2321*fd1fabb7SAndroid Build Coastguard Worker #else
2322*fd1fabb7SAndroid Build Coastguard Worker
2323*fd1fabb7SAndroid Build Coastguard Worker // Fallback to a pure Unicode sort order.
2324*fd1fabb7SAndroid Build Coastguard Worker
2325*fd1fabb7SAndroid Build Coastguard Worker {
2326*fd1fabb7SAndroid Build Coastguard Worker
2327*fd1fabb7SAndroid Build Coastguard Worker for (uint32 pass = 0; pass < 2; pass++)
2328*fd1fabb7SAndroid Build Coastguard Worker {
2329*fd1fabb7SAndroid Build Coastguard Worker
2330*fd1fabb7SAndroid Build Coastguard Worker const char *aPtr = Get ();
2331*fd1fabb7SAndroid Build Coastguard Worker const char *bPtr = s.Get ();
2332*fd1fabb7SAndroid Build Coastguard Worker
2333*fd1fabb7SAndroid Build Coastguard Worker while (*aPtr || *bPtr)
2334*fd1fabb7SAndroid Build Coastguard Worker {
2335*fd1fabb7SAndroid Build Coastguard Worker
2336*fd1fabb7SAndroid Build Coastguard Worker if (!bPtr)
2337*fd1fabb7SAndroid Build Coastguard Worker {
2338*fd1fabb7SAndroid Build Coastguard Worker return 1;
2339*fd1fabb7SAndroid Build Coastguard Worker }
2340*fd1fabb7SAndroid Build Coastguard Worker
2341*fd1fabb7SAndroid Build Coastguard Worker else if (!aPtr)
2342*fd1fabb7SAndroid Build Coastguard Worker {
2343*fd1fabb7SAndroid Build Coastguard Worker return -1;
2344*fd1fabb7SAndroid Build Coastguard Worker }
2345*fd1fabb7SAndroid Build Coastguard Worker
2346*fd1fabb7SAndroid Build Coastguard Worker uint32 a = DecodeUTF8 (aPtr);
2347*fd1fabb7SAndroid Build Coastguard Worker uint32 b = DecodeUTF8 (bPtr);
2348*fd1fabb7SAndroid Build Coastguard Worker
2349*fd1fabb7SAndroid Build Coastguard Worker // Ignore case on first compare pass.
2350*fd1fabb7SAndroid Build Coastguard Worker
2351*fd1fabb7SAndroid Build Coastguard Worker if (pass == 0)
2352*fd1fabb7SAndroid Build Coastguard Worker {
2353*fd1fabb7SAndroid Build Coastguard Worker
2354*fd1fabb7SAndroid Build Coastguard Worker if (a >= (uint32) 'a' && a <= (uint32) 'z')
2355*fd1fabb7SAndroid Build Coastguard Worker {
2356*fd1fabb7SAndroid Build Coastguard Worker a = a - (uint32) 'a' + (uint32) 'A';
2357*fd1fabb7SAndroid Build Coastguard Worker }
2358*fd1fabb7SAndroid Build Coastguard Worker
2359*fd1fabb7SAndroid Build Coastguard Worker if (b >= (uint32) 'a' && b <= (uint32) 'z')
2360*fd1fabb7SAndroid Build Coastguard Worker {
2361*fd1fabb7SAndroid Build Coastguard Worker b = b - (uint32) 'a' + (uint32) 'A';
2362*fd1fabb7SAndroid Build Coastguard Worker }
2363*fd1fabb7SAndroid Build Coastguard Worker
2364*fd1fabb7SAndroid Build Coastguard Worker }
2365*fd1fabb7SAndroid Build Coastguard Worker
2366*fd1fabb7SAndroid Build Coastguard Worker if (b > a)
2367*fd1fabb7SAndroid Build Coastguard Worker {
2368*fd1fabb7SAndroid Build Coastguard Worker return 1;
2369*fd1fabb7SAndroid Build Coastguard Worker }
2370*fd1fabb7SAndroid Build Coastguard Worker
2371*fd1fabb7SAndroid Build Coastguard Worker else if (a < b)
2372*fd1fabb7SAndroid Build Coastguard Worker {
2373*fd1fabb7SAndroid Build Coastguard Worker return -1;
2374*fd1fabb7SAndroid Build Coastguard Worker }
2375*fd1fabb7SAndroid Build Coastguard Worker
2376*fd1fabb7SAndroid Build Coastguard Worker }
2377*fd1fabb7SAndroid Build Coastguard Worker
2378*fd1fabb7SAndroid Build Coastguard Worker }
2379*fd1fabb7SAndroid Build Coastguard Worker
2380*fd1fabb7SAndroid Build Coastguard Worker }
2381*fd1fabb7SAndroid Build Coastguard Worker
2382*fd1fabb7SAndroid Build Coastguard Worker #endif
2383*fd1fabb7SAndroid Build Coastguard Worker
2384*fd1fabb7SAndroid Build Coastguard Worker return 0;
2385*fd1fabb7SAndroid Build Coastguard Worker
2386*fd1fabb7SAndroid Build Coastguard Worker }
2387*fd1fabb7SAndroid Build Coastguard Worker
2388*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
2389