Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hrydgard
GitHub Repository: hrydgard/ppsspp
Path: blob/master/Common/Data/Encoding/Shiftjis.h
3188 views
1
#pragma once
2
3
#include <cstdint>
4
5
// Warning: decodes/encodes JIS, not Unicode.
6
// Use a table to map.
7
struct ShiftJIS {
8
static const uint32_t INVALID = (uint32_t) -1;
9
10
ShiftJIS(const char *c) : c_(c), index_(0) {}
11
12
uint32_t next() {
13
uint32_t j = (uint8_t)c_[index_++];
14
15
int row;
16
bool emojiAdjust = false;
17
switch (j >> 4) {
18
case 0x8:
19
if (j == 0x80) {
20
return INVALID;
21
}
22
// Intentional fall-through.
23
[[fallthrough]];
24
case 0x9:
25
case 0xE:
26
row = ((j & 0x3F) << 1) - 0x01;
27
break;
28
29
case 0xF:
30
emojiAdjust = true;
31
if (j < 0xF4) {
32
row = ((j & 0x7F) << 1) - 0x59;
33
} else if (j < 0xFD) {
34
row = ((j & 0x7F) << 1) - 0x1B;
35
} else {
36
return j;
37
}
38
break;
39
40
// Anything else (i.e. <= 0x7x, 0xAx, 0xBx, 0xCx, and 0xDx) is JIS X 0201, return directly.
41
default:
42
return j;
43
}
44
45
// Okay, if we didn't return, it's time for the second byte (the cell.)
46
j = (uint8_t)c_[index_++];
47
// Not a valid second byte.
48
if (j < 0x40 || j == 0x7F || j >= 0xFD) {
49
return INVALID;
50
}
51
52
if (j >= 0x9F) {
53
// This range means the row was even.
54
++row;
55
j -= 0x7E;
56
} else {
57
if (j >= 0x80) {
58
j -= 0x20;
59
} else {
60
// Yuck. They wrapped around 0x7F, so we subtract one less.
61
j -= 0x20 - 1;
62
}
63
64
if (emojiAdjust) {
65
// These are shoved in where they'll fit.
66
if (row == 0x87) {
67
// First byte was 0xF0.
68
row = 0x81;
69
} else if (row == 0x8B) {
70
// First byte was 0xF2.
71
row = 0x85;
72
} else if (row == 0xCD) {
73
// First byte was 0xF4.
74
row = 0x8F;
75
}
76
}
77
}
78
79
// j is already the cell + 0x20.
80
return ((row + 0x20) << 8) | j;
81
}
82
83
bool end() const {
84
return c_[index_] == 0;
85
}
86
87
int length() const {
88
int len = 0;
89
for (ShiftJIS dec(c_); !dec.end(); dec.next())
90
++len;
91
return len;
92
}
93
94
int byteIndex() const {
95
return index_;
96
}
97
98
static int encode(char *dest, uint32_t j) {
99
int row = (j >> 8) - 0x20;
100
int offsetCell = j & 0xFF;
101
102
// JIS X 0201.
103
if ((j & ~0xFF) == 0) {
104
*dest = j;
105
return 1;
106
}
107
108
if (row < 0x3F) {
109
*dest++ = 0x80 + ((row + 1) >> 1);
110
} else if (row < 0x5F) {
111
// Reduce by 0x40 to account for the above range.
112
*dest++ = 0xE0 + ((row - 0x40 + 1) >> 1);
113
} else if (row >= 0x80) {
114
// TODO
115
}
116
117
if (row & 1) {
118
if (offsetCell < 0x60) {
119
// Subtract one to shift around 0x7F.
120
*dest++ = offsetCell + 0x20 - 1;
121
} else {
122
*dest++ = offsetCell + 0x20;
123
}
124
} else {
125
*dest++ = offsetCell + 0x7E;
126
}
127
128
return 2;
129
}
130
131
static int encodeUnits(uint32_t j) {
132
if ((j & ~0xFF) == 0) {
133
return 1;
134
}
135
return 2;
136
}
137
138
private:
139
const char *c_;
140
int index_;
141
};
142
143