00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 int GWEN_DB_EscapeToBufferTolerant(const char *src, GWEN_BUFFER *buf) {
00031 while(*src) {
00032 unsigned char x;
00033
00034 x=(unsigned char)*src;
00035 if (!(
00036 (x>='A' && x<='Z') ||
00037 (x>='a' && x<='z') ||
00038 (x>='0' && x<='9') ||
00039 x=='%' ||
00040 x=='.' ||
00041 x==',' ||
00042 x=='.' ||
00043 x=='_' ||
00044 x=='-' ||
00045 x=='*' ||
00046 x=='?'
00047 )) {
00048 unsigned char c;
00049
00050 GWEN_Buffer_AppendByte(buf, '&');
00051 c=(((unsigned char)(*src))>>4)&0xf;
00052 if (c>9)
00053 c+=7;
00054 c+='0';
00055 GWEN_Buffer_AppendByte(buf, c);
00056 c=((unsigned char)(*src))&0xf;
00057 if (c>9)
00058 c+=7;
00059 c+='0';
00060 GWEN_Buffer_AppendByte(buf, c);
00061 }
00062 else
00063 GWEN_Buffer_AppendByte(buf, *src);
00064
00065 src++;
00066 }
00067
00068 return 0;
00069 }
00070
00071
00072
00073 int GWEN_DB_UnescapeToBufferTolerant(const char *src, GWEN_BUFFER *buf) {
00074 while(*src) {
00075 int charHandled;
00076
00077 charHandled=0;
00078 if (*src=='&') {
00079 if (strlen(src)>2) {
00080 unsigned char d1, d2;
00081 unsigned char c;
00082
00083 if (isxdigit((int)src[1]) && isxdigit((int)src[2])) {
00084
00085 src++;
00086
00087 d1=(unsigned char)(toupper(*src));
00088
00089
00090 src++;
00091 d2=(unsigned char)(toupper(*src));
00092
00093 d1-='0';
00094 if (d1>9)
00095 d1-=7;
00096 c=(d1<<4)&0xf0;
00097 d2-='0';
00098 if (d2>9)
00099 d2-=7;
00100 c+=(d2&0xf);
00101
00102 GWEN_Buffer_AppendByte(buf, (char)c);
00103 charHandled=1;
00104 }
00105 }
00106 }
00107 if (!charHandled)
00108 GWEN_Buffer_AppendByte(buf, *src);
00109 src++;
00110 }
00111
00112 return 0;
00113 }
00114
00115
00116
00117
00118
00119
00120 int GWEN_DB_ReadFileAs(GWEN_DB_NODE *db,
00121 const char *fname,
00122 const char *type,
00123 GWEN_DB_NODE *params,
00124 uint32_t dbflags){
00125 GWEN_SYNCIO *sio;
00126 GWEN_DBIO *dbio;
00127 int rv;
00128
00129 dbio=GWEN_DBIO_GetPlugin(type);
00130 if (!dbio) {
00131 DBG_ERROR(GWEN_LOGDOMAIN, "Plugin \"%s\" is not supported", type);
00132 return GWEN_ERROR_NOT_SUPPORTED;
00133 }
00134
00135 sio=GWEN_SyncIo_File_new(fname, GWEN_SyncIo_File_CreationMode_OpenExisting);
00136 GWEN_SyncIo_AddFlags(sio, GWEN_SYNCIO_FILE_FLAGS_READ);
00137 rv=GWEN_SyncIo_Connect(sio);
00138 if (rv<0) {
00139 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00140 GWEN_SyncIo_free(sio);
00141 return rv;
00142 }
00143
00144 rv=GWEN_DBIO_Import(dbio, sio, db, params, dbflags);
00145 if (rv<0) {
00146 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00147 }
00148 GWEN_SyncIo_Disconnect(sio);
00149 GWEN_SyncIo_free(sio);
00150
00151 return rv;
00152 }
00153
00154
00155
00156 int GWEN_DB_WriteFileAs(GWEN_DB_NODE *db,
00157 const char *fname,
00158 const char *type,
00159 GWEN_DB_NODE *params,
00160 uint32_t dbflags){
00161 int rv;
00162 GWEN_DBIO *dbio;
00163
00164 dbio=GWEN_DBIO_GetPlugin(type);
00165 if (!dbio) {
00166 DBG_ERROR(GWEN_LOGDOMAIN, "Plugin \"%s\" is not supported", type);
00167 return GWEN_ERROR_NOT_SUPPORTED;
00168 }
00169
00170 rv=GWEN_DBIO_ExportToFile(dbio, fname, db, params, dbflags);
00171 if (rv) {
00172 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00173 return rv;
00174 }
00175
00176 return 0;
00177 }
00178
00179
00180
00181 int GWEN_DB_WriteGroupToIoLayer(GWEN_DB_NODE *node,
00182 GWEN_FAST_BUFFER *fb,
00183 uint32_t dbflags,
00184 int insert) {
00185 GWEN_DB_NODE *n;
00186 GWEN_DB_NODE *cn;
00187 int i;
00188 int err;
00189 int lastWasVar;
00190
00191 lastWasVar=0;
00192
00193 n=GWEN_DB_Node_List_First(node->children);
00194 while(n) {
00195 if (!(n->nodeFlags & GWEN_DB_NODE_FLAGS_VOLATILE)) {
00196 DBG_VERBOUS(GWEN_LOGDOMAIN, "Writing node");
00197 switch(n->typ) {
00198 case GWEN_DB_NodeType_Group:
00199 if (dbflags & GWEN_DB_FLAGS_WRITE_SUBGROUPS) {
00200 GWEN_BUFFER *tbuf;
00201
00202 if (dbflags & GWEN_DB_FLAGS_ADD_GROUP_NEWLINES) {
00203 if (lastWasVar) {
00204
00205
00206 GWEN_FASTBUFFER_WRITELINE(fb, err, "");
00207 if (err<0) {
00208 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00209 return err;
00210 }
00211 }
00212 }
00213
00214
00215 if (dbflags & GWEN_DB_FLAGS_INDEND) {
00216 for (i=0; i<insert; i++) {
00217 GWEN_FASTBUFFER_WRITEBYTE(fb, err, ' ');
00218 if (err<0) {
00219 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00220 return err;
00221 }
00222 }
00223 }
00224
00225 tbuf=GWEN_Buffer_new(0, 128, 0, 1);
00226 err=GWEN_DB_EscapeToBufferTolerant(n->data.dataName, tbuf);
00227 if (err<0) {
00228 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", err);
00229 GWEN_Buffer_free(tbuf);
00230 return err;
00231 }
00232
00233 GWEN_FASTBUFFER_WRITEFORCED(fb, err,
00234 GWEN_Buffer_GetStart(tbuf),
00235 GWEN_Buffer_GetUsedBytes(tbuf));
00236 GWEN_Buffer_free(tbuf);
00237 if (err<0) {
00238 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", err);
00239 return err;
00240 }
00241 GWEN_FASTBUFFER_WRITELINE(fb, err, " {");
00242 if (err<0) {
00243 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00244 return err;
00245 }
00246 err=GWEN_DB_WriteGroupToIoLayer(n, fb, dbflags, insert+2);
00247 if (err<0)
00248 return err;
00249
00250
00251 if (dbflags & GWEN_DB_FLAGS_INDEND) {
00252 for (i=0; i<insert; i++) {
00253 GWEN_FASTBUFFER_WRITEBYTE(fb, err, ' ');
00254 if (err<0) {
00255 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00256 return err;
00257 }
00258 }
00259 }
00260
00261 if (dbflags & GWEN_DB_FLAGS_DETAILED_GROUPS) {
00262 GWEN_FASTBUFFER_WRITEFORCED(fb, err, "} #", -1);
00263 if (err<0) {
00264 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00265 return err;
00266 }
00267 GWEN_FASTBUFFER_WRITELINE(fb, err, n->data.dataName);
00268 if (err<0) {
00269 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00270 return err;
00271 }
00272 }
00273 else {
00274 GWEN_FASTBUFFER_WRITELINE(fb, err, "}");
00275 if (err<0) {
00276 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00277 return err;
00278 }
00279 }
00280 if (dbflags & GWEN_DB_FLAGS_ADD_GROUP_NEWLINES) {
00281 if (GWEN_DB_Node_List_Next(n)) {
00282
00283
00284 GWEN_FASTBUFFER_WRITELINE(fb, err, "");
00285 if (err<0) {
00286 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00287 return err;
00288 }
00289 }
00290 }
00291 }
00292 lastWasVar=0;
00293 break;
00294
00295 case GWEN_DB_NodeType_Var:
00296 cn=GWEN_DB_Node_List_First(n->children);
00297 if (cn) {
00298 char *typname;
00299 int namewritten;
00300 int values;
00301
00302 typname=0;
00303 namewritten=0;
00304 values=0;
00305 while(cn) {
00306 char numbuffer[32];
00307 char *binbuffer=NULL;
00308 unsigned int bbsize;
00309 const char *pvalue=NULL;
00310 GWEN_BUFFER *vbuf=NULL;
00311
00312 switch(cn->typ) {
00313 case GWEN_DB_NodeType_ValueChar:
00314 typname="char ";
00315 pvalue=cn->data.dataChar;
00316 if (dbflags & GWEN_DB_FLAGS_ESCAPE_CHARVALUES) {
00317 vbuf=GWEN_Buffer_new(0, strlen(pvalue)+32, 0, 1);
00318 if (GWEN_Text_EscapeToBufferTolerant(pvalue, vbuf)) {
00319 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00320 GWEN_Buffer_free(vbuf);
00321 return 1;
00322 }
00323 pvalue=GWEN_Buffer_GetStart(vbuf);
00324 }
00325 break;
00326
00327 case GWEN_DB_NodeType_ValueInt:
00328 typname="int ";
00329 if (GWEN_Text_NumToString(cn->data.dataInt,
00330 numbuffer,
00331 sizeof(numbuffer)-1,
00332 0)<1) {
00333 DBG_ERROR(GWEN_LOGDOMAIN, "Error writing numeric value");
00334 return GWEN_ERROR_GENERIC;
00335 }
00336 pvalue=numbuffer;
00337 break;
00338
00339 case GWEN_DB_NodeType_ValueBin:
00340 bbsize=cn->dataSize*2+1;
00341 binbuffer=(char*)GWEN_Memory_malloc(bbsize);
00342 assert(binbuffer);
00343 typname="bin ";
00344 if (!GWEN_Text_ToHex(cn->data.dataBin,
00345 cn->dataSize,
00346 binbuffer,
00347 bbsize)) {
00348 DBG_ERROR(GWEN_LOGDOMAIN, "Error writing binary value");
00349 return GWEN_ERROR_GENERIC;
00350 }
00351 pvalue=binbuffer;
00352 break;
00353
00354 case GWEN_DB_NodeType_ValuePtr:
00355 DBG_DEBUG(GWEN_LOGDOMAIN, "Not writing ptr type");
00356 break;
00357
00358 default:
00359 DBG_DEBUG(GWEN_LOGDOMAIN, "Unhandled type [%d]", cn->typ);
00360 break;
00361 }
00362
00363 if (pvalue) {
00364 if (!namewritten) {
00365
00366
00367 if (dbflags & GWEN_DB_FLAGS_INDEND) {
00368 for (i=0; i<insert; i++) {
00369 GWEN_FASTBUFFER_WRITEBYTE(fb, err, ' ');
00370 if (err<0) {
00371 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00372 GWEN_Memory_dealloc(binbuffer);
00373 GWEN_Buffer_free(vbuf);
00374 return 1;
00375 }
00376 }
00377 }
00378 if (!(dbflags & GWEN_DB_FLAGS_OMIT_TYPES)) {
00379 GWEN_FASTBUFFER_WRITEFORCED(fb, err, typname, -1);
00380 if (err<0) {
00381 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00382 GWEN_Memory_dealloc(binbuffer);
00383 GWEN_Buffer_free(vbuf);
00384 return 1;
00385 }
00386 }
00387 if (dbflags & GWEN_DB_FLAGS_QUOTE_VARNAMES) {
00388 GWEN_FASTBUFFER_WRITEBYTE(fb, err, '\"');
00389 if (err<0) {
00390 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00391 GWEN_Memory_dealloc(binbuffer);
00392 GWEN_Buffer_free(vbuf);
00393 return 1;
00394 }
00395 }
00396 GWEN_FASTBUFFER_WRITEFORCED(fb, err, n->data.dataName, -1);
00397 if (err<0) {
00398 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00399 GWEN_Memory_dealloc(binbuffer);
00400 GWEN_Buffer_free(vbuf);
00401 return 1;
00402 }
00403 if (dbflags & GWEN_DB_FLAGS_QUOTE_VARNAMES) {
00404 GWEN_FASTBUFFER_WRITEBYTE(fb, err, '\"');
00405 if (err<0) {
00406 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00407 GWEN_Memory_dealloc(binbuffer);
00408 GWEN_Buffer_free(vbuf);
00409 return 1;
00410 }
00411 }
00412 GWEN_FASTBUFFER_WRITEFORCED(fb, err, ((dbflags & GWEN_DB_FLAGS_USE_COLON)?": ":"="), -1);
00413 if (err<0) {
00414 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00415 GWEN_Memory_dealloc(binbuffer);
00416 GWEN_Buffer_free(vbuf);
00417 return 1;
00418 }
00419 namewritten=1;
00420 }
00421
00422 if (values) {
00423 GWEN_FASTBUFFER_WRITEFORCED(fb, err, ", ", -1);
00424 if (err<0) {
00425 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00426 GWEN_Memory_dealloc(binbuffer);
00427 GWEN_Buffer_free(vbuf);
00428 return 1;
00429 }
00430 }
00431 values++;
00432 if (dbflags & GWEN_DB_FLAGS_QUOTE_VALUES) {
00433 GWEN_FASTBUFFER_WRITEBYTE(fb, err, '\"');
00434 if (err<0) {
00435 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00436 GWEN_Memory_dealloc(binbuffer);
00437 GWEN_Buffer_free(vbuf);
00438 return 1;
00439 }
00440 }
00441
00442 GWEN_FASTBUFFER_WRITEFORCED(fb, err, pvalue, -1);
00443 if (err<0) {
00444 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00445 GWEN_Memory_dealloc(binbuffer);
00446 GWEN_Buffer_free(vbuf);
00447 return 1;
00448 }
00449
00450 if (dbflags & GWEN_DB_FLAGS_QUOTE_VALUES) {
00451 GWEN_FASTBUFFER_WRITEBYTE(fb, err, '\"');
00452 if (err<0) {
00453 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00454 GWEN_Memory_dealloc(binbuffer);
00455 GWEN_Buffer_free(vbuf);
00456 return 1;
00457 }
00458 }
00459 }
00460
00461 GWEN_Memory_dealloc(binbuffer);
00462 GWEN_Buffer_free(vbuf);
00463 cn=GWEN_DB_Node_List_Next(cn);
00464 }
00465
00466 if (namewritten) {
00467 GWEN_FASTBUFFER_WRITELINE(fb, err, "");
00468 if (err<0) {
00469 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00470 return GWEN_ERROR_GENERIC;
00471 }
00472 }
00473 }
00474 lastWasVar=1;
00475 break;
00476
00477 default:
00478 DBG_WARN(GWEN_LOGDOMAIN, "[unhandled node type %d]", n->typ);
00479 }
00480 }
00481 else {
00482 DBG_DEBUG(GWEN_LOGDOMAIN, "Node is volatile, not writing it");
00483 }
00484 n=GWEN_DB_Node_List_Next(n);
00485 }
00486
00487 return 0;
00488 }
00489
00490
00491
00492 int GWEN_DB_WriteToFastBuffer(GWEN_DB_NODE *node,
00493 GWEN_FAST_BUFFER *fb,
00494 uint32_t dbflags) {
00495 int rv;
00496
00497 rv=GWEN_DB_WriteGroupToIoLayer(node, fb, dbflags, 0);
00498 if (rv<0) {
00499 return rv;
00500 }
00501 GWEN_FASTBUFFER_FLUSH(fb, rv);
00502 return rv;
00503 }
00504
00505
00506
00507 int GWEN_DB_WriteToIo(GWEN_DB_NODE *node,
00508 GWEN_SYNCIO *sio,
00509 uint32_t dbflags) {
00510 int rv;
00511 GWEN_FAST_BUFFER *fb;
00512
00513 fb=GWEN_FastBuffer_new(512, sio);
00514 if (dbflags & GWEN_DB_FLAGS_DOSMODE)
00515 GWEN_FastBuffer_AddFlags(fb, GWEN_FAST_BUFFER_FLAGS_DOSMODE);
00516 rv=GWEN_DB_WriteGroupToIoLayer(node, fb, dbflags, 0);
00517 if (rv<0) {
00518 GWEN_FastBuffer_free(fb);
00519 return rv;
00520 }
00521 GWEN_FASTBUFFER_FLUSH(fb, rv);
00522 GWEN_FastBuffer_free(fb);
00523 return rv;
00524 }
00525
00526
00527
00528 int GWEN_DB_WriteFile(GWEN_DB_NODE *n, const char *fname, uint32_t dbflags){
00529 int rv;
00530 GWEN_FSLOCK *lck=0;
00531 GWEN_SYNCIO *sio;
00532
00533
00534 if (dbflags & GWEN_DB_FLAGS_LOCKFILE) {
00535 GWEN_FSLOCK_RESULT res;
00536
00537 lck=GWEN_FSLock_new(fname, GWEN_FSLock_TypeFile);
00538 assert(lck);
00539 res=GWEN_FSLock_Lock(lck, GWEN_DB_DEFAULT_LOCK_TIMEOUT, 0);
00540 if (res!=GWEN_FSLock_ResultOk) {
00541 DBG_ERROR(GWEN_LOGDOMAIN,
00542 "Could not apply lock to file \"%s\" (%d)",
00543 fname, res);
00544 GWEN_FSLock_free(lck);
00545 return -1;
00546 }
00547 }
00548
00549
00550 sio=GWEN_SyncIo_File_new(fname, GWEN_SyncIo_File_CreationMode_CreateAlways);
00551 if (dbflags & GWEN_DB_FLAGS_APPEND_FILE)
00552 GWEN_SyncIo_AddFlags(sio, GWEN_SYNCIO_FILE_FLAGS_APPEND);
00553 GWEN_SyncIo_AddFlags(sio,
00554 GWEN_SYNCIO_FILE_FLAGS_READ |
00555 GWEN_SYNCIO_FILE_FLAGS_WRITE |
00556 GWEN_SYNCIO_FILE_FLAGS_UREAD |
00557 GWEN_SYNCIO_FILE_FLAGS_UWRITE);
00558 rv=GWEN_SyncIo_Connect(sio);
00559 if (rv<0) {
00560 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00561 GWEN_SyncIo_free(sio);
00562 if (lck) {
00563 GWEN_FSLock_Unlock(lck);
00564 GWEN_FSLock_free(lck);
00565 }
00566 return rv;
00567 }
00568
00569 rv=GWEN_DB_WriteToIo(n, sio, dbflags);
00570 if (rv<0) {
00571 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00572 GWEN_SyncIo_Disconnect(sio);
00573 GWEN_SyncIo_free(sio);
00574 if (lck) {
00575 GWEN_FSLock_Unlock(lck);
00576 GWEN_FSLock_free(lck);
00577 }
00578 return rv;
00579 }
00580
00581 rv=GWEN_SyncIo_Disconnect(sio);
00582 if (rv<0) {
00583 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00584 GWEN_SyncIo_free(sio);
00585 if (lck) {
00586 GWEN_FSLock_Unlock(lck);
00587 GWEN_FSLock_free(lck);
00588 }
00589 return rv;
00590 }
00591 GWEN_SyncIo_free(sio);
00592
00593
00594 if (lck) {
00595 GWEN_FSLOCK_RESULT res;
00596
00597 res=GWEN_FSLock_Unlock(lck);
00598 if (res!=GWEN_FSLock_ResultOk) {
00599 DBG_WARN(GWEN_LOGDOMAIN,
00600 "Could not remove lock on file \"%s\" (%d)",
00601 fname, res);
00602 }
00603 GWEN_FSLock_free(lck);
00604 }
00605
00606 return 0;
00607 }
00608
00609
00610
00611 int GWEN_DB__ReadValues(GWEN_DB_NODE *n,
00612 uint32_t dbflags,
00613 const char *typeName,
00614 const char *varName,
00615 uint8_t *p) {
00616 GWEN_DB_NODE_TYPE nodeType=GWEN_DB_NodeType_ValueChar;
00617 GWEN_DB_NODE *dbVar;
00618 GWEN_BUFFER *wbuf;
00619 uint8_t *pDebug;
00620
00621 pDebug=p;
00622
00623 if (typeName==NULL)
00624 typeName="char";
00625 if (strcasecmp(typeName, "int")==0)
00626 nodeType=GWEN_DB_NodeType_ValueInt;
00627 else if (strcasecmp(typeName, "char")==0)
00628 nodeType=GWEN_DB_NodeType_ValueChar;
00629 else if (strcasecmp(typeName, "bin")==0)
00630 nodeType=GWEN_DB_NodeType_ValueBin;
00631 else {
00632 DBG_ERROR(GWEN_LOGDOMAIN, "Unknown type \"%s\"", typeName);
00633 return GWEN_ERROR_BAD_DATA;
00634 }
00635
00636 dbVar=GWEN_DB_GetNode(n, varName, dbflags | GWEN_PATH_FLAGS_VARIABLE);
00637 if (dbVar==NULL) {
00638 DBG_INFO(GWEN_LOGDOMAIN, "Variable [%s] is not available", varName);
00639 return GWEN_ERROR_GENERIC;
00640 }
00641
00642 wbuf=GWEN_Buffer_new(0, 32, 0, 1);
00643 for (;;) {
00644 int quotes=0;
00645 GWEN_DB_NODE *dbVal=NULL;
00646 const char *v;
00647
00648 while(*p && isspace(*p))
00649 p++;
00650 if (!*p) {
00651 DBG_INFO(GWEN_LOGDOMAIN, "Missing value");
00652 GWEN_Buffer_free(wbuf);
00653 return GWEN_ERROR_BAD_DATA;
00654 }
00655
00656 if (*p=='"') {
00657 quotes=1;
00658 p++;
00659 }
00660
00661 while(*p) {
00662 if (*p=='%') {
00663 uint8_t c;
00664 uint8_t cHex;
00665
00666
00667 p++;
00668 if (!*p) {
00669 DBG_INFO(GWEN_LOGDOMAIN, "Incomplete escape sequence");
00670 GWEN_Buffer_free(wbuf);
00671 return GWEN_ERROR_BAD_DATA;
00672 }
00673 c=toupper(*p)-'0';
00674 if (c>9) c-=7;
00675 cHex=c<<4;
00676
00677 p++;
00678 if (!*p) {
00679 DBG_INFO(GWEN_LOGDOMAIN, "Incomplete escape sequence");
00680 GWEN_Buffer_free(wbuf);
00681 return GWEN_ERROR_BAD_DATA;
00682 }
00683 c=toupper(*p)-'0';
00684 if (c>9) c-=7;
00685 cHex|=c;
00686 GWEN_Buffer_AppendByte(wbuf, cHex);
00687 }
00688 else
00689 if (quotes) {
00690 if (*p=='"') {
00691 p++;
00692 break;
00693 }
00694 else
00695 GWEN_Buffer_AppendByte(wbuf, *p);
00696 }
00697 else {
00698 if (*p==',' || *p==';' || *p=='#')
00699 break;
00700 else if (*p=='"') {
00701 DBG_INFO(GWEN_LOGDOMAIN, "Unexpected quotation mark (Line: [%s], parsed: [%s]",
00702 pDebug, GWEN_Buffer_GetStart(wbuf));
00703 GWEN_Buffer_free(wbuf);
00704 return GWEN_ERROR_BAD_DATA;
00705 }
00706 else
00707 GWEN_Buffer_AppendByte(wbuf, *p);
00708 }
00709 p++;
00710 }
00711
00712 v=GWEN_Buffer_GetStart(wbuf);
00713 if (nodeType==GWEN_DB_NodeType_ValueInt) {
00714 int i;
00715
00716 if (1!=sscanf(v, "%d", &i)) {
00717 DBG_INFO(GWEN_LOGDOMAIN, "Not an integer value [%s]", v);
00718 GWEN_Buffer_free(wbuf);
00719 return GWEN_ERROR_BAD_DATA;
00720 }
00721 dbVal=GWEN_DB_ValueInt_new(i);
00722 }
00723 else if (nodeType==GWEN_DB_NodeType_ValueChar)
00724 dbVal=GWEN_DB_ValueChar_new(v);
00725 else if (nodeType==GWEN_DB_NodeType_ValueBin) {
00726 GWEN_BUFFER *bbuf;
00727 int rv;
00728
00729 bbuf=GWEN_Buffer_new(0, (GWEN_Buffer_GetUsedBytes(wbuf)/2)+1, 0, 1);
00730 rv=GWEN_Text_FromHexBuffer(v, bbuf);
00731 if (rv) {
00732 DBG_INFO(GWEN_LOGDOMAIN, "Bad bin value [%s]", v);
00733 GWEN_Buffer_free(bbuf);
00734 GWEN_Buffer_free(wbuf);
00735 return GWEN_ERROR_BAD_DATA;
00736 }
00737 dbVal=GWEN_DB_ValueBin_new(GWEN_Buffer_GetStart(bbuf),
00738 GWEN_Buffer_GetUsedBytes(bbuf));
00739 GWEN_Buffer_free(bbuf);
00740 }
00741 else {
00742
00743 assert(0);
00744 }
00745 GWEN_DB_Node_Append(dbVar, dbVal);
00746
00747
00748 while(*p && isspace(*p))
00749 p++;
00750 if (!*p || *p==';' || *p=='#')
00751 break;
00752 else if (*p!=',') {
00753 DBG_INFO(GWEN_LOGDOMAIN, "Unexpected character [%s]", p);
00754 GWEN_Buffer_free(wbuf);
00755 return GWEN_ERROR_BAD_DATA;
00756 }
00757 p++;
00758 GWEN_Buffer_Reset(wbuf);
00759 }
00760
00761 GWEN_Buffer_free(wbuf);
00762 return 0;
00763 }
00764
00765
00766
00767 int GWEN_DB_ReadFromFastBuffer(GWEN_DB_NODE *n,
00768 GWEN_FAST_BUFFER *fb,
00769 uint32_t dbflags) {
00770 GWEN_BUFFER *lbuf;
00771 GWEN_BUFFER *tbuf;
00772 int level=0;
00773 int someLinesRead=0;
00774
00775 lbuf=GWEN_Buffer_new(0, 128, 0, 1);
00776 tbuf=GWEN_Buffer_new(0, 128, 0, 1);
00777
00778 for (;;) {
00779 int rv;
00780 uint8_t *p;
00781
00782 rv=GWEN_FastBuffer_ReadLineToBuffer(fb, lbuf);
00783 if (rv<0) {
00784 if (rv==GWEN_ERROR_EOF) {
00785 if (!someLinesRead && !(dbflags & GWEN_DB_FLAGS_ALLOW_EMPTY_STREAM)){
00786 DBG_INFO(GWEN_LOGDOMAIN, "Unexpected EOF (%d)", rv);
00787 GWEN_Buffer_free(tbuf);
00788 GWEN_Buffer_free(lbuf);
00789 return rv;
00790 }
00791 break;
00792 }
00793 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00794 GWEN_Buffer_free(tbuf);
00795 GWEN_Buffer_free(lbuf);
00796 return rv;
00797 }
00798
00799 if (GWEN_Buffer_GetUsedBytes(lbuf)==0) {
00800 if (dbflags & GWEN_DB_FLAGS_UNTIL_EMPTY_LINE) {
00801 break;
00802 }
00803 }
00804 else {
00805 someLinesRead=1;
00806 p=(uint8_t*)GWEN_Buffer_GetStart(lbuf);
00807 while(*p && isspace(*p))
00808 p++;
00809 if (*p) {
00810 uint8_t *p1begin=NULL, *p1end=NULL;
00811 uint8_t *p2begin=NULL, *p2end=NULL;
00812
00813
00814 if (*p=='}') {
00815
00816 if (level<1) {
00817 DBG_INFO(GWEN_LOGDOMAIN, "Unbalanced number of curly bracket");
00818 GWEN_Buffer_free(tbuf);
00819 GWEN_Buffer_free(lbuf);
00820 return GWEN_ERROR_BAD_DATA;
00821 }
00822 n=n->parent;
00823 assert(n);
00824 assert(n->typ==GWEN_DB_NodeType_Group);
00825 level--;
00826 }
00827 else if (*p=='#') {
00828
00829 }
00830 else {
00831 p1begin=p;
00832
00833 while(*p && !isspace(*p) &&
00834 *p!='{' &&
00835 *p!=((dbflags & GWEN_DB_FLAGS_USE_COLON)?':':'=') &&
00836 *p!='}' &&
00837 *p!=',' &&
00838 *p!=';')
00839 p++;
00840 if (!*p) {
00841 DBG_INFO(GWEN_LOGDOMAIN, "Missing 2nd token (first: \"%s\")", p1begin);
00842 GWEN_Buffer_Dump(lbuf, 2);
00843 GWEN_Buffer_free(tbuf);
00844 GWEN_Buffer_free(lbuf);
00845 return GWEN_ERROR_BAD_DATA;
00846 }
00847 p1end=p;
00848
00849
00850 while(*p && isspace(*p))
00851 p++;
00852 if (!*p) {
00853 DBG_INFO(GWEN_LOGDOMAIN, "Missing 2nd token");
00854 GWEN_Buffer_free(tbuf);
00855 GWEN_Buffer_free(lbuf);
00856 return GWEN_ERROR_BAD_DATA;
00857 }
00858
00859 if (*p=='{') {
00860 GWEN_DB_NODE *newGr;
00861
00862
00863 *p1end=0;
00864 rv=GWEN_DB_UnescapeToBufferTolerant((const char*)p1begin, tbuf);
00865 if (rv<0) {
00866 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00867 GWEN_Buffer_free(tbuf);
00868 GWEN_Buffer_free(lbuf);
00869 return rv;
00870 }
00871 newGr=GWEN_DB_GetGroup(n, dbflags, GWEN_Buffer_GetStart(tbuf));
00872 if (newGr==NULL) {
00873 DBG_INFO(GWEN_LOGDOMAIN, "Could not create group [%s]", GWEN_Buffer_GetStart(tbuf));
00874 GWEN_Buffer_free(tbuf);
00875 GWEN_Buffer_free(lbuf);
00876 return GWEN_ERROR_GENERIC;
00877 }
00878 GWEN_Buffer_Reset(tbuf);
00879 n=newGr;
00880 level++;
00881 }
00882 else if (*p=='=' || *p==':') {
00883
00884 *p1end=0;
00885 p++;
00886 rv=GWEN_DB__ReadValues(n, dbflags, NULL, (const char*)p1begin, p);
00887 if (rv) {
00888 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00889 GWEN_Buffer_free(tbuf);
00890 GWEN_Buffer_free(lbuf);
00891 return rv;
00892 }
00893 }
00894 else if (*p==',' || *p==';') {
00895 DBG_INFO(GWEN_LOGDOMAIN, "Unexpected delimiter found");
00896 GWEN_Buffer_free(tbuf);
00897 GWEN_Buffer_free(lbuf);
00898 return GWEN_ERROR_BAD_DATA;
00899 }
00900 else {
00901
00902 p2begin=p;
00903 while(*p &&
00904 !isspace(*p) &&
00905 *p!='{' &&
00906 *p!=((dbflags & GWEN_DB_FLAGS_USE_COLON)?':':'=') &&
00907 *p!='}' &&
00908 *p!=',' &&
00909 *p!=';')
00910 p++;
00911 if (!*p) {
00912 DBG_INFO(GWEN_LOGDOMAIN, "Missing 2nd token [%s], [%s]", p1begin, p2begin);
00913 GWEN_Buffer_free(tbuf);
00914 GWEN_Buffer_free(lbuf);
00915 return GWEN_ERROR_BAD_DATA;
00916 }
00917 p2end=p;
00918 if (isspace(*p)) {
00919 while(*p && isspace(*p))
00920 p++;
00921 if (!*p) {
00922 DBG_INFO(GWEN_LOGDOMAIN, "Missing 2nd token");
00923 GWEN_Buffer_free(tbuf);
00924 GWEN_Buffer_free(lbuf);
00925 return GWEN_ERROR_BAD_DATA;
00926 }
00927 }
00928 if (*p!='=' && *p!=':') {
00929 DBG_INFO(GWEN_LOGDOMAIN, "Equation mark expected");
00930 GWEN_Buffer_free(tbuf);
00931 GWEN_Buffer_free(lbuf);
00932 return GWEN_ERROR_BAD_DATA;
00933 }
00934 p++;
00935
00936 *p1end=0;
00937 *p2end=0;
00938 rv=GWEN_DB__ReadValues(n, dbflags, (const char*)p1begin, (const char*)p2begin, p);
00939 if (rv) {
00940 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00941 GWEN_Buffer_free(tbuf);
00942 GWEN_Buffer_free(lbuf);
00943 return rv;
00944 }
00945 }
00946 }
00947 }
00948 }
00949 GWEN_Buffer_Reset(lbuf);
00950 }
00951
00952 if (level) {
00953 DBG_INFO(GWEN_LOGDOMAIN, "Unbalanced number of curly bracket (too few)");
00954 GWEN_Buffer_free(tbuf);
00955 GWEN_Buffer_free(lbuf);
00956 return GWEN_ERROR_BAD_DATA;
00957 }
00958
00959 GWEN_Buffer_free(tbuf);
00960 GWEN_Buffer_free(lbuf);
00961
00962 return 0;
00963 }
00964
00965
00966
00967 int GWEN_DB_ReadFromIo(GWEN_DB_NODE *n, GWEN_SYNCIO *sio, uint32_t dbflags) {
00968 GWEN_FAST_BUFFER *fb;
00969 int rv;
00970
00971
00972 fb=GWEN_FastBuffer_new(1024, sio);
00973 if (dbflags & GWEN_DB_FLAGS_DOSMODE)
00974 GWEN_FastBuffer_AddFlags(fb, GWEN_FAST_BUFFER_FLAGS_DOSMODE);
00975
00976
00977 rv=GWEN_DB_ReadFromFastBuffer(n, fb, dbflags);
00978 if (rv<0) {
00979 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00980 GWEN_FastBuffer_free(fb);
00981 return rv;
00982 }
00983
00984 GWEN_FastBuffer_free(fb);
00985
00986 return 0;
00987 }
00988
00989
00990
00991 int GWEN_DB_ReadFile(GWEN_DB_NODE *n,
00992 const char *fname,
00993 uint32_t dbflags) {
00994 GWEN_SYNCIO *sio;
00995 int rv;
00996
00997 sio=GWEN_SyncIo_File_new(fname, GWEN_SyncIo_File_CreationMode_OpenExisting);
00998 GWEN_SyncIo_AddFlags(sio, GWEN_SYNCIO_FILE_FLAGS_READ);
00999 rv=GWEN_SyncIo_Connect(sio);
01000 if (rv<0) {
01001 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01002 GWEN_SyncIo_free(sio);
01003 return rv;
01004 }
01005
01006
01007 rv=GWEN_DB_ReadFromIo(n, sio, dbflags);
01008 if (rv<0) {
01009 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01010 GWEN_SyncIo_Disconnect(sio);
01011 GWEN_SyncIo_free(sio);
01012 return rv;
01013 }
01014
01015 GWEN_SyncIo_Disconnect(sio);
01016 GWEN_SyncIo_free(sio);
01017 return 0;
01018 }
01019
01020
01021
01022 int GWEN_DB_ReadFromString(GWEN_DB_NODE *n,
01023 const char *str,
01024 int len,
01025 uint32_t dbflags) {
01026 GWEN_SYNCIO *sio;
01027 int rv;
01028
01029 if (len==0)
01030 len=strlen(str);
01031
01032 sio=GWEN_SyncIo_Memory_fromBuffer((const uint8_t*) str, len);
01033 rv=GWEN_DB_ReadFromIo(n, sio, dbflags);
01034 if (rv<0) {
01035 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01036 GWEN_SyncIo_free(sio);
01037 return rv;
01038 }
01039
01040 GWEN_SyncIo_free(sio);
01041
01042 return 0;
01043 }
01044
01045
01046
01047 int GWEN_DB_WriteToBuffer(GWEN_DB_NODE *n,
01048 GWEN_BUFFER *buf,
01049 uint32_t dbflags) {
01050 GWEN_SYNCIO *sio;
01051 int rv;
01052
01053
01054 sio=GWEN_SyncIo_Memory_new(buf, 0);
01055 rv=GWEN_DB_WriteToIo(n, sio, dbflags);
01056 if (rv<0) {
01057 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01058 GWEN_SyncIo_free(sio);
01059 return rv;
01060 }
01061
01062 GWEN_SyncIo_free(sio);
01063 return 0;
01064 }
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076