summaryrefslogtreecommitdiff
path: root/src/sablotr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/sablotr.cpp')
-rw-r--r--src/sablotr.cpp121
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;
+}