OSDN Git Service

first commit
[soopy/alpha1.git] / src / EucJPRW.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: EucJPRW.cpp,v 1.27 2004/05/22 05:22:34 randy Exp $
12  */
13
14 #include "soopy.h"
15
16 /*
17  * Class EucJPReader
18  */
19
20 #include <stdio.h>
21
22 SpChar EucJPReadEncoder::readCh()
23 {
24     SpChar c;
25     int ch, ku, ten;
26
27     if(count >= 0){
28         return buf[count--];
29     }
30     if(eof()){ return (SpChar)NULL; }
31     c = reader->ReadChar();
32     if(isEOF(c)){ return (SpChar)NULL; }
33
34     if(!EqualCharCode(c, CodeJIS)){
35         return c;
36     }
37     ch  = SpCharGetChar(c);
38     ku  = (ch >> 8);
39     ten = (ch & 0xFF);
40     if(ku == 0){
41         return ten;
42     }else{
43         // first byte
44         ku  += 0xA0 - 0x20;
45         // second byte
46         ten += 0xA0 - 0x20;
47         buf[0] = ten;
48         count = 0;
49     }
50     return ku;
51 }
52
53 SpChar EucJPReadDecoder::readCh()
54 {
55     char c;
56     int ch1, ch2;
57
58     if(eof()){ return (SpChar)NULL; }
59     c = reader->ReadChar();
60     if(isEOF(c)){ return (SpChar)NULL; }
61     ch1 = c & 0xff;
62     if(0xA1 <= ch1 && ch1 <= 0xFE){ // JIS X 0208
63         c = reader->ReadChar();
64         ch2 = c & 0xff;
65         ch1 = ch1 - 0xA0 + 0x20;
66         ch2 = ch2 - 0xA0 + 0x20;
67         return MakeSpChar(CodeJIS, (ch1<<8) | ch2);
68     }
69     return MakeSpChar(CodeJIS, c);
70 }
71
72 /*
73  * Class EucJPWriteEncoder
74  */
75
76 void EucJPWriteEncoder::WriteChar(SpChar c)
77 {
78     int ch, ku, ten;
79
80     if(!EqualCharCode(c, CodeJIS)){
81         writeTextTronCode(c);
82         return;
83     }
84     ch  = SpCharGetChar(c);
85     ku  = (ch >> 8);
86     ten = (ch & 0xFF);
87     if(ku == 0){
88         writer->WriteChar((char)ten);
89     }else{
90         ku  += 0xA0 - 0x20;
91         ten += 0xA0 - 0x20;
92         // put first byte
93         writer->WriteChar((char)ku);
94         // put second byte
95         writer->WriteChar((char)ten);
96     }
97 }
98
99 /*
100  * Class EucJPWriteDecoder
101  */
102
103 void EucJPWriteDecoder::WriteChar(SpChar c)
104 {
105     int ch2;
106
107     if(count == 0){
108         if(c > 0xFF){ // not jis
109             if(isEOL(c)){
110                 writer->WriteChar(c);
111             }else{
112                 writeTextTronCode(c);
113             }
114         }else if(0xA1 <= c && c <= 0xFE){ // JIS X 0208
115             /*
116             if(0xA1 <= ch1 && ch1 <= 0xDF){ // when hankaku KANA
117                 // write Zenkaku KANA
118             }
119             */
120             ch1 = c;
121             count++;
122         }else{
123             writer->WriteChar(c);
124         }
125         return;
126     }
127     // count == 1
128     count = 0;
129     ch2 = c;
130     ch1 = ch1 - 0xA0 + 0x20;
131     ch2 = ch2 - 0xA0 + 0x20;
132     writer->WriteChar(MakeSpChar(CodeJIS, (ch1<<8) | ch2));
133 }
134
135 /*
136  * EucJPFile
137  *   openIn, openOut
138  */
139
140 SpValue& eucjp_openIn(SpValue& v)
141 {
142     SpValue name = v.eval();
143     if(!name.isString()){
144         throw SpException("filename is not string (EucJP.openIn)");
145     }
146     SpString* str = name.asString();
147     char* filename = (char*)str->toCStringWithEncoder();
148     ifstream* fin = new ifstream;
149 #ifdef __WIN32__
150     fin->open(filename, ios::binary);
151 #else
152     fin->open(filename);
153 #endif
154     if(fin->fail()){
155         delete fin;
156         throw SpException("can't open file");
157     }
158     FileStreamReader* sr = new FileStreamReader(fin, filename);
159     ReadEncoder* encoder = new EucJPReadDecoder(sr);
160     return SpObjectResult(encoder);
161 }
162
163 SpValue& eucjp_openOut(SpValue& v)
164 {
165     SpValue name = v.eval();
166     if(!name.isString()){
167         throw SpException("filename is not string (EucJP.openOut)");
168     }
169     SpString* str = name.asString();
170     char* filename = (char*)str->toCStringWithEncoder();
171     ofstream* fout = new ofstream;
172 #ifdef __WIN32__
173     fout->open(filename, ios::binary);
174 #else
175     fout->open(filename);
176 #endif
177     if(fout->fail()){
178         delete fout;
179         throw SpException("can't open file");
180     }
181     FileStreamWriter* sw = new FileStreamWriter(fout, filename);
182     WriteEncoder* encoder = new EucJPWriteEncoder(sw);
183     return SpObjectResult(encoder);
184 }
185
186 SpValue& eucjp_openAppend(SpValue& v)
187 {
188     SpValue name = v.eval();
189     if(!name.isString()){
190         throw SpException("filename is not string (EucJP.openAppend)");
191     }
192     SpString* str = name.asString();
193     char* filename = (char*)str->toCStringWithEncoder();
194     ofstream* fout = new ofstream;
195 #ifdef __WIN32__
196     fout->open(filename, ios::app | ios::binary);
197 #else
198     fout->open(filename, ios::app);
199 #endif
200     if(fout->fail()){
201         delete fout;
202         throw SpException("can't open file");
203     }
204     FileStreamWriter* sw = new FileStreamWriter(fout, filename);
205     WriteEncoder* encoder = new EucJPWriteEncoder(sw);
206     //    static SpValue result;
207     //    result.setNewObject(encoder);
208     //    return result;
209     return SpObjectResult(encoder);
210 }
211
212 SpValue& eucjp_encoderIn(SpValue& v)
213 {
214     SpValue r = v.eval();
215     if(!r.isReader()){
216         throw SpException("not reader (EucJP.encoderIn)");
217     }
218     Reader* reader = r.asReader();
219     ReadEncoder* encoder = new EucJPReadEncoder(reader);
220     return SpObjectResult(encoder);
221 }
222
223 SpValue& eucjp_decoderIn(SpValue& v)
224 {
225     SpValue r = v.eval();
226     if(!r.isReader()){
227         throw SpException("not reader (EucJP.decoderIn)");
228     }
229     Reader* reader = r.asReader();
230     ReadEncoder* encoder = new EucJPReadDecoder(reader);
231     return SpObjectResult(encoder);
232 }
233
234 SpValue& eucjp_encoderOut(SpValue& v)
235 {
236     SpValue w = v.eval();
237     if(!w.isWriter()){
238         throw SpException("not writer (EucJP.encoderOut)");
239     }
240     Writer* writer = w.asWriter();
241     WriteEncoder* encoder = new EucJPWriteEncoder(writer);
242     return SpObjectResult(encoder);
243 }
244
245 SpValue& eucjp_decoderOut(SpValue& v)
246 {
247     SpValue w = v.eval();
248     if(!w.isWriter()){
249         throw SpException("not writer (EucJP.decoderOut)");
250     }
251     Writer* writer = w.asWriter();
252     WriteEncoder* encoder = new EucJPWriteDecoder(writer);
253     return SpObjectResult(encoder);
254 }
255
256 // init
257 void initEucJPFile()
258 {
259     SpValue SymEucJP(new SpSymbol("eucjp"));
260     SpNameSpace* ns = new SpNameSpace;
261     SpValue NSEucJP(ns);
262     PMainNameSpace->internConst(SymEucJP, NSEucJP);
263
264     SpValue PrimOpenIn(new SpPrim1(&eucjp_openIn));
265     ns->internConst(SymOpenIn, PrimOpenIn);
266     SpValue PrimEncoderIn(new SpPrim1(&eucjp_encoderIn));
267     ns->internConst(SymEncoderIn, PrimEncoderIn);
268     SpValue PrimDecoderIn(new SpPrim1(&eucjp_decoderIn));
269     ns->internConst(SymDecoderIn, PrimDecoderIn);
270
271     SpValue PrimOpenOut(new SpPrim1(&eucjp_openOut));
272     ns->internConst(SymOpenOut, PrimOpenOut);
273     SpValue PrimOpenAppend(new SpPrim1(&eucjp_openAppend));
274     ns->internConst(SymOpenAppend, PrimOpenAppend);
275     SpValue PrimEncoderOut(new SpPrim1(&eucjp_encoderOut));
276     ns->internConst(SymEncoderOut, PrimEncoderOut);
277     SpValue PrimDecoderOut(new SpPrim1(&eucjp_decoderOut));
278     ns->internConst(SymDecoderOut, PrimDecoderOut);
279 }
280