diff options
Diffstat (limited to 'src/sablotr.cpp')
| -rw-r--r-- | src/sablotr.cpp | 121 | 
1 files changed, 121 insertions, 0 deletions
| diff --git a/src/sablotr.cpp b/src/sablotr.cpp new file mode 100644 index 0000000..465648a --- /dev/null +++ b/src/sablotr.cpp @@ -0,0 +1,121 @@ +// +// AUTHOR +// N. Nielsen +// +// LICENSE +// This software is in the public domain. +// +// The software is provided "as is", without warranty of any kind, +// express or implied, including but not limited to the warranties +// of merchantability, fitness for a particular purpose, and +// noninfringement. In no event shall the author(s) be liable for any +// claim, damages, or other liability, whether in an action of +// contract, tort, or otherwise, arising from, out of, or in connection +// with the software or the use or other dealings in the software. +// +// SUPPORT +// Send bug reports to: <nielsen@memberwebs.com> +// +// SITE +// http://memberwebs.com/nielsen/ +// + +// SABLOTRON C++ WRAPPER CONVERSION FUNCTIONS +// + +#include "wchar.h" +#include "sablo.h" + +bool DOM::transcode16to8(const std::basic_string<wchar_t>& data, +						 std::basic_string<char>& ret) +{ +	ret.resize(0); +	ret.reserve(data.length() + (data.length() / 2)); + +	// basic_string.c_str doesn't work properly everywhere +	// most notably not in the g++ std library + +	const wchar_t* c = data.length() ? data.data() : L""; +	const wchar_t* e = c + data.length(); + +	for( ; c != e; c++) +	{ +		if(*c <= 0x007F) +		{ +			ret.append(1, (char)*c); +		} +		else if(*c <= 0x07FF) +		{ +			ret.append(1, (char)(192 | (*c >> 6))); +			ret.append(1, (char)(128 | (*c & 63))); +		} +		else +		{ +			ret.append(1, (char)(224 | (*c >> 12))); +			ret.append(1, (char)(128 | ((*c >> 6) & 63))); +			ret.append(1, (char)(128 | (*c & 63)) ); +		} +	} + +	return true; +} + +bool DOM::transcode8to16(const std::basic_string<char>& data, +						 std::basic_string<wchar_t>& ret) +{ +	ret.resize(0); +	ret.reserve(data.length()); + +	// basic_string.c_str doesn't work properly everywhere +	// most notably not in the g++ std library + +	const char* c = data.length() ? data.data() : ""; +	const char* e = c + data.length(); + +	for( ; c != e; c++) +	{ +		// First 4 bits set +		if((c[0] & 0xF8) == 0xF0 && +		   (c[1] & 0xC0) == 0x80 && +		   (c[2] & 0xC0) == 0x80 && +		   (c[3] & 0xC0) == 0x80) +		{ +			ret.append(1, ((wchar_t)c[0] & 7) << 18 | +				       ((wchar_t)c[1] & 63) << 12 | +					   ((wchar_t)c[2] & 63) << 6 | +					   ((wchar_t)c[3] & 63)); +			c += 3; +		} + +		// First 3 bits set +		else if((c[0] & 0xF0) == 0xE0 && +		        (c[1] & 0xC0) == 0x80 && +				(c[2] & 0xC0) == 0x80) +		{ +			ret.append(1, ((wchar_t)c[0] & 15) << 12 | +				       ((wchar_t)c[1] & 63) << 6 | +					   ((wchar_t)c[2] & 63)); +			c += 2; +		} + +		// First 2 bits set +		else if((c[0] & 0xE0) == 0xC0 && +			    (c[1] & 0xC0) == 0x80) +		{ +			ret.append(1, ((wchar_t)c[0] & 31) << 6 | +					   ((wchar_t)c[1] & 63)); +			c += 1; +		} + +		// First bit set +		else if(!(c[0] & 0x80)) +		{ +			ret.append(1, (wchar_t)c[0]); +		} + +		else +			return false; +	} + +	return true; +} | 
