Home | History | Annotate | Download | only in src
      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 
     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 
     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 
     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 
     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 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    389 void prewind(PFile* stream)
    390 {
    391   PFileSeek(stream, 0, SEEK_SET);
    392 }
    393 
    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 
    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 
    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 
    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 
    435 void pclearerr(PFile* stream)
    436 {
    437   PFileClearError(stream);
    438 }
    439 
    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 
    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 
    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 
    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 
    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 
    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