gwenhywfar 5.12.0
msgengine.c
Go to the documentation of this file.
1/***************************************************************************
2 begin : Fri Jul 04 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#ifdef HAVE_CONFIG_H
26# include <config.h>
27#endif
28
29#define DISABLE_DEBUGLOG
30/*#define HEAVY_DEBUG_MSGENGINE*/
31
32
33#include <gwenhywfar/gwenhywfarapi.h>
34#include <msgengine_p.h>
35#include <gwenhywfar/xml.h>
36#include <gwenhywfar/text.h>
37#include <gwenhywfar/misc.h>
38#include <gwenhywfar/path.h>
39#include <gwenhywfar/debug.h>
40#include <gwenhywfar/buffer.h>
41#include <stdlib.h>
42#include <assert.h>
43#include <string.h>
44#include <ctype.h>
45
46
47
48
50 GWEN_BUFFER *msgbuf,
51 GWEN_XMLNODE *n,
52 GWEN_XMLNODE *rnode,
53 GWEN_DB_NODE *gr,
54 char currentDelimiter,
55 char currentTerminator,
56 const char *delimiters,
57 uint32_t flags);
58
59
60
61
62
64
65
67{
69
72 e->charsToEscape=strdup(GWEN_MSGENGINE_CHARSTOESCAPE);
73 e->delimiters=strdup(GWEN_MSGENGINE_DEFAULT_DELIMITERS);
74 e->globalValues=GWEN_DB_Group_new("globalvalues");
75 e->escapeChar='\\';
76
77 e->usage=1;
78 return e;
79}
80
81
83{
84 if (e) {
85 assert(e->usage);
86 if (--(e->usage)==0) {
88
89 if (e->inheritorData && e->freeDataPtr)
90 e->freeDataPtr(e);
91 if (e->ownDefs)
92 GWEN_XMLNode_free(e->defs);
93 free(e->charsToEscape);
94 free(e->delimiters);
95 GWEN_DB_Group_free(e->globalValues);
96 if (e->trustInfos) {
97 /* free trustInfos */
99
100 td=e->trustInfos;
101 while (td) {
102 tdn=td->next;
104 td=tdn;
105 } /* while */
106 }
108 }
109 }
110}
111
112
113
115{
116 assert(e);
117 e->usage++;
118}
119
120
122{
123 assert(e);
124 e->escapeChar=c;
125}
126
127
128
130{
131 assert(e);
132 return e->escapeChar;
133}
134
135
136
138{
139 assert(e);
140 free(e->charsToEscape);
141 e->charsToEscape=strdup(c);
142}
143
144
145
147{
148 assert(e);
149 return e->charsToEscape;
150}
151
152
153
155{
156 assert(e);
157 free(e->delimiters);
158 if (s)
159 e->delimiters=strdup(s);
160 else
161 e->delimiters=strdup(GWEN_MSGENGINE_DEFAULT_DELIMITERS);
162}
163
164
165
167{
168 assert(e);
169 return e->delimiters;
170}
171
172
173
174void GWEN_MsgEngine_SetMode(GWEN_MSGENGINE *e, const char *mode)
175{
176 GWEN_DB_NODE *db;
177
178 assert(e);
180
181 if (mode)
184 "engine/secmode",
185 mode);
186 else
187 GWEN_DB_DeleteVar(db, "engine/secmode");
188}
189
190
192{
193 GWEN_DB_NODE *db;
194
195 assert(e);
197 return GWEN_DB_GetCharValue(db, "engine/secmode", 0, 0);
198}
199
200
201
203{
204 GWEN_DB_NODE *globalValues;
205
206 assert(e);
207 if (e->getGlobalValuesPtr) {
208 globalValues=e->getGlobalValuesPtr(e);
209 if (!globalValues)
210 globalValues=e->globalValues;
211 }
212 else {
213 globalValues=e->globalValues;
214 }
215 assert(globalValues);
216 return globalValues;
217}
218
219
220
222{
223 GWEN_DB_NODE *db;
224
225 assert(e);
227 return GWEN_DB_GetIntValue(db, "engine/pversion", 0, 0);
228}
229
230
231
233 unsigned int p)
234{
235 GWEN_DB_NODE *db;
236
237 assert(e);
239
242 "engine/pversion",
243 p);
244}
245
246
247
249{
250 assert(e);
251 return e->defs;
252}
253
254
256 GWEN_XMLNODE *n,
257 int take)
258{
259 assert(e);
260 if (e->ownDefs)
261 GWEN_XMLNode_free(e->defs);
262 e->defs=n;
263 e->ownDefs=take;
264}
265
266
267
270{
271 assert(e);
272 e->getGlobalValuesPtr=p;
273}
274
275
276
278{
279 assert(e);
280 return e->getGlobalValuesPtr;
281}
282
283
284
287{
288 assert(e);
289 e->typeReadPtr=p;
290}
291
292
293
295{
296 assert(e);
297 return e->typeReadPtr;
298}
299
300
301
304{
305 assert(e);
306 e->typeWritePtr=p;
307}
308
309
310
312{
313 assert(e);
314 return e->typeWritePtr;
315}
316
317
318
321{
322 assert(e);
323 e->typeCheckPtr=p;
324}
325
326
327
329{
330 assert(e);
331 return e->typeCheckPtr;
332}
333
334
335
336
337
338
341{
342 assert(e);
343 e->binTypeReadPtr=p;
344}
345
346
347
349{
350 assert(e);
351 return e->binTypeReadPtr;
352}
353
354
355
358{
359 assert(e);
360 e->binTypeWritePtr=p;
361}
362
363
364
366{
367 assert(e);
368 return e->binTypeWritePtr;
369}
370
371
372
375{
376 assert(e);
377 e->getCharValuePtr=p;
378}
379
380
381
384{
385 assert(e);
386 e->getIntValuePtr=p;
387}
388
389
390
393{
394 assert(e);
395 DBG_WARN(GWEN_LOGDOMAIN, "GWEN_MsgEngine_SetFreeDataFunction: Deprecated");
396 e->freeDataPtr=p;
397}
398
399
400
402{
403 assert(e);
404 return e->inheritorData;
405}
406
407
408
410{
411 assert(e);
412 DBG_WARN(GWEN_LOGDOMAIN, "GWEN_MsgEngine_SetInheritorData: Deprecated");
413 if (e->inheritorData && e->freeDataPtr)
414 e->freeDataPtr(e);
415 e->inheritorData=d;
416}
417
418
419
421 GWEN_BUFFER *gbuf,
422 GWEN_BUFFER *data,
423 GWEN_XMLNODE *node)
424{
425 unsigned int minsize;
426 unsigned int maxsize;
427 unsigned int fixSize;
428 unsigned int startPos;
429 int filler;
430 const char *type;
431 const char *name;
432 int rv;
433
434 /* get some sizes */
435 minsize=atoi(GWEN_XMLNode_GetProperty(node, "minsize", "0"));
436 maxsize=atoi(GWEN_XMLNode_GetProperty(node, "maxsize", "0"));
437 fixSize=atoi(GWEN_XMLNode_GetProperty(node, "size", "0"));
438 filler=atoi(GWEN_XMLNode_GetProperty(node, "filler", "0"));
439 type=GWEN_XMLNode_GetProperty(node, "type", "ASCII");
440 name=GWEN_XMLNode_GetProperty(node, "name", "<unnamed>");
441 startPos=GWEN_Buffer_GetPos(gbuf);
442
443 /* check sizes */
444 if (minsize && GWEN_Buffer_GetUsedBytes(data)<minsize) {
445 DBG_ERROR(GWEN_LOGDOMAIN, "Data too short (minsize is %d)", minsize);
446 return -1;
447 }
448 if (maxsize && GWEN_Buffer_GetUsedBytes(data)>maxsize) {
449 DBG_ERROR(GWEN_LOGDOMAIN, "Data too long (maxsize is %d)", maxsize);
450 return -1;
451 }
452
453 rv=1;
454 if (e->typeWritePtr) {
455 rv=e->typeWritePtr(e,
456 gbuf,
457 data,
458 node);
459 }
460 if (rv==-1) {
461 DBG_INFO(GWEN_LOGDOMAIN, "External type writing failed");
462 return -1;
463 }
464 else if (rv==1) {
465 int i;
466
467 /* type not handled externally, so handle it myself */
468 if (strcasecmp(type, "bin")==0) {
469 DBG_DEBUG(GWEN_LOGDOMAIN, "Writing binary data (%d bytes added to %d bytes)",
473 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
474 return -1;
475 }
476 sprintf(GWEN_Buffer_GetPosPointer(gbuf),
477 "@%d@",
479
480
481 i=strlen(GWEN_Buffer_GetPosPointer(gbuf));
484 GWEN_Buffer_AppendBuffer(gbuf, data);
485 } /* if type is "bin" */
486 else if (strcasecmp(type, "num")==0) {
487 //int num;
488 unsigned int len;
489 unsigned int lj;
490
491 //num=atoi(GWEN_Buffer_GetPosPointer(data));
492 len=strlen(GWEN_Buffer_GetPosPointer(data));
493
494 if (atoi(GWEN_XMLNode_GetProperty(node, "leftfill", "0"))) {
495 if (GWEN_Buffer_AllocRoom(gbuf, maxsize+1)) {
496 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
497 return -1;
498 }
499
500 /* fill left */
501 for (lj=0; lj<(maxsize-len); lj++)
502 GWEN_Buffer_AppendByte(gbuf, '0');
503
504 /* write value */
505 for (lj=0; lj<len; lj++)
507 }
508 else if (atoi(GWEN_XMLNode_GetProperty(node, "rightfill", "0"))) {
509 if (GWEN_Buffer_AllocRoom(gbuf, maxsize+1)) {
510 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
511 return -1;
512 }
513
514 /* write value */
515 for (lj=0; lj<len; lj++)
517
518 /* fill right */
519 for (lj=0; lj<(maxsize-len); lj++)
520 GWEN_Buffer_AppendByte(gbuf, '0');
521 }
522 else {
523 if (GWEN_Buffer_AllocRoom(gbuf, maxsize+1)) {
524 DBG_ERROR(GWEN_LOGDOMAIN, "Maxsize in XML file is higher than the buffer size");
525 return -1;
526 }
527 for (lj=0; lj<len; lj++)
529 }
530 } /* if type is num */
531 else {
532 /* TODO: Check for valids */
533 const char *p;
534 int lastWasEscape;
535 unsigned int pcount;
536
538 pcount=0;
539 lastWasEscape=0;
540 while (*p && pcount<GWEN_Buffer_GetUsedBytes(data)) {
541 int c;
542
543 c=(unsigned char)*p;
544 if (lastWasEscape) {
545 lastWasEscape=0;
546 switch (c) {
547 case 'r':
548 c='\r';
549 break;
550 case 'n':
551 c='\n';
552 break;
553 case 'f':
554 c='\f';
555 break;
556 case 't':
557 c='\t';
558 break;
559 default:
560 c=(unsigned char)*p;
561 } /* switch */
562 }
563 else {
564 if (*p=='\\') {
565 lastWasEscape=1;
566 c=-1;
567 }
568 else
569 c=(unsigned char)*p;
570 }
571 if (c!=-1) {
572 int needsEscape;
573
574 needsEscape=0;
575 if (c==e->escapeChar)
576 needsEscape=1;
577 else {
578 if (e->charsToEscape)
579 if (strchr(e->charsToEscape, c))
580 needsEscape=1;
581 }
582 if (needsEscape) {
583 /* write escape char */
584 if (GWEN_Buffer_AppendByte(gbuf,
585 e->escapeChar)) {
586 return -1;
587 }
588 }
589 if (GWEN_Buffer_AppendByte(gbuf, c)) {
590 return -1;
591 }
592 }
593 p++;
594 pcount++;
595 } /* while */
596 if (pcount<GWEN_Buffer_GetUsedBytes(data)) {
597 DBG_WARN(GWEN_LOGDOMAIN, "Premature end of string (%d<%d)",
598 pcount, GWEN_Buffer_GetUsedBytes(data));
599 }
600 if (*p) {
602 "String for \"%s\" (type %s) is longer than expected "
603 "(no #0 at pos=%d)",
604 name, type,
606 }
607 } /* if type is not BIN */
608 } /* if type not external */
609 else {
610 DBG_INFO(GWEN_LOGDOMAIN, "Type \"%s\" (for %s) is external (write)",
611 type, name);
612
613 } /* if external type */
614
615 /* fill data */
616 if (fixSize) {
617 uint32_t bs;
618 unsigned int j;
619
620 bs=GWEN_Buffer_GetPos(gbuf)-startPos;
621 if (bs>fixSize) {
623 "Data too long (size is %d, fixed size is %d)",
624 bs, fixSize);
625 return -1;
626 }
627
628 for (j=bs; j<fixSize; j++)
629 GWEN_Buffer_AppendByte(gbuf, (unsigned char)filler);
630 }
631
632 return 0;
633}
634
635
636
638 const char *type)
639{
640 if (e->typeCheckPtr) {
642
643 vt=e->typeCheckPtr(e, type);
644 if (vt!=GWEN_DB_NodeType_Unknown) {
646 return 1;
647 }
648 }
649 return
650 (strcasecmp(type, "alpha")==0) ||
651 (strcasecmp(type, "ascii")==0) ||
652 (strcasecmp(type, "an")==0) ||
653 (strcasecmp(type, "float")==0);
654}
655
656
657
659 const char *type)
660{
661 if (e->typeCheckPtr) {
663
664 vt=e->typeCheckPtr(e, type);
665 if (vt!=GWEN_DB_NodeType_Unknown) {
667 return 1;
668 }
669 }
670 return
671 (strcasecmp(type, "num")==0);
672}
673
674
675
677 const char *type)
678{
679 if (e->typeCheckPtr) {
681
682 vt=e->typeCheckPtr(e, type);
683 if (vt!=GWEN_DB_NodeType_Unknown) {
685 return 1;
686 }
687 }
688 return
689 (strcasecmp(type, "bin")==0);
690}
691
692
693
695 GWEN_XMLNODE *node,
696 GWEN_BUFFER *mbuf)
697{
698 /* get data from within the XML node */
699 GWEN_XMLNODE *n;
700 const char *type;
701
702
703 type=GWEN_XMLNode_GetProperty(node, "type", "ascii");
705 "Getting data of type \"%s\" from within XML file", type);
707 if (!n) {
708 DBG_DEBUG(GWEN_LOGDOMAIN, "No child");
709 return 1;
710 }
711
712 if (GWEN_MsgEngine__IsBinTyp(e, type)) {
713 const char *dp;
714 //unsigned int dplen;
715 const char *stype;
716
717 stype=GWEN_XMLNode_GetProperty(node, "storedAs", type);
718 if (GWEN_MsgEngine__IsBinTyp(e, stype)) {
720 //dplen=strlen(dp);
721 if (GWEN_Text_FromHexBuffer(dp, mbuf)) {
722 DBG_INFO(GWEN_LOGDOMAIN, "here");
723 return -1;
724 }
725 } /* if stored as bin */
726 else {
727 /* stored as char */
729 }
730 } /* if binType */
731 else {
733 }
734
735 return 0;
736}
737
738
739
740
741
743 GWEN_BUFFER *gbuf,
744 GWEN_XMLNODE *node,
745 GWEN_DB_NODE *gr,
746 int loopNr,
747 int isOptional,
748 GWEN_XMLNODE_PATH *nodePath)
749{
750 const char *name;
751 const char *type;
752 //unsigned int minsize;
753 //unsigned int maxsize;
754 char numbuffer[256];
755 const char *pdata;
756 unsigned int datasize;
757 GWEN_BUFFER *data;
758 GWEN_BUFFER *tdata;
759 int handled;
760
761 pdata=0;
762 handled=0;
763 data=0;
764 tdata=0;
765
766 /* get type */
767 type=GWEN_XMLNode_GetProperty(node, "type", "ASCII");
768 DBG_DEBUG(GWEN_LOGDOMAIN, "Type is \"%s\"", type);
769 /* get some sizes */
770 //minsize=atoi(GWEN_XMLNode_GetProperty(node, "minsize","0"));
771 //maxsize=atoi(GWEN_XMLNode_GetProperty(node, "maxsize","0"));
772
773 if (e->binTypeWritePtr &&
774 GWEN_MsgEngine__IsBinTyp(e, type) &&
775 atoi(GWEN_XMLNode_GetProperty(node, "writebin", "1"))) {
776 int rv;
777
778 data=GWEN_Buffer_new(0,
779 64,
780 0,
781 1);
782
783 rv=e->binTypeWritePtr(e, node, gr, data);
784 if (rv==-1) {
785 /* error */
786 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
787 return -1;
788 }
789 else if (rv==0) {
790 handled=1;
791 }
792 else if (rv==1) {
793 GWEN_Buffer_free(data);
794 data=0;
795 }
796 }
797
798 if (!handled) {
799 /* get name */
800 name=GWEN_XMLNode_GetProperty(node, "name", 0);
801 if (!name) {
802 int rv;
803
804 /* get data from within the XML node */
805 tdata=GWEN_Buffer_new(0, 32, 0, 1);
806 GWEN_Buffer_SetStep(tdata, 256);
807 rv=GWEN_MsgEngine__GetInline(e, node, tdata);
808 if (rv==0) {
809 pdata=GWEN_Buffer_GetStart(tdata);
810 datasize=GWEN_Buffer_GetUsedBytes(tdata);
811 }
812 else {
813 GWEN_Buffer_free(tdata);
814 tdata=0;
815 pdata="";
816 datasize=0;
817 }
818 } /* if (!name) */
819 else {
820 const char *nptr;
821
822 DBG_DEBUG(GWEN_LOGDOMAIN, "Name provided (%s), loop is %d", name, loopNr);
823 nptr=name;
824
825 if (gr) {
827 int idata;
828
829 /* Variable type of DB takes precedence
830 */
831 vt=GWEN_DB_GetValueTypeByPath(gr, nptr, loopNr);
832 if (vt==GWEN_DB_NodeType_Unknown) {
833 if (GWEN_MsgEngine__IsCharTyp(e, type))
835 else if (GWEN_MsgEngine__IsIntTyp(e, type))
837 else if (GWEN_MsgEngine__IsBinTyp(e, type))
839 else {
841 "Unable to determine parameter "
842 "type (%s), assuming \"char\" for this matter", type);
844 }
845 }
846
847 /* get the value of the given var from the db */
848 switch (vt) {
850 DBG_DEBUG(GWEN_LOGDOMAIN, "Type of \"%s\" is char", name);
851 pdata=GWEN_DB_GetCharValue(gr, nptr, loopNr, 0);
852 if (pdata) {
853 DBG_DEBUG(GWEN_LOGDOMAIN, "Value of \"%s\" is %s", nptr, pdata);
854 datasize=strlen(pdata);
855 }
856 else
857 datasize=0;
858 break;
859
861 DBG_DEBUG(GWEN_LOGDOMAIN, "Type of \"%s\" is int", name);
862 if (GWEN_DB_ValueExists(gr, nptr, loopNr)) {
863 idata=GWEN_DB_GetIntValue(gr, nptr, loopNr, 0);
864 if (-1==GWEN_Text_NumToString(idata, numbuffer,
865 sizeof(numbuffer), 0)) {
866 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
867 GWEN_Buffer_free(data);
868 return -1;
869 }
870 DBG_DEBUG(GWEN_LOGDOMAIN, "Value of \"%s\" is %d", nptr, idata);
871 pdata=numbuffer;
872 datasize=strlen(numbuffer);
873 }
874 break;
875
877 DBG_DEBUG(GWEN_LOGDOMAIN, "Type of \"%s\" is bin", name);
878 pdata=GWEN_DB_GetBinValue(gr, nptr, loopNr, 0, 0, &datasize);
879 break;
880
881 default:
882 DBG_WARN(GWEN_LOGDOMAIN, "Unsupported parameter type (%d)", vt);
883 break;
884 } /* switch vt */
885 } /* if gr */
886
887 if (!pdata) {
888 GWEN_XMLNODE_PATH *copyOfNodePath;
889
890 copyOfNodePath=GWEN_XMLNode_Path_dup(nodePath);
891
892 /* still no data, try to get it from the XML file */
893 DBG_DEBUG(GWEN_LOGDOMAIN, "Searching for value of \"%s\"", name);
895 node, copyOfNodePath, nptr,
896 &datasize);
897 GWEN_XMLNode_Path_free(copyOfNodePath);
898 if (pdata) {
899 DBG_DEBUG(GWEN_LOGDOMAIN, "Found value of \"%s\"", name);
900 }
901 }
902
903 if (!pdata) {
904 int rv;
905
906 /* get data from within the XML node */
907 tdata=GWEN_Buffer_new(0, 32, 0, 1);
908 GWEN_Buffer_SetStep(tdata, 256);
909 rv=GWEN_MsgEngine__GetInline(e, node, tdata);
910 if (rv==0) {
911 pdata=GWEN_Buffer_GetStart(tdata);
912 datasize=GWEN_Buffer_GetUsedBytes(tdata);
913 }
914 else {
915 GWEN_Buffer_free(tdata);
916 tdata=0;
917 }
918 }
919
920 if (pdata==0) {
921 if (isOptional) {
922 DBG_INFO(GWEN_LOGDOMAIN, "Value not found, omitting element \"%s[%d]\"",
923 name, loopNr);
924 GWEN_Buffer_free(data);
925 return 1;
926 }
927 else {
929 "Value for element \"%s[%d]\" (mode \"%s\") not found",
930 name, loopNr,
932 GWEN_DB_Dump(gr, 4);
933 GWEN_Buffer_free(data);
934 return -1;
935 }
936 }
937 }
938
939 if (!data)
940 data=GWEN_Buffer_new((char *)pdata,
941 datasize,
942 datasize,
943 0 /* dont take ownership*/);
944 }
945
946 /* write value */
948 gbuf,
949 data,
950 node)!=0) {
951 DBG_INFO(GWEN_LOGDOMAIN, "Could not write value");
952 GWEN_Buffer_free(data);
953 GWEN_Buffer_free(tdata);
954 return -1;
955 }
956 GWEN_Buffer_free(data);
957 GWEN_Buffer_free(tdata);
958
959 return 0;
960}
961
962
963
965 const char *pname,
966 int version,
967 const char *pvalue)
968{
969 return GWEN_MsgEngine_FindNodeByProperty(e, "GROUP", pname, version, pvalue);
970}
971
972
973
975 const char *t,
976 const char *pname,
977 int version,
978 const char *pvalue)
979{
980 GWEN_XMLNODE *n;
981 const char *p;
982 int i;
983 const char *mode;
984 unsigned int proto;
985 char buffer[256];
986
987 if ((strlen(t)+4)>sizeof(buffer)) {
988 DBG_ERROR(GWEN_LOGDOMAIN, "Type name too long.");
989 return 0;
990 }
991
994 if (!e->defs) {
995 DBG_INFO(GWEN_LOGDOMAIN, "No definitions available");
996 return 0;
997 }
998 n=e->defs;
1000
1001 /* find type+"S" */
1002 strcpy(buffer, t);
1003 strcat(buffer, "S");
1004 while (n) {
1007 assert(p);
1008 if (strcasecmp(p, buffer)==0)
1009 break;
1010 }
1011 n=GWEN_XMLNode_Next(n);
1012 } /* while */
1013
1014 if (!n) {
1015 DBG_INFO(GWEN_LOGDOMAIN, "No definitions available for type \"%s\"", t);
1016 return 0;
1017 }
1018
1019 /* find approppriate group definition */
1020 if (!mode)
1021 mode="";
1023 if (!n) {
1024 DBG_INFO(GWEN_LOGDOMAIN, "No definitions inside \"%s\"", buffer);
1025 return 0;
1026 }
1027
1028 /* find type+"def" */
1029 strcpy(buffer, t);
1030 strcat(buffer, "def");
1031 while (n) {
1034 assert(p);
1035 if (strcasecmp(p, buffer)==0) {
1036 p=GWEN_XMLNode_GetProperty(n, pname, "");
1037 if (strcasecmp(p, pvalue)==0) {
1038 i=atoi(GWEN_XMLNode_GetProperty(n, "pversion", "0"));
1039 if (proto==0 || (int)proto==i || i==0) {
1040 i=atoi(GWEN_XMLNode_GetProperty(n, "version", "0"));
1041 if (version==0 || version==i) {
1042 p=GWEN_XMLNode_GetProperty(n, "mode", "");
1043 if (strcasecmp(p, mode)==0 || !*p) {
1044 DBG_DEBUG(GWEN_LOGDOMAIN, "Group definition for \"%s=%s\" found",
1045 pname, pvalue);
1046 return n;
1047 }
1048 }
1049 }
1050 }
1051 }
1052 }
1053 n=GWEN_XMLNode_Next(n);
1054 } /* while */
1055
1056 DBG_INFO(GWEN_LOGDOMAIN, "Group definition for \"%s=%s\"(%d) not found",
1057 pname,
1058 pvalue,
1059 version);
1060 return 0;
1061}
1062
1063
1064
1066 const char *t,
1067 const char *pname,
1068 int version,
1069 const char *pvalue)
1070{
1071 GWEN_XMLNODE *n;
1072 const char *p;
1073 int i;
1074 const char *mode;
1075 unsigned int proto;
1076 char buffer[256];
1077
1078 if ((strlen(t)+4)>sizeof(buffer)) {
1079 DBG_ERROR(GWEN_LOGDOMAIN, "Type name too long.");
1080 return 0;
1081 }
1082
1083 mode=GWEN_MsgEngine_GetMode(e);
1085 if (!e->defs) {
1086 DBG_INFO(GWEN_LOGDOMAIN, "No definitions available");
1087 return 0;
1088 }
1089 n=e->defs;
1091
1092 /* find type+"S" */
1093 strcpy(buffer, t);
1094 strcat(buffer, "S");
1095 while (n) {
1098 assert(p);
1099 if (strcasecmp(p, buffer)==0)
1100 break;
1101 }
1102 n=GWEN_XMLNode_Next(n);
1103 } /* while */
1104
1105 if (!n) {
1106 DBG_INFO(GWEN_LOGDOMAIN, "No definitions available for type \"%s\"", t);
1107 return 0;
1108 }
1109
1110 /* find approppriate group definition */
1111 if (!mode)
1112 mode="";
1114 if (!n) {
1115 DBG_INFO(GWEN_LOGDOMAIN, "No definitions inside \"%s\"", buffer);
1116 return 0;
1117 }
1118
1119 /* find type+"def" */
1120 strcpy(buffer, t);
1121 strcat(buffer, "def");
1122 while (n) {
1125 assert(p);
1126 if (strcasecmp(p, buffer)==0) {
1127 p=GWEN_XMLNode_GetProperty(n, pname, "");
1128 if (strcasecmp(p, pvalue)==0) {
1129 i=atoi(GWEN_XMLNode_GetProperty(n, "pversion", "0"));
1130 if (proto==0 || (int)proto==i) {
1131 i=atoi(GWEN_XMLNode_GetProperty(n, "version", "0"));
1132 if (version==0 || version==i) {
1133 p=GWEN_XMLNode_GetProperty(n, "mode", "");
1134 if (strcasecmp(p, mode)==0 || !*p) {
1135 DBG_DEBUG(GWEN_LOGDOMAIN, "Group definition for \"%s=%s\" found",
1136 pname, pvalue);
1137 return n;
1138 }
1139 }
1140 }
1141 }
1142 }
1143 }
1144 n=GWEN_XMLNode_Next(n);
1145 } /* while */
1146
1147 DBG_INFO(GWEN_LOGDOMAIN, "Group definition for \"%s=%s\"(%d) not found",
1148 pname,
1149 pvalue,
1150 version);
1151 return 0;
1152}
1153
1154
1155
1157 const char *pvalue,
1158 GWEN_XMLNODE *node,
1159 GWEN_XMLNODE *dnode,
1160 unsigned int *datasize)
1161{
1162 const char *p;
1163 static char pbuffer[256];
1164 GWEN_DB_NODE *globalValues;
1165
1166 globalValues=GWEN_MsgEngine__GetGlobalValues(e);
1167 assert(globalValues);
1168
1169 if (pvalue) {
1170 DBG_DEBUG(GWEN_LOGDOMAIN, "Transforming value \"%s\"", pvalue);
1171 /* check whether the value is a property */
1172 p=pvalue;
1173 while (*p && isspace((int)*p))
1174 p++;
1175 if (*p=='$' || *p=='+') {
1176 /* global property */
1177 int incr;
1178
1179 incr=(*p=='+');
1180 p++;
1181
1182 DBG_DEBUG(GWEN_LOGDOMAIN, "Getting global property \"%s\"", p);
1183 if (incr) {
1184 int z;
1185
1186 z=GWEN_DB_GetIntValue(globalValues, p, 0, 0);
1187 DBG_DEBUG(GWEN_LOGDOMAIN, "Incrementing global property \"%s\" (%d)",
1188 p, z);
1189 if (GWEN_Text_NumToString(z, pbuffer, sizeof(pbuffer), 0)<1) {
1190 DBG_ERROR(GWEN_LOGDOMAIN, "Error converting num to string");
1191 return 0;
1192 }
1193
1194 z++;
1195 DBG_DEBUG(GWEN_LOGDOMAIN, "Setting global property \"%s\"=%d", p, z);
1196 GWEN_DB_SetIntValue(globalValues,
1199 p, z);
1200 pvalue=pbuffer;
1201 *datasize=strlen(pvalue);
1202 }
1203 else {
1204 int z;
1206 const char *type = "should_be_known";
1207 /* default value; otherwise the compiler issues a warning */
1208
1209 DBG_DEBUG(GWEN_LOGDOMAIN, "Getting global property \"%s\"", p);
1210 vt=GWEN_DB_GetVariableType(globalValues, p);
1211 if (vt==GWEN_DB_NodeType_Unknown) {
1212 if (!GWEN_DB_VariableExists(globalValues, p)) {
1213 DBG_ERROR(GWEN_LOGDOMAIN, "Unable to determine type of \"%s\"", p);
1214 return 0;
1215 }
1216 type=GWEN_XMLNode_GetProperty(dnode, "type", "ascii");
1217 if (GWEN_MsgEngine__IsCharTyp(e, type))
1219 else if (GWEN_MsgEngine__IsIntTyp(e, type))
1221 else if (GWEN_MsgEngine__IsBinTyp(e, type))
1223 else {
1225 "Unable to determine type of \"%s\" (xml)", p);
1226 return 0;
1227 }
1228 }
1229
1230 switch (vt) {
1232 pvalue=GWEN_DB_GetCharValue(globalValues, p, 0, "");
1233 *datasize=strlen(pvalue);
1234 break;
1235
1237 z=GWEN_DB_GetIntValue(globalValues, p, 0, 0);
1238 if (GWEN_Text_NumToString(z, pbuffer, sizeof(pbuffer), 0)<1) {
1239 DBG_ERROR(GWEN_LOGDOMAIN, "Error converting num to string");
1240 return 0;
1241 }
1242 pvalue=pbuffer;
1243 *datasize=strlen(pvalue);
1244 break;
1245
1247 pvalue=GWEN_DB_GetBinValue(globalValues, p, 0,
1248 0, 0,
1249 datasize);
1250 break;
1251
1252 default:
1253 DBG_ERROR(GWEN_LOGDOMAIN, "Unknown type %s", type);
1254 return 0;
1255 } /* switch */
1256 }
1257 DBG_DEBUG(GWEN_LOGDOMAIN, "Value transformed");
1258 }
1259 else if (*p=='%') {
1260 /* local property */
1261 p++;
1262
1263 DBG_DEBUG(GWEN_LOGDOMAIN, "Getting property \"%s\"", p);
1264 pvalue=GWEN_XMLNode_GetProperty(node, p, 0);
1265 if (pvalue) {
1266 *datasize=strlen(pvalue);
1267 DBG_DEBUG(GWEN_LOGDOMAIN, "Transformed value \"%s\"", pvalue);
1268 }
1269 else
1270 *datasize=0;
1271 }
1272 else if (*p=='?') {
1274 int z;
1275 const char *dtype;
1276
1277 /* get type */
1278 dtype=GWEN_XMLNode_GetProperty(dnode, "type", "ASCII");
1279
1280 /* program variable accessable via callback */
1281 p++;
1282 DBG_DEBUG(GWEN_LOGDOMAIN, "Getting program variable \"%s\"", p);
1283
1284 pvalue=0;
1285 if (GWEN_MsgEngine__IsCharTyp(e, dtype))
1287 else if (GWEN_MsgEngine__IsIntTyp(e, dtype))
1289 else {
1291 }
1292
1293 switch (vt) {
1295 if (e->getCharValuePtr) {
1296 pvalue=e->getCharValuePtr(e, p, 0);
1297 if (pvalue)
1298 *datasize=strlen(pvalue);
1299 }
1300 break;
1301
1303 if (e->getIntValuePtr) {
1304 z=e->getIntValuePtr(e, p, 0);
1305 if (GWEN_Text_NumToString(z, pbuffer, sizeof(pbuffer), 0)<1) {
1306 DBG_ERROR(GWEN_LOGDOMAIN, "Error converting num to string");
1307 return 0;
1308 }
1309 pvalue=pbuffer;
1310 *datasize=strlen(pvalue);
1311 }
1312 else {
1313 DBG_NOTICE(GWEN_LOGDOMAIN, "Callback for getIntValue not set");
1314 }
1315 break;
1316
1317 default:
1318 DBG_ERROR(GWEN_LOGDOMAIN, "Unhandled type %s", dtype);
1319 return 0;
1320 } /* switch */
1321
1322 DBG_DEBUG(GWEN_LOGDOMAIN, "Value transformed");
1323 }
1324 else {
1325 *datasize=strlen(pvalue);
1326 }
1327 }
1328 return pvalue;
1329}
1330
1331
1332
1334 GWEN_XMLNODE *refnode,
1335 const char *name,
1336 int topDown)
1337{
1338 const char *pvalue;
1339 GWEN_XMLNODE *pn;
1340 const char *lastValue;
1341
1342 DBG_DEBUG(GWEN_LOGDOMAIN, "Searching for value of \"%s\" in properties", name);
1343 lastValue=0;
1344
1345 pvalue=GWEN_XMLNode_GetProperty(node, name, 0);
1346 if (pvalue) {
1347 if (!topDown)
1348 return pvalue;
1349 DBG_DEBUG(GWEN_LOGDOMAIN, "Found a value (%s), but will look further", pvalue);
1350 lastValue=pvalue;
1351 }
1352
1353 pn=refnode;
1354 while (pn) {
1355 pvalue=GWEN_XMLNode_GetProperty(pn, name, 0);
1356 if (pvalue) {
1357 if (!topDown)
1358 return pvalue;
1359 DBG_DEBUG(GWEN_LOGDOMAIN, "Found a value (%s), but will look further", pvalue);
1360 lastValue=pvalue;
1361 }
1363 } /* while */
1364 return lastValue;
1365}
1366
1367
1368
1370 GWEN_XMLNODE *refnode)
1371{
1372 int value;
1373 GWEN_XMLNODE *pn;
1374 int highestTrust;
1375
1376 highestTrust=0;
1377
1378 value=atoi(GWEN_XMLNode_GetProperty(node, "trustlevel", "0"));
1379 if (value>highestTrust)
1380 highestTrust=value;
1381
1382 pn=node;
1383 while (pn) {
1384 value=atoi(GWEN_XMLNode_GetProperty(pn, "trustlevel", "0"));
1385 if (value>highestTrust)
1386 highestTrust=value;
1388 } /* while */
1389
1390 pn=refnode;
1391 while (pn) {
1392 value=atoi(GWEN_XMLNode_GetProperty(pn, "trustlevel", "0"));
1393 if (value>highestTrust)
1394 highestTrust=value;
1396 } /* while */
1397 return highestTrust;
1398}
1399
1400
1401
1403 GWEN_XMLNODE *node,
1404 GWEN_XMLNODE_PATH *nodePath,
1405 const char *name,
1406 unsigned int *datasize)
1407{
1408 const char *pvalue;
1409 GWEN_XMLNODE *pn;
1410 char *bufferPtr;
1411 int topDown;
1412 const char *lastValue;
1413 unsigned int lastDataSize;
1414 unsigned int ldatasize;
1415
1416 DBG_DEBUG(GWEN_LOGDOMAIN, "Searching for value of \"%s\" in <VALUES>",
1417 name);
1418 if (!node) {
1419 DBG_WARN(GWEN_LOGDOMAIN, "No node !");
1420 }
1421 topDown=atoi(GWEN_XMLNode_GetProperty(node, "topdown", "0"));
1422 lastValue=0;
1423 lastDataSize=0;
1424
1425 bufferPtr=0;
1426
1427 /*pn=GWEN_XMLNode_GetParent(node);*/
1428 pn=GWEN_XMLNode_Path_Surface(nodePath);
1429 while (pn) {
1430 const char *ppath;
1431 /*
1432 if (GWEN_XMLNode_GetType(pn)==GWEN_XMLNodeTypeTag) {
1433 DBG_NOTICE(GWEN_LOGDOMAIN, "Checking node \"%s\"",
1434 GWEN_XMLNode_GetData(pn));
1435 }*/
1436 pvalue=GWEN_MsgEngine__findInValues(e, pn, node, name, &ldatasize);
1437 if (pvalue) {
1438 if (!topDown) {
1439 free(bufferPtr);
1440 *datasize=ldatasize;
1441 return pvalue;
1442 }
1443 DBG_DEBUG(GWEN_LOGDOMAIN, "Found a value, but will look further");
1444 lastValue=pvalue;
1445 lastDataSize=ldatasize;
1446 }
1447
1448 ppath=GWEN_XMLNode_GetProperty(pn, "name", "");
1449
1450 if (*ppath) {
1451 int i;
1452 char *tmpptr;
1453
1454 if (bufferPtr) {
1455 i=strlen(bufferPtr)+strlen(ppath)+2;
1456 tmpptr=(char *)malloc(i);
1457 assert(tmpptr);
1458 sprintf(tmpptr, "%s/%s", ppath, bufferPtr);
1459 free(bufferPtr);
1460 bufferPtr=tmpptr;
1461 }
1462 else {
1463 i=strlen(ppath)+strlen(name)+2;
1464 tmpptr=(char *)malloc(i);
1465 assert(tmpptr);
1466 sprintf(tmpptr, "%s/%s", ppath, name);
1467 bufferPtr=tmpptr;
1468 }
1469 name=bufferPtr;
1470 }
1471 pn=GWEN_XMLNode_Path_Surface(nodePath);
1472 } /* while */
1473
1474 free(bufferPtr);
1475 if (!lastValue)
1476 *datasize=0;
1477 else
1478 *datasize=lastDataSize;
1479 return lastValue;
1480}
1481
1482
1483
1485 GWEN_XMLNODE *node,
1486 GWEN_XMLNODE *dnode,
1487 const char *name,
1488 unsigned int *datasize)
1489{
1490 GWEN_XMLNODE *pn;
1491
1492 DBG_VERBOUS(GWEN_LOGDOMAIN, "Looking for value of \"%s\" in <VALUES>", name);
1493 pn=GWEN_XMLNode_GetChild(node);
1494
1495 while (pn) {
1497 GWEN_XMLNODE *n;
1498 const char *p;
1499
1501 assert(p);
1502 DBG_DEBUG(GWEN_LOGDOMAIN, "Checking %s", p);
1503 if (strcasecmp(p, "VALUES")==0) {
1504 DBG_DEBUG(GWEN_LOGDOMAIN, "<values> found");
1505 /* <preset> found, check all values */
1507 while (n) {
1510 assert(p);
1511 if (strcasecmp(p, "VALUE")==0) {
1512 const char *pname;
1513 const char *pvalue;
1514
1515 pname=GWEN_XMLNode_GetProperty(n, "path", 0);
1516 if (pname) {
1517 DBG_DEBUG(GWEN_LOGDOMAIN, "Comparing against \"%s\"", pname);
1518 if (strcasecmp(name, pname)==0) {
1519 GWEN_XMLNODE *dn;
1520
1522 while (dn) {
1524 pvalue=GWEN_XMLNode_GetData(dn);
1525 if (pvalue) {
1526 DBG_DEBUG(GWEN_LOGDOMAIN, "Transforming \"%s\"", pvalue);
1528 pvalue,
1529 node,
1530 dnode,
1531 datasize);
1532 }
1533 if (pvalue)
1534 return pvalue;
1535 }
1536 dn=GWEN_XMLNode_Next(dn);
1537 } /* while dn */
1538 } /* if path matches name */
1539 } /* if path given */
1540 } /* if VALUE tag */
1541 } /* if TAG */
1542 n=GWEN_XMLNode_Next(n);
1543 } /* while */
1544 break; /* REMOVE this to check multiple groups */
1545 } /* if <preset> found */
1546 } /* if tag */
1547 pn=GWEN_XMLNode_Next(pn);
1548 } /* while node */
1549
1550 DBG_DEBUG(GWEN_LOGDOMAIN, "No value found for \"%s\" in <VALUES>", name);
1551 return 0;
1552}
1553
1554
1555
1557 GWEN_XMLNODE *node,
1558 const char *t,
1559 int version,
1560 const char *pvalue)
1561{
1562 GWEN_XMLNODE *n;
1563 const char *p;
1564 int i;
1565 const char *mode;
1566 unsigned int proto;
1567 char buffer[256];
1568
1569 if ((strlen(t)+4)>sizeof(buffer)) {
1570 DBG_ERROR(GWEN_LOGDOMAIN, "Type name too long.");
1571 return 0;
1572 }
1573
1574 mode=GWEN_MsgEngine_GetMode(e);
1576
1577 /* find type+"S" */
1578 strcpy(buffer, t);
1579 strcat(buffer, "S");
1580 n=GWEN_XMLNode_FindFirstTag(node, buffer, 0, 0);
1581 if (!n) {
1583 "No definitions here for type \"%s\"", t);
1584 return 0;
1585 }
1586
1587 /* find approppriate group definition */
1588 if (!mode)
1589 mode="";
1591 if (!n) {
1592 DBG_INFO(GWEN_LOGDOMAIN, "No definitions inside \"%s\"", buffer);
1593 return 0;
1594 }
1595
1596 /* find type+"def" */
1597 strcpy(buffer, t);
1598 strcat(buffer, "def");
1599 while (n) {
1601 assert(p);
1602 if (strcasecmp(p, buffer)==0 ||
1603 strcasecmp(p, t)==0) {
1604 p=GWEN_XMLNode_GetProperty(n, "id", "");
1605 if (strcasecmp(p, pvalue)!=0)
1606 p=GWEN_XMLNode_GetProperty(n, "name", "");
1607 if (strcasecmp(p, pvalue)==0) {
1608 i=atoi(GWEN_XMLNode_GetProperty(n, "pversion", "0"));
1609 if (proto==0 || (int)proto==i || i==0) {
1610 i=atoi(GWEN_XMLNode_GetProperty(n, "version", "0"));
1611 if (version==0 || version==i) {
1612 p=GWEN_XMLNode_GetProperty(n, "mode", "");
1613 if (strcasecmp(p, mode)==0 || !*p) {
1615 "Group definition for \"%s=%s\" found",
1616 t, pvalue);
1617 return n;
1618 }
1619 }
1620 }
1621 }
1622 }
1624 } /* while */
1625
1627 "Group definition for \"%s=%s\"(%d) not found here",
1628 t,
1629 pvalue,
1630 version);
1631 return 0;
1632}
1633
1634
1635
1637 GWEN_XMLNODE *node,
1638 const GWEN_XMLNODE_PATH *nodePath,
1639 const char *t,
1640 int version,
1641 const char *pvalue)
1642{
1643 GWEN_XMLNODE *n;
1644 GWEN_XMLNODE *nLast = 0;
1645 GWEN_XMLNODE *nRes = 0;
1646 GWEN_XMLNODE_PATH *pathCopy;
1647
1648 assert(node);
1649 assert(nodePath);
1650 assert(t);
1651 assert(pvalue);
1652
1653 pathCopy=GWEN_XMLNode_Path_dup(nodePath);
1654 n=GWEN_XMLNode_Path_Surface(pathCopy);
1655 /* first try all nodes along the path */
1656 while (n) {
1657 nLast=n;
1658 nRes=GWEN_MsgEngine__GetGroup(e, n, t, version, pvalue);
1659 if (nRes)
1660 break;
1661 n=GWEN_XMLNode_Path_Surface(pathCopy);
1662 }
1663 GWEN_XMLNode_Path_free(pathCopy);
1664 if (nRes) {
1665 /* already found */
1666 if (nRes==node) {
1667 DBG_ERROR(GWEN_LOGDOMAIN, "Loop detected.");
1668 return 0;
1669 }
1670 return nRes;
1671 }
1672
1673 if (nLast)
1674 n=nLast;
1675 else
1676 n=node;
1677
1678 if (n) {
1680 while (n) {
1681 nRes=GWEN_MsgEngine__GetGroup(e, n, t, version, pvalue);
1682 if (nRes)
1683 break;
1685 }
1686 }
1687
1688 /* try root as a last resort */
1689 if (!nRes && e->defs)
1690 nRes=GWEN_MsgEngine__GetGroup(e, e->defs, t, version, pvalue);
1691
1692 if (!nRes) {
1694 "Group definition for \"%s=%s\"(%d) not found",
1695 t,
1696 pvalue,
1697 version);
1698 return 0;
1699 }
1700 if (nRes==node) {
1701 DBG_ERROR(GWEN_LOGDOMAIN, "Loop detected.");
1702 return 0;
1703 }
1704 return nRes;
1705}
1706
1707
1708
1710 GWEN_BUFFER *gbuf,
1711 GWEN_XMLNODE *node,
1712 GWEN_XMLNODE *rnode,
1713 GWEN_DB_NODE *gr,
1714 int groupIsOptional,
1715 GWEN_XMLNODE_PATH *nodePath)
1716{
1717 GWEN_XMLNODE *n;
1718 const char *p;
1719 char delimiter;
1720 char terminator;
1721 int isFirstElement;
1722 int omittedElements;
1723 int hasEntries;
1724
1725
1726 /* get some settings */
1727 if (rnode) {
1728 /* get delimiter */
1730 "delimiter",
1732 "delimiter",
1733 ""));
1734 delimiter=*p;
1735
1736 /* get terminating char, if any */
1738 "terminator",
1740 "terminator",
1741 ""));
1742 terminator=*p;
1743 }
1744 else {
1745 /* get delimiter */
1747 "delimiter",
1748 "");
1749 delimiter=*p;
1750
1751 /* get terminating char, if any */
1752 p=GWEN_XMLNode_GetProperty(node, "terminator", "");
1753 terminator=*p;
1754 }
1755
1756 /* handle all child entries */
1757 n=GWEN_XMLNode_GetChild(node);
1758 isFirstElement=1;
1759 omittedElements=0;
1760 hasEntries=0;
1761 if (!n) {
1762 DBG_INFO(GWEN_LOGDOMAIN, "No subnodes !");
1763 }
1764 while (n) {
1765 int t;
1766 unsigned int minnum;
1767 unsigned int maxnum;
1768 int gversion;
1769 const char *addEmptyMode;
1770 unsigned int loopNr;
1771
1772 minnum=atoi(GWEN_XMLNode_GetProperty(n, "minnum", "1"));
1773 maxnum=atoi(GWEN_XMLNode_GetProperty(n, "maxnum", "1"));
1774 gversion=atoi(GWEN_XMLNode_GetProperty(n, "version", "0"));
1775 addEmptyMode=GWEN_XMLNode_GetProperty(n, "addemptymode", "one");
1776
1777 DBG_DEBUG(GWEN_LOGDOMAIN, "Omitted elements: %d", omittedElements);
1779 if (t==GWEN_XMLNodeTypeTag) {
1780 const char *typ;
1781
1782 typ=GWEN_XMLNode_GetData(n);
1783 if (typ==0) {
1784 DBG_ERROR(GWEN_LOGDOMAIN, "Unnamed tag found (internal error?)");
1785 return -1;
1786 }
1787 if (strcasecmp(typ, "ELEM")==0) {
1788 /* element tag found */
1789 int j;
1790 int rv;
1791
1792 DBG_VERBOUS(GWEN_LOGDOMAIN, "Found an element");
1793 /* write element as often as needed */
1794 for (loopNr=0; loopNr<maxnum; loopNr++) {
1795 unsigned int posBeforeElement;
1796
1797 posBeforeElement=GWEN_Buffer_GetPos(gbuf);
1798
1799 /* write delimiter, if needed */
1800 if (delimiter) {
1801 DBG_VERBOUS(GWEN_LOGDOMAIN, "Appending %d delimiters",
1802 omittedElements);
1803 for (j=0; j<omittedElements; j++) {
1804 if (GWEN_Buffer_AppendByte(gbuf, delimiter)) {
1805 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
1806 return -1;
1807 }
1808 }
1809 if (!isFirstElement)
1810 if (GWEN_Buffer_AppendByte(gbuf, delimiter)) {
1811 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
1812 return -1;
1813 }
1814 }
1815
1817 gbuf,
1818 n,
1819 gr,
1820 loopNr,
1821 loopNr>=minnum ||
1822 (groupIsOptional && !hasEntries),
1823 nodePath);
1824 if (rv==-1) {
1825 DBG_INFO(GWEN_LOGDOMAIN, "Error writing element");
1826 DBG_INFO(GWEN_LOGDOMAIN, "Node is:");
1827 GWEN_XMLNode_Dump(n, 1);
1828 if (gr) {
1829 DBG_INFO(GWEN_LOGDOMAIN, "Data is:");
1830 GWEN_DB_Dump(gr, 1);
1831 }
1832 return -1;
1833 }
1834 else if (rv==0) {
1835 isFirstElement=0;
1836 omittedElements=0;
1837 hasEntries=1;
1838 DBG_DEBUG(GWEN_LOGDOMAIN, "Element written");
1839 }
1840 else {
1841 /* element is optional, not found */
1842 /* restore position */
1843 GWEN_Buffer_SetPos(gbuf, posBeforeElement);
1844 GWEN_Buffer_Crop(gbuf, 0, posBeforeElement);
1845
1846 if (strcasecmp(addEmptyMode, "max")==0) {
1847 DBG_DEBUG(GWEN_LOGDOMAIN, "Adding max empty");
1848 omittedElements+=(maxnum-loopNr);
1849 }
1850 else if (strcasecmp(addEmptyMode, "min")==0) {
1851 DBG_DEBUG(GWEN_LOGDOMAIN, "Adding min empty");
1852 if (loopNr<minnum)
1853 omittedElements+=(minnum-loopNr);
1854 }
1855 else if (strcasecmp(addEmptyMode, "one")==0) {
1856 if (loopNr==0)
1857 omittedElements++;
1858 }
1859 else if (strcasecmp(addEmptyMode, "none")==0) {
1860 }
1861 else {
1862 DBG_ERROR(GWEN_LOGDOMAIN, "Unknown addemptymode \"%s\"",
1863 addEmptyMode);
1864 return -1;
1865 }
1866 break;
1867 }
1868 } /* for */
1869 }
1870 else if (strcasecmp(typ, "VALUES")==0) {
1871 }
1872 else if (strcasecmp(typ, "DESCR")==0) {
1873 }
1874 else {
1875 /* group tag found */
1876 GWEN_XMLNODE *gn;
1877 GWEN_DB_NODE *gcfg;
1878 const char *gname;
1879 const char *gtype;
1880 unsigned int posBeforeGroup;
1881
1882 DBG_VERBOUS(GWEN_LOGDOMAIN, "Found a group");
1883
1884 gcfg=0;
1885 gtype=GWEN_XMLNode_GetProperty(n, "type", 0);
1886 if (!gtype) {
1887 /* no "type" property, so use this group directly */
1888 DBG_INFO(GWEN_LOGDOMAIN, "<%s> tag has no \"type\" property", typ);
1889 gtype="";
1890 gn=n;
1891 }
1892 else {
1893 DBG_VERBOUS(GWEN_LOGDOMAIN, "<%s> tag is of type \"%s\"", typ, gtype);
1894 gn=GWEN_MsgEngine_GetGroup(e, n, nodePath, typ,
1895 gversion, gtype);
1896 if (!gn) {
1897 DBG_INFO(GWEN_LOGDOMAIN, "Definition for type \"%s\" not found", typ);
1898 return -1;
1899 }
1900 }
1901
1902 gname=NULL;
1903 gcfg=NULL;
1904 if (gr) {
1905 gname=GWEN_XMLNode_GetProperty(n, "name", 0);
1906 if (gname) {
1907 DBG_VERBOUS(GWEN_LOGDOMAIN, "Group \"%s\" using special data", gname);
1908 gcfg=GWEN_DB_FindFirstGroup(gr, gname);
1909 }
1910 else {
1911 DBG_DEBUG(GWEN_LOGDOMAIN, "Unnamed group, using basic data");
1912 /* TODO: check for maxnum==1, since only then the following line makes sense */
1913 gcfg=gr;
1914 }
1915 }
1916
1917 /* write group as often as needed */
1918 for (loopNr=0; loopNr<maxnum; loopNr++) {
1919 int rv;
1920 int groupIsEmpty;
1921
1922 groupIsEmpty=0;
1923 posBeforeGroup=GWEN_Buffer_GetPos(gbuf);
1924
1925 /* write delimiter, if needed */
1926 if (delimiter) {
1927 int j;
1928
1929 DBG_VERBOUS(GWEN_LOGDOMAIN, "Appending %d delimiters",
1930 omittedElements);
1931 for (j=0; j<omittedElements; j++) {
1932 if (GWEN_Buffer_AppendByte(gbuf, delimiter)) {
1933 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
1934 return -1;
1935 }
1936 }
1937 if (!isFirstElement)
1938 if (GWEN_Buffer_AppendByte(gbuf, delimiter)) {
1939 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
1940 return -1;
1941 }
1942 }
1943
1944 /* find next matching group */
1945 if (gcfg==0) {
1946 DBG_DEBUG(GWEN_LOGDOMAIN, "No group found");
1947 if (loopNr>=minnum)
1948 groupIsEmpty=1;
1949 }
1950
1951 if (groupIsEmpty) {
1952 /* empty group, flag as such */
1953 rv=1;
1954 }
1955 else {
1956 int dive;
1957
1958 /* write group */
1959 if (GWEN_XMLNode_Path_Dive(nodePath, n)) {
1960 DBG_INFO(GWEN_LOGDOMAIN, "Called from here");
1961 return -1;
1962 }
1963 if (n==gn)
1964 dive=1;
1965 else {
1966 if (GWEN_XMLNode_Path_Dive(nodePath, gn)) {
1967 DBG_INFO(GWEN_LOGDOMAIN, "Called from here");
1968 return -1;
1969 }
1970 dive=2;
1971 }
1973 gbuf,
1974 gn,
1975 n,
1976 gcfg,
1977 loopNr>=minnum || groupIsOptional,
1978 nodePath);
1979 GWEN_XMLNode_Path_Surface(nodePath);
1980 if (dive==2)
1981 GWEN_XMLNode_Path_Surface(nodePath);
1982 }
1983
1984 if (rv==-1) {
1985 DBG_INFO(GWEN_LOGDOMAIN, "Could not write group \"%s\"", gtype);
1986 if (gn) {
1987 DBG_INFO(GWEN_LOGDOMAIN, "Node is:");
1988 GWEN_XMLNode_Dump(gn, 1);
1989 }
1990 if (n) {
1991 DBG_INFO(GWEN_LOGDOMAIN, "Referring node is:");
1992 GWEN_XMLNode_Dump(n, 1);
1993 }
1994 if (gr) {
1995 DBG_INFO(GWEN_LOGDOMAIN, "Data is:");
1996 GWEN_DB_Dump(gr, 1);
1997 }
1998 return -1;
1999 }
2000 else if (rv==0) {
2001 isFirstElement=0;
2002 omittedElements=0;
2003 hasEntries=1;
2004 DBG_DEBUG(GWEN_LOGDOMAIN, "Element written");
2005 }
2006 else {
2007 /* group is optional, not found */
2008 /* restore position */
2009 GWEN_Buffer_SetPos(gbuf, posBeforeGroup);
2010 GWEN_Buffer_Crop(gbuf, 0, posBeforeGroup);
2011
2012 if (strcasecmp(addEmptyMode, "max")==0) {
2013 DBG_DEBUG(GWEN_LOGDOMAIN, "Adding max empty");
2014 omittedElements+=(maxnum-loopNr);
2015 }
2016 else if (strcasecmp(addEmptyMode, "min")==0) {
2017 DBG_DEBUG(GWEN_LOGDOMAIN, "Adding min empty");
2018 if (loopNr<minnum)
2019 omittedElements+=(minnum-loopNr);
2020 }
2021 else if (strcasecmp(addEmptyMode, "one")==0) {
2022 if (loopNr==0)
2023 omittedElements++;
2024 }
2025 else if (strcasecmp(addEmptyMode, "none")==0) {
2026 }
2027 else {
2028 DBG_ERROR(GWEN_LOGDOMAIN, "Unknown addemptymode \"%s\"",
2029 addEmptyMode);
2030 return -1;
2031 }
2032 break;
2033 }
2034
2035 /* use next group next time if any */
2036 if (gcfg && gname)
2037 gcfg=GWEN_DB_FindNextGroup(gcfg, gname);
2038 } /* for */
2039 } /* if "GROUP" */
2040 } /* if TAG */
2041 else if (t==GWEN_XMLNodeTypeData) {
2042 }
2043 else {
2044 DBG_DEBUG(GWEN_LOGDOMAIN, "Unhandled node type %d", t);
2045 }
2046 n=GWEN_XMLNode_Next(n);
2047 } /* while */
2048
2049 /* write terminating character, if any */
2050 if (terminator) {
2051 if (GWEN_Buffer_AppendByte(gbuf, terminator)) {
2052 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
2053 return -1;
2054 }
2055 }
2056
2057 if (!hasEntries) {
2058 DBG_INFO(GWEN_LOGDOMAIN, "No entries in node");
2059 }
2060 return hasEntries?0:1;
2061}
2062
2063
2064
2066 GWEN_XMLNODE *node,
2067 GWEN_BUFFER *gbuf,
2068 GWEN_DB_NODE *msgData)
2069{
2071 int rv;
2072
2073 assert(e);
2074 assert(node);
2075 assert(msgData);
2076
2078 GWEN_XMLNode_Path_Dive(np, node);
2080 gbuf,
2081 node,
2082 0,
2083 msgData,
2084 0,
2085 np);
2087 if (rv) {
2088 const char *p;
2089
2090 p=GWEN_XMLNode_GetData(node);
2091 if (p) {
2092 DBG_INFO(GWEN_LOGDOMAIN, "Error writing group \"%s\"", p);
2093 }
2094 else {
2095 DBG_INFO(GWEN_LOGDOMAIN, "Error writing group");
2096 }
2097 return -1;
2098 }
2099
2100 return 0;
2101}
2102
2103
2104
2106 const char *msgName,
2107 int msgVersion,
2108 GWEN_BUFFER *gbuf,
2109 GWEN_DB_NODE *msgData)
2110{
2111 GWEN_XMLNODE *group;
2112
2113 group=GWEN_MsgEngine_FindGroupByProperty(e, "id", msgVersion, msgName);
2114 if (!group) {
2115 DBG_ERROR(GWEN_LOGDOMAIN, "Group \"%s\" not found\n", msgName);
2116 return -1;
2117 }
2119 group,
2120 gbuf,
2121 msgData);
2122}
2123
2124
2125
2127 GWEN_XMLNODE *node)
2128{
2129 GWEN_XMLNODE *nsrc, *ndst;
2130
2131 assert(e);
2132 assert(node);
2133
2134 if (!e->defs) {
2135 e->defs=GWEN_XMLNode_dup(node);
2136 e->ownDefs=1;
2137 return 0;
2138 }
2139
2140 nsrc=GWEN_XMLNode_GetChild(node);
2141 while (nsrc) {
2144 GWEN_XMLNode_GetData(nsrc));
2145 if (ndst) {
2146 GWEN_XMLNODE *n;
2147
2148 n=GWEN_XMLNode_GetChild(nsrc);
2149 while (n) {
2150 GWEN_XMLNODE *newNode;
2151
2152 DBG_DEBUG(GWEN_LOGDOMAIN, "Adding node \"%s\"", GWEN_XMLNode_GetData(n));
2153 newNode=GWEN_XMLNode_dup(n);
2154 GWEN_XMLNode_AddChild(ndst, newNode);
2155 n=GWEN_XMLNode_Next(n);
2156 } /* while n */
2157 }
2158 else {
2159 GWEN_XMLNODE *newNode;
2160
2161 DBG_DEBUG(GWEN_LOGDOMAIN, "Adding branch \"%s\"", GWEN_XMLNode_GetData(nsrc));
2162 newNode=GWEN_XMLNode_dup(nsrc);
2163 GWEN_XMLNode_AddChild(e->defs, newNode);
2164 }
2165 } /* if TAG */
2166 nsrc=GWEN_XMLNode_Next(nsrc);
2167 } /* while */
2168
2169 return 0;
2170}
2171
2172
2173
2175 const char *path,
2176 GWEN_XMLNODE *node,
2177 GWEN_STRINGLIST *sl,
2178 uint32_t flags)
2179{
2180 const char *name;
2181 const char *type;
2182 const char *npath;
2183 unsigned int minsize;
2184 unsigned int maxsize;
2185 unsigned int minnum;
2186 unsigned int maxnum;
2187 int j;
2188 int isSet;
2189 char nbuffer[256];
2191
2192 /* get type */
2193 type=GWEN_XMLNode_GetProperty(node, "type", "ASCII");
2194
2195 /* get some sizes */
2196 minsize=atoi(GWEN_XMLNode_GetProperty(node, "minsize", "0"));
2197 maxsize=atoi(GWEN_XMLNode_GetProperty(node, "maxsize", "0"));
2198 minnum=atoi(GWEN_XMLNode_GetProperty(node, "minnum", "1"));
2199 maxnum=atoi(GWEN_XMLNode_GetProperty(node, "maxnum", "1"));
2200
2201 npath="";
2202 isSet=0;
2203
2204 /* get name */
2205 name=GWEN_XMLNode_GetProperty(node, "name", 0);
2206 if (path==0)
2207 path="";
2208
2209 if (name) {
2210 /* get value of a config variable */
2211 if (strlen(path)+strlen(name)+10>=sizeof(nbuffer)) {
2212 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
2213 return -1;
2214 }
2215 if (*path)
2216 sprintf(nbuffer, "%s/%s", path, name);
2217 else
2218 sprintf(nbuffer, "%s", name);
2219 npath=nbuffer;
2220 }
2221
2223 while (en) {
2225 if (strcasecmp(GWEN_StringListEntry_Data(en), npath)==0) {
2226 isSet=1;
2227 break;
2228 }
2230 } /* while */
2231
2232 if (isSet && (flags & GWEN_MSGENGINE_SHOW_FLAGS_NOSET))
2233 return 0;
2234
2235 fprintf(stdout, " %s",
2236 npath);
2237 j=GWEN_MSGENGINE_VARNAME_WIDTH-strlen(npath);
2238 if (j>0) {
2239 int i;
2240
2241 for (i=0; i<j; i++)
2242 fprintf(stdout, " ");
2243 }
2244 fprintf(stdout, "| %s", type);
2245 j=GWEN_MSGENGINE_TYPENAME_WIDTH-strlen(type);
2246 if (j>0) {
2247 int i;
2248
2249 for (i=0; i<j; i++)
2250 fprintf(stdout, " ");
2251 }
2252 fprintf(stdout, "| %4d-%4d", minsize, maxsize);
2253 fprintf(stdout, " | %3d ", maxnum);
2254 fprintf(stdout, " |");
2255 if (minnum==0)
2256 fprintf(stdout, " optvar");
2257 if (flags & GWEN_MSGENGINE_SHOW_FLAGS_OPTIONAL)
2258 fprintf(stdout, " optgrp");
2259
2260 if (isSet) {
2261 fprintf(stdout, " set");
2262 }
2263
2264 fprintf(stdout, "\n");
2265
2266 return 0;
2267}
2268
2269
2270
2272 const char *path,
2273 GWEN_XMLNODE *node,
2274 GWEN_STRINGLIST *sl,
2275 uint32_t flags)
2276{
2277 GWEN_XMLNODE *n;
2278 //int isFirstElement;
2279 /*int omittedElements;*/
2280 int rv;
2281
2282 /* setup data */
2283 n=GWEN_XMLNode_GetChild(node);
2284
2285 if (path==0)
2286 path="";
2287 if (*path=='/')
2288 path++;
2289
2290 while (n) {
2292 const char *p;
2293
2295 assert(p);
2296 DBG_DEBUG(GWEN_LOGDOMAIN, "Checking %s", p);
2297 if (strcasecmp(p, "VALUES")==0)
2298 break;
2299 } /* if tag */
2300 n=GWEN_XMLNode_Next(n);
2301 } /* while */
2302
2303 if (n) {
2304 DBG_DEBUG(GWEN_LOGDOMAIN, "<preset> found");
2305 /* <preset> found, handle all values */
2307 while (n) {
2309 const char *p;
2310
2312 assert(p);
2313 if (strcasecmp(p, "VALUE")==0) {
2314 const char *pname;
2315 const char *pvalue;
2316
2317 pname=GWEN_XMLNode_GetProperty(n, "path", 0);
2318 if (pname) {
2319 GWEN_XMLNODE *dn;
2320
2321 /* path found, find data */
2323 while (dn) {
2325 pvalue=GWEN_XMLNode_GetData(dn);
2326 if (pvalue) {
2327 char pbuffer[256];
2328
2329 /* check whether the value is a property */
2330 p=pvalue;
2331 while (*p && isspace((int)*p))
2332 p++;
2333 if (strlen(path)+strlen(pname)+2>sizeof(pbuffer)) {
2334 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
2335 return -1;
2336 }
2337 if (*path)
2338 sprintf(pbuffer, "%s/%s", path, pname);
2339 else
2340 sprintf(pbuffer, "%s", pname);
2342 pbuffer,
2343 0,
2344 1);
2345 }
2346 break;
2347 }
2348 dn=GWEN_XMLNode_Next(dn);
2349 } /* while dn */
2350 } /* if path given */
2351 } /* if VALUE tag */
2352 } /* if TAG */
2353 n=GWEN_XMLNode_Next(n);
2354 } /* while */
2355 } /* if <preset> found */
2356
2357 /* now handle all child entries */
2358 n=GWEN_XMLNode_GetChild(node);
2359 //isFirstElement=1;
2360 /*omittedElements=0;*/
2361 while (n) {
2362 int t;
2363 unsigned int minnum;
2364 unsigned int maxnum;
2365 int gversion;
2366 //const char *addEmptyMode;
2367 unsigned int loopNr;
2368 unsigned int lflags;
2369
2370 minnum=atoi(GWEN_XMLNode_GetProperty(n, "minnum", "1"));
2371 maxnum=atoi(GWEN_XMLNode_GetProperty(n, "maxnum", "1"));
2372 gversion=atoi(GWEN_XMLNode_GetProperty(n, "version", "0"));
2373 //addEmptyMode=GWEN_XMLNode_GetProperty(n, "addemptymode","one");
2374
2375 lflags=flags;
2376
2377 /*DBG_DEBUG(GWEN_LOGDOMAIN, "Omitted elements: %d", omittedElements);*/
2379 if (t==GWEN_XMLNodeTypeTag) {
2380 const char *typ;
2381
2382 typ=GWEN_XMLNode_GetData(n);
2383 if (typ==0) {
2384 DBG_ERROR(GWEN_LOGDOMAIN, "Unnamed tag found (internal error?)");
2385 return -1;
2386 }
2387 if (strcasecmp(typ, "ELEM")==0) {
2388 /* element tag found */
2389
2390 /* write element as often as needed */
2392 path,
2393 n,
2394 sl,
2395 lflags);
2396 if (rv==-1)
2397 return -1;
2398 else {
2399 //isFirstElement=0;
2400 /*omittedElements=0;*/
2401 }
2402 }
2403 else if (strcasecmp(typ, "VALUES")==0) {
2404 }
2405 else if (strcasecmp(typ, "DESCR")==0) {
2406 }
2407 else {
2408 /* group tag found */
2409 GWEN_XMLNODE *gn;
2410 const char *gname;
2411 const char *gtype;
2412
2413 if (minnum==0)
2414 lflags|=GWEN_MSGENGINE_SHOW_FLAGS_OPTIONAL;
2415
2416 gtype=GWEN_XMLNode_GetProperty(n, "type", 0);
2417 if (!gtype) {
2418 /* no "type" property, so use this group directly */
2419 DBG_DEBUG(GWEN_LOGDOMAIN, "<%s> tag has no \"type\" property", typ);
2420 gtype="";
2421 gn=n;
2422 }
2423 else {
2424 gn=GWEN_MsgEngine_FindNodeByProperty(e, typ, "id", gversion, gtype);
2425 if (!gn) {
2426 DBG_DEBUG(GWEN_LOGDOMAIN, "Definition for type \"%s\" not found", typ);
2427 return -1;
2428 }
2429 }
2430
2431 /* write group as often as needed */
2432 for (loopNr=0; loopNr<maxnum; loopNr++) {
2433 /* find group */
2434 char pbuffer[256];
2435 const char *npath;
2436
2437 /* get configuration */
2438 gname=GWEN_XMLNode_GetProperty(n, "name", 0);
2439 if (gname) {
2440 if (loopNr==0) {
2441 if (strlen(path)+strlen(gname)+1>sizeof(pbuffer)) {
2442 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
2443 return -1;
2444 }
2445 sprintf(pbuffer, "%s/%s", path, gname);
2446 npath=pbuffer;
2447 }
2448 else {
2449 /* this is not the first one, so create new name */
2450 if (strlen(path)+strlen(gname)+10>sizeof(pbuffer)) {
2451 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
2452 return -1;
2453 }
2454 if (*path)
2455 sprintf(pbuffer, "%s/%s%d", path, gname, loopNr);
2456 else
2457 sprintf(pbuffer, "%s%d", gname, loopNr);
2458 /* get the value of the given var */
2459 npath=pbuffer;
2460 }
2461 } /* if name given */
2462 else
2463 npath=path;
2464
2465 /* write group */
2466 if (GWEN_MsgEngine__ShowGroup(e, npath, gn, sl, lflags)) {
2467 DBG_INFO(GWEN_LOGDOMAIN, "Could not show group \"%s\"", gtype);
2468 return -1;
2469 }
2470 } /* for */
2471 }
2472 }
2473 n=GWEN_XMLNode_Next(n);
2474 } /* while */
2475
2476 return 0;
2477}
2478
2479
2480
2482 const char *typ,
2483 const char *msgName,
2484 int msgVersion,
2485 uint32_t flags)
2486{
2487 GWEN_XMLNODE *group;
2488 GWEN_STRINGLIST *sl;
2489 int i, j;
2490 const char *p;
2491
2493
2494 fprintf(stdout, "Message \"%s\" version %d\n",
2495 msgName, msgVersion);
2496 for (i=0; i<76; i++)
2497 fprintf(stdout, "=");
2498 fprintf(stdout, "\n");
2499 p=" Variable";
2500 fprintf(stdout, "%s", p);
2501 i=GWEN_MSGENGINE_VARNAME_WIDTH-strlen(p);
2502 for (j=0; j<i; j++)
2503 fprintf(stdout, " ");
2504
2505 fprintf(stdout, " |");
2506 p=" Type";
2507 fprintf(stdout, "%s", p);
2508 i=GWEN_MSGENGINE_TYPENAME_WIDTH-strlen(p);
2509 for (j=0; j<i; j++)
2510 fprintf(stdout, " ");
2511
2512 fprintf(stdout, " | Size | Num | Flags\n");
2513 for (i=0; i<76; i++)
2514 fprintf(stdout, "-");
2515 fprintf(stdout, "\n");
2516
2517 group=GWEN_MsgEngine_FindNodeByProperty(e, typ, "id", msgVersion, msgName);
2518 if (!group) {
2519 DBG_ERROR(GWEN_LOGDOMAIN, "Group \"%s\" not found\n", msgName);
2521 return -1;
2522 }
2523
2525 "",
2526 group,
2527 sl,
2528 flags)) {
2529 DBG_INFO(GWEN_LOGDOMAIN, "Error showing group \"%s\"", msgName);
2531 return -1;
2532 }
2533
2535
2536 return 0;
2537}
2538
2539
2540
2542 const char *path,
2543 GWEN_XMLNODE *node,
2544 GWEN_STRINGLIST *sl,
2545 GWEN_XMLNODE *listNode,
2546 uint32_t flags)
2547{
2548 const char *name;
2549 //const char *type;
2550 const char *npath;
2551 int isSet;
2552 char nbuffer[256];
2554 GWEN_XMLNODE *nn;
2555
2556 /* get type */
2557 //type=GWEN_XMLNode_GetProperty(node, "type","ASCII");
2558
2559 npath="";
2560 isSet=0;
2561
2562 /* get name */
2563 name=GWEN_XMLNode_GetProperty(node, "name", 0);
2564 if (path==0)
2565 path="";
2566
2567 if (name) {
2568 /* get value of a config variable */
2569 if (strlen(path)+strlen(name)+10>=sizeof(nbuffer)) {
2570 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
2571 return -1;
2572 }
2573 if (*path)
2574 sprintf(nbuffer, "%s/%s", path, name);
2575 else
2576 sprintf(nbuffer, "%s", name);
2577 npath=nbuffer;
2578 }
2579
2581 while (en) {
2583 if (strcasecmp(GWEN_StringListEntry_Data(en), npath)==0) {
2584 isSet=1;
2585 break;
2586 }
2588 } /* while */
2589
2590 if (isSet && (flags & GWEN_MSGENGINE_SHOW_FLAGS_NOSET))
2591 return 0;
2592
2593 nn=GWEN_XMLNode_dup(node);
2594 if (isSet)
2595 GWEN_XMLNode_SetProperty(nn, "GWEN_set", "1");
2596 GWEN_XMLNode_SetProperty(nn, "GWEN_path", npath);
2597 GWEN_XMLNode_AddChild(listNode, nn);
2598
2599 return 0;
2600}
2601
2602
2603
2605 const char *path,
2606 GWEN_XMLNODE *node,
2607 GWEN_STRINGLIST *sl,
2608 GWEN_XMLNODE *listNode,
2609 uint32_t flags)
2610{
2611 GWEN_XMLNODE *n;
2612 int rv;
2613
2614 /* setup data */
2615 n=GWEN_XMLNode_GetChild(node);
2616
2617 if (path==0)
2618 path="";
2619 if (*path=='/')
2620 path++;
2621
2622 while (n) {
2624 const char *p;
2625
2627 assert(p);
2628 DBG_DEBUG(GWEN_LOGDOMAIN, "Checking %s", p);
2629 if (strcasecmp(p, "VALUES")==0)
2630 break;
2631 } /* if tag */
2632 n=GWEN_XMLNode_Next(n);
2633 } /* while */
2634
2635 if (n) {
2636 DBG_DEBUG(GWEN_LOGDOMAIN, "<values> found");
2637 /* <values> found, handle all values */
2639 while (n) {
2641 const char *p;
2642
2644 assert(p);
2645 if (strcasecmp(p, "VALUE")==0) {
2646 const char *pname;
2647 const char *pvalue;
2648
2649 pname=GWEN_XMLNode_GetProperty(n, "path", 0);
2650 if (pname) {
2651 GWEN_XMLNODE *dn;
2652
2653 /* path found, find data */
2655 while (dn) {
2657 pvalue=GWEN_XMLNode_GetData(dn);
2658 if (pvalue) {
2659 char pbuffer[256];
2660
2661 /* check whether the value is a property */
2662 p=pvalue;
2663 while (*p && isspace((int)*p))
2664 p++;
2665 if (strlen(path)+strlen(pname)+2>sizeof(pbuffer)) {
2666 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
2667 return -1;
2668 }
2669 if (*path)
2670 sprintf(pbuffer, "%s/%s", path, pname);
2671 else
2672 sprintf(pbuffer, "%s", pname);
2673 DBG_INFO(GWEN_LOGDOMAIN, "Found preset value for %s", pbuffer);
2675 pbuffer,
2676 0,
2677 1);
2678 }
2679 break;
2680 }
2681 dn=GWEN_XMLNode_Next(dn);
2682 } /* while dn */
2683 } /* if path given */
2684 } /* if VALUE tag */
2685 } /* if TAG */
2686 n=GWEN_XMLNode_Next(n);
2687 } /* while */
2688 } /* if <values> found */
2689
2690 /* now handle all child entries */
2691 n=GWEN_XMLNode_GetChild(node);
2692 while (n) {
2693 int t;
2694 int gversion;
2695 unsigned int lflags;
2696
2697 gversion=atoi(GWEN_XMLNode_GetProperty(n, "version", "0"));
2698 lflags=flags;
2699
2701 if (t==GWEN_XMLNodeTypeTag) {
2702 const char *typ;
2703
2704 typ=GWEN_XMLNode_GetData(n);
2705 if (typ==0) {
2706 DBG_ERROR(GWEN_LOGDOMAIN, "Unnamed tag found (internal error?)");
2707 return -1;
2708 }
2709 if (strcasecmp(typ, "ELEM")==0) {
2710 /* element tag found */
2711
2712 /* list element */
2714 path,
2715 n,
2716 sl,
2717 listNode,
2718 lflags);
2719 if (rv==-1)
2720 return -1;
2721 }
2722 else if (strcasecmp(typ, "VALUES")==0) {
2723 }
2724 else if (strcasecmp(typ, "DESCR")==0) {
2725 }
2726 else {
2727 /* group tag found */
2728 GWEN_XMLNODE *gn;
2729 GWEN_XMLNODE *nn;
2730 const char *gname;
2731 const char *gtype;
2732 char pbuffer[256];
2733 const char *npath;
2734
2735 gtype=GWEN_XMLNode_GetProperty(n, "type", 0);
2736 if (!gtype) {
2737 /* no "type" property, so use this group directly */
2738 DBG_DEBUG(GWEN_LOGDOMAIN, "<%s> tag has no \"type\" property", typ);
2739 gtype="";
2740 gn=n;
2741 }
2742 else {
2743 gn=GWEN_MsgEngine_FindNodeByProperty(e, typ, "id", gversion, gtype);
2744 if (!gn) {
2745 DBG_DEBUG(GWEN_LOGDOMAIN, "Definition for type \"%s\" not found", typ);
2746 return -1;
2747 }
2748 }
2749
2750 /* get configuration */
2751 gname=GWEN_XMLNode_GetProperty(n, "name", 0);
2752 if (gname) {
2753 if (strlen(path)+strlen(gname)+1>sizeof(pbuffer)) {
2754 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
2755 return -1;
2756 }
2757
2758 if (*path)
2759 sprintf(pbuffer, "%s/%s", path, gname);
2760 else
2761 sprintf(pbuffer, "%s", gname);
2762 npath=pbuffer;
2763 } /* if name given */
2764 else
2765 npath=path;
2766
2767 nn=GWEN_XMLNode_dup(n);
2768 if (gn!=n)
2769 GWEN_XMLNode_CopyProperties(nn, gn, 0);
2770 GWEN_XMLNode_SetProperty(nn, "GWEN_path", npath);
2771 GWEN_XMLNode_AddChild(listNode, nn);
2772
2773 /* write group */
2774 if (GWEN_MsgEngine__ListGroup(e, npath, gn, sl, nn, lflags)) {
2775 DBG_INFO(GWEN_LOGDOMAIN, "Could not list group \"%s\"", gtype);
2776 return -1;
2777 }
2778 }
2779 }
2780 n=GWEN_XMLNode_Next(n);
2781 } /* while */
2782
2783 return 0;
2784}
2785
2786
2787
2789 const char *typ,
2790 const char *msgName,
2791 int msgVersion,
2792 uint32_t flags)
2793{
2794 GWEN_XMLNODE *group;
2795 GWEN_STRINGLIST *sl;
2796 GWEN_XMLNODE *listNode;
2797
2798 group=GWEN_MsgEngine_FindNodeByProperty(e, typ, "id", msgVersion, msgName);
2799 if (!group)
2800 group=GWEN_MsgEngine_FindNodeByProperty(e, typ, "code",
2801 msgVersion, msgName);
2802 if (!group) {
2803 DBG_ERROR(GWEN_LOGDOMAIN, "Group \"%s\" (version %d) not found\n",
2804 msgName, msgVersion);
2805 return 0;
2806 }
2807
2809 /* copy group, but remove all children (we only want the properties) */
2810 listNode=GWEN_XMLNode_dup(group);
2812
2813 if (GWEN_MsgEngine__ListGroup(e, "", group, sl, listNode, flags)) {
2814 DBG_INFO(GWEN_LOGDOMAIN, "Error showing group \"%s\"", msgName);
2816 GWEN_XMLNode_free(listNode);
2817 return 0;
2818 }
2819
2821
2822 return listNode;
2823}
2824
2825
2826
2827
2828
2829
2830
2832 GWEN_BUFFER *msgbuf,
2833 GWEN_XMLNODE *node,
2834 GWEN_XMLNODE *rnode,
2835 GWEN_BUFFER *vbuf,
2836 const char *delimiters,
2837 uint32_t flags)
2838{
2839 unsigned int minsize;
2840 unsigned int maxsize;
2841 unsigned int size;
2842 unsigned int minnum;
2843 GWEN_MSGENGINE_TRUSTLEVEL trustLevel;
2844 //unsigned int posInMsg;
2845 const char *type;
2846 int rv;
2847 unsigned int realSize;
2848
2849 /* get some sizes */
2850 //posInMsg=GWEN_Buffer_GetPos(msgbuf);
2851 realSize=0;
2852 size=atoi(GWEN_XMLNode_GetProperty(node, "size", "0"));
2853 minsize=atoi(GWEN_XMLNode_GetProperty(node, "minsize", "0"));
2854 maxsize=atoi(GWEN_XMLNode_GetProperty(node, "maxsize", "0"));
2855 minnum=atoi(GWEN_XMLNode_GetProperty(node, "minnum", "1"));
2856 type=GWEN_XMLNode_GetProperty(node, "type", "ASCII");
2857
2858 rv=1;
2859 if (e->typeReadPtr) {
2860 rv=e->typeReadPtr(e,
2861 msgbuf,
2862 node,
2863 vbuf,
2864 e->escapeChar,
2865 delimiters);
2866 }
2867 if (rv==-1) {
2868 DBG_INFO(GWEN_LOGDOMAIN, "External type reading failed on type \"%s\"", type);
2869 return -1;
2870 }
2871 else if (rv==1) {
2872 if (strcasecmp(type, "bin")==0) {
2873 if (GWEN_Buffer_GetBytesLeft(msgbuf)==0) {
2874 DBG_ERROR(GWEN_LOGDOMAIN, "Premature end of message (@num@ expected)");
2875 return -1;
2876 }
2877 else {
2878 char lbuffer[16];
2879 int c;
2880 char *p;
2881 int l;
2882
2883 p=lbuffer;
2884 c=GWEN_Buffer_ReadByte(msgbuf);
2885 if (c!='@') {
2886 DBG_ERROR(GWEN_LOGDOMAIN, "\"@num@\" expected");
2887 return -1;
2888 }
2889
2890 c=0;
2891 while (GWEN_Buffer_GetBytesLeft(msgbuf)>0) {
2892 c=GWEN_Buffer_ReadByte(msgbuf);
2893 if (c==-1) {
2894 DBG_ERROR(GWEN_LOGDOMAIN, "\"@\" expected");
2895 return -1;
2896 }
2897 if (c=='@')
2898 break;
2899 *p=(char)c;
2900 p++;
2901 } /* while */
2902 *p=0;
2903 if (c!='@') {
2904 DBG_ERROR(GWEN_LOGDOMAIN, "\"@num@\" expected");
2905 return -1;
2906 }
2907 if (sscanf(lbuffer, "%d", &l)!=1) {
2908 DBG_ERROR(GWEN_LOGDOMAIN, "Bad number format");
2909 return -1;
2910 }
2911 DBG_DEBUG(GWEN_LOGDOMAIN, "Reading binary: %d bytes from pos %d (msgsize=%d)",
2912 l,
2913 GWEN_Buffer_GetPos(msgbuf),
2914 GWEN_Buffer_GetUsedBytes(msgbuf));
2915 if (GWEN_Buffer_GetBytesLeft(msgbuf) < (unsigned) l) {
2916 DBG_ERROR(GWEN_LOGDOMAIN, "Premature end of message (binary beyond end)");
2917 return -1;
2918 }
2919 if (GWEN_Buffer_AppendBytes(vbuf,
2921 l)) {
2922 DBG_DEBUG(GWEN_LOGDOMAIN, "Called from here");
2923 return -1;
2924 }
2925 GWEN_Buffer_IncrementPos(msgbuf, l);
2926 }
2927 } /* if bin */
2928 else {
2929 /* type is not bin */
2930 int lastWasEscape;
2931 int isEscaped;
2932 int br;
2933
2934 isEscaped=0;
2935 lastWasEscape=0;
2936
2937 br=0;
2938 while (GWEN_Buffer_GetBytesLeft(msgbuf) &&
2939 (size==0 || br<(int)size)) {
2940 int c;
2941
2942 c=GWEN_Buffer_ReadByte(msgbuf);
2943 if (lastWasEscape) {
2944 lastWasEscape=0;
2945 isEscaped=1;
2946 }
2947 else {
2948 isEscaped=0;
2949 if (c==e->escapeChar) {
2950 lastWasEscape=1;
2951 c=-1;
2952 }
2953 }
2954 if (c!=-1) {
2955 if (!isEscaped && (c && strchr(delimiters, c)!=0)) {
2956 /* delimiter found, step back */
2957 GWEN_Buffer_DecrementPos(msgbuf, 1);
2958 break;
2959 }
2960 else {
2961 if (c=='\\' || iscntrl(c)) {
2963 "Found a bad character (%02x) in type \"%s\", "
2964 "converting to SPACE",
2965 (unsigned int)c,
2966 type);
2967 c=' ';
2968 }
2969 if (GWEN_Buffer_AppendByte(vbuf, c)) {
2970 DBG_DEBUG(GWEN_LOGDOMAIN, "Called from here");
2971 return -1;
2972 }
2973 br++;
2974 }
2975 }
2976 } /* while */
2977 } /* if !bin */
2978 } /* if type not external */
2979 else {
2980 DBG_DEBUG(GWEN_LOGDOMAIN, "Type \"%s\" is external (read)", type);
2981 }
2982
2983 realSize=GWEN_Buffer_GetUsedBytes(vbuf);
2984
2985 /* check the value */
2986 if (realSize==0) {
2987 DBG_DEBUG(GWEN_LOGDOMAIN, "Datasize is 0");
2988 if (minnum==0) {
2989 DBG_DEBUG(GWEN_LOGDOMAIN, "... but thats ok");
2990 /* value is empty, and that is allowed */
2991 return 1;
2992 }
2993 else {
2994 DBG_ERROR(GWEN_LOGDOMAIN, "Value missing");
2995 GWEN_XMLNode_Dump(node, 1);
2996 return -1;
2997 }
2998 }
2999
3000 /* check minimum size */
3001 if (minsize!=0 && realSize<minsize) {
3002 DBG_INFO(GWEN_LOGDOMAIN, "Value too short (%d<%d).",
3003 realSize,
3004 minsize);
3005 return -1;
3006 }
3007
3008 /* check maximum size */
3009 if (maxsize!=0 && realSize>maxsize) {
3010 DBG_INFO(GWEN_LOGDOMAIN, "Value too long (%d>%d).",
3011 realSize, maxsize);
3012 return -1;
3013 }
3014
3016 /* add trust data to msgEngine */
3017 const char *descr;
3018
3019 trustLevel=GWEN_MsgEngine_GetHighestTrustLevel(node, rnode);
3020 if (trustLevel) {
3021 unsigned int ustart;
3022
3023 ustart=GWEN_Buffer_GetPos(msgbuf)-realSize;
3024 descr=GWEN_XMLNode_GetProperty(node, "name", 0);
3027 realSize,
3028 descr,
3029 trustLevel,
3030 ustart)) {
3031 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
3032 return -1;
3033 }
3034 }
3035 }
3036
3037 return 0;
3038}
3039
3040
3041
3043 GWEN_BUFFER *msgbuf,
3044 GWEN_XMLNODE *node,
3045 GWEN_XMLNODE *rnode,
3046 GWEN_DB_NODE *gr,
3047 const char *delimiters,
3048 uint32_t flags)
3049{
3050 //unsigned int minsize;
3051 //unsigned int maxsize;
3052 unsigned int minnum;
3053 unsigned int maxnum;
3054 const char *p;
3055 char delimiter;
3056 char terminator;
3057 GWEN_XMLNODE *n;
3058 int abortLoop;
3059 GWEN_BUFFER *delimBuffer=0;
3060
3061 /* get some settings */
3062 if (rnode) {
3063 /* get delimiter */
3064 p=GWEN_XMLNode_GetProperty(rnode, "delimiter", GWEN_XMLNode_GetProperty(node, "delimiter", ""));
3065 delimiter=*p;
3066
3067 /* get terminating char, if any */
3068 p=GWEN_XMLNode_GetProperty(rnode, "terminator", GWEN_XMLNode_GetProperty(node, "terminator", ""));
3069 terminator=*p;
3070 }
3071 else {
3072 /* get delimiter */
3073 p=GWEN_XMLNode_GetProperty(node, "delimiter", "");
3074 delimiter=*p;
3075
3076 /* get terminating char, if any */
3077 p=GWEN_XMLNode_GetProperty(node, "terminator", "");
3078 terminator=*p;
3079 }
3080
3081 delimBuffer=GWEN_Buffer_new(0, strlen(delimiters)+2, 0, 1);
3082 GWEN_Buffer_AppendString(delimBuffer, delimiters);
3083 if (delimiter)
3084 GWEN_Buffer_AppendByte(delimBuffer, delimiter);
3085 if (terminator)
3086 GWEN_Buffer_AppendByte(delimBuffer, terminator);
3087
3088 DBG_DEBUG(GWEN_LOGDOMAIN, "Delimiters are \"%s\" and \"%c\"", delimiters, delimiter);
3089
3090 n=GWEN_XMLNode_GetChild(node);
3091 while (n) {
3093 const char *type;
3094
3095 if (GWEN_Buffer_GetBytesLeft(msgbuf)==0)
3096 break;
3097
3098 type=GWEN_XMLNode_GetData(n);
3099
3100#ifdef HEAVY_DEBUG_MSGENGINE
3101 DBG_NOTICE(GWEN_LOGDOMAIN, "Reading group from here :");
3104 3);
3105#endif
3106 if (strcasecmp(type, "ELEM")==0) {
3107 int rv;
3108
3109 rv=_groupReadElement(e, msgbuf, n, rnode, gr, delimiter, terminator, GWEN_Buffer_GetStart(delimBuffer), flags);
3110 if (rv<0) {
3111 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
3112 GWEN_Buffer_free(delimBuffer);
3113 return rv;
3114 }
3115 n=GWEN_XMLNode_Next(n);
3116 } /* if ELEM */
3117 else if (strcasecmp(type, "VALUES")==0) {
3118 n=GWEN_XMLNode_Next(n);
3119 }
3120 else if (strcasecmp(type, "DESCR")==0) {
3121 n=GWEN_XMLNode_Next(n);
3122 }
3123 else {
3124 /* group tag found */
3125 GWEN_XMLNODE *gn;
3126 GWEN_DB_NODE *gcfg;
3127 const char *gname;
3128 const char *gtype;
3129 unsigned int gversion;
3130 unsigned int loopNr;
3131
3132 DBG_VERBOUS(GWEN_LOGDOMAIN, "Reading group");
3133 minnum=atoi(GWEN_XMLNode_GetProperty(n, "minnum", "1"));
3134 maxnum=atoi(GWEN_XMLNode_GetProperty(n, "maxnum", "1"));
3135 gversion=atoi(GWEN_XMLNode_GetProperty(n, "version", "0"));
3136 gtype=GWEN_XMLNode_GetProperty(n, "type", 0);
3137 if (!gtype) {
3138 /* no "type" property, so use this group directly */
3139 DBG_INFO(GWEN_LOGDOMAIN, "<%s> tag has no \"type\" property", type);
3140 gtype="";
3141 gn=n;
3142 }
3143 else {
3144 gn=GWEN_MsgEngine_FindNodeByProperty(e, type, "id", gversion, gtype);
3145 if (!gn) {
3146 DBG_INFO(GWEN_LOGDOMAIN, "Definition for type \"%s\" not found", type);
3147 GWEN_Buffer_free(delimBuffer);
3148 return -1;
3149 }
3150 }
3151
3152 /* get configuration */
3153 loopNr=0;
3154 abortLoop=0;
3155 while ((maxnum==0 || loopNr<maxnum) && !abortLoop) {
3156 int c;
3157
3158 DBG_DEBUG(GWEN_LOGDOMAIN, "Reading group type %s", gtype);
3159 if (GWEN_Buffer_GetBytesLeft(msgbuf)==0)
3160 break;
3161 c=GWEN_Buffer_PeekByte(msgbuf);
3162 if (c &&
3163 (*gtype || (delimiter && delimiter == c) || (terminator && terminator == c)) &&
3164 strchr(GWEN_Buffer_GetStart(delimBuffer), c)) {
3165 abortLoop=1;
3166 }
3167 else {
3168 gname=GWEN_XMLNode_GetProperty(n, "name", 0);
3169 if (gname) {
3170 DBG_DEBUG(GWEN_LOGDOMAIN, "Creating group \"%s\"", gname);
3172 if (!gcfg) {
3173 DBG_ERROR(GWEN_LOGDOMAIN, "Could not select group \"%s\"", gname);
3174 GWEN_Buffer_free(delimBuffer);
3175 return -1;
3176 }
3177 DBG_DEBUG(GWEN_LOGDOMAIN, "Created group \"%s\"", gname);
3178 } /* if name given */
3179 else
3180 gcfg=gr;
3181
3182 /* read group */
3183 DBG_DEBUG(GWEN_LOGDOMAIN, "Reading group \"%s\"", gname);
3185 msgbuf,
3186 gn,
3187 n,
3188 gcfg,
3189 GWEN_Buffer_GetStart(delimBuffer),
3190 flags)) {
3191 DBG_INFO(GWEN_LOGDOMAIN, "Could not read group \"%s\"", gtype);
3192 GWEN_Buffer_free(delimBuffer);
3193 return -1;
3194 }
3195 }
3196 if (GWEN_Buffer_GetBytesLeft(msgbuf)) {
3197 if (delimiter) {
3198 if (GWEN_Buffer_PeekByte(msgbuf)==delimiter) {
3199 GWEN_Buffer_IncrementPos(msgbuf, 1);
3200 if (abortLoop && maxnum) {
3201 uint32_t loopOpt=loopNr+1;
3202
3203 if (maxnum-loopOpt>GWEN_Buffer_GetBytesLeft(msgbuf))
3204 /* Suspicious but not necessarily invalid, let's see */
3205 maxnum=loopOpt+GWEN_Buffer_GetBytesLeft(msgbuf);
3206 for (; loopOpt<maxnum; loopOpt++) {
3207 if (GWEN_Buffer_PeekByte(msgbuf)!=delimiter)
3208 break;
3209 GWEN_Buffer_IncrementPos(msgbuf, 1);
3210 }
3211 if (loopOpt+1==maxnum && terminator) {
3212 if (GWEN_Buffer_PeekByte(msgbuf)==terminator) {
3213 GWEN_Buffer_IncrementPos(msgbuf, 1);
3214 loopOpt++;
3215 }
3216 }
3217 if (loopOpt<maxnum) {
3219 "Delimiting character missing (pos=%d [%x]) "
3220 "expecting \"%c\", got \"%c\")",
3221 GWEN_Buffer_GetPos(msgbuf),
3222 GWEN_Buffer_GetPos(msgbuf),
3223 delimiter,
3224 GWEN_Buffer_PeekByte(msgbuf));
3225 GWEN_XMLNode_Dump(n, 2);
3226 GWEN_Buffer_free(delimBuffer);
3227 return -1;
3228 }
3229 }
3230 }
3231 }
3232 }
3233 loopNr++;
3234 } /* while */
3235 if (loopNr<minnum) {
3236 DBG_ERROR(GWEN_LOGDOMAIN, "Premature end of message (too few group repeats)");
3237 GWEN_Buffer_free(delimBuffer);
3238 return -1;
3239 }
3240 n=GWEN_XMLNode_Next(n);
3241 } /* if GROUP */
3242 } /* if TAG */
3243 else {
3244 n=GWEN_XMLNode_Next(n);
3245 }
3246 } /* while */
3247
3248 /* check whether there still are nodes which have not been read */
3249 while (n) {
3251 if (strcasecmp(GWEN_XMLNode_GetData(n), "ELEM")==0 ||
3252 strcasecmp(GWEN_XMLNode_GetData(n), "GROUP")==0) {
3253 unsigned int i;
3254
3255 i=atoi(GWEN_XMLNode_GetProperty(n, "minnum", "1"));
3256 if (i) {
3257 DBG_ERROR(GWEN_LOGDOMAIN, "Premature end of message (still tags to parse)");
3258 GWEN_XMLNode_Dump(n, 2);
3259 GWEN_Buffer_free(delimBuffer);
3260 return -1;
3261 }
3262 }
3263 }
3264 n=GWEN_XMLNode_Next(n);
3265 }
3266
3267
3268 if (terminator) {
3269 /* skip terminator */
3270 if (GWEN_Buffer_GetBytesLeft(msgbuf)) {
3271 if (GWEN_Buffer_PeekByte(msgbuf)==terminator) {
3272 GWEN_Buffer_IncrementPos(msgbuf, 1);
3273 }
3274 else {
3276 "Terminating character missing (pos=%d [%x]) "
3277 "expecting \"%c\", got \"%c\")",
3278 GWEN_Buffer_GetPos(msgbuf),
3279 GWEN_Buffer_GetPos(msgbuf),
3280 terminator,
3281 GWEN_Buffer_PeekByte(msgbuf));
3282 GWEN_XMLNode_Dump(node, 1);
3283 GWEN_Buffer_free(delimBuffer);
3284 return -1;
3285 }
3286 }
3287 else {
3288 DBG_ERROR(GWEN_LOGDOMAIN, "Terminating character missing");
3289 GWEN_Buffer_free(delimBuffer);
3290 return -1;
3291 }
3292 }
3293
3294 GWEN_Buffer_free(delimBuffer);
3295 return 0;
3296}
3297
3298
3299
3301 GWEN_BUFFER *msgbuf,
3302 GWEN_XMLNODE *n,
3303 GWEN_XMLNODE *rnode,
3304 GWEN_DB_NODE *gr,
3305 char currentDelimiter,
3306 char currentTerminator,
3307 const char *delimiters,
3308 uint32_t flags)
3309{
3310 unsigned int loopNr;
3311 unsigned int minnum;
3312 unsigned int maxnum;
3313 const char *name;
3314 int abortLoop;
3315
3316 DBG_VERBOUS(GWEN_LOGDOMAIN, "Reading element");
3317
3318 /* get some sizes */
3319 //minsize=atoi(GWEN_XMLNode_GetProperty(n, "minsize","0"));
3320 //maxsize=atoi(GWEN_XMLNode_GetProperty(n, "maxsize","0"));
3321 minnum=atoi(GWEN_XMLNode_GetProperty(n, "minnum", "1"));
3322 maxnum=atoi(GWEN_XMLNode_GetProperty(n, "maxnum", "1"));
3323 name=GWEN_XMLNode_GetProperty(n, "name", 0);
3324
3325 loopNr=0;
3326 abortLoop=0;
3327 while ((maxnum==0 || loopNr<maxnum) && !abortLoop) {
3328 int c;
3329
3330 DBG_VERBOUS(GWEN_LOGDOMAIN, "Reading %s", name);
3331 if (GWEN_Buffer_GetBytesLeft(msgbuf)==0)
3332 break;
3333 c=GWEN_Buffer_PeekByte(msgbuf);
3334 if (c==-1) {
3335 DBG_DEBUG(GWEN_LOGDOMAIN, "called from here");
3336 return -1;
3337 }
3338
3340 "Checking delimiter at pos %x "
3341 "(whether \"%c\" is in \"%s\")",
3342 GWEN_Buffer_GetPos(msgbuf),
3343 c, delimiters);
3344 if (c && strchr(delimiters, c)) {
3345 abortLoop=1;
3347 "Found delimiter (\"%c\" is in \"%s\")",
3348 c, delimiters);
3349 } /* if delimiter found */
3350 else {
3351 /* current char is not a delimiter */
3352 if (name==0) {
3353 DBG_VERBOUS(GWEN_LOGDOMAIN, "no name");
3354 }
3355 else {
3356 /* name is given */
3357 int rv;
3358 const char *dtype;
3359 GWEN_BUFFER *vbuf;
3360
3361 DBG_VERBOUS(GWEN_LOGDOMAIN, "Reading value from pos %x", GWEN_Buffer_GetPos(msgbuf));
3363#ifdef HEAVY_DEBUG_MSGENGINE
3364 DBG_ERROR(GWEN_LOGDOMAIN, "Reading value from here:\n");
3367 1);
3368#endif
3369
3370 rv=GWEN_MsgEngine__ReadValue(e, msgbuf, n, rnode, vbuf, delimiters, flags);
3371 if (rv==1) {
3372 DBG_INFO(GWEN_LOGDOMAIN, "Empty value");
3373 }
3374 else if (rv==-1) {
3375 DBG_INFO(GWEN_LOGDOMAIN, "Error parsing node \"%s\" (ELEM)", name);
3376 GWEN_Buffer_free(vbuf);
3377 return -1;
3378 }
3379
3380 GWEN_Buffer_Rewind(vbuf);
3381
3382 /* special handling for binary data */
3383 dtype=GWEN_XMLNode_GetProperty(n, "type", "");
3384 if (GWEN_MsgEngine__IsBinTyp(e, dtype)) {
3385 if (atoi(GWEN_XMLNode_GetProperty(n, "readbin", "1")) && e->binTypeReadPtr) {
3386 rv=e->binTypeReadPtr(e, n, gr, vbuf);
3387 }
3388 else
3389 rv=1;
3390 if (rv==-1) {
3391 DBG_INFO(GWEN_LOGDOMAIN, "Called from here");
3392 GWEN_Buffer_free(vbuf);
3393 return -1;
3394 }
3395 else if (rv==1) {
3396 /* bin type not handled, so handle it myself */
3397 if (GWEN_DB_SetBinValue(gr,
3399 name,
3401 GWEN_Buffer_GetUsedBytes(vbuf))) {
3402 DBG_INFO(GWEN_LOGDOMAIN, "Could not set value for \"%s\"", name);
3403 GWEN_Buffer_free(vbuf);
3404 return -1;
3405 }
3406 }
3407 } /* if type is bin */
3408 else if (GWEN_MsgEngine__IsIntTyp(e, dtype)) {
3409 int z;
3410
3411 if (1!=sscanf(GWEN_Buffer_GetStart(vbuf), "%d", &z)) {
3412 DBG_INFO(GWEN_LOGDOMAIN, "Value for \"%s\" is not an integer", name);
3413 return -1;
3414 }
3415 if (GWEN_DB_SetIntValue(gr, GWEN_DB_FLAGS_DEFAULT, name, z)) {
3416 DBG_INFO(GWEN_LOGDOMAIN, "Could not set int value for \"%s\"", name);
3417 return -1;
3418 }
3419 } /* if type is int */
3420 else {
3421 DBG_DEBUG(GWEN_LOGDOMAIN, "Value is \"%s\"", GWEN_Buffer_GetStart(vbuf));
3422 if (GWEN_DB_SetCharValue(gr,
3424 name,
3425 GWEN_Buffer_GetStart(vbuf))) {
3426 DBG_INFO(GWEN_LOGDOMAIN, "Could not set value for \"%s\"", name);
3427 return -1;
3428 }
3429 } /* if !bin */
3430
3431 GWEN_Buffer_free(vbuf);
3432 } /* if name is given */
3433 } /* if current char is not a delimiter */
3434
3435 if (GWEN_Buffer_GetBytesLeft(msgbuf)) {
3436 if (currentDelimiter) {
3437 if (GWEN_Buffer_PeekByte(msgbuf)==currentDelimiter) {
3438 GWEN_Buffer_IncrementPos(msgbuf, 1);
3439 if (abortLoop && maxnum) {
3440 uint32_t loopOpt=loopNr+1;
3441
3442 if (maxnum-loopOpt>GWEN_Buffer_GetBytesLeft(msgbuf))
3443 /* Suspicious but not necessarily invalid, let's see */
3444 maxnum=loopOpt+GWEN_Buffer_GetBytesLeft(msgbuf);
3445 for (; loopOpt<maxnum; loopOpt++) {
3446 if (GWEN_Buffer_PeekByte(msgbuf)!=currentDelimiter)
3447 break;
3448 GWEN_Buffer_IncrementPos(msgbuf, 1);
3449 }
3450 if (loopOpt+1==maxnum && currentTerminator) {
3451 if (GWEN_Buffer_PeekByte(msgbuf)==currentTerminator) {
3452 GWEN_Buffer_IncrementPos(msgbuf, 1);
3453 loopOpt++;
3454 }
3455 }
3456 if (loopOpt<maxnum) {
3458 "Delimiting character missing (pos=%d [%x]) "
3459 "expecting \"%c\", got \"%c\")",
3460 GWEN_Buffer_GetPos(msgbuf),
3461 GWEN_Buffer_GetPos(msgbuf),
3462 currentDelimiter,
3463 GWEN_Buffer_PeekByte(msgbuf));
3464 GWEN_XMLNode_Dump(n, 2);
3465 return -1;
3466 }
3467 }
3468 }
3469 }
3470 }
3471 loopNr++;
3472 } /* while */
3473 if (loopNr<minnum) {
3474 DBG_ERROR(GWEN_LOGDOMAIN, "Premature end of message (too few ELEM repeats)");
3475 GWEN_XMLNode_Dump(n, 2);
3476 return -1;
3477 }
3478
3479 return 0;
3480}
3481
3482
3483
3484
3485
3487 GWEN_XMLNODE *group,
3488 GWEN_BUFFER *msgbuf,
3489 GWEN_DB_NODE *msgData,
3490 uint32_t flags)
3491{
3492
3494 msgbuf,
3495 group,
3496 0,
3497 msgData,
3498 e->delimiters,
3499 flags)) {
3500 DBG_INFO(GWEN_LOGDOMAIN, "Error reading group");
3501 return -1;
3502 }
3503
3504 return 0;
3505}
3506
3507
3508
3510 const char *path,
3511 const char *value)
3512{
3513 GWEN_DB_NODE *globalValues;
3514
3515 assert(e);
3516 globalValues=GWEN_MsgEngine__GetGlobalValues(e);
3517 assert(globalValues);
3518 return GWEN_DB_SetCharValue(globalValues,
3521 path, value);
3522}
3523
3524
3525
3527 const char *path,
3528 int value)
3529{
3530 GWEN_DB_NODE *globalValues;
3531
3532 assert(e);
3533 globalValues=GWEN_MsgEngine__GetGlobalValues(e);
3534 assert(globalValues);
3535 return GWEN_DB_SetIntValue(globalValues,
3538 path, value);
3539}
3540
3541
3542
3544 const char *path,
3545 const char *defValue)
3546{
3547 GWEN_DB_NODE *globalValues;
3548
3549 assert(e);
3550 globalValues=GWEN_MsgEngine__GetGlobalValues(e);
3551 assert(globalValues);
3552 return GWEN_DB_GetCharValue(globalValues,
3553 path, 0, defValue);
3554}
3555
3556
3557
3559 const char *path,
3560 int defValue)
3561{
3562 GWEN_DB_NODE *globalValues;
3563
3564 assert(e);
3565 globalValues=GWEN_MsgEngine__GetGlobalValues(e);
3566 assert(globalValues);
3567 return GWEN_DB_GetIntValue(globalValues,
3568 path, 0, defValue);
3569}
3570
3571
3572
3573/* --------------------------------------------------------------- FUNCTION */
3575 GWEN_BUFFER *msgbuf,
3576 unsigned char escapeChar,
3577 unsigned char delimiter)
3578{
3579 int esc;
3580
3581 esc=0;
3582 while (GWEN_Buffer_GetBytesLeft(msgbuf)) {
3583 int nc;
3584
3585 if (esc) {
3586 esc=0;
3587 /* skip byte */
3588 nc=GWEN_Buffer_ReadByte(msgbuf);
3589 if (nc<0) {
3590 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", nc);
3591 return -1;
3592 }
3593 }
3594 else {
3595 int i;
3596 unsigned char c;
3597
3598 i=GWEN_Buffer_ReadByte(msgbuf);
3599 if (i<0) {
3600 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
3601 return 0;
3602 }
3603 c=(unsigned int)i;
3604 if (c==escapeChar) { /* escape */
3605 esc=1;
3606 }
3607 else if (c=='@') {
3608 /* skip binary data */
3609 char lbuffer[16];
3610 char *p;
3611 int l;
3612
3613 p=lbuffer;
3614 while (1) {
3615 nc=GWEN_Buffer_ReadByte(msgbuf);
3616 if (nc<0) {
3617 DBG_ERROR(GWEN_LOGDOMAIN, "\"@num@\" expected");
3618 return -1;
3619 }
3620 if (nc=='@')
3621 break;
3622 *p=nc;
3623 p++;
3624 } /* while */
3625 *p=0;
3626 if (sscanf(lbuffer, "%d", &l)!=1) {
3627 DBG_ERROR(GWEN_LOGDOMAIN, "Bad number format");
3628 return -1;
3629 }
3631 < (unsigned) l) {
3632 DBG_ERROR(GWEN_LOGDOMAIN, "Premature end of message (binary beyond end)");
3633 return -1;
3634 }
3635 GWEN_Buffer_IncrementPos(msgbuf, l);
3636 }
3637 else if (c==delimiter) {/* segment-end */
3638 return 0;
3639 break;
3640 }
3641 }
3642 } /* while */
3643
3644 DBG_ERROR(GWEN_LOGDOMAIN, "End of segment not found");
3645 return -1;
3646}
3647
3648
3649
3650/* --------------------------------------------------------------- FUNCTION */
3652 const char *gtype,
3653 GWEN_BUFFER *mbuf,
3654 GWEN_DB_NODE *gr,
3655 uint32_t flags)
3656{
3657 unsigned int segments;
3658
3659 segments=0;
3660
3661 while (GWEN_Buffer_GetBytesLeft(mbuf)) {
3662 GWEN_XMLNODE *node;
3663 unsigned int posBak;
3664 const char *p;
3665 GWEN_DB_NODE *tmpdb;
3666 int segVer;
3667
3668 /* find head segment description */
3669 tmpdb=GWEN_DB_Group_new("tmpdb");
3671 "id",
3672 0,
3673 "SegHead");
3674 if (node==0) {
3675 DBG_ERROR(GWEN_LOGDOMAIN, "Segment description not found");
3676 GWEN_DB_Group_free(tmpdb);
3677 return -1;
3678 }
3679
3680 /* parse head segment */
3681 posBak=GWEN_Buffer_GetPos(mbuf);
3683 node,
3684 mbuf,
3685 tmpdb,
3686 flags)) {
3687 DBG_ERROR(GWEN_LOGDOMAIN, "Error parsing segment head");
3688 GWEN_DB_Group_free(tmpdb);
3689 return -1;
3690 }
3691
3692 /* get segment code */
3693 segVer=GWEN_DB_GetIntValue(tmpdb,
3694 "version",
3695 0,
3696 0);
3697 p=GWEN_DB_GetCharValue(tmpdb,
3698 "code",
3699 0,
3700 0);
3701 if (!p) {
3702 DBG_ERROR(GWEN_LOGDOMAIN, "No segment code for %s ? This seems to be a bad msg...",
3703 gtype);
3704 GWEN_Buffer_SetPos(mbuf, posBak);
3705 DBG_ERROR(GWEN_LOGDOMAIN, "Full message (pos=%04x)", posBak);
3708 1);
3709 GWEN_DB_Dump(tmpdb, 1);
3710 GWEN_DB_Group_free(tmpdb);
3711 return -1;
3712 }
3713
3714 /* try to find corresponding XML node */
3716 gtype,
3717 "code",
3718 segVer,
3719 p);
3720 if (node==0) {
3721 unsigned int ustart;
3722
3723 ustart=GWEN_Buffer_GetPos(mbuf);
3724 ustart++; /* skip delimiter */
3725
3726 /* node not found, skip it */
3728 "Unknown segment \"%s\" (Segnum=%d, version=%d, ref=%d)",
3729 p,
3730 GWEN_DB_GetIntValue(tmpdb, "seq", 0, -1),
3731 GWEN_DB_GetIntValue(tmpdb, "version", 0, -1),
3732 GWEN_DB_GetIntValue(tmpdb, "ref", 0, -1));
3733 if (GWEN_MsgEngine_SkipSegment(e, mbuf, '?', '\'')) {
3734 DBG_ERROR(GWEN_LOGDOMAIN, "Error skipping segment \"%s\"", p);
3735 GWEN_DB_Group_free(tmpdb);
3736 return -1;
3737 }
3739 unsigned int usize;
3740
3741 usize=GWEN_Buffer_GetPos(mbuf)-ustart-1;
3742#if 0
3744 usize,
3745 stderr, 1);
3746#endif
3748 GWEN_Buffer_GetStart(mbuf)+ustart,
3749 usize,
3750 p,
3752 ustart)) {
3753 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
3754 GWEN_DB_Group_free(tmpdb);
3755 return -1;
3756 }
3757 } /* if trustInfo handling wanted */
3758 }
3759 else {
3760 /* ok, node available, get the corresponding description and parse
3761 * the segment */
3762 const char *id;
3763 GWEN_DB_NODE *storegrp;
3764 unsigned int startPos;
3765
3766 /* restore start position, since the segment head is part of a full
3767 * description, so we need to restart reading from the very begin */
3768 GWEN_Buffer_SetPos(mbuf, posBak);
3769
3770 /* create group in DB for this segment */
3771 id=GWEN_XMLNode_GetProperty(node, "id", p);
3772 storegrp=GWEN_DB_GetGroup(gr,
3774 id);
3775 assert(storegrp);
3776
3777 /* store the start position of this segment within the DB */
3778 startPos=GWEN_Buffer_GetPos(mbuf);
3779 GWEN_DB_SetIntValue(storegrp,
3781 "segment/pos",
3782 startPos);
3783
3784 /* parse the segment */
3786 node,
3787 mbuf,
3788 storegrp,
3789 flags)) {
3790 DBG_ERROR(GWEN_LOGDOMAIN, "Error parsing segment \"%s\" at %d (%x)",
3791 p,
3792 GWEN_Buffer_GetPos(mbuf)-startPos,
3793 GWEN_Buffer_GetPos(mbuf)-startPos);
3795 GWEN_Buffer_GetUsedBytes(mbuf)-startPos,
3796 1);
3797 DBG_ERROR(GWEN_LOGDOMAIN, "Stored data so far:");
3798 GWEN_DB_Dump(storegrp, 2);
3799 GWEN_DB_Group_free(tmpdb);
3800 return -1;
3801 }
3802
3803 /* store segment size within DB */
3804 GWEN_DB_SetIntValue(storegrp,
3806 "segment/length",
3807 GWEN_Buffer_GetPos(mbuf)-startPos);
3808 segments++;
3809 }
3810 GWEN_DB_Group_free(tmpdb);
3811 } /* while */
3812
3813 /* done */
3814 if (segments) {
3815 DBG_DEBUG(GWEN_LOGDOMAIN, "Parsed %d segments", segments);
3816 return 0;
3817 }
3818 else {
3819 DBG_INFO(GWEN_LOGDOMAIN, "No segments parsed.");
3820 return 1;
3821 }
3822}
3823
3824
3825
3826
3827
3828
3829
3830
3832 unsigned int size,
3833 const char *description,
3834 GWEN_MSGENGINE_TRUSTLEVEL trustLevel)
3835{
3837
3838 assert(data);
3839 assert(size);
3841 td->data=(char *)malloc(size);
3842 assert(td->data);
3843 memmove(td->data, data, size);
3844 if (description)
3845 td->description=strdup(description);
3846 td->trustLevel=trustLevel;
3847 td->size=size;
3848 return td;
3849}
3850
3851
3852
3854{
3855 if (td) {
3856 free(td->data);
3857 free(td->description);
3858 free(td->replacement);
3859 GWEN_FREE_OBJECT(td);
3860 }
3861}
3862
3863
3864
3870
3871
3872
3874{
3875 assert(td);
3876 return td->data;
3877}
3878
3879
3880
3882{
3883 assert(td);
3884 return td->size;
3885}
3886
3887
3888
3890{
3891 assert(td);
3892 return td->description;
3893}
3894
3895
3896
3898{
3899 assert(td);
3900 return td->trustLevel;
3901}
3902
3903
3904
3906{
3907 assert(td);
3908 return td->replacement;
3909}
3910
3911
3912
3914 unsigned int pos)
3915{
3916 assert(td);
3917 if (td->posCount>=GWEN_MSGENGINE_TRUSTEDDATA_MAXPOS)
3918 return -1;
3919 td->positions[td->posCount++]=pos;
3920 return 0;
3921}
3922
3923
3924
3926{
3927 assert(td);
3928 td->posPointer=0;
3930}
3931
3932
3933
3935{
3936 assert(td);
3937 if (td->posPointer>=td->posCount)
3938 return -1;
3939 return td->positions[td->posPointer++];
3940}
3941
3942
3943
3945 *td)
3946{
3947 unsigned int nextNr;
3949 unsigned int count;
3950
3951 assert(td);
3952 count=0;
3953 ntd=td;
3954 while (ntd) {
3955 count++;
3956 ntd=ntd->next;
3957 }
3958
3959 if (count<0x10)
3960 nextNr=0x01;
3961 else
3962 nextNr=0x11;
3963
3964 ntd=td;
3965 while (ntd) {
3966 unsigned int i;
3967 char numbuffer[32];
3968 char *rp;
3970 int match;
3971
3972 /* check whether the same data already exists */
3973 std=td;
3974 match=0;
3975 while (std && std!=ntd) {
3976
3977 match=1;
3978 if (std->size==ntd->size) {
3979 for (i=0; i<td->size; i++) {
3980 if (std->data[i]!=ntd->data[i]) {
3981 match=0;
3982 break;
3983 }
3984 } /* for */
3985 }
3986 else
3987 match=0;
3988
3989 if (match)
3990 break;
3991 std=std->next;
3992 } /* while */
3993
3994 if (match) {
3995 /* copy the found match */
3996 rp=strdup(std->replacement);
3997 }
3998 else {
3999 /* this is a new one */
4000 rp=(char *)malloc(ntd->size+1);
4001 assert(rp);
4002
4003 if (ntd->size==1) {
4004 if (count>=0x10)
4005 nextNr+=0x10;
4006 }
4007 sprintf(numbuffer, "%02X", nextNr++);
4008 for (i=0; i<ntd->size; i++) {
4009 if (count<0x10)
4010 rp[i]=numbuffer[1];
4011 else
4012 rp[i]=numbuffer[1-(i&1)];
4013 } /* for */
4014 rp[i]=0;
4015 }
4016 /*
4017 DBG_DEBUG(GWEN_LOGDOMAIN, "Replacement: \"%s\" for \"%s\" (%d)", rp,
4018 ntd->description,
4019 ntd->size);
4020 */
4021 free(ntd->replacement);
4022 ntd->replacement=rp;
4023
4024 ntd=ntd->next;
4025 } /* while */
4026 return 0;
4027}
4028
4029
4030
4032{
4034
4035 assert(e);
4036 td=e->trustInfos;
4037 e->trustInfos=0;
4038 return td;
4039}
4040
4041
4042
4043
4045 const char *data,
4046 unsigned int size,
4047 const char *description,
4048 GWEN_MSGENGINE_TRUSTLEVEL trustLevel,
4049 unsigned int pos)
4050{
4052 int match;
4053
4054 assert(e);
4055 assert(data);
4056 assert(size);
4057
4058 if (!description)
4059 description="";
4060
4061 td=e->trustInfos;
4062 while (td) {
4063 unsigned int i;
4064
4065 /* compare data */
4066 if (td->size==size &&
4067 *description &&
4068 *(td->description) &&
4069 trustLevel==td->trustLevel &&
4070 strcasecmp(description, td->description)==0) {
4071 match=1;
4072 for (i=0; i<td->size; i++) {
4073 if (td->data[i]!=data[i]) {
4074 match=0;
4075 break;
4076 }
4077 } /* for */
4078 }
4079 else
4080 match=0;
4081
4082 if (match)
4083 break;
4084 td=td->next;
4085 } /* while */
4086
4087 if (!td) {
4088 DBG_INFO(GWEN_LOGDOMAIN, "Creating new trustInfo for \"%s\" (%d)",
4089 description, size);
4091 size,
4092 description,
4093 trustLevel);
4094 GWEN_LIST_ADD(GWEN_MSGENGINE_TRUSTEDDATA, td, &(e->trustInfos));
4095 }
4096 else {
4097 DBG_INFO(GWEN_LOGDOMAIN, "Reusing trustInfo for \"%s\" (%d)",
4098 description, size);
4099 }
4101 return 0;
4102}
4103
4104
4105
#define NULL
Definition binreloc.c:300
int GWEN_Buffer_DecrementPos(GWEN_BUFFER *bf, uint32_t i)
Definition buffer.c:490
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition buffer.c:42
void GWEN_Buffer_SetStep(GWEN_BUFFER *bf, uint32_t step)
Definition buffer.c:716
int GWEN_Buffer_IncrementPos(GWEN_BUFFER *bf, uint32_t i)
Definition buffer.c:451
int GWEN_Buffer_SetPos(GWEN_BUFFER *bf, uint32_t i)
Definition buffer.c:261
int GWEN_Buffer_AdjustUsedBytes(GWEN_BUFFER *bf)
Definition buffer.c:468
uint32_t GWEN_Buffer_GetBytesLeft(GWEN_BUFFER *bf)
Definition buffer.c:536
int GWEN_Buffer_PeekByte(GWEN_BUFFER *bf)
Definition buffer.c:425
void GWEN_Buffer_Rewind(GWEN_BUFFER *bf)
Definition buffer.c:663
char * GWEN_Buffer_GetPosPointer(const GWEN_BUFFER *bf)
Definition buffer.c:548
int GWEN_Buffer_AppendBytes(GWEN_BUFFER *bf, const char *buffer, uint32_t size)
Definition buffer.c:360
uint32_t GWEN_Buffer_GetPos(const GWEN_BUFFER *bf)
Definition buffer.c:253
int GWEN_Buffer_AppendBuffer(GWEN_BUFFER *bf, GWEN_BUFFER *sf)
Definition buffer.c:506
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition buffer.c:89
int GWEN_Buffer_ReadByte(GWEN_BUFFER *bf)
Definition buffer.c:438
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition buffer.c:992
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition buffer.c:277
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition buffer.c:235
int GWEN_Buffer_AllocRoom(GWEN_BUFFER *bf, uint32_t size)
Definition buffer.c:285
int GWEN_Buffer_Crop(GWEN_BUFFER *bf, uint32_t pos, uint32_t l)
Definition buffer.c:950
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
Definition buffer.c:393
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_DeleteVar(GWEN_DB_NODE *n, const char *path)
Definition db.c:899
int GWEN_DB_VariableExists(GWEN_DB_NODE *n, const char *path)
Definition db.c:1565
GWEN_DB_NODE * GWEN_DB_FindNextGroup(GWEN_DB_NODE *n, const char *name)
Definition db.c:1861
GWEN_DB_NODE * GWEN_DB_Group_new(const char *name)
Definition db.c:173
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_GetGroup(GWEN_DB_NODE *n, uint32_t flags, const char *path)
Definition db.c:1381
GWEN_DB_NODE * GWEN_DB_FindFirstGroup(GWEN_DB_NODE *n, const char *name)
Definition db.c:1840
int GWEN_DB_SetCharValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const char *val)
Definition db.c:997
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
const void * GWEN_DB_GetBinValue(GWEN_DB_NODE *n, const char *path, int idx, const void *defVal, unsigned int defValSize, unsigned int *returnValueSize)
Definition db.c:1237
void GWEN_DB_Dump(GWEN_DB_NODE *n, int insert)
Definition db.c:1420
int GWEN_DB_GetIntValue(GWEN_DB_NODE *n, const char *path, int idx, int defVal)
Definition db.c:1163
void GWEN_DB_Group_free(GWEN_DB_NODE *n)
Definition db.c:421
GWEN_DB_NODE_TYPE
Definition db.h:233
@ GWEN_DB_NodeType_ValueInt
Definition db.h:243
@ GWEN_DB_NodeType_ValueChar
Definition db.h:241
@ 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
struct GWEN_DB_NODE GWEN_DB_NODE
Definition db.h:228
#define DBG_VERBOUS(dbg_logger, format,...)
Definition debug.h:224
#define DBG_INFO(dbg_logger, format,...)
Definition debug.h:181
#define DBG_NOTICE(dbg_logger, format,...)
Definition debug.h:152
#define DBG_ERROR(dbg_logger, format,...)
Definition debug.h:97
#define DBG_WARN(dbg_logger, format,...)
Definition debug.h:125
#define DBG_DEBUG(dbg_logger, format,...)
Definition debug.h:214
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition buffer.h:38
#define GWEN_UNUSED
#define GWEN_INHERIT_FUNCTIONS(t)
Definition inherit.h:163
#define GWEN_INHERIT_INIT(t, element)
Definition inherit.h:223
#define GWEN_INHERIT_FINI(t, element)
Definition inherit.h:238
#define GWEN_LOGDOMAIN
Definition logger.h:35
#define GWEN_FREE_OBJECT(varname)
Definition memory.h:61
#define GWEN_NEW_OBJECT(typ, varname)
Definition memory.h:55
#define GWEN_LIST_ADD(typ, sr, head)
Definition misc.h:82
void GWEN_MsgEngine_TrustedData_free(GWEN_MSGENGINE_TRUSTEDDATA *td)
Definition msgengine.c:3853
void GWEN_MsgEngine_SetEscapeChar(GWEN_MSGENGINE *e, char c)
Definition msgengine.c:121
void GWEN_MsgEngine_SetGetCharValueFunction(GWEN_MSGENGINE *e, GWEN_MSGENGINE_GETCHARVALUE_PTR p)
Definition msgengine.c:373
const char * GWEN_MsgEngine_GetCharsToEscape(GWEN_MSGENGINE *e)
Definition msgengine.c:146
GWEN_DB_NODE * GWEN_MsgEngine__GetGlobalValues(GWEN_MSGENGINE *e)
Definition msgengine.c:202
void GWEN_MsgEngine_SetMode(GWEN_MSGENGINE *e, const char *mode)
Definition msgengine.c:174
int GWEN_MsgEngine_ShowMessage(GWEN_MSGENGINE *e, const char *typ, const char *msgName, int msgVersion, uint32_t flags)
Definition msgengine.c:2481
int GWEN_MsgEngine_TrustedData_AddPos(GWEN_MSGENGINE_TRUSTEDDATA *td, unsigned int pos)
Definition msgengine.c:3913
void GWEN_MsgEngine_SetBinTypeReadFunction(GWEN_MSGENGINE *e, GWEN_MSGENGINE_BINTYPEREAD_PTR p)
Definition msgengine.c:339
int GWEN_MsgEngine__IsBinTyp(GWEN_MSGENGINE *e, const char *type)
Definition msgengine.c:676
const char * GWEN_MsgEngine_SearchForProperty(GWEN_XMLNODE *node, GWEN_XMLNODE *refnode, const char *name, int topDown)
Definition msgengine.c:1333
int GWEN_MsgEngine_TrustedData_GetFirstPos(GWEN_MSGENGINE_TRUSTEDDATA *td)
Definition msgengine.c:3925
int GWEN_MsgEngine__IsIntTyp(GWEN_MSGENGINE *e, const char *type)
Definition msgengine.c:658
const char * GWEN_MsgEngine_GetValue(GWEN_MSGENGINE *e, const char *path, const char *defValue)
Definition msgengine.c:3543
int GWEN_MsgEngine__IsCharTyp(GWEN_MSGENGINE *e, const char *type)
Definition msgengine.c:637
GWEN_MSGENGINE_BINTYPEREAD_PTR GWEN_MsgEngine_GetBinTypeReadFunction(GWEN_MSGENGINE *e)
Definition msgengine.c:348
GWEN_XMLNODE * GWEN_MsgEngine_GetGroup(GWEN_MSGENGINE *e, GWEN_XMLNODE *node, const GWEN_XMLNODE_PATH *nodePath, const char *t, int version, const char *pvalue)
Definition msgengine.c:1636
GWEN_MSGENGINE_TRUSTLEVEL GWEN_MsgEngine_TrustedData_GetTrustLevel(GWEN_MSGENGINE_TRUSTEDDATA *td)
Definition msgengine.c:3897
int GWEN_MsgEngine_ParseMessage(GWEN_MSGENGINE *e, GWEN_XMLNODE *group, GWEN_BUFFER *msgbuf, GWEN_DB_NODE *msgData, uint32_t flags)
Definition msgengine.c:3486
void GWEN_MsgEngine_SetDefinitions(GWEN_MSGENGINE *e, GWEN_XMLNODE *n, int take)
Definition msgengine.c:255
GWEN_XMLNODE * GWEN_MsgEngine_FindNodeByProperty(GWEN_MSGENGINE *e, const char *t, const char *pname, int version, const char *pvalue)
Definition msgengine.c:974
GWEN_MSGENGINE_TRUSTEDDATA * GWEN_MsgEngine_TakeTrustInfo(GWEN_MSGENGINE *e)
Definition msgengine.c:4031
int GWEN_MsgEngine_ReadMessage(GWEN_MSGENGINE *e, const char *gtype, GWEN_BUFFER *mbuf, GWEN_DB_NODE *gr, uint32_t flags)
Definition msgengine.c:3651
void GWEN_MsgEngine_SetDelimiters(GWEN_MSGENGINE *e, const char *s)
Definition msgengine.c:154
int GWEN_MsgEngine__WriteGroup(GWEN_MSGENGINE *e, GWEN_BUFFER *gbuf, GWEN_XMLNODE *node, GWEN_XMLNODE *rnode, GWEN_DB_NODE *gr, int groupIsOptional, GWEN_XMLNODE_PATH *nodePath)
Definition msgengine.c:1709
void GWEN_MsgEngine_free(GWEN_MSGENGINE *e)
Definition msgengine.c:82
GWEN_XMLNODE * GWEN_MsgEngine_FindNodeByPropertyStrictProto(GWEN_MSGENGINE *e, const char *t, const char *pname, int version, const char *pvalue)
Definition msgengine.c:1065
GWEN_XMLNODE * GWEN_MsgEngine_GetDefinitions(GWEN_MSGENGINE *e)
Definition msgengine.c:248
int GWEN_MsgEngine_GetIntValue(GWEN_MSGENGINE *e, const char *path, int defValue)
Definition msgengine.c:3558
void GWEN_MsgEngine_SetProtocolVersion(GWEN_MSGENGINE *e, unsigned int p)
Definition msgengine.c:232
int GWEN_MsgEngine_CreateMessage(GWEN_MSGENGINE *e, const char *msgName, int msgVersion, GWEN_BUFFER *gbuf, GWEN_DB_NODE *msgData)
Definition msgengine.c:2105
GWEN_MSGENGINE_TRUSTEDDATA * GWEN_MsgEngine_TrustedData_GetNext(GWEN_MSGENGINE_TRUSTEDDATA *td)
Definition msgengine.c:3865
int GWEN_MsgEngine__ListGroup(GWEN_MSGENGINE *e, const char *path, GWEN_XMLNODE *node, GWEN_STRINGLIST *sl, GWEN_XMLNODE *listNode, uint32_t flags)
Definition msgengine.c:2604
void GWEN_MsgEngine_SetGetGlobalValuesFunction(GWEN_MSGENGINE *e, GWEN_MSGENGINE_GETGLOBALVALUES_PTR p)
Definition msgengine.c:268
int GWEN_MsgEngine_GetHighestTrustLevel(GWEN_XMLNODE *node, GWEN_XMLNODE *refnode)
Definition msgengine.c:1369
int GWEN_MsgEngine_SetValue(GWEN_MSGENGINE *e, const char *path, const char *value)
Definition msgengine.c:3509
int GWEN_MsgEngine__WriteValue(GWEN_MSGENGINE *e, GWEN_BUFFER *gbuf, GWEN_BUFFER *data, GWEN_XMLNODE *node)
Definition msgengine.c:420
int GWEN_MsgEngine__ListElement(GWEN_UNUSED GWEN_MSGENGINE *e, const char *path, GWEN_XMLNODE *node, GWEN_STRINGLIST *sl, GWEN_XMLNODE *listNode, uint32_t flags)
Definition msgengine.c:2541
int GWEN_MsgEngine__ShowElement(GWEN_UNUSED GWEN_MSGENGINE *e, const char *path, GWEN_XMLNODE *node, GWEN_STRINGLIST *sl, uint32_t flags)
Definition msgengine.c:2174
void GWEN_MsgEngine_SetInheritorData(GWEN_MSGENGINE *e, void *d)
Definition msgengine.c:409
GWEN_XMLNODE * GWEN_MsgEngine_ListMessage(GWEN_MSGENGINE *e, const char *typ, const char *msgName, int msgVersion, uint32_t flags)
Definition msgengine.c:2788
const char * GWEN_MsgEngine_TrustedData_GetDescription(GWEN_MSGENGINE_TRUSTEDDATA *td)
Definition msgengine.c:3889
const char * GWEN_MsgEngine_TrustedData_GetData(GWEN_MSGENGINE_TRUSTEDDATA *td)
Definition msgengine.c:3873
char GWEN_MsgEngine_GetEscapeChar(GWEN_MSGENGINE *e)
Definition msgengine.c:129
const char * GWEN_MsgEngine_GetDelimiters(GWEN_MSGENGINE *e)
Definition msgengine.c:166
void GWEN_MsgEngine_SetTypeWriteFunction(GWEN_MSGENGINE *e, GWEN_MSGENGINE_TYPEWRITE_PTR p)
Definition msgengine.c:302
void GWEN_MsgEngine_SetBinTypeWriteFunction(GWEN_MSGENGINE *e, GWEN_MSGENGINE_BINTYPEWRITE_PTR p)
Definition msgengine.c:356
const char * GWEN_MsgEngine_TrustedData_GetReplacement(GWEN_MSGENGINE_TRUSTEDDATA *td)
Definition msgengine.c:3905
void * GWEN_MsgEngine_GetInheritorData(const GWEN_MSGENGINE *e)
Definition msgengine.c:401
GWEN_MSGENGINE_BINTYPEWRITE_PTR GWEN_MsgEngine_GetBinTypeWriteFunction(GWEN_MSGENGINE *e)
Definition msgengine.c:365
int GWEN_MsgEngine__ReadValue(GWEN_MSGENGINE *e, GWEN_BUFFER *msgbuf, GWEN_XMLNODE *node, GWEN_XMLNODE *rnode, GWEN_BUFFER *vbuf, const char *delimiters, uint32_t flags)
Definition msgengine.c:2831
int GWEN_MsgEngine__WriteElement(GWEN_MSGENGINE *e, GWEN_BUFFER *gbuf, GWEN_XMLNODE *node, GWEN_DB_NODE *gr, int loopNr, int isOptional, GWEN_XMLNODE_PATH *nodePath)
Definition msgengine.c:742
int GWEN_MsgEngine_TrustedData_GetNextPos(GWEN_MSGENGINE_TRUSTEDDATA *td)
Definition msgengine.c:3934
GWEN_MSGENGINE_TYPEWRITE_PTR GWEN_MsgEngine_GetTypeWriteFunction(GWEN_MSGENGINE *e)
Definition msgengine.c:311
void GWEN_MsgEngine_SetTypeCheckFunction(GWEN_MSGENGINE *e, GWEN_MSGENGINE_TYPECHECK_PTR p)
Definition msgengine.c:319
GWEN_MSGENGINE_GETGLOBALVALUES_PTR GWEN_MsgEngine_GetGetGlobalValuesFunction(GWEN_MSGENGINE *e)
Definition msgengine.c:277
GWEN_MSGENGINE_TRUSTEDDATA * GWEN_MsgEngine_TrustedData_new(const char *data, unsigned int size, const char *description, GWEN_MSGENGINE_TRUSTLEVEL trustLevel)
Definition msgengine.c:3831
int GWEN_MsgEngine_AddDefinitions(GWEN_MSGENGINE *e, GWEN_XMLNODE *node)
Definition msgengine.c:2126
const char * GWEN_MsgEngine__TransformValue(GWEN_MSGENGINE *e, const char *pvalue, GWEN_XMLNODE *node, GWEN_XMLNODE *dnode, unsigned int *datasize)
Definition msgengine.c:1156
int GWEN_MsgEngine__ReadGroup(GWEN_MSGENGINE *e, GWEN_BUFFER *msgbuf, GWEN_XMLNODE *node, GWEN_XMLNODE *rnode, GWEN_DB_NODE *gr, const char *delimiters, uint32_t flags)
Definition msgengine.c:3042
int GWEN_MsgEngine__GetInline(GWEN_MSGENGINE *e, GWEN_XMLNODE *node, GWEN_BUFFER *mbuf)
Definition msgengine.c:694
void GWEN_MsgEngine_Attach(GWEN_MSGENGINE *e)
Definition msgengine.c:114
int GWEN_MsgEngine_TrustedData_CreateReplacements(GWEN_MSGENGINE_TRUSTEDDATA *td)
Definition msgengine.c:3944
GWEN_XMLNODE * GWEN_MsgEngine_FindGroupByProperty(GWEN_MSGENGINE *e, const char *pname, int version, const char *pvalue)
Definition msgengine.c:964
GWEN_MSGENGINE_TYPEREAD_PTR GWEN_MsgEngine_GetTypeReadFunction(GWEN_MSGENGINE *e)
Definition msgengine.c:294
int GWEN_MsgEngine__ShowGroup(GWEN_MSGENGINE *e, const char *path, GWEN_XMLNODE *node, GWEN_STRINGLIST *sl, uint32_t flags)
Definition msgengine.c:2271
void GWEN_MsgEngine_SetTypeReadFunction(GWEN_MSGENGINE *e, GWEN_MSGENGINE_TYPEREAD_PTR p)
Definition msgengine.c:285
unsigned int GWEN_MsgEngine_TrustedData_GetSize(GWEN_MSGENGINE_TRUSTEDDATA *td)
Definition msgengine.c:3881
GWEN_XMLNODE * GWEN_MsgEngine__GetGroup(GWEN_MSGENGINE *e, GWEN_XMLNODE *node, const char *t, int version, const char *pvalue)
Definition msgengine.c:1556
unsigned int GWEN_MsgEngine_GetProtocolVersion(GWEN_MSGENGINE *e)
Definition msgengine.c:221
GWEN_MSGENGINE * GWEN_MsgEngine_new(void)
Definition msgengine.c:66
void GWEN_MsgEngine_SetFreeDataFunction(GWEN_MSGENGINE *e, GWEN_MSGENGINE_FREEDATA_PTR p)
Definition msgengine.c:391
void GWEN_MsgEngine_SetGetIntValueFunction(GWEN_MSGENGINE *e, GWEN_MSGENGINE_GETINTVALUE_PTR p)
Definition msgengine.c:382
int GWEN_MsgEngine_AddTrustInfo(GWEN_MSGENGINE *e, const char *data, unsigned int size, const char *description, GWEN_MSGENGINE_TRUSTLEVEL trustLevel, unsigned int pos)
Definition msgengine.c:4044
GWEN_MSGENGINE_TYPECHECK_PTR GWEN_MsgEngine_GetTypeCheckFunction(GWEN_MSGENGINE *e)
Definition msgengine.c:328
static int _groupReadElement(GWEN_MSGENGINE *e, GWEN_BUFFER *msgbuf, GWEN_XMLNODE *n, GWEN_XMLNODE *rnode, GWEN_DB_NODE *gr, char currentDelimiter, char currentTerminator, const char *delimiters, uint32_t flags)
Definition msgengine.c:3300
const char * GWEN_MsgEngine__findInValues(GWEN_MSGENGINE *e, GWEN_XMLNODE *node, GWEN_XMLNODE *dnode, const char *name, unsigned int *datasize)
Definition msgengine.c:1484
const char * GWEN_MsgEngine_GetMode(GWEN_MSGENGINE *e)
Definition msgengine.c:191
int GWEN_MsgEngine_SetIntValue(GWEN_MSGENGINE *e, const char *path, int value)
Definition msgengine.c:3526
int GWEN_MsgEngine_CreateMessageFromNode(GWEN_MSGENGINE *e, GWEN_XMLNODE *node, GWEN_BUFFER *gbuf, GWEN_DB_NODE *msgData)
Definition msgengine.c:2065
const char * GWEN_MsgEngine__SearchForValue(GWEN_MSGENGINE *e, GWEN_XMLNODE *node, GWEN_XMLNODE_PATH *nodePath, const char *name, unsigned int *datasize)
Definition msgengine.c:1402
void GWEN_MsgEngine_SetCharsToEscape(GWEN_MSGENGINE *e, const char *c)
Definition msgengine.c:137
int GWEN_MsgEngine_SkipSegment(GWEN_UNUSED GWEN_MSGENGINE *e, GWEN_BUFFER *msgbuf, unsigned char escapeChar, unsigned char delimiter)
Definition msgengine.c:3574
GWEN_MSGENGINE_TRUSTLEVEL
Definition msgengine.h:54
@ GWEN_MsgEngineTrustLevelHigh
Definition msgengine.h:58
#define GWEN_MSGENGINE_READ_FLAGS_TRUSTINFO
Definition msgengine.h:121
const char *(* GWEN_MSGENGINE_GETCHARVALUE_PTR)(GWEN_MSGENGINE *e, const char *name, const char *defValue)
Definition msgengine.h:177
int(* GWEN_MSGENGINE_TYPEREAD_PTR)(GWEN_MSGENGINE *e, GWEN_BUFFER *msgbuf, GWEN_XMLNODE *node, GWEN_BUFFER *vbuf, char escapeChar, const char *delimiters)
Definition msgengine.h:143
int(* GWEN_MSGENGINE_BINTYPEREAD_PTR)(GWEN_MSGENGINE *e, GWEN_XMLNODE *node, GWEN_DB_NODE *gr, GWEN_BUFFER *vbuf)
Definition msgengine.h:164
GWEN_DB_NODE_TYPE(* GWEN_MSGENGINE_TYPECHECK_PTR)(GWEN_MSGENGINE *e, const char *tname)
Definition msgengine.h:161
void(* GWEN_MSGENGINE_FREEDATA_PTR)(GWEN_MSGENGINE *e)
Definition msgengine.h:187
struct GWEN__MSGENGINE GWEN_MSGENGINE
Definition msgengine.h:131
int(* GWEN_MSGENGINE_BINTYPEWRITE_PTR)(GWEN_MSGENGINE *e, GWEN_XMLNODE *node, GWEN_DB_NODE *gr, GWEN_BUFFER *dbuf)
Definition msgengine.h:169
#define GWEN_MSGENGINE_MAX_VALUE_LEN
Definition msgengine.h:116
int(* GWEN_MSGENGINE_GETINTVALUE_PTR)(GWEN_MSGENGINE *e, const char *name, int defValue)
Definition msgengine.h:180
GWEN_DB_NODE *(* GWEN_MSGENGINE_GETGLOBALVALUES_PTR)(GWEN_MSGENGINE *e)
Definition msgengine.h:185
struct GWEN_MSGENGINE_TRUSTEDDATA GWEN_MSGENGINE_TRUSTEDDATA
Definition msgengine.h:52
int(* GWEN_MSGENGINE_TYPEWRITE_PTR)(GWEN_MSGENGINE *e, GWEN_BUFFER *gbuf, GWEN_BUFFER *data, GWEN_XMLNODE *node)
Definition msgengine.h:153
#define GWEN_MSGENGINE_SHOW_FLAGS_NOSET
Definition msgengine.h:115
#define GWEN_PATH_FLAGS_CREATE_GROUP
Definition path.h:96
void GWEN_StringList_free(GWEN_STRINGLIST *sl)
Definition stringlist.c:62
const char * GWEN_StringListEntry_Data(const GWEN_STRINGLISTENTRY *se)
Definition stringlist.c:406
GWEN_STRINGLISTENTRY * GWEN_StringListEntry_Next(const GWEN_STRINGLISTENTRY *se)
Definition stringlist.c:398
int GWEN_StringList_AppendString(GWEN_STRINGLIST *sl, const char *s, int take, int checkDouble)
Definition stringlist.c:245
GWEN_STRINGLISTENTRY * GWEN_StringList_FirstEntry(const GWEN_STRINGLIST *sl)
Definition stringlist.c:390
GWEN_STRINGLIST * GWEN_StringList_new(void)
Definition stringlist.c:50
struct GWEN_STRINGLISTENTRYSTRUCT GWEN_STRINGLISTENTRY
Definition stringlist.h:53
struct GWEN_STRINGLISTSTRUCT GWEN_STRINGLIST
Definition stringlist.h:56
int GWEN_Text_FromHexBuffer(const char *src, GWEN_BUFFER *buf)
Definition text.c:897
void GWEN_Text_DumpString(const char *s, unsigned int l, unsigned int insert)
Definition text.c:1283
int GWEN_Text_NumToString(int num, char *buffer, unsigned int bufsize, int fillchar)
Definition text.c:1243
GWEN_XMLNODE * GWEN_XMLNode_dup(const GWEN_XMLNODE *n)
Definition xml.c:187
const char * GWEN_XMLNode_GetProperty(const GWEN_XMLNODE *n, const char *name, const char *defaultValue)
Definition xml.c:239
GWEN_XMLNODE * GWEN_XMLNode_FindFirstTag(const GWEN_XMLNODE *n, const char *tname, const char *pname, const char *pvalue)
Definition xml.c:776
GWEN_XMLNODE * GWEN_XMLNode_GetParent(const GWEN_XMLNODE *n)
Definition xml.c:416
GWEN_XMLNODE * GWEN_XMLNode_GetFirstTag(const GWEN_XMLNODE *n)
Definition xml.c:705
GWEN_XMLNODE_TYPE GWEN_XMLNode_GetType(const GWEN_XMLNODE *n)
Definition xml.c:458
void GWEN_XMLNode_Path_free(GWEN_XMLNODE_PATH *np)
Definition xml.c:1928
void GWEN_XMLNode_Dump(const GWEN_XMLNODE *n, int ind)
Definition xml.c:472
void GWEN_XMLNode_SetProperty(GWEN_XMLNODE *n, const char *name, const char *value)
Definition xml.c:322
GWEN_XMLNODE * GWEN_XMLNode_Path_Surface(GWEN_XMLNODE_PATH *np)
Definition xml.c:1956
int GWEN_XMLNode_Path_Dive(GWEN_XMLNODE_PATH *np, GWEN_XMLNODE *n)
Definition xml.c:1935
GWEN_XMLNODE * GWEN_XMLNode_FindNode(const GWEN_XMLNODE *node, GWEN_XMLNODE_TYPE t, const char *data)
Definition xml.c:543
GWEN_XMLNODE * GWEN_XMLNode_Next(const GWEN_XMLNODE *n)
Definition xml.c:465
GWEN_XMLNODE * GWEN_XMLNode_GetNextTag(const GWEN_XMLNODE *n)
Definition xml.c:712
GWEN_XMLNODE_PATH * GWEN_XMLNode_Path_dup(const GWEN_XMLNODE_PATH *np)
Definition xml.c:1913
void GWEN_XMLNode_AddChild(GWEN_XMLNODE *n, GWEN_XMLNODE *child)
Definition xml.c:423
GWEN_XMLNODE_PATH * GWEN_XMLNode_Path_new(void)
Definition xml.c:1903
GWEN_XMLNODE * GWEN_XMLNode_GetFirstData(const GWEN_XMLNODE *n)
Definition xml.c:724
void GWEN_XMLNode_CopyProperties(GWEN_XMLNODE *tn, const GWEN_XMLNODE *sn, int overwrite)
Definition xml.c:588
void GWEN_XMLNode_free(GWEN_XMLNODE *n)
Definition xml.c:160
const char * GWEN_XMLNode_GetData(const GWEN_XMLNODE *n)
Definition xml.c:370
void GWEN_XMLNode_RemoveChildren(GWEN_XMLNODE *n)
Definition xml.c:580
GWEN_XMLNODE * GWEN_XMLNode_GetChild(const GWEN_XMLNODE *n)
Definition xml.c:409
struct GWEN__XMLNODE GWEN_XMLNODE
Definition xml.h:156
@ GWEN_XMLNodeTypeData
Definition xml.h:147
@ GWEN_XMLNodeTypeTag
Definition xml.h:145
struct GWEN_XMLNODE_PATH GWEN_XMLNODE_PATH
Definition xml.h:866