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