Browse Source

sjis2utf8 now working

vampirefrog 1 year ago
parent
commit
47ffb8ffb4
6 changed files with 81 additions and 167 deletions
  1. 1
    1
      Makefile
  2. 22
    166
      sjis.c
  3. 2
    0
      sjis.h
  4. 24
    0
      sjis2utf8.c
  5. 27
    0
      utf8.c
  6. 5
    0
      utf8.h

+ 1
- 1
Makefile View File

@@ -18,7 +18,7 @@ v68: main.o tools.o v68.o v68io.o v68periph.o v68human.o v68doscall.o v68iocscal
18 18
 xinfo: xinfo.o md5.o cmdline.o
19 19
 	gcc $^ -o $@
20 20
 
21
-sjis2utf8: sjis2utf8.o sjis.o sjis_unicode.o
21
+sjis2utf8: sjis2utf8.o sjis.o sjis_unicode.o utf8.o
22 22
 	gcc $^ -o $@
23 23
 
24 24
 test-mem: test-mem.o v68.o v68human.o v68opm.o v68io.o v68doscall.o v68fecall.o v68iocscall.o okim6258.o ym2151.o vgm.o sjis.o sjis_unicode.o $(MUSASHIOBJS) $(MUSASHIGENOBJS)

+ 22
- 166
sjis.c View File

@@ -1,6 +1,8 @@
1 1
 #include <stdio.h>
2
+#include <string.h>
2 3
 
3 4
 #include "sjis.h"
5
+#include "utf8.h"
4 6
 
