--- np2/common/textfile.c 2004/06/20 11:19:45 1.3 +++ np2/common/textfile.c 2005/03/19 18:54:58 1.6 @@ -3,59 +3,248 @@ #include "textfile.h" -static BOOL getnextstrings(TEXTFILEH fh) { +typedef struct { + UINT mode; + FILEH fh; + BOOL xendian; +} _TEXTFH, *TEXTFH; + +typedef struct { + _TEXTFH tf; + UINT8 *buf; + UINT bufsize; + UINT bufpos; + UINT bufrem; +} _TEXTREAD, *TEXTREAD; + + +// ---- A + +static UINT fillbufferA(TEXTREAD tr) { UINT rsize; - if (!fh) { - return(FAILURE); + if (tr->bufrem == 0) { + rsize = file_read(tr->tf.fh, tr->buf, tr->bufsize); + tr->bufpos = 0; + tr->bufrem = rsize; + } + return(tr->bufrem); +} + +static BRESULT readlineA(TEXTREAD tr, void *buffer, UINT size) { + + UINT8 *dst; + BOOL crlf; + BRESULT ret; + UINT8 c; +const UINT8 *src; + UINT pos; + + if (size == 0) { + dst = NULL; + size = 0; + } + else { + dst = (UINT8 *)buffer; + size--; + } + + crlf = FALSE; + ret = FAILURE; + c = 0; + do { + if (fillbufferA(tr) == 0) { + break; + } + ret = SUCCESS; + src = tr->buf; + src += tr->bufpos; + pos = 0; + while(posbufrem) { + c = src[pos]; + pos++; + if ((c == 0x0d) || (c == 0x0a)) { + crlf = TRUE; + break; + } + if (size) { + size--; + *dst++ = c; + } + } + tr->bufpos += pos; + tr->bufrem -= pos; + } while(!crlf); + if ((crlf) && (c == 0x0d)) { + if (fillbufferA(tr) != 0) { + src = tr->buf; + src += tr->bufpos; + if (*src == 0x0a) { + tr->bufpos++; + tr->bufrem--; + } + } } - if (file_seek((FILEH)fh->fh, fh->fhpos, 0) != fh->fhpos) { - return(FAILURE); + if (dst) { + *dst = '\0'; } - rsize = file_read((FILEH)fh->fh, fh + 1, fh->buffersize); - if (rsize == (UINT)-1) { - return(FAILURE); + return(ret); +} + + +// ---- W + +static UINT fillbufferW(TEXTREAD tr) { + + 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) { + while(rsize) { + tmp = buf[0]; + buf[0] = buf[1]; + buf[1] = tmp; + buf += 2; + rsize--; + } + } } - fh->fhpos += rsize; - fh->pos = 0; - fh->remain = rsize; - return(SUCCESS); + return(tr->bufrem); } -TEXTFILEH textfile_open(const char *filename, UINT buffersize) { +static BRESULT readlineW(TEXTREAD tr, void *buffer, UINT size) { + + UINT16 *dst; + BOOL crlf; + BRESULT ret; + UINT16 c; +const UINT16 *src; + UINT pos; + + if (size == 0) { + dst = NULL; + size = 0; + } + else { + dst = (UINT16 *)buffer; + size--; + } + crlf = FALSE; + ret = FAILURE; + c = 0; + do { + if (fillbufferW(tr) == 0) { + break; + } + ret = SUCCESS; + src = (UINT16 *)tr->buf; + src += tr->bufpos; + pos = 0; + while(posbufrem) { + c = src[pos]; + pos++; + if ((c == 0x0d) || (c == 0x0a)) { + crlf = TRUE; + break; + } + if (size) { + size--; + *dst++ = c; + } + } + tr->bufpos += pos; + tr->bufrem -= pos; + } while(!crlf); + if ((crlf) && (c == 0x0d)) { + if (fillbufferW(tr) != 0) { + src = (UINT16 *)tr->buf; + src += tr->bufpos; + if (*src == 0x0a) { + tr->bufpos++; + tr->bufrem--; + } + } + } + if (dst) { + *dst = '\0'; + } + return(ret); +} + + +// ---- + +TEXTFILEH textfile_open(const OEMCHAR *filename, UINT buffersize) { FILEH fh; - TEXTFILEH ret; + UINT8 hdr[4]; + UINT hdrsize; + long fpos; + UINT srcwidth; + BOOL xendian; + TEXTREAD ret; + buffersize = buffersize & (~3); if (buffersize < 256) { buffersize = 256; } - fh = file_open(filename); + fh = file_open_rb(filename); if (fh == FILEH_INVALID) { goto tfo_err1; } - ret = (TEXTFILEH)_MALLOC(sizeof(_TEXTFILE) + buffersize, filename); - if (ret == NULL) { - goto tfo_err2; + 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; } - ZeroMemory(ret, sizeof(_TEXTFILE) + buffersize); - ret->fh = (long)fh; - ret->buffersize = buffersize; -#if defined(OSLANG_UTF8) - getnextstrings(ret); - if (ret->remain >= 3) { - char *ptr; - ptr = ((char *)(ret + 1)) + ret->pos; - if ((ptr[0] == (char)0xef) && - (ptr[1] == (char)0xbb) && - (ptr[2] == (char)0xbf)) { - ret->pos += 3; - ret->remain -= 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 - return(ret); + } + + if (srcwidth != sizeof(OEMCHAR)) { + goto tfo_err2; + } + buffersize = buffersize * sizeof(OEMCHAR); + + if (file_seek(fh, fpos, FSEEK_SET) != fpos) { + goto tfo_err2; + } + + ret = (TEXTREAD)_MALLOC(sizeof(_TEXTREAD) + buffersize, filename); + if (ret == NULL) { + goto tfo_err2; + } + 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: file_close(fh); @@ -64,72 +253,27 @@ tfo_err1: return(NULL); } -void textfile_close(TEXTFILEH fh) { +void textfile_close(TEXTFILEH tfh) { - if (fh) { - file_close((FILEH)fh->fh); - _MFREE(fh); + if (tfh) { + file_close(((TEXTFH)tfh)->fh); + _MFREE(tfh); } } -BOOL textfile_read(TEXTFILEH fh, char *buffer, UINT size) { +BRESULT textfile_read(TEXTFILEH tfh, OEMCHAR *buffer, UINT size) { - char c = '\0'; - char *p; - BOOL crlf; - BOOL ret = FAILURE; + TEXTREAD tr; - if ((fh) && (size > 0)) { - size--; - crlf = FALSE; - do { - if ((!fh->remain) && (getnextstrings(fh))) { - return(FAILURE); - } - if (!fh->remain) { - break; - } - ret = SUCCESS; - 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--; - } - if (!crlf) { - while((fh->remain) && (size)) { - c = *p++; - fh->pos++; - fh->remain--; - if ((c == 0x0d) || (c == 0x0a)) { - crlf = TRUE; - break; - } - } - } - } 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--; - } - } + tr = (TEXTREAD)tfh; + if (tr) { + if (sizeof(OEMCHAR) == 1) { + return(readlineA(tr, buffer, size)); + } + else if (sizeof(OEMCHAR) == 2) { + return(readlineW(tr, buffer, size)); } - *buffer = '\0'; } - return(ret); + return(FAILURE); }