• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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