gwenhywfar
4.3.1
|
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 assert(n); 00368 if (n->typ!=GWEN_DB_NodeType_Group) { 00369 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group"); 00370 return NULL; 00371 } 00372 n=GWEN_DB_Node_List_Next(n); 00373 while(n) { 00374 if (n->typ==GWEN_DB_NodeType_Group) 00375 break; 00376 n=GWEN_DB_Node_List_Next(n); 00377 } /* while node */ 00378 return n; 00379 } 00380 00381 00382 00383 GWEN_DB_NODE *GWEN_DB_GetFirstVar(GWEN_DB_NODE *n){ 00384 GWEN_DB_NODE *nn; 00385 00386 assert(n); 00387 if (n->typ!=GWEN_DB_NodeType_Group) { 00388 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group"); 00389 return NULL; 00390 } 00391 assert(n->children); 00392 nn=GWEN_DB_Node_List_First(n->children); 00393 while(nn) { 00394 if (nn->typ==GWEN_DB_NodeType_Var) 00395 break; 00396 nn=GWEN_DB_Node_List_Next(nn); 00397 } /* while node */ 00398 return nn; 00399 } 00400 00401 00402 00403 GWEN_DB_NODE *GWEN_DB_GetNextVar(GWEN_DB_NODE *n){ 00404 assert(n); 00405 if (n->typ!=GWEN_DB_NodeType_Var) { 00406 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a variable"); 00407 return NULL; 00408 } 00409 n=GWEN_DB_Node_List_Next(n); 00410 while(n) { 00411 if (n->typ==GWEN_DB_NodeType_Var) 00412 break; 00413 n=GWEN_DB_Node_List_Next(n); 00414 } /* while node */ 00415 return n; 00416 } 00417 00418 00419 00420 GWEN_DB_NODE *GWEN_DB_GetFirstValue(GWEN_DB_NODE *n){ 00421 GWEN_DB_NODE *nn; 00422 00423 assert(n); 00424 if (n->typ!=GWEN_DB_NodeType_Var) { 00425 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a variable"); 00426 return NULL; 00427 } 00428 assert(n->children); 00429 nn=GWEN_DB_Node_List_First(n->children); 00430 while(nn) { 00431 if (nn->typ>=GWEN_DB_NodeType_ValueChar && 00432 nn->typ<GWEN_DB_NodeType_ValueLast) { 00433 break; 00434 } 00435 nn=GWEN_DB_Node_List_Next(nn); 00436 } /* while node */ 00437 return nn; 00438 } 00439 00440 00441 00442 GWEN_DB_NODE *GWEN_DB_GetNextValue(GWEN_DB_NODE *n){ 00443 assert(n); 00444 if (n->typ<GWEN_DB_NodeType_ValueChar || 00445 n->typ>=GWEN_DB_NodeType_ValueLast) { 00446 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a value"); 00447 return NULL; 00448 } 00449 00450 n=GWEN_DB_Node_List_Next(n); 00451 while(n) { 00452 if (n->typ>=GWEN_DB_NodeType_ValueChar && 00453 n->typ<GWEN_DB_NodeType_ValueLast) { 00454 break; 00455 } 00456 n=GWEN_DB_Node_List_Next(n); 00457 } /* while node */ 00458 return n; 00459 } 00460 00461 00462 00463 GWEN_DB_NODE_TYPE GWEN_DB_GetValueType(GWEN_DB_NODE *n){ 00464 assert(n); 00465 if (n->typ>=GWEN_DB_NodeType_ValueChar && 00466 n->typ<GWEN_DB_NodeType_ValueLast) { 00467 return n->typ; 00468 } 00469 else { 00470 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a value"); 00471 return GWEN_DB_NodeType_Unknown; 00472 } 00473 } 00474 00475 00476 00477 const char *GWEN_DB_GetCharValueFromNode(const GWEN_DB_NODE *n){ 00478 assert(n); 00479 if (n->typ!=GWEN_DB_NodeType_ValueChar) { 00480 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a char value"); 00481 return NULL; 00482 } 00483 return n->data.dataChar; 00484 } 00485 00486 00487 00488 int GWEN_DB_SetCharValueInNode(GWEN_DB_NODE *n, const char *s) { 00489 assert(n); 00490 assert(s); 00491 00492 if (n->typ!=GWEN_DB_NodeType_ValueChar) { 00493 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a char value"); 00494 return GWEN_ERROR_INVALID; 00495 } 00496 00497 GWEN_Memory_dealloc(n->data.dataChar); 00498 n->data.dataChar=GWEN_Memory_strdup(s); 00499 return 0; 00500 } 00501 00502 00503 00504 int GWEN_DB_GetIntValueFromNode(const GWEN_DB_NODE *n){ 00505 const char *p; 00506 int res; 00507 00508 assert(n); 00509 00510 switch(n->typ) { 00511 case GWEN_DB_NodeType_ValueInt: 00512 return n->data.dataInt; 00513 case GWEN_DB_NodeType_ValueChar: 00514 p=n->data.dataChar; 00515 assert(p); 00516 if (sscanf(p, "%d", &res)!=1) { 00517 DBG_ERROR(GWEN_LOGDOMAIN, "String in node is not an int value"); 00518 return 0; 00519 } 00520 return res; 00521 00522 default: 00523 DBG_ERROR(GWEN_LOGDOMAIN, "Node is neither char nor int value"); 00524 return 0; 00525 } 00526 } 00527 00528 00529 00530 const void *GWEN_DB_GetBinValueFromNode(const GWEN_DB_NODE *n, 00531 unsigned int *size){ 00532 assert(n); 00533 00534 if (n->typ!=GWEN_DB_NodeType_ValueBin) { 00535 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a binary value"); 00536 return NULL; 00537 } 00538 00539 *size=n->dataSize; 00540 return n->data.dataBin; 00541 } 00542 00543 00544 00545 GWEN_DB_NODE *GWEN_DB_FindGroup(GWEN_DB_NODE *n, 00546 const char *name, 00547 int idx) { 00548 GWEN_DB_NODE *nn; 00549 00550 assert(n); 00551 assert(name); 00552 00553 if (n->typ!=GWEN_DB_NodeType_Group) { 00554 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group"); 00555 return NULL; 00556 } 00557 00558 /* find existing node */ 00559 assert(n->children); 00560 nn=GWEN_DB_Node_List_First(n->children); 00561 while(nn) { 00562 if (nn->typ==GWEN_DB_NodeType_Group) { 00563 if (strcasecmp(nn->data.dataName, name)==0) { 00564 if (!idx) 00565 /* ok, group found, return it */ 00566 return nn; 00567 idx--; 00568 } /* if entry found */ 00569 } 00570 nn=GWEN_DB_Node_List_Next(nn); 00571 } /* while node */ 00572 00573 return NULL; 00574 } 00575 00576 00577 00578 GWEN_DB_NODE *GWEN_DB_FindVar(GWEN_DB_NODE *n, 00579 const char *name, 00580 int idx) { 00581 GWEN_DB_NODE *nn; 00582 00583 assert(n); 00584 assert(name); 00585 00586 if (n->typ!=GWEN_DB_NodeType_Group) { 00587 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group"); 00588 return NULL; 00589 } 00590 00591 /* find existing node */ 00592 assert(n->children); 00593 nn=GWEN_DB_Node_List_First(n->children); 00594 while(nn) { 00595 if (nn->typ==GWEN_DB_NodeType_Var) { 00596 if (strcasecmp(nn->data.dataName, name)==0) { 00597 if (!idx) 00598 /* ok, group found, return it */ 00599 return nn; 00600 idx--; 00601 } /* if entry found */ 00602 } 00603 nn=GWEN_DB_Node_List_Next(nn); 00604 } /* while node */ 00605 00606 return NULL; 00607 } 00608 00609 00610 00611 00612 00613 00614 00615 void* GWEN_DB_HandlePath(const char *entry, 00616 void *data, 00617 int idx, 00618 uint32_t flags) { 00619 GWEN_DB_NODE *n; 00620 GWEN_DB_NODE *nn; 00621 00622 n=(GWEN_DB_NODE*)data; 00623 00624 /* check whether we are allowed to simply create the node */ 00625 if ( 00626 ((flags & GWEN_PATH_FLAGS_LAST) && 00627 (((flags & GWEN_PATH_FLAGS_VARIABLE) && 00628 (flags & GWEN_PATH_FLAGS_CREATE_VAR)) || 00629 (!(flags & GWEN_PATH_FLAGS_VARIABLE) && 00630 (flags & GWEN_PATH_FLAGS_CREATE_GROUP))) 00631 ) || 00632 ( 00633 !(flags & GWEN_PATH_FLAGS_LAST) && 00634 (flags & GWEN_PATH_FLAGS_PATHCREATE)) 00635 ) { 00636 /* simply create the new variable/group */ 00637 if (idx!=0) { 00638 DBG_INFO(GWEN_LOGDOMAIN, "Index is not 0, not creating %s[%d]", 00639 entry, idx); 00640 return 0; 00641 } 00642 if (flags & GWEN_PATH_FLAGS_VARIABLE) { 00643 DBG_VERBOUS(GWEN_LOGDOMAIN, 00644 "Unconditionally creating variable \"%s\"", entry); 00645 nn=GWEN_DB_Var_new(entry); 00646 if (flags & GWEN_DB_FLAGS_INSERT) 00647 GWEN_DB_Node_Insert(n, nn); 00648 else 00649 GWEN_DB_Node_Append(n, nn); 00650 return nn; 00651 } 00652 else { 00653 DBG_VERBOUS(GWEN_LOGDOMAIN, 00654 "Unconditionally creating group \"%s\"", entry); 00655 nn=GWEN_DB_Group_new(entry); 00656 if (flags & GWEN_DB_FLAGS_INSERT) 00657 GWEN_DB_Node_Insert(n, nn); 00658 else 00659 GWEN_DB_Node_Append(n, nn); 00660 return nn; 00661 } 00662 } 00663 00664 /* find the node */ 00665 if (flags & GWEN_PATH_FLAGS_VARIABLE) { 00666 nn=GWEN_DB_FindVar(n, entry, idx); 00667 } 00668 else { 00669 nn=GWEN_DB_FindGroup(n, entry, idx); 00670 } 00671 00672 if (!nn) { 00673 /* node not found, check, if we are allowed to create it */ 00674 if ( 00675 (!(flags & GWEN_PATH_FLAGS_LAST) && 00676 (flags & GWEN_PATH_FLAGS_PATHMUSTEXIST)) || 00677 (flags & GWEN_PATH_FLAGS_NAMEMUSTEXIST) 00678 ) { 00679 if (flags & GWEN_PATH_FLAGS_VARIABLE) { 00680 DBG_VERBOUS(GWEN_LOGDOMAIN, 00681 "Variable \"%s\" does not exist", entry); 00682 } 00683 else { 00684 DBG_VERBOUS(GWEN_LOGDOMAIN, 00685 "Group \"%s\" does not exist", entry); 00686 } 00687 return 0; 00688 } 00689 /* create the new variable/group */ 00690 if (idx!=0) { 00691 DBG_INFO(GWEN_LOGDOMAIN, "Index is not 0, not creating %s[%d]", 00692 entry, idx); 00693 return 0; 00694 } 00695 if (flags & GWEN_PATH_FLAGS_VARIABLE) { 00696 DBG_VERBOUS(GWEN_LOGDOMAIN, 00697 "Variable \"%s\" not found, creating", entry); 00698 nn=GWEN_DB_Var_new(entry); 00699 if (flags & GWEN_DB_FLAGS_INSERT) 00700 GWEN_DB_Node_Insert(n, nn); 00701 else 00702 GWEN_DB_Node_Append(n, nn); 00703 } 00704 else { 00705 DBG_VERBOUS(GWEN_LOGDOMAIN, 00706 "Group \"%s\" not found, creating", entry); 00707 nn=GWEN_DB_Group_new(entry); 00708 if (flags & GWEN_DB_FLAGS_INSERT) 00709 GWEN_DB_Node_Insert(n, nn); 00710 else 00711 GWEN_DB_Node_Append(n, nn); 00712 } 00713 } /* if node not found */ 00714 else { 00715 /* node does exist, check whether this is ok */ 00716 if ( 00717 ((flags & GWEN_PATH_FLAGS_LAST) && 00718 (flags & GWEN_PATH_FLAGS_NAMEMUSTNOTEXIST)) || 00719 (!(flags & GWEN_PATH_FLAGS_LAST) && 00720 (flags & GWEN_PATH_FLAGS_PATHMUSTNOTEXIST)) 00721 ) { 00722 DBG_VERBOUS(GWEN_LOGDOMAIN, "Entry \"%s\" already exists", entry); 00723 return 0; 00724 } 00725 } 00726 00727 return nn; 00728 } 00729 00730 00731 00732 GWEN_DB_NODE *GWEN_DB_GetNode(GWEN_DB_NODE *n, 00733 const char *path, 00734 uint32_t flags){ 00735 return (GWEN_DB_NODE*)GWEN_Path_HandleWithIdx(path, 00736 n, 00737 flags, 00738 GWEN_DB_HandlePath); 00739 } 00740 00741 00742 00743 void GWEN_DB_ClearNode(GWEN_DB_NODE *n) { 00744 assert(n); 00745 if (n->children) 00746 GWEN_DB_Node_List_Clear(n->children); 00747 } 00748 00749 00750 00751 GWEN_DB_NODE *GWEN_DB_GetValue(GWEN_DB_NODE *n, 00752 const char *path, 00753 int idx) { 00754 GWEN_DB_NODE *nn; 00755 00756 /* find corresponding node */ 00757 nn=GWEN_DB_GetNode(n, 00758 path, 00759 GWEN_PATH_FLAGS_PATHMUSTEXIST | 00760 GWEN_PATH_FLAGS_NAMEMUSTEXIST | 00761 GWEN_PATH_FLAGS_VARIABLE); 00762 if (!nn) { 00763 DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not found", 00764 path); 00765 return 0; 00766 } 00767 00768 /* find value */ 00769 assert(nn->children); 00770 nn=GWEN_DB_Node_List_First(nn->children); 00771 while(nn) { 00772 if (nn->typ>=GWEN_DB_NodeType_ValueChar && 00773 nn->typ<GWEN_DB_NodeType_ValueLast) { 00774 if (!idx) 00775 return nn; 00776 idx--; 00777 } 00778 nn=GWEN_DB_Node_List_Next(nn); 00779 } 00780 00781 DBG_VERBOUS(GWEN_LOGDOMAIN, "No value[%d] for path \"%s\"", 00782 idx, path); 00783 return NULL; 00784 } 00785 00786 00787 00788 int GWEN_DB_DeleteVar(GWEN_DB_NODE *n, 00789 const char *path) { 00790 GWEN_DB_NODE *nn; 00791 00792 /* find corresponding node */ 00793 nn=GWEN_DB_GetNode(n, 00794 path, 00795 GWEN_PATH_FLAGS_PATHMUSTEXIST | 00796 GWEN_PATH_FLAGS_NAMEMUSTEXIST | 00797 GWEN_PATH_FLAGS_VARIABLE); 00798 if (!nn) { 00799 DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not found", 00800 path); 00801 return 1; 00802 } 00803 GWEN_DB_Node_Unlink(nn); 00804 GWEN_DB_Node_free(nn); 00805 return 0; 00806 } 00807 00808 00809 00810 int GWEN_DB_DeleteGroup(GWEN_DB_NODE *n, 00811 const char *path) { 00812 GWEN_DB_NODE *nn; 00813 00814 /* find corresponding node */ 00815 nn=GWEN_DB_GetNode(n, 00816 path, 00817 GWEN_PATH_FLAGS_PATHMUSTEXIST | 00818 GWEN_PATH_FLAGS_NAMEMUSTEXIST); 00819 if (!nn) { 00820 DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not found", 00821 path); 00822 return 1; 00823 } 00824 GWEN_DB_Node_Unlink(nn); 00825 GWEN_DB_Node_free(nn); 00826 return 0; 00827 } 00828 00829 00830 00831 int GWEN_DB_ClearGroup(GWEN_DB_NODE *n, 00832 const char *path){ 00833 assert(n); 00834 if (path) { 00835 GWEN_DB_NODE *nn; 00836 00837 /* find corresponding node */ 00838 nn=GWEN_DB_GetNode(n, 00839 path, 00840 GWEN_PATH_FLAGS_PATHMUSTEXIST | 00841 GWEN_PATH_FLAGS_NAMEMUSTEXIST); 00842 if (!nn) { 00843 DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not found", 00844 path); 00845 return 1; 00846 } 00847 GWEN_DB_ClearNode(nn); 00848 } 00849 else { 00850 GWEN_DB_ClearNode(n); 00851 } 00852 return 0; 00853 } 00854 00855 00856 00857 const char *GWEN_DB_GetCharValue(GWEN_DB_NODE *n, 00858 const char *path, 00859 int idx, 00860 const char *defVal){ 00861 GWEN_DB_NODE *nn; 00862 00863 nn=GWEN_DB_GetValue(n, path, idx); 00864 if (!nn){ 00865 DBG_VERBOUS(GWEN_LOGDOMAIN, 00866 "Value for \"%s\" not found, returning default value", 00867 path); 00868 return defVal; 00869 } 00870 if (nn->typ!=GWEN_DB_NodeType_ValueChar) { 00871 /* bad type */ 00872 DBG_VERBOUS(GWEN_LOGDOMAIN, 00873 "Bad type for path \"%s\", returning default value", 00874 path); 00875 return defVal; 00876 } 00877 return nn->data.dataChar; 00878 } 00879 00880 00881 00882 int GWEN_DB_SetCharValue(GWEN_DB_NODE *n, 00883 uint32_t flags, 00884 const char *path, 00885 const char *val){ 00886 GWEN_DB_NODE *nn; 00887 GWEN_DB_NODE *nv; 00888 00889 /* select/create node */ 00890 nn=GWEN_DB_GetNode(n, 00891 path, 00892 flags | GWEN_PATH_FLAGS_VARIABLE); 00893 if (!nn) { 00894 DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available", 00895 path); 00896 return 1; 00897 } 00898 00899 nv=GWEN_DB_ValueChar_new(val); 00900 00901 /* delete contents of this variable if wanted */ 00902 if (flags & GWEN_DB_FLAGS_OVERWRITE_VARS) { 00903 DBG_VERBOUS(GWEN_LOGDOMAIN, "Clearing variable \"%s\"", path); 00904 GWEN_DB_ClearNode(nn); 00905 } 00906 00907 /* add previously created value */ 00908 if (flags & GWEN_DB_FLAGS_INSERT) 00909 GWEN_DB_Node_Insert(nn, nv); 00910 else 00911 GWEN_DB_Node_Append(nn, nv); 00912 DBG_VERBOUS(GWEN_LOGDOMAIN, 00913 "Added char value \"%s\" to variable \"%s\"", val, path); 00914 00915 return 0; 00916 } 00917 00918 00919 00920 int GWEN_DB_AddCharValue(GWEN_DB_NODE *n, 00921 const char *path, 00922 const char *val, 00923 int senseCase, 00924 int check){ 00925 GWEN_DB_NODE *nn; 00926 GWEN_DB_NODE *nv; 00927 00928 /* select/create node */ 00929 nn=GWEN_DB_GetNode(n, 00930 path, 00931 GWEN_DB_FLAGS_DEFAULT | GWEN_PATH_FLAGS_VARIABLE); 00932 if (!nn) { 00933 DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available", 00934 path); 00935 return -1; 00936 } 00937 00938 if (check) { 00939 nv=GWEN_DB_GetFirstValue(n); 00940 if (nv && nv->typ==GWEN_DB_NodeType_ValueChar) { 00941 int res; 00942 00943 assert(nv->data.dataChar); 00944 if (senseCase) 00945 res=strcasecmp(nv->data.dataChar, val)==0; 00946 else 00947 res=strcmp(nv->data.dataChar, val)==0; 00948 if (res) { 00949 DBG_DEBUG(GWEN_LOGDOMAIN, 00950 "Value \"%s\" of var \"%s\" already exists", 00951 val, path); 00952 return 1; 00953 } 00954 } 00955 } /* if check */ 00956 00957 nv=GWEN_DB_ValueChar_new(val); 00958 GWEN_DB_Node_Append(nn, nv); 00959 DBG_VERBOUS(GWEN_LOGDOMAIN, 00960 "Added char value \"%s\" to variable \"%s\"", val, path); 00961 00962 return 0; 00963 } 00964 00965 00966 00967 int GWEN_DB_RemoveCharValue(GWEN_DB_NODE *n, 00968 const char *path, 00969 const char *val, 00970 int senseCase){ 00971 GWEN_DB_NODE *nn; 00972 GWEN_DB_NODE *nv; 00973 00974 /* select/create node */ 00975 nn=GWEN_DB_GetNode(n, 00976 path, 00977 GWEN_DB_FLAGS_DEFAULT | GWEN_PATH_FLAGS_VARIABLE); 00978 if (!nn) { 00979 DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available", 00980 path); 00981 return -1; 00982 } 00983 00984 nv=GWEN_DB_GetFirstValue(n); 00985 if (nv && nv->typ==GWEN_DB_NodeType_ValueChar) { 00986 int res; 00987 00988 assert(nv->data.dataChar); 00989 if (senseCase) 00990 res=strcasecmp(nv->data.dataChar, val)==0; 00991 else 00992 res=strcmp(nv->data.dataChar, val)==0; 00993 if (res) { 00994 DBG_DEBUG(GWEN_LOGDOMAIN, 00995 "Value \"%s\" of var \"%s\" already exists", 00996 val, path); 00997 GWEN_DB_Node_Unlink(nv); 00998 GWEN_DB_Node_free(nv); 00999 return 0; 01000 } 01001 } 01002 01003 return 1; 01004 } 01005 01006 01007 01008 int GWEN_DB_GetIntValue(GWEN_DB_NODE *n, 01009 const char *path, 01010 int idx, 01011 int defVal){ 01012 GWEN_DB_NODE *nn; 01013 const char *p; 01014 int res; 01015 01016 assert(n); 01017 nn=GWEN_DB_GetValue(n, path, idx); 01018 if (!nn){ 01019 DBG_VERBOUS(GWEN_LOGDOMAIN, 01020 "Value[%d] for \"%s\" not found, returning default value", 01021 idx, path); 01022 return defVal; 01023 } 01024 01025 switch(nn->typ) { 01026 case GWEN_DB_NodeType_ValueInt: 01027 return nn->data.dataInt; 01028 case GWEN_DB_NodeType_ValueChar: 01029 p=nn->data.dataChar; 01030 assert(p); 01031 if (sscanf(p, "%d", &res)!=1) { 01032 DBG_INFO(GWEN_LOGDOMAIN, 01033 "String [%s] in node is not an int value", p); 01034 return defVal; 01035 } 01036 return res; 01037 01038 default: 01039 DBG_ERROR(GWEN_LOGDOMAIN, "Node is neither char nor int value"); 01040 return defVal; 01041 } 01042 } 01043 01044 01045 01046 int GWEN_DB_SetIntValue(GWEN_DB_NODE *n, 01047 uint32_t flags, 01048 const char *path, 01049 int val){ 01050 GWEN_DB_NODE *nn; 01051 GWEN_DB_NODE *nv; 01052 01053 /* select/create node */ 01054 nn=GWEN_DB_GetNode(n, 01055 path, 01056 flags | GWEN_PATH_FLAGS_VARIABLE); 01057 if (!nn) { 01058 DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available", 01059 path); 01060 return 1; 01061 } 01062 01063 /* delete contents of this variable if wanted */ 01064 if (flags & GWEN_DB_FLAGS_OVERWRITE_VARS) { 01065 DBG_VERBOUS(GWEN_LOGDOMAIN, "Clearing variable \"%s\"", path); 01066 GWEN_DB_ClearNode(nn); 01067 } 01068 01069 nv=GWEN_DB_ValueInt_new(val); 01070 if (flags & GWEN_DB_FLAGS_INSERT) 01071 GWEN_DB_Node_Insert(nn, nv); 01072 else 01073 GWEN_DB_Node_Append(nn, nv); 01074 DBG_VERBOUS(GWEN_LOGDOMAIN, "Added int value \"%d\" to variable \"%s\"", val, path); 01075 return 0; 01076 } 01077 01078 01079 01080 const void *GWEN_DB_GetBinValue(GWEN_DB_NODE *n, 01081 const char *path, 01082 int idx, 01083 const void *defVal, 01084 unsigned int defValSize, 01085 unsigned int *returnValueSize){ 01086 GWEN_DB_NODE *nn; 01087 01088 assert(returnValueSize); 01089 nn=GWEN_DB_GetValue(n, path, idx); 01090 if (!nn){ 01091 DBG_VERBOUS(GWEN_LOGDOMAIN, 01092 "Value for \"%s\" not found, returning default value", 01093 path); 01094 *returnValueSize=defValSize; 01095 return defVal; 01096 } 01097 if (nn->typ!=GWEN_DB_NodeType_ValueBin) { 01098 /* bad type */ 01099 DBG_VERBOUS(GWEN_LOGDOMAIN, 01100 "Bad type for path \"%s\", returning default value", 01101 path); 01102 *returnValueSize=defValSize; 01103 return defVal; 01104 } 01105 *returnValueSize=nn->dataSize; 01106 return nn->data.dataBin; 01107 } 01108 01109 01110 01111 int GWEN_DB_SetBinValue(GWEN_DB_NODE *n, 01112 uint32_t flags, 01113 const char *path, 01114 const void *val, 01115 unsigned int valSize){ 01116 GWEN_DB_NODE *nn; 01117 GWEN_DB_NODE *nv; 01118 01119 assert(val); 01120 /* select/create node */ 01121 nn=GWEN_DB_GetNode(n, 01122 path, 01123 flags | GWEN_PATH_FLAGS_VARIABLE); 01124 if (!nn) { 01125 DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available", 01126 path); 01127 return 1; 01128 } 01129 01130 /* delete contents of this variable if wanted */ 01131 if (flags & GWEN_DB_FLAGS_OVERWRITE_VARS) { 01132 DBG_VERBOUS(GWEN_LOGDOMAIN, "Clearing variable \"%s\"", path); 01133 GWEN_DB_ClearNode(nn); 01134 } 01135 01136 nv=GWEN_DB_ValueBin_new(val, valSize); 01137 if (flags & GWEN_DB_FLAGS_INSERT) 01138 GWEN_DB_Node_Insert(nn, nv); 01139 else 01140 GWEN_DB_Node_Append(nn, nv); 01141 DBG_VERBOUS(GWEN_LOGDOMAIN, "Added bin value to variable \"%s\"", path); 01142 return 0; 01143 } 01144 01145 01146 01147 void *GWEN_DB_GetPtrValue(GWEN_DB_NODE *n, 01148 const char *path, 01149 int idx, 01150 void *defVal){ 01151 GWEN_DB_NODE *nn; 01152 01153 nn=GWEN_DB_GetValue(n, path, idx); 01154 if (!nn){ 01155 DBG_VERBOUS(GWEN_LOGDOMAIN, 01156 "Value for \"%s\" not found, returning default value", 01157 path); 01158 return defVal; 01159 } 01160 if (nn->typ!=GWEN_DB_NodeType_ValuePtr) { 01161 /* bad type */ 01162 DBG_VERBOUS(GWEN_LOGDOMAIN, 01163 "Bad type for path \"%s\", returning default value", 01164 path); 01165 return defVal; 01166 } 01167 return nn->data.dataPtr; 01168 } 01169 01170 01171 01172 int GWEN_DB_SetPtrValue(GWEN_DB_NODE *n, 01173 uint32_t flags, 01174 const char *path, 01175 void *val){ 01176 GWEN_DB_NODE *nn; 01177 GWEN_DB_NODE *nv; 01178 01179 /* select/create node */ 01180 nn=GWEN_DB_GetNode(n, 01181 path, 01182 flags | GWEN_PATH_FLAGS_VARIABLE); 01183 if (!nn) { 01184 DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available", 01185 path); 01186 return 1; 01187 } 01188 01189 /* delete contents of this variable if wanted */ 01190 if (flags & GWEN_DB_FLAGS_OVERWRITE_VARS) { 01191 DBG_VERBOUS(GWEN_LOGDOMAIN, "Clearing variable \"%s\"", path); 01192 GWEN_DB_ClearNode(nn); 01193 } 01194 01195 nv=GWEN_DB_ValuePtr_new(val); 01196 if (flags & GWEN_DB_FLAGS_INSERT) 01197 GWEN_DB_Node_Insert(nn, nv); 01198 else 01199 GWEN_DB_Node_Append(nn, nv); 01200 DBG_VERBOUS(GWEN_LOGDOMAIN, "Added ptr value to variable \"%s\"", path); 01201 01202 return 0; 01203 } 01204 01205 01206 01207 01208 01209 01210 01211 01212 01213 01214 01215 01216 01217 01218 01219 01220 GWEN_DB_NODE *GWEN_DB_GetGroup(GWEN_DB_NODE *n, 01221 uint32_t flags, 01222 const char *path) { 01223 GWEN_DB_NODE *nn; 01224 01225 /* select/create node */ 01226 nn=GWEN_DB_GetNode(n, 01227 path, 01228 flags & ~GWEN_PATH_FLAGS_VARIABLE); 01229 if (!nn) { 01230 DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available", 01231 path); 01232 return NULL; 01233 } 01234 01235 /* delete contents of this variable if wanted */ 01236 if (flags & GWEN_DB_FLAGS_OVERWRITE_GROUPS) { 01237 DBG_VERBOUS(GWEN_LOGDOMAIN, "Clearing group \"%s\"", path); 01238 GWEN_DB_ClearNode(nn); 01239 } 01240 01241 return nn; 01242 } 01243 01244 01245 01246 const char *GWEN_DB_GroupName(GWEN_DB_NODE *n){ 01247 assert(n); 01248 if (n->typ!=GWEN_DB_NodeType_Group) { 01249 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group"); 01250 return NULL; 01251 } 01252 return n->data.dataName; 01253 } 01254 01255 01256 01257 void GWEN_DB_Dump(GWEN_DB_NODE *n, int insert){ 01258 if (n) { 01259 int i; 01260 01261 for (i=0; i<insert; i++) 01262 fprintf(stderr, " "); 01263 01264 /* dump dynamic (allocated) data */ 01265 switch(n->typ) { 01266 case GWEN_DB_NodeType_Group: 01267 fprintf(stderr, "Group : \"%s\"\n", n->data.dataName); 01268 break; 01269 case GWEN_DB_NodeType_Var: 01270 fprintf(stderr, "Var : \"%s\"\n", n->data.dataName); 01271 break; 01272 case GWEN_DB_NodeType_ValueChar: 01273 fprintf(stderr, "Value : \"%s\" (char)\n", n->data.dataChar); 01274 break; 01275 case GWEN_DB_NodeType_ValueInt: 01276 fprintf(stderr, "Value : %d (int)\n", n->data.dataInt); 01277 break; 01278 case GWEN_DB_NodeType_ValueBin: { 01279 char *buffer; 01280 01281 buffer=(char*)GWEN_Memory_malloc((n->dataSize*2)+1); 01282 assert(buffer); 01283 if (GWEN_Text_ToHex(n->data.dataBin, n->dataSize, 01284 buffer, (n->dataSize*2)+1)==0) { 01285 fprintf(stderr, "Value : %d bytes (bin)\n", n->dataSize); 01286 } 01287 else { 01288 fprintf(stderr, "Value : %s (bin)\n", buffer); 01289 } 01290 GWEN_Memory_dealloc(buffer); 01291 break; 01292 } 01293 case GWEN_DB_NodeType_ValuePtr: 01294 fprintf(stderr, "Value : %p (ptr)\n", n->data.dataPtr); 01295 break; 01296 default: 01297 fprintf(stderr, "[unknown node type %d]\n", n->typ); 01298 } 01299 01300 /* dump children */ 01301 if (n->children) { 01302 GWEN_DB_NODE *cn; 01303 01304 cn=GWEN_DB_Node_List_First(n->children); 01305 while(cn) { 01306 GWEN_DB_Dump(cn, insert+4); 01307 cn=GWEN_DB_Node_List_Next(cn); 01308 } 01309 } 01310 } 01311 else { 01312 fprintf(stderr, "[no node]\n"); 01313 } 01314 } 01315 01316 01317 01318 int GWEN_DB_AddGroup(GWEN_DB_NODE *n, GWEN_DB_NODE *nn){ 01319 assert(n); 01320 assert(nn); 01321 01322 if (n->typ!=GWEN_DB_NodeType_Group) { 01323 DBG_ERROR(GWEN_LOGDOMAIN, "Target node is not a group"); 01324 return 0; 01325 } 01326 01327 if (nn->typ!=GWEN_DB_NodeType_Group) { 01328 DBG_ERROR(GWEN_LOGDOMAIN, "Source node is not a group"); 01329 return 0; 01330 } 01331 01332 GWEN_DB_Node_Append(n, nn); 01333 return 0; 01334 } 01335 01336 01337 01338 int GWEN_DB_InsertGroup(GWEN_DB_NODE *n, GWEN_DB_NODE *nn){ 01339 assert(n); 01340 assert(nn); 01341 01342 if (n->typ!=GWEN_DB_NodeType_Group) { 01343 DBG_ERROR(GWEN_LOGDOMAIN, "Target node is not a group"); 01344 return 0; 01345 } 01346 01347 if (nn->typ!=GWEN_DB_NodeType_Group) { 01348 DBG_ERROR(GWEN_LOGDOMAIN, "Source node is not a group"); 01349 return 0; 01350 } 01351 01352 GWEN_DB_Node_Insert(n, nn); 01353 return 0; 01354 } 01355 01356 01357 01358 int GWEN_DB_AddGroupChildren(GWEN_DB_NODE *n, GWEN_DB_NODE *nn){ 01359 GWEN_DB_NODE *cpn; 01360 01361 assert(n); 01362 assert(nn); 01363 01364 if (n->typ!=GWEN_DB_NodeType_Group) { 01365 DBG_ERROR(GWEN_LOGDOMAIN, "Target node is not a group"); 01366 return -1; 01367 } 01368 01369 if (nn->typ!=GWEN_DB_NodeType_Group) { 01370 DBG_ERROR(GWEN_LOGDOMAIN, "Source node is not a group"); 01371 GWEN_DB_Dump(nn, 1); 01372 return -1; 01373 } 01374 01375 nn=GWEN_DB_Node_List_First(nn->children); 01376 while (nn) { 01377 DBG_VERBOUS(GWEN_LOGDOMAIN, "Duplicating node"); 01378 cpn=GWEN_DB_Node_dup(nn); 01379 GWEN_DB_Node_Append(n, cpn); 01380 nn=GWEN_DB_Node_List_Next(nn); 01381 } /* while */ 01382 return 0; 01383 } 01384 01385 01386 01387 void GWEN_DB_UnlinkGroup(GWEN_DB_NODE *n){ 01388 assert(n); 01389 if (n->typ!=GWEN_DB_NodeType_Group) { 01390 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group"); 01391 return; 01392 } 01393 GWEN_DB_Node_Unlink(n); 01394 } 01395 01396 01397 int GWEN_DB_VariableExists(GWEN_DB_NODE *n, const char *path){ 01398 GWEN_DB_NODE *nn; 01399 01400 /* find corresponding node */ 01401 assert(n); 01402 nn=GWEN_DB_GetNode(n, 01403 path, 01404 GWEN_PATH_FLAGS_PATHMUSTEXIST | 01405 GWEN_PATH_FLAGS_NAMEMUSTEXIST | 01406 GWEN_PATH_FLAGS_VARIABLE); 01407 if (!nn) { 01408 DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not found", path); 01409 return 0; 01410 } 01411 01412 return 1; 01413 } 01414 01415 01416 01417 int GWEN_DB_ValueExists(GWEN_DB_NODE *n, 01418 const char *path, 01419 unsigned int i){ 01420 return (GWEN_DB_GetValue(n, path, i)!=0); 01421 } 01422 01423 01424 01425 GWEN_DB_NODE_TYPE GWEN_DB_GetVariableType(GWEN_DB_NODE *n, 01426 const char *p){ 01427 GWEN_DB_NODE *nn; 01428 01429 nn=GWEN_DB_FindVar(n, p, 0); 01430 if (!nn) 01431 return GWEN_DB_NodeType_Unknown; 01432 01433 nn=GWEN_DB_GetFirstValue(nn); 01434 if (!nn) 01435 return GWEN_DB_NodeType_Unknown; 01436 return GWEN_DB_GetValueType(nn); 01437 } 01438 01439 01440 01441 GWEN_DB_NODE_TYPE GWEN_DB_GetValueTypeByPath(GWEN_DB_NODE *n, 01442 const char *path, 01443 unsigned int i){ 01444 GWEN_DB_NODE *nn; 01445 01446 nn=GWEN_DB_GetValue(n, path, i); 01447 if (!nn) 01448 return GWEN_DB_NodeType_Unknown; 01449 return GWEN_DB_GetValueType(nn); 01450 } 01451 01452 01453 void GWEN_DB_GroupRename(GWEN_DB_NODE *n, const char *newname){ 01454 assert(n); 01455 assert(newname); 01456 assert(n->typ==GWEN_DB_NodeType_Group); 01457 GWEN_Memory_dealloc(n->data.dataName); 01458 n->data.dataName=GWEN_Memory_strdup(newname); 01459 } 01460 01461 01462 01463 01464 01465 01466 01467 int GWEN_DB_IsGroup(const GWEN_DB_NODE *n){ 01468 assert(n); 01469 return n->typ==GWEN_DB_NodeType_Group; 01470 } 01471 01472 01473 01474 int GWEN_DB_IsVariable(const GWEN_DB_NODE *n){ 01475 assert(n); 01476 return n->typ==GWEN_DB_NodeType_Var; 01477 } 01478 01479 01480 01481 int GWEN_DB_IsValue(const GWEN_DB_NODE *n){ 01482 assert(n); 01483 return (n->typ>=GWEN_DB_NodeType_ValueChar && 01484 n->typ>=GWEN_DB_NodeType_ValueLast); 01485 } 01486 01487 01488 01489 void *GWEN_DB_Groups_Foreach(GWEN_DB_NODE *node, GWEN_DB_NODES_CB func, 01490 void *user_data){ 01491 GWEN_DB_NODE *iter; 01492 void *res; 01493 01494 assert(node); 01495 assert(func); 01496 01497 iter=GWEN_DB_GetFirstGroup(node); 01498 res=NULL; 01499 while(iter){ 01500 res=(*func)(iter, user_data); 01501 if (res) { 01502 break; 01503 } 01504 iter=GWEN_DB_GetNextGroup(iter); 01505 } 01506 return res; 01507 } 01508 01509 01510 01511 void *GWEN_DB_count_cb(GWEN_UNUSED GWEN_DB_NODE *node, void *user_data){ 01512 unsigned int *a = user_data; 01513 ++(*a); 01514 return NULL; 01515 } 01516 01517 01518 01519 unsigned int GWEN_DB_Groups_Count(const GWEN_DB_NODE *node){ 01520 unsigned int res = 0; 01521 GWEN_DB_Groups_Foreach((GWEN_DB_NODE *)node, GWEN_DB_count_cb, &res); 01522 return res; 01523 } 01524 01525 01526 01527 void *GWEN_DB_Variables_Foreach(GWEN_DB_NODE *node, GWEN_DB_NODES_CB func, 01528 void *user_data){ 01529 GWEN_DB_NODE *iter; 01530 void *res; 01531 01532 assert(node); 01533 assert(func); 01534 01535 iter=GWEN_DB_GetFirstVar(node); 01536 res=NULL; 01537 while(iter){ 01538 res=(*func)(iter, user_data); 01539 if (res) { 01540 break; 01541 } 01542 iter=GWEN_DB_GetNextVar(iter); 01543 } 01544 return res; 01545 } 01546 01547 01548 01549 unsigned int GWEN_DB_Variables_Count(const GWEN_DB_NODE *node){ 01550 unsigned int res = 0; 01551 GWEN_DB_Variables_Foreach((GWEN_DB_NODE *)node, GWEN_DB_count_cb, &res); 01552 return res; 01553 } 01554 01555 01556 01557 void *GWEN_DB_Values_Foreach(GWEN_DB_NODE *node, GWEN_DB_NODES_CB func, 01558 void *user_data){ 01559 GWEN_DB_NODE *iter; 01560 void *res; 01561 01562 assert(node); 01563 assert(func); 01564 01565 iter=GWEN_DB_GetFirstValue(node); 01566 res=NULL; 01567 while(iter){ 01568 res=(*func)(iter, user_data); 01569 if (res) { 01570 break; 01571 } 01572 iter=GWEN_DB_GetNextValue(iter); 01573 } 01574 return res; 01575 } 01576 01577 01578 01579 unsigned int GWEN_DB_Values_Count(const GWEN_DB_NODE *node){ 01580 unsigned int res = 0; 01581 GWEN_DB_Values_Foreach((GWEN_DB_NODE *)node, GWEN_DB_count_cb, &res); 01582 return res; 01583 } 01584 01585 01586 01587 uint32_t GWEN_DB_GetNodeFlags(const GWEN_DB_NODE *n){ 01588 assert(n); 01589 return n->nodeFlags; 01590 } 01591 01592 01593 01594 void GWEN_DB_SetNodeFlags(GWEN_DB_NODE *n, 01595 uint32_t flags){ 01596 assert(n); 01597 n->nodeFlags=flags; 01598 } 01599 01600 01601 01602 void GWEN_DB_ModifyBranchFlagsUp(GWEN_DB_NODE *n, 01603 uint32_t newflags, 01604 uint32_t mask){ 01605 uint32_t flags; 01606 01607 assert(n); 01608 01609 while(n) { 01610 flags=n->nodeFlags; 01611 flags=((flags^newflags)&(mask))^flags; 01612 n->nodeFlags=flags; 01613 n=n->parent; 01614 } /* while */ 01615 } 01616 01617 01618 01619 void GWEN_DB_ModifyBranchFlagsDown(GWEN_DB_NODE *n, 01620 uint32_t newflags, 01621 uint32_t mask){ 01622 uint32_t flags; 01623 GWEN_DB_NODE *cn; 01624 01625 assert(n); 01626 01627 flags=n->nodeFlags; 01628 flags=((flags^newflags)&(mask))^flags; 01629 n->nodeFlags=flags; 01630 01631 cn=GWEN_DB_Node_List_First(n->children); 01632 while(cn) { 01633 GWEN_DB_ModifyBranchFlagsDown(cn, newflags, mask); 01634 cn=GWEN_DB_Node_List_Next(cn); 01635 } /* while cn */ 01636 } 01637 01638 01639 01640 GWEN_DB_NODE *GWEN_DB_GetParentGroup(GWEN_DB_NODE *n) { 01641 GWEN_DB_NODE *nn; 01642 01643 assert(n); 01644 nn=n->parent; 01645 while(nn && nn->typ!=GWEN_DB_NodeType_Group) 01646 nn=nn->parent; 01647 return nn; 01648 } 01649 01650 01651 01652 GWEN_DB_NODE *GWEN_DB_FindFirstGroup(GWEN_DB_NODE *n, const char *name){ 01653 GWEN_DB_NODE *nn; 01654 01655 assert(n); 01656 if (n->typ!=GWEN_DB_NodeType_Group) { 01657 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group"); 01658 return NULL; 01659 } 01660 nn=GWEN_DB_Node_List_First(n->children); 01661 while(nn) { 01662 if ((nn->typ==GWEN_DB_NodeType_Group) && 01663 (-1!=GWEN_Text_ComparePattern(nn->data.dataName, name, 0))) 01664 break; 01665 nn=GWEN_DB_Node_List_Next(nn); 01666 } /* while node */ 01667 return nn; 01668 } 01669 01670 01671 01672 GWEN_DB_NODE *GWEN_DB_FindNextGroup(GWEN_DB_NODE *n, const char *name){ 01673 GWEN_DB_NODE *og; 01674 01675 og=n; 01676 assert(n); 01677 if (n->typ!=GWEN_DB_NodeType_Group) { 01678 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group"); 01679 return NULL; 01680 } 01681 n=GWEN_DB_GetNextGroup(n); 01682 while(n) { 01683 if (-1!=GWEN_Text_ComparePattern(n->data.dataName, name, 0)) 01684 break; 01685 n=GWEN_DB_GetNextGroup(n); 01686 } /* while node */ 01687 assert(n!=og); 01688 return n; 01689 } 01690 01691 01692 01693 GWEN_DB_NODE *GWEN_DB_FindFirstVar(GWEN_DB_NODE *n, const char *name) { 01694 GWEN_DB_NODE *nn; 01695 01696 assert(n); 01697 if (n->typ!=GWEN_DB_NodeType_Group) { 01698 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group"); 01699 return NULL; 01700 } 01701 01702 nn=GWEN_DB_Node_List_First(n->children); 01703 while(nn) { 01704 if ((nn->typ==GWEN_DB_NodeType_Var) && 01705 (-1!=GWEN_Text_ComparePattern(nn->data.dataName, name, 0))) 01706 break; 01707 nn=GWEN_DB_Node_List_Next(nn); 01708 } /* while node */ 01709 01710 return nn; 01711 } 01712 01713 01714 01715 GWEN_DB_NODE *GWEN_DB_FindNextVar(GWEN_DB_NODE *n, const char *name) { 01716 GWEN_DB_NODE *og; 01717 01718 og=n; 01719 assert(n); 01720 if (n->typ!=GWEN_DB_NodeType_Var) { 01721 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a variable"); 01722 return NULL; 01723 } 01724 n=GWEN_DB_GetNextVar(n); 01725 while(n) { 01726 if (-1!=GWEN_Text_ComparePattern(n->data.dataName, name, 0)) 01727 break; 01728 n=GWEN_DB_GetNextVar(n); 01729 } /* while node */ 01730 assert(n!=og); 01731 return n; 01732 } 01733 01734 01735 01736 const char *GWEN_DB_VariableName(GWEN_DB_NODE *n){ 01737 assert(n); 01738 if (n->typ!=GWEN_DB_NodeType_Var) { 01739 DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a variable"); 01740 return NULL; 01741 } 01742 return n->data.dataName; 01743 } 01744 01745 01746 01747 void GWEN_DB_VariableRename(GWEN_DB_NODE *n, const char *newname){ 01748 assert(n); 01749 assert(newname); 01750 assert(n->typ==GWEN_DB_NodeType_Var); 01751 GWEN_Memory_dealloc(n->data.dataName); 01752 n->data.dataName=GWEN_Memory_strdup(newname); 01753 } 01754 01755 01756 01757 01758 01759 01760 #include "dbrw.c" 01761 01762 01763 01764 01765 01766 01767 01768 01769