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