exip  Alpha 0.5.4
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
check_emptyType.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 <check.h>
20 #include "procTypes.h"
21 #include "EXIParser.h"
22 #include "stringManipulate.h"
23 #include "grammarGenerator.h"
24 
25 #define MAX_PATH_LEN 200
26 
27 /* Location for external test data */
28 static char *dataDir;
29 #define EMPTY_TYPE_SCHEMA "EmptyTypes/emptyTypeSchema-xsd.exi"
30 #define EMPTY_TYPE_DEFAULT "EmptyTypes/emptyTypeTest-def.exi"
31 #define EMPTY_TYPE_STRICT "EmptyTypes/emptyTypeTest-strict.exi"
32 
33 #define OUTPUT_BUFFER_SIZE 2000
34 
35 struct appData
36 {
37  unsigned int eventCount;
38  unsigned short expectAttributeData;
39 };
40 typedef struct appData appData;
41 
42 size_t readFileInputStream(void* buf, size_t readSize, void* stream)
43 {
44  FILE *infile = (FILE*) stream;
45  return fread(buf, 1, readSize, infile);
46 }
47 
48 static void parseSchema(const char* fileName, EXIPSchema* schema)
49 {
50  FILE *schemaFile;
51  BinaryBuffer buffer;
52  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
53  size_t pathlen = strlen(dataDir);
54  char exipath[MAX_PATH_LEN + strlen(fileName)];
55 
56  memcpy(exipath, dataDir, pathlen);
57  exipath[pathlen] = '/';
58  memcpy(&exipath[pathlen+1], fileName, strlen(fileName)+1);
59  schemaFile = fopen(exipath, "rb" );
60  if(!schemaFile)
61  {
62  fail("Unable to open file %s", exipath);
63  }
64  else
65  {
66  //Get file length
67  fseek(schemaFile, 0, SEEK_END);
68  buffer.bufLen = ftell(schemaFile) + 1;
69  fseek(schemaFile, 0, SEEK_SET);
70 
71  //Allocate memory
72  buffer.buf = (char *)malloc(buffer.bufLen);
73  if (!buffer.buf)
74  {
75  fclose(schemaFile);
76  fail("Memory allocation error!");
77  }
78 
79  //Read file contents into buffer
80  fread(buffer.buf, buffer.bufLen, 1, schemaFile);
81  fclose(schemaFile);
82 
83  buffer.bufContent = buffer.bufLen;
84  buffer.ioStrm.readWriteToStream = NULL;
85  buffer.ioStrm.stream = NULL;
86 
87  tmp_err_code = generateSchemaInformedGrammars(&buffer, 1, SCHEMA_FORMAT_XSD_EXI, NULL, schema, NULL);
88 
89  if(tmp_err_code != EXIP_OK)
90  {
91  fail("\n Error reading schema: %d", tmp_err_code);
92  }
93 
94  free(buffer.buf);
95  }
96 }
97 
98 /* Document callbacks */
99 
100 static errorCode sample_fatalError(const errorCode code, const char* msg, void* app_data)
101 {
102  printf("\n%3d : FATAL ERROR: %s\n", code, msg);
103  return EXIP_HANDLER_STOP;
104 }
105 
106 static errorCode sample_startElement(QName qname, void* app_data)
107 {
108  appData* appD = (appData*) app_data;
109 
110  if(!stringEqualToAscii(*qname.uri, "http://www.example.org/emptyTypeSchema"))
111  {
112  printf("\nInvalid namespace!");
113  return EXIP_HANDLER_STOP;
114  }
115 
116  switch(appD->eventCount)
117  {
118  case 0:
119  if(!stringEqualToAscii(*qname.localName, "rootElem"))
120  {
121  printf("\nInvalid doc: rootElem!");
122  return EXIP_HANDLER_STOP;
123  }
124  appD->eventCount++;
125  break;
126  case 2:
127  if(!stringEqualToAscii(*qname.localName, "nilabElem"))
128  {
129  printf("\nInvalid doc: nilabElem!");
130  return EXIP_HANDLER_STOP;
131  }
132  appD->eventCount++;
133  break;
134  default:
135  printf("\nInvalid decoding startElement!");
136  return EXIP_HANDLER_STOP;
137  break;
138  }
139  return EXIP_OK;
140 }
141 
142 static errorCode sample_attribute(QName qname, void* app_data)
143 {
144  appData* appD = (appData*) app_data;
145 
146  switch(appD->eventCount)
147  {
148  case 1:
149  if(!stringEqualToAscii(*qname.localName, "basis"))
150  {
151  printf("\nInvalid doc: basis!");
152  return EXIP_HANDLER_STOP;
153  }
154  appD->eventCount++;
155  break;
156  case 3:
157  if(!stringEqualToAscii(*qname.uri, "http://www.w3.org/2001/XMLSchema-instance") ||
158  !stringEqualToAscii(*qname.localName, "nil"))
159  {
160  printf("\nInvalid doc: xsi:nill!");
161  return EXIP_HANDLER_STOP;
162  }
163  appD->eventCount++;
164  break;
165  case 4:
166  if(!stringEqualToAscii(*qname.localName, "bass"))
167  {
168  printf("\nInvalid doc: bass!");
169  return EXIP_HANDLER_STOP;
170  }
171  appD->eventCount++;
172  break;
173  case 5:
174  if(!stringEqualToAscii(*qname.localName, "foo"))
175  {
176  printf("\nInvalid doc: foo!");
177  return EXIP_HANDLER_STOP;
178  }
179  appD->eventCount++;
180  break;
181  default:
182  printf("\nInvalid decoding: attribute!");
183  return EXIP_HANDLER_STOP;
184  break;
185  }
186  return EXIP_OK;
187 }
188 
189 static errorCode sample_stringData(const String value, void* app_data)
190 {
191  appData* appD = (appData*) app_data;
192 
193  switch(appD->eventCount)
194  {
195  case 2:
196  if(!stringEqualToAscii(value, "Ahaa"))
197  {
198  printf("\nInvalid decoding: Ahaa!");
199  return EXIP_HANDLER_STOP;
200  }
201  break;
202  case 5:
203  if(!stringEqualToAscii(value, "fooBass"))
204  {
205  printf("\nInvalid decoding: fooBass!");
206  return EXIP_HANDLER_STOP;
207  }
208  break;
209  default:
210  printf("\nInvalid decoding: stringData!");
211  return EXIP_HANDLER_STOP;
212  break;
213  }
214  return EXIP_OK;
215 }
216 
217 static errorCode sample_intData(Integer int_val, void* app_data)
218 {
219  if(int_val != 11)
220  {
221  printf("\nInvalid decoding: intData!");
222  return EXIP_HANDLER_STOP;
223  }
224 
225  return EXIP_OK;
226 }
227 
228 START_TEST (test_default_options)
229 {
230  EXIPSchema schema;
231  Parser testParser;
232  char buf[OUTPUT_BUFFER_SIZE];
233  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
234  BinaryBuffer buffer;
235  char exipath[MAX_PATH_LEN + strlen(EMPTY_TYPE_DEFAULT)];
236  size_t pathlen;
237  FILE *infile;
238  struct appData parsingData;
239 
240  buffer.buf = buf;
241  buffer.bufContent = 0;
242  buffer.bufLen = OUTPUT_BUFFER_SIZE;
243  buffer.ioStrm.readWriteToStream = NULL;
244  buffer.ioStrm.stream = NULL;
245 
246  // Parsing steps:
247 
248  // I.A: First, read in the schema
249  parseSchema(EMPTY_TYPE_SCHEMA, &schema);
250 
251  // I.B: Define an external stream for the input to the parser if any
252  pathlen = strlen(dataDir);
253  memcpy(exipath, dataDir, pathlen);
254  exipath[pathlen] = '/';
255  memcpy(&exipath[pathlen+1], EMPTY_TYPE_DEFAULT, strlen(EMPTY_TYPE_DEFAULT)+1);
256 
257  infile = fopen(exipath, "rb" );
258  if(!infile)
259  fail("Unable to open file %s", exipath);
260 
262  buffer.ioStrm.stream = infile;
263 
264  // II: Second, initialize the parser object
265  tmp_err_code = initParser(&testParser, buffer, &parsingData);
266  fail_unless (tmp_err_code == EXIP_OK, "initParser returns an error code %d", tmp_err_code);
267 
268  // III: Initialize the parsing data and hook the callback handlers to the parser object
269  parsingData.eventCount = 0;
270  parsingData.expectAttributeData = 0;
271 
272  testParser.handler.fatalError = sample_fatalError;
273  testParser.handler.error = sample_fatalError;
274  testParser.handler.startElement = sample_startElement;
275  testParser.handler.attribute = sample_attribute;
276  testParser.handler.stringData = sample_stringData;
277  testParser.handler.intData = sample_intData;
278 
279  // IV: Parse the header of the stream
280 
281  tmp_err_code = parseHeader(&testParser, TRUE);
282  fail_unless (tmp_err_code == EXIP_OK, "parsing the header returns an error code %d", tmp_err_code);
283 
284  tmp_err_code = setSchema(&testParser, &schema);
285  fail_unless (tmp_err_code == EXIP_OK, "setSchema() returns an error code %d", tmp_err_code);
286  // V: Parse the body of the EXI stream
287 
288  while(tmp_err_code == EXIP_OK)
289  {
290  tmp_err_code = parseNext(&testParser);
291  }
292 
293  // VI: Free the memory allocated by the parser object
294 
295  destroyParser(&testParser);
296  fail_unless (tmp_err_code == EXIP_PARSING_COMPLETE, "Error during parsing of the EXI body %d", tmp_err_code);
297 }
298 END_TEST
299 
300 START_TEST (test_strict_option)
301 {
302  EXIPSchema schema;
303  Parser testParser;
304  char buf[OUTPUT_BUFFER_SIZE];
305  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
306  BinaryBuffer buffer;
307  char exipath[MAX_PATH_LEN + strlen(EMPTY_TYPE_DEFAULT)];
308  size_t pathlen;
309  FILE *infile;
310  struct appData parsingData;
311 
312  buffer.buf = buf;
313  buffer.bufContent = 0;
314  buffer.bufLen = OUTPUT_BUFFER_SIZE;
315  buffer.ioStrm.readWriteToStream = NULL;
316  buffer.ioStrm.stream = NULL;
317 
318  // Parsing steps:
319 
320  // I.A: First, read in the schema
321  parseSchema(EMPTY_TYPE_SCHEMA, &schema);
322 
323  // I.B: Define an external stream for the input to the parser if any
324  pathlen = strlen(dataDir);
325  memcpy(exipath, dataDir, pathlen);
326  exipath[pathlen] = '/';
327  memcpy(&exipath[pathlen+1], EMPTY_TYPE_STRICT, strlen(EMPTY_TYPE_STRICT)+1);
328 
329  infile = fopen(exipath, "rb" );
330  if(!infile)
331  fail("Unable to open file %s", exipath);
332 
334  buffer.ioStrm.stream = infile;
335 
336  // II: Second, initialize the parser object
337  tmp_err_code = initParser(&testParser, buffer, &parsingData);
338  fail_unless (tmp_err_code == EXIP_OK, "initParser returns an error code %d", tmp_err_code);
339 
340  // III: Initialize the parsing data and hook the callback handlers to the parser object
341  parsingData.eventCount = 0;
342  parsingData.expectAttributeData = 0;
343 
344  testParser.handler.fatalError = sample_fatalError;
345  testParser.handler.error = sample_fatalError;
346  testParser.handler.startElement = sample_startElement;
347  testParser.handler.attribute = sample_attribute;
348  testParser.handler.stringData = sample_stringData;
349  testParser.handler.intData = sample_intData;
350 
351  // IV: Parse the header of the stream
352 
353  tmp_err_code = parseHeader(&testParser, FALSE);
354  fail_unless (tmp_err_code == EXIP_OK, "parsing the header returns an error code %d", tmp_err_code);
355 
356  tmp_err_code = setSchema(&testParser, &schema);
357  fail_unless (tmp_err_code == EXIP_OK, "setSchema() returns an error code %d", tmp_err_code);
358 
359  // V: Parse the body of the EXI stream
360 
361  while(tmp_err_code == EXIP_OK)
362  {
363  tmp_err_code = parseNext(&testParser);
364  }
365 
366  // VI: Free the memory allocated by the parser object
367 
368  destroyParser(&testParser);
369  fail_unless (tmp_err_code == EXIP_PARSING_COMPLETE, "Error during parsing of the EXI body %d", tmp_err_code);
370 }
371 END_TEST
372 
373 /* END: SchemaLess tests */
374 
376 {
377  Suite *s = suite_create("Empty Type");
378 
379  {
380  /* Default options test case */
381  TCase *tc_Def = tcase_create ("Default options");
382  tcase_add_test (tc_Def, test_default_options);
383  suite_add_tcase (s, tc_Def);
384 
385  /* Default options test case */
386  TCase *tc_Strict = tcase_create ("Strict");
387  tcase_add_test (tc_Strict, test_strict_option);
388  suite_add_tcase (s, tc_Strict);
389  }
390 
391  return s;
392 }
393 
394 int main (int argc, char *argv[])
395 {
396  if (argc < 2)
397  {
398  printf("ERR: Expected test data directory\n");
399  exit(1);
400  }
401  if (strlen(argv[1]) > MAX_PATH_LEN)
402  {
403  printf("ERR: Test data pathname too long: %u", (unsigned int) strlen(argv[1]));
404  exit(1);
405  }
406  dataDir = argv[1];
407 
408  int number_failed;
409  Suite *s = exip_suite();
410  SRunner *sr = srunner_create (s);
411 #ifdef _MSC_VER
413 #endif
415  number_failed = srunner_ntests_failed (sr);
416  srunner_free (sr);
417  return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
418 }