exip  Alpha 0.5.4
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
templeteDecoder.c
Go to the documentation of this file.
1 /*==================================================================*\
2 | EXIP - Embeddable EXI Processor in C |
3 |--------------------------------------------------------------------|
4 | This work is licensed under BSD 3-Clause License |
5 | The full license terms and conditions are located in LICENSE.txt |
6 \===================================================================*/
7 
17 #include "EXIParser.h"
18 #include "stringManipulate.h"
19 #include "grammarGenerator.h"
20 #include <stdio.h>
21 #include <string.h>
22 
23 static void printfHelp();
24 static void parseSchema(char** fileNames, unsigned int schemaFilesCount, EXIPSchema* schema);
25 
26 #define OUT_EXI 0
27 #define OUT_XML 1
28 #define INPUT_BUFFER_SIZE 200
29 #define MAX_PREFIXES 10
30 #define MAX_XSD_FILES_COUNT 10 // up to 10 XSD files
31 
32 struct appData
33 {
34  unsigned char outputFormat;
35  unsigned char expectAttributeData;
36  char nameBuf[200]; // needed for the OUT_XML Output Format
37  struct element* stack; // needed for the OUT_XML Output Format
38  unsigned char unclosedElement; // needed for the OUT_XML Output Format
39  char prefixes[MAX_PREFIXES][200]; // needed for the OUT_XML Output Format
40  unsigned char prefixesCount; // needed for the OUT_XML Output Format
41 };
42 
43 
44 // Stuff needed for the OUT_XML Output Format
45 // ******************************************
46 struct element {
47  struct element* next;
48  char* name;
49 };
50 
51 static void push(struct element** stack, struct element* el);
52 static struct element* pop(struct element** stack);
53 static struct element* createElement(char* name);
54 static void destroyElement(struct element* el);
55 
56 // returns != 0 if error
57 static char lookupPrefix(struct appData* aData, String ns, unsigned char* prxHit, unsigned char* prefixIndex);
58 
59 // ******************************************
60 
61 // Content Handler API
62 static char sample_fatalError(const char code, const char* msg, void* app_data);
63 static char sample_startDocument(void* app_data);
64 static char sample_endDocument(void* app_data);
65 static char sample_startElement(QName qname, void* app_data);
66 static char sample_endElement(void* app_data);
67 static char sample_attribute(QName qname, void* app_data);
68 static char sample_stringData(const String value, void* app_data);
69 static char sample_decimalData(Decimal value, void* app_data);
70 static char sample_intData(Integer int_val, void* app_data);
71 static char sample_floatData(Float fl_val, void* app_data);
72 static char sample_booleanData(unsigned char bool_val, void* app_data);
73 static char sample_dateTimeData(EXIPDateTime dt_val, void* app_data);
74 static char sample_binaryData(const char* binary_val, Index nbytes, void* app_data);
75 
76 size_t readFileInputStream(void* buf, size_t readSize, void* stream);
77 
78 int main(int argc, char *argv[])
79 {
80  FILE *infile;
81  char sourceFileName[100];
82  EXIPSchema schema;
83  EXIPSchema* schemaPtr = NULL;
84  struct appData parsingData;
85  unsigned int argIndex = 1;
86 
87  parsingData.outputFormat = OUT_EXI; // Default output option
88 
89  if(argc > 1)
90  {
91  if(strcmp(argv[argIndex], "-help") == 0)
92  {
93  printfHelp();
94  return 0;
95  }
96  else if(strcmp(argv[argIndex], "-exi") == 0)
97  {
98  parsingData.outputFormat = OUT_EXI;
99  if(argc == 2)
100  {
101  printfHelp();
102  return 0;
103  }
104 
105  argIndex = 2;
106  }
107  else if(strcmp(argv[argIndex], "-xml") == 0)
108  {
109  parsingData.outputFormat = OUT_XML;
110  if(argc == 2)
111  {
112  printfHelp();
113  return 0;
114  }
115 
116  argIndex = 2;
117  }
118 
119  if(strcmp(argv[argIndex], "-schema") == 0)
120  {
121  if(argc <= argIndex + 2)
122  {
123  printfHelp();
124  return 0;
125  }
126  else
127  {
128  unsigned int schemaFilesCount = 0;
129 
130  schemaFilesCount = argc - argIndex - 2;
131 
132  argIndex++;
133 
134  parseSchema(argv + argIndex, schemaFilesCount, &schema);
135  schemaPtr = &schema;
136 
137  argIndex += schemaFilesCount;
138  }
139  }
140 
141  strcpy(sourceFileName, argv[argIndex]);
142 
143  infile = fopen(sourceFileName, "rb" );
144  if(!infile)
145  {
146  fprintf(stderr, "Unable to open file %s", sourceFileName);
147  return 1;
148  }
149  else
150  {
151  Parser testParser;
152  char buf[INPUT_BUFFER_SIZE];
153  BinaryBuffer buffer;
154  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
155 
156  buffer.buf = buf;
157  buffer.bufLen = INPUT_BUFFER_SIZE;
158  buffer.bufContent = 0;
159  // Parsing steps:
160 
161  // I: First, define an external stream for the input to the parser if any
163  buffer.ioStrm.stream = infile;
164 
165  // II: Second, initialize the parser object
166  tmp_err_code = initParser(&testParser, buffer, schemaPtr, &parsingData);
167  if(tmp_err_code != EXIP_OK)
168  return tmp_err_code;
169 
170  // III: Initialize the parsing data and hook the callback handlers to the parser object
171 
172  parsingData.expectAttributeData = 0;
173  parsingData.stack = NULL;
174  parsingData.unclosedElement = 0;
175  parsingData.prefixesCount = 0;
176 
177  testParser.handler.fatalError = sample_fatalError;
178  testParser.handler.error = sample_fatalError;
179  testParser.handler.startDocument = sample_startDocument;
180  testParser.handler.endDocument = sample_endDocument;
181  testParser.handler.startElement = sample_startElement;
182  testParser.handler.attribute = sample_attribute;
183  testParser.handler.stringData = sample_stringData;
184  testParser.handler.endElement = sample_endElement;
185  testParser.handler.decimalData = sample_decimalData;
186  testParser.handler.intData = sample_intData;
187  testParser.handler.floatData = sample_floatData;
188  testParser.handler.booleanData = sample_booleanData;
189  testParser.handler.dateTimeData = sample_dateTimeData;
190  testParser.handler.binaryData = sample_binaryData;
191 
192  // IV: Parse the header of the stream
193 
194  tmp_err_code = parseHeader(&testParser);
195 
196  // V: Parse the body of the EXI stream
197 
198  while(tmp_err_code == EXIP_OK)
199  {
200  tmp_err_code = parseNext(&testParser);
201  }
202 
203  // VI: Free the memory allocated by the parser and schema object
204 
205  destroyParser(&testParser);
206  if(schemaPtr != NULL)
207  destroySchema(schemaPtr);
208  fclose(infile);
209 
210  if(tmp_err_code == EXIP_PARSING_COMPLETE)
211  return EXIP_OK;
212  else
213  {
214  printf("\nError during parsing of the EXI stream: %d", tmp_err_code);
215  return 1;
216  }
217  }
218  }
219  else
220  {
221  printfHelp();
222  return 1;
223  }
224  return 0;
225 }
226 
227 static void printfHelp()
228 {
229  printf("\n" );
230  printf(" EXIP Copyright (c) 2010 - 2012, EISLAB - LuleĆ„ University of Technology Version 0.4 \n");
231  printf(" Authors: Rumen Kyusakov\n");
232  printf(" Usage: exipd [options] <EXI_FileIn>\n\n");
233  printf(" Options: [-help | [ -xml | -exi ] -schema <schema_files_in>] \n");
234  printf(" -schema : uses schema defined in <schema_files_in> for decoding\n");
235  printf(" -exi : EXI formated output [default]\n");
236  printf(" -xml : XML formated output\n");
237  printf(" -help : Prints this help message\n\n");
238  printf(" Purpose: This program tests the EXIP decoding functionality\n");
239  printf("\n" );
240 }
241 
242 static char sample_fatalError(const char code, const char* msg, void* app_data)
243 {
244  printf("\n%d : FATAL ERROR: %s\n", code, msg);
245  return EXIP_HANDLER_STOP;
246 }
247 
248 static char sample_startDocument(void* app_data)
249 {
250  struct appData* appD = (struct appData*) app_data;
251  if(appD->outputFormat == OUT_EXI)
252  printf("SD\n");
253  else if(appD->outputFormat == OUT_XML)
254  printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
255 
256  return EXIP_HANDLER_OK;
257 }
258 
259 static char sample_endDocument(void* app_data)
260 {
261  struct appData* appD = (struct appData*) app_data;
262  if(appD->outputFormat == OUT_EXI)
263  printf("ED\n");
264  else if(appD->outputFormat == OUT_XML)
265  printf("\n");
266 
267  return EXIP_HANDLER_OK;
268 }
269 
270 static char sample_startElement(QName qname, void* app_data)
271 {
272  struct appData* appD = (struct appData*) app_data;
273  if(appD->outputFormat == OUT_EXI)
274  {
275  printf("SE ");
276  printString(qname.uri);
277  printf(" ");
278  printString(qname.localName);
279  printf("\n");
280  }
281  else if(appD->outputFormat == OUT_XML)
282  {
283  char error = 0;
284  unsigned char prefixIndex = 0;
285  unsigned char prxHit = 1;
286  int t;
287 
288  if(!isStringEmpty(qname.uri))
289  {
290  error = lookupPrefix(appD, *qname.uri, &prxHit, &prefixIndex);
291  if(error != 0)
292  return EXIP_HANDLER_STOP;
293 
294  sprintf(appD->nameBuf, "p%d:", prefixIndex);
295  t = strlen(appD->nameBuf);
296  memcpy(appD->nameBuf + t, qname.localName->str, qname.localName->length);
297  appD->nameBuf[t + qname.localName->length] = '\0';
298  }
299  else
300  {
301  memcpy(appD->nameBuf, qname.localName->str, qname.localName->length);
302  appD->nameBuf[qname.localName->length] = '\0';
303  }
304  push(&(appD->stack), createElement(appD->nameBuf));
305  if(appD->unclosedElement)
306  printf(">\n");
307  printf("<%s", appD->nameBuf);
308 
309  if(prxHit == 0)
310  {
311  sprintf(appD->nameBuf, " xmlns:p%d=\"", prefixIndex);
312  printf("%s", appD->nameBuf);
313  printString(qname.uri);
314  printf("\"");
315  }
316 
317  appD->unclosedElement = 1;
318  }
319 
320  return EXIP_HANDLER_OK;
321 }
322 
323 static char sample_endElement(void* app_data)
324 {
325  struct appData* appD = (struct appData*) app_data;
326  if(appD->outputFormat == OUT_EXI)
327  printf("EE\n");
328  else if(appD->outputFormat == OUT_XML)
329  {
330  struct element* el;
331 
332  if(appD->unclosedElement)
333  printf(">\n");
334  appD->unclosedElement = 0;
335  el = pop(&(appD->stack));
336  printf("</%s>\n", el->name);
337  destroyElement(el);
338  }
339 
340  return EXIP_HANDLER_OK;
341 }
342 
343 static char sample_attribute(QName qname, void* app_data)
344 {
345  struct appData* appD = (struct appData*) app_data;
346  if(appD->outputFormat == OUT_EXI)
347  {
348  printf("AT ");
349  printString(qname.uri);
350  printf(" ");
351  printString(qname.localName);
352  printf("=\"");
353  }
354  else if(appD->outputFormat == OUT_XML)
355  {
356  printf(" ");
357  if(!isStringEmpty(qname.uri))
358  {
359  printString(qname.uri);
360  printf(":");
361  }
362  printString(qname.localName);
363  printf("=\"");
364  }
365  appD->expectAttributeData = 1;
366 
367  return EXIP_HANDLER_OK;
368 }
369 
370 static char sample_stringData(const String value, void* app_data)
371 {
372  struct appData* appD = (struct appData*) app_data;
373  if(appD->outputFormat == OUT_EXI)
374  {
375  if(appD->expectAttributeData)
376  {
377  printString(&value);
378  printf("\"\n");
379  appD->expectAttributeData = 0;
380  }
381  else
382  {
383  printf("CH ");
384  printString(&value);
385  printf("\n");
386  }
387  }
388  else if(appD->outputFormat == OUT_XML)
389  {
390  if(appD->expectAttributeData)
391  {
392  printString(&value);
393  printf("\"");
394  appD->expectAttributeData = 0;
395  }
396  else
397  {
398  if(appD->unclosedElement)
399  printf(">\n");
400  appD->unclosedElement = 0;
401  printString(&value);
402  printf("\n");
403  }
404  }
405 
406  return EXIP_HANDLER_OK;
407 }
408 
409 static char sample_decimalData(Decimal value, void* app_data)
410 {
411  struct appData* appD = (struct appData*) app_data;
412  if(appD->outputFormat == OUT_EXI)
413  {
414  if(appD->expectAttributeData)
415  {
416  printf("%.1f\"\n", (double) value);
417  appD->expectAttributeData = 0;
418  }
419  else
420  {
421  printf("CH %.1f \n", (double) value);
422  }
423  }
424  else if(appD->outputFormat == OUT_XML)
425  {
426  if(appD->expectAttributeData)
427  {
428  printf("%.1f \"", (double) value);
429  appD->expectAttributeData = 0;
430  }
431  else
432  {
433  if(appD->unclosedElement)
434  printf(">\n");
435  appD->unclosedElement = 0;
436  printf("%.1f \n", (double) value);
437  }
438  }
439 
440  return EXIP_HANDLER_OK;
441 }
442 
443 static char sample_intData(Integer int_val, void* app_data)
444 {
445  struct appData* appD = (struct appData*) app_data;
446  char tmp_buf[30];
447  if(appD->outputFormat == OUT_EXI)
448  {
449  if(appD->expectAttributeData)
450  {
451  sprintf(tmp_buf, "%lld", (long long int) int_val);
452  printf("%s", tmp_buf);
453  printf("\"\n");
454  appD->expectAttributeData = 0;
455  }
456  else
457  {
458  printf("CH ");
459  sprintf(tmp_buf, "%lld", (long long int) int_val);
460  printf("%s", tmp_buf);
461  printf("\n");
462  }
463  }
464  else if(appD->outputFormat == OUT_XML)
465  {
466  if(appD->expectAttributeData)
467  {
468  sprintf(tmp_buf, "%lld", (long long int) int_val);
469  printf("%s", tmp_buf);
470  printf("\"");
471  appD->expectAttributeData = 0;
472  }
473  else
474  {
475  if(appD->unclosedElement)
476  printf(">\n");
477  appD->unclosedElement = 0;
478  sprintf(tmp_buf, "%lld", (long long int) int_val);
479  printf("%s", tmp_buf);
480  printf("\n");
481  }
482  }
483 
484  return EXIP_HANDLER_OK;
485 }
486 
487 static char sample_booleanData(unsigned char bool_val, void* app_data)
488 {
489  struct appData* appD = (struct appData*) app_data;
490 
491  if(appD->outputFormat == OUT_EXI)
492  {
493  if(appD->expectAttributeData)
494  {
495  if(bool_val)
496  printf("true\"\n");
497  else
498  printf("false\"\n");
499 
500  appD->expectAttributeData = 0;
501  }
502  else
503  {
504  printf("CH ");
505  if(bool_val)
506  printf("true\n");
507  else
508  printf("false\n");
509  }
510  }
511  else if(appD->outputFormat == OUT_XML)
512  {
513  if(appD->expectAttributeData)
514  {
515  if(bool_val)
516  printf("true\"");
517  else
518  printf("false\"");
519  appD->expectAttributeData = 0;
520  }
521  else
522  {
523  if(appD->unclosedElement)
524  printf(">\n");
525  appD->unclosedElement = 0;
526 
527  if(bool_val)
528  printf("true\n");
529  else
530  printf("false\n");
531  }
532  }
533 
534  return EXIP_HANDLER_OK;
535 }
536 
537 static char sample_floatData(Float fl_val, void* app_data)
538 {
539  struct appData* appD = (struct appData*) app_data;
540  char tmp_buf[30];
541  if(appD->outputFormat == OUT_EXI)
542  {
543  if(appD->expectAttributeData)
544  {
545  sprintf(tmp_buf, "%lldE%d", (long long int) fl_val.mantissa, fl_val.exponent);
546  printf("%s", tmp_buf);
547  printf("\"\n");
548  appD->expectAttributeData = 0;
549  }
550  else
551  {
552  printf("CH ");
553  sprintf(tmp_buf, "%lldE%d", (long long int) fl_val.mantissa, fl_val.exponent);
554  printf("%s", tmp_buf);
555  printf("\n");
556  }
557  }
558  else if(appD->outputFormat == OUT_XML)
559  {
560  if(appD->expectAttributeData)
561  {
562  sprintf(tmp_buf, "%lldE%d", (long long int) fl_val.mantissa, fl_val.exponent);
563  printf("%s", tmp_buf);
564  printf("\"");
565  appD->expectAttributeData = 0;
566  }
567  else
568  {
569  if(appD->unclosedElement)
570  printf(">\n");
571  appD->unclosedElement = 0;
572  sprintf(tmp_buf, "%lldE%d", (long long int) fl_val.mantissa, fl_val.exponent);
573  printf("%s", tmp_buf);
574  printf("\n");
575  }
576  }
577 
578  return EXIP_HANDLER_OK;
579 }
580 
581 static char sample_dateTimeData(EXIPDateTime dt_val, void* app_data)
582 {
583  struct appData* appD = (struct appData*) app_data;
584  char fsecBuf[30];
585  int i;
586 
588  {
589  unsigned int tmpfValue = dt_val.fSecs.value;
590  int digitNum = 0;
591 
592  fsecBuf[0] = '.';
593 
594  while(tmpfValue)
595  {
596  digitNum++;
597  tmpfValue = tmpfValue / 10;
598  }
599  for(i = 0; i < dt_val.fSecs.offset + 1 - digitNum; i++)
600  fsecBuf[1+i] = '0';
601 
602  sprintf(fsecBuf + 1 + i, "%d", dt_val.fSecs.value);
603  }
604  else
605  {
606  fsecBuf[0] = '\0';
607  }
608 
609  if(appD->outputFormat == OUT_EXI)
610  {
611  if(appD->expectAttributeData)
612  {
613  printf("%04d-%02d-%02dT%02d:%02d:%02d%s", dt_val.dateTime.tm_year + 1900,
614  dt_val.dateTime.tm_mon + 1, dt_val.dateTime.tm_mday,
615  dt_val.dateTime.tm_hour, dt_val.dateTime.tm_min,
616  dt_val.dateTime.tm_sec, fsecBuf);
617  printf("\"\n");
618  appD->expectAttributeData = 0;
619  }
620  else
621  {
622  printf("CH ");
623  printf("%04d-%02d-%02dT%02d:%02d:%02d%s", dt_val.dateTime.tm_year + 1900,
624  dt_val.dateTime.tm_mon + 1, dt_val.dateTime.tm_mday,
625  dt_val.dateTime.tm_hour, dt_val.dateTime.tm_min,
626  dt_val.dateTime.tm_sec, fsecBuf);
627  printf("\n");
628  }
629  }
630  else if(appD->outputFormat == OUT_XML)
631  {
632  if(appD->expectAttributeData)
633  {
634  printf("%04d-%02d-%02dT%02d:%02d:%02d%s", dt_val.dateTime.tm_year + 1900,
635  dt_val.dateTime.tm_mon + 1, dt_val.dateTime.tm_mday,
636  dt_val.dateTime.tm_hour, dt_val.dateTime.tm_min,
637  dt_val.dateTime.tm_sec, fsecBuf);
638  printf("\"");
639  appD->expectAttributeData = 0;
640  }
641  else
642  {
643  if(appD->unclosedElement)
644  printf(">\n");
645  appD->unclosedElement = 0;
646  printf("%04d-%02d-%02dT%02d:%02d:%02d%s", dt_val.dateTime.tm_year + 1900,
647  dt_val.dateTime.tm_mon + 1, dt_val.dateTime.tm_mday,
648  dt_val.dateTime.tm_hour, dt_val.dateTime.tm_min,
649  dt_val.dateTime.tm_sec, fsecBuf);
650  printf("\n");
651  }
652  }
653 
654  return EXIP_HANDLER_OK;
655 }
656 
657 static char sample_binaryData(const char* binary_val, Index nbytes, void* app_data)
658 {
659  struct appData* appD = (struct appData*) app_data;
660 
661  if(appD->outputFormat == OUT_EXI)
662  {
663  if(appD->expectAttributeData)
664  {
665  printf("[binary: %d bytes]", (int) nbytes);
666  printf("\"\n");
667  appD->expectAttributeData = 0;
668  }
669  else
670  {
671  printf("CH ");
672  printf("[binary: %d bytes]", (int) nbytes);
673  printf("\n");
674  }
675  }
676  else if(appD->outputFormat == OUT_XML)
677  {
678  if(appD->expectAttributeData)
679  {
680  printf("[binary: %d bytes]", (int) nbytes);
681  printf("\"");
682  appD->expectAttributeData = 0;
683  }
684  else
685  {
686  if(appD->unclosedElement)
687  printf(">\n");
688  appD->unclosedElement = 0;
689  printf("[binary: %d bytes]", (int) nbytes);
690  printf("\n");
691  }
692  }
693 
694  return EXIP_HANDLER_OK;
695 }
696 
697 // Stuff needed for the OUT_XML Output Format
698 // ******************************************
699 static void push(struct element** stack, struct element* el)
700 {
701  if(*stack == NULL)
702  *stack = el;
703  else
704  {
705  el->next = *stack;
706  *stack = el;
707  }
708 }
709 
710 static struct element* pop(struct element** stack)
711 {
712  if(*stack == NULL)
713  return NULL;
714  else
715  {
716  struct element* result;
717  result = *stack;
718  *stack = (*stack)->next;
719  return result;
720  }
721 }
722 
723 static struct element* createElement(char* name)
724 {
725  struct element* el;
726  el = malloc(sizeof(struct element));
727  if(el == NULL)
728  exit(1);
729  el->next = NULL;
730  el->name = malloc(strlen(name)+1);
731  if(el->name == NULL)
732  exit(1);
733  strcpy(el->name, name);
734  return el;
735 }
736 
737 static void destroyElement(struct element* el)
738 {
739  free(el->name);
740  free(el);
741 }
742 // ******************************************
743 
744 size_t readFileInputStream(void* buf, size_t readSize, void* stream)
745 {
746  FILE *infile = (FILE*) stream;
747  return fread(buf, 1, readSize, infile);
748 }
749 
750 static void parseSchema(char** fileNames, unsigned int schemaFilesCount, EXIPSchema* schema)
751 {
752  FILE *schemaFile;
754  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
755  unsigned int i;
756 
757  if(schemaFilesCount > MAX_XSD_FILES_COUNT)
758  {
759  fprintf(stderr, "Too many xsd files given as an input: %d", schemaFilesCount);
760  exit(1);
761  }
762 
763  for(i = 0; i < schemaFilesCount; i++)
764  {
765  schemaFile = fopen(fileNames[i], "rb" );
766  if(!schemaFile)
767  {
768  fprintf(stderr, "Unable to open file %s", fileNames[i]);
769  exit(1);
770  }
771  else
772  {
773  //Get file length
774  fseek(schemaFile, 0, SEEK_END);
775  buffer[i].bufLen = ftell(schemaFile) + 1;
776  fseek(schemaFile, 0, SEEK_SET);
777 
778  //Allocate memory
779  buffer[i].buf = (char *) malloc(buffer[i].bufLen);
780  if (!buffer[i].buf)
781  {
782  fprintf(stderr, "Memory allocation error!");
783  fclose(schemaFile);
784  exit(1);
785  }
786 
787  //Read file contents into buffer
788  fread(buffer[i].buf, buffer[i].bufLen, 1, schemaFile);
789  fclose(schemaFile);
790 
791  buffer[i].bufContent = buffer[i].bufLen;
792  buffer[i].ioStrm.readWriteToStream = NULL;
793  buffer[i].ioStrm.stream = NULL;
794  }
795  }
796 
797  tmp_err_code = generateSchemaInformedGrammars(buffer, schemaFilesCount, SCHEMA_FORMAT_XSD_EXI, schema);
798  if(tmp_err_code != EXIP_OK)
799  {
800  printf("\n Error occured: %d", tmp_err_code);
801  exit(1);
802  }
803 
804  for(i = 0; i < schemaFilesCount; i++)
805  {
806  free(buffer[i].buf);
807  }
808 }
809 
810 static char lookupPrefix(struct appData* aData, String ns, unsigned char* prxHit, unsigned char* prefixIndex)
811 {
812  int i;
813  for(i = 0; i < aData->prefixesCount; i++)
814  {
815  if(stringEqualToAscii(ns, aData->prefixes[i]))
816  {
817  *prefixIndex = i;
818  *prxHit = 1;
819  return 0;
820  }
821  }
822 
823  if(aData->prefixesCount == MAX_PREFIXES)
824  return 1;
825  else
826  {
827  memcpy(aData->prefixes[aData->prefixesCount], ns.str, ns.length);
828  aData->prefixes[aData->prefixesCount][ns.length] = '\0';
829  *prefixIndex = aData->prefixesCount;
830  aData->prefixesCount += 1;
831  *prxHit = 0;
832  return 0;
833  }
834 }