--- np2/common/profile.c 2004/03/31 11:59:17 1.5 +++ np2/common/profile.c 2005/04/01 15:35:49 1.16 @@ -1,13 +1,16 @@ #include "compiler.h" #include "strres.h" -#include "dosio.h" #include "textfile.h" #include "profile.h" +#if defined(SUPPORT_TEXTCNV) +#include "textcnv.h" +#endif +#include "dosio.h" -static void strdelspace(char **buf, int *size) { +static void strdelspace(OEMCHAR **buf, int *size) { - char *p; + OEMCHAR *p; int len; p = *buf; @@ -23,13 +26,13 @@ static void strdelspace(char **buf, int *size = len; } -static char *profana(char *buf, char **data) { +static OEMCHAR *profana(OEMCHAR *buf, OEMCHAR **data) { int len; - char *buf2; + OEMCHAR *buf2; int l; - len = strlen(buf); + len = OEMSTRLEN(buf); strdelspace(&buf, &len); if ((len >= 2) && (buf[0] == '[') && (buf[len - 1] == ']')) { buf++; @@ -62,15 +65,15 @@ static char *profana(char *buf, char **d return(NULL); } -BOOL profile_enum(const char *filename, void *arg, - BOOL (*proc)(void *arg, const char *para, - const char *key, const char *data)) { +BOOL profile_enum(const OEMCHAR *filename, void *arg, + BOOL (*proc)(void *arg, const OEMCHAR *para, + const OEMCHAR *key, const OEMCHAR *data)) { TEXTFILEH fh; BOOL r; - char buf[0x200]; - char para[0x100]; - char *key; - char *data; + OEMCHAR buf[0x200]; + OEMCHAR para[0x100]; + OEMCHAR *key; + OEMCHAR *data; r = FALSE; if (proc == NULL) { @@ -82,13 +85,13 @@ BOOL profile_enum(const char *filename, } para[0] = '\0'; while(1) { - if (textfile_read(fh, buf, sizeof(buf)) != SUCCESS) { + if (textfile_read(fh, buf, NELEMENTS(buf)) != SUCCESS) { break; } key = profana(buf, &data); if (key) { if (data == NULL) { - milstr_ncpy(para, key, sizeof(para)); + milstr_ncpy(para, key, NELEMENTS(para)); } else { r = proc(arg, para, key, data); @@ -107,9 +110,9 @@ gden_err0: // ---- -const char *profile_getarg(const char *str, char *buf, UINT leng) { +const OEMCHAR *profile_getarg(const OEMCHAR *str, OEMCHAR *buf, UINT leng) { - UINT8 c; + OEMCHAR c; if (leng) { leng--; @@ -118,24 +121,24 @@ const char *profile_getarg(const char *s buf = NULL; } if (str) { - c = (UINT8)*str; - while(((c - 1) & 0xff) < 0x20) { + c = *str; + while((c > 0) && (c <= 0x20)) { str++; - c = (UINT8)*str; + c = *str; } if (c == 0) { str = NULL; } } if (str) { - c = (UINT8)*str; - while(c > 0x20) { + c = *str; + while((c < 0) || (c > 0x20)) { if (leng) { *buf++ = c; leng--; } str++; - c = (UINT8)*str; + c = *str; } } if (buf) { @@ -149,16 +152,18 @@ const char *profile_getarg(const char *s // ---- まだテスト typedef struct { - UINT applen; - UINT keylen; - UINT pos; - UINT size; - UINT apphit; -const char *data; - UINT datasize; + UINT applen; + UINT keylen; + UINT pos; + UINT size; + UINT apphit; +const OEMCHAR *data; + UINT datasize; } PFPOS; -static char *delspace(const char *buf, UINT *len) { +#define PFBUFSIZE (1 << 8) + +static OEMCHAR *delspace(const OEMCHAR *buf, UINT *len) { UINT l; @@ -173,15 +178,16 @@ static char *delspace(const char *buf, U } *len = l; } - return((char *)buf); + return((OEMCHAR *)buf); } -static BOOL seakey(PFILEH hdl, PFPOS *pfp, const char *app, const char *key) { +static BRESULT seakey(PFILEH hdl, PFPOS *pfp, const OEMCHAR *app, + const OEMCHAR *key) { PFPOS ret; UINT pos; UINT size; - char *buf; + OEMCHAR *buf; UINT len; UINT cnt; @@ -189,8 +195,8 @@ static BOOL seakey(PFILEH hdl, PFPOS *pf return(FAILURE); } ZeroMemory(&ret, sizeof(ret)); - ret.applen = strlen(app); - ret.keylen = strlen(key); + ret.applen = OEMSTRLEN(app); + ret.keylen = OEMSTRLEN(key); if ((ret.applen == 0) || (ret.keylen == 0)) { return(FAILURE); } @@ -259,12 +265,13 @@ static BOOL seakey(PFILEH hdl, PFPOS *pf return(SUCCESS); } -static BOOL replace(PFILEH hdl, UINT pos, UINT size1, UINT size2) { +static BRESULT replace(PFILEH hdl, UINT pos, UINT size1, UINT size2) { UINT cnt; UINT size; - char *p; - char *q; + UINT newsize; + OEMCHAR *p; + OEMCHAR *q; size1 += pos; size2 += pos; @@ -273,11 +280,21 @@ static BOOL replace(PFILEH hdl, UINT pos } cnt = hdl->size - size1; if (size1 < size2) { - size = size2 - size1; - if ((hdl->size + size) > hdl->buffers) { - return(FAILURE); + size = hdl->size + size2 - size1; + if (size > hdl->buffers) { + newsize = (size & (~(PFBUFSIZE - 1))) + PFBUFSIZE; + p = (OEMCHAR *)_MALLOC(newsize * sizeof(OEMCHAR), "profile"); + if (p == NULL) { + return(FAILURE); + } + if (hdl->buffer) { + CopyMemory(p, hdl->buffer, hdl->buffers * sizeof(OEMCHAR)); + _MFREE(hdl->buffer); + } + hdl->buffer = p; + hdl->buffers = newsize; } - hdl->size += size; + hdl->size = size; if (cnt) { p = hdl->buffer + size1; q = hdl->buffer + size2; @@ -301,76 +318,247 @@ static BOOL replace(PFILEH hdl, UINT pos return(SUCCESS); } -PFILEH profile_open(const char *filename, UINT flag) { +static PFILEH registfile(FILEH fh) { - FILEH fh; - UINT filesize; + UINT rsize; +#if defined(SUPPORT_TEXTCNV) + TCINF inf; +#endif + UINT hdrsize; + UINT width; + UINT8 hdr[4]; UINT size; + UINT newsize; + void *buf; +#if defined(SUPPORT_TEXTCNV) + void *buf2; +#endif PFILEH ret; - if (filename == NULL) { - goto pfore_err1; + rsize = file_read(fh, hdr, sizeof(hdr)); +#if defined(SUPPORT_TEXTCNV) + if (textcnv_getinfo(&inf, hdr, rsize) == 0) { + goto rf_err1; + } + if (!(inf.caps & TEXTCNV_READ)) { + goto rf_err1; + } + if ((inf.width != 1) && (inf.width != 2)) { + goto rf_err1; + } + hdrsize = inf.hdrsize; + width = inf.width; +#else + hdrsize = 0; + width = 1; + if ((rsize >= 3) && + (hdr[0] == 0xef) && (hdr[1] == 0xbb) && (hdr[2] == 0xbf)) { + // UTF-8 + hdrsize = 3; + } + else if ((rsize >= 2) && (hdr[0] == 0xff) && (hdr[1] == 0xfe)) { + // UCSLE + hdrsize = 2; + width = 2; +#if defined(BYTESEX_BIG) + goto rf_err1; +#endif + } + else if ((rsize >= 2) && (hdr[0] == 0xfe) && (hdr[1] == 0xff)) { + // UCS2BE + hdrsize = 2; + width = 2; +#if defined(BYTESEX_LITTLE) + goto rf_err1; +#endif + } + if (width != sizeof(OEMCHAR)) { + goto rf_err1; + } +#endif + + size = file_getsize(fh); + if (size < hdrsize) { + goto rf_err1; + } + if (file_seek(fh, (long)hdrsize, FSEEK_SET) != (long)hdrsize) { + goto rf_err1; + } + size = (size - hdrsize) / width; + newsize = (size & (~(PFBUFSIZE - 1))) + PFBUFSIZE; + buf = _MALLOC(newsize * width, "profile"); + if (buf == NULL) { + goto rf_err1; + } + rsize = file_read(fh, buf, newsize * width) / width; +#if defined(SUPPORT_TEXTCNV) + if (inf.xendian) { + textcnv_swapendian16(buf, rsize); + } + if (inf.tooem) { + size = (inf.tooem)(NULL, 0, buf, rsize); + newsize = (size & (~(PFBUFSIZE - 1))) + PFBUFSIZE; + buf2 = _MALLOC(newsize * sizeof(OEMCHAR), "profile tmp"); + if (buf2 == NULL) { + goto rf_err2; + } + (inf.tooem)(buf2, size, buf, rsize); + _MFREE(buf); + buf = buf2; + rsize = size; } - fh = file_open(filename); - filesize = 0; - if (fh != FILEH_INVALID) { - filesize = file_getsize(fh); - } - else if (flag & PFILEH_READONLY) { - goto pfore_err1; +#endif // defined(SUPPORT_TEXTCNV) + + ret = (PFILEH)_MALLOC(sizeof(_PFILEH), "profile"); + if (ret == NULL) { + goto rf_err2; } - else { - fh = file_create(filename); - if (fh == FILEH_INVALID) { - goto pfore_err1; - } + ZeroMemory(ret, sizeof(_PFILEH)); + ret->buffer = buf; + ret->buffers = newsize; + ret->size = rsize; + if (hdrsize) { + CopyMemory(ret->hdr, hdr, hdrsize); } - size = filesize + 0x2000; - ret = (PFILEH)_MALLOC(sizeof(_PFILEH) + size, filename); + ret->hdrsize = hdrsize; + return(ret); + +rf_err2: + _MFREE(buf); + +rf_err1: + return(NULL); +} + +static PFILEH registnew(void) { + +const UINT8 *hdr; + UINT hdrsize; + PFILEH ret; + +#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 + + ret = (PFILEH)_MALLOC(sizeof(_PFILEH), "profile"); if (ret == NULL) { - goto pfore_err2; + goto rn_err; } - if (filesize) { - if (file_read(fh, ret + 1, filesize) != filesize) { - goto pfore_err3; - } + ZeroMemory(ret, sizeof(_PFILEH)); +// ret->buffer = NULL; +// ret->buffers = 0; +// ret->size = 0; + if (hdrsize) { + CopyMemory(ret->hdr, hdr, hdrsize); } - file_close(fh); - ret->buffer = (BYTE *)(ret + 1); - ret->buffers = size; - ret->size = filesize; - ret->flag = flag; - file_cpyname(ret->path, filename, sizeof(ret->path)); + ret->hdrsize = hdrsize; return(ret); -pfore_err3: - _MFREE(ret); +rn_err: + return(NULL); +} -pfore_err2: - file_close(fh); +PFILEH profile_open(const OEMCHAR *filename, UINT flag) { -pfore_err1: - return(NULL); + PFILEH ret; + FILEH fh; + + ret = NULL; + if (filename != NULL) { + fh = file_open_rb(filename); + if (fh != FILEH_INVALID) { + ret = registfile(fh); + file_close(fh); + } + else if (flag & PFILEH_READONLY) { + } + else { + ret = registnew(); + } + } + if (ret) { + ret->flag = flag; + file_cpyname(ret->path, filename, NELEMENTS(ret->path)); + } + return(ret); } void profile_close(PFILEH hdl) { + void *buf; + UINT bufsize; +#if defined(SUPPORT_TEXTCNV) + TCINF inf; + void *buf2; + UINT buf2size; +#endif + UINT hdrsize; + UINT width; FILEH fh; - if (hdl) { - if (hdl->flag & PFILEH_MODIFY) { - fh = file_create(hdl->path); - if (fh != FILEH_INVALID) { - file_write(fh, hdl->buffer, hdl->size); - file_close(fh); + if (hdl == NULL) { + return; + } + buf = hdl->buffer; + bufsize = hdl->size; + if (hdl->flag & PFILEH_MODIFY) { +#if defined(SUPPORT_TEXTCNV) + if (textcnv_getinfo(&inf, hdl->hdr, hdl->hdrsize) == 0) { + goto wf_err1; + } + if (!(inf.caps & TEXTCNV_WRITE)) { + goto wf_err1; + } + if ((inf.width != 1) && (inf.width != 2)) { + goto wf_err1; + } + if (inf.fromoem) { + buf2size = (inf.fromoem)(NULL, 0, buf, bufsize); + buf2 = _MALLOC(buf2size * inf.width, "profile tmp"); + if (buf2 == NULL) { + goto wf_err1; } + (inf.fromoem)(buf2, buf2size, buf, bufsize); + _MFREE(buf); + buf = buf2; + bufsize = buf2size; + } + if (inf.xendian) { + textcnv_swapendian16(buf, bufsize); + } + hdrsize = inf.hdrsize; + width = inf.width; +#else // defined(SUPPORT_TEXTCNV) + hdrsize = hdl->hdrsize; + width = sizeof(OEMCHAR); +#endif // defined(SUPPORT_TEXTCNV) + fh = file_create(hdl->path); + if (fh == FILEH_INVALID) { + goto wf_err1; + } + if (hdrsize) { + file_write(fh, hdl->hdr, hdrsize); } - _MFREE(hdl); + file_write(fh, buf, bufsize * width); + file_close(fh); } + +wf_err1: + if (buf) { + _MFREE(buf); + } + _MFREE(hdl); } -BOOL profile_read(const char *app, const char *key, const char *def, - char *ret, UINT size, PFILEH hdl) { +BRESULT profile_read(const OEMCHAR *app, const OEMCHAR *key, + const OEMCHAR *def, OEMCHAR *ret, UINT size, PFILEH hdl) { PFPOS pfp; @@ -388,58 +576,152 @@ BOOL profile_read(const char *app, const } } -BOOL profile_write(const char *app, const char *key, - const char *data, PFILEH hdl) { +BRESULT profile_write(const OEMCHAR *app, const OEMCHAR *key, + const OEMCHAR *data, PFILEH hdl) { PFPOS pfp; UINT newsize; UINT datalen; - char *buf; + OEMCHAR *buf; if ((hdl == NULL) || (hdl->flag & PFILEH_READONLY) || (data == NULL) || (seakey(hdl, &pfp, app, key) != SUCCESS)) { return(FAILURE); } if (!pfp.apphit) { - newsize = pfp.applen + 2 + 2; + newsize = pfp.applen + 2; +#if defined(OSLINEBREAK_CR) || defined(OSLINEBREAK_CRLF) + newsize++; +#endif +#if defined(OSLINEBREAK_LF) || defined(OSLINEBREAK_CRLF) + newsize++; +#endif if (replace(hdl, pfp.pos, 0, newsize) != SUCCESS) { return(FAILURE); } buf = hdl->buffer + pfp.pos; *buf++ = '['; - CopyMemory(buf, app, pfp.applen); + CopyMemory(buf, app, pfp.applen * sizeof(OEMCHAR)); buf += pfp.applen; - buf[0] = ']'; - buf[1] = '\r'; - buf[2] = '\n'; + *buf++ = ']'; +#if defined(OSLINEBREAK_CR) || defined(OSLINEBREAK_CRLF) + *buf++ = '\r'; +#endif +#if defined(OSLINEBREAK_LF) || defined(OSLINEBREAK_CRLF) + *buf++ = '\n'; +#endif pfp.pos += newsize; } - datalen = strlen(data); - newsize = pfp.keylen + 1 + datalen + 2; + datalen = OEMSTRLEN(data); + newsize = pfp.keylen + 1 + datalen; +#if defined(OSLINEBREAK_CR) || defined(OSLINEBREAK_CRLF) + newsize++; +#endif +#if defined(OSLINEBREAK_LF) || defined(OSLINEBREAK_CRLF) + newsize++; +#endif if (replace(hdl, pfp.pos, pfp.size, newsize) != SUCCESS) { return(FAILURE); } buf = hdl->buffer + pfp.pos; - CopyMemory(buf, key, pfp.keylen); + CopyMemory(buf, key, pfp.keylen * sizeof(OEMCHAR)); buf += pfp.keylen; *buf++ = '='; - CopyMemory(buf, data, datalen); + CopyMemory(buf, data, datalen * sizeof(OEMCHAR)); buf += datalen; - buf[0] = '\r'; - buf[1] = '\n'; +#if defined(OSLINEBREAK_CR) || defined(OSLINEBREAK_CRLF) + *buf++ = '\r'; +#endif +#if defined(OSLINEBREAK_LF) || defined(OSLINEBREAK_CRLF) + *buf++ = '\n'; +#endif return(SUCCESS); } // ---- -void profile_iniread(const char *path, const char *app, - const PFTBL *tbl, UINT count) { +static void bitmapset(UINT8 *ptr, UINT pos, BOOL set) { + + UINT8 bit; + + ptr += (pos >> 3); + bit = 1 << (pos & 7); + if (set) { + *ptr |= bit; + } + else { + *ptr &= ~bit; + } +} + +static BOOL bitmapget(const UINT8 *ptr, UINT pos) { + + return((ptr[pos >> 3] >> (pos & 7)) & 1); +} + +static void binset(UINT8 *bin, UINT binlen, const OEMCHAR *src) { + + UINT i; + UINT8 val; + BOOL set; + OEMCHAR c; + + for (i=0; i= '0') && (c <= '9')) { + val <<= 4; + val += c - '0'; + set = TRUE; + } + else { + c |= 0x20; + if ((c >= 'a') && (c <= 'f')) { + val <<= 4; + val += c - 'a' + 10; + set = TRUE; + } + } + src++; + } + if (set == FALSE) { + break; + } + bin[i] = val; + } +} + +static void binget(OEMCHAR *work, int size, const UINT8 *bin, UINT binlen) { + + UINT i; + OEMCHAR tmp[8]; + + if (binlen) { + OEMSPRINTF(tmp, OEMTEXT("%.2x"), bin[0]); + milstr_ncpy(work, tmp, size); + } + for (i=1; iitem, NULL, work, sizeof(work), pfh) == SUCCESS) { - switch(p->itemtype) { + switch(p->itemtype & PFTYPE_MASK) { + case PFTYPE_STR: + milstr_ncpy((OEMCHAR *)p->value, work, p->arg); + break; + + case PFTYPE_BOOL: + *((UINT8 *)p->value) = (!milstr_cmp(work, str_true))?1:0; + break; + + case PFTYPE_BITMAP: + bitmapset((UINT8 *)p->value, p->arg, + (!milstr_cmp(work, str_true))?TRUE:FALSE); + break; + + case PFTYPE_BIN: + binset((UINT8 *)p->value, p->arg, work); + break; + + case PFTYPE_SINT8: + case PFTYPE_UINT8: + *(UINT8 *)p->value = (UINT32)milstr_solveINT(work); + break; + + case PFTYPE_SINT16: + case PFTYPE_UINT16: + *(UINT16 *)p->value = (UINT32)milstr_solveINT(work); + break; + case PFTYPE_SINT32: case PFTYPE_UINT32: - *(UINT32 *)p->value = (UINT32)milstr_solveINT(work); - break; + *(UINT32 *)p->value = (UINT32)milstr_solveINT(work); + break; + + case PFTYPE_HEX8: + *(UINT8 *)p->value = (UINT8)milstr_solveHEX(work); + break; + + case PFTYPE_HEX16: + *(UINT16 *)p->value = (UINT16)milstr_solveHEX(work); + break; + + case PFTYPE_HEX32: + *(UINT32 *)p->value = (UINT32)milstr_solveHEX(work); + break; + + default: + if (cb != NULL) { + (*cb)(p, work); + } + break; } } p++; @@ -462,14 +789,14 @@ const PFTBL *pterm; profile_close(pfh); } -void profile_iniwrite(const char *path, const char *app, - const PFTBL *tbl, UINT count) { +void profile_iniwrite(const OEMCHAR *path, const OEMCHAR *app, + const PFTBL *tbl, UINT count, PFWRITE cb) { - PFILEH pfh; -const PFTBL *p; -const PFTBL *pterm; -const char *set; - char work[512]; + PFILEH pfh; +const PFTBL *p; +const PFTBL *pterm; +const OEMCHAR *set; + OEMCHAR work[512]; pfh = profile_open(path, 0); if (pfh == NULL) { @@ -478,19 +805,75 @@ const char *set; p = tbl; pterm = tbl + count; while(p < pterm) { - work[0] = '\0'; - set = work; - switch(p->itemtype) { - case PFTYPE_SINT32: - SPRINTF(work, str_d, *((SINT32 *)p->value)); - break; + if (!(p->itemtype & PFFLAG_RO)) { + work[0] = '\0'; + set = work; + switch(p->itemtype & PFTYPE_MASK) { + case PFTYPE_STR: + set = (OEMCHAR *)p->value; + break; - default: - set = NULL; - break; - } - if (set) { - profile_write(app, p->item, set, pfh); + case PFTYPE_BOOL: + set = (*((UINT8 *)p->value))?str_true:str_false; + break; + + case PFTYPE_BITMAP: + set = (bitmapget((UINT8 *)p->value, p->arg))? + str_true:str_false; + break; + + case PFTYPE_BIN: + binget(work, NELEMENTS(work), (UINT8 *)p->value, p->arg); + break; + + case PFTYPE_SINT8: + OEMSPRINTF(work, str_d, *((SINT8 *)p->value)); + break; + + case PFTYPE_SINT16: + OEMSPRINTF(work, str_d, *((SINT16 *)p->value)); + break; + + case PFTYPE_SINT32: + OEMSPRINTF(work, str_d, *((SINT32 *)p->value)); + break; + + case PFTYPE_UINT8: + OEMSPRINTF(work, str_u, *((UINT8 *)p->value)); + break; + + case PFTYPE_UINT16: + OEMSPRINTF(work, str_u, *((UINT16 *)p->value)); + break; + + case PFTYPE_UINT32: + OEMSPRINTF(work, str_u, *((UINT32 *)p->value)); + break; + + case PFTYPE_HEX8: + OEMSPRINTF(work, str_x, *((UINT8 *)p->value)); + break; + + case PFTYPE_HEX16: + OEMSPRINTF(work, str_x, *((UINT16 *)p->value)); + break; + + case PFTYPE_HEX32: + OEMSPRINTF(work, str_x, *((UINT32 *)p->value)); + break; + + default: + if (cb != NULL) { + set = (*cb)(p, work, NELEMENTS(work)); + } + else { + set = NULL; + } + break; + } + if (set) { + profile_write(app, p->item, set, pfh); + } } p++; }