// // 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: // // SITE // http://memberwebs.com/nielsen/ // // SABLOTRON C++ WRAPPER CONVERSION FUNCTIONS // #include "wchar.h" #include "sablo.h" bool DOM::transcode16to8(const std::basic_string& data, std::basic_string& 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& data, std::basic_string& 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; }