exip  Alpha 0.5.4
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
check_exip.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 <stdio.h>
19 #include <stdlib.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 MAX_PATH_LEN 200
28 #define OUTPUT_BUFFER_SIZE 2000
29 /* Location for external test data */
30 static char *dataDir;
31 
32 static size_t writeFileOutputStream(void* buf, size_t readSize, void* stream);
33 static size_t readFileInputStream(void* buf, size_t readSize, void* stream);
34 static void parseSchema(char** xsdList, int count, EXIPSchema* schema);
35 
36 #define TRY_CATCH_ENCODE(func) TRY_CATCH(func, serialize.closeEXIStream(&testStrm))
37 
38 /* BEGIN: SchemaLess tests */
39 
40 START_TEST (test_default_options)
41 {
42  EXIStream testStrm;
43  Parser testParser;
44  String uri;
45  String ln;
46  QName qname= {&uri, &ln};
47  String chVal;
48  char buf[OUTPUT_BUFFER_SIZE];
49  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
50  BinaryBuffer buffer;
51  EXITypeClass valueType;
52 
53  buffer.buf = buf;
54  buffer.bufContent = 0;
55  buffer.bufLen = OUTPUT_BUFFER_SIZE;
56  buffer.ioStrm.readWriteToStream = NULL;
57  buffer.ioStrm.stream = NULL;
58 
59  // Serialization steps:
60 
61  // I: First initialize the header of the stream
62  serialize.initHeader(&testStrm);
63 
64  // II: Set any options in the header, if different from the defaults
65 
66  // III: Define an external stream for the output if any
67 
68  // IV: Initialize the stream
69  tmp_err_code = serialize.initStream(&testStrm, buffer, NULL);
70  fail_unless (tmp_err_code == EXIP_OK, "initStream returns an error code %d", tmp_err_code);
71 
72  // V: Start building the stream step by step: header, document, element etc...
73  tmp_err_code = serialize.exiHeader(&testStrm);
74  fail_unless (tmp_err_code == EXIP_OK, "serialize.exiHeader returns an error code %d", tmp_err_code);
75 
76  tmp_err_code = serialize.startDocument(&testStrm);
77  fail_unless (tmp_err_code == EXIP_OK, "serialize.startDocument returns an error code %d", tmp_err_code);
78 
79  tmp_err_code += asciiToString("http://www.ltu.se/EISLAB/schema-test", &uri, &testStrm.memList, FALSE);
80  tmp_err_code += asciiToString("EXIPEncoder", &ln, &testStrm.memList, FALSE);
81  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType);
82  fail_unless (tmp_err_code == EXIP_OK, "serialize.startElement returns an error code %d", tmp_err_code);
83 
84  tmp_err_code += asciiToString("", &uri, &testStrm.memList, FALSE);
85  tmp_err_code += asciiToString("version", &ln, &testStrm.memList, FALSE);
86  tmp_err_code += serialize.attribute(&testStrm, qname, TRUE, &valueType);
87  fail_unless (tmp_err_code == EXIP_OK, "serialize.attribute returns an error code %d", tmp_err_code);
88 
89  tmp_err_code += asciiToString("0.2", &chVal, &testStrm.memList, FALSE);
90  tmp_err_code += serialize.stringData(&testStrm, chVal);
91  fail_unless (tmp_err_code == EXIP_OK, "serialize.stringData returns an error code %d", tmp_err_code);
92 
93  tmp_err_code += asciiToString("", &uri, &testStrm.memList, FALSE);
94  tmp_err_code += asciiToString("status", &ln, &testStrm.memList, FALSE);
95  tmp_err_code += serialize.attribute(&testStrm, qname, TRUE, &valueType);
96  fail_unless (tmp_err_code == EXIP_OK, "serialize.attribute returns an error code %d", tmp_err_code);
97 
98  tmp_err_code += asciiToString("alpha", &chVal, &testStrm.memList, FALSE);
99  tmp_err_code += serialize.stringData(&testStrm, chVal);
100  fail_unless (tmp_err_code == EXIP_OK, "serialize.stringData returns an error code %d", tmp_err_code);
101 
102  tmp_err_code += asciiToString("This is an example of serializing EXI streams using EXIP low level API", &chVal, &testStrm.memList, FALSE);
103  tmp_err_code += serialize.stringData(&testStrm, chVal);
104 
105  tmp_err_code += serialize.endElement(&testStrm);
106  tmp_err_code += serialize.endDocument(&testStrm);
107 
108  if(tmp_err_code != EXIP_OK)
109  fail_unless (tmp_err_code == EXIP_OK, "serialization ended with error code %d", tmp_err_code);
110 
111  // V: Free the memory allocated by the EXI stream object
112  tmp_err_code = serialize.closeEXIStream(&testStrm);
113  fail_unless (tmp_err_code == EXIP_OK, "serialize.closeEXIStream ended with error code %d", tmp_err_code);
114 
115 
117  // Parsing steps:
118 
119  // I: First, define an external stream for the input to the parser if any
120 
121  // II: Second, initialize the parser object
122  tmp_err_code = initParser(&testParser, buffer, NULL);
123  fail_unless (tmp_err_code == EXIP_OK, "initParser returns an error code %d", tmp_err_code);
124 
125  // III: Initialize the parsing data and hook the callback handlers to the parser object
126 
127  // IV: Parse the header of the stream
128 
129  tmp_err_code = parseHeader(&testParser, TRUE);
130  fail_unless (tmp_err_code == EXIP_OK, "parsing the header returns an error code %d", tmp_err_code);
131 
132  tmp_err_code = setSchema(&testParser, NULL);
133  fail_unless (tmp_err_code == EXIP_OK, "setSchema() returns an error code %d", tmp_err_code);
134 
135  // V: Parse the body of the EXI stream
136 
137  while(tmp_err_code == EXIP_OK)
138  {
139  tmp_err_code = parseNext(&testParser);
140  }
141 
142  // VI: Free the memory allocated by the parser object
143 
144  destroyParser(&testParser);
145  fail_unless (tmp_err_code == EXIP_PARSING_COMPLETE, "Error during parsing of the EXI body %d", tmp_err_code);
146 }
147 END_TEST
148 
149 START_TEST (test_fragment_option)
150 {
151  EXIStream testStrm;
152  Parser testParser;
153  String uri;
154  String ln;
155  QName qname= {&uri, &ln};
156  String chVal;
157  char buf[OUTPUT_BUFFER_SIZE];
158  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
159  BinaryBuffer buffer;
160  EXITypeClass valueType;
161 
162  buffer.buf = buf;
163  buffer.bufContent = 0;
164  buffer.bufLen = OUTPUT_BUFFER_SIZE;
165  buffer.ioStrm.readWriteToStream = NULL;
166  buffer.ioStrm.stream = NULL;
167 
168  // Serialization steps:
169 
170  // I: First initialize the header of the stream
171  serialize.initHeader(&testStrm);
172 
173  // II: Set any options in the header, if different from the defaults
174  testStrm.header.has_cookie = TRUE;
175  testStrm.header.has_options = TRUE;
176  SET_FRAGMENT(testStrm.header.opts.enumOpt);
177 
178  // III: Define an external stream for the output if any
179 
180  // IV: Initialize the stream
181  tmp_err_code = serialize.initStream(&testStrm, buffer, NULL);
182  fail_unless (tmp_err_code == EXIP_OK, "initStream returns an error code %d", tmp_err_code);
183 
184  // V: Start building the stream step by step: header, document, element etc...
185  tmp_err_code = serialize.exiHeader(&testStrm);
186  fail_unless (tmp_err_code == EXIP_OK, "serialize.exiHeader returns an error code %d", tmp_err_code);
187 
188  tmp_err_code = serialize.startDocument(&testStrm);
189  fail_unless (tmp_err_code == EXIP_OK, "serialize.startDocument returns an error code %d", tmp_err_code);
190 
191  tmp_err_code += asciiToString("http://www.ltu.se/EISLAB/schema-test", &uri, &testStrm.memList, FALSE);
192  tmp_err_code += asciiToString("EXIPEncoder", &ln, &testStrm.memList, FALSE);
193  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType);
194  fail_unless (tmp_err_code == EXIP_OK, "serialize.startElement returns an error code %d", tmp_err_code);
195 
196  tmp_err_code += asciiToString("", &uri, &testStrm.memList, FALSE);
197  tmp_err_code += asciiToString("version", &ln, &testStrm.memList, FALSE);
198  tmp_err_code += serialize.attribute(&testStrm, qname, TRUE, &valueType);
199  fail_unless (tmp_err_code == EXIP_OK, "serialize.attribute returns an error code %d", tmp_err_code);
200 
201  tmp_err_code += asciiToString("0.2", &chVal, &testStrm.memList, FALSE);
202  tmp_err_code += serialize.stringData(&testStrm, chVal);
203  fail_unless (tmp_err_code == EXIP_OK, "serialize.stringData returns an error code %d", tmp_err_code);
204 
205  tmp_err_code += asciiToString("", &uri, &testStrm.memList, FALSE);
206  tmp_err_code += asciiToString("status", &ln, &testStrm.memList, FALSE);
207  tmp_err_code += serialize.attribute(&testStrm, qname, TRUE, &valueType);
208  fail_unless (tmp_err_code == EXIP_OK, "serialize.attribute returns an error code %d", tmp_err_code);
209 
210  tmp_err_code += asciiToString("alpha", &chVal, &testStrm.memList, FALSE);
211  tmp_err_code += serialize.stringData(&testStrm, chVal);
212  fail_unless (tmp_err_code == EXIP_OK, "serialize.stringData returns an error code %d", tmp_err_code);
213 
214  tmp_err_code += asciiToString("Test", &ln, &testStrm.memList, FALSE);
215  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType);
216  fail_unless (tmp_err_code == EXIP_OK, "serialize.startElement returns an error code %d", tmp_err_code);
217 
218  tmp_err_code += asciiToString("beta tests", &chVal, &testStrm.memList, FALSE);
219  tmp_err_code += serialize.stringData(&testStrm, chVal);
220  fail_unless (tmp_err_code == EXIP_OK, "serialize.stringData returns an error code %d", tmp_err_code);
221 
222  tmp_err_code += serialize.endElement(&testStrm);
223 
224  tmp_err_code += serialize.endElement(&testStrm);
225 
226  tmp_err_code += asciiToString("Test2", &ln, &testStrm.memList, FALSE);
227  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType);
228  fail_unless (tmp_err_code == EXIP_OK, "serialize.startElement returns an error code %d", tmp_err_code);
229 
230  tmp_err_code += asciiToString("beta tests -> second root element", &chVal, &testStrm.memList, FALSE);
231  tmp_err_code += serialize.stringData(&testStrm, chVal);
232  fail_unless (tmp_err_code == EXIP_OK, "serialize.stringData returns an error code %d", tmp_err_code);
233 
234  tmp_err_code = serialize.endElement(&testStrm);
235  fail_unless (tmp_err_code == EXIP_OK, "serialize.endElement returns an error code %d", tmp_err_code);
236 
237  tmp_err_code = serialize.endDocument(&testStrm);
238  fail_unless (tmp_err_code == EXIP_OK, "serialize.endDocument returns an error code %d", tmp_err_code);
239 
240  if(tmp_err_code != EXIP_OK)
241  fail_unless (tmp_err_code == EXIP_OK, "serialization ended with error code %d", tmp_err_code);
242 
243  // V: Free the memory allocated by the EXI stream object
244  tmp_err_code = serialize.closeEXIStream(&testStrm);
245  fail_unless (tmp_err_code == EXIP_OK, "serialize.closeEXIStream ended with error code %d", tmp_err_code);
246 
248 
249  // Parsing steps:
250 
251  // I: First, define an external stream for the input to the parser if any
252 
253  // II: Second, initialize the parser object
254  tmp_err_code = initParser(&testParser, buffer, NULL);
255  fail_unless (tmp_err_code == EXIP_OK, "initParser returns an error code %d", tmp_err_code);
256 
257  // III: Initialize the parsing data and hook the callback handlers to the parser object
258 
259  // IV: Parse the header of the stream
260 
261  tmp_err_code = parseHeader(&testParser, FALSE);
262  fail_unless (tmp_err_code == EXIP_OK, "parsing the header returns an error code %d", tmp_err_code);
263 
264  tmp_err_code = setSchema(&testParser, NULL);
265  fail_unless (tmp_err_code == EXIP_OK, "setSchema() returns an error code %d", tmp_err_code);
266  // V: Parse the body of the EXI stream
267 
268  while(tmp_err_code == EXIP_OK)
269  {
270  tmp_err_code = parseNext(&testParser);
271  }
272 
273  // VI: Free the memory allocated by the parser object
274 
275  destroyParser(&testParser);
276  fail_unless (tmp_err_code == EXIP_PARSING_COMPLETE, "Error during parsing of the EXI body %d", tmp_err_code);
277 }
278 END_TEST
279 
280 START_TEST (test_value_part_zero)
281 {
282  const String NS_EMPTY_STR = {NULL, 0};
283  const String ELEM_COBS_STR = {"cobs", 4};
284  const String ELEM_TM_STAMP_STR = {"timestamp", 9};
285  const String ELEM_RPM_STR = {"rpm", 3};
286  const String ELEM_ACC_RNDS_STR = {"accRounds", 9};
287  const String ELEM_TEMP_STR = {"temp", 4};
288  const String ELEM_LEFT_STR = {"left", 4};
289  const String ELEM_RIGHT_STR = {"right", 5};
290  const String ELEM_RSSI_STR = {"RSSI", 4};
291  const String ELEM_MIN_STR = {"min", 3};
292  const String ELEM_MAX_STR = {"max", 3};
293  const String ELEM_AVG_STR = {"avg", 3};
294  const String ELEM_BATTERY_STR = {"battery", 7};
295  const String ATTR_NODE_ID_STR = {"nodeId", 6};
296 
297  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
298  EXIStream testStrm;
299  String uri;
300  String ln;
301  QName qname = {&uri, &ln, NULL};
302  String chVal;
303  BinaryBuffer buffer;
304  EXITypeClass valueType;
305  char valStr[50];
306  char buf[OUTPUT_BUFFER_SIZE];
307  Parser testParser;
308 
309  buffer.buf = buf;
310  buffer.bufLen = OUTPUT_BUFFER_SIZE;
311  buffer.bufContent = 0;
312 
313  // Serialization steps:
314 
315  // I: First initialize the header of the stream
316  serialize.initHeader(&testStrm);
317 
318  // II: Set any options in the header, if different from the defaults
319  testStrm.header.has_options = TRUE;
320  testStrm.header.opts.valuePartitionCapacity = 0;
321 
322  // III: Define an external stream for the output if any
323  buffer.ioStrm.readWriteToStream = NULL;
324  buffer.ioStrm.stream = NULL;
325 
326  // IV: Initialize the stream
327  tmp_err_code = serialize.initStream(&testStrm, buffer, NULL);
328  fail_unless (tmp_err_code == EXIP_OK, "initStream returns an error code %d", tmp_err_code);
329 
330  // V: Start building the stream step by step: header, document, element etc...
331  tmp_err_code += serialize.exiHeader(&testStrm);
332  fail_unless (tmp_err_code == EXIP_OK, "exiHeader returns an error code %d", tmp_err_code);
333 
334  tmp_err_code += serialize.startDocument(&testStrm);
335  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
336 
337  qname.uri = &NS_EMPTY_STR;
338  qname.localName = &ELEM_COBS_STR;
339  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType); // <cobs>
340  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
341  qname.localName = &ATTR_NODE_ID_STR;
342  tmp_err_code += serialize.attribute(&testStrm, qname, TRUE, &valueType); // nodeId="..."
343  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
344  sprintf(valStr, "%d", 111);
345  chVal.str = valStr;
346  chVal.length = strlen(valStr);
347  tmp_err_code += serialize.stringData(&testStrm, chVal);
348  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
349  qname.localName = &ELEM_TM_STAMP_STR;
350  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType); // <timestamp>
351  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
352  chVal.str = "2012-12-31T12:09:3.44";
353  chVal.length = strlen("2012-12-31T12:09:3.44");
354  tmp_err_code += serialize.stringData(&testStrm, chVal);
355  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
356  tmp_err_code += serialize.endElement(&testStrm); // </timestamp>
357  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
358  qname.localName = &ELEM_RPM_STR;
359  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType); // <rpm>
360  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
361  sprintf(valStr, "%d", 222);
362  chVal.str = valStr;
363  chVal.length = strlen(valStr);
364  tmp_err_code += serialize.stringData(&testStrm, chVal);
365  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
366  tmp_err_code += serialize.endElement(&testStrm); // </rpm>
367  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
368  qname.localName = &ELEM_ACC_RNDS_STR;
369  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType); // <accRounds>
370  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
371  sprintf(valStr, "%d", 4212);
372  chVal.str = valStr;
373  chVal.length = strlen(valStr);
374  tmp_err_code += serialize.stringData(&testStrm, chVal);
375  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
376  tmp_err_code += serialize.endElement(&testStrm); // </accRounds>
377  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
378  qname.localName = &ELEM_TEMP_STR;
379  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType); // <temp>
380  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
381  qname.localName = &ELEM_LEFT_STR;
382  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType); // <left>
383  sprintf(valStr, "%f", 32.2);
384  chVal.str = valStr;
385  chVal.length = strlen(valStr);
386  tmp_err_code += serialize.stringData(&testStrm, chVal);
387  tmp_err_code += serialize.endElement(&testStrm); // </left>
388  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
389  qname.localName = &ELEM_RIGHT_STR;
390  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType); // <right>
391  sprintf(valStr, "%f", 34.23);
392  chVal.str = valStr;
393  chVal.length = strlen(valStr);
394  tmp_err_code += serialize.stringData(&testStrm, chVal);
395  tmp_err_code += serialize.endElement(&testStrm); // </right>
396  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
397  tmp_err_code += serialize.endElement(&testStrm); // </temp>
398  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
399  qname.localName = &ELEM_RSSI_STR;
400  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType); // <RSSI>
401  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
402  qname.localName = &ELEM_AVG_STR;
403  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType); // <avg>
404  sprintf(valStr, "%d", 123);
405  chVal.str = valStr;
406  chVal.length = strlen(valStr);
407  tmp_err_code += serialize.stringData(&testStrm, chVal);
408  tmp_err_code += serialize.endElement(&testStrm); // </avg>
409  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
410  qname.localName = &ELEM_MAX_STR;
411  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType); // <max>
412  sprintf(valStr, "%d", 2746);
413  chVal.str = valStr;
414  chVal.length = strlen(valStr);
415  tmp_err_code += serialize.stringData(&testStrm, chVal);
416  tmp_err_code += serialize.endElement(&testStrm); // </max>
417  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
418  qname.localName = &ELEM_MIN_STR;
419  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType); // <min>
420  sprintf(valStr, "%d", 112);
421  chVal.str = valStr;
422  chVal.length = strlen(valStr);
423  tmp_err_code += serialize.stringData(&testStrm, chVal);
424  tmp_err_code += serialize.endElement(&testStrm); // </min>
425  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
426  tmp_err_code += serialize.endElement(&testStrm); // </RSSI>
427  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
428  qname.localName = &ELEM_BATTERY_STR;
429  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType); // <battery>
430  sprintf(valStr, "%f", 1.214);
431  chVal.str = valStr;
432  chVal.length = strlen(valStr);
433  tmp_err_code += serialize.stringData(&testStrm, chVal);
434  tmp_err_code += serialize.endElement(&testStrm); // </battery>
435  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
436  tmp_err_code += serialize.endElement(&testStrm); // </cobs>
437  tmp_err_code += serialize.endDocument(&testStrm);
438  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
439  // VI: Free the memory allocated by the EXI stream object
440  tmp_err_code += serialize.closeEXIStream(&testStrm);
441  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
442 
444  // Parsing steps:
445 
446  // I: First, define an external stream for the input to the parser if any
447 
448  // II: Second, initialize the parser object
449  tmp_err_code = initParser(&testParser, buffer, NULL);
450  fail_unless (tmp_err_code == EXIP_OK, "initParser returns an error code %d", tmp_err_code);
451 
452  // III: Initialize the parsing data and hook the callback handlers to the parser object
453 
454  // IV: Parse the header of the stream
455 
456  tmp_err_code = parseHeader(&testParser, TRUE);
457  fail_unless (tmp_err_code == EXIP_OK, "parsing the header returns an error code %d", tmp_err_code);
458 
459  tmp_err_code = setSchema(&testParser, NULL);
460  fail_unless (tmp_err_code == EXIP_OK, "setSchema() returns an error code %d", tmp_err_code);
461  // V: Parse the body of the EXI stream
462 
463  while(tmp_err_code == EXIP_OK)
464  {
465  tmp_err_code = parseNext(&testParser);
466  }
467 
468  // VI: Free the memory allocated by the parser object
469 
470  destroyParser(&testParser);
471  fail_unless (tmp_err_code == EXIP_PARSING_COMPLETE, "Error during parsing of the EXI body %d", tmp_err_code);
472 }
473 END_TEST
474 
475 START_TEST (test_recursive_defs)
476 {
477  const String NS_EMPTY_STR = {NULL, 0};
478  const String ELEM_OBJ_STR = {"obj", 3};
479  const String ELEM_STR_STR = {"str", 3};
480  const String ELEM_LIST_STR = {"list", 4};
481 
482  const String ATTR_XSTR_STR = {"xsss", 4};
483  const String ATTR_XTEMP_STR = {"x-template", 10};
484  const String ATTR_NAME_STR = {"name", 4};
485  const String ATTR_VAL_STR = {"val", 3};
486 
487  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
488  EXIStream testStrm;
489  String uri;
490  String ln;
491  QName qname = {&uri, &ln, NULL};
492  String chVal;
493  BinaryBuffer buffer;
494  EXITypeClass valueType;
495  char valStr[50];
496  char buf[OUTPUT_BUFFER_SIZE];
497  Parser testParser;
498 
499  buffer.buf = buf;
500  buffer.bufLen = OUTPUT_BUFFER_SIZE;
501  buffer.bufContent = 0;
502 
503  // Serialization steps:
504 
505  // I: First initialize the header of the stream
506  serialize.initHeader(&testStrm);
507 
508  // II: Set any options in the header, if different from the defaults
509  testStrm.header.has_options = TRUE;
510  SET_STRICT(testStrm.header.opts.enumOpt);
512 
513  // III: Define an external stream for the output if any
514  buffer.ioStrm.readWriteToStream = NULL;
515  buffer.ioStrm.stream = NULL;
516 
517  // IV: Initialize the stream
518  tmp_err_code = serialize.initStream(&testStrm, buffer, NULL);
519  fail_unless (tmp_err_code == EXIP_OK, "initStream returns an error code %d", tmp_err_code);
520 
521  // V: Start building the stream step by step: header, document, element etc...
522  tmp_err_code += serialize.exiHeader(&testStrm);
523  fail_unless (tmp_err_code == EXIP_OK, "exiHeader returns an error code %d", tmp_err_code);
524 
525  tmp_err_code += serialize.startDocument(&testStrm);
526  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
527 
528  qname.uri = &NS_EMPTY_STR;
529  qname.localName = &ELEM_OBJ_STR;
530  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType); // <obj>
531  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
532  qname.localName = &ATTR_XSTR_STR;
533  tmp_err_code += serialize.attribute(&testStrm, qname, TRUE, &valueType); // xsss="..."
534  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
535  sprintf(valStr, "%s", "http://obix.org/ns/schema/1.1");
536  chVal.str = valStr;
537  chVal.length = strlen(valStr);
538  tmp_err_code += serialize.stringData(&testStrm, chVal);
539  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
540  qname.localName = &ATTR_XTEMP_STR;
541  tmp_err_code += serialize.attribute(&testStrm, qname, TRUE, &valueType); // x-template="..."
542  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
543  sprintf(valStr, "%s", "ipu_inst.xml");
544  chVal.str = valStr;
545  chVal.length = strlen(valStr);
546  tmp_err_code += serialize.stringData(&testStrm, chVal);
547  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
548  qname.localName = &ELEM_STR_STR;
549  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType); // <str>
550  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
551  qname.localName = &ATTR_NAME_STR;
552  tmp_err_code += serialize.attribute(&testStrm, qname, TRUE, &valueType); // name="..."
553  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
554  sprintf(valStr, "%s", "interworkingProxyID");
555  chVal.str = valStr;
556  chVal.length = strlen(valStr);
557  tmp_err_code += serialize.stringData(&testStrm, chVal);
558  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
559  qname.localName = &ATTR_VAL_STR;
560  tmp_err_code += serialize.attribute(&testStrm, qname, TRUE, &valueType); // val="..."
561  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
562  sprintf(valStr, "%s", "IPU_6LoWPAN");
563  chVal.str = valStr;
564  chVal.length = strlen(valStr);
565  tmp_err_code += serialize.stringData(&testStrm, chVal);
566  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
567  tmp_err_code += serialize.endElement(&testStrm); // </str>
568  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
569  qname.localName = &ELEM_LIST_STR;
570  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType); // <list>
571  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
572  qname.localName = &ATTR_NAME_STR;
573  tmp_err_code += serialize.attribute(&testStrm, qname, TRUE, &valueType); // name="..."
574  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
575  sprintf(valStr, "%s", "supportedTechnologies");
576  chVal.str = valStr;
577  chVal.length = strlen(valStr);
578  tmp_err_code += serialize.stringData(&testStrm, chVal);
579  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
580  qname.localName = &ELEM_OBJ_STR;
581  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType); // <obj>
582  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
583 
584  qname.localName = &ELEM_STR_STR;
585  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType); // <str>
586  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
587  qname.localName = &ATTR_NAME_STR;
588  tmp_err_code += serialize.attribute(&testStrm, qname, TRUE, &valueType); // name="..."
589  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
590  sprintf(valStr, "%s", "anPhysical");
591  chVal.str = valStr;
592  chVal.length = strlen(valStr);
593  tmp_err_code += serialize.stringData(&testStrm, chVal);
594  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
595  qname.localName = &ATTR_VAL_STR;
596  tmp_err_code += serialize.attribute(&testStrm, qname, TRUE, &valueType); // val="..."
597  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
598  sprintf(valStr, "%s", "2003_2_4GHz");
599  chVal.str = valStr;
600  chVal.length = strlen(valStr);
601  tmp_err_code += serialize.stringData(&testStrm, chVal);
602  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
603  tmp_err_code += serialize.endElement(&testStrm); // </str>
604  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
605 
606  qname.localName = &ELEM_STR_STR;
607  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType); // <str>
608  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
609  qname.localName = &ATTR_NAME_STR;
610  tmp_err_code += serialize.attribute(&testStrm, qname, TRUE, &valueType); // name="..."
611  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
612  sprintf(valStr, "%s", "anStandard");
613  chVal.str = valStr;
614  chVal.length = strlen(valStr);
615  tmp_err_code += serialize.stringData(&testStrm, chVal);
616  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
617  qname.localName = &ATTR_VAL_STR;
618  tmp_err_code += serialize.attribute(&testStrm, qname, TRUE, &valueType); // val="..."
619  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
620  sprintf(valStr, "%s", "Bee_1_0");
621  chVal.str = valStr;
622  chVal.length = strlen(valStr);
623  tmp_err_code += serialize.stringData(&testStrm, chVal);
624  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
625  tmp_err_code += serialize.endElement(&testStrm); // </str>
626  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
627 
628 
629  qname.localName = &ELEM_STR_STR;
630  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType); // <str>
631  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
632  qname.localName = &ATTR_NAME_STR;
633  tmp_err_code += serialize.attribute(&testStrm, qname, TRUE, &valueType); // name="..."
634  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
635  sprintf(valStr, "%s", "anProfile");
636  chVal.str = valStr;
637  chVal.length = strlen(valStr);
638  tmp_err_code += serialize.stringData(&testStrm, chVal);
639  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
640  qname.localName = &ATTR_VAL_STR;
641  tmp_err_code += serialize.attribute(&testStrm, qname, TRUE, &valueType); // val="..."
642  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
643  sprintf(valStr, "%s", "Bee_HA");
644  chVal.str = valStr;
645  chVal.length = strlen(valStr);
646  tmp_err_code += serialize.stringData(&testStrm, chVal);
647  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
648  tmp_err_code += serialize.endElement(&testStrm); // </str>
649  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
650 
651  tmp_err_code += serialize.endElement(&testStrm); // </obj>
652  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
653 
654  tmp_err_code += serialize.endElement(&testStrm); // </list>
655  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
656 
657  tmp_err_code += serialize.endElement(&testStrm); // </obj>
658  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
659 
660  tmp_err_code += serialize.endDocument(&testStrm);
661  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
662  // VI: Free the memory allocated by the EXI stream object
663  tmp_err_code += serialize.closeEXIStream(&testStrm);
664  fail_unless (tmp_err_code == EXIP_OK, "serialize.* returns an error code %d", tmp_err_code);
665 
667  // Parsing steps:
668 
669  // I: First, define an external stream for the input to the parser if any
670 
671  // II: Second, initialize the parser object
672  tmp_err_code = initParser(&testParser, buffer, NULL);
673  fail_unless (tmp_err_code == EXIP_OK, "initParser returns an error code %d", tmp_err_code);
674 
675  // III: Initialize the parsing data and hook the callback handlers to the parser object
676 
677  // IV: Parse the header of the stream
678 
679  tmp_err_code = parseHeader(&testParser, FALSE);
680  fail_unless (tmp_err_code == EXIP_OK, "parsing the header returns an error code %d", tmp_err_code);
681 
682  tmp_err_code = setSchema(&testParser, NULL);
683  fail_unless (tmp_err_code == EXIP_OK, "setSchema() returns an error code %d", tmp_err_code);
684 
685  // V: Parse the body of the EXI stream
686 
687  while(tmp_err_code == EXIP_OK)
688  {
689  tmp_err_code = parseNext(&testParser);
690  }
691 
692  // VI: Free the memory allocated by the parser object
693 
694  destroyParser(&testParser);
695  fail_unless (tmp_err_code == EXIP_PARSING_COMPLETE, "Error during parsing of the EXI body %d", tmp_err_code);
696 }
697 END_TEST
698 
699 errorCode encodeWithDynamicTypes(char* buf, int buf_size, int *strmSize);
700 
712 START_TEST (test_built_in_dynamic_types)
713 {
714  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
715  char buf[OUTPUT_BUFFER_SIZE];
716  int strmSize = 0;
717  BinaryBuffer buffer;
718  Parser testParser;
719 
720  tmp_err_code = encodeWithDynamicTypes(buf, OUTPUT_BUFFER_SIZE, &strmSize);
721  fail_unless(tmp_err_code == EXIP_OK, "There is an error in the encoding of dynamic types through xsi:type switch.");
722  fail_unless(strmSize > 0, "Encoding of dynamic types through xsi:type switch produces empty streams.");
723 
724  buffer.bufContent = strmSize;
725  buffer.buf = buf;
726  buffer.bufLen = OUTPUT_BUFFER_SIZE;
727 
728  // Parsing steps:
729 
730  // I: First, define an external stream for the input to the parser if any
731 
732  // II: Second, initialize the parser object
733  tmp_err_code = initParser(&testParser, buffer, NULL);
734  fail_unless (tmp_err_code == EXIP_OK, "initParser returns an error code %d", tmp_err_code);
735 
736  // III: Initialize the parsing data and hook the callback handlers to the parser object
737 
738  // IV: Parse the header of the stream
739 
740  tmp_err_code = parseHeader(&testParser, FALSE);
741  fail_unless (tmp_err_code == EXIP_OK, "parsing the header returns an error code %d", tmp_err_code);
742 
743  tmp_err_code = setSchema(&testParser, NULL);
744  fail_unless (tmp_err_code == EXIP_OK, "setSchema() returns an error code %d", tmp_err_code);
745 
746  // V: Parse the body of the EXI stream
747 
748  while(tmp_err_code == EXIP_OK)
749  {
750  tmp_err_code = parseNext(&testParser);
751  }
752 
753  // VI: Free the memory allocated by the parser object
754 
755  destroyParser(&testParser);
756  fail_unless (tmp_err_code == EXIP_PARSING_COMPLETE, "Error during parsing of the EXI body %d", tmp_err_code);
757 }
758 END_TEST
759 
760 errorCode encodeWithDynamicTypes(char* buf, int buf_size, int *strmSize)
761 {
762  const String NS_EMPTY = {NULL, 0};
763  const String NS_XSI = {"http://www.w3.org/2001/XMLSchema-instance", 41};
764  const String NS_XSD = {"http://www.w3.org/2001/XMLSchema", 32};
765 
766  const String ELEM_TRIVIAL = {"trivial", 7};
767  const String ELEM_AN_ELEMENT = {"anElement", 9};
768 
769  const String PREFIX_XSI = {"xsi", 3};
770 
771  const String ATTR_TYPE = {"type", 4};
772 
773  const String VALUE_DATE = {"dateTime", 8};
774 
775  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
776  EXIStream testStrm;
777  String uri;
778  String ln;
779  QName qname = {&uri, &ln, NULL};
780 
781  BinaryBuffer buffer;
782  EXITypeClass valueType;
783  EXIPDateTime dt_val;
784 
785  buffer.buf = buf;
786  buffer.bufLen = OUTPUT_BUFFER_SIZE;
787  buffer.bufContent = 0;
788 
789  // Serialization steps:
790 
791  // I: First initialize the header of the stream
792  serialize.initHeader(&testStrm);
793 
794  // II: Set any options in the header (including schemaID and schemaIDMode), if different from the defaults.
795  testStrm.header.has_options = TRUE;
798 
799  // III: Define an external stream for the output if any, otherwise set to NULL
800  buffer.ioStrm.readWriteToStream = NULL;
801  buffer.ioStrm.stream = NULL;
802 
803  // IV: Initialize the stream
804  TRY_CATCH_ENCODE(serialize.initStream(&testStrm, buffer, NULL));
805 
806  // V: Start building the stream step by step: header, document, element etc...
808 
810 
811  qname.uri = &NS_EMPTY;
812  qname.localName = &ELEM_TRIVIAL;
813  TRY_CATCH_ENCODE(serialize.startElement(&testStrm, qname, &valueType)); // <trivial>
814 
815  TRY_CATCH_ENCODE(serialize.namespaceDeclaration(&testStrm, NS_XSI, PREFIX_XSI, FALSE)); // xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
816 
817  qname.uri = &NS_EMPTY;
818  qname.localName = &ELEM_AN_ELEMENT;
819  TRY_CATCH_ENCODE(serialize.startElement(&testStrm, qname, &valueType)); // <anElement>
820 
821  qname.uri = &NS_XSI;
822  qname.localName = &ATTR_TYPE;
823  TRY_CATCH_ENCODE(serialize.attribute(&testStrm, qname, TRUE, &valueType)); // xsi:type="
824 
825  qname.uri = &NS_XSD;
826  qname.localName = &VALUE_DATE;
827  TRY_CATCH_ENCODE(serialize.qnameData(&testStrm, qname)); // xsd:date
828 
829  dt_val.dateTime.tm_year = 114; // + 1900 offset = 2014
830  dt_val.dateTime.tm_mon = 0; // 0 = Jan
831  dt_val.dateTime.tm_mday = 31;
832  dt_val.dateTime.tm_hour = 16;
833  dt_val.dateTime.tm_min = 15;
834  dt_val.dateTime.tm_sec = 25;
835  dt_val.presenceMask = 0;
836  dt_val.presenceMask |= TZONE_PRESENCE;
837  dt_val.TimeZone = 2*64; // UTC + 2
838  TRY_CATCH_ENCODE(serialize.dateTimeData(&testStrm, dt_val)); // dateTime: 2014-01-31T16:15:25+02:00
839 
840  TRY_CATCH_ENCODE(serialize.endElement(&testStrm)); // </anElement>
841  TRY_CATCH_ENCODE(serialize.endElement(&testStrm)); // </trivial>
842 
844 
845  *strmSize = testStrm.context.bufferIndx + 1;
846 
847  // VI: Free the memory allocated by the EXI stream object
849 
850  return EXIP_OK;
851 }
852 
853 /* END: SchemaLess tests */
854 
855 #define OUTPUT_BUFFER_SIZE_LARGE_DOC 20000
856 #define MAX_XSD_FILES_COUNT 10 // up to 10 XSD files
857 
858 /* BEGIN: Schema-mode tests */
859 START_TEST (test_large_doc_str_pattern)
860 {
861  const String NS_EMPTY_STR = {NULL, 0};
862 
863  const String ELEM_CONFIGURATION = {"configuration", 13};
864  const String ELEM_CAPSWITCH = {"capable-switch", 14};
865  const String ELEM_RESOURCES = {"resources", 9};
866  const String ELEM_PORT = {"port", 4};
867  const String ELEM_RESID = {"resource-id", 11};
868  const String ELEM_ADMIN_STATE = {"admin-state", 11};
869  const String ELEM_NORECEIVE = {"no-receive", 10};
870  const String ELEM_NOFORWARD = {"no-forward", 10};
871  const String ELEM_NOPACKET = {"no-packet-in", 12};
872 
873  const String ELEM_LOGSWITCHES = {"logical-switches", 16};
874  const String ELEM_SWITCH = {"switch", 6};
875  const String ELEM_ID = {"id", 2};
876  const String ELEM_DATAPATHID = {"datapath-id", 11};
877  const String ELEM_ENABLED = {"enabled", 7};
878  const String ELEM_LOSTCONNBEH = {"lost-connection-behavior", 24};
879  const String ELEM_CONTROLLERS = {"controllers", 11};
880  const String ELEM_CONTROLLER = {"controller", 10};
881  const String ELEM_ROLE = {"role", 4};
882  const String ELEM_IPADDR = {"ip-address", 10};
883  const String ELEM_PROTOCOL = {"protocol", 8};
884  const String ELEM_STATE = {"state", 5};
885  const String ELEM_CONNSTATE = {"connection-state", 16};
886  const String ELEM_CURRVER = {"current-version", 15};
887 
888  const char * PORT_STR = "port";
889  const char * SWITCH_STR = "switch";
890  const char * STATE_UP_STR = "up";
891  const char * DATAPATH_STR = "10:14:56:7C:89:46:7A:";
892  const char * LOST_CONN_BEHAVIOR_STR = "failSecureMode";
893  const char * CTRL_STR = "ctrl";
894  const char * ROLE_STR = "equal";
895  const char * IPADDR_STR = "10.10.10.";
896  const char * PROTOCOL_STR = "tcp";
897  const char * VER_STR = "1.0";
898 
899  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
900  FILE *outfile;
901  char* sourceFile = "testOutputFile.exi";
902  EXIPSchema schema;
903 // struct timespec start;
904 // struct timespec end;
905  char* schemafname[1] = {"exip/schema_demo.exi"};
906  EXIStream testStrm;
907  String uri;
908  String ln;
909  QName qname = {&uri, &ln, NULL};
910  String chVal;
912  BinaryBuffer buffer;
913  int i, j;
914  char strbuffer[32];
915 
916  buffer.buf = buf;
918  buffer.bufContent = 0;
919 
920  parseSchema(schemafname, 1, &schema);
921 
922  outfile = fopen(sourceFile, "wb" );
923  fail_if(!outfile, "Unable to open file %s", sourceFile);
924 
925  // Serialization steps:
926 
927  // I: First initialize the header of the stream
928  serialize.initHeader(&testStrm);
929 
930  // II: Set any options in the header, if different from the defaults
931  testStrm.header.has_cookie = TRUE;
932  testStrm.header.has_options = TRUE;
933  testStrm.header.opts.valueMaxLength = 300;
935  SET_STRICT(testStrm.header.opts.enumOpt);
936 
937  // III: Define an external stream for the output if any
939  buffer.ioStrm.stream = outfile;
940  //buffer.ioStrm.readWriteToStream = NULL;
941  //buffer.ioStrm.stream = NULL;
942 // printf("line:%d: %d\n", __LINE__, tmp_err_code);
943  //clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);
944  // IV: Initialize the stream
945  tmp_err_code = serialize.initStream(&testStrm, buffer, &schema);
946  fail_unless(tmp_err_code == EXIP_OK);
947 
948 //printf("line:%d: %d\n", __LINE__, tmp_err_code);
949 // clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);
950 
951  // V: Start building the stream step by step: header, document, element etc...
952  tmp_err_code += serialize.exiHeader(&testStrm);
953 // printf("line:%d: %d\n", __LINE__, tmp_err_code);
954  tmp_err_code += serialize.startDocument(&testStrm);
955 // printf("line:%d: %d\n", __LINE__, tmp_err_code);
956  qname.uri = &NS_EMPTY_STR;
957  qname.localName = &ELEM_CONFIGURATION;
958  EXITypeClass typeClass;
959  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
960 
961  qname.uri = &NS_EMPTY_STR;
962  qname.localName = &ELEM_CAPSWITCH;
963  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
964 
965  qname.uri = &NS_EMPTY_STR;
966  qname.localName = &ELEM_RESOURCES;
967  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
968 
969 // printf("line:%d: %d\n", __LINE__, tmp_err_code);
970  for (i = 0; i < 100; i++)
971  {
972  qname.uri = &NS_EMPTY_STR;
973  qname.localName = &ELEM_PORT;
974  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
975 
976  qname.uri = &NS_EMPTY_STR;
977  qname.localName = &ELEM_RESID;
978  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
979 
980  sprintf(strbuffer, "%s%d", PORT_STR, i);
981  tmp_err_code += asciiToString(strbuffer, &chVal, &testStrm.memList, FALSE);
982  tmp_err_code += serialize.stringData(&testStrm, chVal);
983  tmp_err_code += serialize.endElement(&testStrm);
984 
985  qname.uri = &NS_EMPTY_STR;
986  qname.localName = &ELEM_CONFIGURATION;
987  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
988 
989  qname.uri = &NS_EMPTY_STR;
990  qname.localName = &ELEM_ADMIN_STATE;
991  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
992  tmp_err_code += asciiToString(STATE_UP_STR, &chVal, &testStrm.memList, FALSE);
993  tmp_err_code += serialize.stringData(&testStrm, chVal);
994  tmp_err_code += serialize.endElement(&testStrm);
995 
996  qname.uri = &NS_EMPTY_STR;
997  qname.localName = &ELEM_NORECEIVE;
998  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
999  tmp_err_code += serialize.booleanData(&testStrm, FALSE);
1000  tmp_err_code += serialize.endElement(&testStrm);
1001 
1002  qname.uri = &NS_EMPTY_STR;
1003  qname.localName = &ELEM_NOFORWARD;
1004  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
1005  tmp_err_code += serialize.booleanData(&testStrm, FALSE);
1006  tmp_err_code += serialize.endElement(&testStrm);
1007 
1008  qname.uri = &NS_EMPTY_STR;
1009  qname.localName = &ELEM_NOPACKET;
1010  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
1011  tmp_err_code += serialize.booleanData(&testStrm, TRUE);
1012  tmp_err_code += serialize.endElement(&testStrm);
1013 
1014  tmp_err_code += serialize.endElement(&testStrm);
1015 
1016  tmp_err_code += serialize.endElement(&testStrm);
1017  }
1018  tmp_err_code += serialize.endElement(&testStrm);
1019 
1020  qname.uri = &NS_EMPTY_STR;
1021  qname.localName = &ELEM_LOGSWITCHES;
1022  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
1023 
1024  for (i = 0; i < 20; i++)
1025  {
1026  qname.uri = &NS_EMPTY_STR;
1027  qname.localName = &ELEM_SWITCH;
1028  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
1029 
1030  qname.uri = &NS_EMPTY_STR;
1031  qname.localName = &ELEM_ID;
1032  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
1033 
1034  sprintf(strbuffer, "%s%d", SWITCH_STR, i);
1035  tmp_err_code += asciiToString(strbuffer, &chVal, &testStrm.memList, FALSE);
1036  tmp_err_code += serialize.stringData(&testStrm, chVal);
1037  tmp_err_code += serialize.endElement(&testStrm);
1038 
1039  qname.uri = &NS_EMPTY_STR;
1040  qname.localName = &ELEM_DATAPATHID;
1041  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
1042 
1043  sprintf(strbuffer, "%s%d", DATAPATH_STR, 10 + i);
1044  tmp_err_code += asciiToString(strbuffer, &chVal, &testStrm.memList, FALSE);
1045  tmp_err_code += serialize.stringData(&testStrm, chVal);
1046  tmp_err_code += serialize.endElement(&testStrm);
1047 
1048  qname.uri = &NS_EMPTY_STR;
1049  qname.localName = &ELEM_ENABLED;
1050  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
1051  tmp_err_code += serialize.booleanData(&testStrm, TRUE);
1052  tmp_err_code += serialize.endElement(&testStrm);
1053 
1054  qname.uri = &NS_EMPTY_STR;
1055  qname.localName = &ELEM_LOSTCONNBEH;
1056  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
1057  tmp_err_code += asciiToString(LOST_CONN_BEHAVIOR_STR, &chVal, &testStrm.memList, FALSE);
1058  tmp_err_code += serialize.stringData(&testStrm, chVal);
1059  tmp_err_code += serialize.endElement(&testStrm);
1060 // printf("in loop(%d) line:%d: %d\n", i, __LINE__, tmp_err_code);
1061 // if ( i == 0 )
1062 // {
1063  qname.uri = &NS_EMPTY_STR;
1064  qname.localName = &ELEM_RESOURCES;
1065  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
1066 
1067  for (j = 0; j < 100; j++)
1068  {
1069  qname.uri = &NS_EMPTY_STR;
1070  qname.localName = &ELEM_PORT;
1071  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
1072 
1073  sprintf(strbuffer, "%s%d", PORT_STR, j);
1074  tmp_err_code += asciiToString(strbuffer, &chVal, &testStrm.memList, FALSE);
1075  tmp_err_code += serialize.stringData(&testStrm, chVal);
1076  tmp_err_code += serialize.endElement(&testStrm);
1077  }
1078  tmp_err_code += serialize.endElement(&testStrm);
1079 // }
1080 // printf("in loop(%d) line:%d: %d\n", i, __LINE__, tmp_err_code);
1081  qname.uri = &NS_EMPTY_STR;
1082  qname.localName = &ELEM_CONTROLLERS;
1083  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
1084 // printf("in loop(%d) line:%d: %d\n", i, __LINE__, tmp_err_code);
1085  qname.uri = &NS_EMPTY_STR;
1086  qname.localName = &ELEM_CONTROLLER;
1087  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
1088 // printf("in loop(%d) line:%d: %d\n", i, __LINE__, tmp_err_code);
1089  qname.uri = &NS_EMPTY_STR;
1090  qname.localName = &ELEM_ID;
1091  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
1092 // printf("in loop(%d) line:%d: %d\n", i, __LINE__, tmp_err_code);
1093  sprintf(strbuffer, "%s%d", CTRL_STR, i);
1094  tmp_err_code += asciiToString(strbuffer, &chVal, &testStrm.memList, FALSE);
1095  tmp_err_code += serialize.stringData(&testStrm, chVal);
1096  tmp_err_code += serialize.endElement(&testStrm);
1097 // printf("in loop(%d) line:%d: %d\n", i, __LINE__, tmp_err_code);
1098  qname.uri = &NS_EMPTY_STR;
1099  qname.localName = &ELEM_ROLE;
1100  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
1101  tmp_err_code += asciiToString(ROLE_STR, &chVal, &testStrm.memList, FALSE);
1102  tmp_err_code += serialize.stringData(&testStrm, chVal);
1103  tmp_err_code += serialize.endElement(&testStrm);
1104 
1105  qname.uri = &NS_EMPTY_STR;
1106  qname.localName = &ELEM_IPADDR;
1107  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
1108  sprintf(strbuffer, "%s%d", IPADDR_STR, i);
1109  tmp_err_code += asciiToString(strbuffer, &chVal, &testStrm.memList, FALSE);
1110  tmp_err_code += serialize.stringData(&testStrm, chVal);
1111  tmp_err_code += serialize.endElement(&testStrm);
1112 
1113  qname.uri = &NS_EMPTY_STR;
1114  qname.localName = &ELEM_PORT;
1115  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
1116  tmp_err_code += serialize.intData(&testStrm, 6620);
1117  tmp_err_code += serialize.endElement(&testStrm);
1118 
1119  qname.uri = &NS_EMPTY_STR;
1120  qname.localName = &ELEM_PROTOCOL;
1121  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
1122  tmp_err_code += asciiToString(PROTOCOL_STR, &chVal, &testStrm.memList, FALSE);
1123  tmp_err_code += serialize.stringData(&testStrm, chVal);
1124  tmp_err_code += serialize.endElement(&testStrm);
1125 
1126  qname.uri = &NS_EMPTY_STR;
1127  qname.localName = &ELEM_STATE;
1128  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
1129 
1130  qname.uri = &NS_EMPTY_STR;
1131  qname.localName = &ELEM_CONNSTATE;
1132  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
1133  tmp_err_code += asciiToString(STATE_UP_STR, &chVal, &testStrm.memList, FALSE);
1134  tmp_err_code += serialize.stringData(&testStrm, chVal);
1135  tmp_err_code += serialize.endElement(&testStrm);
1136 
1137 // printf("in loop(%d) line:%d: %d\n", i, __LINE__, tmp_err_code);
1138  qname.uri = &NS_EMPTY_STR;
1139  qname.localName = &ELEM_CURRVER;
1140  tmp_err_code += serialize.startElement(&testStrm, qname, &typeClass);
1141 // printf("in loop(%d) line:%d: %d\n", i, __LINE__, tmp_err_code);
1142  tmp_err_code += asciiToString(VER_STR, &chVal, &testStrm.memList, FALSE);
1143 
1144  tmp_err_code += serialize.stringData(&testStrm, chVal);
1145  tmp_err_code += serialize.endElement(&testStrm);
1146 
1147  tmp_err_code += serialize.endElement(&testStrm);
1148 
1149  tmp_err_code += serialize.endElement(&testStrm);
1150 
1151  tmp_err_code += serialize.endElement(&testStrm);
1152 
1153  tmp_err_code += serialize.endElement(&testStrm);
1154  }
1155 
1156  tmp_err_code += serialize.endElement(&testStrm);
1157 
1158  tmp_err_code += serialize.endElement(&testStrm);
1159 
1160  tmp_err_code += serialize.endElement(&testStrm);
1161  tmp_err_code += serialize.endDocument(&testStrm);
1162  fail_unless(tmp_err_code == EXIP_OK);
1163 
1164 // clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);
1165 
1166  // VI: Free the memory allocated by the EXI stream object
1167  tmp_err_code = serialize.closeEXIStream(&testStrm);
1168 
1169 // clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);
1170 // total += ((end.tv_sec * SEC2NANO) + end.tv_nsec) - ((start.tv_sec * SEC2NANO) + start.tv_nsec);
1171 
1172  fclose(outfile);
1173 
1174  /* DECODE */
1175  {
1176  Parser testParser;
1177  FILE *infile;
1178 
1179  buffer.buf = buf;
1180  buffer.bufContent = 0;
1182  unsigned int eventCount;
1183 
1184  // Parsing steps:
1185 
1186  // I.A: First, read in the schema
1187  parseSchema(schemafname, 1, &schema);
1188 
1189  // I.B: Define an external stream for the input to the parser if any
1190  infile = fopen(sourceFile, "rb" );
1191  if(!infile)
1192  fail("Unable to open file %s", sourceFile);
1193 
1195  buffer.ioStrm.stream = infile;
1196 
1197  // II: Second, initialize the parser object
1198  tmp_err_code = initParser(&testParser, buffer, &eventCount);
1199  fail_unless (tmp_err_code == EXIP_OK, "initParser returns an error code %d", tmp_err_code);
1200 
1201  // IV: Parse the header of the stream
1202  tmp_err_code = parseHeader(&testParser, FALSE);
1203  fail_unless (tmp_err_code == EXIP_OK, "parsing the header returns an error code %d", tmp_err_code);
1204 
1205  tmp_err_code = setSchema(&testParser, &schema);
1206  fail_unless (tmp_err_code == EXIP_OK, "setSchema() returns an error code %d", tmp_err_code);
1207 
1208  // V: Parse the body of the EXI stream
1209  while(tmp_err_code == EXIP_OK)
1210  {
1211  tmp_err_code = parseNext(&testParser);
1212  }
1213 
1214  // VI: Free the memory allocated by the parser object
1215  destroyParser(&testParser);
1216  fclose(infile);
1217  fail_unless (tmp_err_code == EXIP_PARSING_COMPLETE, "Error during parsing of the EXI body %d", tmp_err_code);
1218  }
1219 
1220  remove(sourceFile);
1221  destroySchema(&schema);
1222 }
1223 END_TEST
1224 
1225 #define INPUT_BUFFER_SIZE 200
1226 
1227 /* Test substitution groups */
1228 START_TEST (test_substitution_groups)
1229 {
1230  EXIPSchema schema;
1231  FILE *infile;
1232  Parser testParser;
1233  char buf[INPUT_BUFFER_SIZE];
1234  char* schemafname[2] = {"exip/subsGroups/root-xsd.exi","exip/subsGroups/sub-xsd.exi"};
1235  char *exifname = "exip/subsGroups/root.exi";
1236  char exipath[MAX_PATH_LEN + strlen(exifname)];
1237  unsigned int eventCount;
1238  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
1239  BinaryBuffer buffer;
1240 
1241  buffer.buf = buf;
1242  buffer.bufContent = 0;
1243  buffer.bufLen = INPUT_BUFFER_SIZE;
1244 
1245  // Parsing steps:
1246 
1247  // I.A: First, read in the schema
1248  parseSchema(schemafname, 2, &schema);
1249 
1250  // I.B: Define an external stream for the input to the parser if any
1251  size_t pathlen = strlen(dataDir);
1252  memcpy(exipath, dataDir, pathlen);
1253  exipath[pathlen] = '/';
1254  memcpy(&exipath[pathlen+1], exifname, strlen(exifname)+1);
1255 
1256  infile = fopen(exipath, "rb" );
1257  if(!infile)
1258  fail("Unable to open file %s", exipath);
1259 
1261  buffer.ioStrm.stream = infile;
1262 
1263  // II: Second, initialize the parser object
1264  tmp_err_code = initParser(&testParser, buffer, &eventCount);
1265  fail_unless (tmp_err_code == EXIP_OK, "initParser returns an error code %d", tmp_err_code);
1266 
1267  // III: Initialize the parsing data and hook the callback handlers to the parser object
1268  eventCount = 0;
1269 
1270  // IV: Parse the header of the stream
1271  tmp_err_code = parseHeader(&testParser, FALSE);
1272  fail_unless (tmp_err_code == EXIP_OK, "parsing the header returns an error code %d", tmp_err_code);
1273 
1274  tmp_err_code = setSchema(&testParser, &schema);
1275  fail_unless (tmp_err_code == EXIP_OK, "setSchema() returns an error code %d", tmp_err_code);
1276  // V: Parse the body of the EXI stream
1277  while(tmp_err_code == EXIP_OK)
1278  {
1279  tmp_err_code = parseNext(&testParser);
1280  eventCount++;
1281  }
1282 
1283  fail_unless(eventCount == 38,
1284  "Unexpected event count: %u", eventCount);
1285 
1286  // VI: Free the memory allocated by the parser object
1287  destroyParser(&testParser);
1288  fclose(infile);
1289  fail_unless (tmp_err_code == EXIP_PARSING_COMPLETE, "Error during parsing of the EXI body %d", tmp_err_code);
1290 }
1291 END_TEST
1292 
1293 errorCode encodeNonBlockingStreaming(EXIPSchema* schema, char* flushBuf, int buf_size, int *strmSize, unsigned char alignment);
1294 
1295 START_TEST (test_non_blocking_streaming)
1296 {
1297  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
1298  char flushBuf[OUTPUT_BUFFER_SIZE];
1299  int strmSize = 0;
1300  BinaryBuffer buffer;
1301  Parser testParser;
1302  char* schemafname[1] = {"exip/NonBlockingStreaming-xsd.exi"};
1303  EXIPSchema schema;
1304  char tmpBuf[40];
1305  unsigned int flushMarker;
1306  unsigned int bytesRead;
1307 
1308  parseSchema(schemafname, 1, &schema);
1309 
1310  tmp_err_code = encodeNonBlockingStreaming(&schema, flushBuf, OUTPUT_BUFFER_SIZE, &strmSize, BIT_PACKED);
1311  fail_unless(tmp_err_code == EXIP_OK, "There is an error in the encoding of non blocking EXI stream");
1312  fail_unless(strmSize > 0, "Encoding using non blocking flushing produces empty streams.");
1313 
1314  flushMarker = 20;
1315  memcpy(tmpBuf, flushBuf, flushMarker);
1316 
1317  buffer.bufContent = flushMarker;
1318  buffer.buf = tmpBuf;
1319  buffer.bufLen = 40;
1320  buffer.ioStrm.readWriteToStream = NULL;
1321  buffer.ioStrm.stream = NULL;
1322 
1323  // Parsing steps:
1324 
1325  // I: First, define an external stream for the input to the parser if any
1326 
1327  // II: Second, initialize the parser object
1328  tmp_err_code = parse.initParser(&testParser, buffer, NULL);
1329  fail_unless (tmp_err_code == EXIP_OK, "initParser returns an error code %d", tmp_err_code);
1330 
1331  // III: Initialize the parsing data and hook the callback handlers to the parser object
1332 
1333  // IV: Parse the header of the stream
1334 
1335  tmp_err_code = parse.parseHeader(&testParser, FALSE);
1336  fail_unless (tmp_err_code == EXIP_OK, "parsing the header returns an error code %d", tmp_err_code);
1337 
1338  tmp_err_code = parse.setSchema(&testParser, &schema);
1339  fail_unless (tmp_err_code == EXIP_OK, "setSchema() returns an error code %d", tmp_err_code);
1340 
1341  // V: Parse the body of the EXI stream
1342 
1343  while(tmp_err_code == EXIP_OK)
1344  {
1345  tmp_err_code = parse.parseNext(&testParser);
1346  }
1347 
1348  while (tmp_err_code == EXIP_BUFFER_END_REACHED)
1349  {
1350  tmp_err_code = parse.pushEXIData(flushBuf + flushMarker, strmSize - flushMarker, &bytesRead, &testParser);
1351  if(tmp_err_code != EXIP_OK)
1352  break;
1353  flushMarker += bytesRead;
1354 
1355  while(tmp_err_code == EXIP_OK)
1356  {
1357  tmp_err_code = parse.parseNext(&testParser);
1358  }
1359  }
1360 
1361  // VI: Free the memory allocated by the parser object
1362 
1363  parse.destroyParser(&testParser);
1364  fail_unless (tmp_err_code == EXIP_PARSING_COMPLETE, "Error during parsing of the EXI body %d", tmp_err_code);
1365 }
1366 END_TEST
1367 
1368 START_TEST (test_non_blocking_streaming_bytealigned)
1369 {
1370  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
1371  char flushBuf[OUTPUT_BUFFER_SIZE];
1372  int strmSize = 0;
1373  BinaryBuffer buffer;
1374  Parser testParser;
1375  char* schemafname[1] = {"exip/NonBlockingStreaming-xsd.exi"};
1376  EXIPSchema schema;
1377  char tmpBuf[40];
1378  unsigned int flushMarker;
1379  unsigned int bytesRead;
1380 
1381  parseSchema(schemafname, 1, &schema);
1382 
1383  tmp_err_code = encodeNonBlockingStreaming(&schema, flushBuf, OUTPUT_BUFFER_SIZE, &strmSize, BYTE_ALIGNMENT);
1384  fail_unless(tmp_err_code == EXIP_OK, "There is an error in the encoding of non blocking EXI stream");
1385  fail_unless(strmSize > 0, "Encoding using non blocking flushing produces empty streams.");
1386 
1387  flushMarker = 20;
1388  memcpy(tmpBuf, flushBuf, flushMarker);
1389 
1390  buffer.bufContent = flushMarker;
1391  buffer.buf = tmpBuf;
1392  buffer.bufLen = 40;
1393  buffer.ioStrm.readWriteToStream = NULL;
1394  buffer.ioStrm.stream = NULL;
1395 
1396  // Parsing steps:
1397 
1398  // I: First, define an external stream for the input to the parser if any
1399 
1400  // II: Second, initialize the parser object
1401  tmp_err_code = parse.initParser(&testParser, buffer, NULL);
1402  fail_unless (tmp_err_code == EXIP_OK, "initParser returns an error code %d", tmp_err_code);
1403 
1404  // III: Initialize the parsing data and hook the callback handlers to the parser object
1405 
1406  // IV: Parse the header of the stream
1407 
1408  tmp_err_code = parse.parseHeader(&testParser, FALSE);
1409  fail_unless (tmp_err_code == EXIP_OK, "parsing the header returns an error code %d", tmp_err_code);
1410 
1411  tmp_err_code = parse.setSchema(&testParser, &schema);
1412  fail_unless (tmp_err_code == EXIP_OK, "setSchema() returns an error code %d", tmp_err_code);
1413 
1414  // V: Parse the body of the EXI stream
1415 
1416  while(tmp_err_code == EXIP_OK)
1417  {
1418  tmp_err_code = parse.parseNext(&testParser);
1419  }
1420 
1421  while (tmp_err_code == EXIP_BUFFER_END_REACHED)
1422  {
1423  tmp_err_code = parse.pushEXIData(flushBuf + flushMarker, strmSize - flushMarker, &bytesRead, &testParser);
1424  if(tmp_err_code != EXIP_OK)
1425  break;
1426  flushMarker += bytesRead;
1427 
1428  while(tmp_err_code == EXIP_OK)
1429  {
1430  tmp_err_code = parse.parseNext(&testParser);
1431  }
1432  }
1433 
1434  // VI: Free the memory allocated by the parser object
1435 
1436  parse.destroyParser(&testParser);
1437  fail_unless (tmp_err_code == EXIP_PARSING_COMPLETE, "Error during parsing of the EXI body %d", tmp_err_code);
1438 }
1439 END_TEST
1440 
1441 errorCode encodeNonBlockingStreaming(EXIPSchema* schema, char* flushBuf, int buf_size, int *strmSize, unsigned char alignment)
1442 {
1443  const String NS_EMPTY_STR = {NULL, 0};
1444  const String NS_URN_STR = {"non:blocking:check", 18};
1445 
1446  const String ELEM_TEST = {"test", 4};
1447  const String ELEM_LONG_TEST = {"long-test", 9};
1448 
1449  const String ATTR_SAMPLE = {"sample", 6};
1450  const String ATTR_SAMPLE_2 = {"sample-2", 8};
1451 
1452  const String LONG_DATA_STR = {"Test data.", 10};
1453  const String SHORT_DATA_STR = {"echo-echoo-echooo", 17};
1454  const String LT1_DATA_STR = {"long-test 1 data", 16};
1455  const String LT2_DATA_STR = {"long-test 2 data", 16};
1456  const String LT3_DATA_STR = {"long-test 3 data", 16};
1457 
1458  const String SCHEMA_ID_STR = {"schemaID=test", 13};
1459 
1460  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
1461  EXIStream testStrm;
1462  BinaryBuffer buffer;
1463  String uri;
1464  String ln;
1465  QName qname = {&uri, &ln, NULL};
1466  EXITypeClass valueType;
1467  char smallBuf[40];
1468  StreamContext savedContext;
1469  SmallIndex savedNonTerminalIndex;
1470  unsigned int bytesFlushed = 0;
1471 
1472  buffer.buf = smallBuf;
1473  buffer.bufLen = 40;
1474  buffer.bufContent = 0;
1475 
1476  *strmSize = 0;
1477 
1478  // Serialization steps:
1479  // I: First initialize the header of the stream
1480  serialize.initHeader(&testStrm);
1481 
1482  // II: Set any options in the header (including schemaID and schemaIDMode), if different from the defaults.
1483  testStrm.header.has_options = TRUE;
1484  SET_ALIGNMENT(testStrm.header.opts.enumOpt, alignment);
1486  testStrm.header.opts.schemaID = SCHEMA_ID_STR;
1487 
1488  // III: Define an external stream for the output if any, otherwise set to NULL
1489  buffer.ioStrm.readWriteToStream = NULL;
1490  buffer.ioStrm.stream = NULL;
1491 
1492  // IV: Initialize the stream
1493  TRY_CATCH_ENCODE(serialize.initStream(&testStrm, buffer, schema));
1494 
1495  // V: Start building the stream step by step: header, document, element etc...
1496  TRY_CATCH_ENCODE(serialize.exiHeader(&testStrm));
1497 
1499 
1500  savedContext = testStrm.context;
1501  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1502  qname.uri = &NS_URN_STR;
1503  qname.localName = &ELEM_TEST;
1504  tmp_err_code = serialize.startElement(&testStrm, qname, &valueType); // <test>
1505  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1506  {
1507  testStrm.context = savedContext;
1508  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1509  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1510  *strmSize += bytesFlushed;
1511  TRY_CATCH_ENCODE(serialize.startElement(&testStrm, qname, &valueType)); // redo the <test>
1512  }
1513  else if(tmp_err_code != EXIP_OK)
1514  return tmp_err_code;
1515 
1516  savedContext = testStrm.context;
1517  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1518  qname.uri = &NS_EMPTY_STR;
1519  qname.localName = &ATTR_SAMPLE;
1520  tmp_err_code = serialize.attribute(&testStrm, qname, TRUE, &valueType); // sample="
1521  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1522  {
1523  testStrm.context = savedContext;
1524  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1525  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1526  *strmSize += bytesFlushed;
1527  TRY_CATCH_ENCODE(serialize.attribute(&testStrm, qname, TRUE, &valueType)); // redo sample="
1528  }
1529  else if(tmp_err_code != EXIP_OK)
1530  return tmp_err_code;
1531 
1532  savedContext = testStrm.context;
1533  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1534  tmp_err_code = serialize.stringData(&testStrm, SHORT_DATA_STR);
1535  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1536  {
1537  testStrm.context = savedContext;
1538  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1539  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1540  *strmSize += bytesFlushed;
1541  TRY_CATCH_ENCODE(serialize.stringData(&testStrm, SHORT_DATA_STR)); // redo SHORT_DATA_STR encoding
1542  }
1543  else if(tmp_err_code != EXIP_OK)
1544  return tmp_err_code;
1545 
1546  savedContext = testStrm.context;
1547  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1548  qname.uri = &NS_EMPTY_STR;
1549  qname.localName = &ELEM_LONG_TEST;
1550  tmp_err_code = serialize.startElement(&testStrm, qname, &valueType); // <long-test>
1551  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1552  {
1553  testStrm.context = savedContext;
1554  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1555  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1556  *strmSize += bytesFlushed;
1557  TRY_CATCH_ENCODE(serialize.startElement(&testStrm, qname, &valueType)); // redo the <long-test>
1558  }
1559  else if(tmp_err_code != EXIP_OK)
1560  return tmp_err_code;
1561 
1562  savedContext = testStrm.context;
1563  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1564  qname.uri = &NS_EMPTY_STR;
1565  qname.localName = &ATTR_SAMPLE_2;
1566  tmp_err_code = serialize.attribute(&testStrm, qname, TRUE, &valueType); // sample-2="
1567  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1568  {
1569  testStrm.context = savedContext;
1570  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1571  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1572  *strmSize += bytesFlushed;
1573  TRY_CATCH_ENCODE(serialize.attribute(&testStrm, qname, TRUE, &valueType)); // redo sample-2="
1574  }
1575  else if(tmp_err_code != EXIP_OK)
1576  return tmp_err_code;
1577 
1578  savedContext = testStrm.context;
1579  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1580  tmp_err_code = serialize.stringData(&testStrm, SHORT_DATA_STR);
1581  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1582  {
1583  testStrm.context = savedContext;
1584  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1585  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1586  *strmSize += bytesFlushed;
1587  TRY_CATCH_ENCODE(serialize.stringData(&testStrm, SHORT_DATA_STR)); // redo SHORT_DATA_STR encoding
1588  }
1589  else if(tmp_err_code != EXIP_OK)
1590  return tmp_err_code;
1591 
1592  savedContext = testStrm.context;
1593  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1594  tmp_err_code = serialize.stringData(&testStrm, LONG_DATA_STR);
1595  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1596  {
1597  testStrm.context = savedContext;
1598  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1599  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1600  *strmSize += bytesFlushed;
1601  TRY_CATCH_ENCODE(serialize.stringData(&testStrm, LONG_DATA_STR)); // redo LONG_DATA_STR encoding
1602  }
1603  else if(tmp_err_code != EXIP_OK)
1604  return tmp_err_code;
1605 
1606  savedContext = testStrm.context;
1607  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1608  tmp_err_code = serialize.endElement(&testStrm); // </long-test>
1609  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1610  {
1611  testStrm.context = savedContext;
1612  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1613  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1614  *strmSize += bytesFlushed;
1615  TRY_CATCH_ENCODE(serialize.endElement(&testStrm)); // redo the </long-test>
1616  }
1617  else if(tmp_err_code != EXIP_OK)
1618  return tmp_err_code;
1619 
1620  // ***************************
1621 
1622  savedContext = testStrm.context;
1623  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1624  qname.uri = &NS_EMPTY_STR;
1625  qname.localName = &ELEM_LONG_TEST;
1626  tmp_err_code = serialize.startElement(&testStrm, qname, &valueType); // <long-test>
1627  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1628  {
1629  testStrm.context = savedContext;
1630  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1631  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1632  *strmSize += bytesFlushed;
1633  TRY_CATCH_ENCODE(serialize.startElement(&testStrm, qname, &valueType)); // redo the <long-test>
1634  }
1635  else if(tmp_err_code != EXIP_OK)
1636  return tmp_err_code;
1637 
1638  savedContext = testStrm.context;
1639  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1640  qname.uri = &NS_EMPTY_STR;
1641  qname.localName = &ATTR_SAMPLE_2;
1642  tmp_err_code = serialize.attribute(&testStrm, qname, TRUE, &valueType); // sample-2="
1643  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1644  {
1645  testStrm.context = savedContext;
1646  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1647  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1648  *strmSize += bytesFlushed;
1649  TRY_CATCH_ENCODE(serialize.attribute(&testStrm, qname, TRUE, &valueType)); // redo sample-2="
1650  }
1651  else if(tmp_err_code != EXIP_OK)
1652  return tmp_err_code;
1653 
1654  savedContext = testStrm.context;
1655  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1656  tmp_err_code = serialize.stringData(&testStrm, SHORT_DATA_STR);
1657  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1658  {
1659  testStrm.context = savedContext;
1660  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1661  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1662  *strmSize += bytesFlushed;
1663  TRY_CATCH_ENCODE(serialize.stringData(&testStrm, SHORT_DATA_STR)); // redo SHORT_DATA_STR encoding
1664  }
1665  else if(tmp_err_code != EXIP_OK)
1666  return tmp_err_code;
1667 
1668  savedContext = testStrm.context;
1669  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1670  tmp_err_code = serialize.stringData(&testStrm, LT1_DATA_STR);
1671  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1672  {
1673  testStrm.context = savedContext;
1674  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1675  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1676  *strmSize += bytesFlushed;
1677  TRY_CATCH_ENCODE(serialize.stringData(&testStrm, LT1_DATA_STR)); // redo LT1_DATA_STR encoding
1678  }
1679  else if(tmp_err_code != EXIP_OK)
1680  return tmp_err_code;
1681 
1682  savedContext = testStrm.context;
1683  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1684  tmp_err_code = serialize.endElement(&testStrm); // </long-test>
1685  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1686  {
1687  testStrm.context = savedContext;
1688  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1689  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1690  *strmSize += bytesFlushed;
1691  TRY_CATCH_ENCODE(serialize.endElement(&testStrm)); // redo the </long-test>
1692  }
1693  else if(tmp_err_code != EXIP_OK)
1694  return tmp_err_code;
1695 
1696  // *************************
1697 
1698  savedContext = testStrm.context;
1699  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1700  qname.uri = &NS_EMPTY_STR;
1701  qname.localName = &ELEM_LONG_TEST;
1702  tmp_err_code = serialize.startElement(&testStrm, qname, &valueType); // <long-test>
1703  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1704  {
1705  testStrm.context = savedContext;
1706  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1707  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1708  *strmSize += bytesFlushed;
1709  TRY_CATCH_ENCODE(serialize.startElement(&testStrm, qname, &valueType)); // redo the <long-test>
1710  }
1711  else if(tmp_err_code != EXIP_OK)
1712  return tmp_err_code;
1713 
1714  savedContext = testStrm.context;
1715  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1716  qname.uri = &NS_EMPTY_STR;
1717  qname.localName = &ATTR_SAMPLE_2;
1718  tmp_err_code = serialize.attribute(&testStrm, qname, TRUE, &valueType); // sample-2="
1719  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1720  {
1721  testStrm.context = savedContext;
1722  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1723  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1724  *strmSize += bytesFlushed;
1725  TRY_CATCH_ENCODE(serialize.attribute(&testStrm, qname, TRUE, &valueType)); // redo sample-2="
1726  }
1727  else if(tmp_err_code != EXIP_OK)
1728  return tmp_err_code;
1729 
1730  savedContext = testStrm.context;
1731  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1732  tmp_err_code = serialize.stringData(&testStrm, SHORT_DATA_STR);
1733  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1734  {
1735  testStrm.context = savedContext;
1736  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1737  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1738  *strmSize += bytesFlushed;
1739  TRY_CATCH_ENCODE(serialize.stringData(&testStrm, SHORT_DATA_STR)); // redo SHORT_DATA_STR encoding
1740  }
1741  else if(tmp_err_code != EXIP_OK)
1742  return tmp_err_code;
1743 
1744  savedContext = testStrm.context;
1745  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1746  tmp_err_code = serialize.stringData(&testStrm, LT2_DATA_STR);
1747  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1748  {
1749  testStrm.context = savedContext;
1750  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1751  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1752  *strmSize += bytesFlushed;
1753  TRY_CATCH_ENCODE(serialize.stringData(&testStrm, LT2_DATA_STR)); // redo LT2_DATA_STR encoding
1754  }
1755  else if(tmp_err_code != EXIP_OK)
1756  return tmp_err_code;
1757 
1758  savedContext = testStrm.context;
1759  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1760  tmp_err_code = serialize.endElement(&testStrm); // </long-test>
1761  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1762  {
1763  testStrm.context = savedContext;
1764  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1765  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1766  *strmSize += bytesFlushed;
1767  TRY_CATCH_ENCODE(serialize.endElement(&testStrm)); // redo the </long-test>
1768  }
1769  else if(tmp_err_code != EXIP_OK)
1770  return tmp_err_code;
1771 
1772  // ********************************************
1773 
1774  savedContext = testStrm.context;
1775  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1776  qname.uri = &NS_EMPTY_STR;
1777  qname.localName = &ELEM_LONG_TEST;
1778  tmp_err_code = serialize.startElement(&testStrm, qname, &valueType); // <long-test>
1779  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1780  {
1781  testStrm.context = savedContext;
1782  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1783  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1784  *strmSize += bytesFlushed;
1785  TRY_CATCH_ENCODE(serialize.startElement(&testStrm, qname, &valueType)); // redo the <long-test>
1786  }
1787  else if(tmp_err_code != EXIP_OK)
1788  return tmp_err_code;
1789 
1790  savedContext = testStrm.context;
1791  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1792  qname.uri = &NS_EMPTY_STR;
1793  qname.localName = &ATTR_SAMPLE_2;
1794  tmp_err_code = serialize.attribute(&testStrm, qname, TRUE, &valueType); // sample-2="
1795  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1796  {
1797  testStrm.context = savedContext;
1798  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1799  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1800  *strmSize += bytesFlushed;
1801  TRY_CATCH_ENCODE(serialize.attribute(&testStrm, qname, TRUE, &valueType)); // redo sample-2="
1802  }
1803  else if(tmp_err_code != EXIP_OK)
1804  return tmp_err_code;
1805 
1806  savedContext = testStrm.context;
1807  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1808  tmp_err_code = serialize.stringData(&testStrm, SHORT_DATA_STR);
1809  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1810  {
1811  testStrm.context = savedContext;
1812  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1813  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1814  *strmSize += bytesFlushed;
1815  TRY_CATCH_ENCODE(serialize.stringData(&testStrm, SHORT_DATA_STR)); // redo SHORT_DATA_STR encoding
1816  }
1817  else if(tmp_err_code != EXIP_OK)
1818  return tmp_err_code;
1819 
1820  savedContext = testStrm.context;
1821  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1822  tmp_err_code = serialize.stringData(&testStrm, LT3_DATA_STR);
1823  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1824  {
1825  testStrm.context = savedContext;
1826  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1827  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1828  *strmSize += bytesFlushed;
1829  TRY_CATCH_ENCODE(serialize.stringData(&testStrm, LT3_DATA_STR)); // redo LT2_DATA_STR encoding
1830  }
1831  else if(tmp_err_code != EXIP_OK)
1832  return tmp_err_code;
1833 
1834  savedContext = testStrm.context;
1835  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1836  tmp_err_code = serialize.endElement(&testStrm); // </long-test>
1837  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1838  {
1839  testStrm.context = savedContext;
1840  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1841  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1842  *strmSize += bytesFlushed;
1843  TRY_CATCH_ENCODE(serialize.endElement(&testStrm)); // redo the </long-test>
1844  }
1845  else if(tmp_err_code != EXIP_OK)
1846  return tmp_err_code;
1847 
1848  // ************************
1849 
1850  savedContext = testStrm.context;
1851  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1852  qname.uri = &NS_EMPTY_STR;
1853  qname.localName = &ELEM_LONG_TEST;
1854  tmp_err_code = serialize.startElement(&testStrm, qname, &valueType); // <long-test>
1855  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1856  {
1857  testStrm.context = savedContext;
1858  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1859  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1860  *strmSize += bytesFlushed;
1861  TRY_CATCH_ENCODE(serialize.startElement(&testStrm, qname, &valueType)); // redo the <long-test>
1862  }
1863  else if(tmp_err_code != EXIP_OK)
1864  return tmp_err_code;
1865 
1866  savedContext = testStrm.context;
1867  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1868  qname.uri = &NS_EMPTY_STR;
1869  qname.localName = &ATTR_SAMPLE_2;
1870  tmp_err_code = serialize.attribute(&testStrm, qname, TRUE, &valueType); // sample-2="
1871  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1872  {
1873  testStrm.context = savedContext;
1874  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1875  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1876  *strmSize += bytesFlushed;
1877  TRY_CATCH_ENCODE(serialize.attribute(&testStrm, qname, TRUE, &valueType)); // redo sample-2="
1878  }
1879  else if(tmp_err_code != EXIP_OK)
1880  return tmp_err_code;
1881 
1882  savedContext = testStrm.context;
1883  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1884  tmp_err_code = serialize.stringData(&testStrm, SHORT_DATA_STR);
1885  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1886  {
1887  testStrm.context = savedContext;
1888  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1889  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1890  *strmSize += bytesFlushed;
1891  TRY_CATCH_ENCODE(serialize.stringData(&testStrm, LONG_DATA_STR)); // redo SHORT_DATA_STR encoding
1892  }
1893  else if(tmp_err_code != EXIP_OK)
1894  return tmp_err_code;
1895 
1896  savedContext = testStrm.context;
1897  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1898  tmp_err_code = serialize.stringData(&testStrm, LONG_DATA_STR);
1899  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1900  {
1901  testStrm.context = savedContext;
1902  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1903  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1904  *strmSize += bytesFlushed;
1905  TRY_CATCH_ENCODE(serialize.stringData(&testStrm, LONG_DATA_STR)); // redo LONG_DATA_STR encoding
1906  }
1907  else if(tmp_err_code != EXIP_OK)
1908  return tmp_err_code;
1909 
1910  savedContext = testStrm.context;
1911  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1912  tmp_err_code = serialize.endElement(&testStrm); // </long-test>
1913  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1914  {
1915  testStrm.context = savedContext;
1916  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1917  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1918  *strmSize += bytesFlushed;
1919  TRY_CATCH_ENCODE(serialize.endElement(&testStrm)); // redo the </long-test>
1920  }
1921  else if(tmp_err_code != EXIP_OK)
1922  return tmp_err_code;
1923 
1924  // ************************
1925 
1926  savedContext = testStrm.context;
1927  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1928  tmp_err_code = serialize.endElement(&testStrm); // </test>
1929  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1930  {
1931  testStrm.context = savedContext;
1932  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1933  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1934  *strmSize += bytesFlushed;
1935  TRY_CATCH_ENCODE(serialize.endElement(&testStrm)); // redo the </test>
1936  }
1937  else if(tmp_err_code != EXIP_OK)
1938  return tmp_err_code;
1939 
1940  savedContext = testStrm.context;
1941  savedNonTerminalIndex = testStrm.gStack->currNonTermID;
1942  tmp_err_code = serialize.endDocument(&testStrm);
1943  if(tmp_err_code == EXIP_BUFFER_END_REACHED)
1944  {
1945  testStrm.context = savedContext;
1946  testStrm.gStack->currNonTermID = savedNonTerminalIndex;
1947  TRY_CATCH_ENCODE(flushEXIData(&testStrm, flushBuf + *strmSize, buf_size - *strmSize, &bytesFlushed));
1948  *strmSize += bytesFlushed;
1950  }
1951  else if(tmp_err_code != EXIP_OK)
1952  return tmp_err_code;
1953 
1954  if(buf_size - *strmSize < testStrm.buffer.bufContent)
1955  return EXIP_UNEXPECTED_ERROR;
1956 
1957  memcpy(flushBuf + *strmSize, testStrm.buffer.buf, testStrm.buffer.bufContent);
1958  *strmSize += testStrm.buffer.bufContent;
1959 
1960  // VI: Free the memory allocated by the EXI stream object
1962 
1963  return EXIP_OK;
1964 }
1965 
1966 #define BN_STR_SIZE 50
1967 #define ALL_STR_SIZE 20
1968 
1969 typedef struct
1970 {
1971  char n[ALL_STR_SIZE]; // "" for N/A
1972  char u[ALL_STR_SIZE]; // "" for N/A
1973  Float v; // Float.exponent == INT16_MAX for N/A
1974  char sv[ALL_STR_SIZE]; // "" for N/A
1975  unsigned char bv; // boolean: 0 False, 1 true, else N/A
1976  Decimal s; // Decimal.exponent == INT16_MAX for N/A
1977  int t; // INT_MAX for N/A
1978  int ut; // INT_MAX for N/A
1979 } senml_elem;
1980 
1981 typedef struct
1982 {
1983  char bn[BN_STR_SIZE]; // "" for N/A
1984  long bt; // LONG_MAX for N/A
1985  int version; // -1 for N/A
1986  char bu[ALL_STR_SIZE]; // "" for N/A
1987  senml_elem* eArray; // Statically assigned array
1988  size_t eArrayCount; // The number of e elements in the array
1989  size_t eArraySize; // The total number of elements allocated in the array
1990 } senml;
1991 
1992 
1997 errorCode encodeSenML(EXIPSchema* schema, senml senmlData, char* buf, int buflen, size_t* size);
1998 
2003 errorCode decodeSenML(EXIPSchema* schema, char* buf, int buflen, senml* senmlData);
2004 
2005 const String NS_SENML_STR = {"urn:ietf:params:xml:ns:senml", 28};
2006 const String NS_EMPTY_STR = {NULL, 0};
2007 
2008 const String ELEM_E_STR = {"e", 1};
2009 const String ELEM_SENML_STR = {"senml", 5};
2010 
2011 const String ATTR_BN_STR = {"bn", 2};
2012 const String ATTR_BT_STR = {"bt", 2};
2013 const String ATTR_BU_STR = {"bu", 2};
2014 const String ATTR_VER_STR = {"ver", 3};
2015 
2016 const String ATTR_N_STR = {"n", 1};
2017 const String ATTR_U_STR = {"u", 1};
2018 const String ATTR_V_STR = {"v", 1};
2019 const String ATTR_SV_STR = {"sv", 2};
2020 const String ATTR_BV_STR = {"bv", 2};
2021 const String ATTR_S_STR = {"s", 1};
2022 const String ATTR_T_STR = {"t", 1};
2023 const String ATTR_UT_STR = {"ut", 2};
2024 
2025 errorCode encodeSenML(EXIPSchema* schema, senml senmlData, char* buf, int buflen, size_t* size)
2026 {
2027  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
2028  EXIStream testStrm;
2029  String uri;
2030  String ln;
2031  QName qname = {&uri, &ln, NULL};
2032  BinaryBuffer buffer;
2033  EXITypeClass valueType;
2034  size_t e;
2035  String chVal;
2036 
2037  buffer.buf = buf;
2038  buffer.bufLen = buflen;
2039  buffer.bufContent = buflen;
2040 
2041  // Serialization steps:
2042 
2043  // I: First initialize the header of the stream
2044  serialize.initHeader(&testStrm);
2045 
2046  // II: Set any options in the header (including schemaID and schemaIDMode), if different from the defaults.
2047  testStrm.header.has_options = TRUE;
2048 
2049  // III: Define an external stream for the output if any, otherwise set to NULL
2050  buffer.ioStrm.readWriteToStream = NULL;
2051  buffer.ioStrm.stream = NULL;
2052 
2053  // IV: Initialize the stream
2054  TRY_CATCH_ENCODE(serialize.initStream(&testStrm, buffer, schema));
2055 
2056  // V: Start building the stream step by step: header, document, element etc...
2057  TRY_CATCH_ENCODE(serialize.exiHeader(&testStrm));
2058 
2060 
2061  qname.uri = &NS_SENML_STR;
2062  qname.localName = &ELEM_SENML_STR;
2063  TRY_CATCH_ENCODE(serialize.startElement(&testStrm, qname, &valueType)); // <senml>
2064 
2065  if(senmlData.bn[0] != '\0')
2066  {
2067  qname.uri = &NS_EMPTY_STR;
2068  qname.localName = &ATTR_BN_STR;
2069  TRY_CATCH_ENCODE(serialize.attribute(&testStrm, qname, TRUE, &valueType)); // bn=""
2070 
2071  TRY_CATCH_ENCODE(asciiToString(senmlData.bn, &chVal, &testStrm.memList, FALSE));
2072  TRY_CATCH_ENCODE(serialize.stringData(&testStrm, chVal));
2073  }
2074 
2075  if(senmlData.bt != LONG_MAX)
2076  {
2077  qname.uri = &NS_EMPTY_STR;
2078  qname.localName = &ATTR_BT_STR;
2079  TRY_CATCH_ENCODE(serialize.attribute(&testStrm, qname, TRUE, &valueType)); // bt=""
2080 
2081  TRY_CATCH_ENCODE(serialize.intData(&testStrm, (Integer) senmlData.bt));
2082  }
2083 
2084  if(senmlData.bu[0] != '\0')
2085  {
2086  qname.uri = &NS_EMPTY_STR;
2087  qname.localName = &ATTR_BU_STR;
2088  TRY_CATCH_ENCODE(serialize.attribute(&testStrm, qname, TRUE, &valueType)); // bu=""
2089  TRY_CATCH_ENCODE(asciiToString(senmlData.bu, &chVal, &testStrm.memList, FALSE));
2090  TRY_CATCH_ENCODE(serialize.stringData(&testStrm, chVal));
2091  }
2092 
2093  if(senmlData.version != -1)
2094  {
2095  qname.uri = &NS_EMPTY_STR;
2096  qname.localName = &ATTR_VER_STR;
2097  TRY_CATCH_ENCODE(serialize.attribute(&testStrm, qname, TRUE, &valueType)); // ver=""
2098  TRY_CATCH_ENCODE(serialize.intData(&testStrm, (Integer) senmlData.version));
2099  }
2100 
2101  for(e = 0; e < senmlData.eArrayCount; e++)
2102  {
2103  qname.uri = &NS_SENML_STR;
2104  qname.localName = &ELEM_E_STR;
2105  TRY_CATCH_ENCODE(serialize.startElement(&testStrm, qname, &valueType)); // <e>
2106 
2107  if(senmlData.eArray[e].bv == 0 || senmlData.eArray[e].bv == 1)
2108  {
2109  qname.uri = &NS_EMPTY_STR;
2110  qname.localName = &ATTR_BV_STR;
2111  TRY_CATCH_ENCODE(serialize.attribute(&testStrm, qname, TRUE, &valueType)); // bv=""
2112  TRY_CATCH_ENCODE(serialize.booleanData(&testStrm, (boolean) senmlData.eArray[e].bv));
2113  }
2114 
2115  if(senmlData.eArray[e].n[0] != '\0')
2116  {
2117  qname.uri = &NS_EMPTY_STR;
2118  qname.localName = &ATTR_N_STR;
2119  TRY_CATCH_ENCODE(serialize.attribute(&testStrm, qname, TRUE, &valueType)); // n=""
2120  TRY_CATCH_ENCODE(asciiToString(senmlData.eArray[e].n, &chVal, &testStrm.memList, FALSE));
2121  TRY_CATCH_ENCODE(serialize.stringData(&testStrm, chVal));
2122  }
2123 
2124  if(senmlData.eArray[e].s.exponent != INT16_MAX)
2125  {
2126  qname.uri = &NS_EMPTY_STR;
2127  qname.localName = &ATTR_S_STR;
2128  TRY_CATCH_ENCODE(serialize.attribute(&testStrm, qname, TRUE, &valueType)); // s=""
2129  TRY_CATCH_ENCODE(serialize.decimalData(&testStrm, senmlData.eArray[e].s));
2130  }
2131 
2132  if(senmlData.eArray[e].sv[0] != '\0')
2133  {
2134  qname.uri = &NS_EMPTY_STR;
2135  qname.localName = &ATTR_SV_STR;
2136  TRY_CATCH_ENCODE(serialize.attribute(&testStrm, qname, TRUE, &valueType)); // sv=""
2137  TRY_CATCH_ENCODE(asciiToString(senmlData.eArray[e].sv, &chVal, &testStrm.memList, FALSE));
2138  TRY_CATCH_ENCODE(serialize.stringData(&testStrm, chVal));
2139  }
2140 
2141  if(senmlData.eArray[e].t != INT_MAX)
2142  {
2143  qname.uri = &NS_EMPTY_STR;
2144  qname.localName = &ATTR_T_STR;
2145  TRY_CATCH_ENCODE(serialize.attribute(&testStrm, qname, TRUE, &valueType)); // t=""
2146  TRY_CATCH_ENCODE(serialize.intData(&testStrm, (Integer) senmlData.eArray[e].t));
2147  }
2148 
2149  if(senmlData.eArray[e].u[0] != '\0')
2150  {
2151  qname.uri = &NS_EMPTY_STR;
2152  qname.localName = &ATTR_U_STR;
2153  TRY_CATCH_ENCODE(serialize.attribute(&testStrm, qname, TRUE, &valueType)); // u=""
2154  TRY_CATCH_ENCODE(asciiToString(senmlData.eArray[e].u, &chVal, &testStrm.memList, FALSE));
2155  TRY_CATCH_ENCODE(serialize.stringData(&testStrm, chVal));
2156  }
2157 
2158  if(senmlData.eArray[e].ut != INT_MAX)
2159  {
2160  qname.uri = &NS_EMPTY_STR;
2161  qname.localName = &ATTR_UT_STR;
2162  TRY_CATCH_ENCODE(serialize.attribute(&testStrm, qname, TRUE, &valueType)); // ut=""
2163  TRY_CATCH_ENCODE(serialize.intData(&testStrm, (Integer) senmlData.eArray[e].ut));
2164  }
2165 
2166  if(senmlData.eArray[e].v.exponent != INT16_MAX)
2167  {
2168  qname.uri = &NS_EMPTY_STR;
2169  qname.localName = &ATTR_V_STR;
2170  TRY_CATCH_ENCODE(serialize.attribute(&testStrm, qname, TRUE, &valueType)); // v=""
2171  TRY_CATCH_ENCODE(serialize.floatData(&testStrm, senmlData.eArray[e].v));
2172  }
2173 
2174  TRY_CATCH_ENCODE(serialize.endElement(&testStrm)); // </e>
2175  }
2176 
2177  TRY_CATCH_ENCODE(serialize.endElement(&testStrm)); // </senml>
2178 
2180 
2181  // VI: Free the memory allocated by the EXI stream object
2183 
2184  *size = testStrm.buffer.bufContent;
2185 
2186  return tmp_err_code;
2187 }
2188 
2189 typedef enum {
2190  BN = 0,
2191  BT = 1,
2192  BU = 2,
2193  VER = 3,
2194  BV = 4,
2195  N = 5,
2196  S = 6,
2197  SV = 7,
2198  T = 8,
2199  U = 9,
2200  UT = 10,
2201  V = 11,
2202  NON = 12
2203 } Attr;
2204 
2205 typedef enum {
2207  ELEM_E = 1,
2209 } Elem;
2210 
2211 typedef struct
2212 {
2216  int eIndex;
2217 } AppData;
2218 
2219 static errorCode sample_startElement(QName qname, void* app_data);
2220 static errorCode sample_attribute(QName qname, void* app_data);
2221 static errorCode sample_stringData(const String value, void* app_data);
2222 static errorCode sample_floatData(Float fl_val, void* app_data);
2223 static errorCode sample_booleanData(boolean bool_val, void* app_data);
2224 static errorCode sample_decimalData(Decimal value, void* app_data);
2225 static errorCode sample_intData(Integer int_val, void* app_data);
2226 
2227 errorCode decodeSenML(EXIPSchema* schema, char* buf, int buflen, senml* senmlData)
2228 {
2229  Parser testParser;
2230  BinaryBuffer buffer;
2231  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
2232  AppData parsingData;
2233 
2234  buffer.buf = buf;
2235  buffer.bufLen = buflen;
2236  buffer.bufContent = buflen;
2237  // Parsing steps:
2238 
2239  // I: First, define an external stream for the input to the parser if any, otherwise set to NULL
2240  buffer.ioStrm.readWriteToStream = NULL;
2241  buffer.ioStrm.stream = NULL;
2242 
2243  parsingData.currElem = ELEM_NON;
2244  parsingData.currAttr = NON;
2245  parsingData.data = senmlData;
2246  parsingData.eIndex = -1;
2247  senmlData->eArrayCount = 0;
2248 
2249  // II: Second, initialize the parser object
2250  TRY(initParser(&testParser, buffer, &parsingData));
2251 
2252  // III: Initialize the parsing data and hook the callback handlers to the parser object.
2253  // If out-of-band options are defined use testParser.strm.header.opts to set them
2254 
2255  testParser.handler.startElement = sample_startElement;
2256  testParser.handler.attribute = sample_attribute;
2257  testParser.handler.stringData = sample_stringData;
2258  testParser.handler.floatData = sample_floatData;
2259  testParser.handler.booleanData = sample_booleanData;
2260  testParser.handler.decimalData = sample_decimalData;
2261  testParser.handler.intData = sample_intData;
2262 
2263  // IV: Parse the header of the stream
2264 
2265  TRY(parseHeader(&testParser, FALSE));
2266 
2267  // IV.1: Set the schema to be used for parsing.
2268  // The schemaID mode and schemaID field can be read at
2269  // parser.strm.header.opts.schemaIDMode and
2270  // parser.strm.header.opts.schemaID respectively
2271  // If schemaless mode, use setSchema(&parser, NULL);
2272 
2273  TRY(setSchema(&testParser, schema));
2274 
2275  // V: Parse the body of the EXI stream
2276 
2277  while(tmp_err_code == EXIP_OK)
2278  {
2279  tmp_err_code = parseNext(&testParser);
2280  }
2281 
2282  // VI: Free the memory allocated by the parser
2283 
2284  destroyParser(&testParser);
2285 
2286  if(tmp_err_code == EXIP_PARSING_COMPLETE)
2287  return EXIP_OK;
2288  else
2289  return tmp_err_code;
2290 }
2291 
2292 static errorCode sample_startElement(QName qname, void* app_data)
2293 {
2294  AppData* appD = (AppData*) app_data;
2295 
2296  if(appD->currElem == ELEM_NON)
2297  {
2298  // must senml
2299  if(stringCompare(*qname.uri, NS_SENML_STR) == 0 && stringCompare(*qname.localName, ELEM_SENML_STR) == 0)
2300  {
2301  appD->currElem = ELEM_SEN_ML;
2302  }
2303  else
2304  return EXIP_HANDLER_STOP;
2305  }
2306  else if (appD->currElem == ELEM_SEN_ML)
2307  {
2308  // must e
2309  if(stringCompare(*qname.uri, NS_SENML_STR) == 0 && stringCompare(*qname.localName, ELEM_E_STR) == 0)
2310  {
2311  appD->currElem = ELEM_E;
2312  }
2313  else
2314  return EXIP_HANDLER_STOP;
2315 
2316  }
2317 
2318  if (appD->currElem == ELEM_E)
2319  {
2320  appD->data->eArrayCount += 1;
2321  if(appD->data->eArrayCount > appD->data->eArraySize)
2322  return EXIP_HANDLER_STOP;
2323 
2324  appD->eIndex += 1;
2325  }
2326 
2327  return EXIP_OK;
2328 }
2329 
2330 static errorCode sample_attribute(QName qname, void* app_data)
2331 {
2332  AppData* appD = (AppData*) app_data;
2333 
2334  // must have empty namespace
2335  if(stringCompare(*qname.uri, NS_EMPTY_STR) != 0)
2336  return EXIP_HANDLER_STOP;
2337 
2338  if(appD->currElem == ELEM_SEN_ML)
2339  {
2340  if(stringCompare(*qname.localName, ATTR_BN_STR) == 0)
2341  appD->currAttr = BN;
2342  else if(stringCompare(*qname.localName, ATTR_BT_STR) == 0)
2343  appD->currAttr = BT;
2344  else if(stringCompare(*qname.localName, ATTR_BU_STR) == 0)
2345  appD->currAttr = BU;
2346  else if(stringCompare(*qname.localName, ATTR_VER_STR) == 0)
2347  appD->currAttr = VER;
2348  }
2349  else if(appD->currElem == ELEM_E)
2350  {
2351  if(stringCompare(*qname.localName, ATTR_N_STR) == 0)
2352  appD->currAttr = N;
2353  else if(stringCompare(*qname.localName, ATTR_U_STR) == 0)
2354  appD->currAttr = U;
2355  else if(stringCompare(*qname.localName, ATTR_V_STR) == 0)
2356  appD->currAttr = V;
2357  else if(stringCompare(*qname.localName, ATTR_SV_STR) == 0)
2358  appD->currAttr = SV;
2359  else if(stringCompare(*qname.localName, ATTR_BV_STR) == 0)
2360  appD->currAttr = BV;
2361  else if(stringCompare(*qname.localName, ATTR_S_STR) == 0)
2362  appD->currAttr = S;
2363  else if(stringCompare(*qname.localName, ATTR_T_STR) == 0)
2364  appD->currAttr = T;
2365  else if(stringCompare(*qname.localName, ATTR_UT_STR) == 0)
2366  appD->currAttr = UT;
2367  }
2368  else
2369  return EXIP_HANDLER_STOP;
2370 
2371  return EXIP_OK;
2372 }
2373 
2374 static errorCode sample_stringData(const String value, void* app_data)
2375 {
2376  AppData* appD = (AppData*) app_data;
2377 
2378  switch(appD->currAttr)
2379  {
2380  case BN:
2381  if(value.length < BN_STR_SIZE)
2382  {
2383  memcpy(appD->data->bn, value.str, value.length);
2384  appD->data->bn[value.length] = '\0';
2385  }
2386  else
2387  return EXIP_HANDLER_STOP;
2388  break;
2389  case BU:
2390  if(value.length < ALL_STR_SIZE)
2391  {
2392  memcpy(appD->data->bu, value.str, value.length);
2393  appD->data->bu[value.length] = '\0';
2394  }
2395  else
2396  return EXIP_HANDLER_STOP;
2397  break;
2398  case N:
2399  if(value.length < ALL_STR_SIZE)
2400  {
2401  memcpy(appD->data->eArray[appD->eIndex].n, value.str, value.length);
2402  appD->data->eArray[appD->eIndex].n[value.length] = '\0';
2403  }
2404  else
2405  return EXIP_HANDLER_STOP;
2406  break;
2407  case U:
2408  if(value.length < ALL_STR_SIZE)
2409  {
2410  memcpy(appD->data->eArray[appD->eIndex].u, value.str, value.length);
2411  appD->data->eArray[appD->eIndex].u[value.length] = '\0';
2412  }
2413  else
2414  return EXIP_HANDLER_STOP;
2415  break;
2416  case SV:
2417  if(value.length < ALL_STR_SIZE)
2418  {
2419  memcpy(appD->data->eArray[appD->eIndex].sv, value.str, value.length);
2420  appD->data->eArray[appD->eIndex].sv[value.length] = '\0';
2421  }
2422  else
2423  return EXIP_HANDLER_STOP;
2424  break;
2425  default:
2426  return EXIP_HANDLER_STOP;
2427  }
2428 
2429  return EXIP_OK;
2430 }
2431 
2432 static errorCode sample_floatData(Float fl_val, void* app_data)
2433 {
2434  AppData* appD = (AppData*) app_data;
2435 
2436  if(appD->currAttr == V)
2437  {
2438  appD->data->eArray[appD->eIndex].v = fl_val;
2439  }
2440  else
2441  return EXIP_HANDLER_STOP;
2442 
2443  return EXIP_OK;
2444 }
2445 
2446 static errorCode sample_booleanData(boolean bool_val, void* app_data)
2447 {
2448  AppData* appD = (AppData*) app_data;
2449 
2450  if(appD->currAttr == BV)
2451  {
2452  appD->data->eArray[appD->eIndex].bv = bool_val;
2453  }
2454  else
2455  return EXIP_HANDLER_STOP;
2456 
2457  return EXIP_OK;
2458 }
2459 
2460 static errorCode sample_decimalData(Decimal value, void* app_data)
2461 {
2462  AppData* appD = (AppData*) app_data;
2463 
2464  if(appD->currAttr == S)
2465  {
2466  appD->data->eArray[appD->eIndex].s = value;
2467  }
2468  else
2469  return EXIP_HANDLER_STOP;
2470 
2471  return EXIP_OK;
2472 }
2473 
2474 static errorCode sample_intData(Integer int_val, void* app_data)
2475 {
2476  AppData* appD = (AppData*) app_data;
2477 
2478  switch(appD->currAttr)
2479  {
2480  case BT:
2481  appD->data->bt = int_val;
2482  break;
2483  case VER:
2484  appD->data->version = int_val;
2485  break;
2486  case T:
2487  appD->data->eArray[appD->eIndex].t = int_val;
2488  break;
2489  case UT:
2490  appD->data->eArray[appD->eIndex].ut = int_val;
2491  break;
2492  default:
2493  return EXIP_HANDLER_STOP;
2494  }
2495  return EXIP_OK;
2496 }
2497 
2498 #define E_ELEM_COUNT 7 // The number of e elems in the senML to be encoded is 7
2499 
2500 START_TEST (test_various_senml)
2501 {
2502  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
2503  char buf[OUTPUT_BUFFER_SIZE];
2504  char* schemafname[1] = {"exip/SenML-xsd.exi"};
2505  EXIPSchema schema;
2506  size_t exiSize = 0;
2507  senml_elem eArr[E_ELEM_COUNT];
2508  senml senML_instance;
2509  senml_elem eArrParsed[E_ELEM_COUNT];
2510  senml senMLParsed;
2511  int i;
2512 
2513  parseSchema(schemafname, 1, &schema);
2514 
2515  strcpy(senML_instance.bn, "urn:dev:mac:0024befffe804ff1");
2516  senML_instance.bt = 1415355691;
2517  senML_instance.version = 1;
2518  senML_instance.bu[0] = '\0';
2519  senML_instance.eArrayCount = E_ELEM_COUNT;
2520  senML_instance.eArraySize = E_ELEM_COUNT;
2521  senML_instance.eArray = eArr;
2522 
2523  // E elem 0
2524  strcpy(eArr[0].n, "pktid");
2525  strcpy(eArr[0].u, "count");
2526  eArr[0].v.mantissa = 1;
2527  eArr[0].v.exponent = 0;
2528 
2529  // E elem 1
2530  strcpy(eArr[1].n, "rpm");
2531  strcpy(eArr[1].u, "r/m");
2532  eArr[1].v.mantissa = 352;
2533  eArr[1].v.exponent = 0;
2534 
2535  // E elem 2
2536  strcpy(eArr[2].n, "rpm_av");
2537  strcpy(eArr[2].u, "r/m");
2538  eArr[2].v.mantissa = 352;
2539  eArr[2].v.exponent = 0;
2540 
2541  // E elem 3
2542  strcpy(eArr[3].n, "totrounds");
2543  strcpy(eArr[3].u, "count");
2544  eArr[3].v.mantissa = 461;
2545  eArr[3].v.exponent = 3; // 461000
2546 
2547  // E elem 4
2548  strcpy(eArr[4].n, "totrounds_r");
2549  strcpy(eArr[4].u, "count");
2550  eArr[4].v.mantissa = 0;
2551  eArr[4].v.exponent = 0;
2552 
2553  // E elem 5
2554  strcpy(eArr[5].n, "bearingtemp");
2555  strcpy(eArr[5].u, "Cel");
2556  eArr[5].v.mantissa = 454;
2557  eArr[5].v.exponent = -1; // 45.4
2558 
2559  // E elem 6
2560  strcpy(eArr[6].n, "rssi");
2561  strcpy(eArr[6].u, "%");
2562  eArr[6].v.mantissa = 9;
2563  eArr[6].v.exponent = 1; // 90
2564 
2565  // All the other fileds are set to N/A
2566  for(i = 0; i < E_ELEM_COUNT; i++)
2567  {
2568  eArr[i].bv = 5;
2569  eArr[i].s.exponent = INT16_MAX;
2570  eArr[i].sv[0] = '\0';
2571  eArr[i].t = INT_MAX;
2572  eArr[i].ut = INT_MAX;
2573  }
2574 
2575  tmp_err_code = encodeSenML(&schema, senML_instance, buf, OUTPUT_BUFFER_SIZE, &exiSize);
2576  fail_unless(tmp_err_code == EXIP_OK, "There is an error in the encoding of an EXI SenML stream");
2577  fail_unless(exiSize > 0, "Encoding SenML produces empty streams.");
2578 
2579  senMLParsed.eArray = eArrParsed;
2580  senMLParsed.bn[0] = '\0';
2581  senMLParsed.bt = LONG_MAX;
2582  senMLParsed.version = -1;
2583  senMLParsed.bu[0] = '\0';
2584  senMLParsed.eArrayCount = 0;
2585  senMLParsed.eArraySize = E_ELEM_COUNT;
2586  senMLParsed.eArray = eArr;
2587 
2588  for(i = 0; i < E_ELEM_COUNT; i++)
2589  {
2590  eArrParsed[i].n[0] = '\0';
2591  eArrParsed[i].u[0] = '\0';
2592  eArrParsed[i].v.exponent = INT16_MAX;
2593  eArrParsed[i].bv = 5;
2594  eArrParsed[i].s.exponent = INT16_MAX;
2595  eArrParsed[i].sv[0] = '\0';
2596  eArrParsed[i].t = INT_MAX;
2597  eArrParsed[i].ut = INT_MAX;
2598  }
2599 
2600  tmp_err_code = decodeSenML(&schema, buf, OUTPUT_BUFFER_SIZE, &senMLParsed);
2601  fail_unless(tmp_err_code == EXIP_OK, "There is an error in the decoding of an EXI SenML stream");
2602  fail_unless(!strcmp(senMLParsed.bn, senML_instance.bn), "SenML BN value error");
2603  fail_unless(senMLParsed.bt == senML_instance.bt, "SenML BT value error");
2604  fail_unless(senMLParsed.version == senML_instance.version, "SenML version value error");
2605 
2606  for(i = 0; i < senMLParsed.eArrayCount; i++)
2607  {
2608  fail_unless(!strcmp(senMLParsed.eArray[i].n, senML_instance.eArray[i].n), "SenML N value error");
2609  fail_unless(!strcmp(senMLParsed.eArray[i].u, senML_instance.eArray[i].u), "SenML U value error");
2610  fail_unless(senMLParsed.eArray[i].v.mantissa == senML_instance.eArray[i].v.mantissa, "SenML V value error");
2611  fail_unless(senMLParsed.eArray[i].v.exponent == senML_instance.eArray[i].v.exponent, "SenML V value error");
2612  }
2613 
2614 }
2615 END_TEST
2616 
2617 /* END: Schema-mode tests */
2618 
2619 /* Helper functions */
2620 static size_t writeFileOutputStream(void* buf, size_t readSize, void* stream)
2621 {
2622  FILE *outfile = (FILE*) stream;
2623  return fwrite(buf, 1, readSize, outfile);
2624 }
2625 
2626 static size_t readFileInputStream(void* buf, size_t readSize, void* stream)
2627 {
2628  FILE *infile = (FILE*) stream;
2629  return fread(buf, 1, readSize, infile);
2630 }
2631 
2632 static void parseSchema(char** xsdList, int count, EXIPSchema* schema)
2633 {
2634  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
2635  FILE *schemaFile;
2636  BinaryBuffer buffer[MAX_XSD_FILES_COUNT]; // up to 10 XSD files
2637  size_t pathlen = strlen(dataDir);
2638  char exipath[MAX_PATH_LEN + strlen(xsdList[0])];
2639  int i;
2640 
2641  for (i = 0; i < count; i++)
2642  {
2643  memcpy(exipath, dataDir, pathlen);
2644  exipath[pathlen] = '/';
2645  memcpy(&exipath[pathlen+1], xsdList[i], strlen(xsdList[i])+1);
2646  schemaFile = fopen(exipath, "rb" );
2647  if(!schemaFile)
2648  {
2649  fail("Unable to open file %s", exipath);
2650  return;
2651  }
2652  else
2653  {
2654  //Get file length
2655  fseek(schemaFile, 0, SEEK_END);
2656  buffer[i].bufLen = ftell(schemaFile) + 1;
2657  fseek(schemaFile, 0, SEEK_SET);
2658 
2659  //Allocate memory
2660  buffer[i].buf = (char *) malloc(buffer[i].bufLen);
2661  if (!buffer[i].buf)
2662  {
2663  fclose(schemaFile);
2664  fail("Memory allocation error!");
2665  }
2666 
2667  //Read file contents into buffer
2668  fread(buffer[i].buf, buffer[i].bufLen, 1, schemaFile);
2669  fclose(schemaFile);
2670 
2671  buffer[i].bufContent = buffer[i].bufLen;
2672  buffer[i].ioStrm.readWriteToStream = NULL;
2673  buffer[i].ioStrm.stream = NULL;
2674  }
2675  }
2676 
2677  // Generate the EXI grammars based on the schema information
2678  tmp_err_code = generateSchemaInformedGrammars(buffer, count, SCHEMA_FORMAT_XSD_EXI, NULL, schema, NULL);
2679 
2680  for(i = 0; i < count; i++)
2681  {
2682  free(buffer[i].buf);
2683  }
2684 
2685  if(tmp_err_code != EXIP_OK)
2686  {
2687  fail("\nGrammar generation error occurred: %d", tmp_err_code);
2688  }
2689 }
2690 
2691 
2693 {
2694  Suite *s = suite_create("EXIP");
2695  {
2696  /* Schema-less test case */
2697  TCase *tc_SchLess = tcase_create ("SchemaLess");
2698  tcase_add_test (tc_SchLess, test_default_options);
2699  tcase_add_test (tc_SchLess, test_fragment_option);
2700  tcase_add_test (tc_SchLess, test_value_part_zero);
2701  tcase_add_test (tc_SchLess, test_recursive_defs);
2702  tcase_add_test (tc_SchLess, test_built_in_dynamic_types);
2703  suite_add_tcase (s, tc_SchLess);
2704  }
2705  {
2706  /* Schema-mode test case */
2707  TCase *tc_Schema = tcase_create ("Schema-mode");
2708  tcase_add_test (tc_Schema, test_large_doc_str_pattern);
2709  tcase_add_test (tc_Schema, test_substitution_groups);
2710  tcase_add_test (tc_Schema, test_non_blocking_streaming);
2711  tcase_add_test (tc_Schema, test_non_blocking_streaming_bytealigned);
2712  tcase_add_test (tc_Schema, test_various_senml);
2713  suite_add_tcase (s, tc_Schema);
2714  }
2715 
2716  return s;
2717 }
2718 
2719 int main (int argc, char *argv[])
2720 {
2721  int number_failed;
2722  Suite *s = exip_suite();
2723  SRunner *sr = srunner_create (s);
2724 
2725  if (argc < 2)
2726  {
2727  printf("ERR: Expected test data directory\n");
2728  exit(1);
2729  }
2730  if (strlen(argv[1]) > MAX_PATH_LEN)
2731  {
2732  printf("ERR: Test data pathname too long: %u", (unsigned int) strlen(argv[1]));
2733  exit(1);
2734  }
2735 
2736  dataDir = argv[1];
2737 
2738 #ifdef _MSC_VER
2740 #endif
2741  srunner_run_all (sr, CK_NORMAL);
2742  number_failed = srunner_ntests_failed (sr);
2743  srunner_free (sr);
2744  return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
2745 }
2746