PageRenderTime 39ms CodeModel.GetById 17ms app.highlight 18ms RepoModel.GetById 1ms app.codeStats 0ms

/xbmc/visualizations/Vortex/angelscript/angelscript/source/as_string_util.cpp

http://github.com/xbmc/xbmc
C++ | 264 lines | 168 code | 32 blank | 64 comment | 58 complexity | dff3f7621a001913d60f39e304a0a731 MD5 | raw file
  1/*
  2   AngelCode Scripting Library
  3   Copyright (c) 2003-2009 Andreas Jonsson
  4
  5   This software is provided 'as-is', without any express or implied 
  6   warranty. In no event will the authors be held liable for any 
  7   damages arising from the use of this software.
  8
  9   Permission is granted to anyone to use this software for any 
 10   purpose, including commercial applications, and to alter it and 
 11   redistribute it freely, subject to the following restrictions:
 12
 13   1. The origin of this software must not be misrepresented; you 
 14      must not claim that you wrote the original software. If you use
 15      this software in a product, an acknowledgment in the product 
 16      documentation would be appreciated but is not required.
 17
 18   2. Altered source versions must be plainly marked as such, and 
 19      must not be misrepresented as being the original software.
 20
 21   3. This notice may not be removed or altered from any source 
 22      distribution.
 23
 24   The original version of this library can be located at:
 25   http://www.angelcode.com/angelscript/
 26
 27   Andreas Jonsson
 28   andreas@angelcode.com
 29
 30*/
 31
 32#include "as_config.h"
 33
 34#include <stdarg.h>     // va_list, va_start(), etc
 35#include <stdlib.h>     // strtod(), strtol()
 36#include <stdio.h>      // _vsnprintf()
 37#include <string.h>     // some compilers declare memcpy() here
 38#include <locale.h>     // setlocale()
 39
 40#if !defined(AS_NO_MEMORY_H)
 41#include <memory.h>
 42#endif
 43
 44#include "as_string.h"
 45#include "as_string_util.h"
 46
 47BEGIN_AS_NAMESPACE
 48
 49double asStringScanDouble(const char *string, size_t *numScanned)
 50{
 51	char *end;
 52
 53    // WinCE doesn't have setlocale. Some quick testing on my current platform
 54    // still manages to parse the numbers such as "3.14" even if the decimal for the
 55    // locale is ",".
 56#if !defined(_WIN32_WCE) && !defined(ANDROID)
 57	// Set the locale to C so that we are guaranteed to parse the float value correctly
 58	asCString orig = setlocale(LC_NUMERIC, 0);
 59	setlocale(LC_NUMERIC, "C");
 60#endif
 61
 62	double res = strtod(string, &end);
 63
 64#if !defined(_WIN32_WCE) && !defined(ANDROID)
 65	// Restore the locale
 66	setlocale(LC_NUMERIC, orig.AddressOf());
 67#endif
 68
 69	if( numScanned )
 70		*numScanned = end - string;
 71
 72	return res;
 73}
 74
 75asQWORD asStringScanUInt64(const char *string, int base, size_t *numScanned)
 76{
 77	asASSERT(base == 10 || base == 16);
 78
 79	const char *end = string;
 80
 81	asQWORD res = 0;
 82	if( base == 10 )
 83	{
 84		while( *end >= '0' && *end <= '9' )
 85		{
 86			res *= 10;
 87			res += *end++ - '0';
 88		}
 89	}
 90	else if( base == 16 )
 91	{
 92		while( (*end >= '0' && *end <= '9') ||
 93		       (*end >= 'a' && *end <= 'f') ||
 94		       (*end >= 'A' && *end <= 'F') )
 95		{
 96			res *= 16;
 97			if( *end >= '0' && *end <= '9' )
 98				res += *end++ - '0';
 99			else if( *end >= 'a' && *end <= 'f' )
100				res += *end++ - 'a' + 10;
101			else if( *end >= 'A' && *end <= 'F' )
102				res += *end++ - 'A' + 10;
103		}
104	}
105
106	if( numScanned )
107		*numScanned = end - string;
108
109	return res;
110}
111
112//
113// The function will encode the unicode code point into the outEncodedBuffer, and then
114// return the length of the encoded value. If the input value is not a valid unicode code 
115// point, then the function will return -1.
116//
117// This function is taken from the AngelCode ToolBox.
118//
119int asStringEncodeUTF8(unsigned int value, char *outEncodedBuffer)
120{
121	unsigned char *buf = (unsigned char*)outEncodedBuffer;
122
123	int length = -1;
124
125	if( value <= 0x7F )
126	{
127		buf[0] = static_cast<unsigned char>(value);
128		return 1;
129	}
130	else if( value >= 0x80 && value <= 0x7FF )
131	{
132		// Encode it with 2 characters
133		buf[0] = static_cast<unsigned char>(0xC0 + (value >> 6));
134		length = 2;
135	}
136	else if( (value >= 0x800 && value <= 0xD7FF) || (value >= 0xE000 && value <= 0xFFFF) )
137	{
138		// Note: Values 0xD800 to 0xDFFF are not valid unicode characters
139		buf[0] = static_cast<unsigned char>(0xE0 + (value >> 12));
140		length = 3;
141	}
142	else if( value >= 0x10000 && value <= 0x10FFFF )
143	{
144		buf[0] = static_cast<unsigned char>(0xF0 + (value >> 18));
145		length = 4;
146	}
147
148	int n = length-1;
149	for( ; n > 0; n-- )
150	{
151		buf[n] = static_cast<unsigned char>(0x80 + (value & 0x3F));
152		value >>= 6;
153	}
154
155	return length;
156}
157
158//
159// The function will decode an UTF8 character and return the unicode code point.
160// outLength will receive the number of bytes that were decoded.
161//
162// This function is taken from the AngelCode ToolBox.
163//
164int asStringDecodeUTF8(const char *encodedBuffer, unsigned int *outLength)
165{
166	const unsigned char *buf = (const unsigned char*)encodedBuffer;
167	
168	int value = 0;
169	int length = -1;
170	unsigned char byte = buf[0];
171	if( (byte & 0x80) == 0 )
172	{
173		// This is the only byte
174		if( outLength ) *outLength = 1;
175		return byte;
176	}
177	else if( (byte & 0xE0) == 0xC0 )
178	{
179		// There is one more byte
180		value = int(byte & 0x1F);
181		length = 2;
182
183		// The value at this moment must not be less than 2, because 
184		// that should have been encoded with one byte only.
185		if( value < 2 )
186			length = -1;
187	}
188	else if( (byte & 0xF0) == 0xE0 )
189	{
190		// There are two more bytes
191		value = int(byte & 0x0F);
192		length = 3;
193	}
194	else if( (byte & 0xF8) == 0xF0 )
195	{
196		// There are three more bytes
197		value = int(byte & 0x07);
198		length = 4;
199	}
200
201	int n = 1;
202	for( ; n < length; n++ )
203	{
204		byte = buf[n];
205		if( (byte & 0xC0) == 0x80 )
206			value = (value << 6) + int(byte & 0x3F);
207		else 
208			break;
209	}
210
211	if( n == length )
212	{
213		if( outLength ) *outLength = (unsigned)length;
214		return value;
215	}
216
217	// The byte sequence isn't a valid UTF-8 byte sequence.
218	return -1;
219}
220
221//
222// The function will encode the unicode code point into the outEncodedBuffer, and then
223// return the length of the encoded value. If the input value is not a valid unicode code 
224// point, then the function will return -1.
225//
226// This function is taken from the AngelCode ToolBox.
227//
228int asStringEncodeUTF16(unsigned int value, char *outEncodedBuffer)
229{
230	if( value < 0x10000 )
231	{
232#ifndef AS_BIG_ENDIAN
233		outEncodedBuffer[0] = (value & 0xFF);
234		outEncodedBuffer[1] = ((value >> 8) & 0xFF);
235#else
236		outEncodedBuffer[1] = (value & 0xFF);
237		outEncodedBuffer[0] = ((value >> 8) & 0xFF);
238#endif
239		return 2;
240	}
241	else
242	{
243		value -= 0x10000;
244		int surrogate1 = ((value >> 10) & 0x3FF) + 0xD800;
245		int surrogate2 = (value & 0x3FF) + 0xDC00;
246
247#ifndef AS_BIG_ENDIAN
248		outEncodedBuffer[0] = (surrogate1 & 0xFF);
249		outEncodedBuffer[1] = ((surrogate1 >> 8) & 0xFF);
250		outEncodedBuffer[2] = (surrogate2 & 0xFF);
251		outEncodedBuffer[3] = ((surrogate2 >> 8) & 0xFF);
252#else
253		outEncodedBuffer[1] = (surrogate1 & 0xFF);
254		outEncodedBuffer[0] = ((surrogate1 >> 8) & 0xFF);
255		outEncodedBuffer[3] = (surrogate2 & 0xFF);
256		outEncodedBuffer[2] = ((surrogate2 >> 8) & 0xFF);
257#endif
258
259		return 4;
260	}
261}
262
263
264END_AS_NAMESPACE