xref: /aosp_15_r20/external/dng_sdk/source/dng_string.cpp (revision fd1fabb72dbdf09ea7034f531e6f8e9f57334c8d)
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