1 /*****************************************************************************/
2 /* Stream Class Library Copyright (c) 1999-2000 Sakai Hiroaki. */
3 /* All Rights Reserved. */
4 /*===========================================================================*/
5 /* This program is free software; you can redistribute it and/or modify */
6 /* it under the terms of the GNU General Public License as published by */
7 /* the Free Software Foundation; either version 2, or (at your option) */
8 /* any later version. */
9 /* */
10 /* This program is distributed in the hope that it will be useful, */
11 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
12 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
13 /* GNU General Public License for more details. */
14 /* */
15 /* You should have received a copy of the GNU General Public License */
16 /* along with this program; see the file COPYING. If not, write to */
17 /* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
18 /*****************************************************************************/
19
20 /*****************************************************************************/
21 /* �������� */
22 /*****************************************************************************/
23
24 #include "StreamP.h"
25
26 /*****************************************************************************/
27 /* �ؿ������ */
28 /*****************************************************************************/
29
30 /*===========================================================================*/
31 /* ���顼���� */
32 /*===========================================================================*/
33
Stream_ErrorExit(char * function,char * message)34 static void Stream_ErrorExit(char * function, char * message)
35 {
36 fprintf(stderr, "Error in %s():%s\n", function, message);
37 exit(1);
38 }
39
40 /*===========================================================================*/
41 /* ���֥������Ȥ����� */
42 /*===========================================================================*/
43
44 /*---------------------------------------------------------------------------*/
45 /* ���֥������Ȥ����� */
46 /*---------------------------------------------------------------------------*/
47
Stream_Create(CreateStreamFrom from,void * object)48 Stream Stream_Create(CreateStreamFrom from, void * object)
49 {
50 Stream this;
51
52 this = (Stream)malloc(sizeof(_Stream));
53 if (this == NULL)
54 Stream_ErrorExit("Stream_Create", "Canot allocate memory.");
55
56 this->unget_buffer = NULL;
57 this->end_flag = 0;
58 this->from = from;
59
60 switch (this->from) {
61
62 case CREATE_NO_STREAM :
63 this->type = STREAM_TYPE_NONE;
64 this->object.dummy = NULL;
65 break;
66
67 case CREATE_STREAM_FROM_FILE :
68 this->type = STREAM_TYPE_FILE_POINTER;
69 this->object.file_pointer = fopen((char *)object, "rt");
70 if (this->object.file_pointer == NULL) {
71 free(this);
72 return (NULL);
73 }
74 break;
75
76 case CREATE_STREAM_FROM_FILE_POINTER :
77 this->type = STREAM_TYPE_FILE_POINTER;
78 this->object.file_pointer = (FILE *)object;
79 break;
80
81 case CREATE_STREAM_FROM_CHARACTERS :
82 this->type = STREAM_TYPE_CHARACTERS;
83 this->object.characters = (char *)object;
84 break;
85
86 default :
87 Stream_ErrorExit("Stream_Create", "Invalid type.");
88 }
89
90 return (this);
91 }
92
93 /*---------------------------------------------------------------------------*/
94 /* �ʤˤ�ʤ��Ȥ���������(���ߡ���) */
95 /*---------------------------------------------------------------------------*/
96
Stream_CreateFromNone()97 Stream Stream_CreateFromNone()
98 {
99 return (Stream_Create(CREATE_NO_STREAM, (void *)NULL));
100 }
101
102 /*---------------------------------------------------------------------------*/
103 /* �ե����뤫������ */
104 /*---------------------------------------------------------------------------*/
105
Stream_CreateFromFile(char * filename)106 Stream Stream_CreateFromFile(char * filename)
107 {
108 return (Stream_Create(CREATE_STREAM_FROM_FILE, (void *)filename));
109 }
110
111 /*---------------------------------------------------------------------------*/
112 /* �ե�����ݥ��������� */
113 /*---------------------------------------------------------------------------*/
114
Stream_CreateFromFilePointer(FILE * fp)115 Stream Stream_CreateFromFilePointer(FILE * fp)
116 {
117 return (Stream_Create(CREATE_STREAM_FROM_FILE_POINTER, (void *)fp));
118 }
119
120 /*---------------------------------------------------------------------------*/
121 /* ʸ����(char * ��)�������� */
122 /*---------------------------------------------------------------------------*/
123
Stream_CreateFromCharacters(char * characters)124 Stream Stream_CreateFromCharacters(char * characters)
125 {
126 return (Stream_Create(CREATE_STREAM_FROM_CHARACTERS, (void *)characters));
127 }
128
129 /*===========================================================================*/
130 /* ���֥������Ȥξõ� */
131 /*===========================================================================*/
132
Stream_Destroy(Stream this)133 int Stream_Destroy(Stream this)
134 {
135 UngetBuffer * p;
136
137 if (!this) Stream_ErrorExit("Stream_Destroy", "Object is not created.");
138
139 switch (this->from) {
140 case CREATE_NO_STREAM :
141 break;
142 case CREATE_STREAM_FROM_FILE :
143 fclose(this->object.file_pointer);
144 break;
145 case CREATE_STREAM_FROM_FILE_POINTER :
146 break;
147 case CREATE_STREAM_FROM_CHARACTERS :
148 break;
149 default :
150 break;
151 }
152
153 while (this->unget_buffer) {
154 p = this->unget_buffer->next;
155 free(this->unget_buffer);
156 this->unget_buffer = p;
157 }
158
159 free(this);
160
161 return (0);
162 }
163
164 /*===========================================================================*/
165 /* ʸ����μ��� */
166 /*===========================================================================*/
167
168 /*---------------------------------------------------------------------------*/
169 /* �ɤ߹���ʸ�����ޤ����뤫�ɤ��� */
170 /*---------------------------------------------------------------------------*/
171
Stream_IsEnd(Stream this)172 int Stream_IsEnd(Stream this)
173 {
174 return (this->end_flag);
175 }
176
177 /*---------------------------------------------------------------------------*/
178 /* Stream ���飱ʸ�������(get)���롥 */
179 /*---------------------------------------------------------------------------*/
180
Stream_GetCharacter(Stream this)181 int Stream_GetCharacter(Stream this)
182 {
183 UngetBuffer * p;
184 int c;
185
186 if (!this) Stream_ErrorExit("Stream_GetCharacter", "Object is not created.");
187
188 if (this->end_flag) {
189 c = EOF;
190 } else if (this->unget_buffer) {
191 c = this->unget_buffer->character;
192 p = this->unget_buffer->next;
193 free(this->unget_buffer);
194 this->unget_buffer = p;
195 } else {
196 switch (this->type) {
197
198 case STREAM_TYPE_NONE :
199 c = EOF;
200 this->end_flag = 1;
201 break;
202
203 case STREAM_TYPE_FILE_POINTER :
204 c = fgetc(this->object.file_pointer);
205 if (c == EOF) this->end_flag = 1;
206 break;
207
208 case STREAM_TYPE_CHARACTERS :
209 c = (int)(*(this->object.characters));
210 if (c == '\0') {
211 c = EOF;
212 this->end_flag = 1;
213 } else {
214 (this->object.characters)++;
215 }
216 break;
217
218 default :
219 Stream_ErrorExit("Stream_GetCharacter", "Invalid type.");
220 }
221 }
222 return (c);
223 }
224
225 /*---------------------------------------------------------------------------*/
226 /* Stream �ˣ�ʸ�����ֵ�(unget)���롥 */
227 /*---------------------------------------------------------------------------*/
228
Stream_UngetCharacter(Stream this,int c)229 int Stream_UngetCharacter(Stream this, int c)
230 {
231 UngetBuffer * p;
232 char character = (char)c;
233
234 if (!this)
235 Stream_ErrorExit("Stream_UngetCharacter", "Object is not created.");
236
237 if (c == EOF) {
238 this->end_flag = 1;
239 return (EOF);
240 }
241
242 p = (UngetBuffer *)malloc(sizeof(UngetBuffer));
243 if (!p) Stream_ErrorExit("Stream_UngetCharacter", "Cannot allocate memory.");
244
245 this->end_flag = 0;
246 p->character = character;
247 p->next = this->unget_buffer;
248 this->unget_buffer = p;
249
250 return (character);
251 }
252
253 /*---------------------------------------------------------------------------*/
254 /* Stream ��ʸ������ֵ�(unget)���롥 */
255 /*---------------------------------------------------------------------------*/
256
Stream_UngetCharacters(Stream this,char * characters)257 int Stream_UngetCharacters(Stream this, char * characters)
258 {
259 int n = 0;
260 int i;
261
262 if (!this)
263 Stream_ErrorExit("Stream_UngetCharacters", "Object is not created.");
264
265 for (i = 0; characters[i] != '\0'; i++) { /* None */ }
266 for(i--; i >= 0; i--) {
267 Stream_UngetCharacter(this, characters[i]);
268 n++;
269 }
270
271 return (n);
272 }
273
274 /*---------------------------------------------------------------------------*/
275 /* ʸ�������ʸ�������뤫�ɤ�����Ƚ�� */
276 /*---------------------------------------------------------------------------*/
277
CheckWord(char * s,int c)278 static int CheckWord(char * s, int c)
279 {
280 if (c == EOF) return (0);
281 if (s == NULL) return (0);
282
283 while (*s != '\0') {
284 if (c == *s) return (1);
285 s++;
286 }
287
288 return (0);
289 }
290
291 /*---------------------------------------------------------------------------*/
292 /* ʸ�����ʸ�����ɲ� */
293 /*---------------------------------------------------------------------------*/
294
AddCharacter(char * buffer,int * buf_len,int * i,char c,int extend)295 static char * AddCharacter(char * buffer, int * buf_len, int * i, char c,
296 int extend)
297 {
298 if (*i >= *buf_len - 1) {
299 if (!extend) return (buffer);
300 (*buf_len) *= 2;
301 if (!buffer) buffer = (char *)malloc(sizeof(char) * (*buf_len));
302 else buffer = (char *)realloc((void *)buffer, sizeof(char) * (*buf_len));
303 if (!buffer) Stream_ErrorExit("AddCharacter", "Cannot allocate memory.");
304 }
305
306 buffer[*i] = c;
307 (*i)++;
308 return (buffer);
309 }
310
311 /*---------------------------------------------------------------------------*/
312 /* Stream ����ȡ�����Ƕ��ڤä�ʸ������ɤ߹��ߡ�ʸ����(String ��)���֤��� */
313 /* ������䥳���ȹԤβ���Ԥ��� */
314 /*---------------------------------------------------------------------------*/
315 /* split1 �ϡ�ʣ���ζ��ڤ�ʸ����Ϣ³������ˤ⡤�̥�ʸ���Ȥ����ڤ�ʬ���롥 */
316 /* split2 �ϡ�ʣ���ζ��ڤ�ʸ����Ϣ³������ˤϡ��ҤȤĤζ��ڤ�ʸ���Ȥ��� */
317 /* �������롥 */
318 /*---------------------------------------------------------------------------*/
319
Stream_GetWord(Stream this,char * buffer,int buffer_length,char * split1,char * split2,char * comment,char * lineend,char * quotation,char * head_skip,char * tail_skip)320 char * Stream_GetWord(Stream this, /* �ɤ߹��߸��� Stream */
321 char * buffer,
322 int buffer_length,
323 char * split1, /* ����ʸ�����ڤ�ʬ���� */
324 char * split2, /* ����ʸ���Ǥ��ڤ�ʬ���� */
325 char * comment, /* �����ȹԤ���Ƭʸ�� '#' �ʤ� */
326 char * lineend, /* ����ʸ�� '\n' �ʤ� */
327 char * quotation, /* ������ʸ�� '\"' �ʤ� */
328 char * head_skip, /* ʸ������Ƭ���ɤߤȤФ�ʸ�� */
329 char * tail_skip /* ʸ�����������ɤߤȤФ�ʸ�� */
330 )
331 {
332 int c;
333 int i = 0;
334 int extend = 0; /* �Хåե����ĥ�Ǥ��뤫 */
335
336 if (!this) Stream_ErrorExit("Stream_GetWord", "Object is not created.");
337
338 do {
339 c = Stream_GetCharacter(this);
340 if (CheckWord(comment, c)) {
341 do {
342 c = Stream_GetCharacter(this);
343 } while (!CheckWord(lineend, c) && (c != EOF));
344 }
345 } while (CheckWord(split2, c) || CheckWord(comment, c) ||
346 CheckWord(lineend, c));
347
348 if (c == EOF) return (NULL); /* �ɤ߽Ф�ñ�줬¸�ߤ��ʤ� */
349
350 if (!buffer) {
351 extend = 1;
352 buffer_length = 10;
353 buffer = (char *)malloc(sizeof(char) * buffer_length);
354 if (!buffer) Stream_ErrorExit("Stream_GetWord", "Cannot allocate memory.");
355 }
356
357 if (CheckWord(quotation, c)) {
358 while (1) {
359 c = Stream_GetCharacter(this);
360 if (CheckWord(quotation, c) || (c == EOF)) break;
361 buffer = AddCharacter(buffer, &buffer_length, &i, c, extend);
362 }
363 } else {
364
365 while (CheckWord(head_skip, c) && (c != EOF))
366 c = Stream_GetCharacter(this);
367
368 while (1) {
369 if (c == EOF) {
370 break;
371 }
372 if (CheckWord(comment, c) || CheckWord(quotation, c) ||
373 CheckWord(split1, c) || CheckWord(split2, c) ||
374 CheckWord(lineend, c)) {
375 Stream_UngetCharacter(this, c);
376 break;
377 }
378 buffer = AddCharacter(buffer, &buffer_length, &i, c, extend);
379 c = Stream_GetCharacter(this);
380 }
381
382 while ((i > 0) && (CheckWord(tail_skip, buffer[i - 1]))) i--;
383 }
384
385 if (i <= buffer_length - 1) buffer[i] = '\0';
386
387 return (buffer);
388 }
389
390 /*****************************************************************************/
391 /* �����ޤ� */
392 /*****************************************************************************/
393
394 /*****************************************************************************/
395 /* End of File. */
396 /*****************************************************************************/
397