1 /***************************************************************************
2  begin       : Tue Sep 09 2003
3  copyright   : (C) 2019 by Martin Preuss
4  email       : martin@libchipcard.de
5 
6  ***************************************************************************
7  *                                                                         *
8  *   This library is free software; you can redistribute it and/or         *
9  *   modify it under the terms of the GNU Lesser General Public            *
10  *   License as published by the Free Software Foundation; either          *
11  *   version 2.1 of the License, or (at your option) any later version.    *
12  *                                                                         *
13  *   This library is distributed in the hope that it will be useful,       *
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
16  *   Lesser General Public License for more details.                       *
17  *                                                                         *
18  *   You should have received a copy of the GNU Lesser General Public      *
19  *   License along with this library; if not, write to the Free Software   *
20  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
21  *   MA  02111-1307  USA                                                   *
22  *                                                                         *
23  ***************************************************************************/
24 
25 
26 #ifdef HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29 
30 #define DISABLE_DEBUGLOG
31 
32 #include "db_p.h"
33 #include <gwenhywfar/misc.h>
34 #include <gwenhywfar/debug.h>
35 #include <gwenhywfar/path.h>
36 #include <gwenhywfar/text.h>
37 #include <gwenhywfar/dbio.h>
38 #include <gwenhywfar/fslock.h>
39 #include <gwenhywfar/fastbuffer.h>
40 #include <gwenhywfar/syncio_file.h>
41 #include <gwenhywfar/syncio_memory.h>
42 
43 #include <stdlib.h>
44 #include <assert.h>
45 #include <string.h>
46 #include <errno.h>
47 #include <ctype.h>
48 
49 #include <sys/types.h>
50 #ifdef HAVE_SYS_STAT_H
51 # include <sys/stat.h>
52 #endif
53 #ifdef HAVE_FCNTL_H
54 # include <fcntl.h>
55 #endif
56 #ifdef HAVE_UNISTD_H
57 # include <unistd.h>
58 #endif
59 
60 
61 #define GWEN_DB_NODE_FLAGS_MASK_INTERNAL  0xf0000000
62 #define GWEN_DB_NODE_FLAGS_GROUP          0x80000000
63 
64 
65 
66 /* ------------------------------------------------------------------------------------------------
67  * forward declarations
68  * ------------------------------------------------------------------------------------------------
69  */
70 
71 static int GWENHYWFAR_CB _replaceVarsCb(void *cbPtr, const char *name, int index, int maxLen, GWEN_BUFFER *dstBuf);
72 
73 
74 /* ------------------------------------------------------------------------------------------------
75  * implementations
76  * ------------------------------------------------------------------------------------------------
77  */
78 
79 
80 
81 
GWEN_LIST_FUNCTIONS(GWEN_DB_NODE,GWEN_DB_Node)82 GWEN_LIST_FUNCTIONS(GWEN_DB_NODE, GWEN_DB_Node)
83 
84 
85 
86 GWEN_DB_NODE *GWEN_DB_Node_new(GWEN_DB_NODE_TYPE t)
87 {
88   GWEN_DB_NODE *node;
89 
90   GWEN_NEW_OBJECT(GWEN_DB_NODE, node);
91   GWEN_LIST_INIT(GWEN_DB_NODE, node);
92   node->typ=t;
93   return (GWEN_DB_NODE *)node;
94 }
95 
96 
97 
98 
GWEN_DB_ValueBin_new(const void * data,unsigned int datasize)99 GWEN_DB_NODE *GWEN_DB_ValueBin_new(const void *data,
100                                    unsigned int datasize)
101 {
102   GWEN_DB_NODE *n;
103 
104   n=GWEN_DB_Node_new(GWEN_DB_NodeType_ValueBin);
105   if (datasize) {
106     assert(data);
107     n->dataSize=datasize;
108     n->data.dataBin=(char *)GWEN_Memory_malloc(datasize);
109     assert(n->data.dataBin);
110     memmove(n->data.dataBin, data, datasize);
111   }
112   return n;
113 }
114 
115 
116 
GWEN_DB_ValueInt_new(int data)117 GWEN_DB_NODE *GWEN_DB_ValueInt_new(int data)
118 {
119   GWEN_DB_NODE *n;
120 
121   n=GWEN_DB_Node_new(GWEN_DB_NodeType_ValueInt);
122   n->data.dataInt=data;
123   return n;
124 }
125 
126 
127 
GWEN_DB_ValueChar_new(const char * data)128 GWEN_DB_NODE *GWEN_DB_ValueChar_new(const char *data)
129 {
130   GWEN_DB_NODE *n;
131 
132   n=GWEN_DB_Node_new(GWEN_DB_NodeType_ValueChar);
133   if (data)
134     n->data.dataChar=GWEN_Memory_strdup(data);
135   else
136     n->data.dataChar=GWEN_Memory_strdup("");
137   return n;
138 }
139 
140 
141 
GWEN_DB_ValueChar_newFromInt(int v)142 GWEN_DB_NODE *GWEN_DB_ValueChar_newFromInt(int v)
143 {
144   GWEN_DB_NODE *n;
145   char numbuffer[64];
146   int rv;
147 
148   rv=snprintf(numbuffer, sizeof(numbuffer)-1, "%d", v);
149   if (rv>=(int)sizeof(numbuffer)) {
150   }
151   numbuffer[sizeof(numbuffer)-1]=0;
152 
153   n=GWEN_DB_Node_new(GWEN_DB_NodeType_ValueChar);
154   n->data.dataChar=GWEN_Memory_strdup(numbuffer);
155   return n;
156 }
157 
158 
159 
GWEN_DB_ValuePtr_new(void * data)160 GWEN_DB_NODE *GWEN_DB_ValuePtr_new(void *data)
161 {
162   GWEN_DB_NODE *n;
163 
164   n=GWEN_DB_Node_new(GWEN_DB_NodeType_ValuePtr);
165   n->data.dataPtr=data;
166   return n;
167 }
168 
169 
170 
GWEN_DB_Group_new(const char * name)171 GWEN_DB_NODE *GWEN_DB_Group_new(const char *name)
172 {
173   GWEN_DB_NODE *n;
174 
175   assert(name);
176   n=GWEN_DB_Node_new(GWEN_DB_NodeType_Group);
177   if (name)
178     n->data.dataName=GWEN_Memory_strdup(name);
179   else
180     n->data.dataName=GWEN_Memory_strdup("");
181   n->children=GWEN_DB_Node_List_new();
182   return n;
183 }
184 
185 
186 
GWEN_DB_Var_new(const char * name)187 GWEN_DB_NODE *GWEN_DB_Var_new(const char *name)
188 {
189   GWEN_DB_NODE *n;
190 
191   assert(name);
192   n=GWEN_DB_Node_new(GWEN_DB_NodeType_Var);
193   if (name)
194     n->data.dataName=GWEN_Memory_strdup(name);
195   else
196     n->data.dataName=GWEN_Memory_strdup("");
197   n->children=GWEN_DB_Node_List_new();
198   return n;
199 }
200 
201 
202 
GWEN_DB_Node_Append_UnDirty(GWEN_DB_NODE * parent,GWEN_DB_NODE * n)203 void GWEN_DB_Node_Append_UnDirty(GWEN_DB_NODE *parent,
204                                  GWEN_DB_NODE *n)
205 {
206   assert(parent);
207   assert(n);
208   assert(parent!=n);
209 
210   assert(parent->children!=NULL);
211   GWEN_DB_Node_List_Add(n, parent->children);
212 
213   n->parent=parent;
214 }
215 
216 
217 
GWEN_DB_Node_Append(GWEN_DB_NODE * parent,GWEN_DB_NODE * n)218 void GWEN_DB_Node_Append(GWEN_DB_NODE *parent,
219                          GWEN_DB_NODE *n)
220 {
221   GWEN_DB_Node_Append_UnDirty(parent, n);
222   GWEN_DB_ModifyBranchFlagsUp(parent,
223                               GWEN_DB_NODE_FLAGS_DIRTY,
224                               GWEN_DB_NODE_FLAGS_DIRTY);
225 }
226 
227 
228 
GWEN_DB_Node_InsertUnDirty(GWEN_DB_NODE * parent,GWEN_DB_NODE * n)229 void GWEN_DB_Node_InsertUnDirty(GWEN_DB_NODE *parent,
230                                 GWEN_DB_NODE *n)
231 {
232   assert(parent);
233   assert(n);
234   assert(parent!=n);
235 
236   assert(parent->children!=NULL);
237   GWEN_DB_Node_List_Insert(n, parent->children);
238 
239   n->parent=parent;
240 }
241 
242 
243 
GWEN_DB_Node_Insert(GWEN_DB_NODE * parent,GWEN_DB_NODE * n)244 void GWEN_DB_Node_Insert(GWEN_DB_NODE *parent,
245                          GWEN_DB_NODE *n)
246 {
247   GWEN_DB_Node_InsertUnDirty(parent, n);
248   GWEN_DB_ModifyBranchFlagsUp(parent,
249                               GWEN_DB_NODE_FLAGS_DIRTY,
250                               GWEN_DB_NODE_FLAGS_DIRTY);
251 }
252 
253 
254 
GWEN_DB_Node_Unlink_UnDirty(GWEN_DB_NODE * n)255 void GWEN_DB_Node_Unlink_UnDirty(GWEN_DB_NODE *n)
256 {
257   GWEN_DB_NODE *parent;
258 
259   assert(n);
260   parent=n->parent;
261   if (!parent) {
262     DBG_WARN(GWEN_LOGDOMAIN, "Node is not linked, nothing to do");
263     return;
264   }
265 
266   GWEN_DB_Node_List_Del(n);
267   n->parent=NULL;
268 }
269 
270 
271 
GWEN_DB_Node_Unlink(GWEN_DB_NODE * n)272 void GWEN_DB_Node_Unlink(GWEN_DB_NODE *n)
273 {
274   GWEN_DB_NODE *parent;
275 
276   assert(n);
277   parent=n->parent;
278   assert(parent);
279 
280   GWEN_DB_Node_Unlink_UnDirty(n);
281   GWEN_DB_ModifyBranchFlagsUp(parent,
282                               GWEN_DB_NODE_FLAGS_DIRTY,
283                               GWEN_DB_NODE_FLAGS_DIRTY);
284 }
285 
286 
287 
GWEN_DB_Node_free(GWEN_DB_NODE * n)288 void GWEN_DB_Node_free(GWEN_DB_NODE *n)
289 {
290   if (n) {
291     GWEN_LIST_FINI(GWEN_DB_NODE, n);
292 
293     /* free children */
294     if (n->children)
295       GWEN_DB_Node_List_free(n->children);
296 
297     if (n->nodeFlags & GWEN_DB_NODE_FLAGS_SAFE) {
298       /* free dynamic (allocated) data safely */
299       switch (n->typ) {
300       case GWEN_DB_NodeType_Group:
301       case GWEN_DB_NodeType_Var:
302         if (n->data.dataName) {
303           int l=strlen(n->data.dataName);
304           if (l)
305             memset(n->data.dataName, 0, l);
306           GWEN_Memory_dealloc(n->data.dataName);
307         }
308         break;
309 
310       case GWEN_DB_NodeType_ValueChar:
311         if (n->data.dataChar) {
312           int l=strlen(n->data.dataChar);
313           if (l)
314             memset(n->data.dataChar, 0, l);
315           GWEN_Memory_dealloc(n->data.dataChar);
316         }
317         break;
318       case GWEN_DB_NodeType_ValueBin:
319         if (n->data.dataBin && n->dataSize) {
320           memset(n->data.dataBin, 0, n->dataSize);
321           GWEN_Memory_dealloc(n->data.dataBin);
322         }
323         break;
324       case GWEN_DB_NodeType_ValuePtr:
325         n->data.dataPtr=NULL;
326         break;
327       case GWEN_DB_NodeType_ValueInt:
328         n->data.dataInt=0;
329         break;
330       default:
331         DBG_WARN(GWEN_LOGDOMAIN, "Unknown node type (%d)", n->typ);
332       }
333     }
334     else {
335       /* free dynamic (allocated) data */
336       switch (n->typ) {
337       case GWEN_DB_NodeType_Group:
338       case GWEN_DB_NodeType_Var:
339         GWEN_Memory_dealloc(n->data.dataName);
340         break;
341 
342       case GWEN_DB_NodeType_ValueChar:
343         GWEN_Memory_dealloc(n->data.dataChar);
344         break;
345       case GWEN_DB_NodeType_ValueBin:
346         GWEN_Memory_dealloc(n->data.dataBin);
347         break;
348       case GWEN_DB_NodeType_ValuePtr:
349       case GWEN_DB_NodeType_ValueInt:
350         break;
351       default:
352         DBG_WARN(GWEN_LOGDOMAIN, "Unknown node type (%d)", n->typ);
353       }
354     }
355 
356     DBG_VERBOUS(GWEN_LOGDOMAIN, "Freeing node itself");
357     GWEN_FREE_OBJECT(n);
358   }
359 }
360 
361 
362 
GWEN_DB_Node_dup(const GWEN_DB_NODE * n)363 GWEN_DB_NODE *GWEN_DB_Node_dup(const GWEN_DB_NODE *n)
364 {
365   GWEN_DB_NODE *nn;
366 
367   switch (n->typ) {
368   case GWEN_DB_NodeType_Group:
369     DBG_VERBOUS(GWEN_LOGDOMAIN, "Duplicating group \"%s\"",
370                 n->data.dataName);
371     nn=GWEN_DB_Group_new(n->data.dataName);
372     break;
373   case GWEN_DB_NodeType_Var:
374     DBG_VERBOUS(GWEN_LOGDOMAIN, "Duplicating variable \"%s\"",
375                 n->data.dataName);
376     nn=GWEN_DB_Var_new(n->data.dataName);
377     break;
378   case GWEN_DB_NodeType_ValueChar:
379     nn=GWEN_DB_ValueChar_new(n->data.dataChar);
380     break;
381   case GWEN_DB_NodeType_ValueBin:
382     nn=GWEN_DB_ValueBin_new(n->data.dataBin, n->dataSize);
383     break;
384   case GWEN_DB_NodeType_ValuePtr:
385     nn=GWEN_DB_ValuePtr_new(n->data.dataPtr);
386     break;
387   case GWEN_DB_NodeType_ValueInt:
388     nn=GWEN_DB_ValueInt_new(n->data.dataInt);
389     break;
390   default:
391     DBG_WARN(GWEN_LOGDOMAIN, "Unknown node type (%d)", n->typ);
392     nn=0;
393   }
394 
395   /* duplicate all children and add them to the new node */
396   if (nn) {
397     const GWEN_DB_NODE *cn;
398 
399     cn=GWEN_DB_Node_List_First(n->children);
400     while (cn) {
401       GWEN_DB_NODE *ncn;
402 
403       /* duplicate child and add it */
404       ncn=GWEN_DB_Node_dup(cn);
405       if (!ncn) {
406         GWEN_DB_Node_free(nn);
407         return NULL;
408       }
409       GWEN_DB_Node_Append_UnDirty(nn, ncn);
410       cn=GWEN_DB_Node_List_Next(cn);
411     } /* while cn */
412   }
413 
414   return nn;
415 }
416 
417 
418 
GWEN_DB_Group_free(GWEN_DB_NODE * n)419 void GWEN_DB_Group_free(GWEN_DB_NODE *n)
420 {
421   GWEN_DB_Node_free(n);
422 }
423 
424 
425 
GWEN_DB_Group_dup(const GWEN_DB_NODE * n)426 GWEN_DB_NODE *GWEN_DB_Group_dup(const GWEN_DB_NODE *n)
427 {
428   assert(n);
429   if (n->typ!=GWEN_DB_NodeType_Group) {
430     DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group");
431     return NULL;
432   }
433   return GWEN_DB_Node_dup(n);
434 }
435 
436 
437 
GWEN_DB_GetFirstGroup(GWEN_DB_NODE * n)438 GWEN_DB_NODE *GWEN_DB_GetFirstGroup(GWEN_DB_NODE *n)
439 {
440   GWEN_DB_NODE *nn;
441 
442   assert(n);
443   if (n->typ!=GWEN_DB_NodeType_Group) {
444     DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group");
445     return NULL;
446   }
447   assert(n->children);
448   nn=GWEN_DB_Node_List_First(n->children);
449   while (nn) {
450     if (nn->typ==GWEN_DB_NodeType_Group)
451       break;
452     nn=GWEN_DB_Node_List_Next(nn);
453   } /* while node */
454   return nn;
455 }
456 
457 
458 
GWEN_DB_GetNextGroup(GWEN_DB_NODE * n)459 GWEN_DB_NODE *GWEN_DB_GetNextGroup(GWEN_DB_NODE *n)
460 {
461   assert(n);
462   if (n->typ!=GWEN_DB_NodeType_Group) {
463     DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group");
464     return NULL;
465   }
466   n=GWEN_DB_Node_List_Next(n);
467   while (n) {
468     if (n->typ==GWEN_DB_NodeType_Group)
469       break;
470     n=GWEN_DB_Node_List_Next(n);
471   } /* while node */
472   return n;
473 }
474 
475 
476 
GWEN_DB_GetFirstVar(GWEN_DB_NODE * n)477 GWEN_DB_NODE *GWEN_DB_GetFirstVar(GWEN_DB_NODE *n)
478 {
479   GWEN_DB_NODE *nn;
480 
481   assert(n);
482   if (n->typ!=GWEN_DB_NodeType_Group) {
483     DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group");
484     return NULL;
485   }
486   assert(n->children);
487   nn=GWEN_DB_Node_List_First(n->children);
488   while (nn) {
489     if (nn->typ==GWEN_DB_NodeType_Var)
490       break;
491     nn=GWEN_DB_Node_List_Next(nn);
492   } /* while node */
493   return nn;
494 }
495 
496 
497 
GWEN_DB_GetNextVar(GWEN_DB_NODE * n)498 GWEN_DB_NODE *GWEN_DB_GetNextVar(GWEN_DB_NODE *n)
499 {
500   assert(n);
501   if (n->typ!=GWEN_DB_NodeType_Var) {
502     DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a variable");
503     return NULL;
504   }
505   n=GWEN_DB_Node_List_Next(n);
506   while (n) {
507     if (n->typ==GWEN_DB_NodeType_Var)
508       break;
509     n=GWEN_DB_Node_List_Next(n);
510   } /* while node */
511   return n;
512 }
513 
514 
515 
GWEN_DB_GetFirstValue(GWEN_DB_NODE * n)516 GWEN_DB_NODE *GWEN_DB_GetFirstValue(GWEN_DB_NODE *n)
517 {
518   GWEN_DB_NODE *nn;
519 
520   assert(n);
521   if (n->typ!=GWEN_DB_NodeType_Var) {
522     DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a variable");
523     return NULL;
524   }
525   assert(n->children);
526   nn=GWEN_DB_Node_List_First(n->children);
527   while (nn) {
528     if (nn->typ>=GWEN_DB_NodeType_ValueChar &&
529         nn->typ<GWEN_DB_NodeType_ValueLast) {
530       break;
531     }
532     nn=GWEN_DB_Node_List_Next(nn);
533   } /* while node */
534   return nn;
535 }
536 
537 
538 
GWEN_DB_GetNextValue(GWEN_DB_NODE * n)539 GWEN_DB_NODE *GWEN_DB_GetNextValue(GWEN_DB_NODE *n)
540 {
541   assert(n);
542   if (n->typ<GWEN_DB_NodeType_ValueChar ||
543       n->typ>=GWEN_DB_NodeType_ValueLast) {
544     DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a value");
545     return NULL;
546   }
547 
548   n=GWEN_DB_Node_List_Next(n);
549   while (n) {
550     if (n->typ>=GWEN_DB_NodeType_ValueChar &&
551         n->typ<GWEN_DB_NodeType_ValueLast) {
552       break;
553     }
554     n=GWEN_DB_Node_List_Next(n);
555   } /* while node */
556   return n;
557 }
558 
559 
560 
GWEN_DB_GetValueType(GWEN_DB_NODE * n)561 GWEN_DB_NODE_TYPE GWEN_DB_GetValueType(GWEN_DB_NODE *n)
562 {
563   assert(n);
564   if (n->typ>=GWEN_DB_NodeType_ValueChar &&
565       n->typ<GWEN_DB_NodeType_ValueLast) {
566     return n->typ;
567   }
568   else {
569     DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a value");
570     return GWEN_DB_NodeType_Unknown;
571   }
572 }
573 
574 
575 
GWEN_DB_GetCharValueFromNode(const GWEN_DB_NODE * n)576 const char *GWEN_DB_GetCharValueFromNode(const GWEN_DB_NODE *n)
577 {
578   assert(n);
579   if (n->typ!=GWEN_DB_NodeType_ValueChar) {
580     DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a char value");
581     return NULL;
582   }
583   return n->data.dataChar;
584 }
585 
586 
587 
GWEN_DB_SetCharValueInNode(GWEN_DB_NODE * n,const char * s)588 int GWEN_DB_SetCharValueInNode(GWEN_DB_NODE *n, const char *s)
589 {
590   assert(n);
591   assert(s);
592 
593   if (n->typ!=GWEN_DB_NodeType_ValueChar) {
594     DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a char value");
595     return GWEN_ERROR_INVALID;
596   }
597 
598   GWEN_Memory_dealloc(n->data.dataChar);
599   n->data.dataChar=GWEN_Memory_strdup(s);
600   return 0;
601 }
602 
603 
604 
GWEN_DB_GetIntValueFromNode(const GWEN_DB_NODE * n)605 int GWEN_DB_GetIntValueFromNode(const GWEN_DB_NODE *n)
606 {
607   const char *p;
608   int res;
609 
610   assert(n);
611 
612   switch (n->typ) {
613   case GWEN_DB_NodeType_ValueInt:
614     return n->data.dataInt;
615   case GWEN_DB_NodeType_ValueChar:
616     p=n->data.dataChar;
617     assert(p);
618     if (sscanf(p, "%d", &res)!=1) {
619       DBG_ERROR(GWEN_LOGDOMAIN, "String in node is not an int value");
620       return 0;
621     }
622     return res;
623 
624   default:
625     DBG_ERROR(GWEN_LOGDOMAIN, "Node is neither char nor int value");
626     return 0;
627   }
628 }
629 
630 
631 
GWEN_DB_GetBinValueFromNode(const GWEN_DB_NODE * n,unsigned int * size)632 const void *GWEN_DB_GetBinValueFromNode(const GWEN_DB_NODE *n,
633                                         unsigned int *size)
634 {
635   assert(n);
636 
637   if (n->typ!=GWEN_DB_NodeType_ValueBin) {
638     DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a binary value");
639     return NULL;
640   }
641 
642   *size=n->dataSize;
643   return n->data.dataBin;
644 }
645 
646 
647 
GWEN_DB_FindGroup(GWEN_DB_NODE * n,const char * name,int idx)648 GWEN_DB_NODE *GWEN_DB_FindGroup(GWEN_DB_NODE *n,
649                                 const char *name,
650                                 int idx)
651 {
652   GWEN_DB_NODE *nn;
653 
654   assert(n);
655   assert(name);
656 
657   if (n->typ!=GWEN_DB_NodeType_Group) {
658     DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group");
659     return NULL;
660   }
661 
662   /* find existing node */
663   assert(n->children);
664   nn=GWEN_DB_Node_List_First(n->children);
665   while (nn) {
666     if (nn->typ==GWEN_DB_NodeType_Group) {
667       if (strcasecmp(nn->data.dataName, name)==0) {
668         if (!idx)
669           /* ok, group found, return it */
670           return nn;
671         idx--;
672       } /* if entry found */
673     }
674     nn=GWEN_DB_Node_List_Next(nn);
675   } /* while node */
676 
677   return NULL;
678 }
679 
680 
681 
GWEN_DB_FindVar(GWEN_DB_NODE * n,const char * name,int idx)682 GWEN_DB_NODE *GWEN_DB_FindVar(GWEN_DB_NODE *n,
683                               const char *name,
684                               int idx)
685 {
686   GWEN_DB_NODE *nn;
687 
688   assert(n);
689   assert(name);
690 
691   if (n->typ!=GWEN_DB_NodeType_Group) {
692     DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group");
693     return NULL;
694   }
695 
696   /* find existing node */
697   assert(n->children);
698   nn=GWEN_DB_Node_List_First(n->children);
699   while (nn) {
700     if (nn->typ==GWEN_DB_NodeType_Var) {
701       if (strcasecmp(nn->data.dataName, name)==0) {
702         if (!idx)
703           /* ok, group found, return it */
704           return nn;
705         idx--;
706       } /* if entry found */
707     }
708     nn=GWEN_DB_Node_List_Next(nn);
709   } /* while node */
710 
711   return NULL;
712 }
713 
714 
715 
716 
717 
718 
719 
GWEN_DB_HandlePath(const char * entry,void * data,int idx,uint32_t flags)720 void *GWEN_DB_HandlePath(const char *entry,
721                          void *data,
722                          int idx,
723                          uint32_t flags)
724 {
725   GWEN_DB_NODE *n;
726   GWEN_DB_NODE *nn;
727 
728   n=(GWEN_DB_NODE *)data;
729 
730   /* check whether we are allowed to simply create the node */
731   if (
732     ((flags & GWEN_PATH_FLAGS_LAST) &&
733      (((flags & GWEN_PATH_FLAGS_VARIABLE) &&
734        (flags & GWEN_PATH_FLAGS_CREATE_VAR)) ||
735       (!(flags & GWEN_PATH_FLAGS_VARIABLE) &&
736        (flags & GWEN_PATH_FLAGS_CREATE_GROUP)))
737     ) ||
738     (
739       !(flags & GWEN_PATH_FLAGS_LAST) &&
740       (flags & GWEN_PATH_FLAGS_PATHCREATE))
741   ) {
742     /* simply create the new variable/group */
743     if (idx!=0) {
744       DBG_INFO(GWEN_LOGDOMAIN, "Index is not 0, not creating %s[%d]",
745                entry, idx);
746       return 0;
747     }
748     if (flags & GWEN_PATH_FLAGS_VARIABLE) {
749       DBG_VERBOUS(GWEN_LOGDOMAIN,
750                   "Unconditionally creating variable \"%s\"", entry);
751       nn=GWEN_DB_Var_new(entry);
752       if (flags & GWEN_DB_FLAGS_INSERT)
753         GWEN_DB_Node_Insert(n, nn);
754       else
755         GWEN_DB_Node_Append(n, nn);
756       return nn;
757     }
758     else {
759       DBG_VERBOUS(GWEN_LOGDOMAIN,
760                   "Unconditionally creating group \"%s\"", entry);
761       nn=GWEN_DB_Group_new(entry);
762       if (flags & GWEN_DB_FLAGS_INSERT)
763         GWEN_DB_Node_Insert(n, nn);
764       else
765         GWEN_DB_Node_Append(n, nn);
766       return nn;
767     }
768   }
769 
770   /* find the node */
771   if (flags & GWEN_PATH_FLAGS_VARIABLE) {
772     nn=GWEN_DB_FindVar(n, entry, idx);
773   }
774   else {
775     nn=GWEN_DB_FindGroup(n, entry, idx);
776   }
777 
778   if (!nn) {
779     /* node not found, check, if we are allowed to create it */
780     if (
781       (!(flags & GWEN_PATH_FLAGS_LAST) &&
782        (flags & GWEN_PATH_FLAGS_PATHMUSTEXIST)) ||
783       (flags & GWEN_PATH_FLAGS_NAMEMUSTEXIST)
784     ) {
785       if (flags & GWEN_PATH_FLAGS_VARIABLE) {
786         DBG_VERBOUS(GWEN_LOGDOMAIN,
787                     "Variable \"%s\" does not exist", entry);
788       }
789       else {
790         DBG_VERBOUS(GWEN_LOGDOMAIN,
791                     "Group \"%s\" does not exist", entry);
792       }
793       return 0;
794     }
795     /* create the new variable/group */
796     if (idx!=0) {
797       DBG_INFO(GWEN_LOGDOMAIN, "Index is not 0, not creating %s[%d]",
798                entry, idx);
799       return 0;
800     }
801     if (flags & GWEN_PATH_FLAGS_VARIABLE) {
802       DBG_VERBOUS(GWEN_LOGDOMAIN,
803                   "Variable \"%s\" not found, creating", entry);
804       nn=GWEN_DB_Var_new(entry);
805       if (flags & GWEN_DB_FLAGS_INSERT)
806         GWEN_DB_Node_Insert(n, nn);
807       else
808         GWEN_DB_Node_Append(n, nn);
809     }
810     else {
811       DBG_VERBOUS(GWEN_LOGDOMAIN,
812                   "Group \"%s\" not found, creating", entry);
813       nn=GWEN_DB_Group_new(entry);
814       if (flags & GWEN_DB_FLAGS_INSERT)
815         GWEN_DB_Node_Insert(n, nn);
816       else
817         GWEN_DB_Node_Append(n, nn);
818     }
819   } /* if node not found */
820   else {
821     /* node does exist, check whether this is ok */
822     if (
823       ((flags & GWEN_PATH_FLAGS_LAST) &&
824        (flags & GWEN_PATH_FLAGS_NAMEMUSTNOTEXIST)) ||
825       (!(flags & GWEN_PATH_FLAGS_LAST) &&
826        (flags & GWEN_PATH_FLAGS_PATHMUSTNOTEXIST))
827     ) {
828       DBG_VERBOUS(GWEN_LOGDOMAIN, "Entry \"%s\" already exists", entry);
829       return 0;
830     }
831   }
832 
833   return nn;
834 }
835 
836 
837 
GWEN_DB_GetNode(GWEN_DB_NODE * n,const char * path,uint32_t flags)838 GWEN_DB_NODE *GWEN_DB_GetNode(GWEN_DB_NODE *n,
839                               const char *path,
840                               uint32_t flags)
841 {
842   return (GWEN_DB_NODE *)GWEN_Path_HandleWithIdx(path,
843                                                  n,
844                                                  flags,
845                                                  GWEN_DB_HandlePath);
846 }
847 
848 
849 
GWEN_DB_ClearNode(GWEN_DB_NODE * n)850 void GWEN_DB_ClearNode(GWEN_DB_NODE *n)
851 {
852   assert(n);
853   if (n->children)
854     GWEN_DB_Node_List_Clear(n->children);
855 }
856 
857 
858 
GWEN_DB_GetValue(GWEN_DB_NODE * n,const char * path,int idx)859 GWEN_DB_NODE *GWEN_DB_GetValue(GWEN_DB_NODE *n,
860                                const char *path,
861                                int idx)
862 {
863   GWEN_DB_NODE *nn;
864 
865   /* find corresponding node */
866   nn=GWEN_DB_GetNode(n,
867                      path,
868                      GWEN_PATH_FLAGS_PATHMUSTEXIST |
869                      GWEN_PATH_FLAGS_NAMEMUSTEXIST |
870                      GWEN_PATH_FLAGS_VARIABLE);
871   if (!nn) {
872     DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not found",
873                 path);
874     return 0;
875   }
876 
877   /* find value */
878   assert(nn->children);
879   nn=GWEN_DB_Node_List_First(nn->children);
880   while (nn) {
881     if (nn->typ>=GWEN_DB_NodeType_ValueChar &&
882         nn->typ<GWEN_DB_NodeType_ValueLast) {
883       if (!idx)
884         return nn;
885       idx--;
886     }
887     nn=GWEN_DB_Node_List_Next(nn);
888   }
889 
890   DBG_VERBOUS(GWEN_LOGDOMAIN, "No value[%d] for path \"%s\"",
891               idx, path);
892   return NULL;
893 }
894 
895 
896 
GWEN_DB_DeleteVar(GWEN_DB_NODE * n,const char * path)897 int GWEN_DB_DeleteVar(GWEN_DB_NODE *n,
898                       const char *path)
899 {
900   GWEN_DB_NODE *nn;
901 
902   /* find corresponding node */
903   nn=GWEN_DB_GetNode(n,
904                      path,
905                      GWEN_PATH_FLAGS_PATHMUSTEXIST |
906                      GWEN_PATH_FLAGS_NAMEMUSTEXIST |
907                      GWEN_PATH_FLAGS_VARIABLE);
908   if (!nn) {
909     DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not found",
910                 path);
911     return 1;
912   }
913   GWEN_DB_Node_Unlink(nn);
914   GWEN_DB_Node_free(nn);
915   return 0;
916 }
917 
918 
919 
GWEN_DB_DeleteGroup(GWEN_DB_NODE * n,const char * path)920 int GWEN_DB_DeleteGroup(GWEN_DB_NODE *n,
921                         const char *path)
922 {
923   GWEN_DB_NODE *nn;
924 
925   /* find corresponding node */
926   nn=GWEN_DB_GetNode(n,
927                      path,
928                      GWEN_PATH_FLAGS_PATHMUSTEXIST |
929                      GWEN_PATH_FLAGS_NAMEMUSTEXIST);
930   if (!nn) {
931     DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not found",
932                 path);
933     return 1;
934   }
935   GWEN_DB_Node_Unlink(nn);
936   GWEN_DB_Node_free(nn);
937   return 0;
938 }
939 
940 
941 
GWEN_DB_ClearGroup(GWEN_DB_NODE * n,const char * path)942 int GWEN_DB_ClearGroup(GWEN_DB_NODE *n,
943                        const char *path)
944 {
945   assert(n);
946   if (path) {
947     GWEN_DB_NODE *nn;
948 
949     /* find corresponding node */
950     nn=GWEN_DB_GetNode(n,
951                        path,
952                        GWEN_PATH_FLAGS_PATHMUSTEXIST |
953                        GWEN_PATH_FLAGS_NAMEMUSTEXIST);
954     if (!nn) {
955       DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not found",
956                   path);
957       return 1;
958     }
959     GWEN_DB_ClearNode(nn);
960   }
961   else {
962     GWEN_DB_ClearNode(n);
963   }
964   return 0;
965 }
966 
967 
968 
GWEN_DB_GetCharValue(GWEN_DB_NODE * n,const char * path,int idx,const char * defVal)969 const char *GWEN_DB_GetCharValue(GWEN_DB_NODE *n,
970                                  const char *path,
971                                  int idx,
972                                  const char *defVal)
973 {
974   GWEN_DB_NODE *nn;
975 
976   nn=GWEN_DB_GetValue(n, path, idx);
977   if (!nn) {
978     DBG_VERBOUS(GWEN_LOGDOMAIN,
979                 "Value for \"%s\" not found, returning default value",
980                 path);
981     return defVal;
982   }
983   if (nn->typ!=GWEN_DB_NodeType_ValueChar) {
984     /* bad type */
985     DBG_VERBOUS(GWEN_LOGDOMAIN,
986                 "Bad type for path \"%s\", returning default value",
987                 path);
988     return defVal;
989   }
990   return nn->data.dataChar;
991 }
992 
993 
994 
GWEN_DB_SetCharValue(GWEN_DB_NODE * n,uint32_t flags,const char * path,const char * val)995 int GWEN_DB_SetCharValue(GWEN_DB_NODE *n,
996                          uint32_t flags,
997                          const char *path,
998                          const char *val)
999 {
1000   GWEN_DB_NODE *nn;
1001   GWEN_DB_NODE *nv;
1002 
1003   /* select/create node */
1004   nn=GWEN_DB_GetNode(n,
1005                      path,
1006                      flags | GWEN_PATH_FLAGS_VARIABLE);
1007   if (!nn) {
1008     DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available",
1009                 path);
1010     return 1;
1011   }
1012 
1013   nv=GWEN_DB_ValueChar_new(val);
1014 
1015   /* delete contents of this variable if wanted */
1016   if (flags & GWEN_DB_FLAGS_OVERWRITE_VARS) {
1017     DBG_VERBOUS(GWEN_LOGDOMAIN, "Clearing variable \"%s\"", path);
1018     GWEN_DB_ClearNode(nn);
1019   }
1020 
1021   /* add previously created value */
1022   if (flags & GWEN_DB_FLAGS_INSERT)
1023     GWEN_DB_Node_Insert(nn, nv);
1024   else
1025     GWEN_DB_Node_Append(nn, nv);
1026   DBG_VERBOUS(GWEN_LOGDOMAIN,
1027               "Added char value \"%s\" to variable \"%s\"", val, path);
1028 
1029   return 0;
1030 }
1031 
1032 
1033 
GWEN_DB_SetCharValueFromInt(GWEN_DB_NODE * n,uint32_t flags,const char * path,int val)1034 int GWEN_DB_SetCharValueFromInt(GWEN_DB_NODE *n,
1035                                 uint32_t flags,
1036                                 const char *path,
1037                                 int val)
1038 {
1039   GWEN_DB_NODE *nn;
1040   GWEN_DB_NODE *nv;
1041 
1042   /* select/create node */
1043   nn=GWEN_DB_GetNode(n, path, flags | GWEN_PATH_FLAGS_VARIABLE);
1044   if (!nn) {
1045     DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available",
1046                 path);
1047     return 1;
1048   }
1049 
1050   nv=GWEN_DB_ValueChar_newFromInt(val);
1051 
1052   /* delete contents of this variable if wanted */
1053   if (flags & GWEN_DB_FLAGS_OVERWRITE_VARS) {
1054     DBG_VERBOUS(GWEN_LOGDOMAIN, "Clearing variable \"%s\"", path);
1055     GWEN_DB_ClearNode(nn);
1056   }
1057 
1058   /* add previously created value */
1059   if (flags & GWEN_DB_FLAGS_INSERT)
1060     GWEN_DB_Node_Insert(nn, nv);
1061   else
1062     GWEN_DB_Node_Append(nn, nv);
1063   DBG_VERBOUS(GWEN_LOGDOMAIN,
1064               "Added char value \"%s\" to variable \"%s\"", val, path);
1065 
1066   return 0;
1067 }
1068 
1069 
1070 
GWEN_DB_AddCharValue(GWEN_DB_NODE * n,const char * path,const char * val,int senseCase,int check)1071 int GWEN_DB_AddCharValue(GWEN_DB_NODE *n,
1072                          const char *path,
1073                          const char *val,
1074                          int senseCase,
1075                          int check)
1076 {
1077   GWEN_DB_NODE *nn;
1078   GWEN_DB_NODE *nv;
1079 
1080   /* select/create node */
1081   nn=GWEN_DB_GetNode(n,
1082                      path,
1083                      GWEN_DB_FLAGS_DEFAULT | GWEN_PATH_FLAGS_VARIABLE);
1084   if (!nn) {
1085     DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available",
1086                 path);
1087     return -1;
1088   }
1089 
1090   if (check) {
1091     nv=GWEN_DB_GetFirstValue(n);
1092     if (nv && nv->typ==GWEN_DB_NodeType_ValueChar) {
1093       int res;
1094 
1095       assert(nv->data.dataChar);
1096       if (senseCase)
1097         res=strcasecmp(nv->data.dataChar, val)==0;
1098       else
1099         res=strcmp(nv->data.dataChar, val)==0;
1100       if (res) {
1101         DBG_DEBUG(GWEN_LOGDOMAIN,
1102                   "Value \"%s\" of var \"%s\" already exists",
1103                   val, path);
1104         return 1;
1105       }
1106     }
1107   } /* if check */
1108 
1109   nv=GWEN_DB_ValueChar_new(val);
1110   GWEN_DB_Node_Append(nn, nv);
1111   DBG_VERBOUS(GWEN_LOGDOMAIN,
1112               "Added char value \"%s\" to variable \"%s\"", val, path);
1113 
1114   return 0;
1115 }
1116 
1117 
1118 
GWEN_DB_RemoveCharValue(GWEN_DB_NODE * n,const char * path,const char * val,int senseCase)1119 int GWEN_DB_RemoveCharValue(GWEN_DB_NODE *n,
1120                             const char *path,
1121                             const char *val,
1122                             int senseCase)
1123 {
1124   GWEN_DB_NODE *nn;
1125   GWEN_DB_NODE *nv;
1126 
1127   /* select/create node */
1128   nn=GWEN_DB_GetNode(n,
1129                      path,
1130                      GWEN_DB_FLAGS_DEFAULT | GWEN_PATH_FLAGS_VARIABLE);
1131   if (!nn) {
1132     DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available",
1133                 path);
1134     return -1;
1135   }
1136 
1137   nv=GWEN_DB_GetFirstValue(n);
1138   if (nv && nv->typ==GWEN_DB_NodeType_ValueChar) {
1139     int res;
1140 
1141     assert(nv->data.dataChar);
1142     if (senseCase)
1143       res=strcasecmp(nv->data.dataChar, val)==0;
1144     else
1145       res=strcmp(nv->data.dataChar, val)==0;
1146     if (res) {
1147       DBG_DEBUG(GWEN_LOGDOMAIN,
1148                 "Value \"%s\" of var \"%s\" already exists",
1149                 val, path);
1150       GWEN_DB_Node_Unlink(nv);
1151       GWEN_DB_Node_free(nv);
1152       return 0;
1153     }
1154   }
1155 
1156   return 1;
1157 }
1158 
1159 
1160 
GWEN_DB_GetIntValue(GWEN_DB_NODE * n,const char * path,int idx,int defVal)1161 int GWEN_DB_GetIntValue(GWEN_DB_NODE *n,
1162                         const char *path,
1163                         int idx,
1164                         int defVal)
1165 {
1166   GWEN_DB_NODE *nn;
1167   const char *p;
1168   int res;
1169 
1170   assert(n);
1171   nn=GWEN_DB_GetValue(n, path, idx);
1172   if (!nn) {
1173     DBG_VERBOUS(GWEN_LOGDOMAIN,
1174                 "Value[%d] for \"%s\" not found, returning default value",
1175                 idx, path);
1176     return defVal;
1177   }
1178 
1179   switch (nn->typ) {
1180   case GWEN_DB_NodeType_ValueInt:
1181     return nn->data.dataInt;
1182   case GWEN_DB_NodeType_ValueChar:
1183     p=nn->data.dataChar;
1184     assert(p);
1185     if (sscanf(p, "%d", &res)!=1) {
1186       DBG_INFO(GWEN_LOGDOMAIN,
1187                "String [%s] in node [%s] is not an int value", p, path);
1188       return defVal;
1189     }
1190     return res;
1191 
1192   default:
1193     DBG_ERROR(GWEN_LOGDOMAIN, "Node is neither char nor int value");
1194     return defVal;
1195   }
1196 }
1197 
1198 
1199 
GWEN_DB_SetIntValue(GWEN_DB_NODE * n,uint32_t flags,const char * path,int val)1200 int GWEN_DB_SetIntValue(GWEN_DB_NODE *n,
1201                         uint32_t flags,
1202                         const char *path,
1203                         int val)
1204 {
1205   GWEN_DB_NODE *nn;
1206   GWEN_DB_NODE *nv;
1207 
1208   /* select/create node */
1209   nn=GWEN_DB_GetNode(n,
1210                      path,
1211                      flags | GWEN_PATH_FLAGS_VARIABLE);
1212   if (!nn) {
1213     DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available",
1214                 path);
1215     return 1;
1216   }
1217 
1218   /* delete contents of this variable if wanted */
1219   if (flags & GWEN_DB_FLAGS_OVERWRITE_VARS) {
1220     DBG_VERBOUS(GWEN_LOGDOMAIN, "Clearing variable \"%s\"", path);
1221     GWEN_DB_ClearNode(nn);
1222   }
1223 
1224   nv=GWEN_DB_ValueInt_new(val);
1225   if (flags & GWEN_DB_FLAGS_INSERT)
1226     GWEN_DB_Node_Insert(nn, nv);
1227   else
1228     GWEN_DB_Node_Append(nn, nv);
1229   DBG_VERBOUS(GWEN_LOGDOMAIN, "Added int value \"%d\" to variable \"%s\"", val, path);
1230   return 0;
1231 }
1232 
1233 
1234 
GWEN_DB_GetBinValue(GWEN_DB_NODE * n,const char * path,int idx,const void * defVal,unsigned int defValSize,unsigned int * returnValueSize)1235 const void *GWEN_DB_GetBinValue(GWEN_DB_NODE *n,
1236                                 const char *path,
1237                                 int idx,
1238                                 const void *defVal,
1239                                 unsigned int defValSize,
1240                                 unsigned int *returnValueSize)
1241 {
1242   GWEN_DB_NODE *nn;
1243 
1244   assert(returnValueSize);
1245   nn=GWEN_DB_GetValue(n, path, idx);
1246   if (!nn) {
1247     DBG_VERBOUS(GWEN_LOGDOMAIN,
1248                 "Value for \"%s\" not found, returning default value",
1249                 path);
1250     *returnValueSize=defValSize;
1251     return defVal;
1252   }
1253   if (nn->typ!=GWEN_DB_NodeType_ValueBin) {
1254     /* bad type */
1255     DBG_VERBOUS(GWEN_LOGDOMAIN,
1256                 "Bad type for path \"%s\", returning default value",
1257                 path);
1258     *returnValueSize=defValSize;
1259     return defVal;
1260   }
1261   *returnValueSize=nn->dataSize;
1262   return nn->data.dataBin;
1263 }
1264 
1265 
1266 
GWEN_DB_SetBinValue(GWEN_DB_NODE * n,uint32_t flags,const char * path,const void * val,unsigned int valSize)1267 int GWEN_DB_SetBinValue(GWEN_DB_NODE *n,
1268                         uint32_t flags,
1269                         const char *path,
1270                         const void *val,
1271                         unsigned int valSize)
1272 {
1273   GWEN_DB_NODE *nn;
1274   GWEN_DB_NODE *nv;
1275 
1276   assert(val);
1277   /* select/create node */
1278   nn=GWEN_DB_GetNode(n,
1279                      path,
1280                      flags | GWEN_PATH_FLAGS_VARIABLE);
1281   if (!nn) {
1282     DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available",
1283                 path);
1284     return 1;
1285   }
1286 
1287   /* delete contents of this variable if wanted */
1288   if (flags & GWEN_DB_FLAGS_OVERWRITE_VARS) {
1289     DBG_VERBOUS(GWEN_LOGDOMAIN, "Clearing variable \"%s\"", path);
1290     GWEN_DB_ClearNode(nn);
1291   }
1292 
1293   nv=GWEN_DB_ValueBin_new(val, valSize);
1294   if (flags & GWEN_DB_FLAGS_INSERT)
1295     GWEN_DB_Node_Insert(nn, nv);
1296   else
1297     GWEN_DB_Node_Append(nn, nv);
1298   DBG_VERBOUS(GWEN_LOGDOMAIN, "Added bin value to variable \"%s\"", path);
1299   return 0;
1300 }
1301 
1302 
1303 
GWEN_DB_GetPtrValue(GWEN_DB_NODE * n,const char * path,int idx,void * defVal)1304 void *GWEN_DB_GetPtrValue(GWEN_DB_NODE *n,
1305                           const char *path,
1306                           int idx,
1307                           void *defVal)
1308 {
1309   GWEN_DB_NODE *nn;
1310 
1311   nn=GWEN_DB_GetValue(n, path, idx);
1312   if (!nn) {
1313     DBG_VERBOUS(GWEN_LOGDOMAIN,
1314                 "Value for \"%s\" not found, returning default value",
1315                 path);
1316     return defVal;
1317   }
1318   if (nn->typ!=GWEN_DB_NodeType_ValuePtr) {
1319     /* bad type */
1320     DBG_VERBOUS(GWEN_LOGDOMAIN,
1321                 "Bad type for path \"%s\", returning default value",
1322                 path);
1323     return defVal;
1324   }
1325   return nn->data.dataPtr;
1326 }
1327 
1328 
1329 
GWEN_DB_SetPtrValue(GWEN_DB_NODE * n,uint32_t flags,const char * path,void * val)1330 int GWEN_DB_SetPtrValue(GWEN_DB_NODE *n,
1331                         uint32_t flags,
1332                         const char *path,
1333                         void *val)
1334 {
1335   GWEN_DB_NODE *nn;
1336   GWEN_DB_NODE *nv;
1337 
1338   /* select/create node */
1339   nn=GWEN_DB_GetNode(n,
1340                      path,
1341                      flags | GWEN_PATH_FLAGS_VARIABLE);
1342   if (!nn) {
1343     DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available",
1344                 path);
1345     return 1;
1346   }
1347 
1348   /* delete contents of this variable if wanted */
1349   if (flags & GWEN_DB_FLAGS_OVERWRITE_VARS) {
1350     DBG_VERBOUS(GWEN_LOGDOMAIN, "Clearing variable \"%s\"", path);
1351     GWEN_DB_ClearNode(nn);
1352   }
1353 
1354   nv=GWEN_DB_ValuePtr_new(val);
1355   if (flags & GWEN_DB_FLAGS_INSERT)
1356     GWEN_DB_Node_Insert(nn, nv);
1357   else
1358     GWEN_DB_Node_Append(nn, nv);
1359   DBG_VERBOUS(GWEN_LOGDOMAIN, "Added ptr value to variable \"%s\"", path);
1360 
1361   return 0;
1362 }
1363 
1364 
1365 
1366 
1367 
1368 
1369 
1370 
1371 
1372 
1373 
1374 
1375 
1376 
1377 
1378 
GWEN_DB_GetGroup(GWEN_DB_NODE * n,uint32_t flags,const char * path)1379 GWEN_DB_NODE *GWEN_DB_GetGroup(GWEN_DB_NODE *n,
1380                                uint32_t flags,
1381                                const char *path)
1382 {
1383   GWEN_DB_NODE *nn;
1384 
1385   /* select/create node */
1386   nn=GWEN_DB_GetNode(n,
1387                      path,
1388                      flags & ~GWEN_PATH_FLAGS_VARIABLE);
1389   if (!nn) {
1390     DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available",
1391                 path);
1392     return NULL;
1393   }
1394 
1395   /* delete contents of this variable if wanted */
1396   if (flags & GWEN_DB_FLAGS_OVERWRITE_GROUPS) {
1397     DBG_VERBOUS(GWEN_LOGDOMAIN, "Clearing group \"%s\"", path);
1398     GWEN_DB_ClearNode(nn);
1399   }
1400 
1401   return nn;
1402 }
1403 
1404 
1405 
GWEN_DB_GroupName(GWEN_DB_NODE * n)1406 const char *GWEN_DB_GroupName(GWEN_DB_NODE *n)
1407 {
1408   assert(n);
1409   if (n->typ!=GWEN_DB_NodeType_Group) {
1410     DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group");
1411     return NULL;
1412   }
1413   return n->data.dataName;
1414 }
1415 
1416 
1417 
GWEN_DB_Dump(GWEN_DB_NODE * n,int insert)1418 void GWEN_DB_Dump(GWEN_DB_NODE *n, int insert)
1419 {
1420   if (n) {
1421     int i;
1422 
1423     for (i=0; i<insert; i++)
1424       fprintf(stderr, " ");
1425 
1426     /* dump dynamic (allocated) data */
1427     switch (n->typ) {
1428     case GWEN_DB_NodeType_Group:
1429       fprintf(stderr, "Group : \"%s\"\n", n->data.dataName);
1430       break;
1431     case GWEN_DB_NodeType_Var:
1432       fprintf(stderr, "Var   : \"%s\"\n", n->data.dataName);
1433       break;
1434     case GWEN_DB_NodeType_ValueChar:
1435       fprintf(stderr, "Value : \"%s\" (char)\n", n->data.dataChar);
1436       break;
1437     case GWEN_DB_NodeType_ValueInt:
1438       fprintf(stderr, "Value : %d (int)\n", n->data.dataInt);
1439       break;
1440     case GWEN_DB_NodeType_ValueBin: {
1441       char *buffer;
1442 
1443       buffer=(char *)GWEN_Memory_malloc((n->dataSize*2)+1);
1444       assert(buffer);
1445       if (GWEN_Text_ToHex(n->data.dataBin, n->dataSize,
1446                           buffer, (n->dataSize*2)+1)==0) {
1447         fprintf(stderr, "Value : %d bytes (bin)\n", n->dataSize);
1448       }
1449       else {
1450         fprintf(stderr, "Value : %s (bin)\n", buffer);
1451       }
1452       GWEN_Memory_dealloc(buffer);
1453       break;
1454     }
1455     case GWEN_DB_NodeType_ValuePtr:
1456       fprintf(stderr, "Value : %p (ptr)\n", n->data.dataPtr);
1457       break;
1458     default:
1459       fprintf(stderr, "[unknown node type %d]\n", n->typ);
1460     }
1461 
1462     /* dump children */
1463     if (n->children) {
1464       GWEN_DB_NODE *cn;
1465 
1466       cn=GWEN_DB_Node_List_First(n->children);
1467       while (cn) {
1468         GWEN_DB_Dump(cn, insert+4);
1469         cn=GWEN_DB_Node_List_Next(cn);
1470       }
1471     }
1472   }
1473   else {
1474     fprintf(stderr, "[no node]\n");
1475   }
1476 }
1477 
1478 
1479 
GWEN_DB_AddGroup(GWEN_DB_NODE * n,GWEN_DB_NODE * nn)1480 int GWEN_DB_AddGroup(GWEN_DB_NODE *n, GWEN_DB_NODE *nn)
1481 {
1482   assert(n);
1483   assert(nn);
1484 
1485   if (n->typ!=GWEN_DB_NodeType_Group) {
1486     DBG_ERROR(GWEN_LOGDOMAIN, "Target node is not a group");
1487     return 0;
1488   }
1489 
1490   if (nn->typ!=GWEN_DB_NodeType_Group) {
1491     DBG_ERROR(GWEN_LOGDOMAIN, "Source node is not a group");
1492     return 0;
1493   }
1494 
1495   GWEN_DB_Node_Append(n, nn);
1496   return 0;
1497 }
1498 
1499 
1500 
GWEN_DB_InsertGroup(GWEN_DB_NODE * n,GWEN_DB_NODE * nn)1501 int GWEN_DB_InsertGroup(GWEN_DB_NODE *n, GWEN_DB_NODE *nn)
1502 {
1503   assert(n);
1504   assert(nn);
1505 
1506   if (n->typ!=GWEN_DB_NodeType_Group) {
1507     DBG_ERROR(GWEN_LOGDOMAIN, "Target node is not a group");
1508     return 0;
1509   }
1510 
1511   if (nn->typ!=GWEN_DB_NodeType_Group) {
1512     DBG_ERROR(GWEN_LOGDOMAIN, "Source node is not a group");
1513     return 0;
1514   }
1515 
1516   GWEN_DB_Node_Insert(n, nn);
1517   return 0;
1518 }
1519 
1520 
1521 
GWEN_DB_AddGroupChildren(GWEN_DB_NODE * n,GWEN_DB_NODE * nn)1522 int GWEN_DB_AddGroupChildren(GWEN_DB_NODE *n, GWEN_DB_NODE *nn)
1523 {
1524   GWEN_DB_NODE *cpn;
1525 
1526   assert(n);
1527   assert(nn);
1528 
1529   if (n->typ!=GWEN_DB_NodeType_Group) {
1530     DBG_ERROR(GWEN_LOGDOMAIN, "Target node is not a group");
1531     return -1;
1532   }
1533 
1534   if (nn->typ!=GWEN_DB_NodeType_Group) {
1535     DBG_ERROR(GWEN_LOGDOMAIN, "Source node is not a group");
1536     GWEN_DB_Dump(nn, 1);
1537     return -1;
1538   }
1539 
1540   nn=GWEN_DB_Node_List_First(nn->children);
1541   while (nn) {
1542     DBG_VERBOUS(GWEN_LOGDOMAIN, "Duplicating node");
1543     cpn=GWEN_DB_Node_dup(nn);
1544     GWEN_DB_Node_Append(n, cpn);
1545     nn=GWEN_DB_Node_List_Next(nn);
1546   } /* while */
1547   return 0;
1548 }
1549 
1550 
1551 
GWEN_DB_UnlinkGroup(GWEN_DB_NODE * n)1552 void GWEN_DB_UnlinkGroup(GWEN_DB_NODE *n)
1553 {
1554   assert(n);
1555   if (n->typ!=GWEN_DB_NodeType_Group) {
1556     DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group");
1557     return;
1558   }
1559   GWEN_DB_Node_Unlink(n);
1560 }
1561 
1562 
GWEN_DB_VariableExists(GWEN_DB_NODE * n,const char * path)1563 int GWEN_DB_VariableExists(GWEN_DB_NODE *n, const char *path)
1564 {
1565   GWEN_DB_NODE *nn;
1566 
1567   /* find corresponding node */
1568   assert(n);
1569   nn=GWEN_DB_GetNode(n,
1570                      path,
1571                      GWEN_PATH_FLAGS_PATHMUSTEXIST |
1572                      GWEN_PATH_FLAGS_NAMEMUSTEXIST |
1573                      GWEN_PATH_FLAGS_VARIABLE);
1574   if (!nn) {
1575     DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not found", path);
1576     return 0;
1577   }
1578 
1579   return 1;
1580 }
1581 
1582 
1583 
GWEN_DB_ValueExists(GWEN_DB_NODE * n,const char * path,unsigned int i)1584 int GWEN_DB_ValueExists(GWEN_DB_NODE *n,
1585                         const char *path,
1586                         unsigned int i)
1587 {
1588   return (GWEN_DB_GetValue(n, path, i)!=0);
1589 }
1590 
1591 
1592 
GWEN_DB_GetVariableType(GWEN_DB_NODE * n,const char * p)1593 GWEN_DB_NODE_TYPE GWEN_DB_GetVariableType(GWEN_DB_NODE *n,
1594                                           const char *p)
1595 {
1596   GWEN_DB_NODE *nn;
1597 
1598   nn=GWEN_DB_FindVar(n, p, 0);
1599   if (!nn)
1600     return GWEN_DB_NodeType_Unknown;
1601 
1602   nn=GWEN_DB_GetFirstValue(nn);
1603   if (!nn)
1604     return GWEN_DB_NodeType_Unknown;
1605   return GWEN_DB_GetValueType(nn);
1606 }
1607 
1608 
1609 
GWEN_DB_GetValueTypeByPath(GWEN_DB_NODE * n,const char * path,unsigned int i)1610 GWEN_DB_NODE_TYPE GWEN_DB_GetValueTypeByPath(GWEN_DB_NODE *n,
1611                                              const char *path,
1612                                              unsigned int i)
1613 {
1614   GWEN_DB_NODE *nn;
1615 
1616   nn=GWEN_DB_GetValue(n, path, i);
1617   if (!nn)
1618     return GWEN_DB_NodeType_Unknown;
1619   return GWEN_DB_GetValueType(nn);
1620 }
1621 
1622 
GWEN_DB_GroupRename(GWEN_DB_NODE * n,const char * newname)1623 void GWEN_DB_GroupRename(GWEN_DB_NODE *n, const char *newname)
1624 {
1625   assert(n);
1626   assert(newname);
1627   assert(n->typ==GWEN_DB_NodeType_Group);
1628   GWEN_Memory_dealloc(n->data.dataName);
1629   n->data.dataName=GWEN_Memory_strdup(newname);
1630 }
1631 
1632 
1633 
1634 
1635 
1636 
1637 
GWEN_DB_IsGroup(const GWEN_DB_NODE * n)1638 int GWEN_DB_IsGroup(const GWEN_DB_NODE *n)
1639 {
1640   assert(n);
1641   return n->typ==GWEN_DB_NodeType_Group;
1642 }
1643 
1644 
1645 
GWEN_DB_IsVariable(const GWEN_DB_NODE * n)1646 int GWEN_DB_IsVariable(const GWEN_DB_NODE *n)
1647 {
1648   assert(n);
1649   return n->typ==GWEN_DB_NodeType_Var;
1650 }
1651 
1652 
1653 
GWEN_DB_IsValue(const GWEN_DB_NODE * n)1654 int GWEN_DB_IsValue(const GWEN_DB_NODE *n)
1655 {
1656   assert(n);
1657   return (n->typ>=GWEN_DB_NodeType_ValueChar &&
1658           n->typ>=GWEN_DB_NodeType_ValueLast);
1659 }
1660 
1661 
1662 
GWEN_DB_Groups_Foreach(GWEN_DB_NODE * node,GWEN_DB_NODES_CB func,void * user_data)1663 void *GWEN_DB_Groups_Foreach(GWEN_DB_NODE *node, GWEN_DB_NODES_CB func,
1664                              void *user_data)
1665 {
1666   GWEN_DB_NODE *iter;
1667   void *res;
1668 
1669   assert(node);
1670   assert(func);
1671 
1672   iter=GWEN_DB_GetFirstGroup(node);
1673   res=NULL;
1674   while (iter) {
1675     res=(*func)(iter, user_data);
1676     if (res) {
1677       break;
1678     }
1679     iter=GWEN_DB_GetNextGroup(iter);
1680   }
1681   return res;
1682 }
1683 
1684 
1685 
GWEN_DB_count_cb(GWEN_UNUSED GWEN_DB_NODE * node,void * user_data)1686 void *GWEN_DB_count_cb(GWEN_UNUSED GWEN_DB_NODE *node, void *user_data)
1687 {
1688   unsigned int *a = user_data;
1689   ++(*a);
1690   return NULL;
1691 }
1692 
1693 
1694 
GWEN_DB_Groups_Count(const GWEN_DB_NODE * node)1695 unsigned int GWEN_DB_Groups_Count(const GWEN_DB_NODE *node)
1696 {
1697   unsigned int res = 0;
1698   GWEN_DB_Groups_Foreach((GWEN_DB_NODE *)node, GWEN_DB_count_cb, &res);
1699   return res;
1700 }
1701 
1702 
1703 
GWEN_DB_Variables_Foreach(GWEN_DB_NODE * node,GWEN_DB_NODES_CB func,void * user_data)1704 void *GWEN_DB_Variables_Foreach(GWEN_DB_NODE *node, GWEN_DB_NODES_CB func,
1705                                 void *user_data)
1706 {
1707   GWEN_DB_NODE *iter;
1708   void *res;
1709 
1710   assert(node);
1711   assert(func);
1712 
1713   iter=GWEN_DB_GetFirstVar(node);
1714   res=NULL;
1715   while (iter) {
1716     res=(*func)(iter, user_data);
1717     if (res) {
1718       break;
1719     }
1720     iter=GWEN_DB_GetNextVar(iter);
1721   }
1722   return res;
1723 }
1724 
1725 
1726 
GWEN_DB_Variables_Count(const GWEN_DB_NODE * node)1727 unsigned int GWEN_DB_Variables_Count(const GWEN_DB_NODE *node)
1728 {
1729   unsigned int res = 0;
1730   GWEN_DB_Variables_Foreach((GWEN_DB_NODE *)node, GWEN_DB_count_cb, &res);
1731   return res;
1732 }
1733 
1734 
1735 
GWEN_DB_Values_Foreach(GWEN_DB_NODE * node,GWEN_DB_NODES_CB func,void * user_data)1736 void *GWEN_DB_Values_Foreach(GWEN_DB_NODE *node, GWEN_DB_NODES_CB func,
1737                              void *user_data)
1738 {
1739   GWEN_DB_NODE *iter;
1740   void *res;
1741 
1742   assert(node);
1743   assert(func);
1744 
1745   iter=GWEN_DB_GetFirstValue(node);
1746   res=NULL;
1747   while (iter) {
1748     res=(*func)(iter, user_data);
1749     if (res) {
1750       break;
1751     }
1752     iter=GWEN_DB_GetNextValue(iter);
1753   }
1754   return res;
1755 }
1756 
1757 
1758 
GWEN_DB_Values_Count(const GWEN_DB_NODE * node)1759 unsigned int GWEN_DB_Values_Count(const GWEN_DB_NODE *node)
1760 {
1761   unsigned int res = 0;
1762   GWEN_DB_Values_Foreach((GWEN_DB_NODE *)node, GWEN_DB_count_cb, &res);
1763   return res;
1764 }
1765 
1766 
1767 
GWEN_DB_GetNodeFlags(const GWEN_DB_NODE * n)1768 uint32_t GWEN_DB_GetNodeFlags(const GWEN_DB_NODE *n)
1769 {
1770   assert(n);
1771   return n->nodeFlags;
1772 }
1773 
1774 
1775 
GWEN_DB_SetNodeFlags(GWEN_DB_NODE * n,uint32_t flags)1776 void GWEN_DB_SetNodeFlags(GWEN_DB_NODE *n,
1777                           uint32_t flags)
1778 {
1779   assert(n);
1780   n->nodeFlags=flags;
1781 }
1782 
1783 
1784 
GWEN_DB_ModifyBranchFlagsUp(GWEN_DB_NODE * n,uint32_t newflags,uint32_t mask)1785 void GWEN_DB_ModifyBranchFlagsUp(GWEN_DB_NODE *n,
1786                                  uint32_t newflags,
1787                                  uint32_t mask)
1788 {
1789   uint32_t flags;
1790 
1791   assert(n);
1792 
1793   while (n) {
1794     flags=n->nodeFlags;
1795     flags=((flags^newflags)&(mask))^flags;
1796     n->nodeFlags=flags;
1797     n=n->parent;
1798   } /* while */
1799 }
1800 
1801 
1802 
GWEN_DB_ModifyBranchFlagsDown(GWEN_DB_NODE * n,uint32_t newflags,uint32_t mask)1803 void GWEN_DB_ModifyBranchFlagsDown(GWEN_DB_NODE *n,
1804                                    uint32_t newflags,
1805                                    uint32_t mask)
1806 {
1807   uint32_t flags;
1808   GWEN_DB_NODE *cn;
1809 
1810   assert(n);
1811 
1812   flags=n->nodeFlags;
1813   flags=((flags^newflags)&(mask))^flags;
1814   n->nodeFlags=flags;
1815 
1816   cn=GWEN_DB_Node_List_First(n->children);
1817   while (cn) {
1818     GWEN_DB_ModifyBranchFlagsDown(cn, newflags, mask);
1819     cn=GWEN_DB_Node_List_Next(cn);
1820   } /* while cn */
1821 }
1822 
1823 
1824 
GWEN_DB_GetParentGroup(GWEN_DB_NODE * n)1825 GWEN_DB_NODE *GWEN_DB_GetParentGroup(GWEN_DB_NODE *n)
1826 {
1827   GWEN_DB_NODE *nn;
1828 
1829   assert(n);
1830   nn=n->parent;
1831   while (nn && nn->typ!=GWEN_DB_NodeType_Group)
1832     nn=nn->parent;
1833   return nn;
1834 }
1835 
1836 
1837 
GWEN_DB_FindFirstGroup(GWEN_DB_NODE * n,const char * name)1838 GWEN_DB_NODE *GWEN_DB_FindFirstGroup(GWEN_DB_NODE *n, const char *name)
1839 {
1840   GWEN_DB_NODE *nn;
1841 
1842   assert(n);
1843   if (n->typ!=GWEN_DB_NodeType_Group) {
1844     DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group");
1845     return NULL;
1846   }
1847   nn=GWEN_DB_Node_List_First(n->children);
1848   while (nn) {
1849     if ((nn->typ==GWEN_DB_NodeType_Group) &&
1850         (-1!=GWEN_Text_ComparePattern(nn->data.dataName, name, 0)))
1851       break;
1852     nn=GWEN_DB_Node_List_Next(nn);
1853   } /* while node */
1854   return nn;
1855 }
1856 
1857 
1858 
GWEN_DB_FindNextGroup(GWEN_DB_NODE * n,const char * name)1859 GWEN_DB_NODE *GWEN_DB_FindNextGroup(GWEN_DB_NODE *n, const char *name)
1860 {
1861   GWEN_DB_NODE *og;
1862 
1863   og=n;
1864   assert(n);
1865   if (n->typ!=GWEN_DB_NodeType_Group) {
1866     DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group");
1867     return NULL;
1868   }
1869   n=GWEN_DB_GetNextGroup(n);
1870   while (n) {
1871     if (-1!=GWEN_Text_ComparePattern(n->data.dataName, name, 0))
1872       break;
1873     n=GWEN_DB_GetNextGroup(n);
1874   } /* while node */
1875   assert(n!=og);
1876   return n;
1877 }
1878 
1879 
1880 
GWEN_DB_FindFirstVar(GWEN_DB_NODE * n,const char * name)1881 GWEN_DB_NODE *GWEN_DB_FindFirstVar(GWEN_DB_NODE *n, const char *name)
1882 {
1883   GWEN_DB_NODE *nn;
1884 
1885   assert(n);
1886   if (n->typ!=GWEN_DB_NodeType_Group) {
1887     DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group");
1888     return NULL;
1889   }
1890 
1891   nn=GWEN_DB_Node_List_First(n->children);
1892   while (nn) {
1893     if ((nn->typ==GWEN_DB_NodeType_Var) &&
1894         (-1!=GWEN_Text_ComparePattern(nn->data.dataName, name, 0)))
1895       break;
1896     nn=GWEN_DB_Node_List_Next(nn);
1897   } /* while node */
1898 
1899   return nn;
1900 }
1901 
1902 
1903 
GWEN_DB_FindNextVar(GWEN_DB_NODE * n,const char * name)1904 GWEN_DB_NODE *GWEN_DB_FindNextVar(GWEN_DB_NODE *n, const char *name)
1905 {
1906   GWEN_DB_NODE *og;
1907 
1908   og=n;
1909   assert(n);
1910   if (n->typ!=GWEN_DB_NodeType_Var) {
1911     DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a variable");
1912     return NULL;
1913   }
1914   n=GWEN_DB_GetNextVar(n);
1915   while (n) {
1916     if (-1!=GWEN_Text_ComparePattern(n->data.dataName, name, 0))
1917       break;
1918     n=GWEN_DB_GetNextVar(n);
1919   } /* while node */
1920   assert(n!=og);
1921   return n;
1922 }
1923 
1924 
1925 
GWEN_DB_VariableName(GWEN_DB_NODE * n)1926 const char *GWEN_DB_VariableName(GWEN_DB_NODE *n)
1927 {
1928   assert(n);
1929   if (n->typ!=GWEN_DB_NodeType_Var) {
1930     DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a variable");
1931     return NULL;
1932   }
1933   return n->data.dataName;
1934 }
1935 
1936 
1937 
GWEN_DB_VariableRename(GWEN_DB_NODE * n,const char * newname)1938 void GWEN_DB_VariableRename(GWEN_DB_NODE *n, const char *newname)
1939 {
1940   assert(n);
1941   assert(newname);
1942   assert(n->typ==GWEN_DB_NodeType_Var);
1943   GWEN_Memory_dealloc(n->data.dataName);
1944   n->data.dataName=GWEN_Memory_strdup(newname);
1945 }
1946 
1947 
1948 
GWEN_DB_ReplaceVars(GWEN_DB_NODE * db,const char * s,GWEN_BUFFER * dbuf)1949 int GWEN_DB_ReplaceVars(GWEN_DB_NODE *db, const char *s, GWEN_BUFFER *dbuf)
1950 {
1951   int rv;
1952 
1953   rv=GWEN_Text_ReplaceVars(s, dbuf, _replaceVarsCb, db);
1954   if (rv<0) {
1955     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1956     return rv;
1957   }
1958   return 0;
1959 }
1960 
1961 
1962 
_replaceVarsCb(void * cbPtr,const char * name,int index,GWEN_UNUSED int maxLen,GWEN_BUFFER * dstBuf)1963 int GWENHYWFAR_CB _replaceVarsCb(void *cbPtr, const char *name, int index, GWEN_UNUSED int maxLen, GWEN_BUFFER *dstBuf)
1964 {
1965   GWEN_DB_NODE *db;
1966   int rv;
1967 
1968   db=(GWEN_DB_NODE *) cbPtr;
1969   rv=GWEN_DB_WriteVarValueToBuffer(db, name, index, dstBuf);
1970   if (rv<0) {
1971     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1972     return rv;
1973   }
1974 
1975   return 0;
1976 }
1977 
1978 
1979 
GWEN_DB_WriteVarValueToBuffer(GWEN_DB_NODE * db,const char * name,int index,GWEN_BUFFER * dstBuf)1980 int GWEN_DB_WriteVarValueToBuffer(GWEN_DB_NODE *db, const char *name, int index, GWEN_BUFFER *dstBuf)
1981 {
1982   const char *valueString;
1983   int valueInt;
1984   char numbuf[32];
1985   int rv;
1986   GWEN_DB_NODE_TYPE valType;
1987 
1988   assert(db);
1989 
1990   /*valType=GWEN_DB_GetVariableType(db, name);*/
1991   DBG_DEBUG(GWEN_LOGDOMAIN, "Get value for %s[%i]", name, index);
1992   valType=GWEN_DB_GetValueTypeByPath(db, name, index);
1993   switch (valType) { /* GWEN_DB_GetVariableType */
1994   case GWEN_DB_NodeType_ValueInt:
1995     valueInt=GWEN_DB_GetIntValue(db, name, index, 0);
1996     rv=GWEN_Text_NumToString(valueInt, numbuf, sizeof(numbuf)-1, 0);
1997     if (rv>=0)
1998       GWEN_Buffer_AppendString(dstBuf, numbuf);
1999     break;
2000   case GWEN_DB_NodeType_ValueChar:
2001     valueString=GWEN_DB_GetCharValue(db, name, index, NULL);
2002     if (valueString)
2003       GWEN_Buffer_AppendString(dstBuf, valueString);
2004     break;
2005 
2006   case GWEN_DB_NodeType_Unknown:
2007   default:
2008     return GWEN_ERROR_NO_DATA;
2009   }
2010 
2011   return 0;
2012 }
2013 
2014 
2015 
2016 #include "dbrw.c"
2017 
2018 
2019 
2020 
2021 
2022 
2023 
2024 
2025 
2026