exip  Alpha 0.5.4
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
decodeTestEXI.c
Go to the documentation of this file.
1 /*==================================================================*\
2 | EXIP - Embeddable EXI Processor in C |
3 |--------------------------------------------------------------------|
4 | This work is licensed under BSD 3-Clause License |
5 | The full license terms and conditions are located in LICENSE.txt |
6 \===================================================================*/
7 
17 #include "EXIParser.h"
18 #include "stringManipulate.h"
19 #include <stdio.h>
20 #include <string.h>
21 #include "decodeTestEXI.h"
22 
23 #define INPUT_BUFFER_SIZE 200
24 #define MAX_PREFIXES 10
25 
26 struct appData
27 {
28  unsigned char outputFormat;
29  unsigned char expectAttributeData;
30  char nameBuf[200]; // needed for the OUT_XML Output Format
31  struct element* stack; // needed for the OUT_XML Output Format
32  unsigned char unclosedElement; // needed for the OUT_XML Output Format
33  char prefixes[MAX_PREFIXES][200]; // needed for the OUT_XML Output Format
34  unsigned char prefixesCount; // needed for the OUT_XML Output Format
35 };
36 
37 
38 // Stuff needed for the OUT_XML Output Format
39 // ******************************************
40 struct element {
41  struct element* next;
42  char* name;
43 };
44 
45 static void push(struct element** stack, struct element* el);
46 static struct element* pop(struct element** stack);
47 static struct element* createElement(char* name);
48 static void destroyElement(struct element* el);
49 
50 // returns != 0 if error
51 static char lookupPrefix(struct appData* aData, String ns, unsigned char* prxHit, unsigned char* prefixIndex);
52 
53 // ******************************************
54 
55 // Content Handler API
56 static errorCode sample_fatalError(const errorCode code, const char* msg, void* app_data);
57 static errorCode sample_startDocument(void* app_data);
58 static errorCode sample_endDocument(void* app_data);
59 static errorCode sample_startElement(QName qname, void* app_data);
60 static errorCode sample_endElement(void* app_data);
61 static errorCode sample_attribute(QName qname, void* app_data);
62 static errorCode sample_stringData(const String value, void* app_data);
63 static errorCode sample_decimalData(Decimal value, void* app_data);
64 static errorCode sample_intData(Integer int_val, void* app_data);
65 static errorCode sample_floatData(Float fl_val, void* app_data);
66 static errorCode sample_booleanData(boolean bool_val, void* app_data);
67 static errorCode sample_dateTimeData(EXIPDateTime dt_val, void* app_data);
68 static errorCode sample_binaryData(const char* binary_val, Index nbytes, void* app_data);
69 static errorCode sample_qnameData(const QName qname, void* app_data);
70 
71 errorCode decode(EXIPSchema* schemaPtr, unsigned char outFlag, FILE *infile, boolean outOfBandOpts, EXIOptions* opts, size_t (*inputStream)(void* buf, size_t size, void* stream))
72 {
73  Parser testParser;
74  char buf[INPUT_BUFFER_SIZE];
75  BinaryBuffer buffer;
76  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
77  struct appData parsingData;
78 
79  buffer.buf = buf;
80  buffer.bufLen = INPUT_BUFFER_SIZE;
81  buffer.bufContent = 0;
82  // Parsing steps:
83 
84  // I: First, define an external stream for the input to the parser if any, otherwise set to NULL
85  buffer.ioStrm.readWriteToStream = inputStream;
86  buffer.ioStrm.stream = infile;
87 
88  // II: Second, initialize the parser object
89  TRY(parse.initParser(&testParser, buffer, &parsingData));
90 
91  // III: Initialize the parsing data and hook the callback handlers to the parser object.
92  // If out-of-band options are defined use testParser.strm.header.opts to set them
93  parsingData.expectAttributeData = 0;
94  parsingData.stack = NULL;
95  parsingData.unclosedElement = 0;
96  parsingData.prefixesCount = 0;
97  parsingData.outputFormat = outFlag;
98  if(outOfBandOpts && opts != NULL)
99  testParser.strm.header.opts = *opts;
100 
101  testParser.handler.fatalError = sample_fatalError;
102  testParser.handler.error = sample_fatalError;
103  testParser.handler.startDocument = sample_startDocument;
104  testParser.handler.endDocument = sample_endDocument;
105  testParser.handler.startElement = sample_startElement;
106  testParser.handler.attribute = sample_attribute;
107  testParser.handler.stringData = sample_stringData;
108  testParser.handler.endElement = sample_endElement;
109  testParser.handler.decimalData = sample_decimalData;
110  testParser.handler.intData = sample_intData;
111  testParser.handler.floatData = sample_floatData;
112  testParser.handler.booleanData = sample_booleanData;
113  testParser.handler.dateTimeData = sample_dateTimeData;
114  testParser.handler.binaryData = sample_binaryData;
115  testParser.handler.qnameData = sample_qnameData;
116 
117  // IV: Parse the header of the stream
118 
119  TRY(parse.parseHeader(&testParser, outOfBandOpts));
120 
121  // IV.1: Set the schema to be used for parsing.
122  // The schemaID mode and schemaID field can be read at
123  // parser.strm.header.opts.schemaIDMode and
124  // parser.strm.header.opts.schemaID respectively
125  // If schemaless mode, use setSchema(&parser, NULL);
126 
127  TRY(parse.setSchema(&testParser, schemaPtr));
128 
129  // V: Parse the body of the EXI stream
130 
131  while(tmp_err_code == EXIP_OK)
132  {
133  tmp_err_code = parse.parseNext(&testParser);
134  }
135 
136  // VI: Free the memory allocated by the parser
137 
138  parse.destroyParser(&testParser);
139 
140  if(tmp_err_code == EXIP_PARSING_COMPLETE)
141  return EXIP_OK;
142  else
143  return tmp_err_code;
144 }
145 
146 static errorCode sample_fatalError(const errorCode code, const char* msg, void* app_data)
147 {
148  printf("\n%d : FATAL ERROR: %s\n", code, msg);
149  return EXIP_HANDLER_STOP;
150 }
151 
152 static errorCode sample_startDocument(void* app_data)
153 {
154  struct appData* appD = (struct appData*) app_data;
155  if(appD->outputFormat == OUT_EXI)
156  printf("SD\n");
157  else if(appD->outputFormat == OUT_XML)
158  printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
159 
160  return EXIP_OK;
161 }
162 
163 static errorCode sample_endDocument(void* app_data)
164 {
165  struct appData* appD = (struct appData*) app_data;
166  if(appD->outputFormat == OUT_EXI)
167  printf("ED\n");
168  else if(appD->outputFormat == OUT_XML)
169  printf("\n");
170 
171  return EXIP_OK;
172 }
173 
174 static errorCode sample_startElement(QName qname, void* app_data)
175 {
176  struct appData* appD = (struct appData*) app_data;
177  if(appD->outputFormat == OUT_EXI)
178  {
179  printf("SE ");
180  printString(qname.uri);
181  printf(" ");
182  printString(qname.localName);
183  printf("\n");
184  }
185  else if(appD->outputFormat == OUT_XML)
186  {
187  char error = 0;
188  unsigned char prefixIndex = 0;
189  unsigned char prxHit = 1;
190  int t;
191 
192  if(!isStringEmpty(qname.uri))
193  {
194  error = lookupPrefix(appD, *qname.uri, &prxHit, &prefixIndex);
195  if(error != 0)
196  return EXIP_HANDLER_STOP;
197 
198  sprintf(appD->nameBuf, "p%d:", prefixIndex);
199  t = strlen(appD->nameBuf);
200  memcpy(appD->nameBuf + t, qname.localName->str, qname.localName->length);
201  appD->nameBuf[t + qname.localName->length] = '\0';
202  }
203  else
204  {
205  memcpy(appD->nameBuf, qname.localName->str, qname.localName->length);
206  appD->nameBuf[qname.localName->length] = '\0';
207  }
208  push(&(appD->stack), createElement(appD->nameBuf));
209  if(appD->unclosedElement)
210  printf(">\n");
211  printf("<%s", appD->nameBuf);
212 
213  if(prxHit == 0)
214  {
215  sprintf(appD->nameBuf, " xmlns:p%d=\"", prefixIndex);
216  printf("%s", appD->nameBuf);
217  printString(qname.uri);
218  printf("\"");
219  }
220 
221  appD->unclosedElement = 1;
222  }
223 
224  return EXIP_OK;
225 }
226 
227 static errorCode sample_endElement(void* app_data)
228 {
229  struct appData* appD = (struct appData*) app_data;
230  if(appD->outputFormat == OUT_EXI)
231  printf("EE\n");
232  else if(appD->outputFormat == OUT_XML)
233  {
234  struct element* el;
235 
236  if(appD->unclosedElement)
237  printf(">\n");
238  appD->unclosedElement = 0;
239  el = pop(&(appD->stack));
240  printf("</%s>\n", el->name);
241  destroyElement(el);
242  }
243 
244  return EXIP_OK;
245 }
246 
247 static errorCode sample_attribute(QName qname, void* app_data)
248 {
249  struct appData* appD = (struct appData*) app_data;
250  if(appD->outputFormat == OUT_EXI)
251  {
252  printf("AT ");
253  printString(qname.uri);
254  printf(" ");
255  printString(qname.localName);
256  printf("=\"");
257  }
258  else if(appD->outputFormat == OUT_XML)
259  {
260  printf(" ");
261  if(!isStringEmpty(qname.uri))
262  {
263  printString(qname.uri);
264  printf(":");
265  }
266  printString(qname.localName);
267  printf("=\"");
268  }
269  appD->expectAttributeData = 1;
270 
271  return EXIP_OK;
272 }
273 
274 static errorCode sample_stringData(const String value, void* app_data)
275 {
276  struct appData* appD = (struct appData*) app_data;
277  if(appD->outputFormat == OUT_EXI)
278  {
279  if(appD->expectAttributeData)
280  {
281  printString(&value);
282  printf("\"\n");
283  appD->expectAttributeData = 0;
284  }
285  else
286  {
287  printf("CH ");
288  printString(&value);
289  printf("\n");
290  }
291  }
292  else if(appD->outputFormat == OUT_XML)
293  {
294  if(appD->expectAttributeData)
295  {
296  printString(&value);
297  printf("\"");
298  appD->expectAttributeData = 0;
299  }
300  else
301  {
302  if(appD->unclosedElement)
303  printf(">");
304  appD->unclosedElement = 0;
305  printString(&value);
306  }
307  }
308 
309  return EXIP_OK;
310 }
311 
312 static errorCode sample_decimalData(Decimal value, void* app_data)
313 {
314  return sample_floatData(value, app_data);
315 }
316 
317 static errorCode sample_intData(Integer int_val, void* app_data)
318 {
319  struct appData* appD = (struct appData*) app_data;
320  char tmp_buf[30];
321  if(appD->outputFormat == OUT_EXI)
322  {
323  if(appD->expectAttributeData)
324  {
325  sprintf(tmp_buf, "%lld", (long long int) int_val);
326  printf("%s", tmp_buf);
327  printf("\"\n");
328  appD->expectAttributeData = 0;
329  }
330  else
331  {
332  printf("CH ");
333  sprintf(tmp_buf, "%lld", (long long int) int_val);
334  printf("%s", tmp_buf);
335  printf("\n");
336  }
337  }
338  else if(appD->outputFormat == OUT_XML)
339  {
340  if(appD->expectAttributeData)
341  {
342  sprintf(tmp_buf, "%lld", (long long int) int_val);
343  printf("%s", tmp_buf);
344  printf("\"");
345  appD->expectAttributeData = 0;
346  }
347  else
348  {
349  if(appD->unclosedElement)
350  printf(">");
351  appD->unclosedElement = 0;
352  sprintf(tmp_buf, "%lld", (long long int) int_val);
353  printf("%s", tmp_buf);
354  }
355  }
356 
357  return EXIP_OK;
358 }
359 
360 static errorCode sample_booleanData(boolean bool_val, void* app_data)
361 {
362  struct appData* appD = (struct appData*) app_data;
363 
364  if(appD->outputFormat == OUT_EXI)
365  {
366  if(appD->expectAttributeData)
367  {
368  if(bool_val)
369  printf("true\"\n");
370  else
371  printf("false\"\n");
372 
373  appD->expectAttributeData = 0;
374  }
375  else
376  {
377  printf("CH ");
378  if(bool_val)
379  printf("true\n");
380  else
381  printf("false\n");
382  }
383  }
384  else if(appD->outputFormat == OUT_XML)
385  {
386  if(appD->expectAttributeData)
387  {
388  if(bool_val)
389  printf("true\"");
390  else
391  printf("false\"");
392  appD->expectAttributeData = 0;
393  }
394  else
395  {
396  if(appD->unclosedElement)
397  printf(">");
398  appD->unclosedElement = 0;
399 
400  if(bool_val)
401  printf("true");
402  else
403  printf("false");
404  }
405  }
406 
407  return EXIP_OK;
408 }
409 
410 static errorCode sample_floatData(Float fl_val, void* app_data)
411 {
412  struct appData* appD = (struct appData*) app_data;
413  char tmp_buf[30];
414  if(appD->outputFormat == OUT_EXI)
415  {
416  if(appD->expectAttributeData)
417  {
418  sprintf(tmp_buf, "%lldE%d", (long long int) fl_val.mantissa, fl_val.exponent);
419  printf("%s", tmp_buf);
420  printf("\"\n");
421  appD->expectAttributeData = 0;
422  }
423  else
424  {
425  printf("CH ");
426  sprintf(tmp_buf, "%lldE%d", (long long int) fl_val.mantissa, fl_val.exponent);
427  printf("%s", tmp_buf);
428  printf("\n");
429  }
430  }
431  else if(appD->outputFormat == OUT_XML)
432  {
433  if(appD->expectAttributeData)
434  {
435  sprintf(tmp_buf, "%lldE%d", (long long int) fl_val.mantissa, fl_val.exponent);
436  printf("%s", tmp_buf);
437  printf("\"");
438  appD->expectAttributeData = 0;
439  }
440  else
441  {
442  if(appD->unclosedElement)
443  printf(">");
444  appD->unclosedElement = 0;
445  sprintf(tmp_buf, "%lldE%d", (long long int) fl_val.mantissa, fl_val.exponent);
446  printf("%s", tmp_buf);
447  }
448  }
449 
450  return EXIP_OK;
451 }
452 
453 static errorCode sample_dateTimeData(EXIPDateTime dt_val, void* app_data)
454 {
455  struct appData* appD = (struct appData*) app_data;
456  char fsecBuf[30];
457  char tzBuf[30];
458  int i;
459 
461  {
462  unsigned int tmpfValue = dt_val.fSecs.value;
463  int digitNum = 0;
464 
465  fsecBuf[0] = '.';
466 
467  while(tmpfValue)
468  {
469  digitNum++;
470  tmpfValue = tmpfValue / 10;
471  }
472  for(i = 0; i < dt_val.fSecs.offset + 1 - digitNum; i++)
473  fsecBuf[1+i] = '0';
474 
475  sprintf(fsecBuf + 1 + i, "%d", dt_val.fSecs.value);
476  }
477  else
478  {
479  fsecBuf[0] = '\0';
480  }
481 
483  {
484  if(dt_val.TimeZone < 0)
485  tzBuf[0] = '-';
486  else
487  tzBuf[0] = '+';
488  sprintf(tzBuf + 1, "%02d", dt_val.TimeZone/64);
489  tzBuf[3] = ':';
490  sprintf(tzBuf + 4, "%02d", dt_val.TimeZone%64);
491  tzBuf[6] = '\0';
492  }
493  else
494  {
495  tzBuf[0] = '\0';
496  }
497 
498  if(appD->outputFormat == OUT_EXI)
499  {
500  if(appD->expectAttributeData)
501  {
502  printf("%04d-%02d-%02dT%02d:%02d:%02d%s%s", dt_val.dateTime.tm_year + 1900,
503  dt_val.dateTime.tm_mon + 1, dt_val.dateTime.tm_mday,
504  dt_val.dateTime.tm_hour, dt_val.dateTime.tm_min,
505  dt_val.dateTime.tm_sec, fsecBuf, tzBuf);
506  printf("\"\n");
507  appD->expectAttributeData = 0;
508  }
509  else
510  {
511  printf("CH ");
512  printf("%04d-%02d-%02dT%02d:%02d:%02d%s%s", dt_val.dateTime.tm_year + 1900,
513  dt_val.dateTime.tm_mon + 1, dt_val.dateTime.tm_mday,
514  dt_val.dateTime.tm_hour, dt_val.dateTime.tm_min,
515  dt_val.dateTime.tm_sec, fsecBuf, tzBuf);
516  printf("\n");
517  }
518  }
519  else if(appD->outputFormat == OUT_XML)
520  {
521  if(appD->expectAttributeData)
522  {
523  printf("%04d-%02d-%02dT%02d:%02d:%02d%s%s", dt_val.dateTime.tm_year + 1900,
524  dt_val.dateTime.tm_mon + 1, dt_val.dateTime.tm_mday,
525  dt_val.dateTime.tm_hour, dt_val.dateTime.tm_min,
526  dt_val.dateTime.tm_sec, fsecBuf, tzBuf);
527  printf("\"");
528  appD->expectAttributeData = 0;
529  }
530  else
531  {
532  if(appD->unclosedElement)
533  printf(">");
534  appD->unclosedElement = 0;
535  printf("%04d-%02d-%02dT%02d:%02d:%02d%s%s", dt_val.dateTime.tm_year + 1900,
536  dt_val.dateTime.tm_mon + 1, dt_val.dateTime.tm_mday,
537  dt_val.dateTime.tm_hour, dt_val.dateTime.tm_min,
538  dt_val.dateTime.tm_sec, fsecBuf, tzBuf);
539  }
540  }
541 
542  return EXIP_OK;
543 }
544 
545 static errorCode sample_binaryData(const char* binary_val, Index nbytes, void* app_data)
546 {
547  struct appData* appD = (struct appData*) app_data;
548 
549  if(appD->outputFormat == OUT_EXI)
550  {
551  if(appD->expectAttributeData)
552  {
553  printf("[binary: %d bytes]", (int) nbytes);
554  printf("\"\n");
555  appD->expectAttributeData = 0;
556  }
557  else
558  {
559  printf("CH ");
560  printf("[binary: %d bytes]", (int) nbytes);
561  printf("\n");
562  }
563  }
564  else if(appD->outputFormat == OUT_XML)
565  {
566  if(appD->expectAttributeData)
567  {
568  printf("[binary: %d bytes]", (int) nbytes);
569  printf("\"");
570  appD->expectAttributeData = 0;
571  }
572  else
573  {
574  if(appD->unclosedElement)
575  printf(">");
576  appD->unclosedElement = 0;
577  printf("[binary: %d bytes]", (int) nbytes);
578  }
579  }
580 
581  return EXIP_OK;
582 }
583 
584 static errorCode sample_qnameData(const QName qname, void* app_data)
585 {
586  struct appData* appD = (struct appData*) app_data;
587  if(appD->outputFormat == OUT_EXI)
588  {
589  if(appD->expectAttributeData)
590  {
591  printString(qname.uri);
592  printf(":");
593  printString(qname.localName);
594  printf("\"\n");
595  appD->expectAttributeData = 0;
596  }
597  else
598  {
599  printf("QNAME ");
600  printString(qname.uri);
601  printf(":");
602  printString(qname.localName);
603  printf("\n");
604  }
605  }
606  else if(appD->outputFormat == OUT_XML)
607  {
608  if(appD->expectAttributeData)
609  {
610  printString(qname.uri);
611  printf(":");
612  printString(qname.localName);
613  printf("\"");
614  appD->expectAttributeData = 0;
615  }
616  else
617  {
618  if(appD->unclosedElement)
619  printf(">");
620  appD->unclosedElement = 0;
621  printString(qname.uri);
622  printf(":");
623  printString(qname.localName);
624  }
625  }
626 
627  return EXIP_OK;
628 }
629 
630 // Stuff needed for the OUT_XML Output Format
631 // ******************************************
632 static void push(struct element** stack, struct element* el)
633 {
634  if(*stack == NULL)
635  *stack = el;
636  else
637  {
638  el->next = *stack;
639  *stack = el;
640  }
641 }
642 
643 static struct element* pop(struct element** stack)
644 {
645  if(*stack == NULL)
646  return NULL;
647  else
648  {
649  struct element* result;
650  result = *stack;
651  *stack = (*stack)->next;
652  return result;
653  }
654 }
655 
656 static struct element* createElement(char* name)
657 {
658  struct element* el;
659  el = malloc(sizeof(struct element));
660  if(el == NULL)
661  exit(1);
662  el->next = NULL;
663  el->name = malloc(strlen(name)+1);
664  if(el->name == NULL)
665  exit(1);
666  strcpy(el->name, name);
667  return el;
668 }
669 
670 static void destroyElement(struct element* el)
671 {
672  free(el->name);
673  free(el);
674 }
675 // ******************************************
676 
677 static char lookupPrefix(struct appData* aData, String ns, unsigned char* prxHit, unsigned char* prefixIndex)
678 {
679  int i;
680  for(i = 0; i < aData->prefixesCount; i++)
681  {
682  if(stringEqualToAscii(ns, aData->prefixes[i]))
683  {
684  *prefixIndex = i;
685  *prxHit = 1;
686  return 0;
687  }
688  }
689 
690  if(aData->prefixesCount == MAX_PREFIXES)
691  return 1;
692  else
693  {
694  memcpy(aData->prefixes[aData->prefixesCount], ns.str, ns.length);
695  aData->prefixes[aData->prefixesCount][ns.length] = '\0';
696  *prefixIndex = aData->prefixesCount;
697  aData->prefixesCount += 1;
698  *prxHit = 0;
699  return 0;
700  }
701 }