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
71static int GWENHYWFAR_CB _replaceVarsCb(void *cbPtr, const char *name, int index, int maxLen, GWEN_BUFFER *dstBuf);
72static 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
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
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
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{
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{
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");
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) {
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 &&
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 ||
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
722void *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) &&
739 ) ||
740 (
741 !(flags & GWEN_PATH_FLAGS_LAST) &&
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) &&
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{
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 &&
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 }
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 }
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 }
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);
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);
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) {
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
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);
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);
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);
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);
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);
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
1420void 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;
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
1565int 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)
1603
1604 nn=GWEN_DB_GetFirstValue(nn);
1605 if (!nn)
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)
1621 return GWEN_DB_GetValueType(nn);
1622}
1623
1624
1625void 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 &&
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
1688void *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
1697unsigned 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
1729unsigned 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
1761unsigned 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 }
1872 while (n) {
1873 if (-1!=GWEN_Text_ComparePattern(n->data.dataName, name, 0))
1874 break;
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
1940void 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
1951int 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
1965int 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
1982int 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
2007int _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
#define NULL
Definition: binreloc.c:300
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:989
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition: buffer.c:277
int GWEN_DB_ValueExists(GWEN_DB_NODE *n, const char *path, unsigned int i)
Definition: db.c:1586
const char * GWEN_DB_GetCharValue(GWEN_DB_NODE *n, const char *path, int idx, const char *defVal)
Definition: db.c:971
int GWEN_DB_SetPtrValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, void *val)
Definition: db.c:1332
int GWEN_DB_ClearGroup(GWEN_DB_NODE *n, const char *path)
Definition: db.c:944
int GWEN_DB_DeleteVar(GWEN_DB_NODE *n, const char *path)
Definition: db.c:899
GWEN_DB_NODE * GWEN_DB_FindFirstVar(GWEN_DB_NODE *n, const char *name)
Definition: db.c:1883
int GWEN_DB_VariableExists(GWEN_DB_NODE *n, const char *path)
Definition: db.c:1565
GWEN_DB_NODE * GWEN_DB_Var_new(const char *name)
Definition: db.c:189
void GWEN_DB_VariableRename(GWEN_DB_NODE *n, const char *newname)
Definition: db.c:1940
unsigned int GWEN_DB_Groups_Count(const GWEN_DB_NODE *node)
Definition: db.c:1697
GWEN_DB_NODE * GWEN_DB_GetNextVar(GWEN_DB_NODE *n)
Definition: db.c:500
int GWEN_DB_SetCharValueInNode(GWEN_DB_NODE *n, const char *s)
Definition: db.c:590
void * GWEN_DB_GetPtrValue(GWEN_DB_NODE *n, const char *path, int idx, void *defVal)
Definition: db.c:1306
void * GWEN_DB_Groups_Foreach(GWEN_DB_NODE *node, GWEN_DB_NODES_CB func, void *user_data)
Definition: db.c:1665
GWEN_DB_NODE * GWEN_DB_FindNextGroup(GWEN_DB_NODE *n, const char *name)
Definition: db.c:1861
int GWEN_DB_IsValue(const GWEN_DB_NODE *n)
Definition: db.c:1656
GWEN_DB_NODE * GWEN_DB_GetValue(GWEN_DB_NODE *n, const char *path, int idx)
Definition: db.c:861
GWEN_DB_NODE * GWEN_DB_Group_new(const char *name)
Definition: db.c:173
GWEN_DB_NODE * GWEN_DB_ValueChar_newFromInt(int v)
Definition: db.c:144
const char * GWEN_DB_GetCharValueFromNode(const GWEN_DB_NODE *n)
Definition: db.c:578
GWEN_DB_NODE * GWEN_DB_FindGroup(GWEN_DB_NODE *n, const char *name, int idx)
Definition: db.c:650
GWEN_DB_NODE_TYPE GWEN_DB_GetValueType(GWEN_DB_NODE *n)
Definition: db.c:563
void GWEN_DB_Node_InsertUnDirty(GWEN_DB_NODE *parent, GWEN_DB_NODE *n)
Definition: db.c:231
unsigned int GWEN_DB_Values_Count(const GWEN_DB_NODE *node)
Definition: db.c:1761
int GWEN_DB_AddGroupChildren(GWEN_DB_NODE *n, GWEN_DB_NODE *nn)
Definition: db.c:1524
void * GWEN_DB_Variables_Foreach(GWEN_DB_NODE *node, GWEN_DB_NODES_CB func, void *user_data)
Definition: db.c:1706
int GWEN_DB_AddCharValue(GWEN_DB_NODE *n, const char *path, const char *val, int senseCase, int check)
Definition: db.c:1073
int GWEN_DB_SetIntValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, int val)
Definition: db.c:1202
GWEN_DB_NODE * GWEN_DB_GetNode(GWEN_DB_NODE *n, const char *path, uint32_t flags)
Definition: db.c:840
void * GWEN_DB_Values_Foreach(GWEN_DB_NODE *node, GWEN_DB_NODES_CB func, void *user_data)
Definition: db.c:1738
GWEN_DB_NODE * GWEN_DB_FindVar(GWEN_DB_NODE *n, const char *name, int idx)
Definition: db.c:684
uint32_t GWEN_DB_GetNodeFlags(const GWEN_DB_NODE *n)
Definition: db.c:1770
const char * GWEN_DB_GroupName(GWEN_DB_NODE *n)
Definition: db.c:1408
int GWEN_DB_IsGroup(const GWEN_DB_NODE *n)
Definition: db.c:1640
GWEN_DB_NODE * GWEN_DB_ValueInt_new(int data)
Definition: db.c:119
int GWEN_DB_InsertGroup(GWEN_DB_NODE *n, GWEN_DB_NODE *nn)
Definition: db.c:1503
GWEN_DB_NODE * GWEN_DB_FindNextVar(GWEN_DB_NODE *n, const char *name)
Definition: db.c:1906
int GWEN_DB_AddGroup(GWEN_DB_NODE *n, GWEN_DB_NODE *nn)
Definition: db.c:1482
GWEN_DB_NODE * GWEN_DB_GetGroup(GWEN_DB_NODE *n, uint32_t flags, const char *path)
Definition: db.c:1381
int GWEN_DB_SetCharValueFromInt(GWEN_DB_NODE *n, uint32_t flags, const char *path, int val)
Definition: db.c:1036
void GWEN_DB_ModifyBranchFlagsUp(GWEN_DB_NODE *n, uint32_t newflags, uint32_t mask)
Definition: db.c:1787
void GWEN_DB_Node_Append(GWEN_DB_NODE *parent, GWEN_DB_NODE *n)
Definition: db.c:220
const void * GWEN_DB_GetBinValueFromNode(const GWEN_DB_NODE *n, unsigned int *size)
Definition: db.c:634
GWEN_DB_NODE * GWEN_DB_ValuePtr_new(void *data)
Definition: db.c:162
GWEN_DB_NODE * GWEN_DB_GetFirstGroup(GWEN_DB_NODE *n)
Definition: db.c:440
int GWEN_DB_DeleteGroup(GWEN_DB_NODE *n, const char *path)
Definition: db.c:922
void * GWEN_DB_count_cb(GWEN_UNUSED GWEN_DB_NODE *node, void *user_data)
Definition: db.c:1688
GWEN_DB_NODE * GWEN_DB_FindFirstGroup(GWEN_DB_NODE *n, const char *name)
Definition: db.c:1840
GWEN_DB_NODE * GWEN_DB_ValueChar_new(const char *data)
Definition: db.c:130
GWEN_DB_NODE * GWEN_DB_GetFirstVar(GWEN_DB_NODE *n)
Definition: db.c:479
int GWEN_DB_WriteVarValueToBuffer(GWEN_DB_NODE *db, const char *name, int index, GWEN_BUFFER *dstBuf)
Definition: db.c:1982
int GWEN_DB_SetCharValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const char *val)
Definition: db.c:997
GWEN_DB_NODE * GWEN_DB_GetParentGroup(GWEN_DB_NODE *n)
Definition: db.c:1827
static int _writeVarValueToBuffer(GWEN_DB_NODE *db, const char *name, int index, GWEN_BUFFER *dstBuf)
Definition: db.c:2007
void GWEN_DB_ClearNode(GWEN_DB_NODE *n)
Definition: db.c:852
GWEN_DB_NODE * GWEN_DB_ValueBin_new(const void *data, unsigned int datasize)
Definition: db.c:101
GWEN_DB_NODE * GWEN_DB_Node_new(GWEN_DB_NODE_TYPE t)
Definition: db.c:88
GWEN_DB_NODE_TYPE GWEN_DB_GetVariableType(GWEN_DB_NODE *n, const char *p)
Definition: db.c:1595
int GWEN_DB_SetBinValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const void *val, unsigned int valSize)
Definition: db.c:1269
GWEN_DB_NODE_TYPE GWEN_DB_GetValueTypeByPath(GWEN_DB_NODE *n, const char *path, unsigned int i)
Definition: db.c:1612
void GWEN_DB_Node_Unlink(GWEN_DB_NODE *n)
Definition: db.c:274
GWEN_DB_NODE * GWEN_DB_Group_dup(const GWEN_DB_NODE *n)
Definition: db.c:428
void GWEN_DB_Node_Unlink_UnDirty(GWEN_DB_NODE *n)
Definition: db.c:257
const char * GWEN_DB_VariableName(GWEN_DB_NODE *n)
Definition: db.c:1928
void GWEN_DB_Node_Insert(GWEN_DB_NODE *parent, GWEN_DB_NODE *n)
Definition: db.c:246
void GWEN_DB_SetNodeFlags(GWEN_DB_NODE *n, uint32_t flags)
Definition: db.c:1778
void GWEN_DB_Node_Append_UnDirty(GWEN_DB_NODE *parent, GWEN_DB_NODE *n)
Definition: db.c:205
GWEN_DB_NODE * GWEN_DB_GetNextGroup(GWEN_DB_NODE *n)
Definition: db.c:461
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
GWEN_DB_NODE * GWEN_DB_GetNextValue(GWEN_DB_NODE *n)
Definition: db.c:541
void GWEN_DB_ModifyBranchFlagsDown(GWEN_DB_NODE *n, uint32_t newflags, uint32_t mask)
Definition: db.c:1805
void * GWEN_DB_HandlePath(const char *entry, void *data, int idx, uint32_t flags)
Definition: db.c:722
void GWEN_DB_Node_free(GWEN_DB_NODE *n)
Definition: db.c:290
GWEN_DB_NODE * GWEN_DB_Node_dup(const GWEN_DB_NODE *n)
Definition: db.c:365
int GWEN_DB_ReplaceVars(GWEN_DB_NODE *db, const char *s, GWEN_BUFFER *dbuf)
Definition: db.c:1951
unsigned int GWEN_DB_Variables_Count(const GWEN_DB_NODE *node)
Definition: db.c:1729
void GWEN_DB_GroupRename(GWEN_DB_NODE *n, const char *newname)
Definition: db.c:1625
int GWEN_DB_RemoveCharValue(GWEN_DB_NODE *n, const char *path, const char *val, int senseCase)
Definition: db.c:1121
void GWEN_DB_Dump(GWEN_DB_NODE *n, int insert)
Definition: db.c:1420
GWEN_DB_NODE * GWEN_DB_GetFirstValue(GWEN_DB_NODE *n)
Definition: db.c:518
int GWEN_DB_GetIntValue(GWEN_DB_NODE *n, const char *path, int idx, int defVal)
Definition: db.c:1163
int GWEN_DB_IsVariable(const GWEN_DB_NODE *n)
Definition: db.c:1648
void GWEN_DB_UnlinkGroup(GWEN_DB_NODE *n)
Definition: db.c:1554
int GWEN_DB_GetIntValueFromNode(const GWEN_DB_NODE *n)
Definition: db.c:607
static int GWENHYWFAR_CB _replaceVarsCb(void *cbPtr, const char *name, int index, int maxLen, GWEN_BUFFER *dstBuf)
void GWEN_DB_Group_free(GWEN_DB_NODE *n)
Definition: db.c:421
#define GWEN_DB_NODE_FLAGS_DIRTY
Definition: db.h:207
void *(* GWEN_DB_NODES_CB)(GWEN_DB_NODE *node, void *user_data)
Definition: db.h:378
#define GWEN_DB_FLAGS_INSERT
Definition: db.h:160
#define GWEN_DB_FLAGS_OVERWRITE_GROUPS
Definition: db.h:123
GWEN_DB_NODE_TYPE
Definition: db.h:233
@ GWEN_DB_NodeType_ValueInt
Definition: db.h:243
@ GWEN_DB_NodeType_Group
Definition: db.h:237
@ GWEN_DB_NodeType_ValueChar
Definition: db.h:241
@ GWEN_DB_NodeType_ValuePtr
Definition: db.h:247
@ GWEN_DB_NodeType_ValueLast
Definition: db.h:249
@ GWEN_DB_NodeType_Var
Definition: db.h:239
@ GWEN_DB_NodeType_Unknown
Definition: db.h:235
@ GWEN_DB_NodeType_ValueBin
Definition: db.h:245
#define GWEN_DB_FLAGS_DEFAULT
Definition: db.h:168
#define GWEN_DB_FLAGS_OVERWRITE_VARS
Definition: db.h:121
#define GWEN_DB_NODE_FLAGS_SAFE
Definition: db.h:214
struct GWEN_DB_NODE GWEN_DB_NODE
Definition: db.h:228
#define DBG_DEBUG(dbg_logger, format, args...)
Definition: debug.h:214
#define DBG_WARN(dbg_logger, format, args...)
Definition: debug.h:125
#define DBG_VERBOUS(dbg_logger, format, args...)
Definition: debug.h:224
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:181
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
#define GWEN_ERROR_INVALID
Definition: error.h:67
#define GWEN_ERROR_NO_DATA
Definition: error.h:94
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
#define GWEN_UNUSED
#define GWENHYWFAR_CB
Definition: gwenhywfarapi.h:89
#define GWEN_LIST_FINI(t, element)
Definition: list1.h:474
#define GWEN_LIST_FUNCTIONS(t, pr)
Definition: list1.h:366
#define GWEN_LIST_INIT(t, element)
Definition: list1.h:465
#define GWEN_LOGDOMAIN
Definition: logger.h:35
char * GWEN_Memory_strdup(const char *s)
Definition: memory.c:76
void * GWEN_Memory_malloc(size_t wsize)
Definition: memory.c:39
void GWEN_Memory_dealloc(void *p)
Definition: memory.c:69
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:61
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:55
void * GWEN_Path_HandleWithIdx(const char *path, void *data, uint32_t flags, GWEN_PATHIDXHANDLERPTR elementFunction)
Definition: path.c:210
#define GWEN_PATH_FLAGS_CREATE_GROUP
Definition: path.h:96
#define GWEN_PATH_FLAGS_PATHMUSTEXIST
Definition: path.h:66
#define GWEN_PATH_FLAGS_PATHCREATE
Definition: path.h:78
#define GWEN_PATH_FLAGS_NAMEMUSTNOTEXIST
Definition: path.h:89
#define GWEN_PATH_FLAGS_CREATE_VAR
Definition: path.h:103
#define GWEN_PATH_FLAGS_LAST
Definition: path.h:166
#define GWEN_PATH_FLAGS_PATHMUSTNOTEXIST
Definition: path.h:70
#define GWEN_PATH_FLAGS_VARIABLE
Definition: path.h:111
#define GWEN_PATH_FLAGS_NAMEMUSTEXIST
Definition: path.h:84
int GWEN_Text_ReplaceVars(const char *s, GWEN_BUFFER *dbuf, GWEN_TEXT_REPLACE_VARS_CB fn, void *ptr)
Definition: text.c:2110
int GWEN_Text_ComparePattern(const char *w, const char *p, int sensecase)
Definition: text.c:1208
char * GWEN_Text_ToHex(const char *src, unsigned l, char *buffer, unsigned int maxsize)
Definition: text.c:657
int GWEN_Text_NumToString(int num, char *buffer, unsigned int bufsize, int fillchar)
Definition: text.c:1243