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