1 /*---------------------------------------------------------------------------*
2 * PFile.c *
3 * *
4 * Copyright 2007, 2008 Nuance Communciations, Inc. *
5 * *
6 * Licensed under the Apache License, Version 2.0 (the 'License'); *
7 * you may not use this file except in compliance with the License. *
8 * *
9 * You may obtain a copy of the License at *
10 * http://www.apache.org/licenses/LICENSE-2.0 *
11 * *
12 * Unless required by applicable law or agreed to in writing, software *
13 * distributed under the License is distributed on an 'AS IS' BASIS, *
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
15 * See the License for the specific language governing permissions and *
16 * limitations under the License. *
17 * *
18 *---------------------------------------------------------------------------*/
19
20 #include "LCHAR.h"
21 #include "pendian.h"
22 #include "PFile.h"
23 #include "PFileSystem.h"
24 #include "plog.h"
25 #include "pstdio.h"
26
27
PFileDestroy(PFile * self)28 ESR_ReturnCode PFileDestroy(PFile* self)
29 {
30 if (self == NULL)
31 {
32 PLogError(L("ESR_INVALID_ARGUMENT"));
33 return ESR_INVALID_ARGUMENT;
34 }
35 return self->destroy(self);
36 }
37
PFileOpen(PFile * self,const LCHAR * mode)38 ESR_ReturnCode PFileOpen(PFile* self, const LCHAR* mode)
39 {
40 if (self == NULL)
41 {
42 PLogError(L("ESR_INVALID_ARGUMENT"));
43 return ESR_INVALID_ARGUMENT;
44 }
45 return self->open(self, mode);
46 }
47
PFileClose(PFile * self)48 ESR_ReturnCode PFileClose(PFile* self)
49 {
50 if (self == NULL)
51 {
52 PLogError(L("ESR_INVALID_ARGUMENT"));
53 return ESR_INVALID_ARGUMENT;
54 }
55 return self->close(self);
56 }
57
PFileRead(PFile * self,void * buffer,size_t size,size_t * count)58 ESR_ReturnCode PFileRead(PFile* self, void* buffer, size_t size, size_t* count)
59 {
60 if (self == NULL)
61 {
62 PLogError(L("ESR_INVALID_ARGUMENT"));
63 return ESR_INVALID_ARGUMENT;
64 }
65 return self->read(self, buffer, size, count);
66 }
67
PFileWrite(PFile * self,void * buffer,size_t size,size_t * count)68 ESR_ReturnCode PFileWrite(PFile* self, void* buffer, size_t size, size_t* count)
69 {
70 if (self == NULL)
71 {
72 PLogError(L("ESR_INVALID_ARGUMENT"));
73 return ESR_INVALID_ARGUMENT;
74 }
75 return self->write(self, buffer, size, count);
76 }
77
PFileFlush(PFile * self)78 ESR_ReturnCode PFileFlush(PFile* self)
79 {
80 if (self == NULL)
81 {
82 PLogError(L("ESR_INVALID_ARGUMENT"));
83 return ESR_INVALID_ARGUMENT;
84 }
85 return self->flush(self);
86 }
87
PFileSeek(PFile * self,long offset,int origin)88 ESR_ReturnCode PFileSeek(PFile* self, long offset, int origin)
89 {
90 if (self == NULL)
91 {
92 PLogError(L("ESR_INVALID_ARGUMENT"));
93 return ESR_INVALID_ARGUMENT;
94 }
95 return self->seek(self, offset, origin);
96 }
97
98
PFileGetPosition(PFile * self,size_t * position)99 ESR_ReturnCode PFileGetPosition(PFile* self, size_t* position)
100 {
101 if (self == NULL)
102 {
103 PLogError(L("ESR_INVALID_ARGUMENT"));
104 return ESR_INVALID_ARGUMENT;
105 }
106 return self->getPosition(self, position);
107 }
108
PFileIsOpen(PFile * self,ESR_BOOL * isOpen)109 ESR_ReturnCode PFileIsOpen(PFile* self, ESR_BOOL* isOpen)
110 {
111 if (self == NULL)
112 {
113 PLogError(L("ESR_INVALID_ARGUMENT"));
114 return ESR_INVALID_ARGUMENT;
115 }
116 return self->isOpen(self, isOpen);
117 }
118
PFileIsEOF(PFile * self,ESR_BOOL * isEof)119 ESR_ReturnCode PFileIsEOF(PFile* self, ESR_BOOL* isEof)
120 {
121 if (self == NULL)
122 {
123 PLogError(L("ESR_INVALID_ARGUMENT"));
124 return ESR_INVALID_ARGUMENT;
125 }
126 return self->isEOF(self, isEof);
127 }
128
PFileGetFilename(PFile * self,LCHAR * filename,size_t * len)129 ESR_ReturnCode PFileGetFilename(PFile* self, LCHAR* filename, size_t* len)
130 {
131 ESR_ReturnCode rc;
132
133 if (self == NULL)
134 {
135 PLogError(L("ESR_INVALID_ARGUMENT"));
136 return ESR_INVALID_ARGUMENT;
137 }
138 rc = self->getFilename(self, filename, len);
139 return rc;
140 }
141
PFileIsErrorSet(PFile * self,ESR_BOOL * isError)142 ESR_ReturnCode PFileIsErrorSet(PFile* self, ESR_BOOL* isError)
143 {
144 if (self == NULL)
145 {
146 PLogError(L("ESR_INVALID_ARGUMENT"));
147 return ESR_INVALID_ARGUMENT;
148 }
149 return self->isErrorSet(self, isError);
150 }
151
PFileClearError(PFile * self)152 ESR_ReturnCode PFileClearError(PFile* self)
153 {
154 if (self == NULL)
155 {
156 PLogError(L("ESR_INVALID_ARGUMENT"));
157 return ESR_INVALID_ARGUMENT;
158 }
159 return self->clearError(self);
160 }
161
PFileVfprintf(PFile * self,int * result,const LCHAR * format,va_list args)162 ESR_ReturnCode PFileVfprintf(PFile* self, int* result, const LCHAR* format, va_list args)
163 {
164 ESR_ReturnCode rc;
165
166 if (self == NULL)
167 {
168 PLogError(L("ESR_INVALID_ARGUMENT"));
169 return ESR_INVALID_ARGUMENT;
170 }
171 rc = self->vfprintf(self, result, format, args);
172 return rc;
173 }
174
PFileFgetc(PFile * self,LINT * result)175 ESR_ReturnCode PFileFgetc(PFile* self, LINT* result)
176 {
177 if (self == NULL)
178 {
179 PLogError(L("ESR_INVALID_ARGUMENT"));
180 return ESR_INVALID_ARGUMENT;
181 }
182 return self->fgetc(self, result);
183 }
184
PFileFgets(PFile * self,LCHAR * string,int n,LCHAR ** result)185 ESR_ReturnCode PFileFgets(PFile* self, LCHAR* string, int n, LCHAR** result)
186 {
187 if (self == NULL)
188 {
189 PLogError(L("ESR_INVALID_ARGUMENT"));
190 return ESR_INVALID_ARGUMENT;
191 }
192 return self->fgets(self, string, n, result);
193 }
194
PFileReadInt(PFile * self,int * value)195 ESR_ReturnCode PFileReadInt(PFile* self, int* value)
196 {
197 LCHAR number[MAX_INT_DIGITS+1];
198 size_t i, bufferSize, count, totalRead = 0;
199 ESR_ReturnCode rc;
200
201 /* Skip whitespace before token */
202 do
203 {
204 count = pfread(number, sizeof(LCHAR), MAX_INT_DIGITS, self);
205 totalRead += count;
206 if (count < MAX_INT_DIGITS)
207 {
208 if (pferror(self))
209 {
210 rc = ESR_READ_ERROR;
211 PLogError(ESR_rc2str(rc));
212 goto CLEANUP;
213 }
214 else
215 {
216 rc = ESR_INVALID_STATE;
217 PLogError(L("%s: reached end of file before finding token"), ESR_rc2str(rc));
218 goto CLEANUP;
219 }
220 }
221 /* locate first non-whitespace character */
222 for (i = 0; i < count && LISSPACE(number[i]); ++i);
223 }
224 while (i == count);
225 bufferSize = count - i;
226
227 /* Fill remainder of buffer */
228 if (bufferSize < MAX_INT_DIGITS)
229 {
230 count = pfread(number + bufferSize, sizeof(LCHAR), MAX_INT_DIGITS - bufferSize, self);
231 bufferSize += count;
232 totalRead += count;
233 if (count < MAX_INT_DIGITS - bufferSize && pferror(self))
234 {
235 rc = ESR_READ_ERROR;
236 PLogError(ESR_rc2str(rc));
237 goto CLEANUP;
238 }
239 }
240
241 /* locate first whitespace character */
242 for (i = 0; i < bufferSize && !LISSPACE(number[i]); ++i);
243 if (i < bufferSize)
244 {
245 /* unread anything after the token */
246 if (PFileSeek(self, - (int)(bufferSize - i), SEEK_CUR))
247 {
248 rc = ESR_SEEK_ERROR;
249 PLogError(ESR_rc2str(rc));
250 }
251 totalRead -= bufferSize - i;
252 number[i] = L('\0');
253 }
254
255 if (number[0] != L('-') && !LISDIGIT(number[0]))
256 {
257 rc = ESR_INVALID_STATE;
258 PLogError(L("%s: token was not number (%s)"), ESR_rc2str(rc), number);
259 goto CLEANUP;
260 }
261
262 CHKLOG(rc, lstrtoi(number, value, 10));
263 return rc;
264 CLEANUP:
265 if (PFileSeek(self, - (int) count, SEEK_CUR))
266 PLogError(L("ESR_SEEK_ERROR"));
267 return rc;
268 }
269
PFileReadLCHAR(PFile * self,LCHAR * value,size_t len)270 ESR_ReturnCode PFileReadLCHAR(PFile* self, LCHAR* value, size_t len)
271 {
272 size_t i, bufferSize, count, totalRead = 0;
273 ESR_ReturnCode rc = ESR_SUCCESS;
274
275 /* Skip whitespace before token */
276 do
277 {
278 count = pfread(value, sizeof(LCHAR), len, self);
279 totalRead += count;
280 if (count < len)
281 {
282 if (pferror(self))
283 {
284 rc = ESR_READ_ERROR;
285 PLogError(ESR_rc2str(rc));
286 goto CLEANUP;
287 }
288 else
289 {
290 rc = ESR_INVALID_STATE;
291 PLogError(L("%s: reached end of file before finding token"), ESR_rc2str(rc));
292 goto CLEANUP;
293 }
294 }
295 /* locate first non-whitespace character */
296 for (i = 0; i < count && LISSPACE(value[i]); ++i);
297 }
298 while (i == count);
299 bufferSize = count - i;
300
301 /* Fill remainder of buffer */
302 if (bufferSize < len)
303 {
304 count = pfread(value + bufferSize, sizeof(LCHAR), len - bufferSize, self);
305 bufferSize += count;
306 totalRead += count;
307 if (count < len - bufferSize && pferror(self))
308 {
309 rc = ESR_READ_ERROR;
310 PLogError(ESR_rc2str(rc));
311 goto CLEANUP;
312 }
313 }
314
315 /* locate first whitespace character */
316 for (i = 0; i < bufferSize && !LISSPACE(value[i]); ++i);
317 if (i < bufferSize)
318 {
319 /* unread anything after the token */
320 if (PFileSeek(self, -(int)(bufferSize - i), SEEK_CUR))
321 {
322 rc = ESR_SEEK_ERROR;
323 PLogError(ESR_rc2str(rc));
324 }
325 totalRead -= bufferSize - i;
326 value[i] = L('\0');
327 }
328 return rc;
329 CLEANUP:
330 if (PFileSeek(self, - (int) count, SEEK_CUR))
331 PLogError(L("ESR_SEEK_ERROR"));
332 return rc;
333 }
334
pfopen(const LCHAR * filename,const LCHAR * mode)335 PFile* pfopen(const LCHAR* filename, const LCHAR* mode)
336 {
337 PFile* result;
338 ESR_ReturnCode rc;
339 ESR_BOOL isLittleEndian;
340
341 #if __BYTE_ORDER==__LITTLE_ENDIAN
342 isLittleEndian = ESR_TRUE;
343 #else
344 isLittleEndian = ESR_FALSE;
345 #endif
346
347 rc = PFileSystemCreatePFile(filename, isLittleEndian, &result);
348 if (rc != ESR_SUCCESS)
349 return NULL;
350 rc = result->open(result, mode);
351 if (rc != ESR_SUCCESS)
352 {
353 result->destroy(result);
354 return NULL;
355 }
356 return result;
357 }
358
pfread(void * buffer,size_t size,size_t count,PFile * stream)359 size_t pfread(void* buffer, size_t size, size_t count, PFile* stream)
360 {
361 ESR_ReturnCode rc;
362
363 rc = PFileRead(stream, buffer, size, &count);
364 if (rc != ESR_SUCCESS)
365 return 0;
366 return count;
367 }
368
pfwrite(const void * buffer,size_t size,size_t count,PFile * stream)369 size_t pfwrite(const void* buffer, size_t size, size_t count, PFile* stream)
370 {
371 ESR_ReturnCode rc;
372
373 rc = PFileWrite(stream, buffer, size, &count);
374 if (rc != ESR_SUCCESS)
375 return 0;
376 return count;
377 }
378
pfclose(PFile * stream)379 int pfclose(PFile* stream)
380 {
381 ESR_ReturnCode rc;
382
383 rc = PFileDestroy(stream);
384 if (rc != ESR_SUCCESS)
385 return PEOF;
386 return 0;
387 }
388
prewind(PFile * stream)389 void prewind(PFile* stream)
390 {
391 PFileSeek(stream, 0, SEEK_SET);
392 }
393
pfseek(PFile * stream,long offset,int origin)394 int pfseek(PFile* stream, long offset, int origin)
395 {
396 ESR_ReturnCode rc;
397
398 rc = PFileSeek(stream, offset, origin);
399 if (rc != ESR_SUCCESS)
400 return 1;
401 return 0;
402 }
403
pftell(PFile * stream)404 long pftell(PFile* stream)
405 {
406 size_t result;
407 ESR_ReturnCode rc;
408
409 rc = PFileGetPosition(stream, &result);
410 if (rc != ESR_SUCCESS)
411 return -1;
412 return result;
413 }
414
pfeof(PFile * stream)415 int pfeof(PFile* stream)
416 {
417 ESR_BOOL eof;
418
419 PFileIsEOF(stream, &eof);
420 if (!eof)
421 return 0;
422 return 1;
423 }
424
pferror(PFile * stream)425 int pferror(PFile* stream)
426 {
427 ESR_BOOL error;
428
429 PFileIsErrorSet(stream, &error);
430 if (!error)
431 return 0;
432 return 1;
433 }
434
pclearerr(PFile * stream)435 void pclearerr(PFile* stream)
436 {
437 PFileClearError(stream);
438 }
439
pfflush(PFile * stream)440 int pfflush(PFile* stream)
441 {
442 ESR_ReturnCode rc;
443
444 rc = PFileFlush(stream);
445 if (rc != ESR_SUCCESS)
446 return PEOF;
447 return 0;
448 }
449
pfgets(LCHAR * string,int n,PFile * self)450 LCHAR* pfgets(LCHAR* string, int n, PFile* self)
451 {
452 LCHAR* result;
453 ESR_ReturnCode rc;
454
455 rc = PFileFgets(self, string, n, &result);
456 if (rc != ESR_SUCCESS)
457 return NULL;
458 return result;
459 }
460
pfgetc(PFile * self)461 LINT pfgetc(PFile* self)
462 {
463 LINT result;
464 ESR_ReturnCode rc;
465
466 rc = PFileFgetc(self, &result);
467 if (rc != ESR_SUCCESS)
468 return PEOF;
469 return result;
470 }
471
pfprintf(PFile * stream,const LCHAR * format,...)472 int pfprintf(PFile* stream, const LCHAR* format, ...)
473 {
474 #ifdef FINAL_RELEASE
475 return 0;
476 #else
477 va_list args;
478 int result;
479 ESR_ReturnCode rc;
480
481 va_start(args, format);
482 rc = PFileVfprintf(stream, &result, format, args);
483 va_end(args);
484 if (rc != ESR_SUCCESS)
485 return -1;
486 return result;
487 #endif
488 }
489
pvfprintf(PFile * stream,const LCHAR * format,va_list argptr)490 int pvfprintf(PFile* stream, const LCHAR* format, va_list argptr)
491 {
492 #ifdef FINAL_RELEASE
493 return 0;
494 #else
495 int result;
496 ESR_ReturnCode rc;
497
498 rc = PFileVfprintf(stream, &result, format, argptr);
499 if (rc != ESR_SUCCESS)
500 return -1;
501 return result;
502 #endif
503 }
504
pprintf(const LCHAR * format,...)505 int pprintf(const LCHAR* format, ...)
506 {
507 #ifdef FINAL_RELEASE
508 return 0;
509 #else
510 va_list args;
511 int result;
512 ESR_ReturnCode rc;
513
514 va_start(args, format);
515 rc = PFileVfprintf(PSTDOUT, &result, format, args);
516 va_end(args);
517 if (rc != ESR_SUCCESS)
518 return -1;
519 return result;
520 #endif
521 }
522