gwenhywfar  5.4.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 
73 
74 /* ------------------------------------------------------------------------------------------------
75  * implementations
76  * ------------------------------------------------------------------------------------------------
77  */
78 
79 
80 
81 
82 GWEN_LIST_FUNCTIONS(GWEN_DB_NODE, GWEN_DB_Node)
83 
84 
85 
87 {
88  GWEN_DB_NODE *node;
89 
92  node->typ=t;
93  return (GWEN_DB_NODE *)node;
94 }
95 
96 
97 
98 
100  unsigned int datasize)
101 {
102  GWEN_DB_NODE *n;
103 
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 
118 {
119  GWEN_DB_NODE *n;
120 
122  n->data.dataInt=data;
123  return n;
124 }
125 
126 
127 
129 {
130  GWEN_DB_NODE *n;
131 
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 
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 
154  n->data.dataChar=GWEN_Memory_strdup(numbuffer);
155  return n;
156 }
157 
158 
159 
161 {
162  GWEN_DB_NODE *n;
163 
165  n->data.dataPtr=data;
166  return n;
167 }
168 
169 
170 
171 GWEN_DB_NODE *GWEN_DB_Group_new(const char *name)
172 {
173  GWEN_DB_NODE *n;
174 
175  assert(name);
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 
187 GWEN_DB_NODE *GWEN_DB_Var_new(const char *name)
188 {
189  GWEN_DB_NODE *n;
190 
191  assert(name);
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 
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 
219  GWEN_DB_NODE *n)
220 {
221  GWEN_DB_Node_Append_UnDirty(parent, n);
225 }
226 
227 
228 
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 
245  GWEN_DB_NODE *n)
246 {
247  GWEN_DB_Node_InsertUnDirty(parent, n);
251 }
252 
253 
254 
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 
273 {
274  GWEN_DB_NODE *parent;
275 
276  assert(n);
277  parent=n->parent;
278  assert(parent);
279 
284 }
285 
286 
287 
289 {
290  if (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) {
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 
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;
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;
325  n->data.dataPtr=NULL;
326  break;
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) {
339  GWEN_Memory_dealloc(n->data.dataName);
340  break;
341 
343  GWEN_Memory_dealloc(n->data.dataChar);
344  break;
346  GWEN_Memory_dealloc(n->data.dataBin);
347  break;
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 
364 {
365  GWEN_DB_NODE *nn;
366 
367  switch (n->typ) {
369  DBG_VERBOUS(GWEN_LOGDOMAIN, "Duplicating group \"%s\"",
370  n->data.dataName);
371  nn=GWEN_DB_Group_new(n->data.dataName);
372  break;
374  DBG_VERBOUS(GWEN_LOGDOMAIN, "Duplicating variable \"%s\"",
375  n->data.dataName);
376  nn=GWEN_DB_Var_new(n->data.dataName);
377  break;
379  nn=GWEN_DB_ValueChar_new(n->data.dataChar);
380  break;
382  nn=GWEN_DB_ValueBin_new(n->data.dataBin, n->dataSize);
383  break;
385  nn=GWEN_DB_ValuePtr_new(n->data.dataPtr);
386  break;
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  }
410  cn=GWEN_DB_Node_List_Next(cn);
411  } /* while cn */
412  }
413 
414  return nn;
415 }
416 
417 
418 
420 {
422 }
423 
424 
425 
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 
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 
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 
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 
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 
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 
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 &&
552  break;
553  }
554  n=GWEN_DB_Node_List_Next(n);
555  } /* while node */
556  return n;
557 }
558 
559 
560 
562 {
563  assert(n);
564  if (n->typ>=GWEN_DB_NodeType_ValueChar &&
566  return n->typ;
567  }
568  else {
569  DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a value");
571  }
572 }
573 
574 
575 
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 
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 
606 {
607  const char *p;
608  int res;
609 
610  assert(n);
611 
612  switch (n->typ) {
614  return n->data.dataInt;
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 
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 
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 
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 
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) {
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 {
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)) ||
784  ) {
785  if (flags & GWEN_PATH_FLAGS_VARIABLE) {
787  "Variable \"%s\" does not exist", entry);
788  }
789  else {
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) {
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 {
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) &&
825  (!(flags & GWEN_PATH_FLAGS_LAST) &&
827  ) {
828  DBG_VERBOUS(GWEN_LOGDOMAIN, "Entry \"%s\" already exists", entry);
829  return 0;
830  }
831  }
832 
833  return nn;
834 }
835 
836 
837 
839  const char *path,
840  uint32_t flags)
841 {
842  return (GWEN_DB_NODE *)GWEN_Path_HandleWithIdx(path,
843  n,
844  flags,
846 }
847 
848 
849 
851 {
852  assert(n);
853  if (n->children)
854  GWEN_DB_Node_List_Clear(n->children);
855 }
856 
857 
858 
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,
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 
898  const char *path)
899 {
900  GWEN_DB_NODE *nn;
901 
902  /* find corresponding node */
903  nn=GWEN_DB_GetNode(n,
904  path,
908  if (!nn) {
909  DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not found",
910  path);
911  return 1;
912  }
914  GWEN_DB_Node_free(nn);
915  return 0;
916 }
917 
918 
919 
921  const char *path)
922 {
923  GWEN_DB_NODE *nn;
924 
925  /* find corresponding node */
926  nn=GWEN_DB_GetNode(n,
927  path,
930  if (!nn) {
931  DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not found",
932  path);
933  return 1;
934  }
936  GWEN_DB_Node_free(nn);
937  return 0;
938 }
939 
940 
941 
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,
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 {
963  }
964  return 0;
965 }
966 
967 
968 
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) {
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 */
986  "Bad type for path \"%s\", returning default value",
987  path);
988  return defVal;
989  }
990  return nn->data.dataChar;
991 }
992 
993 
994 
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);
1027  "Added char value \"%s\" to variable \"%s\"", val, path);
1028 
1029  return 0;
1030 }
1031 
1032 
1033 
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 
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);
1064  "Added char value \"%s\" to variable \"%s\"", val, path);
1065 
1066  return 0;
1067 }
1068 
1069 
1070 
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,
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) {
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);
1112  "Added char value \"%s\" to variable \"%s\"", val, path);
1113 
1114  return 0;
1115 }
1116 
1117 
1118 
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,
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) {
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 
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) {
1174  "Value[%d] for \"%s\" not found, returning default value",
1175  idx, path);
1176  return defVal;
1177  }
1178 
1179  switch (nn->typ) {
1181  return nn->data.dataInt;
1183  p=nn->data.dataChar;
1184  assert(p);
1185  if (sscanf(p, "%d", &res)!=1) {
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 
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 
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) {
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 */
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 
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 
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) {
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 */
1321  "Bad type for path \"%s\", returning default value",
1322  path);
1323  return defVal;
1324  }
1325  return nn->data.dataPtr;
1326 }
1327 
1328 
1329 
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 
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 
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 
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) {
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;
1435  fprintf(stderr, "Value : \"%s\" (char)\n", n->data.dataChar);
1436  break;
1438  fprintf(stderr, "Value : %d (int)\n", n->data.dataInt);
1439  break;
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  }
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 
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 
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 
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 
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  }
1560 }
1561 
1562 
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,
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 
1585  const char *path,
1586  unsigned int i)
1587 {
1588  return (GWEN_DB_GetValue(n, path, i)!=0);
1589 }
1590 
1591 
1592 
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 
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 
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 
1639 {
1640  assert(n);
1641  return n->typ==GWEN_DB_NodeType_Group;
1642 }
1643 
1644 
1645 
1647 {
1648  assert(n);
1649  return n->typ==GWEN_DB_NodeType_Var;
1650 }
1651 
1652 
1653 
1655 {
1656  assert(n);
1657  return (n->typ>=GWEN_DB_NodeType_ValueChar &&
1658  n->typ>=GWEN_DB_NodeType_ValueLast);
1659 }
1660 
1661 
1662 
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 
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 
1695 unsigned int GWEN_DB_Groups_Count(const GWEN_DB_NODE *node)
1696 {
1697  unsigned int res = 0;
1699  return res;
1700 }
1701 
1702 
1703 
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 
1727 unsigned int GWEN_DB_Variables_Count(const GWEN_DB_NODE *node)
1728 {
1729  unsigned int res = 0;
1731  return res;
1732 }
1733 
1734 
1735 
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 
1759 unsigned int GWEN_DB_Values_Count(const GWEN_DB_NODE *node)
1760 {
1761  unsigned int res = 0;
1763  return res;
1764 }
1765 
1766 
1767 
1769 {
1770  assert(n);
1771  return n->nodeFlags;
1772 }
1773 
1774 
1775 
1777  uint32_t flags)
1778 {
1779  assert(n);
1780  n->nodeFlags=flags;
1781 }
1782 
1783 
1784 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 */
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;
2001  valueString=GWEN_DB_GetCharValue(db, name, index, NULL);
2002  if (valueString)
2003  GWEN_Buffer_AppendString(dstBuf, valueString);
2004  break;
2005 
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 
int GWEN_DB_ReplaceVars(GWEN_DB_NODE *db, const char *s, GWEN_BUFFER *dbuf)
Definition: db.c:1949
GWEN_DB_NODE * GWEN_DB_GetValue(GWEN_DB_NODE *n, const char *path, int idx)
Definition: db.c:859
#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:1785
void GWEN_DB_Dump(GWEN_DB_NODE *n, int insert)
Definition: db.c:1418
void * GWEN_DB_Groups_Foreach(GWEN_DB_NODE *node, GWEN_DB_NODES_CB func, void *user_data)
Definition: db.c:1663
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:419
#define GWEN_ERROR_INVALID
Definition: error.h:67
void GWEN_DB_ClearNode(GWEN_DB_NODE *n)
Definition: db.c:850
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:160
uint32_t GWEN_DB_GetNodeFlags(const GWEN_DB_NODE *n)
Definition: db.c:1768
#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:217
GWEN_DB_NODE * GWEN_DB_GetNextValue(GWEN_DB_NODE *n)
Definition: db.c:539
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:1623
void GWEN_DB_Node_Append_UnDirty(GWEN_DB_NODE *parent, GWEN_DB_NODE *n)
Definition: db.c:203
unsigned int GWEN_DB_Groups_Count(const GWEN_DB_NODE *node)
Definition: db.c:1695
#define DBG_WARN(dbg_logger, format, args...)
Definition: debug.h:124
int GWEN_DB_WriteVarValueToBuffer(GWEN_DB_NODE *db, const char *name, int index, GWEN_BUFFER *dstBuf)
Definition: db.c:1980
#define GWEN_LOGDOMAIN
Definition: logger.h:35
void GWEN_DB_ModifyBranchFlagsDown(GWEN_DB_NODE *n, uint32_t newflags, uint32_t mask)
Definition: db.c:1803
int GWEN_DB_ValueExists(GWEN_DB_NODE *n, const char *path, unsigned int i)
Definition: db.c:1584
int GWEN_DB_SetPtrValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, void *val)
Definition: db.c:1330
GWEN_DB_NODE * GWEN_DB_ValueBin_new(const void *data, unsigned int datasize)
Definition: db.c:99
#define GWEN_PATH_FLAGS_LAST
Definition: path.h:166
GWEN_DB_NODE * GWEN_DB_Node_dup(const GWEN_DB_NODE *n)
Definition: db.c:363
int GWEN_DB_InsertGroup(GWEN_DB_NODE *n, GWEN_DB_NODE *nn)
Definition: db.c:1501
GWEN_DB_NODE * GWEN_DB_GetNode(GWEN_DB_NODE *n, const char *path, uint32_t flags)
Definition: db.c:838
int GWEN_DB_AddGroup(GWEN_DB_NODE *n, GWEN_DB_NODE *nn)
Definition: db.c:1480
#define GWEN_PATH_FLAGS_NAMEMUSTNOTEXIST
Definition: path.h:89
GWEN_DB_NODE * GWEN_DB_GetFirstVar(GWEN_DB_NODE *n)
Definition: db.c:477
GWEN_DB_NODE_TYPE GWEN_DB_GetVariableType(GWEN_DB_NODE *n, const char *p)
Definition: db.c:1593
int GWEN_DB_IsVariable(const GWEN_DB_NODE *n)
Definition: db.c:1646
int GWEN_DB_SetBinValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const void *val, unsigned int valSize)
Definition: db.c:1267
void GWEN_DB_Node_free(GWEN_DB_NODE *n)
Definition: db.c:288
void GWEN_DB_VariableRename(GWEN_DB_NODE *n, const char *newname)
Definition: db.c:1938
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:55
void GWEN_DB_Node_Unlink_UnDirty(GWEN_DB_NODE *n)
Definition: db.c:255
#define GWENHYWFAR_CB
Definition: gwenhywfarapi.h:89
#define DBG_DEBUG(dbg_logger, format, args...)
Definition: debug.h:209
const char * GWEN_DB_GroupName(GWEN_DB_NODE *n)
Definition: db.c:1406
GWEN_DB_NODE * GWEN_DB_ValueChar_newFromInt(int v)
Definition: db.c:142
void GWEN_DB_Node_Append(GWEN_DB_NODE *parent, GWEN_DB_NODE *n)
Definition: db.c:218
int GWEN_DB_DeleteGroup(GWEN_DB_NODE *n, const char *path)
Definition: db.c:920
#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:1235
void GWEN_DB_Node_InsertUnDirty(GWEN_DB_NODE *parent, GWEN_DB_NODE *n)
Definition: db.c:229
GWEN_DB_NODE * GWEN_DB_GetNextGroup(GWEN_DB_NODE *n)
Definition: db.c:459
void * GWEN_DB_GetPtrValue(GWEN_DB_NODE *n, const char *path, int idx, void *defVal)
Definition: db.c:1304
const void * GWEN_DB_GetBinValueFromNode(const GWEN_DB_NODE *n, unsigned int *size)
Definition: db.c:632
const char * GWEN_DB_GetCharValue(GWEN_DB_NODE *n, const char *path, int idx, const char *defVal)
Definition: db.c:969
GWEN_DB_NODE * GWEN_DB_Group_dup(const GWEN_DB_NODE *n)
Definition: db.c:426
const char * GWEN_DB_VariableName(GWEN_DB_NODE *n)
Definition: db.c:1926
int GWEN_DB_IsValue(const GWEN_DB_NODE *n)
Definition: db.c:1654
int GWEN_DB_VariableExists(GWEN_DB_NODE *n, const char *path)
Definition: db.c:1563
GWEN_DB_NODE * GWEN_DB_FindNextVar(GWEN_DB_NODE *n, const char *name)
Definition: db.c:1904
GWEN_DB_NODE * GWEN_DB_GetGroup(GWEN_DB_NODE *n, uint32_t flags, const char *path)
Definition: db.c:1379
GWEN_DB_NODE * GWEN_DB_ValueChar_new(const char *data)
Definition: db.c:128
int GWEN_DB_SetCharValueFromInt(GWEN_DB_NODE *n, uint32_t flags, const char *path, int val)
Definition: db.c:1034
GWEN_DB_NODE * GWEN_DB_FindGroup(GWEN_DB_NODE *n, const char *name, int idx)
Definition: db.c:648
int GWEN_DB_DeleteVar(GWEN_DB_NODE *n, const char *path)
Definition: db.c:897
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:86
#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:272
GWEN_DB_NODE * GWEN_DB_FindFirstVar(GWEN_DB_NODE *n, const char *name)
Definition: db.c:1881
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:995
unsigned int GWEN_DB_Variables_Count(const GWEN_DB_NODE *node)
Definition: db.c:1727
void * GWEN_DB_HandlePath(const char *entry, void *data, int idx, uint32_t flags)
Definition: db.c:720
GWEN_DB_NODE * GWEN_DB_GetFirstValue(GWEN_DB_NODE *n)
Definition: db.c:516
#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:1610
int GWEN_DB_IsGroup(const GWEN_DB_NODE *n)
Definition: db.c:1638
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:178
int GWEN_DB_AddCharValue(GWEN_DB_NODE *n, const char *path, const char *val, int senseCase, int check)
Definition: db.c:1071
GWEN_DB_NODE * GWEN_DB_GetNextVar(GWEN_DB_NODE *n)
Definition: db.c:498
GWEN_DB_NODE * GWEN_DB_FindVar(GWEN_DB_NODE *n, const char *name, int idx)
Definition: db.c:682
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:1552
void * GWEN_DB_count_cb(GWEN_UNUSED GWEN_DB_NODE *node, void *user_data)
Definition: db.c:1686
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:1161
GWEN_DB_NODE * GWEN_DB_GetParentGroup(GWEN_DB_NODE *n)
Definition: db.c:1825
GWEN_DB_NODE * GWEN_DB_FindFirstGroup(GWEN_DB_NODE *n, const char *name)
Definition: db.c:1838
GWEN_DB_NODE * GWEN_DB_Group_new(const char *name)
Definition: db.c:171
GWEN_DB_NODE * GWEN_DB_GetFirstGroup(GWEN_DB_NODE *n)
Definition: db.c:438
int GWEN_DB_SetIntValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, int val)
Definition: db.c:1200
#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:206
int GWEN_DB_GetIntValueFromNode(const GWEN_DB_NODE *n)
Definition: db.c:605
int GWEN_DB_RemoveCharValue(GWEN_DB_NODE *n, const char *path, const char *val, int senseCase)
Definition: db.c:1119
void * GWEN_DB_Variables_Foreach(GWEN_DB_NODE *node, GWEN_DB_NODES_CB func, void *user_data)
Definition: db.c:1704
int GWEN_DB_ClearGroup(GWEN_DB_NODE *n, const char *path)
Definition: db.c:942
int GWEN_DB_AddGroupChildren(GWEN_DB_NODE *n, GWEN_DB_NODE *nn)
Definition: db.c:1522
#define GWEN_PATH_FLAGS_NAMEMUSTEXIST
Definition: path.h:84
int GWEN_DB_SetCharValueInNode(GWEN_DB_NODE *n, const char *s)
Definition: db.c:588
GWEN_DB_NODE * GWEN_DB_FindNextGroup(GWEN_DB_NODE *n, const char *name)
Definition: db.c:1859
#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:1736
#define GWEN_UNUSED
GWEN_DB_NODE * GWEN_DB_ValueInt_new(int data)
Definition: db.c:117
void GWEN_DB_SetNodeFlags(GWEN_DB_NODE *n, uint32_t flags)
Definition: db.c:1776
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:244
GWEN_DB_NODE_TYPE GWEN_DB_GetValueType(GWEN_DB_NODE *n)
Definition: db.c:561
GWEN_DB_NODE * GWEN_DB_Var_new(const char *name)
Definition: db.c:187
unsigned int GWEN_DB_Values_Count(const GWEN_DB_NODE *node)
Definition: db.c:1759
const char * GWEN_DB_GetCharValueFromNode(const GWEN_DB_NODE *n)
Definition: db.c:576