Diff for /np2/common/textfile.c between versions 1.3 and 1.7

version 1.3, 2004/06/20 11:19:45 version 1.7, 2005/03/20 06:09:16
Line 1 Line 1
 #include        "compiler.h"  #include        "compiler.h"
   #include        "strres.h"
 #include        "dosio.h"  #include        "dosio.h"
 #include        "textfile.h"  #include        "textfile.h"
   
   
 static BOOL getnextstrings(TEXTFILEH fh) {  enum {
           TFMODE_READ             = 0x01,
           TFMODE_WRITE    = 0x02
   };
   
   typedef struct {
           UINT8   mode;
           UINT8   access;
           UINT8   srcwidth;
           UINT8   xendian;
           FILEH   fh;
           long    fpos;
           void    *buf;
           UINT    bufsize;
           UINT    bufpos;
           UINT    bufrem;
   } _TEXTFILE, *TEXTFILE;
   
   
   static TEXTFILEH registfile(FILEH fh, UINT buffersize,
                                                                                           const UINT8 *hdr, UINT hdrsize) {
   
           long            fpos;
           UINT8           srcwidth;
           UINT8           xendian;
           TEXTFILE        ret;
   
         UINT    rsize;          buffersize = buffersize & (~3);
           if (buffersize < 256) {
                   buffersize = 256;
           }
           fpos = 0;
           srcwidth = 1;
           xendian = FALSE;
           if ((hdrsize >= 3) &&
                   (hdr[0] == 0xef) && (hdr[1] == 0xbb) && (hdr[2] == 0xbf)) {
                   // UTF-8
                   fpos = 3;
           }
           else if ((hdrsize >= 2) && (hdr[0] == 0xff) && (hdr[1] == 0xfe)) {
                   // UCSLE
                   fpos = 2;
                   srcwidth = 2;
   #if defined(BYTESEX_BIG)
                   xendian = TRUE;
   #endif
           }
           else if ((hdrsize >= 2) && (hdr[0] == 0xfe) && (hdr[1] == 0xff)) {
                   // UCS2BE
                   fpos = 2;
                   srcwidth = 2;
   #if defined(BYTESEX_LITTLE)
                   xendian = TRUE;
   #endif
           }
   
         if (!fh) {          if (srcwidth != sizeof(OEMCHAR)) {
                 return(FAILURE);                  return(NULL);
         }          }
         if (file_seek((FILEH)fh->fh, fh->fhpos, 0) != fh->fhpos) {          buffersize = buffersize * sizeof(OEMCHAR);
                 return(FAILURE);  
           ret = (TEXTFILE)_MALLOC(sizeof(_TEXTFILE) + buffersize, "TEXTFILE");
           if (ret == NULL) {
                   return(NULL);
         }          }
         rsize = file_read((FILEH)fh->fh, fh + 1, fh->buffersize);          ZeroMemory(ret, sizeof(_TEXTFILE));
         if (rsize == (UINT)-1) {  //      ret->mode = 0;
           ret->srcwidth = srcwidth;
           ret->xendian = xendian;
           ret->fh = fh;
           ret->fpos = fpos;
           ret->buf = (UINT8 *)(ret + 1);
           ret->bufsize = buffersize;
           return((TEXTFILEH)ret);
   }
   
   static BRESULT flushfile(TEXTFILE tf) {
   
           if (tf->mode & TFMODE_READ) {
                   tf->fpos -= tf->bufrem * tf->srcwidth;
           }
           tf->mode = 0;
           tf->bufpos = 0;
           tf->bufrem = 0;
           if (file_seek(tf->fh, tf->fpos, FSEEK_SET) == tf->fpos) {
                   return(SUCCESS);
           }
           else {
                 return(FAILURE);                  return(FAILURE);
         }          }
         fh->fhpos += rsize;  
         fh->pos = 0;  
         fh->remain = rsize;  
         return(SUCCESS);  
 }  }
   
 TEXTFILEH textfile_open(const char *filename, UINT buffersize) {  
   
         FILEH           fh;  // ---- A
         TEXTFILEH       ret;  
   
         if (buffersize < 256) {  static UINT fillbufferA(TEXTFILE tf) {
                 buffersize = 256;  
           UINT    rsize;
   
           if (tf->bufrem == 0) {
                   rsize = file_read(tf->fh, tf->buf, tf->bufsize);
                   rsize = rsize / sizeof(char);
                   tf->fpos += rsize * sizeof(char);
                   tf->bufpos = 0;
                   tf->bufrem = rsize;
         }          }
         fh = file_open(filename);          return(tf->bufrem);
         if (fh == FILEH_INVALID) {  }
                 goto tfo_err1;  
   static BRESULT readlineA(TEXTFILE tf, void *buffer, UINT size) {
   
           char    *dst;
           BOOL    crlf;
           BRESULT ret;
           char    c;
   const char      *src;
           UINT    pos;
   
           if (size == 0) {
                   dst = NULL;
                   size = 0;
         }          }
         ret = (TEXTFILEH)_MALLOC(sizeof(_TEXTFILE) + buffersize, filename);          else {
         if (ret == NULL) {                  dst = (char *)buffer;
                 goto tfo_err2;                  size--;
         }          }
         ZeroMemory(ret, sizeof(_TEXTFILE) + buffersize);  
         ret->fh = (long)fh;          crlf = FALSE;
         ret->buffersize = buffersize;          ret = FAILURE;
 #if defined(OSLANG_UTF8)          c = 0;
         getnextstrings(ret);          do {
         if (ret->remain >= 3) {                  if (fillbufferA(tf) == 0) {
                 char *ptr;                          break;
                 ptr = ((char *)(ret + 1)) + ret->pos;                  }
                 if ((ptr[0] == (char)0xef) &&                  ret = SUCCESS;
                         (ptr[1] == (char)0xbb) &&                  src = (char *)tf->buf;
                         (ptr[2] == (char)0xbf)) {                  src += tf->bufpos;
                         ret->pos += 3;                  pos = 0;
                         ret->remain -= 3;                  while(pos<tf->bufrem) {
                           c = src[pos];
                           pos++;
                           if ((c == 0x0d) || (c == 0x0a)) {
                                   crlf = TRUE;
                                   break;
                           }
                           if (size) {
                                   size--;
                                   *dst++ = c;
                           }
                   }
                   tf->bufpos += pos;
                   tf->bufrem -= pos;
           } while(!crlf);
           if ((crlf) && (c == 0x0d)) {
                   if (fillbufferA(tf) != 0) {
                           src = (char *)tf->buf;
                           src += tf->bufpos;
                           if (*src == 0x0a) {
                                   tf->bufpos++;
                                   tf->bufrem--;
                           }
                 }                  }
         }          }
 #endif          if (dst) {
                   *dst = '\0';
           }
         return(ret);          return(ret);
   }
   
 tfo_err2:  
         file_close(fh);  
   
 tfo_err1:  // ---- W
         return(NULL);  
 }  
   
 void textfile_close(TEXTFILEH fh) {  static UINT fillbufferW(TEXTFILE tf) {
   
         if (fh) {          UINT    rsize;
                 file_close((FILEH)fh->fh);          UINT8   *buf;
                 _MFREE(fh);          UINT8   tmp;
   
           if (tf->bufrem == 0) {
                   buf = tf->buf;
                   rsize = file_read(tf->fh, buf, tf->bufsize);
                   rsize = rsize / sizeof(UINT16);
                   tf->fpos += rsize * sizeof(UINT16);
                   tf->bufpos = 0;
                   tf->bufrem = rsize;
                   if (tf->xendian) {
                           while(rsize) {
                                   tmp = buf[0];
                                   buf[0] = buf[1];
                                   buf[1] = tmp;
                                   buf += 2;
                                   rsize--;
                           }
                   }
         }          }
           return(tf->bufrem);
 }  }
   
 BOOL textfile_read(TEXTFILEH fh, char *buffer, UINT size) {  static BRESULT readlineW(TEXTFILE tf, void *buffer, UINT size) {
   
         char    c = '\0';          UINT16          *dst;
         char    *p;          BOOL            crlf;
         BOOL    crlf;          BRESULT         ret;
         BOOL    ret = FAILURE;          UINT16          c;
   const UINT16    *src;
         if ((fh) && (size > 0)) {          UINT            pos;
   
           if (size == 0) {
                   dst = NULL;
                   size = 0;
           }
           else {
                   dst = (UINT16 *)buffer;
                 size--;                  size--;
                 crlf = FALSE;          }
                 do {          crlf = FALSE;
                         if ((!fh->remain) && (getnextstrings(fh))) {          ret = FAILURE;
                                 return(FAILURE);          c = 0;
                         }          do {
                         if (!fh->remain) {                  if (fillbufferW(tf) == 0) {
                           break;
                   }
                   ret = SUCCESS;
                   src = (UINT16 *)tf->buf;
                   src += tf->bufpos;
                   pos = 0;
                   while(pos<tf->bufrem) {
                           c = src[pos];
                           pos++;
                           if ((c == 0x0d) || (c == 0x0a)) {
                                   crlf = TRUE;
                                 break;                                  break;
                         }                          }
                         ret = SUCCESS;                          if (size) {
                         p = (char *)(fh + 1);  
                         p += fh->pos;  
                         while((fh->remain) && (size)) {  
                                 c = *p++;  
                                 fh->pos++;  
                                 fh->remain--;  
                                 if ((c == 0x0d) || (c == 0x0a)) {  
                                         crlf = TRUE;  
                                         break;  
                                 }  
                                 *buffer++ = c;  
                                 size--;                                  size--;
                                   *dst++ = c;
                         }                          }
                         if (!crlf) {                  }
                                 while((fh->remain) && (size)) {                  tf->bufpos += pos;
                                         c = *p++;                  tf->bufrem -= pos;
                                         fh->pos++;          } while(!crlf);
                                         fh->remain--;          if ((crlf) && (c == 0x0d)) {
                                         if ((c == 0x0d) || (c == 0x0a)) {                  if (fillbufferW(tf) != 0) {
                                                 crlf = TRUE;                          src = (UINT16 *)tf->buf;
                                                 break;                          src += tf->bufpos;
                                         }                          if (*src == 0x0a) {
                                 }                                  tf->bufpos++;
                         }                                  tf->bufrem--;
                 } while(!crlf);  
                 if ((crlf) && (c == 0x0d)) {  
                         if ((!fh->remain) && (getnextstrings(fh))) {  
                                 return(FAILURE);  
                         }  
                         if (fh->remain) {  
                                 p = (char *)(fh + 1);  
                                 p += fh->pos;  
                                 if (*p == 0x0a) {  
                                         fh->pos++;  
                                         fh->remain--;  
                                 }  
                         }                          }
                 }                  }
                 *buffer = '\0';          }
           if (dst) {
                   *dst = '\0';
         }          }
         return(ret);          return(ret);
 }  }
   
   
   // ----
   
   TEXTFILEH textfile_open(const OEMCHAR *filename, UINT buffersize) {
   
           FILEH           fh;
           UINT8           hdr[4];
           UINT            hdrsize;
           TEXTFILEH       ret;
   
           fh = file_open_rb(filename);
           if (fh == FILEH_INVALID) {
                   goto tfo_err;
           }
           hdrsize = file_read(fh, hdr, sizeof(hdr));
           ret = registfile(fh, buffersize, hdr, hdrsize);
           if (ret) {
                   return(ret);
           }
           file_close(fh);
   
   tfo_err:
           return(NULL);
   }
   
   TEXTFILEH textfile_create(const OEMCHAR *filename, UINT buffersize) {
   
           FILEH           fh;
   const UINT8             *hdr;
           UINT            hdrsize;
           TEXTFILEH       ret;
   
           fh = file_create(filename);
           if (fh == FILEH_INVALID) {
                   goto tfc_err1;
           }
   #if defined(OSLANG_UTF8)
           hdr = str_utf8;
           hdrsize = sizeof(str_utf8);
   #elif defined(OSLANG_UCS2) 
           hdr = (UINT8 *)str_ucs2;
           hdrsize = sizeof(str_ucs2);
   #else
           hdr = NULL;
           hdrsize = 0;
   #endif
           if ((hdrsize) && (file_write(fh, hdr, hdrsize) != hdrsize)) {
                   goto tfc_err2;
           }
           ret = registfile(fh, buffersize, hdr, hdrsize);
           if (ret) {
                   return(ret);
           }
   
   tfc_err2:
           file_close(fh);
   
   tfc_err1:
           return(NULL);
   }
   
   BRESULT textfile_read(TEXTFILEH tfh, OEMCHAR *buffer, UINT size) {
   
           TEXTFILE        tf;
   
           tf = (TEXTFILE)tfh;
           if (tf) {
                   if (!(tf->mode & TFMODE_READ)) {
                           flushfile(tf);
                           tf->mode = TFMODE_READ;
                   }
                   if (sizeof(OEMCHAR) == 1) {
                           return(readlineA(tf, buffer, size));
                   }
                   else if (sizeof(OEMCHAR) == 2) {
                           return(readlineW(tf, buffer, size));
                   }
           }
           return(FAILURE);
   }
   
   BRESULT textfile_write(TEXTFILEH tfh, const OEMCHAR *buffer) {
   
           TEXTFILE        tf;
           UINT            leng;
           UINT            wsize;
   
           tf = (TEXTFILE)tfh;
           if (tf) {
                   if (!(tf->mode & TFMODE_WRITE)) {
                           flushfile(tf);
                           tf->mode = TFMODE_WRITE;
                   }
                   leng = OEMSTRLEN(buffer);
                   leng = leng * sizeof(OEMCHAR);
                   wsize = file_write(tf->fh, buffer, leng);
                   tf->fpos += wsize;
                   if (wsize == leng) {
                           return(SUCCESS);
                   }
           }
           return(FAILURE);
   }
   
   void textfile_close(TEXTFILEH tfh) {
   
           if (tfh) {
                   file_close(((TEXTFILE)tfh)->fh);
                   _MFREE(tfh);
           }
   }
   

Removed from v.1.3  
changed lines
  Added in v.1.7


RetroPC.NET-CVS <cvs@retropc.net>