-
Notifications
You must be signed in to change notification settings - Fork 2
/
sjis.c
115 lines (103 loc) · 2.26 KB
/
sjis.c
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <stdio.h>
#include <string.h>
#include "sjis.h"
#include "utf8.h"
int sjis_strlen(uint8_t *data, int len) {
int l = 0;
for(int i = 0; i < len; i++) {
l++;
if(data[i] >= 0x80) {
l++;
i++;
}
}
return l;
}
int sjis_to_utf8(uint8_t *sjis_data, int sjis_len, uint8_t *utf8_data, int utf8_len) {
if(sjis_len < 1) return 0;
if(utf8_len < 1) return -1;
int j = 0, last_byte = 0;
for(int i = 0; i < sjis_len; i++) {
uint8_t b = sjis_data[i];
if(last_byte == 0 && SJIS_FIRST_CHAR(b)) {
last_byte = b;
} else {
char buf[4];
int l = utf8_encode(sjis_char_to_unicode((last_byte << 8) | b), buf);
if(j + l >= utf8_len - 1)
return j;
strcpy((char *)utf8_data + j, buf);
j += l;
last_byte = 0;
}
}
return j;
}
int sjis_print_utf8(uint8_t *sjis_data, int sjis_len) {
return sjis_write_utf8(stdout, sjis_data, sjis_len);
}
int sjis_write_utf8(FILE *f, uint8_t *sjis_data, int sjis_len) {
if(sjis_len < 1) return 0;
int j = 0, last_byte = 0;
for(int i = 0; i < sjis_len; i++) {
uint8_t b = sjis_data[i];
if(last_byte == 0 && SJIS_FIRST_CHAR(b)) {
last_byte = b;
} else {
char buf[4];
int l = utf8_encode(sjis_char_to_unicode((last_byte << 8) | b), buf);
if(l) fwrite(buf, l, 1, f);
j += l;
last_byte = 0;
}
}
return j;
}
uint16_t jis_to_sjis(uint16_t val) {
uint8_t j2 = val & 0xff;
uint8_t j1 = val >> 8;
uint8_t s1, s2;
if(33 <= j1 && j1 <= 94)
s1 = (j1 + 1) / 2 + 112;
else
s1 = (j1 + 1) / 2 + 176;
if(j1 & 1)
s2 = j2 + 31 + (j2 / 96);
else
s2 = j2 + 126;
return (s1 << 8) | s2;
}
uint16_t jis_from_sjis(uint16_t val) {
int status = 0;
uint8_t j1 = 0;
uint8_t j2 = 0;
uint8_t b1 = val >> 8;
uint8_t b2 = val & 0xff;
if((b1 >= 0x81 && b1 <= 0x84) || (b1 >= 0x87 && b1 <= 0x9f)) {
j1 = 2 * (b1 - 0x70) - 1;
if (b2 >= 0x40 && b2 <= 0x9e) {
j2 = b2 - 31;
if (j2 > 95)
j2 -= 1;
status = 1;
} else if (b2 >= 0x9f && b2 <= 0xfc) {
j2 = b2 - 126;
j1 += 1;
status = 1;
}
} else if (b1 >= 0xe0 && b1 <= 0xef) {
j1 = 2 * (b1 - 0xb0) - 1;
if (b2 >= 0x40 && b2 <= 0x9e) {
j2 = b2 - 31;
if (j2 > 95)
j2 -= 1;
status = 1;
} else if (b2 >= 0x9f && b2 <= 0xfc) {
j2 = b2 - 126;
j1 += 1;
status = 1;
}
}
if(status == 0) return 0;
return (j1 << 8) | j2;
}