OSDN Git Service

first commit
[soopy/alpha1.git] / src / SjisRW.cpp
1 /*
2  * Programming Language SOOPY
3  *   (Simple Object Oriented Programming sYstem)
4  * 
5  * Copyright (C) 2002,2003 SUZUKI Jun
6  * 
7  * URL: http://sourceforge.jp/projects/soopy/
8  * License: GPL(GNU General Public License)
9  * 
10  * 
11  * $Id: SjisRW.cpp,v 1.28 2004/05/22 05:22:34 randy Exp $
12  */
13
14 #ifdef __WIN32__
15 #include <io.h>
16 #else
17 #include <unistd.h>
18 #include <stdio.h>
19 #endif
20
21 #include "soopy.h"
22
23 /*
24  * Class SjisReadEncoder
25  *   TronCode -> Sjis
26  */
27
28 SpChar SjisReadEncoder::readCh()
29 {
30     SpChar c, ch, ch2, ku, ten;
31
32     if(count >= 0){
33         return buf[count--];
34     }
35     if(eof()){ return (SpChar)NULL; }
36     c = reader->ReadChar();
37 //printf("w-code: %x\n", c);
38     if(isEOF(c)){ return (SpChar)NULL; }
39
40     if(!EqualCharCode(c, CodeJIS)){
41         return c;
42     }
43
44     ch = SpCharGetChar(c);
45     ku = (ch >> 8);
46     ten = (ch & 0xFF);
47     if(ku == 0){
48         return ten;
49     }else{
50         ku  -= 0x20;
51         ten -= 0x20;
52         // first byte
53         if(ku < 63){
54 //printf("ku1: %x\n", (unsigned char)(0x81 + ((ku-1)>>1)));
55             ch2 = ((unsigned char)(0x81 + ((ku-1)>>1)));
56         }else{
57 //printf("ku2: %x\n", (unsigned char)(0xE0 + ((ku-63)>>1)));
58             ch2 = ((unsigned char)(0xE0 + ((ku-63)>>1)));
59         }
60         // second byte
61         if(ku & 1){
62             if(ten < 0x3F){
63 //printf("ten1: %x\n", (unsigned char)(ten + 0x3F));
64                 buf[0] = ((unsigned char)(ten + 0x3F));
65             }else{
66 //printf("ten2: %x\n", (unsigned char)(ten + 0x40));
67                 buf[0] = ((unsigned char)(ten + 0x40));
68             }
69         }else{
70 //printf("ten3: %x\n", (unsigned char)(0x9E + ten));
71             buf[0] = ((unsigned char)(0x9E + ten));
72         }
73         count = 0;
74     }
75     return ch2;
76 }
77
78 /*
79  * Class SjisReadDecoder
80  *   Sjis -> TronCode
81  */
82
83 SpChar SjisReadDecoder::readCh()
84 {
85     SpChar c;
86     int ch1, ch2;
87     int ku, ten, base1, base2;
88     if(eof()){ return (SpChar)NULL; }
89     c = reader->ReadChar();
90     if(isEOF(c)){ return (SpChar)NULL; }
91     ch1 = c & 0xff;
92     if(ch1 > 0x7F){
93         /*
94         if(0xA1 <= ch1 && ch1 <= 0xDF){ // when hankaku KANA
95             // return Zenkaku KANA
96         }
97         */
98         if((0x81 <= ch1 && ch1 <= 0x9F) 
99            || (0xE0 <= ch1 && ch1 <= 0xEF)) // JIS X 0208
100         {
101             if(eof()){ return (SpChar)NULL; }
102             c = reader->ReadChar();
103             ch2 = c & 0xff;
104             base1 = ch1 < 0xA0 ? 0x80 : 0xDF;
105             base2 = ch1 < 0xA0 ? 0 : 62;
106             //if(ch2 < 0x9E){
107             if(ch2 < 0x9F){
108                 ku = ((ch1 - base1)<<1) - 1 + base2;
109                 ten = ch2 - (ch2 < 0x7F ? 0x3F : 0x40);
110             }else{
111                 ku = ((ch1 - base1)<<1) + base2;
112                 ten = ch2 - 0x9E;
113             }
114             ku += 0x20;
115             ten += 0x20;
116 //printf("ch: %x\n", MakeSpChar(CodeJIS, (ku<<8) | ten));
117             return MakeSpChar(CodeJIS, (ku<<8) | ten);
118         }else{
119             return MakeSpChar(CodeJIS, '?');
120         }
121     }
122 //printf("ch2: %x\n", MakeSpChar(CodeJIS, c));
123     return MakeSpChar(CodeJIS, c);
124 }
125
126 /*
127  * Class SjisWriteEncoder
128  *   TronCode -> Sjis
129  */
130
131 void SjisWriteEncoder::WriteChar(SpChar c)
132 {
133     int ch, ku, ten;
134
135 //printf("w-code--: %x\n", c);
136     if(!EqualCharCode(c, CodeJIS)){
137         writeTextTronCode(c);
138         return;
139     }
140     ch = SpCharGetChar(c);
141     ku = (ch >> 8);
142     ten = (ch & 0xFF);
143     if(ku == 0){
144         writer->WriteChar(ten);
145     }else{
146         ku  -= 0x20;
147         ten -= 0x20;
148         // put first byte
149         if(ku < 63){
150 //printf("ku_1: %x\n", (unsigned char)(0x81 + ((ku-1)>>1)));
151             writer->WriteChar((unsigned char)(0x81 + ((ku-1)>>1)));
152         }else{
153 //printf("ku_2: %x\n", (unsigned char)(0xE0 + ((ku-63)>>1)));
154              writer->WriteChar((unsigned char)(0xE0 + ((ku-63)>>1)));
155         }
156         // put second byte
157         if(ku & 1){
158             if(ten < 0x3F){
159 //printf("ten_1: %x\n", (unsigned char)(ten + 0x3F));
160                 writer->WriteChar((unsigned char)(ten + 0x3F));
161             }else{
162 //printf("ten_2: %x\n", (unsigned char)(ten + 0x40));
163                 writer->WriteChar((unsigned char)(ten + 0x40));
164             }
165         }else{
166 //printf("ten_3: %x\n", (unsigned char)(0x9E + ten));
167             writer->WriteChar((unsigned char)(0x9E + ten));
168         }
169     }
170 }
171
172
173 /*
174  * Class SjisWriteDecoder
175  *   Sjis -> TronCode
176  */
177
178 void SjisWriteDecoder::WriteChar(SpChar c)
179 {
180     int ch2;
181     int ku, ten, base1, base2;
182
183     if(count == 0){
184         if(c > 0xFF){ // not sjis
185             if(isEOL(c)){
186                 writer->WriteChar(c);
187             }else{
188                 writeTextTronCode(c);
189             }
190         }else if(c > 0x7F){
191             /*
192             if(0xA1 <= ch1 && ch1 <= 0xDF){ // when hankaku KANA
193                 // write Zenkaku KANA
194             }
195             */
196             ch1 = c;
197             count++;
198         }else{
199             writer->WriteChar(c);
200         }
201         return;
202     }
203     // count == 1
204     count = 0;
205     if((0x81 <= ch1 && ch1 <= 0x9F) 
206        || (0xE0 <= ch1 && ch1 <= 0xEF)) // JIS X 0208
207     {
208         ch2 = c;
209         base1 = ch1 < 0xA0 ? 0x80 : 0xDF;
210         base2 = ch1 < 0xA0 ? 0 : 62;
211         if(ch2 < 0x9F){
212             ku = ((ch1 - base1)<<1) - 1 + base2;
213             ten = ch2 - (ch2 < 0x7F ? 0x3F : 0x40);
214         }else{
215             ku = ((ch1 - base1)<<1) + base2;
216             ten = ch2 - 0x9E;
217         }
218         ku += 0x20;
219         ten += 0x20;
220         writer->WriteChar(MakeSpChar(CodeJIS, (ku<<8) | ten));
221     }else{
222         writer->WriteChar(MakeSpChar(CodeJIS, '?'));
223     }
224 }
225
226
227 /*
228  * SjisFile
229  *   openIn, openOut
230  */
231
232 SpValue& sjis_openIn(SpValue& v)
233 {
234     SpValue name = v.eval();
235     if(!name.isString()){
236         throw SpException("filename is not string (Sjis.openIn)");
237     }
238     SpString* str = name.asString();
239     char* filename = (char*)str->toCStringWithEncoder();
240     ifstream* fin = new ifstream;
241 #ifdef __WIN32__
242     fin->open(filename, ios::binary);
243 #else
244     fin->open(filename);
245 #endif
246     if(fin->fail()){
247         delete fin;
248         throw SpException("can't open file");
249     }
250     FileStreamReader* sr = new FileStreamReader(fin, filename);
251     ReadEncoder* encoder = new SjisReadDecoder(sr);
252     //    static SpValue result;
253     //    result.setNewObject(encoder);
254     //    return result;
255     return SpObjectResult(encoder);
256 }
257
258 SpValue& sjis_openOut(SpValue& v)
259 {
260     SpValue name = v.eval();
261     if(!name.isString()){
262         throw SpException("filename is not string (Sjis.openOut)");
263     }
264     SpString* str = name.asString();
265     char* filename = (char*)str->toCStringWithEncoder();
266     ofstream* fout = new ofstream;
267 #ifdef __WIN32__
268     fout->open(filename, ios::binary);
269 #else
270     fout->open(filename);
271 #endif
272     if(fout->fail()){
273         delete fout;
274         throw SpException("can't open file");
275     }
276     FileStreamWriter* sw = new FileStreamWriter(fout, filename);
277     WriteEncoder* encoder = new SjisWriteEncoder(sw);
278     //    static SpValue result;
279     //    result.setNewObject(encoder);
280     //    return result;
281     return SpObjectResult(encoder);
282 }
283
284 SpValue& sjis_openAppend(SpValue& v)
285 {
286     SpValue name = v.eval();
287     if(!name.isString()){
288         throw SpException("filename is not string (Sjis.openAppend)");
289     }
290     SpString* str = name.asString();
291     char* filename = (char*)str->toCStringWithEncoder();
292     ofstream* fout = new ofstream;
293 #ifdef __WIN32__
294     fout->open(filename, ios::app | ios::binary);
295 #else
296     fout->open(filename, ios::app);
297 #endif
298     if(fout->fail()){
299         delete fout;
300         throw SpException("can't open file");
301     }
302     FileStreamWriter* sw = new FileStreamWriter(fout, filename);
303     WriteEncoder* encoder = new SjisWriteEncoder(sw);
304     //    static SpValue result;
305     //    result.setNewObject(encoder);
306     //    return result;
307     return SpObjectResult(encoder);
308 }
309
310 SpValue& sjis_encoderIn(SpValue& v)
311 {
312     SpValue r = v.eval();
313     if(!r.isReader()){
314         throw SpException("not reader (Sjis.encoderIn)");
315     }
316     Reader* reader = r.asReader();
317     ReadEncoder* encoder = new SjisReadEncoder(reader);
318     //    static SpValue result;
319     //    result.setNewObject(encoder);
320     //    return result;
321     return SpObjectResult(encoder);
322 }
323
324 SpValue& sjis_decoderIn(SpValue& v)
325 {
326     SpValue r = v.eval();
327     if(!r.isReader()){
328         throw SpException("not reader (Sjis.decoderIn)");
329     }
330     Reader* reader = r.asReader();
331     ReadEncoder* encoder = new SjisReadDecoder(reader);
332     //    static SpValue result;
333     //    result.setNewObject(encoder);
334     //    return result;
335     return SpObjectResult(encoder);
336 }
337
338 SpValue& sjis_encoderOut(SpValue& v)
339 {
340     SpValue w = v.eval();
341     if(!w.isWriter()){
342         throw SpException("not writer (Sjis.encoderOut)");
343     }
344     Writer* writer = w.asWriter();
345     WriteEncoder* encoder = new SjisWriteEncoder(writer);
346     //    static SpValue result;
347     //    result.setNewObject(encoder);
348     //    return result;
349     return SpObjectResult(encoder);
350 }
351
352 SpValue& sjis_decoderOut(SpValue& v)
353 {
354     SpValue w = v.eval();
355     if(!w.isWriter()){
356         throw SpException("not writer (Sjis.decoderOut)");
357     }
358     Writer* writer = w.asWriter();
359     WriteEncoder* encoder = new SjisWriteDecoder(writer);
360     //    static SpValue result;
361     //    result.setNewObject(encoder);
362     //    return result;
363     return SpObjectResult(encoder);
364 }
365
366 // init
367 void initSjisFile()
368 {
369     SpValue SymSjis(new SpSymbol("sjis"));
370     SpNameSpace* ns = new SpNameSpace;
371     SpValue NSSjis(ns);
372     PMainNameSpace->internConst(SymSjis, NSSjis);
373
374     SpValue PrimOpenIn(new SpPrim1(&sjis_openIn));
375     ns->internConst(SymOpenIn, PrimOpenIn);
376     SpValue PrimEncoderIn(new SpPrim1(&sjis_encoderIn));
377     ns->internConst(SymEncoderIn, PrimEncoderIn);
378     SpValue PrimDecoderIn(new SpPrim1(&sjis_decoderIn));
379     ns->internConst(SymDecoderIn, PrimDecoderIn);
380
381     SpValue PrimOpenOut(new SpPrim1(&sjis_openOut));
382     ns->internConst(SymOpenOut, PrimOpenOut);
383     SpValue PrimOpenAppend(new SpPrim1(&sjis_openAppend));
384     ns->internConst(SymOpenAppend, PrimOpenAppend);
385     SpValue PrimEncoderOut(new SpPrim1(&sjis_encoderOut));
386     ns->internConst(SymEncoderOut, PrimEncoderOut);
387     SpValue PrimDecoderOut(new SpPrim1(&sjis_decoderOut));
388     ns->internConst(SymDecoderOut, PrimDecoderOut);
389 }
390