--- np2/common/profile.c 2004/02/11 17:39:59 1.2 +++ np2/common/profile.c 2004/03/31 14:02:50 1.6 @@ -1,4 +1,5 @@ #include "compiler.h" +#include "strres.h" #include "dosio.h" #include "textfile.h" #include "profile.h" @@ -106,14 +107,7 @@ gden_err0: // ---- -typedef struct { - UINT8 num; - char str[7]; -} KEYNAME; - -#include "pf_key.tbl" - -static const char *getarg(const char *str, char *buf, UINT leng) { +const char *profile_getarg(const char *str, char *buf, UINT leng) { UINT8 c; @@ -150,86 +144,437 @@ static const char *getarg(const char *st return(str); } -static const KEYNAME *searchkeynum(const char *str) { -const KEYNAME *n; -const KEYNAME *nterm; - n = keyname; - nterm = keyname + (sizeof(keyname) / sizeof(KEYNAME)); - while(n < nterm) { - if (!milstr_cmp(str, n->str)) { - return(n); +// ---- まだテスト + +typedef struct { + UINT applen; + UINT keylen; + UINT pos; + UINT size; + UINT apphit; +const char *data; + UINT datasize; +} PFPOS; + +static char *delspace(const char *buf, UINT *len) { + + UINT l; + + if ((buf != NULL) && (len != NULL)) { + l = *len; + while((l) && (buf[0] == ' ')) { + l--; + buf++; + } + while((l) && (buf[l - 1] == ' ')) { + l--; } - n++; + *len = l; } - return(NULL); + return((char *)buf); +} + +static BOOL seakey(PFILEH hdl, PFPOS *pfp, const char *app, const char *key) { + + PFPOS ret; + UINT pos; + UINT size; + char *buf; + UINT len; + UINT cnt; + + if ((hdl == NULL) || (app == NULL) || (key == NULL)) { + return(FAILURE); + } + ZeroMemory(&ret, sizeof(ret)); + ret.applen = strlen(app); + ret.keylen = strlen(key); + if ((ret.applen == 0) || (ret.keylen == 0)) { + return(FAILURE); + } + + pos = 0; + size = hdl->size; + while(size) { + buf = hdl->buffer + pos; + len = 0; + cnt = 0; + do { + if (buf[len] == '\r') { + if (((len + 1) < size) && (buf[len + 1] == '\n')) { + cnt = 2; + } + else { + cnt = 1; + } + break; + } + if (buf[len] == '\n') { + cnt = 1; + break; + } + len++; + } while(len < size); + cnt += len; + buf = delspace(buf, &len); + if ((len >= 2) && (buf[0] == '[') && (buf[len - 1] == ']')) { + if (ret.apphit) { + break; + } + buf++; + len -= 2; + buf = delspace(buf, &len); + if ((len == ret.applen) && (!milstr_memcmp(buf, app))) { + ret.apphit = 1; + } + } + else if ((ret.apphit) && (len > ret.keylen) && + (!milstr_memcmp(buf, key))) { + buf += ret.keylen; + len -= ret.keylen; + buf = delspace(buf, &len); + if ((len) && (buf[0] == '=')) { + buf++; + len--; + buf = delspace(buf, &len); + ret.pos = pos; + ret.size = cnt; + ret.data = buf; + ret.datasize = len; + break; + } + } + if (len) { + ret.pos = pos + cnt; + ret.size = 0; + } + pos += cnt; + size -= cnt; + } + if (pfp) { + *pfp = ret; + } + return(SUCCESS); } -static const KEYNAME *searchkeystr(UINT8 num) { +static BOOL replace(PFILEH hdl, UINT pos, UINT size1, UINT size2) { -const KEYNAME *n; -const KEYNAME *nterm; + UINT cnt; + UINT size; + char *p; + char *q; - n = keyname; - nterm = keyname + (sizeof(keyname) / sizeof(KEYNAME)); - while(n < nterm) { - if (n->num == num) { - return(n); + size1 += pos; + size2 += pos; + if (size1 > hdl->size) { + return(FAILURE); + } + cnt = hdl->size - size1; + if (size1 < size2) { + size = size2 - size1; + if ((hdl->size + size) > hdl->buffers) { + return(FAILURE); + } + hdl->size += size; + if (cnt) { + p = hdl->buffer + size1; + q = hdl->buffer + size2; + do { + --cnt; + q[cnt] = p[cnt]; + } while(cnt); + } + } + else if (size1 > size2) { + hdl->size -= (size1 - size2); + if (cnt) { + p = hdl->buffer + size1; + q = hdl->buffer + size2; + do { + *q++ = *p++; + } while(--cnt); } - n++; } + hdl->flag |= PFILEH_MODIFY; + return(SUCCESS); +} + +PFILEH profile_open(const char *filename, UINT flag) { + + FILEH fh; + UINT filesize; + UINT size; + PFILEH ret; + + if (filename == NULL) { + goto pfore_err1; + } + fh = file_open(filename); + filesize = 0; + if (fh != FILEH_INVALID) { + filesize = file_getsize(fh); + } + else if (flag & PFILEH_READONLY) { + goto pfore_err1; + } + else { + fh = file_create(filename); + if (fh == FILEH_INVALID) { + goto pfore_err1; + } + } + size = filesize + 0x2000; + ret = (PFILEH)_MALLOC(sizeof(_PFILEH) + size, filename); + if (ret == NULL) { + goto pfore_err2; + } + if (filesize) { + if (file_read(fh, ret + 1, filesize) != filesize) { + goto pfore_err3; + } + } + 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)); + return(ret); + +pfore_err3: + _MFREE(ret); + +pfore_err2: + file_close(fh); + +pfore_err1: return(NULL); } -UINT profile_setkeys(const char *str, UINT8 *key, UINT keymax) { +void profile_close(PFILEH hdl) { - UINT ret; - char work[7]; -const KEYNAME *k; - - ret = 0; - while(ret < keymax) { - str = getarg(str, work, sizeof(work)); - if (str == NULL) { - break; + 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); + } } - k = searchkeynum(work); - if (k) { - key[ret] = k->num; - ret++; + _MFREE(hdl); + } +} + +BOOL profile_read(const char *app, const char *key, const char *def, + char *ret, UINT size, PFILEH hdl) { + + PFPOS pfp; + + if ((seakey(hdl, &pfp, app, key) != SUCCESS) || (pfp.data == NULL)) { + if (def == NULL) { + def = str_null; } + milstr_ncpy(ret, def, size); + return(FAILURE); + } + else { + size = min(size, pfp.datasize + 1); + milstr_ncpy(ret, pfp.data, size); + return(SUCCESS); } - return(ret); } -void profile_getkeys(char *str, UINT strmax, const UINT8 *key, UINT keys) { +BOOL profile_write(const char *app, const char *key, + const char *data, PFILEH hdl) { + + PFPOS pfp; + UINT newsize; + UINT datalen; + char *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; + if (replace(hdl, pfp.pos, 0, newsize) != SUCCESS) { + return(FAILURE); + } + buf = hdl->buffer + pfp.pos; + *buf++ = '['; + CopyMemory(buf, app, pfp.applen); + buf += pfp.applen; + buf[0] = ']'; + buf[1] = '\r'; + buf[2] = '\n'; + pfp.pos += newsize; + } + datalen = strlen(data); + newsize = pfp.keylen + 1 + datalen + 2; + if (replace(hdl, pfp.pos, pfp.size, newsize) != SUCCESS) { + return(FAILURE); + } + buf = hdl->buffer + pfp.pos; + CopyMemory(buf, key, pfp.keylen); + buf += pfp.keylen; + *buf++ = '='; + CopyMemory(buf, data, datalen); + buf += datalen; + buf[0] = '\r'; + buf[1] = '\n'; + return(SUCCESS); +} + + +// ---- + +void profile_iniread(const char *path, const char *app, + const PFTBL *tbl, UINT count) { - UINT space; - UINT i; -const KEYNAME *k; - UINT len; + PFILEH pfh; +const PFTBL *p; +const PFTBL *pterm; + char work[512]; - if ((str == NULL) || (strmax == 0)) { + pfh = profile_open(path, 0); + if (pfh == NULL) { return; } - strmax--; - space = 0; - for (i=0; istr); - if ((len + space) > strmax) { - break; + p = tbl; + pterm = tbl + count; + while(p < pterm) { + if (profile_read(app, p->item, NULL, work, sizeof(work), pfh) + == SUCCESS) { + switch(p->itemtype & PFITYPE_MASK) { + case PFTYPE_STR: + milstr_ncpy(p->value, work, p->arg); + break; + + case PFTYPE_BOOL: + *((UINT8 *)p->value) = (!milstr_cmp(work, str_true))?1:0; + break; + + case PFTYPE_BITMAP: // Todo + case PFTYPE_BIN: + 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; + + 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; + } + } + p++; + } + profile_close(pfh); +} + +void profile_iniwrite(const char *path, const char *app, + const PFTBL *tbl, UINT count) { + + PFILEH pfh; +const PFTBL *p; +const PFTBL *pterm; +const char *set; + char work[512]; + + pfh = profile_open(path, 0); + if (pfh == NULL) { + return; + } + p = tbl; + pterm = tbl + count; + while(p < pterm) { + if (!(p->itemtype & PFFLAG_RO)) { + work[0] = '\0'; + set = work; + switch(p->itemtype & PFITYPE_MASK) { + case PFTYPE_STR: + set = (char *)p->value; + break; + + case PFTYPE_BOOL: + set = (*((UINT8 *)p->value))?str_true:str_false; + break; + + case PFTYPE_BITMAP: // Todo + case PFTYPE_BIN: + set = NULL; + break; + + case PFTYPE_SINT8: + SPRINTF(work, str_d, *((SINT8 *)p->value)); + break; + + case PFTYPE_SINT16: + SPRINTF(work, str_d, *((SINT16 *)p->value)); + break; + + case PFTYPE_SINT32: + SPRINTF(work, str_d, *((SINT32 *)p->value)); + break; + + case PFTYPE_UINT8: + SPRINTF(work, str_u, *((UINT8 *)p->value)); + break; + + case PFTYPE_UINT16: + SPRINTF(work, str_u, *((UINT16 *)p->value)); + break; + + case PFTYPE_UINT32: + SPRINTF(work, str_u, *((UINT32 *)p->value)); + break; + + case PFTYPE_HEX8: + SPRINTF(work, str_x, *((UINT8 *)p->value)); + break; + + case PFTYPE_HEX16: + SPRINTF(work, str_x, *((UINT16 *)p->value)); + break; + + case PFTYPE_HEX32: + SPRINTF(work, str_x, *((UINT32 *)p->value)); + break; + + default: + set = NULL; + break; } - if (space) { - *str++ = ' '; + if (set) { + profile_write(app, p->item, set, pfh); } - CopyMemory(str, k->str, len); - str += len; - space = 1; } + p++; } - str[0] = '\0'; + profile_close(pfh); }