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