| version 1.1, 2003/10/16 17:57:10 | version 1.14, 2005/03/20 08:58:19 | 
| 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" | 
 | #include        "profile.h" | #include        "profile.h" | 
 |  |  | 
 |  |  | 
| static void strdelspace(char **buf, int *size) { | static void strdelspace(OEMCHAR **buf, int *size) { | 
 |  |  | 
| char    *p; | OEMCHAR *p; | 
 | int             len; | int             len; | 
 |  |  | 
 | p = *buf; | p = *buf; | 
| Line 22  static void strdelspace(char **buf, int | Line 23  static void strdelspace(char **buf, int | 
 | *size = len; | *size = len; | 
 | } | } | 
 |  |  | 
| static char *profana(char *buf, char **data) { | static OEMCHAR *profana(OEMCHAR *buf, OEMCHAR **data) { | 
 |  |  | 
 | int             len; | int             len; | 
| char    *buf2; | OEMCHAR *buf2; | 
 | int             l; | int             l; | 
 |  |  | 
| len = strlen(buf); | len = OEMSTRLEN(buf); | 
 | strdelspace(&buf, &len); | strdelspace(&buf, &len); | 
 | if ((len >= 2) && (buf[0] == '[') && (buf[len - 1] == ']')) { | if ((len >= 2) && (buf[0] == '[') && (buf[len - 1] == ']')) { | 
 | buf++; | buf++; | 
| Line 61  static char *profana(char *buf, char **d | Line 62  static char *profana(char *buf, char **d | 
 | return(NULL); | return(NULL); | 
 | } | } | 
 |  |  | 
| BOOL profile_enum(const char *filename, void *arg, | BOOL profile_enum(const OEMCHAR *filename, void *arg, | 
| BOOL (*proc)(void *arg, const char *para, | BOOL (*proc)(void *arg, const OEMCHAR *para, | 
| const char *key, const char *data)) { | const OEMCHAR *key, const OEMCHAR *data)) { | 
 | TEXTFILEH       fh; | TEXTFILEH       fh; | 
 | BOOL            r; | BOOL            r; | 
| char            buf[0x200]; | OEMCHAR         buf[0x200]; | 
| char            para[0x100]; | OEMCHAR         para[0x100]; | 
| char            *key; | OEMCHAR         *key; | 
| char            *data; | OEMCHAR         *data; | 
 |  |  | 
 | r = FALSE; | r = FALSE; | 
 | if (proc == NULL) { | if (proc == NULL) { | 
| Line 81  BOOL profile_enum(const char *filename, | Line 82  BOOL profile_enum(const char *filename, | 
 | } | } | 
 | para[0] = '\0'; | para[0] = '\0'; | 
 | while(1) { | while(1) { | 
| if (textfile_read(fh, buf, sizeof(buf)) != SUCCESS) { | if (textfile_read(fh, buf, NELEMENTS(buf)) != SUCCESS) { | 
 | break; | break; | 
 | } | } | 
 | key = profana(buf, &data); | key = profana(buf, &data); | 
 | if (key) { | if (key) { | 
 | if (data == NULL) { | if (data == NULL) { | 
| milstr_ncpy(para, key, sizeof(para)); | milstr_ncpy(para, key, NELEMENTS(para)); | 
 | } | } | 
 | else { | else { | 
 | r = proc(arg, para, key, data); | r = proc(arg, para, key, data); | 
| Line 103  gden_err0: | Line 104  gden_err0: | 
 | return(r); | return(r); | 
 | } | } | 
 |  |  | 
 |  |  | 
 |  | // ---- | 
 |  |  | 
 |  | const OEMCHAR *profile_getarg(const OEMCHAR *str, OEMCHAR *buf, UINT leng) { | 
 |  |  | 
 |  | UINT8   c; | 
 |  |  | 
 |  | if (leng) { | 
 |  | leng--; | 
 |  | } | 
 |  | else { | 
 |  | buf = NULL; | 
 |  | } | 
 |  | if (str) { | 
 |  | c = (UINT8)*str; | 
 |  | while(((c - 1) & 0xff) < 0x20) { | 
 |  | str++; | 
 |  | c = (UINT8)*str; | 
 |  | } | 
 |  | if (c == 0) { | 
 |  | str = NULL; | 
 |  | } | 
 |  | } | 
 |  | if (str) { | 
 |  | c = (UINT8)*str; | 
 |  | while(c > 0x20) { | 
 |  | if (leng) { | 
 |  | *buf++ = c; | 
 |  | leng--; | 
 |  | } | 
 |  | str++; | 
 |  | c = (UINT8)*str; | 
 |  | } | 
 |  | } | 
 |  | if (buf) { | 
 |  | buf[0] = '\0'; | 
 |  | } | 
 |  | return(str); | 
 |  | } | 
 |  |  | 
 |  |  | 
 |  |  | 
 |  | // ---- まだテスト | 
 |  |  | 
 |  | typedef struct { | 
 |  | UINT            applen; | 
 |  | UINT            keylen; | 
 |  | UINT            pos; | 
 |  | UINT            size; | 
 |  | UINT            apphit; | 
 |  | const OEMCHAR   *data; | 
 |  | UINT            datasize; | 
 |  | } PFPOS; | 
 |  |  | 
 |  | #define PFBUFSIZE       (1 << 8) | 
 |  |  | 
 |  | static OEMCHAR *delspace(const OEMCHAR *buf, UINT *len) { | 
 |  |  | 
 |  | UINT    l; | 
 |  |  | 
 |  | if ((buf != NULL) && (len != NULL)) { | 
 |  | l = *len; | 
 |  | while((l) && (buf[0] == ' ')) { | 
 |  | l--; | 
 |  | buf++; | 
 |  | } | 
 |  | while((l) && (buf[l - 1] == ' ')) { | 
 |  | l--; | 
 |  | } | 
 |  | *len = l; | 
 |  | } | 
 |  | return((OEMCHAR *)buf); | 
 |  | } | 
 |  |  | 
 |  | static BRESULT seakey(PFILEH hdl, PFPOS *pfp, const OEMCHAR *app, | 
 |  | const OEMCHAR *key) { | 
 |  |  | 
 |  | PFPOS   ret; | 
 |  | UINT    pos; | 
 |  | UINT    size; | 
 |  | OEMCHAR *buf; | 
 |  | UINT    len; | 
 |  | UINT    cnt; | 
 |  |  | 
 |  | if ((hdl == NULL) || (app == NULL) || (key == NULL)) { | 
 |  | return(FAILURE); | 
 |  | } | 
 |  | ZeroMemory(&ret, sizeof(ret)); | 
 |  | ret.applen = OEMSTRLEN(app); | 
 |  | ret.keylen = OEMSTRLEN(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 BRESULT replace(PFILEH hdl, UINT pos, UINT size1, UINT size2) { | 
 |  |  | 
 |  | UINT    cnt; | 
 |  | UINT    size; | 
 |  | UINT    newsize; | 
 |  | OEMCHAR *p; | 
 |  | OEMCHAR *q; | 
 |  |  | 
 |  | size1 += pos; | 
 |  | size2 += pos; | 
 |  | if (size1 > hdl->size) { | 
 |  | return(FAILURE); | 
 |  | } | 
 |  | cnt = hdl->size - size1; | 
 |  | if (size1 < size2) { | 
 |  | 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; | 
 |  | 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); | 
 |  | } | 
 |  | } | 
 |  | hdl->flag |= PFILEH_MODIFY; | 
 |  | return(SUCCESS); | 
 |  | } | 
 |  |  | 
 |  | static PFILEH registfile(FILEH fh) { | 
 |  |  | 
 |  | UINT    hdrsize; | 
 |  | UINT    srcwidth; | 
 |  | BOOL    xendian; | 
 |  | UINT    rsize; | 
 |  | UINT8   hdr[4]; | 
 |  | UINT    size; | 
 |  | UINT    newsize; | 
 |  | OEMCHAR *buf; | 
 |  | PFILEH  ret; | 
 |  |  | 
 |  | hdrsize = 0; | 
 |  | srcwidth = 1; | 
 |  | xendian = FALSE; | 
 |  | rsize = file_read(fh, hdr, sizeof(hdr)); | 
 |  | 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; | 
 |  | srcwidth = 2; | 
 |  | #if defined(BYTESEX_BIG) | 
 |  | xendian = TRUE; | 
 |  | #endif | 
 |  | } | 
 |  | else if ((rsize >= 2) && (hdr[0] == 0xfe) && (hdr[1] == 0xff)) { | 
 |  | // UCS2BE | 
 |  | hdrsize = 2; | 
 |  | srcwidth = 2; | 
 |  | #if defined(BYTESEX_LITTLE) | 
 |  | xendian = TRUE; | 
 |  | #endif | 
 |  | } | 
 |  |  | 
 |  | if (srcwidth != sizeof(OEMCHAR)) { | 
 |  | goto rf_err1; | 
 |  | } | 
 |  | 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) / srcwidth; | 
 |  | newsize = (size & (~(PFBUFSIZE - 1))) + PFBUFSIZE; | 
 |  | buf = (OEMCHAR *)_MALLOC(newsize * srcwidth, "profile"); | 
 |  | if (buf == NULL) { | 
 |  | goto rf_err1; | 
 |  | } | 
 |  | rsize = file_read(fh, buf, newsize * srcwidth) / srcwidth; | 
 |  |  | 
 |  | ret = (PFILEH)_MALLOC(sizeof(_PFILEH), "profile"); | 
 |  | if (ret == NULL) { | 
 |  | goto rf_err2; | 
 |  | } | 
 |  | ZeroMemory(ret, sizeof(_PFILEH)); | 
 |  | ret->buffer = buf; | 
 |  | ret->buffers = newsize; | 
 |  | ret->size = rsize; | 
 |  | if (hdrsize) { | 
 |  | CopyMemory(ret->hdr, hdr, hdrsize); | 
 |  | } | 
 |  | 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 rn_err; | 
 |  | } | 
 |  | ZeroMemory(ret, sizeof(_PFILEH)); | 
 |  | //      ret->buffer = NULL; | 
 |  | //      ret->buffers = 0; | 
 |  | //      ret->size = 0; | 
 |  | if (hdrsize) { | 
 |  | CopyMemory(ret->hdr, hdr, hdrsize); | 
 |  | } | 
 |  | ret->hdrsize = hdrsize; | 
 |  | return(ret); | 
 |  |  | 
 |  | rn_err: | 
 |  | return(NULL); | 
 |  | } | 
 |  |  | 
 |  | PFILEH profile_open(const OEMCHAR *filename, UINT flag) { | 
 |  |  | 
 |  | 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) { | 
 |  |  | 
 |  | FILEH   fh; | 
 |  |  | 
 |  | if (hdl) { | 
 |  | if (hdl->flag & PFILEH_MODIFY) { | 
 |  | fh = file_create(hdl->path); | 
 |  | if (fh != FILEH_INVALID) { | 
 |  | file_write(fh, hdl->hdr, hdl->hdrsize); | 
 |  | file_write(fh, hdl->buffer, hdl->size * sizeof(OEMCHAR)); | 
 |  | file_close(fh); | 
 |  | } | 
 |  | } | 
 |  | _MFREE(hdl); | 
 |  | } | 
 |  | } | 
 |  |  | 
 |  | BRESULT profile_read(const OEMCHAR *app, const OEMCHAR *key, | 
 |  | const OEMCHAR *def, OEMCHAR *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); | 
 |  | } | 
 |  | } | 
 |  |  | 
 |  | BRESULT profile_write(const OEMCHAR *app, const OEMCHAR *key, | 
 |  | const OEMCHAR *data, PFILEH hdl) { | 
 |  |  | 
 |  | PFPOS   pfp; | 
 |  | UINT    newsize; | 
 |  | UINT    datalen; | 
 |  | 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; | 
 |  | #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 * sizeof(OEMCHAR)); | 
 |  | buf += pfp.applen; | 
 |  | *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 = 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 * sizeof(OEMCHAR)); | 
 |  | buf += pfp.keylen; | 
 |  | *buf++ = '='; | 
 |  | CopyMemory(buf, data, datalen * sizeof(OEMCHAR)); | 
 |  | buf += datalen; | 
 |  | #if defined(OSLINEBREAK_CR) || defined(OSLINEBREAK_CRLF) | 
 |  | *buf++ = '\r'; | 
 |  | #endif | 
 |  | #if defined(OSLINEBREAK_LF) || defined(OSLINEBREAK_CRLF) | 
 |  | *buf++ = '\n'; | 
 |  | #endif | 
 |  | return(SUCCESS); | 
 |  | } | 
 |  |  | 
 |  |  | 
 |  | // ---- | 
 |  |  | 
 |  | 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<binlen; i++) { | 
 |  | val = 0; | 
 |  | set = FALSE; | 
 |  | while(*src == ' ') { | 
 |  | src++; | 
 |  | } | 
 |  | while(1) { | 
 |  | c = *src; | 
 |  | if ((c == '\0') || (c == ' ')) { | 
 |  | break; | 
 |  | } | 
 |  | else if ((c >= '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; i<binlen; i++) { | 
 |  | OEMSPRINTF(tmp, OEMTEXT(" %.2x"), bin[i]); | 
 |  | milstr_ncat(work, tmp, size); | 
 |  | } | 
 |  | } | 
 |  |  | 
 |  | void profile_iniread(const OEMCHAR *path, const OEMCHAR *app, | 
 |  | const PFTBL *tbl, UINT count, PFREAD cb) { | 
 |  |  | 
 |  | PFILEH  pfh; | 
 |  | const PFTBL     *p; | 
 |  | const PFTBL     *pterm; | 
 |  | OEMCHAR work[512]; | 
 |  |  | 
 |  | pfh = profile_open(path, 0); | 
 |  | if (pfh == NULL) { | 
 |  | return; | 
 |  | } | 
 |  | p = tbl; | 
 |  | pterm = tbl + count; | 
 |  | while(p < pterm) { | 
 |  | if (profile_read(app, p->item, NULL, work, sizeof(work), pfh) | 
 |  | == SUCCESS) { | 
 |  | switch(p->itemtype & PFTYPE_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: | 
 |  | 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; | 
 |  |  | 
 |  | 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++; | 
 |  | } | 
 |  | profile_close(pfh); | 
 |  | } | 
 |  |  | 
 |  | 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 OEMCHAR   *set; | 
 |  | OEMCHAR         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 & PFTYPE_MASK) { | 
 |  | case PFTYPE_STR: | 
 |  | set = (OEMCHAR *)p->value; | 
 |  | break; | 
 |  |  | 
 |  | 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++; | 
 |  | } | 
 |  | profile_close(pfh); | 
 |  | } | 
 |  |  |