--- np2/common/textfile.c 2005/03/19 18:54:58 1.6 +++ np2/common/textfile.c 2005/03/20 06:09:16 1.7 @@ -1,44 +1,125 @@ #include "compiler.h" +#include "strres.h" #include "dosio.h" #include "textfile.h" -typedef struct { - UINT mode; - FILEH fh; - BOOL xendian; -} _TEXTFH, *TEXTFH; +enum { + TFMODE_READ = 0x01, + TFMODE_WRITE = 0x02 +}; typedef struct { - _TEXTFH tf; - UINT8 *buf; + UINT8 mode; + UINT8 access; + UINT8 srcwidth; + UINT8 xendian; + FILEH fh; + long fpos; + void *buf; UINT bufsize; UINT bufpos; UINT bufrem; -} _TEXTREAD, *TEXTREAD; +} _TEXTFILE, *TEXTFILE; + + +static TEXTFILEH registfile(FILEH fh, UINT buffersize, + const UINT8 *hdr, UINT hdrsize) { + + long fpos; + UINT8 srcwidth; + UINT8 xendian; + TEXTFILE ret; + + 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 (srcwidth != sizeof(OEMCHAR)) { + return(NULL); + } + buffersize = buffersize * sizeof(OEMCHAR); + + ret = (TEXTFILE)_MALLOC(sizeof(_TEXTFILE) + buffersize, "TEXTFILE"); + if (ret == NULL) { + return(NULL); + } + ZeroMemory(ret, sizeof(_TEXTFILE)); +// 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); + } +} // ---- A -static UINT fillbufferA(TEXTREAD tr) { +static UINT fillbufferA(TEXTFILE tf) { UINT rsize; - if (tr->bufrem == 0) { - rsize = file_read(tr->tf.fh, tr->buf, tr->bufsize); - tr->bufpos = 0; - tr->bufrem = 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; } - return(tr->bufrem); + return(tf->bufrem); } -static BRESULT readlineA(TEXTREAD tr, void *buffer, UINT size) { +static BRESULT readlineA(TEXTFILE tf, void *buffer, UINT size) { - UINT8 *dst; + char *dst; BOOL crlf; BRESULT ret; - UINT8 c; -const UINT8 *src; + char c; +const char *src; UINT pos; if (size == 0) { @@ -46,7 +127,7 @@ const UINT8 *src; size = 0; } else { - dst = (UINT8 *)buffer; + dst = (char *)buffer; size--; } @@ -54,14 +135,14 @@ const UINT8 *src; ret = FAILURE; c = 0; do { - if (fillbufferA(tr) == 0) { + if (fillbufferA(tf) == 0) { break; } ret = SUCCESS; - src = tr->buf; - src += tr->bufpos; + src = (char *)tf->buf; + src += tf->bufpos; pos = 0; - while(posbufrem) { + while(posbufrem) { c = src[pos]; pos++; if ((c == 0x0d) || (c == 0x0a)) { @@ -73,16 +154,16 @@ const UINT8 *src; *dst++ = c; } } - tr->bufpos += pos; - tr->bufrem -= pos; + tf->bufpos += pos; + tf->bufrem -= pos; } while(!crlf); if ((crlf) && (c == 0x0d)) { - if (fillbufferA(tr) != 0) { - src = tr->buf; - src += tr->bufpos; + if (fillbufferA(tf) != 0) { + src = (char *)tf->buf; + src += tf->bufpos; if (*src == 0x0a) { - tr->bufpos++; - tr->bufrem--; + tf->bufpos++; + tf->bufrem--; } } } @@ -95,18 +176,20 @@ const UINT8 *src; // ---- W -static UINT fillbufferW(TEXTREAD tr) { +static UINT fillbufferW(TEXTFILE tf) { UINT rsize; UINT8 *buf; UINT8 tmp; - if (tr->bufrem == 0) { - buf = tr->buf; - rsize = file_read(tr->tf.fh, buf, tr->bufsize) / 2; - tr->bufpos = 0; - tr->bufrem = rsize / 2; - if (tr->tf.xendian) { + 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]; @@ -116,10 +199,10 @@ static UINT fillbufferW(TEXTREAD tr) { } } } - return(tr->bufrem); + return(tf->bufrem); } -static BRESULT readlineW(TEXTREAD tr, void *buffer, UINT size) { +static BRESULT readlineW(TEXTFILE tf, void *buffer, UINT size) { UINT16 *dst; BOOL crlf; @@ -140,14 +223,14 @@ const UINT16 *src; ret = FAILURE; c = 0; do { - if (fillbufferW(tr) == 0) { + if (fillbufferW(tf) == 0) { break; } ret = SUCCESS; - src = (UINT16 *)tr->buf; - src += tr->bufpos; + src = (UINT16 *)tf->buf; + src += tf->bufpos; pos = 0; - while(posbufrem) { + while(posbufrem) { c = src[pos]; pos++; if ((c == 0x0d) || (c == 0x0a)) { @@ -159,16 +242,16 @@ const UINT16 *src; *dst++ = c; } } - tr->bufpos += pos; - tr->bufrem -= pos; + tf->bufpos += pos; + tf->bufrem -= pos; } while(!crlf); if ((crlf) && (c == 0x0d)) { - if (fillbufferW(tr) != 0) { - src = (UINT16 *)tr->buf; - src += tr->bufpos; + if (fillbufferW(tf) != 0) { + src = (UINT16 *)tf->buf; + src += tf->bufpos; if (*src == 0x0a) { - tr->bufpos++; - tr->bufrem--; + tf->bufpos++; + tf->bufrem--; } } } @@ -186,94 +269,107 @@ TEXTFILEH textfile_open(const OEMCHAR *f FILEH fh; UINT8 hdr[4]; UINT hdrsize; - long fpos; - UINT srcwidth; - BOOL xendian; - TEXTREAD ret; + TEXTFILEH ret; - buffersize = buffersize & (~3); - if (buffersize < 256) { - buffersize = 256; - } fh = file_open_rb(filename); if (fh == FILEH_INVALID) { - goto tfo_err1; + goto tfo_err; } - hdrsize = file_read(fh, hdr, 4); - 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 + hdrsize = file_read(fh, hdr, sizeof(hdr)); + ret = registfile(fh, buffersize, hdr, hdrsize); + if (ret) { + return(ret); } + file_close(fh); - if (srcwidth != sizeof(OEMCHAR)) { - goto tfo_err2; - } - buffersize = buffersize * sizeof(OEMCHAR); +tfo_err: + return(NULL); +} - if (file_seek(fh, fpos, FSEEK_SET) != fpos) { - goto tfo_err2; - } +TEXTFILEH textfile_create(const OEMCHAR *filename, UINT buffersize) { - ret = (TEXTREAD)_MALLOC(sizeof(_TEXTREAD) + buffersize, filename); - if (ret == NULL) { - goto tfo_err2; + 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); } - ZeroMemory(ret, sizeof(_TEXTREAD)); - ret->tf.mode = 0; - ret->tf.fh = fh; - ret->tf.xendian = xendian; - ret->buf = (UINT8 *)(ret + 1); - ret->bufsize = buffersize; - return((TEXTFILEH)ret); -tfo_err2: +tfc_err2: file_close(fh); -tfo_err1: +tfc_err1: return(NULL); } -void textfile_close(TEXTFILEH tfh) { - - if (tfh) { - file_close(((TEXTFH)tfh)->fh); - _MFREE(tfh); - } -} - BRESULT textfile_read(TEXTFILEH tfh, OEMCHAR *buffer, UINT size) { - TEXTREAD tr; + TEXTFILE tf; - tr = (TEXTREAD)tfh; - if (tr) { + tf = (TEXTFILE)tfh; + if (tf) { + if (!(tf->mode & TFMODE_READ)) { + flushfile(tf); + tf->mode = TFMODE_READ; + } if (sizeof(OEMCHAR) == 1) { - return(readlineA(tr, buffer, size)); + return(readlineA(tf, buffer, size)); } else if (sizeof(OEMCHAR) == 2) { - return(readlineW(tr, buffer, size)); + 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); + } +} +