5 7
 int sjis_strlen(uint8_t *data, int len) {
6 8
 	int l = 0;
@@ -18,80 +20,24 @@ int sjis_to_utf8(uint8_t *sjis_data, int sjis_len, uint8_t *utf8_data, int utf8_
18 20
 	if(sjis_len < 1) return 0;
19 21
 	if(utf8_len < 1) return -1;
20 22
 
21
-	int j = 0;
23
+	int j = 0, last_byte = 0;
22 24
 	for(int i = 0; i < sjis_len; i++) {
23
-		uint32_t c;
24
-		if((sjis_data[i] >= 0x80 && sjis_data[i] <= 0xa0) || (sjis_data[i] >= 0xe0 && sjis_data[i] <= 0xff)) {
25
-			if(sjis_len - i < 2)
26
-				return -1;
27
-			c = sjis_char_to_unicode((sjis_data[i] << 8) | sjis_data[i+1]);
28
-			i++;
29
-		} else if(sjis_data[i] < 0x20) {
30
-			c = sjis_data[i];
25
+		char b = sjis_data[i];
26
+		if(SJIS_FIRST_CHAR(b)) {
27
+			last_byte = b;
31 28
 		} else {
32
-			c = sjis_char_to_unicode(sjis_data[i]);
33
-		}
34
-
35
-		if(c < 0x80) {
36
-			if(utf8_len - j < 1)
37
-				return j;
38
-			utf8_data[j++] = c;
39
-		} else if(c < 0x800) {
40
-			if(utf8_len - j < 2)
41
-				return j;
42
-			utf8_data[j++] = 192 + c / 64;
43
-			utf8_data[j++] = 128 + c % 64;
44
-		} else if(c - 0xd800u < 0x800) {
45
-			return j;
46
-		} else if(c < 0x10000) {
47
-			if(utf8_len - j < 3)
29
+			char buf[4];
30
+			int l = utf8_encode(sjis_char_to_unicode((last_byte << 8) | b), buf);
31
+			if(j + l >= utf8_len - 1)
48 32
 				return j;
49
-			utf8_data[j++] = 224 + c / 4096;
50
-			utf8_data[j++] = 128 + c / 64 % 64;
51
-			utf8_data[j++] = 128 + c % 64;
52
-		} else if (c<0x110000) {
53
-			if(utf8_len - j < 4)
54
-				return j;
55
-			utf8_data[j++] = 240+c/262144;
56
-			utf8_data[j++] = 128+c/4096%64;
57
-			utf8_data[j++] = 128+c/64%64;
58
-			utf8_data[j++] = 128+c%64;
59
-		} else return j;
33
+			strcpy((char *)utf8_data + j, buf);
34
+			j += l;
35
+			last_byte = 0;
36
+		}
60 37
 	}
61 38
 	return j;
62 39
 }
63 40
 
64
-static void put_escaped(uint8_t c) {
65
-	switch(c) {
66
-		case 0:
67
-			putchar('\\');
68
-			putchar('0');
69
-			break;
70
-		case '\b':
71
-			putchar('\\');
72
-			putchar('b');
73
-			break;
74
-		// case '\r':
75
-		// 	putchar('\\');
76
-		// 	putchar('r');
77
-		// 	break;
78
-		// case '\n':
79
-		// 	putchar('\\');
80
-		// 	putchar('n');
81
-		// 	break;
82
-		case '\t':
83
-			putchar('\\');
84
-			putchar('\t');
85
-			break;
86
-		case '\\':
87
-			putchar('\\');
88
-			putchar('\\');
89
-			break;
90
-		default:
91
-			printf("\\0%02o", c);
92
-	}
93
-}
94
-
95 41
 int sjis_print_utf8(uint8_t *sjis_data, int sjis_len) {
96 42
 	return sjis_write_utf8(stdout, sjis_data, sjis_len);
97 43
 }
@@ -99,110 +45,20 @@ int sjis_print_utf8(uint8_t *sjis_data, int sjis_len) {
99 45
 int sjis_write_utf8(FILE *f, uint8_t *sjis_data, int sjis_len) {
100 46
 	if(sjis_len < 1) return 0;
101 47
 
102
-	int j = 0;
103
-	for(int i = 0; i < sjis_len; i++) {
104
-		uint32_t c;
105
-		if(sjis_data[i] >= 0xf0 && sjis_data[i] <= 0xf3) {
106
-			continue;
107
-		} else if((sjis_data[i] >= 0x80 && sjis_data[i] <= 0xa0) || (sjis_data[i] >= 0xe0 && sjis_data[i] <= 0xef)) {
108
-			if(sjis_len - i < 2)
109
-				return -1;
110
-			c = sjis_char_to_unicode((sjis_data[i] << 8) | sjis_data[i+1]);
111
-			i++;
112
-		} else {
113
-			c = sjis_char_to_unicode(sjis_data[i]);
114
-		}
115
-
116
-		char buf[4];
117
-		if(c < 0x80) {
118
-			buf[0] = c;
119
-			fwrite(buf, 1, 1, f);
120
-		} else if(c < 0x800) {
121
-			buf[0] = 192 + c / 64;
122
-			buf[1] = 128 + c % 64;
123
-			fwrite(buf, 2, 1, f);
124
-		} else if(c - 0xd800u < 0x800) {
125
-		} else if(c < 0x10000) {
126
-			buf[0] = 224 + c / 4096;
127
-			buf[1] = 128 + c / 64 % 64;
128
-			buf[2] = 128 + c % 64;
129
-			fwrite(buf, 3, 1, f);
130
-		} else if (c<0x110000) {
131
-			buf[0] = 240+c/262144;
132
-			buf[1] = 128+c/4096%64;
133
-			buf[2] = 128+c/64%64;
134
-			buf[3] = 128+c%64;
135
-			fwrite(buf, 4, 1, f);
136
-		}
137
-	}
138
-	return j;
139
-}
140
-
141
-int sjis_print_utf8_escaped(uint8_t *sjis_data, int sjis_len) {
142
-	if(sjis_len < 1) return 0;
143
-
144
-	int j = 0;
48
+	int j = 0, last_byte = 0;
145 49
 	for(int i = 0; i < sjis_len; i++) {
146
-		uint32_t c;
147
-		if(sjis_data[i] >= 0xf0 && sjis_data[i] <= 0xf3) {
148
-			continue;
149
-		} else if((sjis_data[i] >= 0x80 && sjis_data[i] <= 0xa0) || (sjis_data[i] >= 0xe0 && sjis_data[i] <= 0xef)) {
150
-			if(sjis_len - i < 2)
151
-				return -1;
152
-			c = sjis_char_to_unicode((sjis_data[i] << 8) | sjis_data[i+1]);
153
-			i++;
154
-		} else if(sjis_data[i] == '"') {
155
-			putchar('\\');
156
-			putchar('"');
157
-		} else if(sjis_data[i] < 0x20) {
158
-			put_escaped(sjis_data[i]);
159
-			continue;
50
+		char b = sjis_data[i];
51
+		if(SJIS_FIRST_CHAR(b)) {
52
+			last_byte = b;
160 53
 		} else {
161
-			c = sjis_char_to_unicode(sjis_data[i]);
162
-		}
163
-
164
-		if(c < 0x80) {
165
-			putchar(c);
166
-		} else if(c < 0x800) {
167
-			putchar(192 + c / 64);
168
-			putchar(128 + c % 64);
169
-		} else if(c - 0xd800u < 0x800) {
170
-		} else if(c < 0x10000) {
171
-			putchar(224 + c / 4096);
172
-			putchar(128 + c / 64 % 64);
173
-			putchar(128 + c % 64);
174
-		} else if (c<0x110000) {
175
-			putchar(240+c/262144);
176
-			putchar(128+c/4096%64);
177
-			putchar(128+c/64%64);
178
-			putchar(128+c%64);
54
+			char buf[4];
55
+			int l = utf8_encode(sjis_char_to_unicode((last_byte << 8) | b), buf);
56
+			if(l) fwrite(buf, l, 1, f);
57
+			j += l;
58
+			last_byte = 0;
179 59
 		}
180 60
 	}
181
-	return j;
182
-}
183
-
184
-int sjis_print_escaped(uint8_t *sjis_data, int sjis_len) {
185
-	if(sjis_len < 1) return 0;
186 61
 
187
-	int j = 0;
188
-	for(int i = 0; i < sjis_len; i++) {
189
-		if(sjis_data[i] >= 0xf0 && sjis_data[i] <= 0xf3) {
190
-			putchar(sjis_data[i]);
191
-			continue;
192
-		} else if((sjis_data[i] >= 0x80 && sjis_data[i] <= 0xa0) || (sjis_data[i] >= 0xe0 && sjis_data[i] <= 0xef)) {
193
-			if(sjis_len - i < 2)
194
-				return -1;
195
-			putchar(sjis_data[i]);
196
-			putchar(sjis_data[i+1]);
197
-			i++;
198
-		} else if(sjis_data[i] < 0x20) {
199
-			put_escaped(sjis_data[i]);
200
-		} else {
201
-			if(sjis_data[i] == '"')
202
-				putchar('\\');
203
-			putchar(sjis_data[i]);
204
-		}
205
-	}
206 62
 	return j;
207 63
 }
208 64
 

+ 2
- 0
sjis.h View File

@@ -4,6 +4,8 @@
4 4
 #include <stdio.h>
5 5
 #include <stdint.h>
6 6
 
7
+#define SJIS_FIRST_CHAR(c) ((c >= 0x80 && c <= 0x84) || (c >= 0x88 && c <= 0x9f) || (c >= 0xe0 && c <= 0xeb) || (c >= 0xf0 && c <= 0xf3))
8
+
7 9
 int sjis_strlen(uint8_t *data, int len);
8 10
 int sjis_to_utf8(uint8_t *sjis_data, int sjis_len, uint8_t *utf8_data, int utf8_len);
9 11
 int utf8_to_sjis(uint8_t *utf8_data, int utf8_len, uint8_t *sjis_data, int sjis_len);

+ 24
- 0
sjis2utf8.c View File

@@ -1,5 +1,29 @@
1 1
 #include "sjis.h"
2
+#include "utf8.h"
3
+
4
+void put_utf8(FILE *f, int c) {
5
+	char buf[4];
6
+	int chars = utf8_encode(c, buf);
7
+	if(chars) {
8
+		fwrite(buf, chars, 1, f);
9
+	}
10
+}
2 11
 
3 12
 int main(int argc, char **argv) {
13
+	FILE *in = stdin, *out = stdout;
14
+	if(argc > 1) in = fopen(argv[1], "rb");
15
+	if(argc > 2) out = fopen(argv[2], "rb");
16
+
17
+	int last_byte = 0;
18
+	int b = 0;
19
+	while((b = fgetc(in)) != EOF) {
20
+		if(SJIS_FIRST_CHAR(b)) {
21
+			last_byte = b;
22
+		} else {
23
+			put_utf8(out, sjis_char_to_unicode((last_byte << 8) | b));
24
+			last_byte = 0;
25
+		}
26
+	}
27
+
4 28
 	return 0;
5 29
 }

+ 27
- 0
utf8.c View File

@@ -0,0 +1,27 @@
1
+#include "utf8.h"
2
+
3
+int utf8_encode(int c, char *buf) {
4
+	if(c < 0x80) {
5
+		buf[0] = c;
6
+		return 1;
7
+	} else if(c < 0x800) {
8
+		buf[0] = 192 + c / 64;
9
+		buf[1] = 128 + c % 64;
10
+		return 2;
11
+	} else if(c - 0xd800u < 0x800) {
12
+	} else if(c < 0x10000) {
13
+		buf[0] = 224 + c / 4096;
14
+		buf[1] = 128 + c / 64 % 64;
15
+		buf[2] = 128 + c % 64;
16
+		return 3;
17
+	} else if (c<0x110000) {
18
+		buf[0] = 240+c/262144;
19
+		buf[1] = 128+c/4096%64;
20
+		buf[2] = 128+c/64%64;
21
+		buf[3] = 128+c%64;
22
+		return 4;
23
+	}
24
+
25
+	buf[0] = c;
26
+	return 1;
27
+}

+ 5
- 0
utf8.h View File

@@ -0,0 +1,5 @@
1
+#pragma once
2
+
3
+int utf8_encode(int c, char *buf);
4
+int utf8_strlen(char *buf);
5
+int utf8_strnlen(char *buf, int n);

Loading…
Cancel
Save