2
Copyright (c) 2008-2009 NetAllied Systems GmbH
4
This file is part of COLLADABaseUtils.
6
Licensed under the MIT Open Source License,
7
for details please see LICENSE file or the website
8
http://www.opensource.org/licenses/mit-license.php
11
#include "COLLADABUStableHeaders.h"
12
#include "COLLADABUStringUtils.h"
13
#include "COLLADABUException.h"
14
#include "ConvertUTF.h"
19
/* Maximum number of bytes a unicode character can have in UTF8 encoding*/
20
#define MAX_UTF8_CHAR_LENGTH 4
27
//---------------------------------
28
WideString StringUtils::checkNCName ( const WideString &ncName )
31
result.reserve ( ncName.length() );
33
// check if first character is an alpha character
34
const wchar_t& firstCharacter = ncName[0];
36
if ( isNameStartChar(( firstCharacter ) ) )
37
result.append ( 1, firstCharacter );
39
result.append ( 1, '_' );
41
//replace all spaces and colons by underlines
42
for ( size_t i = 1; i<ncName.length(); ++i )
44
const wchar_t& character = ncName[i];
46
if ( isNameChar ( character ) )
47
result.append ( 1, character );
49
result.append ( 1, '_' );
55
//---------------------------------
56
WideString StringUtils::checkID ( const WideString &id )
58
return checkNCName ( id );
61
//---------------------------------
62
String StringUtils::translateToXML ( const String &srcString )
66
for ( unsigned int i=0; i<srcString.length(); ++i )
68
switch ( srcString[i])
71
// returnString += String("
");
74
returnString += String("<");
77
returnString += String(">");
80
returnString += String("&");
83
returnString += String(""");
86
returnString += String("'");
89
returnString += srcString[i];
97
//---------------------------------
98
WideString StringUtils::translateToXML ( const WideString &srcString )
100
WideString returnString;
102
for ( unsigned int i=0; i<srcString.length(); ++i )
104
switch ( srcString[i])
107
// returnString += L"
";
110
returnString += L"<";
113
returnString += L">";
116
returnString += L"&";
119
returnString += L""";
122
returnString += L"'";
125
returnString += srcString[i];
134
//---------------------------------
135
String StringUtils::uriEncode ( const String & sSrc )
137
const char DEC2HEX[16 + 1] = "0123456789ABCDEF";
138
const unsigned char * pSrc = ( const unsigned char * ) sSrc.c_str();
139
const int SRC_LEN = ( const int ) sSrc.length();
140
unsigned char * const pStart = new unsigned char[SRC_LEN * 3];
141
unsigned char * pEnd = pStart;
142
const unsigned char * const SRC_END = pSrc + SRC_LEN;
144
for ( ; pSrc < SRC_END; ++pSrc )
147
*pEnd++ = ( *pSrc == 0x5c ) ? 0x2f : *pSrc;
152
*pEnd++ = DEC2HEX[*pSrc >> 4];
153
*pEnd++ = DEC2HEX[*pSrc & 0x0F];
157
String sResult ( ( char * ) pStart, ( char * ) pEnd );
163
//---------------------------------
164
String StringUtils::replaceDot ( const String& text )
166
std::stringstream stream;
168
for ( size_t i = 0; i < text.length(); ++i )
170
if ( text[i] == '.' )
176
return String(stream.str());
181
//--------------------------------
182
bool StringUtils::equalsIgnoreCase ( const WideString& s1, const WideString& s2 )
184
if ( s1.length() != s2.length() )
187
WideString::const_iterator it1=s1.begin();
188
WideString::const_iterator it2=s2.begin();
190
// has the end of at least one of the strings been reached?
191
while ( (it1!=s1.end()) && (it2!=s2.end()) )
193
if(::toupper(*it1) != ::toupper(*it2)) //letters differ?
195
// proceed to the next character in each string
202
//--------------------------------
203
bool StringUtils::isNameStartChar( wchar_t c )
206
|| ( c >= 'A' && c <= 'Z' )
208
|| ( c >= 'a' && c <= 'z' )
209
|| ( c >= 0xC0 && c <= 0xD6 )
210
|| ( c >= 0xD8 && c <= 0xF6 )
211
|| ( c >= 0xF8 && c <= 0x2FF )
212
|| ( c >= 0x370 && c <= 0x37D )
213
|| ( c >= 0x37F && c <= 0x1FFF )
214
|| ( c >= 0x200C && c <= 0x200D )
215
|| ( c >= 0x2070 && c <= 0x218F )
216
|| ( c >= 0x2C00 && c <= 0x2FEF )
217
|| ( c >= 0x3001 && c <= 0xD7FF )
218
|| ( c >= 0xF900 && c <= 0xFDCF )
219
|| ( c >= 0xFDF0 && c <= 0xFFFD )
220
|| ( c >= 0x10000 && c <= 0xEFFFF);
224
//--------------------------------
225
bool StringUtils::isNameChar( wchar_t c )
227
return isNameStartChar( c )
230
|| ( c >= '0' && c <= '9' )
232
|| ( c >= 0x0300 && c <= 0x036F )
233
|| ( c >= 0x203F && c <= 0x2040 );
236
//--------------------------------
237
WideString StringUtils::utf8String2WideString( const String& utf8String )
239
size_t widesize = utf8String.length();
240
WideString returnWideString;
242
if ( sizeof( wchar_t ) == sizeof(UTF16) )
244
returnWideString.resize( widesize + 1, L'\0' );
245
const UTF8* sourcestart = reinterpret_cast<const UTF8*>( utf8String.c_str() );
246
const UTF8* sourceend = sourcestart + widesize;
247
UTF16* targetstart = reinterpret_cast<UTF16*>( &((returnWideString)[ 0 ]) );
248
UTF16* thisFirstWChar = targetstart;
249
UTF16* targetend = targetstart + widesize;
250
ConversionResult res = ConvertUTF8toUTF16( &sourcestart, sourceend, &targetstart, targetend, strictConversion );
251
returnWideString.resize(targetstart - thisFirstWChar);
253
if ( res != conversionOK )
255
throw Exception(Exception::ERROR_UTF8_2_WIDE, String("Could not convert from UTF8 to wide string."));
260
else if ( sizeof( wchar_t ) == sizeof(UTF32) )
262
returnWideString.resize( widesize + 1, L'\0' );
263
const UTF8* sourcestart = reinterpret_cast<const UTF8*>( utf8String.c_str() );
264
const UTF8* sourceend = sourcestart + widesize;
265
UTF32* targetstart = reinterpret_cast<UTF32*>( &((returnWideString)[ 0 ]) );
266
UTF32* thisFirstWChar = targetstart;
267
UTF32* targetend = targetstart + widesize;
268
ConversionResult res = ConvertUTF8toUTF32( &sourcestart, sourceend, &targetstart, targetend, strictConversion );
269
returnWideString.resize(targetstart - thisFirstWChar);
271
if ( res != conversionOK )
273
throw Exception(Exception::ERROR_UTF8_2_WIDE, String("Could not convert from UTF8 to wide string."));
280
COLLADABU_ASSERT(false);
282
return returnWideString;
285
//--------------------------------
286
String StringUtils::wideString2utf8String( const WideString& wideString )
288
size_t widesize = wideString.length();
291
if ( sizeof( wchar_t ) == sizeof(UTF16) )
293
size_t utf8size = MAX_UTF8_CHAR_LENGTH * widesize + 1;
294
returnString.resize( utf8size, '\0' );
295
const UTF16* sourcestart = reinterpret_cast<const UTF16*>( wideString.c_str() );
296
const UTF16* sourceend = sourcestart + widesize;
297
UTF8* targetstart = reinterpret_cast<UTF8*>( &((returnString)[ 0 ]) );
298
UTF8* thisFirstWChar = targetstart;
299
UTF8* targetend = targetstart + utf8size;
300
ConversionResult res = ConvertUTF16toUTF8( &sourcestart, sourceend, &targetstart, targetend, strictConversion );
302
if ( res != conversionOK )
304
throw Exception(Exception::ERROR_WIDE_2_UTF8, String("Could not convert from wide string to UTF8."));
307
returnString.resize(targetstart - thisFirstWChar);
309
else if ( sizeof( wchar_t ) == sizeof(UTF32) )
311
size_t utf8size = MAX_UTF8_CHAR_LENGTH * widesize + 1;
312
returnString.resize( utf8size, '\0' );
313
const UTF32* sourcestart = reinterpret_cast<const UTF32*>( wideString.c_str() );
314
const UTF32* sourceend = sourcestart + widesize;
315
UTF8* targetstart = reinterpret_cast<UTF8*>( &((returnString)[ 0 ]) );
316
UTF8* thisFirstWChar = targetstart;
317
UTF8* targetend = targetstart + utf8size;
318
ConversionResult res = ConvertUTF32toUTF8( &sourcestart, sourceend, &targetstart, targetend, strictConversion );
320
if ( res != conversionOK )
322
throw Exception(Exception::ERROR_WIDE_2_UTF8, String("Could not convert from wide string to UTF8."));
325
returnString.resize(targetstart - thisFirstWChar);
329
COLLADABU_ASSERT(false);
334
//------------------------------
335
char StringUtils::toUpperASCIIChar( char c )
337
if ( isLowerAsciiChar(c) )
339
return c + 'A' - 'a';