-
Notifications
You must be signed in to change notification settings - Fork 224
/
pstring.h
75 lines (70 loc) · 2.07 KB
/
pstring.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// -*- C++ -*-
#ifndef ocropus_clstm_pstring_
#define ocropus_clstm_pstring_
#include <assert.h>
#include <wchar.h>
#include <iostream>
#include <string>
namespace {
std::wstring utf8_to_utf32(std::string s) {
int i = 0;
std::wstring result;
while (i < s.size()) {
unsigned c = unsigned(s[i]);
unsigned w = '~';
if ((c & 0x80) == 0) {
w = c;
i += 1;
} else if ((c & 0xe0) == 0xc0) {
if (i + 1 >= s.size()) THROW("bad encoding");
unsigned c1 = unsigned(s[i + 1]);
w = (((c & 0x1f) << 6) | (c1 & 0x3f));
i += 2;
} else if ((c & 0xf0) == 0xe0) {
if (i + 2 >= s.size()) THROW("bad encoding");
unsigned c1 = unsigned(s[i + 1]);
unsigned c2 = unsigned(s[i + 2]);
w = (((c & 0x0f) << 12) | ((c1 & 0x3f) << 6) | (c2 & 0x3f));
i += 3;
} else if ((c & 0xf8) == 0xf0) {
if (i + 3 >= s.size()) THROW("bad encoding");
unsigned c1 = unsigned(s[i + 1]);
unsigned c2 = unsigned(s[i + 2]);
unsigned c3 = unsigned(s[i + 3]);
w = (((c & 0x0f) << 18) | ((c1 & 0x3f) << 12) | ((c2 & 0x3f) << 6) |
(c3 & 0x3f));
i += 4;
} else {
THROW("unicode character out of range");
}
assert(w != 0);
result.push_back(wchar_t(w));
}
return result;
}
std::string utf32_to_utf8(std::wstring s) {
std::string result;
for (int i = 0; i < s.size(); i++) {
unsigned c = s[i];
if (c < 0x80) {
result.push_back(char(c));
} else if (c <= 0x7ff) {
result.push_back(char((c >> 6) | 0xc0));
result.push_back(char((c & 0x3f) | 0x80));
} else if (c <= 0xffff) {
result.push_back(char((c >> 12) | 0xe0));
result.push_back(char(((c >> 6) & 0x3f) | 0x80));
result.push_back(char((c & 0x3f) | 0x80));
} else if (c <= 0x10ffff) {
result.push_back(char((c >> 18) | 0xf0));
result.push_back(char(((c >> 12) & 0x3f) | 0x80));
result.push_back(char(((c >> 6) & 0x3f) | 0x80));
result.push_back(char((c & 0x3f) | 0x80));
} else {
THROW("unicode character out of range");
}
}
return result;
}
}
#endif