Diff for /np2/common/profile.c between versions 1.1.1.1 and 1.14

version 1.1.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);
   }
   

Removed from v.1.1.1.1  
changed lines
  Added in v.1.14


RetroPC.NET-CVS <cvs@retropc.net>