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