db.c

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

Generated on Fri Apr 11 01:53:46 2008 for gwenhywfar by  doxygen 1.5.5