exip  Alpha 0.5.4
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
check_strict_grammar.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 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <check.h>
22 #include "EXISerializer.h"
23 #include "EXIParser.h"
24 #include "stringManipulate.h"
25 #include "grammarGenerator.h"
26 #include "memManagement.h"
27 
28 #define INPUT_BUFFER_SIZE 200
29 #define OUTPUT_BUFFER_SIZE 200
30 #define MAX_PATH_LEN 200
31 
32 /* Location for external test data */
33 static char *dataDir;
34 
35 struct appData
36 {
37  unsigned int eventCount;
38  unsigned short expectAttributeData;
43 };
44 typedef struct appData appData;
45 
46 /* Helper functions */
47 
48 size_t readFileInputStream(void* buf, size_t readSize, void* stream)
49 {
50  FILE *infile = (FILE*) stream;
51  return fread(buf, 1, readSize, infile);
52 }
53 
54 size_t writeFileOutputStream(void* buf, size_t readSize, void* stream)
55 {
56  FILE *outfile = (FILE*) stream;
57  return fwrite(buf, 1, readSize, outfile);
58 }
59 
60 static void parseSchema(const char* fileName, EXIPSchema* schema)
61 {
62  FILE *schemaFile;
63  BinaryBuffer buffer;
64  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
65  size_t pathlen = strlen(dataDir);
66  char exipath[MAX_PATH_LEN + strlen(fileName)];
67 
68  memcpy(exipath, dataDir, pathlen);
69  exipath[pathlen] = '/';
70  memcpy(&exipath[pathlen+1], fileName, strlen(fileName)+1);
71  schemaFile = fopen(exipath, "rb" );
72  if(!schemaFile)
73  {
74  fail("Unable to open file %s", exipath);
75  }
76  else
77  {
78  //Get file length
79  fseek(schemaFile, 0, SEEK_END);
80  buffer.bufLen = ftell(schemaFile) + 1;
81  fseek(schemaFile, 0, SEEK_SET);
82 
83  //Allocate memory
84  buffer.buf = (char *)malloc(buffer.bufLen);
85  if (!buffer.buf)
86  {
87  fclose(schemaFile);
88  fail("Memory allocation error!");
89  }
90 
91  //Read file contents into buffer
92  fread(buffer.buf, buffer.bufLen, 1, schemaFile);
93  fclose(schemaFile);
94 
95  buffer.bufContent = buffer.bufLen;
96  buffer.ioStrm.readWriteToStream = NULL;
97  buffer.ioStrm.stream = NULL;
98 
99  tmp_err_code = generateSchemaInformedGrammars(&buffer, 1, SCHEMA_FORMAT_XSD_EXI, NULL, schema, NULL);
100 
101  if(tmp_err_code != EXIP_OK)
102  {
103  fail("\n Error reading schema: %d", tmp_err_code);
104  }
105 
106  free(buffer.buf);
107  }
108 }
109 
110 
111 /* Document callbacks */
112 
113 static errorCode sample_fatalError(const errorCode code, const char* msg, void* app_data)
114 {
115  printf("\n%3d : FATAL ERROR: %s\n", code, msg);
116  return EXIP_HANDLER_STOP;
117 }
118 
119 static errorCode sample_startDocument(void* app_data)
120 {
121  appData* appD = (appData*) app_data;
122  asciiToString("SD", &appD->eventCode, &appD->allocList, TRUE);
123 
124  return EXIP_OK;
125 }
126 
127 static errorCode sample_endDocument(void* app_data)
128 {
129  appData* appD = (appData*) app_data;
130  asciiToString("ED", &appD->eventCode, &appD->allocList, TRUE);
131 
132  return EXIP_OK;
133 }
134 
135 static errorCode sample_startElement(QName qname, void* app_data)
136 {
137  appData* appD = (appData*) app_data;
138  asciiToString("SE", &appD->eventCode, &appD->allocList, TRUE);
139  cloneStringManaged(qname.uri, &appD->uri, &appD->allocList);
140  cloneStringManaged(qname.localName, &appD->localName, &appD->allocList);
141 
142  return EXIP_OK;
143 }
144 
145 static errorCode sample_endElement(void* app_data)
146 {
147  appData* appD = (appData*) app_data;
148  asciiToString("EE", &appD->eventCode, &appD->allocList, TRUE);
149 
150  return EXIP_OK;
151 }
152 
153 static errorCode sample_attribute(QName qname, void* app_data)
154 {
155  appData* appD = (appData*) app_data;
156  asciiToString("AT", &appD->eventCode, &appD->allocList, TRUE);
157 
158  /*
159  printString(qname.uri);
160  printf(" ");
161  printString(qname.localName);
162  printf("=\"");
163  */
164 
165  appD->expectAttributeData = 1;
166 
167  return EXIP_OK;
168 }
169 
170 static errorCode sample_stringData(const String value, void* app_data)
171 {
172  appData* appD = (appData*) app_data;
173  if(appD->expectAttributeData)
174  {
175  asciiToString("AT", &appD->eventCode, &appD->allocList, TRUE);
176  /*
177  printString(&value);
178  printf("\"\n");
179  */
180  appD->expectAttributeData = 0;
181  }
182  else
183  {
184  asciiToString("CH", &appD->eventCode, &appD->allocList, TRUE);
185  /*
186  printString(&value);
187  printf("\n");
188  */
189  }
190 
191  return EXIP_OK;
192 }
193 
194 static errorCode sample_decimalData(Decimal value, void* app_data)
195 {
196  appData* appD = (appData*) app_data;
197  if(appD->expectAttributeData)
198  {
199  asciiToString("AT", &appD->eventCode, &appD->allocList, TRUE);
200  /*
201  printf("%.1f\"\n", (double) value);
202  */
203  appD->expectAttributeData = 0;
204  }
205  else
206  {
207  asciiToString("CH", &appD->eventCode, &appD->allocList, TRUE);
208  }
209 
210  return EXIP_OK;
211 }
212 
213 static errorCode sample_intData(Integer int_val, void* app_data)
214 {
215  appData* appD = (appData*) app_data;
216  /* char tmp_buf[30]; */
217  if(appD->expectAttributeData)
218  {
219  asciiToString("AT", &appD->eventCode, &appD->allocList, TRUE);
220  /*
221  sprintf(tmp_buf, "%lld", int_val);
222  printf("%s", tmp_buf);
223  printf("\"\n");
224  */
225  appD->expectAttributeData = 0;
226  }
227  else
228  {
229  asciiToString("CH", &appD->eventCode, &appD->allocList, TRUE);
230  /*
231  sprintf(tmp_buf, "%lld", int_val);
232  printf("%s", tmp_buf);
233  printf("\n");
234  */
235  }
236 
237  return EXIP_OK;
238 }
239 
240 static errorCode sample_floatData(Float fl_val, void* app_data)
241 {
242  appData* appD = (appData*) app_data;
243  /* char tmp_buf[30]; */
244  if(appD->expectAttributeData)
245  {
246  asciiToString("AT", &appD->eventCode, &appD->allocList, TRUE);
247  /*
248  sprintf(tmp_buf, "%lldE%d", fl_val.mantissa, fl_val.exponent);
249  printf("%s", tmp_buf);
250  printf("\"\n");
251  */
252  appD->expectAttributeData = 0;
253  }
254  else
255  {
256  asciiToString("CH", &appD->eventCode, &appD->allocList, TRUE);
257  /*
258  printf("%3d CH ", appD->eventCount);
259  sprintf(tmp_buf, "%lldE%d", fl_val.mantissa, fl_val.exponent);
260  printf("%s", tmp_buf);
261  printf("\n");
262  */
263  }
264 
265  return EXIP_OK;
266 }
267 
268 /* Tests */
269 
270 /* Compares document structure, including minOccurs/maxOccurs. */
271 START_TEST (test_acceptance_for_A_01)
272 {
273  EXIPSchema schema;
274  FILE *infile;
275  Parser testParser;
276  char buf[INPUT_BUFFER_SIZE];
277  const char *schemafname = "testStates/acceptance-xsd.exi";
278  const char *exifname = "testStates/acceptance_a_01.exi";
279  char exipath[MAX_PATH_LEN + strlen(exifname)];
280  struct appData parsingData;
281  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
282  BinaryBuffer buffer;
283 
284  buffer.buf = buf;
285  buffer.bufContent = 0;
286  buffer.bufLen = INPUT_BUFFER_SIZE;
287 
288  // Parsing steps:
289 
290  // I.A: First, read in the schema
291  parseSchema(schemafname, &schema);
292 
293  // I.B: Define an external stream for the input to the parser if any
294  size_t pathlen = strlen(dataDir);
295  memcpy(exipath, dataDir, pathlen);
296  exipath[pathlen] = '/';
297  memcpy(&exipath[pathlen+1], exifname, strlen(exifname)+1);
298 
299  infile = fopen(exipath, "rb" );
300  if(!infile)
301  fail("Unable to open file %s", exipath);
302 
304  buffer.ioStrm.stream = infile;
305 
306  // II: Second, initialize the parser object
307  tmp_err_code = initParser(&testParser, buffer, &parsingData);
308  fail_unless (tmp_err_code == EXIP_OK, "initParser returns an error code %d", tmp_err_code);
309 
310  // III: Initialize the parsing data and hook the callback handlers to the parser object
311  parsingData.eventCount = 0;
312  parsingData.expectAttributeData = 0;
313  if (EXIP_OK != initAllocList(&parsingData.allocList))
314  fail("Memory allocation error!");
315 
316 
317  testParser.handler.fatalError = sample_fatalError;
318  testParser.handler.error = sample_fatalError;
319  testParser.handler.startDocument = sample_startDocument;
320  testParser.handler.endDocument = sample_endDocument;
321  testParser.handler.startElement = sample_startElement;
322  testParser.handler.attribute = sample_attribute;
323  testParser.handler.stringData = sample_stringData;
324  testParser.handler.endElement = sample_endElement;
325  testParser.handler.decimalData = sample_decimalData;
326  testParser.handler.intData = sample_intData;
327  testParser.handler.floatData = sample_floatData;
328 
329  // IV: Parse the header of the stream
330  tmp_err_code = parseHeader(&testParser, FALSE);
331  fail_unless (tmp_err_code == EXIP_OK, "parsing the header returns an error code %d", tmp_err_code);
332 
333  tmp_err_code = setSchema(&testParser, &schema);
334  fail_unless (tmp_err_code == EXIP_OK, "setSchema() returns an error code %d", tmp_err_code);
335  // V: Parse the body of the EXI stream
336  while(tmp_err_code == EXIP_OK)
337  {
338  switch (parsingData.eventCount)
339  {
340  case 0:
341  fail_unless(stringEqualToAscii(parsingData.eventCode, "SD"));
342  break;
343  case 1:
344  fail_unless(stringEqualToAscii(parsingData.eventCode, "SE"));
345  fail_unless(stringEqualToAscii(parsingData.uri, "urn:foo"));
346  fail_unless(stringEqualToAscii(parsingData.localName, "A"));
347  break;
348  case 2:
349  fail_unless(stringEqualToAscii(parsingData.eventCode, "SE"));
350  fail_unless(stringEqualToAscii(parsingData.uri, "urn:foo"));
351  fail_unless(stringEqualToAscii(parsingData.localName, "AB"));
352  break;
353  case 3:
354  fail_unless(stringEqualToAscii(parsingData.eventCode, "CH"));
355  break;
356  case 4:
357  fail_unless(stringEqualToAscii(parsingData.eventCode, "EE"));
358  break;
359  case 5:
360  fail_unless(stringEqualToAscii(parsingData.eventCode, "SE"));
361  fail_unless(stringEqualToAscii(parsingData.uri, "urn:foo"));
362  fail_unless(stringEqualToAscii(parsingData.localName, "AC"));
363  break;
364  case 6:
365  fail_unless(stringEqualToAscii(parsingData.eventCode, "CH"));
366  break;
367  case 7:
368  fail_unless(stringEqualToAscii(parsingData.eventCode, "EE"));
369  break;
370  case 8:
371  fail_unless(stringEqualToAscii(parsingData.eventCode, "SE"));
372  fail_unless(stringEqualToAscii(parsingData.uri, "urn:foo"));
373  fail_unless(stringEqualToAscii(parsingData.localName, "AC"));
374  break;
375  case 9:
376  fail_unless(stringEqualToAscii(parsingData.eventCode, "CH"));
377  break;
378  case 10:
379  fail_unless(stringEqualToAscii(parsingData.eventCode, "EE"));
380  break;
381  case 11:
382  fail_unless(stringEqualToAscii(parsingData.eventCode, "SE"));
383  fail_unless(stringEqualToAscii(parsingData.uri, "urn:foo"));
384  fail_unless(stringEqualToAscii(parsingData.localName, "AD"));
385  break;
386  case 12:
387  fail_unless(stringEqualToAscii(parsingData.eventCode, "CH"));
388  break;
389  case 13:
390  fail_unless(stringEqualToAscii(parsingData.eventCode, "EE"));
391  break;
392  case 14:
393  fail_unless(stringEqualToAscii(parsingData.eventCode, "SE"));
394  fail_unless(stringEqualToAscii(parsingData.uri, "urn:foo"));
395  fail_unless(stringEqualToAscii(parsingData.localName, "AE"));
396  break;
397  case 15:
398  fail_unless(stringEqualToAscii(parsingData.eventCode, "CH"));
399  break;
400  case 16:
401  fail_unless(stringEqualToAscii(parsingData.eventCode, "EE"));
402  break;
403  case 17:
404  fail_unless(stringEqualToAscii(parsingData.eventCode, "EE"));
405  break;
406  case 18:
407  fail_unless(stringEqualToAscii(parsingData.eventCode, "ED"));
408  break;
409  default:
410  // Unexpected event count caught below.
411  break;
412  }
413  tmp_err_code = parseNext(&testParser);
414 
415  parsingData.eventCount++;
416 
417  }
418 
419  fail_unless(stringEqualToAscii(parsingData.eventCode, "ED"));
420 
421  fail_unless(parsingData.eventCount == 18,
422  "Unexpected event count: %u", parsingData.eventCount);
423 
424  // VI: Free the memory allocated by the parser object
425  freeAllocList(&parsingData.allocList);
426  destroyParser(&testParser);
427  fclose(infile);
428  fail_unless (tmp_err_code == EXIP_PARSING_COMPLETE, "Error during parsing of the EXI body %d", tmp_err_code);
429 }
430 END_TEST
431 
432 /* Verifies a single global element also used as a reference. */
433 START_TEST (test_acceptance_for_A_01_exip1)
434 {
435  EXIPSchema schema;
436  FILE *infile;
437  Parser testParser;
438  char buf[INPUT_BUFFER_SIZE];
439  const char *schemafname = "testStates/acceptance-xsd.exi";
440  const char *exifname = "testStates/acceptance_a_01a.exi";
441  char exipath[MAX_PATH_LEN + strlen(exifname)];
442  struct appData parsingData;
443  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
444  BinaryBuffer buffer;
445 
446  buffer.buf = buf;
447  buffer.bufContent = 0;
448  buffer.bufLen = INPUT_BUFFER_SIZE;
449 
450  // Parsing steps:
451 
452  // I.A: First, read in the schema
453  parseSchema(schemafname, &schema);
454 
455  // I.B: Define an external stream for the input to the parser if any
456  size_t pathlen = strlen(dataDir);
457  memcpy(exipath, dataDir, pathlen);
458  exipath[pathlen] = '/';
459  memcpy(&exipath[pathlen+1], exifname, strlen(exifname)+1);
460 
461  infile = fopen(exipath, "rb" );
462  if(!infile)
463  fail("Unable to open file %s", exipath);
464 
466  buffer.ioStrm.stream = infile;
467 
468  // II: Second, initialize the parser object
469  tmp_err_code = initParser(&testParser, buffer, &parsingData);
470  fail_unless (tmp_err_code == EXIP_OK, "initParser returns an error code %d", tmp_err_code);
471 
472  // III: Initialize the parsing data and hook the callback handlers to the parser object
473  parsingData.eventCount = 0;
474  parsingData.expectAttributeData = 0;
475  if (EXIP_OK != initAllocList(&parsingData.allocList))
476  fail("Memory allocation error!");
477 
478  testParser.handler.fatalError = sample_fatalError;
479  testParser.handler.error = sample_fatalError;
480  testParser.handler.startDocument = sample_startDocument;
481  testParser.handler.endDocument = sample_endDocument;
482  testParser.handler.startElement = sample_startElement;
483  testParser.handler.attribute = sample_attribute;
484  testParser.handler.stringData = sample_stringData;
485  testParser.handler.endElement = sample_endElement;
486  testParser.handler.decimalData = sample_decimalData;
487  testParser.handler.intData = sample_intData;
488  testParser.handler.floatData = sample_floatData;
489 
490  // IV: Parse the header of the stream
491  tmp_err_code = parseHeader(&testParser, FALSE);
492  fail_unless (tmp_err_code == EXIP_OK, "parsing the header returns an error code %d", tmp_err_code);
493 
494  tmp_err_code = setSchema(&testParser, &schema);
495  fail_unless (tmp_err_code == EXIP_OK, "setSchema() returns an error code %d", tmp_err_code);
496 
497  // V: Parse the body of the EXI stream
498  while(tmp_err_code == EXIP_OK)
499  {
500  switch (parsingData.eventCount)
501  {
502  case 0:
503  fail_unless(stringEqualToAscii(parsingData.eventCode, "SD"));
504  break;
505  case 1:
506  fail_unless(stringEqualToAscii(parsingData.eventCode, "SE"));
507  fail_unless(stringEqualToAscii(parsingData.uri, "urn:foo"));
508  fail_unless(stringEqualToAscii(parsingData.localName, "AB"));
509  break;
510  case 2:
511  fail_unless(stringEqualToAscii(parsingData.eventCode, "CH"));
512  break;
513  case 3:
514  fail_unless(stringEqualToAscii(parsingData.eventCode, "EE"));
515  break;
516  case 4:
517  fail_unless(stringEqualToAscii(parsingData.eventCode, "ED"));
518  break;
519  default:
520  // Unexpected event count caught below.
521  break;
522  }
523 
524  tmp_err_code = parseNext(&testParser);
525  parsingData.eventCount++;
526  }
527 
528  fail_unless(stringEqualToAscii(parsingData.eventCode, "ED"));
529 
530  fail_unless(parsingData.eventCount == 4,
531  "Unexpected event count: %u", parsingData.eventCount);
532 
533  // VI: Free the memory allocated by the parser object
534  freeAllocList(&parsingData.allocList);
535  destroyParser(&testParser);
536  fclose(infile);
537  fail_unless (tmp_err_code == EXIP_PARSING_COMPLETE, "Error during parsing of the EXI body %d", tmp_err_code);
538 }
539 END_TEST
540 
541 /*
542  * Verifies error when more elements than schema maxOccurs permits. Attempts
543  * to encode:
544  *
545  * <A xmlns='urn:foo'>
546  * <AB/><AC/><AC/><AC/>
547  * </A>
548  */
549 START_TEST (test_acceptance_for_A_01b)
550 {
551  EXIPSchema schema;
552  EXIStream testStrm;
553  String uri;
554  String ln;
555  QName qname = {&uri, &ln, NULL};
556  char buf[OUTPUT_BUFFER_SIZE];
557  const char *schemafname = "testStates/acceptance-xsd.exi";
558  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
559  EXITypeClass valueType;
560 
561  const String NS_STR = {"urn:foo", 7};
562  const String ELEM_A = {"A", 1};
563  const String ELEM_AB = {"AB", 2};
564  const String ELEM_AC = {"AC", 2};
565  const String CH = {"", 0};
566 
567  BinaryBuffer buffer;
568  buffer.buf = buf;
569  buffer.bufLen = OUTPUT_BUFFER_SIZE;
570  buffer.bufContent = 0;
571 
572  // Serialization steps:
573 
574  // I.A: First, read in the schema
575  parseSchema(schemafname, &schema);
576 
577  // I: First initialize the header of the stream
578  serialize.initHeader(&testStrm);
579 
580  // II: Set any options in the header, if different from the defaults
581  testStrm.header.has_cookie = TRUE;
582  testStrm.header.has_options = TRUE;
583  testStrm.header.opts.valueMaxLength = 300;
584  testStrm.header.opts.valuePartitionCapacity = 50;
585  SET_STRICT(testStrm.header.opts.enumOpt);
586 
587  // III: Define an external stream for the output if any
588  buffer.ioStrm.readWriteToStream = NULL;
589  buffer.ioStrm.stream = NULL;
590 
591  // IV: Initialize the stream
592  tmp_err_code = serialize.initStream(&testStrm, buffer, &schema);
593  fail_unless (tmp_err_code == EXIP_OK, "initStream returns an error code %d", tmp_err_code);
594 
595  // V: Start building the stream step by step: header, document, element etc...
596  tmp_err_code += serialize.exiHeader(&testStrm);
597 
598  tmp_err_code += serialize.startDocument(&testStrm);
599 
600  qname.uri = &NS_STR;
601  qname.localName = &ELEM_A;
602  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType);
603  fail_unless (tmp_err_code == EXIP_OK, "serialization returns an error code %d", tmp_err_code);
604 
605  qname.localName = &ELEM_AB;
606  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType);
607  tmp_err_code += serialize.stringData(&testStrm, CH);
608  tmp_err_code += serialize.endElement(&testStrm);
609  fail_unless (tmp_err_code == EXIP_OK, "serialization returns an error code %d", tmp_err_code);
610 
611  qname.localName = &ELEM_AC;
612  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType);
613  tmp_err_code += serialize.stringData(&testStrm, CH);
614  tmp_err_code += serialize.endElement(&testStrm);
615  fail_unless (tmp_err_code == EXIP_OK, "serialization returns an error code %d", tmp_err_code);
616 
617  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType);
618  tmp_err_code += serialize.stringData(&testStrm, CH);
619  tmp_err_code += serialize.endElement(&testStrm);
620  fail_unless (tmp_err_code == EXIP_OK, "serialization returns an error code %d", tmp_err_code);
621 
622  /* Expect failure when start third AC element */
623  tmp_err_code += serialize.startElement(&testStrm, qname, &valueType);
624  fail_unless (tmp_err_code == EXIP_INCONSISTENT_PROC_STATE,
625  "Expected EXIP_INCONSISTENT_PROC_STATE, but returns an error code %d", tmp_err_code);
626 
627  // VI: Free the memory allocated by the EXI stream object
628  tmp_err_code = serialize.closeEXIStream(&testStrm);
629 }
630 END_TEST
631 
632 /* START THE LKAB DEMO SUIT*/
633 /**********************************************************************/
634 /**********************************************************************/
635 /**********************************************************************/
636 /**********************************************************************/
637 typedef char error_code; // 0 - OK; Error otherwise
638 
639 struct timestamp
640 {
641  unsigned int year;
642  unsigned int month;
643  unsigned int mday;
644  unsigned int hour;
645  unsigned int min;
646  unsigned int sec;
647  unsigned int msec;
648 };
649 
650 typedef struct timestamp Timestamp;
651 
653 {
654  Bool =0,
655  Long =1
656 };
657 
658 typedef enum ValueType ValueType;
659 
660 enum Quality {
661  Good =0,
663 
669 
670  Bad =7,
678 };
679 
680 typedef enum Quality Quality;
681 
682 struct boolValue
683 {
685  Quality quality;
686  unsigned char val;
687 };
688 
689 typedef struct boolValue BoolValue;
690 
692 {
693  char name[50];
694  ValueType type;
695  unsigned char isReadOnly; // boolean
696  char description[150];
697 };
698 
700 
702 {
703  char id[50];
704  char name[50];
705  char type[50];
706  char location[100];
708 };
709 
711 
712 extern const EXISerializer serialize;
713 
714 const String NS_STR = {"http://imc-aesop.eu/lkab-demo", 29};
715 const String NS_EMPTY_STR = {NULL, 0};
716 
717 const String ELEM_BOOL_VAL_STR = {"BoolValue", 9};
718 const String ELEM_QUAL_STR = {"quality", 7};
719 const String ELEM_TIMESTAMP_STR = {"timestamp", 9};
720 const String ELEM_VALUE_STR = {"value", 5};
721 
722 const String ELEM_DEV_DESC_STR = {"DeviceDescription", 17};
723 const String ELEM_ID_STR = {"id", 2};
724 const String ELEM_NAME_STR = {"name", 4};
725 const String ELEM_TYPE_STR = {"type", 4};
726 
727 const String ELEM_LOCATION_STR = {"location", 8};
728 const String ELEM_PROSS_VAL_STR = {"processValues", 13};
729 const String ELEM_IS_READONLY_STR = {"isReadOnly", 10};
730 const String ELEM_DESC_STR = {"description", 11};
731 
732 static String ENUM_DATA_QUALITY[] = {{"Good", 4},
733  {"Good_LocalOverride", 18},
734  {"Uncertain", 9},
735  {"Uncertain_LastUsable", 20},
736  {"Uncertain_SensorCal", 19},
737  {"Uncertain_EGUExeeded", 20},
738  {"Uncertain_SubNormal", 19},
739  {"Bad", 3},
740  {"Bad_ConfigError", 15},
741  {"Bad_NotConnected", 16},
742  {"Bad_DeviceFailure", 17},
743  {"Bad_SensorFailure", 17},
744  {"Bad_CommFailureLastKnownAvailable", 33},
745  {"Bad_CommFailure", 15},
746  {"Bad_OutOfService", 16}};
747 
748 static String ENUM_DATA_VAL_TYPE[] = {{"Bool", 4},
749  {"Long", 4}};
750 
752 {
755  unsigned int currElementNumber;
756 };
757 
758 // Content Handler API
759 static errorCode lkab_fatalError(const errorCode code, const char* msg, void* app_data);
760 static errorCode lkab_startElement_io(QName qname, void* app_data);
761 static errorCode lkab_startElement_desc(QName qname, void* app_data);
762 static errorCode lkab_endElement(void* app_data);
763 static errorCode lkab_stringData_io(const String value, void* app_data);
764 static errorCode lkab_stringData_desc(const String value, void* app_data);
765 static errorCode lkab_booleanData_io(boolean bool_val, void* app_data);
766 static errorCode lkab_booleanData_desc(boolean bool_val, void* app_data);
767 static errorCode lkab_dateTimeData(EXIPDateTime dt_val, void* app_data);
768 
777 static error_code parseIOMsg(char* buf, unsigned int buf_size, BoolValue *val);
778 
787 static error_code parseDevDescMsg(char* buf, unsigned int buf_size, DevDescribtion* devDesc);
788 
798 static error_code serializeIOMsg(char* buf, unsigned int buf_size, unsigned int* msg_size, BoolValue val);
799 
809 static error_code serializeDevDescMsg(char* buf, unsigned int buf_size, unsigned int* msg_size, DevDescribtion devDesc);
810 
811 
812 static error_code serializeIOMsg(char* buf, unsigned int buf_size, unsigned int* msg_size, BoolValue val)
813 {
814  EXIStream strm;
815  String uri;
816  String ln;
817  QName qname = {&uri, &ln, NULL};
818  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
819  BinaryBuffer buffer;
820  EXIPDateTime dt;
821  EXIPSchema lkab_schema;
822  const char *schemafname = "SchemaStrict/lkab-devices-xsd.exi";
823  EXITypeClass valueType;
824 
825  buffer.buf = buf;
826  buffer.bufLen = buf_size;
827  buffer.bufContent = 0;
828 
829  // Serialization steps:
830 
831  // I.A: First, read in the schema
832  parseSchema(schemafname, &lkab_schema);
833 
834  // I: First initialize the header of the stream
835  serialize.initHeader(&strm);
836 
837  // II: Set any options in the header, if different from the defaults
838  strm.header.has_options = TRUE;
840 
841  // III: Define an external stream for the output if any
842  buffer.ioStrm.stream = NULL;
843  buffer.ioStrm.readWriteToStream = NULL;
844 
845  // IV: Initialize the stream
846  tmp_err_code = serialize.initStream(&strm, buffer, &lkab_schema);
847  if(tmp_err_code != EXIP_OK)
848  return tmp_err_code;
849 
850  // V: Start building the stream step by step: header, document, element etc...
851  tmp_err_code += serialize.exiHeader(&strm);
852 
853  tmp_err_code += serialize.startDocument(&strm);
854 
855  qname.uri = &NS_STR;
856  qname.localName = &ELEM_BOOL_VAL_STR;
857  tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <BoolValue>
858 
859  qname.uri = &NS_STR;
860  qname.localName = &ELEM_TIMESTAMP_STR;
861  tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <timeStamp>
862 
864 
865  dt.dateTime.tm_year = val.ts.year;
866  dt.dateTime.tm_mon = val.ts.month;
867  dt.dateTime.tm_mday = val.ts.mday;
868  dt.dateTime.tm_hour = val.ts.hour;
869  dt.dateTime.tm_min = val.ts.min;
870  dt.dateTime.tm_sec = val.ts.sec;
871  dt.fSecs.value = val.ts.msec;
872  dt.fSecs.offset = 2;
873 
874  tmp_err_code += serialize.dateTimeData(&strm, dt);
875 
876  tmp_err_code += serialize.endElement(&strm); // </timeStamp>
877 
878  qname.uri = &NS_STR;
879  qname.localName = &ELEM_QUAL_STR;
880  tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <quality>
881 
882  tmp_err_code += serialize.stringData(&strm, ENUM_DATA_QUALITY[val.quality]); // quality
883 
884  tmp_err_code += serialize.endElement(&strm); // </quality>
885 
886  qname.uri = &NS_STR;
887  qname.localName = &ELEM_VALUE_STR;
888  tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <value>
889 
890  tmp_err_code += serialize.booleanData(&strm, val.val);
891 
892  tmp_err_code += serialize.endElement(&strm); // </value>
893 
894  tmp_err_code += serialize.endElement(&strm); // </BoolValue>
895 
896  tmp_err_code += serialize.endDocument(&strm);
897 
898  if(tmp_err_code != EXIP_OK)
899  return tmp_err_code;
900 
901  *msg_size = strm.context.bufferIndx + 1;
902 
903  // VI: Free the memory allocated by the EXI stream object
904  tmp_err_code = serialize.closeEXIStream(&strm);
905 
906  return EXIP_OK;
907 }
908 
909 static error_code serializeDevDescMsg(char* buf, unsigned int buf_size, unsigned int* msg_size, DevDescribtion devDesc)
910 {
911  EXIStream strm;
912  String uri;
913  String ln;
914  String ch;
915  QName qname = {&uri, &ln, NULL};
916  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
917  BinaryBuffer buffer;
918  EXIPSchema lkab_schema;
919  const char *schemafname = "SchemaStrict/lkab-devices-xsd.exi";
920  EXITypeClass valueType;
921 
922  buffer.buf = buf;
923  buffer.bufLen = buf_size;
924  buffer.bufContent = 0;
925 
926  // Serialization steps:
927 
928  // I.A: First, read in the schema
929  parseSchema(schemafname, &lkab_schema);
930 
931  // I: First initialize the header of the stream
932  serialize.initHeader(&strm);
933 
934  // II: Set any options in the header, if different from the defaults
935  strm.header.has_options = TRUE;
937 
938  // III: Define an external stream for the output if any
939  buffer.ioStrm.stream = NULL;
940  buffer.ioStrm.readWriteToStream = NULL;
941 
942  // IV: Initialize the stream
943  tmp_err_code = serialize.initStream(&strm, buffer, &lkab_schema);
944  if(tmp_err_code != EXIP_OK)
945  return tmp_err_code;
946 
947  // V: Start building the stream step by step: header, document, element etc...
948  tmp_err_code += serialize.exiHeader(&strm);
949 
950  tmp_err_code += serialize.startDocument(&strm);
951 
952  qname.uri = &NS_STR;
953  qname.localName = &ELEM_DEV_DESC_STR;
954  tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <DeviceDescription>
955 
956  qname.uri = &NS_STR;
957  qname.localName = &ELEM_ID_STR;
958  tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <id>
959 
960  ch.str = devDesc.id;
961  ch.length = strlen(devDesc.id);
962  tmp_err_code += serialize.stringData(&strm, ch); // device id
963 
964  tmp_err_code += serialize.endElement(&strm); // </id>
965 
966  qname.uri = &NS_STR;
967  qname.localName = &ELEM_NAME_STR;
968  tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <name>
969 
970  ch.str = devDesc.name;
971  ch.length = strlen(devDesc.name);
972  tmp_err_code += serialize.stringData(&strm, ch); // device name
973 
974  tmp_err_code += serialize.endElement(&strm); // </name>
975 
976  qname.uri = &NS_STR;
977  qname.localName = &ELEM_TYPE_STR;
978  tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <type>
979 
980  ch.str = devDesc.type;
981  ch.length = strlen(devDesc.type);
982  tmp_err_code += serialize.stringData(&strm, ch); // device type
983 
984  tmp_err_code += serialize.endElement(&strm); // </type>
985 
986  qname.uri = &NS_STR;
987  qname.localName = &ELEM_LOCATION_STR;
988  tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <location>
989 
990  ch.str = devDesc.location;
991  ch.length = strlen(devDesc.location);
992  tmp_err_code += serialize.stringData(&strm, ch); // device location
993 
994  tmp_err_code += serialize.endElement(&strm); // </location>
995 
996  qname.uri = &NS_STR;
997  qname.localName = &ELEM_PROSS_VAL_STR;
998  tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <processValues>
999 
1000  qname.uri = &NS_STR;
1001  qname.localName = &ELEM_NAME_STR;
1002  tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <name>
1003 
1004  ch.str = devDesc.processValue.name;
1005  ch.length = strlen(devDesc.processValue.name);
1006  tmp_err_code += serialize.stringData(&strm, ch); // processValues name
1007 
1008  tmp_err_code += serialize.endElement(&strm); // </name>
1009 
1010  qname.uri = &NS_STR;
1011  qname.localName = &ELEM_TYPE_STR;
1012  tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <type>
1013 
1014  tmp_err_code += serialize.stringData(&strm, ENUM_DATA_VAL_TYPE[devDesc.processValue.type]); // processValues type
1015 
1016  tmp_err_code += serialize.endElement(&strm); // </type>
1017 
1018  qname.uri = &NS_STR;
1020  tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <isReadOnly>
1021 
1022  tmp_err_code += serialize.booleanData(&strm, 0); // processValues isReadOnly
1023 
1024  tmp_err_code += serialize.endElement(&strm); // </isReadOnly>
1025 
1026  qname.uri = &NS_STR;
1027  qname.localName = &ELEM_DESC_STR;
1028  tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <description>
1029 
1030  ch.str = devDesc.processValue.description;
1031  ch.length = strlen(devDesc.processValue.description);
1032  tmp_err_code += serialize.stringData(&strm, ch); // processValues description
1033 
1034  tmp_err_code += serialize.endElement(&strm); // </description>
1035 
1036  tmp_err_code += serialize.endElement(&strm); // </processValues>
1037 
1038  tmp_err_code += serialize.endElement(&strm); // </DeviceDescription>
1039 
1040  tmp_err_code += serialize.endDocument(&strm);
1041 
1042  if(tmp_err_code != EXIP_OK)
1043  return tmp_err_code;
1044 
1045  *msg_size = strm.context.bufferIndx + 1;
1046 
1047  // VI: Free the memory allocated by the EXI stream object
1048  tmp_err_code = serialize.closeEXIStream(&strm);
1049 
1050  return EXIP_OK;
1051 }
1052 
1053 static error_code parseIOMsg(char* buf, unsigned int buf_size, BoolValue *val)
1054 {
1055  Parser lkabParser;
1056  BinaryBuffer buffer;
1057  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
1058  struct appDataLKAB parsingData;
1059  EXIPSchema lkab_schema;
1060  const char *schemafname = "SchemaStrict/lkab-devices-xsd.exi";
1061 
1062  buffer.buf = buf;
1063  buffer.bufLen = buf_size;
1064  buffer.bufContent = buf_size;
1065  // Parsing steps:
1066 
1067  // I.A: First, read in the schema
1068  parseSchema(schemafname, &lkab_schema);
1069 
1070  // I: First, define an external stream for the input to the parser if any
1071  buffer.ioStrm.stream = NULL;
1072 
1073  // II: Second, initialize the parser object
1074  tmp_err_code = initParser(&lkabParser, buffer, &parsingData);
1075  if(tmp_err_code != EXIP_OK)
1076  return tmp_err_code;
1077 
1078  // III: Initialize the parsing data and hook the callback handlers to the parser object
1079 
1080  parsingData.currElementNumber = 0;
1081  parsingData.val.quality = Good;
1082  parsingData.val.val = 0;
1083  parsingData.val.ts.year = 0;
1084  parsingData.val.ts.month = 0;
1085  parsingData.val.ts.mday = 0;
1086  parsingData.val.ts.hour = 0;
1087  parsingData.val.ts.min = 0;
1088  parsingData.val.ts.sec = 0;
1089  parsingData.val.ts.msec = 0;
1090 
1091  lkabParser.handler.fatalError = lkab_fatalError;
1092  lkabParser.handler.error = lkab_fatalError;
1093  lkabParser.handler.startElement = lkab_startElement_io;
1094  lkabParser.handler.stringData = lkab_stringData_io;
1095  lkabParser.handler.endElement = lkab_endElement;
1096  lkabParser.handler.booleanData = lkab_booleanData_io;
1097  lkabParser.handler.dateTimeData = lkab_dateTimeData;
1098 
1099  // IV: Parse the header of the stream
1100 
1101  tmp_err_code = parseHeader(&lkabParser, FALSE);
1102 
1103  tmp_err_code = setSchema(&lkabParser, &lkab_schema);
1104  // V: Parse the body of the EXI stream
1105 
1106  while(tmp_err_code == EXIP_OK)
1107  {
1108  tmp_err_code = parseNext(&lkabParser);
1109  }
1110 
1111  // VI: Free the memory allocated by the parser object
1112 
1113  destroyParser(&lkabParser);
1114 
1115  val->ts = parsingData.val.ts;
1116  val->val = parsingData.val.val;
1117  val->quality = parsingData.val.quality;
1118 
1119  if(tmp_err_code == EXIP_PARSING_COMPLETE)
1120  return EXIP_OK;
1121  else
1122  return tmp_err_code;
1123 }
1124 
1125 static error_code parseDevDescMsg(char* buf, unsigned int buf_size, DevDescribtion* devDesc)
1126 {
1127  Parser lkabParser;
1128  BinaryBuffer buffer;
1129  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
1130  struct appDataLKAB parsingData;
1131  EXIPSchema lkab_schema;
1132  const char *schemafname = "SchemaStrict/lkab-devices-xsd.exi";
1133 
1134  buffer.buf = buf;
1135  buffer.bufLen = buf_size;
1136  buffer.bufContent = buf_size;
1137 
1138  // Parsing steps:
1139 
1140  // I.A: First, read in the schema
1141  parseSchema(schemafname, &lkab_schema);
1142 
1143  // I: First, define an external stream for the input to the parser if any
1144  buffer.ioStrm.stream = NULL;
1145 
1146  // II: Second, initialize the parser object
1147  tmp_err_code = initParser(&lkabParser, buffer, &parsingData);
1148  if(tmp_err_code != EXIP_OK)
1149  return tmp_err_code;
1150 
1151  // III: Initialize the parsing data and hook the callback handlers to the parser object
1152 
1153  parsingData.currElementNumber = 0;
1154  parsingData.devDesc.id[0] = '\0';
1155  parsingData.devDesc.location[0] = '\0';
1156  parsingData.devDesc.name[0] = '\0';
1157  parsingData.devDesc.type[0] = '\0';
1158  parsingData.devDesc.processValue.description[0] = '\0';
1159  parsingData.devDesc.processValue.name[0] = '\0';
1160  parsingData.devDesc.processValue.isReadOnly = 0;
1161  parsingData.devDesc.processValue.type = Bool;
1162 
1163  lkabParser.handler.fatalError = lkab_fatalError;
1164  lkabParser.handler.error = lkab_fatalError;
1165  lkabParser.handler.startElement = lkab_startElement_desc;
1166  lkabParser.handler.stringData = lkab_stringData_desc;
1167  lkabParser.handler.endElement = lkab_endElement;
1168  lkabParser.handler.booleanData = lkab_booleanData_desc;
1169 
1170  // IV: Parse the header of the stream
1171 
1172  tmp_err_code = parseHeader(&lkabParser, FALSE);
1173 
1174  tmp_err_code = setSchema(&lkabParser, &lkab_schema);
1175  // V: Parse the body of the EXI stream
1176 
1177  while(tmp_err_code == EXIP_OK)
1178  {
1179  tmp_err_code = parseNext(&lkabParser);
1180  }
1181 
1182  // VI: Free the memory allocated by the parser object
1183 
1184  destroyParser(&lkabParser);
1185 
1186  strcpy(devDesc->id, parsingData.devDesc.id);
1187  strcpy(devDesc->location, parsingData.devDesc.location);
1188  strcpy(devDesc->name, parsingData.devDesc.name);
1189  strcpy(devDesc->type, parsingData.devDesc.type);
1190  strcpy(devDesc->processValue.description, parsingData.devDesc.processValue.description);
1191  strcpy(devDesc->processValue.name, parsingData.devDesc.processValue.name);
1192  devDesc->processValue.isReadOnly = parsingData.devDesc.processValue.isReadOnly;
1193  devDesc->processValue.type = parsingData.devDesc.processValue.type;
1194 
1195  if(tmp_err_code == EXIP_PARSING_COMPLETE)
1196  return EXIP_OK;
1197  else
1198  return tmp_err_code;
1199 }
1200 
1201 static errorCode lkab_fatalError(const errorCode code, const char* msg, void* app_data)
1202 {
1203  return EXIP_HANDLER_STOP;
1204 }
1205 
1206 static errorCode lkab_startElement_io(QName qname, void* app_data)
1207 {
1208  struct appDataLKAB* appD = (struct appDataLKAB*) app_data;
1209  QName expectedElem;
1210 
1211  appD->currElementNumber += 1;
1212 
1213  expectedElem.uri = &NS_STR;
1214  switch(appD->currElementNumber)
1215  {
1216  case 1:
1217  expectedElem.localName = &ELEM_BOOL_VAL_STR;
1218  break;
1219  case 2:
1220  expectedElem.localName = &ELEM_TIMESTAMP_STR;
1221  break;
1222  case 3:
1223  expectedElem.localName = &ELEM_QUAL_STR;
1224  break;
1225  case 4:
1226  expectedElem.localName = &ELEM_VALUE_STR;
1227  break;
1228  default:
1229  return EXIP_HANDLER_STOP;
1230  break;
1231  }
1232 
1233  if(!stringEqual(*expectedElem.uri, *(qname.uri)) ||
1234  !stringEqual(*expectedElem.localName, *(qname.localName)))
1235  {
1236  return EXIP_HANDLER_STOP;
1237  }
1238 
1239  return EXIP_OK;
1240 }
1241 
1242 static errorCode lkab_startElement_desc(QName qname, void* app_data)
1243 {
1244  struct appDataLKAB* appD = (struct appDataLKAB*) app_data;
1245  QName expectedElem;
1246 
1247  appD->currElementNumber += 1;
1248 
1249  expectedElem.uri = &NS_STR;
1250  switch(appD->currElementNumber)
1251  {
1252  case 1:
1253  expectedElem.localName = &ELEM_DEV_DESC_STR;
1254  break;
1255  case 2:
1256  expectedElem.localName = &ELEM_ID_STR;
1257  break;
1258  case 3:
1259  expectedElem.localName = &ELEM_NAME_STR;
1260  break;
1261  case 4:
1262  expectedElem.localName = &ELEM_TYPE_STR;
1263  break;
1264  case 5:
1265  expectedElem.localName = &ELEM_LOCATION_STR;
1266  break;
1267  case 6:
1268  expectedElem.localName = &ELEM_PROSS_VAL_STR;
1269  break;
1270  case 7:
1271  expectedElem.localName = &ELEM_NAME_STR;
1272  break;
1273  case 8:
1274  expectedElem.localName = &ELEM_TYPE_STR;
1275  break;
1276  case 9:
1277  expectedElem.localName = &ELEM_IS_READONLY_STR;
1278  break;
1279  case 10:
1280  expectedElem.localName = &ELEM_DESC_STR;
1281  break;
1282  default:
1283  return EXIP_HANDLER_STOP;
1284  break;
1285  }
1286 
1287  if(!stringEqual(*expectedElem.uri, *(qname.uri)) ||
1288  !stringEqual(*expectedElem.localName, *(qname.localName)))
1289  {
1290  return EXIP_HANDLER_STOP;
1291  }
1292 
1293  return EXIP_OK;
1294 }
1295 
1296 static errorCode lkab_endElement(void* app_data)
1297 {
1298  return EXIP_OK;
1299 }
1300 
1301 static errorCode lkab_stringData_io(const String value, void* app_data)
1302 {
1303  struct appDataLKAB* appD = (struct appDataLKAB*) app_data;
1304 
1305  if(appD->currElementNumber != 3)
1306  return EXIP_HANDLER_STOP;
1307  else
1308  {
1309  int i;
1310  for(i = 0; i < 15; i++)
1311  {
1312  if(stringEqual(ENUM_DATA_QUALITY[i], value))
1313  {
1314  appD->val.quality = i;
1315  return EXIP_OK;
1316  }
1317  }
1318  return EXIP_HANDLER_STOP;
1319  }
1320 }
1321 
1322 static errorCode lkab_stringData_desc(const String value, void* app_data)
1323 {
1324  struct appDataLKAB* appD = (struct appDataLKAB*) app_data;
1325 
1326  switch(appD->currElementNumber)
1327  {
1328  case 2:
1329  memcpy(appD->devDesc.id, value.str, sizeof(CharType)*value.length);
1330  appD->devDesc.id[value.length] = '\0';
1331  break;
1332  case 3:
1333  memcpy(appD->devDesc.name, value.str, sizeof(CharType)*value.length);
1334  appD->devDesc.name[value.length] = '\0';
1335  break;
1336  case 4:
1337  memcpy(appD->devDesc.type, value.str, sizeof(CharType)*value.length);
1338  appD->devDesc.type[value.length] = '\0';
1339  break;
1340  case 5:
1341  memcpy(appD->devDesc.location, value.str, sizeof(CharType)*value.length);
1342  appD->devDesc.location[value.length] = '\0';
1343  break;
1344  case 7:
1345  memcpy(appD->devDesc.processValue.name, value.str, sizeof(CharType)*value.length);
1346  appD->devDesc.processValue.name[value.length] = '\0';
1347  break;
1348  case 8:
1349  if(stringEqual(value, ENUM_DATA_VAL_TYPE[Bool]))
1350  appD->devDesc.processValue.type = Bool;
1351  else if(stringEqual(value, ENUM_DATA_VAL_TYPE[Long]))
1352  appD->devDesc.processValue.type = Long;
1353  else
1354  return EXIP_HANDLER_STOP;
1355  break;
1356  case 10:
1357  memcpy(appD->devDesc.processValue.description, value.str, sizeof(CharType)*value.length);
1358  appD->devDesc.processValue.description[value.length] = '\0';
1359  break;
1360  default:
1361  return EXIP_HANDLER_STOP;
1362  break;
1363  }
1364 
1365  return EXIP_OK;
1366 }
1367 
1368 static errorCode lkab_booleanData_io(boolean bool_val, void* app_data)
1369 {
1370  struct appDataLKAB* appD = (struct appDataLKAB*) app_data;
1371 
1372  if(appD->currElementNumber != 4)
1373  return EXIP_HANDLER_STOP;
1374  else
1375  {
1376  appD->val.val = bool_val;
1377  }
1378 
1379  return EXIP_OK;
1380 }
1381 
1382 static errorCode lkab_booleanData_desc(boolean bool_val, void* app_data)
1383 {
1384  struct appDataLKAB* appD = (struct appDataLKAB*) app_data;
1385 
1386  if(appD->currElementNumber != 9)
1387  return EXIP_HANDLER_STOP;
1388  else
1389  {
1390  appD->devDesc.processValue.isReadOnly = bool_val;
1391  }
1392 
1393  return EXIP_OK;
1394 }
1395 
1396 static errorCode lkab_dateTimeData(EXIPDateTime dt_val, void* app_data)
1397 {
1398  struct appDataLKAB* appD = (struct appDataLKAB*) app_data;
1399 
1400  appD->val.ts.year = dt_val.dateTime.tm_year;
1401  appD->val.ts.month = dt_val.dateTime.tm_mon;
1402  appD->val.ts.mday = dt_val.dateTime.tm_mday;
1403  appD->val.ts.hour = dt_val.dateTime.tm_hour;
1404  appD->val.ts.min = dt_val.dateTime.tm_min;
1405  appD->val.ts.sec = dt_val.dateTime.tm_sec;
1406  appD->val.ts.msec = dt_val.fSecs.value;
1407 
1408  return EXIP_OK;
1409 }
1410 
1411 #define LKAB_BUFFER_SIZE 1000
1412 
1413 START_TEST (test_lkab_demo_suit)
1414 {
1415  char lkab_buf[LKAB_BUFFER_SIZE];
1416  unsigned int msg_size;
1417  BoolValue bVal;
1418  DevDescribtion devD;
1419  error_code err;
1420 
1421  memset(lkab_buf, '\0', LKAB_BUFFER_SIZE);
1422 
1423  bVal.ts.hour = 0;
1424  bVal.ts.mday = 0;
1425  bVal.ts.min = 10;
1426  bVal.ts.month = 0;
1427  bVal.ts.msec = 115;
1428  bVal.ts.sec = 10;
1429  bVal.ts.year = 0;
1430  bVal.quality = Good;
1431  bVal.val = 1;
1432 
1433  err = serializeIOMsg(lkab_buf, LKAB_BUFFER_SIZE, &msg_size, bVal);
1434 
1435  fail_unless (err == EXIP_OK, "Error during serialization of IO Msg %d", err);
1436  fail_if(msg_size == 0, "0 Length message size");
1437 
1438  bVal.ts.hour = 10;
1439  bVal.ts.mday = 30;
1440  bVal.ts.min = 120;
1441  bVal.ts.month = 44;
1442  bVal.ts.msec = 125;
1443  bVal.ts.sec = 110;
1444  bVal.ts.year = 4;
1445  bVal.val = 0;
1446  bVal.quality = Bad;
1447 
1448  err = parseIOMsg(lkab_buf, LKAB_BUFFER_SIZE, &bVal);
1449 
1450  fail_unless (err == EXIP_OK, "Error during parsing of IO Msg %d", err);
1451  fail_unless (bVal.quality == Good, "quality not correct");
1452  fail_unless (bVal.val == 1, "value not correct");
1453  fail_unless (bVal.ts.min == 10, "min not correct");
1454  fail_unless (bVal.ts.sec == 10, "sec not correct");
1455  fail_unless (bVal.ts.msec == 115, "msec not correct");
1456 
1457  strcpy(devD.id, "AirPS");
1458  strcpy(devD.location, "Grate Support Shaft");
1459  strcpy(devD.name, "Pressure switch");
1460  strcpy(devD.type, "Air pressure switch");
1461  strcpy(devD.processValue.description, "This is an Air pressure switch ON/OFF value");
1462  strcpy(devD.processValue.name, "Air pressure switch ON/OFF");
1463  devD.processValue.isReadOnly = 0;
1464  devD.processValue.type = Bool;
1465 
1466  err = serializeDevDescMsg(lkab_buf, LKAB_BUFFER_SIZE, &msg_size, devD);
1467 
1468  fail_unless (err == EXIP_OK, "Error during serialization of DevDesc Msg %d", err);
1469  fail_if(msg_size == 0, "0 Length message size");
1470 
1471  strcpy(devD.id, "00000000000");
1472  strcpy(devD.location, "00000000000");
1473  strcpy(devD.name, "00000000000");
1474  strcpy(devD.type, "00000000000");
1475  strcpy(devD.processValue.description, "00000000000");
1476  strcpy(devD.processValue.name, "00000000000");
1477  devD.processValue.isReadOnly = 1;
1478  devD.processValue.type = Long;
1479 
1480  err = parseDevDescMsg(lkab_buf, LKAB_BUFFER_SIZE, &devD);
1481 
1482  fail_unless (err == EXIP_OK, "Error during parsing of DevDesc Msg %d", err);
1483  fail_unless (devD.processValue.isReadOnly == 0, "isReadOnly not correct");
1484  fail_unless (devD.processValue.type == Bool, "type not correct");
1485  fail_unless (strcmp(devD.id, "AirPS") == 0, "id not correct");
1486  fail_unless (strcmp(devD.location, "Grate Support Shaft") == 0, "location not correct");
1487  fail_unless (strcmp(devD.name, "Pressure switch") == 0, "name not correct");
1488  fail_unless (strcmp(devD.type, "Air pressure switch") == 0, "type not correct");
1489  fail_unless (strcmp(devD.processValue.description, "This is an Air pressure switch ON/OFF value") == 0, "description not correct");
1490  fail_unless (strcmp(devD.processValue.name, "Air pressure switch ON/OFF") == 0, "name not correct");
1491 }
1492 END_TEST
1493 /**********************************************************************/
1494 /**********************************************************************/
1495 /* END THE LKAB DEMO SUIT*/
1496 
1497 /* Test suite */
1498 
1500 {
1501  Suite *s = suite_create("Strict Grammar");
1502 
1503  {
1504  TCase *tc_builtin = tcase_create ("Strict Grammar");
1505  tcase_add_test (tc_builtin, test_acceptance_for_A_01);
1506  tcase_add_test (tc_builtin, test_acceptance_for_A_01_exip1);
1507  tcase_add_test (tc_builtin, test_acceptance_for_A_01b);
1508  tcase_add_test (tc_builtin, test_lkab_demo_suit);
1509  suite_add_tcase (s, tc_builtin);
1510  }
1511 
1512  return s;
1513 }
1514 
1515 int main (int argc, char *argv[])
1516 {
1517  if (argc < 2)
1518  {
1519  printf("ERR: Expected test data directory\n");
1520  exit(1);
1521  }
1522  if (strlen(argv[1]) > MAX_PATH_LEN)
1523  {
1524  printf("ERR: Test data pathname too long: %u", (unsigned int) strlen(argv[1]));
1525  exit(1);
1526  }
1527  dataDir = argv[1];
1528 
1529  int number_failed;
1530  Suite *s = exip_suite();
1531  SRunner *sr = srunner_create (s);
1532 #ifdef _MSC_VER
1534 #endif
1535  srunner_run_all (sr, CK_NORMAL);
1536  number_failed = srunner_ntests_failed (sr);
1537  srunner_free (sr);
1538  return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
1539 }
1540