exip  Alpha 0.5.4
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
check_xsi_type.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 
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <check.h>
21 #include "procTypes.h"
22 #include "EXISerializer.h"
23 #include "EXIParser.h"
24 #include "stringManipulate.h"
25 #include "grammarGenerator.h"
26 
27 #define OUTPUT_BUFFER_SIZE 2000
28 
29 /* BEGIN: SchemaLess tests */
30 
31 START_TEST (test_default_options)
32 {
33  EXIStream testStrm;
34  Parser testParser;
35  String uri;
36  String ln;
37  QName qname= {&uri, &ln};
38  String chVal;
39  char buf[OUTPUT_BUFFER_SIZE];
40  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
41  BinaryBuffer buffer;
42  EXITypeClass valueType;
43 
44  buffer.buf = buf;
45  buffer.bufContent = 0;
46  buffer.bufLen = OUTPUT_BUFFER_SIZE;
47  buffer.ioStrm.readWriteToStream = NULL;
48  buffer.ioStrm.stream = NULL;
49 
50  // Serialization steps:
51 
52  // I: First initialize the header of the stream
53  serialize.initHeader(&testStrm);
54 
55  // II: Set any options in the header, if different from the defaults
56  testStrm.header.has_options = TRUE;
58 
59  // III: Define an external stream for the output if any
60 
61  // IV: Initialize the stream
62  tmp_err_code = serialize.initStream(&testStrm, buffer, NULL);
63  fail_unless (tmp_err_code == EXIP_OK, "initStream returns an error code %d", tmp_err_code);
64 
65  // V: Start building the stream step by step: header, document, element etc...
66  tmp_err_code = serialize.exiHeader(&testStrm);
67  fail_unless (tmp_err_code == EXIP_OK, "serialize.exiHeader returns an error code %d", tmp_err_code);
68 
69  tmp_err_code = serialize.startDocument(&testStrm);
70  fail_unless (tmp_err_code == EXIP_OK, "serialize.startDocument returns an error code %d", tmp_err_code);
71 
72  tmp_err_code += asciiToString("http://www.ltu.se/EISLAB/schema-test", &uri, &testStrm.memList, FALSE);
73  tmp_err_code += asciiToString("EXIPEncoder", &ln, &testStrm.memList, FALSE);
74  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType);
75  fail_unless (tmp_err_code == EXIP_OK, "serialize.startElement returns an error code %d", tmp_err_code);
76 
77  tmp_err_code += asciiToString("", &uri, &testStrm.memList, FALSE);
78  tmp_err_code += asciiToString("version", &ln, &testStrm.memList, FALSE);
79  tmp_err_code += serialize.attribute(&testStrm, qname, TRUE, &valueType);
80  fail_unless (tmp_err_code == EXIP_OK, "serialize.attribute returns an error code %d", tmp_err_code);
81 
82  tmp_err_code += asciiToString("0.2", &chVal, &testStrm.memList, FALSE);
83  tmp_err_code += serialize.stringData(&testStrm, chVal);
84  fail_unless (tmp_err_code == EXIP_OK, "serialize.stringData returns an error code %d", tmp_err_code);
85 
86  tmp_err_code += asciiToString("", &uri, &testStrm.memList, FALSE);
87  tmp_err_code += asciiToString("status", &ln, &testStrm.memList, FALSE);
88  tmp_err_code += serialize.attribute(&testStrm, qname, TRUE, &valueType);
89  fail_unless (tmp_err_code == EXIP_OK, "serialize.attribute returns an error code %d", tmp_err_code);
90 
91  tmp_err_code += asciiToString("alpha", &chVal, &testStrm.memList, FALSE);
92  tmp_err_code += serialize.stringData(&testStrm, chVal);
93  fail_unless (tmp_err_code == EXIP_OK, "serialize.stringData returns an error code %d", tmp_err_code);
94 
95  tmp_err_code += asciiToString("This is an example of serializing EXI streams using EXIP low level API", &chVal, &testStrm.memList, FALSE);
96  tmp_err_code += serialize.stringData(&testStrm, chVal);
97  fail_unless (tmp_err_code == EXIP_OK, "serialize.stringData returns an error code %d", tmp_err_code);
98 
99  tmp_err_code += asciiToString("", &uri, &testStrm.memList, FALSE);
100  tmp_err_code += asciiToString("xsitypetest", &ln, &testStrm.memList, FALSE);
101  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType);
102  fail_unless (tmp_err_code == EXIP_OK, "serialize.startElement returns an error code %d", tmp_err_code);
103 
104  tmp_err_code += asciiToString("http://www.w3.org/2001/XMLSchema-instance", &uri, &testStrm.memList, FALSE);
105  tmp_err_code += asciiToString("type", &ln, &testStrm.memList, FALSE);
106  tmp_err_code += serialize.attribute(&testStrm, qname, TRUE, &valueType);
107  fail_unless (tmp_err_code == EXIP_OK, "serialize.attribute returns an error code %d", tmp_err_code);
108 
109  tmp_err_code += asciiToString("http://www.w3.org/2001/XMLSchema", &uri, &testStrm.memList, FALSE);
110  tmp_err_code += asciiToString("integer", &ln, &testStrm.memList, FALSE);
111  tmp_err_code += serialize.qnameData(&testStrm, qname);
112  fail_unless (tmp_err_code == EXIP_OK, "serialize.qnameData returns an error code %d", tmp_err_code);
113 
114  tmp_err_code += serialize.intData(&testStrm, 144);
115  fail_unless (tmp_err_code == EXIP_OK, "serialize.intData returns an error code %d", tmp_err_code);
116 
117  tmp_err_code += serialize.endElement(&testStrm);
118 
119  tmp_err_code += serialize.endElement(&testStrm);
120  tmp_err_code += serialize.endDocument(&testStrm);
121 
122  if(tmp_err_code != EXIP_OK)
123  fail_unless (tmp_err_code == EXIP_OK, "serialization ended with error code %d", tmp_err_code);
124 
125  // V: Free the memory allocated by the EXI stream object
126  tmp_err_code = serialize.closeEXIStream(&testStrm);
127  fail_unless (tmp_err_code == EXIP_OK, "serialize.closeEXIStream ended with error code %d", tmp_err_code);
128 
129 
131  // Parsing steps:
132 
133  // I: First, define an external stream for the input to the parser if any
134 
135  // II: Second, initialize the parser object
136  tmp_err_code = initParser(&testParser, buffer, NULL);
137  fail_unless (tmp_err_code == EXIP_OK, "initParser returns an error code %d", tmp_err_code);
138 
139  // III: Initialize the parsing data and hook the callback handlers to the parser object
140 
141  // IV: Parse the header of the stream
142 
143  tmp_err_code = parseHeader(&testParser, FALSE);
144  fail_unless (tmp_err_code == EXIP_OK, "parsing the header returns an error code %d", tmp_err_code);
145 
146  tmp_err_code = setSchema(&testParser, NULL);
147  fail_unless (tmp_err_code == EXIP_OK, "setSchema() returns an error code %d", tmp_err_code);
148 
149  // V: Parse the body of the EXI stream
150 
151  while(tmp_err_code == EXIP_OK)
152  {
153  tmp_err_code = parseNext(&testParser);
154  }
155 
156  // VI: Free the memory allocated by the parser object
157 
158  destroyParser(&testParser);
159  fail_unless (tmp_err_code == EXIP_PARSING_COMPLETE, "Error during parsing of the EXI body %d", tmp_err_code);
160 }
161 END_TEST
162 
163 /* END: SchemaLess tests */
164 
165 /* BEGIN: Schema-mode tests */
166 
167 char *XSI = "http://www.w3.org/2001/XMLSchema-instance";
168 char *XS = "http://www.w3.org/2001/XMLSchema";
169 char *EXEMPLE = "http://www.exemple.com/XMLNameSpace";
170 #define MAX_XSD_FILES_COUNT 10 // up to 10 XSD files
171 static char *dataDir;
172 #define MAX_PATH_LEN 200
173 
174 #define PRINTOUTS 0
175 
176 static void parseSchema(const char* fileName, EXIPSchema* schema);
177 
178 static errorCode sample_fatalError(const errorCode code, const char* msg, void* app_data);
179 static errorCode sample_startDocument(void* app_data);
180 static errorCode sample_endDocument(void* app_data);
181 static errorCode sample_startElement(QName qname, void* app_data);
182 static errorCode sample_endElement(void* app_data);
183 static errorCode sample_attribute(QName qname, void* app_data);
184 static errorCode sample_stringData(const String value, void* app_data);
185 static errorCode sample_decimalData(Decimal value, void* app_data);
186 static errorCode sample_intData(Integer int_val, void* app_data);
187 static errorCode sample_floatData(Float fl_val, void* app_data);
188 static errorCode sample_booleanData(boolean bool_val, void* app_data);
189 static errorCode sample_dateTimeData(EXIPDateTime dt_val, void* app_data);
190 static errorCode sample_binaryData(const char* binary_val, Index nbytes, void* app_data);
191 static errorCode sample_qnameData(const QName qname, void* app_data);
192 
193 START_TEST (test_simple_schema)
194 {
195  const char* schemafname = "xsitype/Product.exs";
196  EXIStream testStrm;
197  EXIPSchema schema, *schemaPtr = NULL;
198  String uri;
199  String ln;
200  QName qname= {&uri, &ln};
201  String chVal;
202  char buf[OUTPUT_BUFFER_SIZE];
203  errorCode tmp_err_code = 0;
204  BinaryBuffer buffer;
205  EXITypeClass valueType;
206 
207  buffer.buf = buf;
208  buffer.bufContent = 0;
209  buffer.bufLen = OUTPUT_BUFFER_SIZE;
210  buffer.ioStrm.readWriteToStream = NULL;
211  buffer.ioStrm.stream = NULL;
212 
213  parseSchema(schemafname, &schema);
214  schemaPtr = &schema;
215 
216  serialize.initHeader(&testStrm);
217 
218  testStrm.header.has_options = TRUE;
220 
221  if (schemaPtr) {
222  tmp_err_code = asciiToString("product", &testStrm.header.opts.schemaID, &testStrm.memList, FALSE);
223  fail_unless (tmp_err_code == EXIP_OK, "asciiToString returns an error code %d", tmp_err_code);
225  }
226 
227  tmp_err_code = serialize.initStream(&testStrm, buffer, schemaPtr);
228  fail_unless (tmp_err_code == EXIP_OK, "serialize returns an error code %d", tmp_err_code);
229  tmp_err_code = serialize.exiHeader(&testStrm);
230  fail_unless (tmp_err_code == EXIP_OK, "serialize returns an error code %d", tmp_err_code);
231  tmp_err_code = serialize.startDocument(&testStrm);
232  fail_unless (tmp_err_code == EXIP_OK, "serialize returns an error code %d", tmp_err_code);
233 
234  tmp_err_code += asciiToString(EXEMPLE, &uri, &testStrm.memList, FALSE);
235  tmp_err_code += asciiToString("product", &ln, &testStrm.memList, FALSE);
236  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType);
237 
238  tmp_err_code += asciiToString(XSI, &uri, &testStrm.memList, FALSE);
239  tmp_err_code += asciiToString("type", &ln, &testStrm.memList, FALSE);
240  tmp_err_code += serialize.attribute(&testStrm, qname, TRUE, &valueType);
241 
242  tmp_err_code += asciiToString(EXEMPLE, &uri, &testStrm.memList, FALSE);
243  tmp_err_code += asciiToString("ShirtType", &ln, &testStrm.memList, FALSE);
244  tmp_err_code += serialize.qnameData(&testStrm, qname);
245 
246  tmp_err_code += asciiToString("", &uri, &testStrm.memList, FALSE);
247  tmp_err_code += asciiToString("number", &ln, &testStrm.memList, FALSE);
248  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType);
249  fail_unless (tmp_err_code == EXIP_OK, "serialize returns an error code %d", tmp_err_code);
250 
251  if (schemaPtr) {
252  tmp_err_code += serialize.intData(&testStrm, 12345);
253  }
254  else {
255  tmp_err_code += asciiToString("12345", &chVal, &testStrm.memList, FALSE);
256  tmp_err_code += serialize.stringData(&testStrm, chVal);
257  }
258 
259  fail_unless (tmp_err_code == EXIP_OK, "serialize returns an error code %d", tmp_err_code);
260  tmp_err_code += serialize.endElement(&testStrm);
261 
262  tmp_err_code += asciiToString("", &uri, &testStrm.memList, FALSE);
263  tmp_err_code += asciiToString("size", &ln, &testStrm.memList, FALSE);
264  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType);
265 
266  if (schemaPtr) {
267  tmp_err_code += serialize.intData(&testStrm, 33);
268  }
269  else {
270  tmp_err_code += asciiToString("33", &chVal, &testStrm.memList, FALSE);
271  tmp_err_code += serialize.stringData(&testStrm, chVal);
272  }
273 
274  tmp_err_code += serialize.endElement(&testStrm);
275  tmp_err_code += serialize.endElement(&testStrm);
276  tmp_err_code += serialize.endDocument(&testStrm);
277 
278  // V: Free the memory allocated by the EXI stream object
279  tmp_err_code = serialize.closeEXIStream(&testStrm);
280 
281  fail_unless (tmp_err_code == EXIP_OK, "serialize returns an error code %d", tmp_err_code);
282 
283  // DECODING
284 
285  Parser testParser;
286 
287  buffer.bufContent = testStrm.context.bufferIndx + 1;
288  tmp_err_code = initParser(&testParser, buffer, NULL);
289 
290  testParser.handler.fatalError = sample_fatalError;
291  testParser.handler.error = sample_fatalError;
292  testParser.handler.startDocument = sample_startDocument;
293  testParser.handler.endDocument = sample_endDocument;
294  testParser.handler.startElement = sample_startElement;
295  testParser.handler.attribute = sample_attribute;
296  testParser.handler.stringData = sample_stringData;
297  testParser.handler.endElement = sample_endElement;
298  testParser.handler.decimalData = sample_decimalData;
299  testParser.handler.intData = sample_intData;
300  testParser.handler.floatData = sample_floatData;
301  testParser.handler.booleanData = sample_booleanData;
302  testParser.handler.dateTimeData = sample_dateTimeData;
303  testParser.handler.binaryData = sample_binaryData;
304  testParser.handler.qnameData = sample_qnameData;
305 
306  tmp_err_code = parseHeader(&testParser, FALSE);
307 
308  // IV.1: Set the schema to be used for parsing.
309  // The schemaID mode and schemaID field can be read at
310  // parser.strm.header.opts.schemaIDMode and
311  // parser.strm.header.opts.schemaID respectively
312  // If schemaless mode, use setSchema(&parser, NULL);
313 
314  tmp_err_code = setSchema(&testParser, schemaPtr);
315  fail_unless (tmp_err_code == EXIP_OK, "setSchema() returns an error code %d", tmp_err_code);
316 
317  while(tmp_err_code == EXIP_OK)
318  {
319  tmp_err_code = parseNext(&testParser);
320  }
321 
322  destroyParser(&testParser);
323  fail_unless (tmp_err_code == EXIP_PARSING_COMPLETE, "Error during parsing of the EXI body %d", tmp_err_code);
324 }
325 END_TEST
326 
327 #if PRINTOUTS
328 static void printURI(const String *str) {
329  if (stringEqualToAscii(*str, XSI))
330  printf ("xsi");
331  else if (stringEqualToAscii(*str, XS))
332  printf ("xs");
333  else if (stringEqualToAscii(*str, EXEMPLE))
334  printf ("ABC");
335  else
336  fwrite (str->str, sizeof(CharType), str->length, stdout);
337 }
338 
339 void printQName(const QName qname) {
340  printURI (qname.uri);
341  printf(":");
342  printString(qname.localName);
343 }
344 #endif
345 
346 static errorCode sample_fatalError(const errorCode code, const char* msg, void* app_data)
347 {
348 #if PRINTOUTS
349  printf("\n### %d : FATAL ERROR: %s\n", code, msg);
350 #endif
351  return EXIP_HANDLER_STOP;
352 }
353 
354 static errorCode sample_startDocument(void* app_data)
355 {
356 #if PRINTOUTS
357  printf("### SD\n");
358 #endif
359  return EXIP_OK;
360 }
361 
362 static errorCode sample_endDocument(void* app_data)
363 {
364 #if PRINTOUTS
365  printf("### ED\n");
366 #endif
367  return EXIP_OK;
368 }
369 
370 static errorCode sample_startElement(QName qname, void* app_data)
371 {
372 #if PRINTOUTS
373  printf("### SE ");
374  printQName (qname);
375  printf("\n");
376 #endif
377  return EXIP_OK;
378 }
379 
380 static errorCode sample_endElement(void* app_data)
381 {
382 #if PRINTOUTS
383  printf("### EE\n");
384 #endif
385  return EXIP_OK;
386 }
387 
389 
390 static errorCode sample_attribute(QName qname, void* app_data)
391 {
392 #if PRINTOUTS
393  printf("### AT ");
394  printQName (qname);
395  printf("=\"");
396 #endif
397  expectAttributeData = 1;
398  return EXIP_OK;
399 }
400 
401 static errorCode sample_stringData(const String value, void* app_data)
402 {
403  if(expectAttributeData)
404  {
405 #if PRINTOUTS
406  printString(&value);
407  printf("\"\n");
408 #endif
409  expectAttributeData = 0;
410  }
411  else
412  {
413 #if PRINTOUTS
414  printf("CH ");
415  printString(&value);
416  printf("\n");
417 #endif
418  }
419  return EXIP_OK;
420 }
421 
422 static errorCode sample_decimalData(Decimal value, void* app_data)
423 {
424  return EXIP_OK;
425 }
426 
427 static errorCode sample_intData(Integer int_val, void* app_data)
428 {
429  if(expectAttributeData)
430  {
431 #if PRINTOUTS
432  char tmp_buf[30];
433  sprintf(tmp_buf, "%lld", (long long int) int_val);
434  printf("### intData %s", tmp_buf);
435  printf("\"\n");
436 #endif
437  expectAttributeData = 0;
438  }
439  else
440  {
441 #if PRINTOUTS
442  char tmp_buf[30];
443  printf("### intData ");
444  sprintf(tmp_buf, "%lld", (long long int) int_val);
445  printf("%s", tmp_buf);
446  printf("\n");
447 #endif
448  }
449  return EXIP_OK;
450 }
451 
452 static errorCode sample_booleanData(boolean bool_val, void* app_data)
453 {
454  return EXIP_OK;
455 }
456 
457 static errorCode sample_floatData(Float fl_val, void* app_data)
458 {
459  return EXIP_OK;
460 }
461 
462 static errorCode sample_dateTimeData(EXIPDateTime dt_val, void* app_data)
463 {
464  return EXIP_OK;
465 }
466 
467 static errorCode sample_binaryData(const char* binary_val, Index nbytes, void* app_data)
468 {
469  return EXIP_OK;
470 }
471 
472 static errorCode sample_qnameData(const QName qname, void* app_data)
473 {
474 #if PRINTOUTS
475  printf ("### qnameData : ");
476  printQName (qname);
477  printf("\"\n");
478 #endif
479  expectAttributeData = 0;
480  return EXIP_OK;
481 }
482 
483 static void parseSchema(const char* fileName, EXIPSchema* schema)
484 {
485  FILE *schemaFile;
486  BinaryBuffer buffer;
487  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
488  size_t pathlen = strlen(dataDir);
489  char exipath[MAX_PATH_LEN + strlen(fileName)];
490 
491  memcpy(exipath, dataDir, pathlen);
492  exipath[pathlen] = '/';
493  memcpy(&exipath[pathlen+1], fileName, strlen(fileName)+1);
494  schemaFile = fopen(exipath, "rb" );
495  if(!schemaFile)
496  {
497  fail("Unable to open file %s", exipath);
498  }
499  else
500  {
501  //Get file length
502  fseek(schemaFile, 0, SEEK_END);
503  buffer.bufLen = ftell(schemaFile) + 1;
504  fseek(schemaFile, 0, SEEK_SET);
505 
506  //Allocate memory
507  buffer.buf = (char *)malloc(buffer.bufLen);
508  if (!buffer.buf)
509  {
510  fclose(schemaFile);
511  fail("Memory allocation error!");
512  }
513 
514  //Read file contents into buffer
515  fread(buffer.buf, buffer.bufLen, 1, schemaFile);
516  fclose(schemaFile);
517 
518  buffer.bufContent = buffer.bufLen;
519  buffer.ioStrm.readWriteToStream = NULL;
520  buffer.ioStrm.stream = NULL;
521 
522  tmp_err_code = generateSchemaInformedGrammars(&buffer, 1, SCHEMA_FORMAT_XSD_EXI, NULL, schema, NULL);
523 
524  if(tmp_err_code != EXIP_OK)
525  {
526  fail("\n Error reading schema: %d", tmp_err_code);
527  }
528 
529  free(buffer.buf);
530  }
531 }
532 
533 /* END: Schema-mode tests */
534 
536 {
537  Suite *s = suite_create("XSI:TYPE");
538 
539  {
540  /* Schema-less test case */
541  TCase *tc_SchLess = tcase_create ("SchemaLess");
542  tcase_add_test (tc_SchLess, test_default_options);
543  suite_add_tcase (s, tc_SchLess);
544  }
545  {
546  /* Schema-mode test case */
547  TCase *tc_Schema = tcase_create ("Schema-mode");
548  tcase_add_test (tc_Schema, test_simple_schema);
549  suite_add_tcase (s, tc_Schema);
550  }
551 
552  return s;
553 }
554 
555 int main (int argc, char *argv[])
556 {
557  int number_failed;
558  Suite *s = exip_suite();
559  SRunner *sr = srunner_create (s);
560 
561  if (argc < 2)
562  {
563  printf("ERR: Expected test data directory\n");
564  exit(1);
565  }
566  if (strlen(argv[1]) > MAX_PATH_LEN)
567  {
568  printf("ERR: Test data pathname too long: %u", (unsigned int) strlen(argv[1]));
569  exit(1);
570  }
571 
572  dataDir = argv[1];
573 
574 #ifdef _MSC_VER
576 #endif
578  number_failed = srunner_ntests_failed (sr);
579  srunner_free (sr);
580  return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
581 }
582