gwenhywfar 4.0.3
|
00001 /*************************************************************************** 00002 begin : Tue Sep 09 2003 00003 copyright : (C) 2003-2010 by Martin Preuss 00004 email : martin@libchipcard.de 00005 00006 *************************************************************************** 00007 * * 00008 * This library is free software; you can redistribute it and/or * 00009 * modify it under the terms of the GNU Lesser General Public * 00010 * License as published by the Free Software Foundation; either * 00011 * version 2.1 of the License, or (at your option) any later version. * 00012 * * 00013 * This library is distributed in the hope that it will be useful, * 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00016 * Lesser General Public License for more details. * 00017 * * 00018 * You should have received a copy of the GNU Lesser General Public * 00019 * License along with this library; if not, write to the Free Software * 00020 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * 00021 * MA 02111-1307 USA * 00022 * * 00023 ***************************************************************************/ 00024 00025 00026 #ifdef HAVE_CONFIG_H 00027 # include <config.h> 00028 #endif 00029 00030 #define DISABLE_DEBUGLOG 00031 00032 #include "db_p.h" 00033 #include <gwenhywfar/misc.h> 00034 #include <gwenhywfar/debug.h> 00035 #include <gwenhywfar/path.h> 00036 #include <gwenhywfar/text.h> 00037 #include <gwenhywfar/dbio.h> 00038 #include <gwenhywfar/fslock.h> 00039 #include <gwenhywfar/fastbuffer.h> 00040 #include <gwenhywfar/syncio_file.h> 00041 #include <gwenhywfar/syncio_memory.h> 00042 00043 #include <stdlib.h> 00044 #include <assert.h> 00045 #include <string.h> 00046 #include <errno.h> 00047 #include <ctype.h> 00048 00049 #include <sys/types.h> 00050 #ifdef HAVE_SYS_STAT_H 00051 # include <sys/stat.h> 00052 #endif 00053 #ifdef HAVE_FCNTL_H 00054 # include <fcntl.h> 00055 #endif 00056 #ifdef HAVE_UNISTD_H 00057 # include <unistd.h> 00058 #endif 00059 00060 00061 #define GWEN_DB_NODE_FLAGS_MASK_INTERNAL 0xf0000000 00062 #define GWEN_DB_NODE_FLAGS_GROUP 0x80000000 00063 00064 00065 GWEN_LIST_FUNCTIONS(GWEN_DB_NODE, GWEN_DB_Node) 00066 00067 00068 00069 GWEN_DB_NODE *GWEN_DB_Node_new(GWEN_DB_NODE_TYPE t){ 00070 GWEN_DB_NODE *node; 00071 00072 GWEN_NEW_OBJECT(GWEN_DB_NODE, node); 00073 GWEN_LIST_INIT(GWEN_DB_NODE, node); 00074 node->typ=t; 00075 return (GWEN_DB_NODE*)node; 00076 } 00077 00078 00079 00080 00081 GWEN_DB_NODE *GWEN_DB_ValueBin_new(const void *data, 00082 unsigned int datasize){ 00083 GWEN_DB_NODE *n; 00084 00085 n=GWEN_DB_Node_new(GWEN_DB_NodeType_ValueBin); 00086 if (datasize) { 00087 assert(data); 00088 n->dataSize=datasize; 00089 n->data.dataBin=(char*)GWEN_Memory_malloc(datasize); 00090 assert(n->data.dataBin); 00091 memmove(n->data.dataBin, data, datasize); 00092 } 00093 return n; 00094 } 00095 00096 00097 00098 GWEN_DB_NODE *GWEN_DB_ValueInt_new(int data) { 00099 GWEN_DB_NODE *n; 00100 00101 n=GWEN_DB_Node_new(GWEN_DB_NodeType_ValueInt); 00102 n->data.dataInt=data; 00103 return n; 00104 } 00105 00106 00107 00108 GWEN_DB_NODE *GWEN_DB_ValueChar_new(const char *data) { 00109 GWEN_DB_NODE *n; 00110 00111 n=GWEN_DB_Node_new(GWEN_DB_NodeType_ValueChar); 00112 if (data) 00113 n->data.dataChar=GWEN_Memory_strdup(data); 00114 else 00115 n->data.dataChar=GWEN_Memory_strdup(""); 00116 return n; 00117 } 00118 00119 00120 00121 GWEN_DB_NODE *GWEN_DB_ValuePtr_new(void *data) { 00122 GWEN_DB_NODE *n; 00123 00124 n=GWEN_DB_Node_new(GWEN_DB_NodeType_ValuePtr); 00125 n->data.dataPtr=data; 00126 return n; 00127 } 00128 00129 00130 00131 GWEN_DB_NODE *GWEN_DB_Group_new(const char *name){ 00132 GWEN_DB_NODE *n; 00133 00134 assert(name); 00135 n=GWEN_DB_Node_new(GWEN_DB_NodeType_Group); 00136 if (name) 00137 n->data.dataName=GWEN_Memory_strdup(name); 00138 else 00139 n->data.dataName=GWEN_Memory_strdup(""); 00140 n->children=GWEN_DB_Node_List_new(); 00141 return n; 00142 } 00143 00144 00145 00146 GWEN_DB_NODE *GWEN_DB_Var_new(const char *name){ 00147 GWEN_DB_NODE *n; 00148 00149 assert(name); 00150 n=GWEN_DB_Node_new(GWEN_DB_NodeType_Var); 00151 if (name) 00152 n->data.dataName=GWEN_Memory_strdup(name); 00153 else 00154 n->data.dataName=GWEN_Memory_strdup(""); 00155 n->children=GWEN_DB_Node_List_new(); 00156 return n; 00157 } 00158 00159 00160 00161 void GWEN_DB_Node_Append_UnDirty(GWEN_DB_NODE *parent, 00162 GWEN_DB_NODE *n){ 00163 assert(parent); 00164 assert(n); 00165 assert(parent!=n); 00166 00167 assert(parent->children!=NULL); 00168 GWEN_DB_Node_List_Add(n, parent->children); 00169 00170 n->parent=parent; 00171 } 00172 00173 00174 00175 void GWEN_DB_Node_Append(GWEN_DB_NODE *parent, 00176 GWEN_DB_NODE *n){ 00177 GWEN_DB_Node_Append_UnDirty(parent, n); 00178 GWEN_DB_ModifyBranchFlagsUp(parent, 00179 GWEN_DB_NODE_FLAGS_DIRTY, 00180 GWEN_DB_NODE_FLAGS_DIRTY); 00181 } 00182 00183 00184 00185 void GWEN_DB_Node_InsertUnDirty(GWEN_DB_NODE *parent, 00186 GWEN_DB_NODE *n){ 00187 assert(parent); 00188 assert(n); 00189 assert(parent!=n); 00190 00191 assert(parent->children!=NULL); 00192 GWEN_DB_Node_List_Insert(n, parent->children); 00193 00194 n->parent=parent; 00195 } 00196 00197 00198 00199 void GWEN_DB_Node_Insert(GWEN_DB_NODE *parent, 00200 GWEN_DB_NODE *n){ 00201 GWEN_DB_Node_InsertUnDirty(parent, n); 00202 GWEN_DB_ModifyBranchFlagsUp(parent, 00203 GWEN_DB_NODE_FLAGS_DIRTY, 00204 GWEN_DB_NODE_FLAGS_DIRTY); 00205 } 00206 00207 00208 00209 void GWEN_DB_Node_Unlink_UnDirty(GWEN_DB_NODE *n) { 00210 GWEN_DB_NODE *parent; 00211 00212 assert(n); 00213 parent=n->parent; 00214 if (!parent) { 00215 DBG_WARN(GWEN_LOGDOMAIN, "Node is not linked, nothing to do"); 00216 return; 00217 } 00218 00219 GWEN_DB_Node_List_Del(n); 00220 n->parent=NULL; 00221 } 00222 00223 00224 00225 void GWEN_DB_Node_Unlink(GWEN_DB_NODE *n) { 00226 GWEN_DB_NODE *parent; 00227 00228 assert(n); 00229 parent=n->parent; 00230 assert(parent); 00231 00232 GWEN_DB_Node_Unlink_UnDirty(n); 00233 GWEN_DB_ModifyBranchFlagsUp(parent, 00234 GWEN_DB_NODE_FLAGS_DIRTY, 00235 GWEN_DB_NODE_FLAGS_DIRTY); 00236 } 00237 00238 00239 00240 void GWEN_DB_Node_free(GWEN_DB_NODE *n){ 00241 if (n) { 00242 GWEN_LIST_FINI(GWEN_DB_NODE, n); 00243 00244 /* free children */ 00245 if (n->children) 00246 GWEN_DB_Node_List_free(n->children); 00247 00248 /* free dynamic (allocated) data */ 00249 switch(n->typ) { 00250 case GWEN_DB_NodeType_Group: 00251 case GWEN_DB_NodeType_Var: 00252 GWEN_Memory_dealloc(n->data.dataName); 00253 break; 00254 00255 case GWEN_DB_NodeType_ValueChar: 00256 GWEN_Memory_dealloc(n->data.dataChar); 00257 break; 00258 case GWEN_DB_NodeType_ValueBin: 00259 GWEN_Memory_dealloc(n->data.dataBin); 00260 break; 00261 case GWEN_DB_NodeType_ValuePtr: 00262 case GWEN_DB_NodeType_ValueInt: 00263 break; 00264 default: 00265 DBG_WARN(GWEN_LOGDOMAIN, "Unknown node type (%d)", n->typ); 00266 } 00267 DBG_VERBOUS(GWEN_LOGDOMAIN, "Freeing node itself"); 00268 GWEN_FREE_OBJECT(n); 00269 } 00270 } 00271 00272 00273 00274 GWEN_DB_NODE *GWEN_DB_Node_dup(const GWEN_DB_NODE *n){ 00275 GWEN_DB_NODE *nn; 00276 00277 switch(n->typ) { 00278 case GWEN_DB_NodeType_Group: 00279 DBG_VERBOUS(GWEN_LOGDOMAIN, "Duplicating group \"%s\"", 00280 n->data.dataName); 00281 nn=GWEN_DB_Group_new(n->data.dataName); 00282 break; 00283 case GWEN_DB_NodeType_Var: 00284 DBG_VERBOUS(GWEN_LOGDOMAIN, "Duplicating variable \"%s\"", 00285 n->data.dataName); 00286 nn=GWEN_DB_Var_new(n->data.dataName); 00287 break; 00288 case GWEN_DB_NodeType_ValueChar: 00289 nn=GWEN_DB_ValueChar_new(n->data.dataChar); 00290 break; 00291 case GWEN_DB_NodeType_ValueBin: 00292 nn=GWEN_DB_ValueBin_new(n->data.dataBin, n->dataSize); 00293 break; 00294 case GWEN_DB_NodeType_ValuePtr: 00295 nn=GWEN_DB_ValuePtr_new(n->data.dataPtr); 00296 break; 00297 case GWEN_DB_NodeType_ValueInt: 00298 nn=GWEN_DB_ValueInt_new(n->data.dataInt); 00299 break; 00300 default: 00301 DBG_WARN(GWEN_LOGDOMAIN, "Unknown node type (%d)", n->typ); 00302 nn=0; 00303 } 00304 00305 /* duplicate all children and add them to the new node */ 00306 if (nn) { 00307 const GWEN_DB_NODE *cn; 00308 00309 cn=GWEN_DB_Node_List_First(n->children); 00310 while(cn) { 00311 GWEN_DB_NODE *ncn; 00312 00313 /* duplicate child and add it */ 00314 ncn=GWEN_DB_Node_dup(cn); 00315 if (!ncn) { 00316 GWEN_DB_Node_free(nn); 00317 return NULL; 00318 } 00319 GWEN_DB_Node_Append_UnDirty(nn, ncn); 00320 cn=GWEN_DB_Node_List_Next(cn); 00321 } /* while cn */ 00322 } 00323 00324 return nn; 00325 } 00326 00327 00328 00329 void GWEN_DB_Group_free(GWEN_DB_NODE *n){ 00330 GWEN_DB_Node_free(n); 00331 } 00332 00333 00334 00335 GWEN_DB_NODE *GWEN_DB_Group_dup(const GWEN_DB_NODE *n){ 00336 assert(n); 00337 if (n->typ!=GWEN_DB_NodeType_Group) { 00338 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group"); 00339 return NULL; 00340 } 00341 return GWEN_DB_Node_dup(n); 00342 } 00343 00344 00345 00346 GWEN_DB_NODE *GWEN_DB_GetFirstGroup(GWEN_DB_NODE *n){ 00347 GWEN_DB_NODE *nn; 00348 00349 assert(n); 00350 if (n->typ!=GWEN_DB_NodeType_Group) { 00351 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group"); 00352 return NULL; 00353 } 00354 assert(n->children); 00355 nn=GWEN_DB_Node_List_First(n->children); 00356 while(nn) { 00357 if (nn->typ==GWEN_DB_NodeType_Group) 00358 break; 00359 nn=GWEN_DB_Node_List_Next(nn); 00360 } /* while node */ 00361 return nn; 00362 } 00363 00364 00365 00366 GWEN_DB_NODE *GWEN_DB_GetNextGroup(GWEN_DB_NODE *n){ 00367 GWEN_DB_NODE *og; 00368 00369 og=n; 00370 assert(n); 00371 if (n->typ!=GWEN_DB_NodeType_Group) { 00372 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group"); 00373 return NULL; 00374 } 00375 n=GWEN_DB_Node_List_Next(n); 00376 while(n) { 00377 if (n->typ==GWEN_DB_NodeType_Group) 00378 break; 00379 n=GWEN_DB_Node_List_Next(n); 00380 } /* while node */ 00381 return n; 00382 } 00383 00384 00385 00386 GWEN_DB_NODE *GWEN_DB_GetFirstVar(GWEN_DB_NODE *n){ 00387 GWEN_DB_NODE *nn; 00388 00389 assert(n); 00390 if (n->typ!=GWEN_DB_NodeType_Group) { 00391 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group"); 00392 return NULL; 00393 } 00394 assert(n->children); 00395 nn=GWEN_DB_Node_List_First(n->children); 00396 while(nn) { 00397 if (nn->typ==GWEN_DB_NodeType_Var) 00398 break; 00399 nn=GWEN_DB_Node_List_Next(nn); 00400 } /* while node */ 00401 return nn; 00402 } 00403 00404 00405 00406 GWEN_DB_NODE *GWEN_DB_GetNextVar(GWEN_DB_NODE *n){ 00407 GWEN_DB_NODE *og; 00408 00409 og=n; 00410 assert(n); 00411 if (n->typ!=GWEN_DB_NodeType_Var) { 00412 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a variable"); 00413 return NULL; 00414 } 00415 n=GWEN_DB_Node_List_Next(n); 00416 while(n) { 00417 if (n->typ==GWEN_DB_NodeType_Var) 00418 break; 00419 n=GWEN_DB_Node_List_Next(n); 00420 } /* while node */ 00421 return n; 00422 } 00423 00424 00425 00426 GWEN_DB_NODE *GWEN_DB_GetFirstValue(GWEN_DB_NODE *n){ 00427 GWEN_DB_NODE *nn; 00428 00429 assert(n); 00430 if (n->typ!=GWEN_DB_NodeType_Var) { 00431 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a variable"); 00432 return NULL; 00433 } 00434 assert(n->children); 00435 nn=GWEN_DB_Node_List_First(n->children); 00436 while(nn) { 00437 if (nn->typ>=GWEN_DB_NodeType_ValueChar && 00438 nn->typ<GWEN_DB_NodeType_ValueLast) { 00439 break; 00440 } 00441 nn=GWEN_DB_Node_List_Next(nn); 00442 } /* while node */ 00443 return nn; 00444 } 00445 00446 00447 00448 GWEN_DB_NODE *GWEN_DB_GetNextValue(GWEN_DB_NODE *n){ 00449 assert(n); 00450 if (n->typ<GWEN_DB_NodeType_ValueChar || 00451 n->typ>=GWEN_DB_NodeType_ValueLast) { 00452 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a value"); 00453 return NULL; 00454 } 00455 00456 n=GWEN_DB_Node_List_Next(n); 00457 while(n) { 00458 if (n->typ>=GWEN_DB_NodeType_ValueChar && 00459 n->typ<GWEN_DB_NodeType_ValueLast) { 00460 break; 00461 } 00462 n=GWEN_DB_Node_List_Next(n); 00463 } /* while node */ 00464 return n; 00465 } 00466 00467 00468 00469 GWEN_DB_NODE_TYPE GWEN_DB_GetValueType(GWEN_DB_NODE *n){ 00470 assert(n); 00471 if (n->typ>=GWEN_DB_NodeType_ValueChar && 00472 n->typ<GWEN_DB_NodeType_ValueLast) { 00473 return n->typ; 00474 } 00475 else { 00476 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a value"); 00477 return GWEN_DB_NodeType_Unknown; 00478 } 00479 } 00480 00481 00482 00483 const char *GWEN_DB_GetCharValueFromNode(const GWEN_DB_NODE *n){ 00484 assert(n); 00485 if (n->typ!=GWEN_DB_NodeType_ValueChar) { 00486 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a char value"); 00487 return NULL; 00488 } 00489 return n->data.dataChar; 00490 } 00491 00492 00493 00494 int GWEN_DB_SetCharValueInNode(GWEN_DB_NODE *n, const char *s) { 00495 assert(n); 00496 assert(s); 00497 00498 if (n->typ!=GWEN_DB_NodeType_ValueChar) { 00499 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a char value"); 00500 return GWEN_ERROR_INVALID; 00501 } 00502 00503 GWEN_Memory_dealloc(n->data.dataChar); 00504 n->data.dataChar=GWEN_Memory_strdup(s); 00505 return 0; 00506 } 00507 00508 00509 00510 int GWEN_DB_GetIntValueFromNode(const GWEN_DB_NODE *n){ 00511 const char *p; 00512 int res; 00513 00514 assert(n); 00515 00516 switch(n->typ) { 00517 case GWEN_DB_NodeType_ValueInt: 00518 return n->data.dataInt; 00519 case GWEN_DB_NodeType_ValueChar: 00520 p=n->data.dataChar; 00521 assert(p); 00522 if (sscanf(p, "%d", &res)!=1) { 00523 DBG_ERROR(GWEN_LOGDOMAIN, "String in node is not an int value"); 00524 return 0; 00525 } 00526 return res; 00527 00528 default: 00529 DBG_ERROR(GWEN_LOGDOMAIN, "Node is neither char nor int value"); 00530 return 0; 00531 } 00532 } 00533 00534 00535 00536 const void *GWEN_DB_GetBinValueFromNode(const GWEN_DB_NODE *n, 00537 unsigned int *size){ 00538 assert(n); 00539 00540 if (n->typ!=GWEN_DB_NodeType_ValueBin) { 00541 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a binary value"); 00542 return NULL; 00543 } 00544 00545 *size=n->dataSize; 00546 return n->data.dataBin; 00547 } 00548 00549 00550 00551 GWEN_DB_NODE *GWEN_DB_FindGroup(GWEN_DB_NODE *n, 00552 const char *name, 00553 int idx) { 00554 GWEN_DB_NODE *nn; 00555 00556 assert(n); 00557 assert(name); 00558 00559 if (n->typ!=GWEN_DB_NodeType_Group) { 00560 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group"); 00561 return NULL; 00562 } 00563 00564 /* find existing node */ 00565 assert(n->children); 00566 nn=GWEN_DB_Node_List_First(n->children); 00567 while(nn) { 00568 if (nn->typ==GWEN_DB_NodeType_Group) { 00569 if (strcasecmp(nn->data.dataName, name)==0) { 00570 if (!idx) 00571 /* ok, group found, return it */ 00572 return nn; 00573 idx--; 00574 } /* if entry found */ 00575 } 00576 nn=GWEN_DB_Node_List_Next(nn); 00577 } /* while node */ 00578 00579 return NULL; 00580 } 00581 00582 00583 00584 GWEN_DB_NODE *GWEN_DB_FindVar(GWEN_DB_NODE *n, 00585 const char *name, 00586 int idx) { 00587 GWEN_DB_NODE *nn; 00588 00589 assert(n); 00590 assert(name); 00591 00592 if (n->typ!=GWEN_DB_NodeType_Group) { 00593 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group"); 00594 return NULL; 00595 } 00596 00597 /* find existing node */ 00598 assert(n->children); 00599 nn=GWEN_DB_Node_List_First(n->children); 00600 while(nn) { 00601 if (nn->typ==GWEN_DB_NodeType_Var) { 00602 if (strcasecmp(nn->data.dataName, name)==0) { 00603 if (!idx) 00604 /* ok, group found, return it */ 00605 return nn; 00606 idx--; 00607 } /* if entry found */ 00608 } 00609 nn=GWEN_DB_Node_List_Next(nn); 00610 } /* while node */ 00611 00612 return NULL; 00613 } 00614 00615 00616 00617 00618 00619 00620 00621 void* GWEN_DB_HandlePath(const char *entry, 00622 void *data, 00623 int idx, 00624 uint32_t flags) { 00625 GWEN_DB_NODE *n; 00626 GWEN_DB_NODE *nn; 00627 00628 n=(GWEN_DB_NODE*)data; 00629 00630 /* check whether we are allowed to simply create the node */ 00631 if ( 00632 ((flags & GWEN_PATH_FLAGS_LAST) && 00633 (((flags & GWEN_PATH_FLAGS_VARIABLE) && 00634 (flags & GWEN_PATH_FLAGS_CREATE_VAR)) || 00635 (!(flags & GWEN_PATH_FLAGS_VARIABLE) && 00636 (flags & GWEN_PATH_FLAGS_CREATE_GROUP))) 00637 ) || 00638 ( 00639 !(flags & GWEN_PATH_FLAGS_LAST) && 00640 (flags & GWEN_PATH_FLAGS_PATHCREATE)) 00641 ) { 00642 /* simply create the new variable/group */ 00643 if (idx!=0) { 00644 DBG_INFO(GWEN_LOGDOMAIN, "Index is not 0, not creating %s[%d]", 00645 entry, idx); 00646 return 0; 00647 } 00648 if (flags & GWEN_PATH_FLAGS_VARIABLE) { 00649 DBG_VERBOUS(GWEN_LOGDOMAIN, 00650 "Unconditionally creating variable \"%s\"", entry); 00651 nn=GWEN_DB_Var_new(entry); 00652 if (flags & GWEN_DB_FLAGS_INSERT) 00653 GWEN_DB_Node_Insert(n, nn); 00654 else 00655 GWEN_DB_Node_Append(n, nn); 00656 return nn; 00657 } 00658 else { 00659 DBG_VERBOUS(GWEN_LOGDOMAIN, 00660 "Unconditionally creating group \"%s\"", entry); 00661 nn=GWEN_DB_Group_new(entry); 00662 if (flags & GWEN_DB_FLAGS_INSERT) 00663 GWEN_DB_Node_Insert(n, nn); 00664 else 00665 GWEN_DB_Node_Append(n, nn); 00666 return nn; 00667 } 00668 } 00669 00670 /* find the node */ 00671 if (flags & GWEN_PATH_FLAGS_VARIABLE) { 00672 nn=GWEN_DB_FindVar(n, entry, idx); 00673 } 00674 else { 00675 nn=GWEN_DB_FindGroup(n, entry, idx); 00676 } 00677 00678 if (!nn) { 00679 /* node not found, check, if we are allowed to create it */ 00680 if ( 00681 (!(flags & GWEN_PATH_FLAGS_LAST) && 00682 (flags & GWEN_PATH_FLAGS_PATHMUSTEXIST)) || 00683 (flags & GWEN_PATH_FLAGS_NAMEMUSTEXIST) 00684 ) { 00685 if (flags & GWEN_PATH_FLAGS_VARIABLE) { 00686 DBG_VERBOUS(GWEN_LOGDOMAIN, 00687 "Variable \"%s\" does not exist", entry); 00688 } 00689 else { 00690 DBG_VERBOUS(GWEN_LOGDOMAIN, 00691 "Group \"%s\" does not exist", entry); 00692 } 00693 return 0; 00694 } 00695 /* create the new variable/group */ 00696 if (idx!=0) { 00697 DBG_INFO(GWEN_LOGDOMAIN, "Index is not 0, not creating %s[%d]", 00698 entry, idx); 00699 return 0; 00700 } 00701 if (flags & GWEN_PATH_FLAGS_VARIABLE) { 00702 DBG_VERBOUS(GWEN_LOGDOMAIN, 00703 "Variable \"%s\" not found, creating", entry); 00704 nn=GWEN_DB_Var_new(entry); 00705 if (flags & GWEN_DB_FLAGS_INSERT) 00706 GWEN_DB_Node_Insert(n, nn); 00707 else 00708 GWEN_DB_Node_Append(n, nn); 00709 } 00710 else { 00711 DBG_VERBOUS(GWEN_LOGDOMAIN, 00712 "Group \"%s\" not found, creating", entry); 00713 nn=GWEN_DB_Group_new(entry); 00714 if (flags & GWEN_DB_FLAGS_INSERT) 00715 GWEN_DB_Node_Insert(n, nn); 00716 else 00717 GWEN_DB_Node_Append(n, nn); 00718 } 00719 } /* if node not found */ 00720 else { 00721 /* node does exist, check whether this is ok */ 00722 if ( 00723 ((flags & GWEN_PATH_FLAGS_LAST) && 00724 (flags & GWEN_PATH_FLAGS_NAMEMUSTNOTEXIST)) || 00725 (!(flags & GWEN_PATH_FLAGS_LAST) && 00726 (flags & GWEN_PATH_FLAGS_PATHMUSTNOTEXIST)) 00727 ) { 00728 DBG_VERBOUS(GWEN_LOGDOMAIN, "Entry \"%s\" already exists", entry); 00729 return 0; 00730 } 00731 } 00732 00733 return nn; 00734 } 00735 00736 00737 00738 GWEN_DB_NODE *GWEN_DB_GetNode(GWEN_DB_NODE *n, 00739 const char *path, 00740 uint32_t flags){ 00741 return (GWEN_DB_NODE*)GWEN_Path_HandleWithIdx(path, 00742 n, 00743 flags, 00744 GWEN_DB_HandlePath); 00745 } 00746 00747 00748 00749 void GWEN_DB_ClearNode(GWEN_DB_NODE *n) { 00750 assert(n); 00751 if (n->children) 00752 GWEN_DB_Node_List_Clear(n->children); 00753 } 00754 00755 00756 00757 GWEN_DB_NODE *GWEN_DB_GetValue(GWEN_DB_NODE *n, 00758 const char *path, 00759 int idx) { 00760 GWEN_DB_NODE *nn; 00761 00762 /* find corresponding node */ 00763 nn=GWEN_DB_GetNode(n, 00764 path, 00765 GWEN_PATH_FLAGS_PATHMUSTEXIST | 00766 GWEN_PATH_FLAGS_NAMEMUSTEXIST | 00767 GWEN_PATH_FLAGS_VARIABLE); 00768 if (!nn) { 00769 DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not found", 00770 path); 00771 return 0; 00772 } 00773 00774 /* find value */ 00775 assert(nn->children); 00776 nn=GWEN_DB_Node_List_First(nn->children); 00777 while(nn) { 00778 if (nn->typ>=GWEN_DB_NodeType_ValueChar && 00779 nn->typ<GWEN_DB_NodeType_ValueLast) { 00780 if (!idx) 00781 return nn; 00782 idx--; 00783 } 00784 nn=GWEN_DB_Node_List_Next(nn); 00785 } 00786 00787 DBG_VERBOUS(GWEN_LOGDOMAIN, "No value[%d] for path \"%s\"", 00788 idx, path); 00789 return NULL; 00790 } 00791 00792 00793 00794 int GWEN_DB_DeleteVar(GWEN_DB_NODE *n, 00795 const char *path) { 00796 GWEN_DB_NODE *nn; 00797 00798 /* find corresponding node */ 00799 nn=GWEN_DB_GetNode(n, 00800 path, 00801 GWEN_PATH_FLAGS_PATHMUSTEXIST | 00802 GWEN_PATH_FLAGS_NAMEMUSTEXIST | 00803 GWEN_PATH_FLAGS_VARIABLE); 00804 if (!nn) { 00805 DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not found", 00806 path); 00807 return 1; 00808 } 00809 GWEN_DB_Node_Unlink(nn); 00810 GWEN_DB_Node_free(nn); 00811 return 0; 00812 } 00813 00814 00815 00816 int GWEN_DB_DeleteGroup(GWEN_DB_NODE *n, 00817 const char *path) { 00818 GWEN_DB_NODE *nn; 00819 00820 /* find corresponding node */ 00821 nn=GWEN_DB_GetNode(n, 00822 path, 00823 GWEN_PATH_FLAGS_PATHMUSTEXIST | 00824 GWEN_PATH_FLAGS_NAMEMUSTEXIST); 00825 if (!nn) { 00826 DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not found", 00827 path); 00828 return 1; 00829 } 00830 GWEN_DB_Node_Unlink(nn); 00831 GWEN_DB_Node_free(nn); 00832 return 0; 00833 } 00834 00835 00836 00837 int GWEN_DB_ClearGroup(GWEN_DB_NODE *n, 00838 const char *path){ 00839 assert(n); 00840 if (path) { 00841 GWEN_DB_NODE *nn; 00842 00843 /* find corresponding node */ 00844 nn=GWEN_DB_GetNode(n, 00845 path, 00846 GWEN_PATH_FLAGS_PATHMUSTEXIST | 00847 GWEN_PATH_FLAGS_NAMEMUSTEXIST); 00848 if (!nn) { 00849 DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not found", 00850 path); 00851 return 1; 00852 } 00853 GWEN_DB_ClearNode(nn); 00854 } 00855 else { 00856 GWEN_DB_ClearNode(n); 00857 } 00858 return 0; 00859 } 00860 00861 00862 00863 const char *GWEN_DB_GetCharValue(GWEN_DB_NODE *n, 00864 const char *path, 00865 int idx, 00866 const char *defVal){ 00867 GWEN_DB_NODE *nn; 00868 00869 nn=GWEN_DB_GetValue(n, path, idx); 00870 if (!nn){ 00871 DBG_VERBOUS(GWEN_LOGDOMAIN, 00872 "Value for \"%s\" not found, returning default value", 00873 path); 00874 return defVal; 00875 } 00876 if (nn->typ!=GWEN_DB_NodeType_ValueChar) { 00877 /* bad type */ 00878 DBG_VERBOUS(GWEN_LOGDOMAIN, 00879 "Bad type for path \"%s\", returning default value", 00880 path); 00881 return defVal; 00882 } 00883 return nn->data.dataChar; 00884 } 00885 00886 00887 00888 int GWEN_DB_SetCharValue(GWEN_DB_NODE *n, 00889 uint32_t flags, 00890 const char *path, 00891 const char *val){ 00892 GWEN_DB_NODE *nn; 00893 GWEN_DB_NODE *nv; 00894 00895 /* select/create node */ 00896 nn=GWEN_DB_GetNode(n, 00897 path, 00898 flags | GWEN_PATH_FLAGS_VARIABLE); 00899 if (!nn) { 00900 DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available", 00901 path); 00902 return 1; 00903 } 00904 00905 nv=GWEN_DB_ValueChar_new(val); 00906 00907 /* delete contents of this variable if wanted */ 00908 if (flags & GWEN_DB_FLAGS_OVERWRITE_VARS) { 00909 DBG_VERBOUS(GWEN_LOGDOMAIN, "Clearing variable \"%s\"", path); 00910 GWEN_DB_ClearNode(nn); 00911 } 00912 00913 /* add previously created value */ 00914 if (flags & GWEN_DB_FLAGS_INSERT) 00915 GWEN_DB_Node_Insert(nn, nv); 00916 else 00917 GWEN_DB_Node_Append(nn, nv); 00918 DBG_VERBOUS(GWEN_LOGDOMAIN, 00919 "Added char value \"%s\" to variable \"%s\"", val, path); 00920 00921 return 0; 00922 } 00923 00924 00925 00926 int GWEN_DB_AddCharValue(GWEN_DB_NODE *n, 00927 const char *path, 00928 const char *val, 00929 int senseCase, 00930 int check){ 00931 GWEN_DB_NODE *nn; 00932 GWEN_DB_NODE *nv; 00933 00934 /* select/create node */ 00935 nn=GWEN_DB_GetNode(n, 00936 path, 00937 GWEN_DB_FLAGS_DEFAULT | GWEN_PATH_FLAGS_VARIABLE); 00938 if (!nn) { 00939 DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available", 00940 path); 00941 return -1; 00942 } 00943 00944 if (check) { 00945 nv=GWEN_DB_GetFirstValue(n); 00946 if (nv && nv->typ==GWEN_DB_NodeType_ValueChar) { 00947 int res; 00948 00949 assert(nv->data.dataChar); 00950 if (senseCase) 00951 res=strcasecmp(nv->data.dataChar, val)==0; 00952 else 00953 res=strcmp(nv->data.dataChar, val)==0; 00954 if (res) { 00955 DBG_DEBUG(GWEN_LOGDOMAIN, 00956 "Value \"%s\" of var \"%s\" already exists", 00957 val, path); 00958 return 1; 00959 } 00960 } 00961 } /* if check */ 00962 00963 nv=GWEN_DB_ValueChar_new(val); 00964 GWEN_DB_Node_Append(nn, nv); 00965 DBG_VERBOUS(GWEN_LOGDOMAIN, 00966 "Added char value \"%s\" to variable \"%s\"", val, path); 00967 00968 return 0; 00969 } 00970 00971 00972 00973 int GWEN_DB_RemoveCharValue(GWEN_DB_NODE *n, 00974 const char *path, 00975 const char *val, 00976 int senseCase){ 00977 GWEN_DB_NODE *nn; 00978 GWEN_DB_NODE *nv; 00979 00980 /* select/create node */ 00981 nn=GWEN_DB_GetNode(n, 00982 path, 00983 GWEN_DB_FLAGS_DEFAULT | GWEN_PATH_FLAGS_VARIABLE); 00984 if (!nn) { 00985 DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available", 00986 path); 00987 return -1; 00988 } 00989 00990 nv=GWEN_DB_GetFirstValue(n); 00991 if (nv && nv->typ==GWEN_DB_NodeType_ValueChar) { 00992 int res; 00993 00994 assert(nv->data.dataChar); 00995 if (senseCase) 00996 res=strcasecmp(nv->data.dataChar, val)==0; 00997 else 00998 res=strcmp(nv->data.dataChar, val)==0; 00999 if (res) { 01000 DBG_DEBUG(GWEN_LOGDOMAIN, 01001 "Value \"%s\" of var \"%s\" already exists", 01002 val, path); 01003 GWEN_DB_Node_Unlink(nv); 01004 GWEN_DB_Node_free(nv); 01005 return 0; 01006 } 01007 } 01008 01009 return 1; 01010 } 01011 01012 01013 01014 int GWEN_DB_GetIntValue(GWEN_DB_NODE *n, 01015 const char *path, 01016 int idx, 01017 int defVal){ 01018 GWEN_DB_NODE *nn; 01019 const char *p; 01020 int res; 01021 01022 assert(n); 01023 nn=GWEN_DB_GetValue(n, path, idx); 01024 if (!nn){ 01025 DBG_VERBOUS(GWEN_LOGDOMAIN, 01026 "Value[%d] for \"%s\" not found, returning default value", 01027 idx, path); 01028 return defVal; 01029 } 01030 01031 switch(nn->typ) { 01032 case GWEN_DB_NodeType_ValueInt: 01033 return nn->data.dataInt; 01034 case GWEN_DB_NodeType_ValueChar: 01035 p=nn->data.dataChar; 01036 assert(p); 01037 if (sscanf(p, "%d", &res)!=1) { 01038 DBG_INFO(GWEN_LOGDOMAIN, 01039 "String [%s] in node is not an int value", p); 01040 return defVal; 01041 } 01042 return res; 01043 01044 default: 01045 DBG_ERROR(GWEN_LOGDOMAIN, "Node is neither char nor int value"); 01046 return defVal; 01047 } 01048 } 01049 01050 01051 01052 int GWEN_DB_SetIntValue(GWEN_DB_NODE *n, 01053 uint32_t flags, 01054 const char *path, 01055 int val){ 01056 GWEN_DB_NODE *nn; 01057 GWEN_DB_NODE *nv; 01058 01059 /* select/create node */ 01060 nn=GWEN_DB_GetNode(n, 01061 path, 01062 flags | GWEN_PATH_FLAGS_VARIABLE); 01063 if (!nn) { 01064 DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available", 01065 path); 01066 return 1; 01067 } 01068 01069 /* delete contents of this variable if wanted */ 01070 if (flags & GWEN_DB_FLAGS_OVERWRITE_VARS) { 01071 DBG_VERBOUS(GWEN_LOGDOMAIN, "Clearing variable \"%s\"", path); 01072 GWEN_DB_ClearNode(nn); 01073 } 01074 01075 nv=GWEN_DB_ValueInt_new(val); 01076 if (flags & GWEN_DB_FLAGS_INSERT) 01077 GWEN_DB_Node_Insert(nn, nv); 01078 else 01079 GWEN_DB_Node_Append(nn, nv); 01080 DBG_VERBOUS(GWEN_LOGDOMAIN, "Added int value \"%d\" to variable \"%s\"", val, path); 01081 return 0; 01082 } 01083 01084 01085 01086 const void *GWEN_DB_GetBinValue(GWEN_DB_NODE *n, 01087 const char *path, 01088 int idx, 01089 const void *defVal, 01090 unsigned int defValSize, 01091 unsigned int *returnValueSize){ 01092 GWEN_DB_NODE *nn; 01093 01094 assert(returnValueSize); 01095 nn=GWEN_DB_GetValue(n, path, idx); 01096 if (!nn){ 01097 DBG_VERBOUS(GWEN_LOGDOMAIN, 01098 "Value for \"%s\" not found, returning default value", 01099 path); 01100 *returnValueSize=defValSize; 01101 return defVal; 01102 } 01103 if (nn->typ!=GWEN_DB_NodeType_ValueBin) { 01104 /* bad type */ 01105 DBG_VERBOUS(GWEN_LOGDOMAIN, 01106 "Bad type for path \"%s\", returning default value", 01107 path); 01108 *returnValueSize=defValSize; 01109 return defVal; 01110 } 01111 *returnValueSize=nn->dataSize; 01112 return nn->data.dataBin; 01113 } 01114 01115 01116 01117 int GWEN_DB_SetBinValue(GWEN_DB_NODE *n, 01118 uint32_t flags, 01119 const char *path, 01120 const void *val, 01121 unsigned int valSize){ 01122 GWEN_DB_NODE *nn; 01123 GWEN_DB_NODE *nv; 01124 01125 assert(val); 01126 /* select/create node */ 01127 nn=GWEN_DB_GetNode(n, 01128 path, 01129 flags | GWEN_PATH_FLAGS_VARIABLE); 01130 if (!nn) { 01131 DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available", 01132 path); 01133 return 1; 01134 } 01135 01136 /* delete contents of this variable if wanted */ 01137 if (flags & GWEN_DB_FLAGS_OVERWRITE_VARS) { 01138 DBG_VERBOUS(GWEN_LOGDOMAIN, "Clearing variable \"%s\"", path); 01139 GWEN_DB_ClearNode(nn); 01140 } 01141 01142 nv=GWEN_DB_ValueBin_new(val, valSize); 01143 if (flags & GWEN_DB_FLAGS_INSERT) 01144 GWEN_DB_Node_Insert(nn, nv); 01145 else 01146 GWEN_DB_Node_Append(nn, nv); 01147 DBG_VERBOUS(GWEN_LOGDOMAIN, "Added bin value to variable \"%s\"", path); 01148 return 0; 01149 } 01150 01151 01152 01153 void *GWEN_DB_GetPtrValue(GWEN_DB_NODE *n, 01154 const char *path, 01155 int idx, 01156 void *defVal){ 01157 GWEN_DB_NODE *nn; 01158 01159 nn=GWEN_DB_GetValue(n, path, idx); 01160 if (!nn){ 01161 DBG_VERBOUS(GWEN_LOGDOMAIN, 01162 "Value for \"%s\" not found, returning default value", 01163 path); 01164 return defVal; 01165 } 01166 if (nn->typ!=GWEN_DB_NodeType_ValuePtr) { 01167 /* bad type */ 01168 DBG_VERBOUS(GWEN_LOGDOMAIN, 01169 "Bad type for path \"%s\", returning default value", 01170 path); 01171 return defVal; 01172 } 01173 return nn->data.dataPtr; 01174 } 01175 01176 01177 01178 int GWEN_DB_SetPtrValue(GWEN_DB_NODE *n, 01179 uint32_t flags, 01180 const char *path, 01181 void *val){ 01182 GWEN_DB_NODE *nn; 01183 GWEN_DB_NODE *nv; 01184 01185 /* select/create node */ 01186 nn=GWEN_DB_GetNode(n, 01187 path, 01188 flags | GWEN_PATH_FLAGS_VARIABLE); 01189 if (!nn) { 01190 DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available", 01191 path); 01192 return 1; 01193 } 01194 01195 /* delete contents of this variable if wanted */ 01196 if (flags & GWEN_DB_FLAGS_OVERWRITE_VARS) { 01197 DBG_VERBOUS(GWEN_LOGDOMAIN, "Clearing variable \"%s\"", path); 01198 GWEN_DB_ClearNode(nn); 01199 } 01200 01201 nv=GWEN_DB_ValuePtr_new(val); 01202 if (flags & GWEN_DB_FLAGS_INSERT) 01203 GWEN_DB_Node_Insert(nn, nv); 01204 else 01205 GWEN_DB_Node_Append(nn, nv); 01206 DBG_VERBOUS(GWEN_LOGDOMAIN, "Added ptr value to variable \"%s\"", path); 01207 01208 return 0; 01209 } 01210 01211 01212 01213 01214 01215 01216 01217 01218 01219 01220 01221 01222 01223 01224 01225 01226 GWEN_DB_NODE *GWEN_DB_GetGroup(GWEN_DB_NODE *n, 01227 uint32_t flags, 01228 const char *path) { 01229 GWEN_DB_NODE *nn; 01230 01231 /* select/create node */ 01232 nn=GWEN_DB_GetNode(n, 01233 path, 01234 flags & ~GWEN_PATH_FLAGS_VARIABLE); 01235 if (!nn) { 01236 DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available", 01237 path); 01238 return NULL; 01239 } 01240 01241 /* delete contents of this variable if wanted */ 01242 if (flags & GWEN_DB_FLAGS_OVERWRITE_GROUPS) { 01243 DBG_VERBOUS(GWEN_LOGDOMAIN, "Clearing group \"%s\"", path); 01244 GWEN_DB_ClearNode(nn); 01245 } 01246 01247 return nn; 01248 } 01249 01250 01251 01252 const char *GWEN_DB_GroupName(GWEN_DB_NODE *n){ 01253 assert(n); 01254 if (n->typ!=GWEN_DB_NodeType_Group) { 01255 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group"); 01256 return NULL; 01257 } 01258 return n->data.dataName; 01259 } 01260 01261 01262 01263 void GWEN_DB_Dump(GWEN_DB_NODE *n, int insert){ 01264 if (n) { 01265 int i; 01266 01267 for (i=0; i<insert; i++) 01268 fprintf(stderr, " "); 01269 01270 /* dump dynamic (allocated) data */ 01271 switch(n->typ) { 01272 case GWEN_DB_NodeType_Group: 01273 fprintf(stderr, "Group : \"%s\"\n", n->data.dataName); 01274 break; 01275 case GWEN_DB_NodeType_Var: 01276 fprintf(stderr, "Var : \"%s\"\n", n->data.dataName); 01277 break; 01278 case GWEN_DB_NodeType_ValueChar: 01279 fprintf(stderr, "Value : \"%s\" (char)\n", n->data.dataChar); 01280 break; 01281 case GWEN_DB_NodeType_ValueInt: 01282 fprintf(stderr, "Value : %d (int)\n", n->data.dataInt); 01283 break; 01284 case GWEN_DB_NodeType_ValueBin: { 01285 char *buffer; 01286 01287 buffer=(char*)GWEN_Memory_malloc((n->dataSize*2)+1); 01288 assert(buffer); 01289 if (GWEN_Text_ToHex(n->data.dataBin, n->dataSize, 01290 buffer, (n->dataSize*2)+1)==0) { 01291 fprintf(stderr, "Value : %d bytes (bin)\n", n->dataSize); 01292 } 01293 else { 01294 fprintf(stderr, "Value : %s (bin)\n", buffer); 01295 } 01296 GWEN_Memory_dealloc(buffer); 01297 break; 01298 } 01299 case GWEN_DB_NodeType_ValuePtr: 01300 fprintf(stderr, "Value : %p (ptr)\n", n->data.dataPtr); 01301 break; 01302 default: 01303 fprintf(stderr, "[unknown node type %d]\n", n->typ); 01304 } 01305 01306 /* dump children */ 01307 if (n->children) { 01308 GWEN_DB_NODE *cn; 01309 01310 cn=GWEN_DB_Node_List_First(n->children); 01311 while(cn) { 01312 GWEN_DB_Dump(cn, insert+4); 01313 cn=GWEN_DB_Node_List_Next(cn); 01314 } 01315 } 01316 } 01317 else { 01318 fprintf(stderr, "[no node]\n"); 01319 } 01320 } 01321 01322 01323 01324 int GWEN_DB_AddGroup(GWEN_DB_NODE *n, GWEN_DB_NODE *nn){ 01325 assert(n); 01326 assert(nn); 01327 01328 if (n->typ!=GWEN_DB_NodeType_Group) { 01329 DBG_ERROR(GWEN_LOGDOMAIN, "Target node is not a group"); 01330 return 0; 01331 } 01332 01333 if (nn->typ!=GWEN_DB_NodeType_Group) { 01334 DBG_ERROR(GWEN_LOGDOMAIN, "Source node is not a group"); 01335 return 0; 01336 } 01337 01338 GWEN_DB_Node_Append(n, nn); 01339 return 0; 01340 } 01341 01342 01343 01344 int GWEN_DB_InsertGroup(GWEN_DB_NODE *n, GWEN_DB_NODE *nn){ 01345 assert(n); 01346 assert(nn); 01347 01348 if (n->typ!=GWEN_DB_NodeType_Group) { 01349 DBG_ERROR(GWEN_LOGDOMAIN, "Target node is not a group"); 01350 return 0; 01351 } 01352 01353 if (nn->typ!=GWEN_DB_NodeType_Group) { 01354 DBG_ERROR(GWEN_LOGDOMAIN, "Source node is not a group"); 01355 return 0; 01356 } 01357 01358 GWEN_DB_Node_Insert(n, nn); 01359 return 0; 01360 } 01361 01362 01363 01364 int GWEN_DB_AddGroupChildren(GWEN_DB_NODE *n, GWEN_DB_NODE *nn){ 01365 GWEN_DB_NODE *cpn; 01366 01367 assert(n); 01368 assert(nn); 01369 01370 if (n->typ!=GWEN_DB_NodeType_Group) { 01371 DBG_ERROR(GWEN_LOGDOMAIN, "Target node is not a group"); 01372 return -1; 01373 } 01374 01375 if (nn->typ!=GWEN_DB_NodeType_Group) { 01376 DBG_ERROR(GWEN_LOGDOMAIN, "Source node is not a group"); 01377 GWEN_DB_Dump(nn, 1); 01378 return -1; 01379 } 01380 01381 nn=GWEN_DB_Node_List_First(nn->children); 01382 while (nn) { 01383 DBG_VERBOUS(GWEN_LOGDOMAIN, "Duplicating node"); 01384 cpn=GWEN_DB_Node_dup(nn); 01385 GWEN_DB_Node_Append(n, cpn); 01386 nn=GWEN_DB_Node_List_Next(nn); 01387 } /* while */ 01388 return 0; 01389 } 01390 01391 01392 01393 void GWEN_DB_UnlinkGroup(GWEN_DB_NODE *n){ 01394 assert(n); 01395 if (n->typ!=GWEN_DB_NodeType_Group) { 01396 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group"); 01397 return; 01398 } 01399 GWEN_DB_Node_Unlink(n); 01400 } 01401 01402 01403 int GWEN_DB_VariableExists(GWEN_DB_NODE *n, const char *path){ 01404 GWEN_DB_NODE *nn; 01405 01406 /* find corresponding node */ 01407 assert(n); 01408 nn=GWEN_DB_GetNode(n, 01409 path, 01410 GWEN_PATH_FLAGS_PATHMUSTEXIST | 01411 GWEN_PATH_FLAGS_NAMEMUSTEXIST | 01412 GWEN_PATH_FLAGS_VARIABLE); 01413 if (!nn) { 01414 DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not found", path); 01415 return 0; 01416 } 01417 01418 return 1; 01419 } 01420 01421 01422 01423 int GWEN_DB_ValueExists(GWEN_DB_NODE *n, 01424 const char *path, 01425 unsigned int i){ 01426 return (GWEN_DB_GetValue(n, path, i)!=0); 01427 } 01428 01429 01430 01431 GWEN_DB_NODE_TYPE GWEN_DB_GetVariableType(GWEN_DB_NODE *n, 01432 const char *p){ 01433 GWEN_DB_NODE *nn; 01434 01435 nn=GWEN_DB_FindVar(n, p, 0); 01436 if (!nn) 01437 return GWEN_DB_NodeType_Unknown; 01438 01439 nn=GWEN_DB_GetFirstValue(nn); 01440 if (!nn) 01441 return GWEN_DB_NodeType_Unknown; 01442 return GWEN_DB_GetValueType(nn); 01443 } 01444 01445 01446 01447 GWEN_DB_NODE_TYPE GWEN_DB_GetValueTypeByPath(GWEN_DB_NODE *n, 01448 const char *path, 01449 unsigned int i){ 01450 GWEN_DB_NODE *nn; 01451 01452 nn=GWEN_DB_GetValue(n, path, i); 01453 if (!nn) 01454 return GWEN_DB_NodeType_Unknown; 01455 return GWEN_DB_GetValueType(nn); 01456 } 01457 01458 01459 void GWEN_DB_GroupRename(GWEN_DB_NODE *n, const char *newname){ 01460 assert(n); 01461 assert(newname); 01462 assert(n->typ==GWEN_DB_NodeType_Group); 01463 GWEN_Memory_dealloc(n->data.dataName); 01464 n->data.dataName=GWEN_Memory_strdup(newname); 01465 } 01466 01467 01468 01469 01470 01471 01472 01473 int GWEN_DB_IsGroup(const GWEN_DB_NODE *n){ 01474 assert(n); 01475 return n->typ==GWEN_DB_NodeType_Group; 01476 } 01477 01478 01479 01480 int GWEN_DB_IsVariable(const GWEN_DB_NODE *n){ 01481 assert(n); 01482 return n->typ==GWEN_DB_NodeType_Var; 01483 } 01484 01485 01486 01487 int GWEN_DB_IsValue(const GWEN_DB_NODE *n){ 01488 assert(n); 01489 return (n->typ>=GWEN_DB_NodeType_ValueChar && 01490 n->typ>=GWEN_DB_NodeType_ValueLast); 01491 } 01492 01493 01494 01495 void *GWEN_DB_Groups_Foreach(GWEN_DB_NODE *node, GWEN_DB_NODES_CB func, 01496 void *user_data){ 01497 GWEN_DB_NODE *iter; 01498 void *res; 01499 01500 assert(node); 01501 assert(func); 01502 01503 iter=GWEN_DB_GetFirstGroup(node); 01504 res=NULL; 01505 while(iter){ 01506 res=(*func)(iter, user_data); 01507 if (res) { 01508 break; 01509 } 01510 iter=GWEN_DB_GetNextGroup(iter); 01511 } 01512 return res; 01513 } 01514 01515 01516 01517 void *GWEN_DB_count_cb(GWEN_UNUSED GWEN_DB_NODE *node, void *user_data){ 01518 unsigned int *a = user_data; 01519 ++(*a); 01520 return NULL; 01521 } 01522 01523 01524 01525 unsigned int GWEN_DB_Groups_Count(const GWEN_DB_NODE *node){ 01526 unsigned int res = 0; 01527 GWEN_DB_Groups_Foreach((GWEN_DB_NODE *)node, GWEN_DB_count_cb, &res); 01528 return res; 01529 } 01530 01531 01532 01533 void *GWEN_DB_Variables_Foreach(GWEN_DB_NODE *node, GWEN_DB_NODES_CB func, 01534 void *user_data){ 01535 GWEN_DB_NODE *iter; 01536 void *res; 01537 01538 assert(node); 01539 assert(func); 01540 01541 iter=GWEN_DB_GetFirstVar(node); 01542 res=NULL; 01543 while(iter){ 01544 res=(*func)(iter, user_data); 01545 if (res) { 01546 break; 01547 } 01548 iter=GWEN_DB_GetNextVar(iter); 01549 } 01550 return res; 01551 } 01552 01553 01554 01555 unsigned int GWEN_DB_Variables_Count(const GWEN_DB_NODE *node){ 01556 unsigned int res = 0; 01557 GWEN_DB_Variables_Foreach((GWEN_DB_NODE *)node, GWEN_DB_count_cb, &res); 01558 return res; 01559 } 01560 01561 01562 01563 void *GWEN_DB_Values_Foreach(GWEN_DB_NODE *node, GWEN_DB_NODES_CB func, 01564 void *user_data){ 01565 GWEN_DB_NODE *iter; 01566 void *res; 01567 01568 assert(node); 01569 assert(func); 01570 01571 iter=GWEN_DB_GetFirstValue(node); 01572 res=NULL; 01573 while(iter){ 01574 res=(*func)(iter, user_data); 01575 if (res) { 01576 break; 01577 } 01578 iter=GWEN_DB_GetNextValue(iter); 01579 } 01580 return res; 01581 } 01582 01583 01584 01585 unsigned int GWEN_DB_Values_Count(const GWEN_DB_NODE *node){ 01586 unsigned int res = 0; 01587 GWEN_DB_Values_Foreach((GWEN_DB_NODE *)node, GWEN_DB_count_cb, &res); 01588 return res; 01589 } 01590 01591 01592 01593 uint32_t GWEN_DB_GetNodeFlags(const GWEN_DB_NODE *n){ 01594 assert(n); 01595 return n->nodeFlags; 01596 } 01597 01598 01599 01600 void GWEN_DB_SetNodeFlags(GWEN_DB_NODE *n, 01601 uint32_t flags){ 01602 assert(n); 01603 n->nodeFlags=flags; 01604 } 01605 01606 01607 01608 void GWEN_DB_ModifyBranchFlagsUp(GWEN_DB_NODE *n, 01609 uint32_t newflags, 01610 uint32_t mask){ 01611 uint32_t flags; 01612 01613 assert(n); 01614 01615 while(n) { 01616 flags=n->nodeFlags; 01617 flags=((flags^newflags)&(mask))^flags; 01618 n->nodeFlags=flags; 01619 n=n->parent; 01620 } /* while */ 01621 } 01622 01623 01624 01625 void GWEN_DB_ModifyBranchFlagsDown(GWEN_DB_NODE *n, 01626 uint32_t newflags, 01627 uint32_t mask){ 01628 uint32_t flags; 01629 GWEN_DB_NODE *cn; 01630 01631 assert(n); 01632 01633 flags=n->nodeFlags; 01634 flags=((flags^newflags)&(mask))^flags; 01635 n->nodeFlags=flags; 01636 01637 cn=GWEN_DB_Node_List_First(n->children); 01638 while(cn) { 01639 GWEN_DB_ModifyBranchFlagsDown(cn, newflags, mask); 01640 cn=GWEN_DB_Node_List_Next(cn); 01641 } /* while cn */ 01642 } 01643 01644 01645 01646 GWEN_DB_NODE *GWEN_DB_FindFirstGroup(GWEN_DB_NODE *n, const char *name){ 01647 GWEN_DB_NODE *nn; 01648 01649 assert(n); 01650 if (n->typ!=GWEN_DB_NodeType_Group) { 01651 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group"); 01652 return NULL; 01653 } 01654 nn=GWEN_DB_Node_List_First(n->children); 01655 while(nn) { 01656 if ((nn->typ==GWEN_DB_NodeType_Group) && 01657 (-1!=GWEN_Text_ComparePattern(nn->data.dataName, name, 0))) 01658 break; 01659 nn=GWEN_DB_Node_List_Next(nn); 01660 } /* while node */ 01661 return nn; 01662 } 01663 01664 01665 01666 GWEN_DB_NODE *GWEN_DB_FindNextGroup(GWEN_DB_NODE *n, const char *name){ 01667 GWEN_DB_NODE *og; 01668 01669 og=n; 01670 assert(n); 01671 if (n->typ!=GWEN_DB_NodeType_Group) { 01672 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group"); 01673 return NULL; 01674 } 01675 n=GWEN_DB_GetNextGroup(n); 01676 while(n) { 01677 if (-1!=GWEN_Text_ComparePattern(n->data.dataName, name, 0)) 01678 break; 01679 n=GWEN_DB_GetNextGroup(n); 01680 } /* while node */ 01681 assert(n!=og); 01682 return n; 01683 } 01684 01685 01686 01687 GWEN_DB_NODE *GWEN_DB_FindFirstVar(GWEN_DB_NODE *n, const char *name) { 01688 GWEN_DB_NODE *nn; 01689 01690 assert(n); 01691 if (n->typ!=GWEN_DB_NodeType_Group) { 01692 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group"); 01693 return NULL; 01694 } 01695 01696 nn=GWEN_DB_Node_List_First(n->children); 01697 while(nn) { 01698 if ((nn->typ==GWEN_DB_NodeType_Var) && 01699 (-1!=GWEN_Text_ComparePattern(nn->data.dataName, name, 0))) 01700 break; 01701 nn=GWEN_DB_Node_List_Next(nn); 01702 } /* while node */ 01703 01704 return nn; 01705 } 01706 01707 01708 01709 GWEN_DB_NODE *GWEN_DB_FindNextVar(GWEN_DB_NODE *n, const char *name) { 01710 GWEN_DB_NODE *og; 01711 01712 og=n; 01713 assert(n); 01714 if (n->typ!=GWEN_DB_NodeType_Var) { 01715 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a variable"); 01716 return NULL; 01717 } 01718 n=GWEN_DB_GetNextVar(n); 01719 while(n) { 01720 if (-1!=GWEN_Text_ComparePattern(n->data.dataName, name, 0)) 01721 break; 01722 n=GWEN_DB_GetNextVar(n); 01723 } /* while node */ 01724 assert(n!=og); 01725 return n; 01726 } 01727 01728 01729 01730 const char *GWEN_DB_VariableName(GWEN_DB_NODE *n){ 01731 assert(n); 01732 if (n->typ!=GWEN_DB_NodeType_Var) { 01733 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a variable"); 01734 return NULL; 01735 } 01736 return n->data.dataName; 01737 } 01738 01739 01740 01741 void GWEN_DB_VariableRename(GWEN_DB_NODE *n, const char *newname){ 01742 assert(n); 01743 assert(newname); 01744 assert(n->typ==GWEN_DB_NodeType_Var); 01745 GWEN_Memory_dealloc(n->data.dataName); 01746 n->data.dataName=GWEN_Memory_strdup(newname); 01747 } 01748 01749 01750 01751 01752 01753 01754 #include "dbrw.c" 01755 01756 01757 01758 01759 01760 01761 01762 01763