exip  Alpha 0.5.4
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
bodyEncode.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 "bodyEncode.h"
19 #include "sTables.h"
20 #include "streamEncode.h"
21 #include "ioUtil.h"
22 #include "stringManipulate.h"
23 #include "grammars.h"
24 #include "memManagement.h"
25 #include "dynamicArray.h"
26 
27 extern const String XML_SCHEMA_INSTANCE;
28 
31 static errorCode stateMachineProdEncode(EXIStream* strm, EventTypeClass eventClass, GrammarRule* currentRule,
32  QName* qname, EventCode ec, Production* prodHit);
33 
34 errorCode encodeStringData(EXIStream* strm, String strng, QNameID qnameID, Index typeId)
35 {
36  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
37  boolean flag_StringLiteralsPartition = FALSE;
38 
39  /* ENUMERATION CHECK */
41  {
42  // There is enumeration defined
43  EnumDefinition eDefSearch;
44  EnumDefinition* eDefFound;
45  SmallIndex i;
46 
47  eDefSearch.typeId = typeId;
48  eDefFound = bsearch(&eDefSearch, strm->schema->enumTable.enumDef, strm->schema->enumTable.count, sizeof(EnumDefinition), compareEnumDefs);
49  if(eDefFound == NULL)
50  return EXIP_UNEXPECTED_ERROR;
51 
52  for(i = 0; i < eDefFound->count; i++)
53  {
54  if(stringEqual(((String*) eDefFound->values)[i], strng))
55  {
56  return encodeNBitUnsignedInteger(strm, getBitsNumber(eDefFound->count - 1), i);
57  }
58  }
59  /* The enum value is not found! */
60  return EXIP_UNEXPECTED_ERROR;
61  }
62 #if VALUE_CROSSTABLE_USE
63  {
64  VxTable* vxTable = GET_LN_URI_QNAME(strm->schema->uriTable, qnameID).vxTable;
65  Index vxEntryId = 0;
66  flag_StringLiteralsPartition = lookupVx(&strm->valueTable, vxTable, strng, &vxEntryId);
67  if(flag_StringLiteralsPartition && vxTable->vx[vxEntryId].globalId != INDEX_MAX) // "local" value partition table hit; when INDEX_MAX -> compact identifier permanently unassigned
68  {
69  unsigned char vxBits;
70 
71  TRY(encodeUnsignedInteger(strm, 0));
72  vxBits = getBitsNumber(vxTable->count - 1);
73  TRY(encodeNBitUnsignedInteger(strm, vxBits, vxEntryId));
74  return EXIP_OK;
75  }
76  }
77 #endif
78  { // "local" value partition table miss
79  Index valueEntryId = 0;
80  flag_StringLiteralsPartition = lookupValue(&strm->valueTable, strng, &valueEntryId);
81  if(flag_StringLiteralsPartition) // global value partition table hit
82  {
83  unsigned char valueBits;
84 
85  TRY(encodeUnsignedInteger(strm, 1));
86  valueBits = getBitsNumber((unsigned int)(strm->valueTable.count - 1));
87  TRY(encodeNBitUnsignedInteger(strm, valueBits, (unsigned int)(valueEntryId)));
88  }
89  else // "local" value partition and global value partition table miss
90  {
91  TRY(encodeUnsignedInteger(strm, (UnsignedInteger)(strng.length + 2)));
92  TRY(encodeStringOnly(strm, &strng));
93 
94  if(strng.length > 0 && strng.length <= strm->header.opts.valueMaxLength && strm->header.opts.valuePartitionCapacity > 0)
95  {
96  // The value should be added in the value partitions of the string tables
97  String clonedValue;
98 
99  TRY(cloneString(&strng, &clonedValue));
100  TRY(addValueEntry(strm, clonedValue, qnameID));
101  }
102  }
103  }
104 
105  return EXIP_OK;
106 }
107 
108 errorCode encodeProduction(EXIStream* strm, EventTypeClass eventClass, boolean isSchemaType, QName* qname, EXITypeClass chTypeClass, Production* prodHit)
109 {
110  GrammarRule* currentRule;
111  EventCode ec;
112  Index j = 0;
113  Production* tmpProd = NULL;
114  Index prodCount;
115  unsigned int bitCount;
116  boolean matchFound = FALSE;
117  SmallIndex currNonTermID = strm->gStack->currNonTermID;
118 
119  // TODO: GR_CONTENT_2 is only needed when schema deviations are allowed.
120  // Here and in many other places when schema deviations are fully disabled
121  // many parts of the code can be pruned during compile time using macro parameters in the build.
122  // This includes the EXI Profile features itself (excluding localValueCapping)
123  if(currNonTermID == GR_CONTENT_2)
124  currNonTermID = GET_CONTENT_INDEX(strm->gStack->grammar->props);
125 
126  if(currNonTermID >= strm->gStack->grammar->count)
128 
129 #if BUILD_IN_GRAMMARS_USE
130  if(IS_BUILT_IN_ELEM(strm->gStack->grammar->props)) // If the current grammar is build-in Element grammar ...
131  {
132  currentRule = (GrammarRule*) &((DynGrammarRule*) strm->gStack->grammar->rule)[currNonTermID];
133  prodCount = currentRule->pCount;
134  }
135  else
136 #endif
137  {
138  currentRule = &strm->gStack->grammar->rule[currNonTermID];
139 
140  if(strm->context.isNilType)
141  { /* xsi:nil=true case */
142  prodCount = RULE_GET_AT_COUNT(currentRule->meta) + RULE_CONTAIN_EE(currentRule->meta);
143  if(currNonTermID >= GET_CONTENT_INDEX(strm->gStack->grammar->props))
144  {
145  // Instead of content we have a single EE production in the emptyType grammars
146  prodCount = 1;
147  if(eventClass != EVENT_EE_CLASS)
149  }
150 
151  if(eventClass == EVENT_EE_CLASS)
152  {
153  if(RULE_CONTAIN_EE(currentRule->meta) || currNonTermID >= GET_CONTENT_INDEX(strm->gStack->grammar->props))
154  {
155  bitCount = getBitsFirstPartCode(strm, prodCount, currNonTermID);
156  ec.length = 1;
157  ec.part[0] = prodCount - 1;
158  ec.bits[0] = bitCount;
160  strm->context.isNilType = FALSE;
161 
162  return writeEventCode(strm, ec);
163  }
164  }
165  }
166  else
167  prodCount = currentRule->pCount;
168  }
169 
170 #if DEBUG_CONTENT_IO == ON
171  {
172  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
173  TRY(printGrammarRule(currNonTermID, currentRule, strm->schema));
174  }
175 #endif
176 
177  bitCount = getBitsFirstPartCode(strm, prodCount, currNonTermID);
178 
179  if(isSchemaType == TRUE)
180  {
181  for(j = 0; j < prodCount; j++)
182  {
183  tmpProd = &currentRule->production[currentRule->pCount - 1 - j];
184 
185  if(GET_EVENT_CLASS(GET_PROD_EXI_EVENT(tmpProd->content)) == eventClass)
186  {
187  if(eventClass == EVENT_AT_CLASS || eventClass == EVENT_SE_CLASS)
188  {
189  assert(qname);
190  if(tmpProd->qnameId.uriId == URI_MAX || (stringEqual(strm->schema->uriTable.uri[tmpProd->qnameId.uriId].uriStr, *(qname->uri)) &&
191  (tmpProd->qnameId.lnId == LN_MAX || stringEqual(GET_LN_URI_QNAME(strm->schema->uriTable, tmpProd->qnameId).lnStr, *(qname->localName)))))
192  {
193  matchFound = TRUE;
194  break;
195  }
196  }
197  else if(eventClass == EVENT_CH_CLASS)
198  {
199  EXIType exiType;
200  if(tmpProd->typeId != INDEX_MAX)
201  exiType = GET_EXI_TYPE(strm->schema->simpleTypeTable.sType[tmpProd->typeId].content);
202  else
203  exiType = VALUE_TYPE_NONE;
204 
205  if(exiType == VALUE_TYPE_NONE || exiType == VALUE_TYPE_UNTYPED)
206  matchFound = TRUE;
207  else if(chTypeClass == GET_VALUE_TYPE_CLASS(exiType))
208  matchFound = TRUE;
209  break;
210  }
211  else
212  {
213  matchFound = TRUE;
214  break;
215  }
216  }
217  }
218  }
219 
220  if(matchFound == TRUE)
221  {
222  *prodHit = *tmpProd;
223  ec.length = 1;
224  ec.part[0] = j;
225  ec.bits[0] = bitCount;
226  strm->gStack->currNonTermID = GET_PROD_NON_TERM(tmpProd->content);
227 
228  return writeEventCode(strm, ec);
229  }
230  else
231  {
232  // Production not found: encoded as second or third level production
233 
234  DEBUG_MSG(INFO, DEBUG_CONTENT_IO, (">Secodn/third level production \n"));
235 
236  ec.length = 2;
237  ec.part[0] = prodCount;
238  ec.bits[0] = bitCount;
239 
240  return stateMachineProdEncode(strm, eventClass, currentRule, qname, ec, prodHit);
241  }
242 }
243 
244 static errorCode stateMachineProdEncode(EXIStream* strm, EventTypeClass eventClass,
245  GrammarRule* currentRule, QName* qname, EventCode ec, Production* prodHit)
246 {
247  QNameID qnameID;
248 
249  if(IS_BUILT_IN_ELEM(strm->gStack->grammar->props))
250  {
251  // Built-in element grammar
252 #if BUILD_IN_GRAMMARS_USE
253  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
254  QNameID voidQnameID = {SMALL_INDEX_MAX, INDEX_MAX};
256  {
257  ec.bits[1] = getBitsNumber(3 +
262  }
263  else if(strm->gStack->currNonTermID == GR_ELEMENT_CONTENT)
264  {
267  }
268  else
270 
271  switch(eventClass)
272  {
273  case EVENT_EE_CLASS:
276 
278  ec.part[1] = 0;
280 
281  // #1# COMMENT and #2# COMMENT
282  // NOTE: In general, first you need to check if EE does not already exists, just then insert it
283  // However, the encodeProduction(); will always use first level EE if exists so no such check is needed here.
284  TRY(insertZeroProduction((DynGrammarRule*) currentRule, EVENT_EE, GR_VOID_NON_TERMINAL, &voidQnameID, 1));
285  break;
286  case EVENT_AT_CLASS:
289 
291  ec.part[1] = 1;
293 
294  if(!lookupUri(&strm->schema->uriTable, *qname->uri, &qnameID.uriId))
295  {
296  qnameID.uriId = strm->schema->uriTable.count;
297  qnameID.lnId = 0;
298  }
299  else if(!lookupLn(&strm->schema->uriTable.uri[qnameID.uriId].lnTable, *qname->localName, &qnameID.lnId))
300  {
301  qnameID.lnId = strm->schema->uriTable.uri[qnameID.uriId].lnTable.count;
302  }
303 
304  // If eventType == AT(qname) and qname == xsi:type check first if there is no
305  // such production already at top level (see http://www.w3.org/XML/EXI/exi-10-errata#Substantive20120508)
306  // If there is no -> insert one, otherwise don't insert it
307  if(qnameID.uriId == XML_SCHEMA_INSTANCE_ID && qnameID.lnId == XML_SCHEMA_INSTANCE_TYPE_ID)
308  {
309  if(!RULE_CONTAIN_XSI_TYPE(((DynGrammarRule*) currentRule)->meta))
310  {
311  RULE_SET_CONTAIN_XSI_TYPE(((DynGrammarRule*) currentRule)->meta);
312  TRY(insertZeroProduction((DynGrammarRule*) currentRule, EVENT_AT_QNAME, GR_START_TAG_CONTENT, &qnameID, 1));
313  }
314  }
315  else
316  TRY(insertZeroProduction((DynGrammarRule*) currentRule, EVENT_AT_QNAME, GR_START_TAG_CONTENT, &qnameID, 1));
317  break;
318  case EVENT_NS_CLASS:
321 
323  ec.part[1] = 2;
325  break;
326  case EVENT_SC_CLASS:
328  break;
329  case EVENT_SE_CLASS:
333  else
334  ec.part[1] = 0;
336 
337  if(!lookupUri(&strm->schema->uriTable, *qname->uri, &qnameID.uriId))
338  {
339  qnameID.uriId = strm->schema->uriTable.count;
340  qnameID.lnId = 0;
341  }
342  else if(!lookupLn(&strm->schema->uriTable.uri[qnameID.uriId].lnTable, *qname->localName, &qnameID.lnId))
343  {
344  qnameID.lnId = strm->schema->uriTable.uri[qnameID.uriId].lnTable.count;
345  }
346 
347  TRY(insertZeroProduction((DynGrammarRule*) currentRule, EVENT_SE_QNAME, GR_ELEMENT_CONTENT, &qnameID, 1));
348  break;
349  case EVENT_CH_CLASS:
353  else
354  ec.part[1] = 1;
356 
357  // #1# COMMENT and #2# COMMENT
358  // NOTE: In general, first you need to check if CH does not already exists, just then insert it
359  // However, the encodeProduction(); will always use first level CH if exists so no such check is needed here.
360  TRY(insertZeroProduction((DynGrammarRule*) currentRule, EVENT_CH, GR_ELEMENT_CONTENT, &voidQnameID, 1));
361  break;
362  case EVENT_ER_CLASS:
364  break;
365  case EVENT_CM_CLASS:
367  break;
368  case EVENT_PI_CLASS:
370  break;
371  default:
373  }
374 #else
375  DEBUG_MSG(ERROR, DEBUG_CONTENT_IO, (">Build-in element grammars are not supported by this configuration \n"));
376  assert(FALSE);
378 #endif
379  }
380  else if(IS_DOCUMENT(strm->gStack->grammar->props))
381  {
382  // Document grammar
383  switch(eventClass)
384  {
385  case EVENT_DT_CLASS:
387  break;
388  case EVENT_CM_CLASS:
390  break;
391  case EVENT_PI_CLASS:
393  break;
394  default:
396  }
397  }
398  else if(IS_FRAGMENT(strm->gStack->grammar->props))
399  {
400  // Fragment grammar
401  switch(eventClass)
402  {
403  case EVENT_CM_CLASS:
405  break;
406  case EVENT_PI_CLASS:
408  break;
409  default:
411  }
412  }
413  else
414  {
415  // Schema-informed element/type grammar
416  if(WITH_STRICT(strm->header.opts.enumOpt))
417  {
418  // Strict mode
420  eventClass != EVENT_AT_CLASS ||
421  !stringEqual(*qname->uri, XML_SCHEMA_INSTANCE))
423  if(stringEqualToAscii(*qname->localName, "type"))
424  {
427 
431  ec.part[1] = 0;
432 
433  if(!IS_NILLABLE(strm->gStack->grammar->props))
434  ec.bits[1] = 0;
435  else
436  ec.bits[1] = 1;
437  }
438  else if(stringEqualToAscii(*qname->localName, "nil"))
439  {
440  if(!IS_NILLABLE(strm->gStack->grammar->props))
442 
446 
448  {
449  ec.part[1] = 0;
450  ec.bits[1] = 0;
451  }
452  else
453  {
454  ec.part[1] = 1;
455  ec.bits[1] = 1;
456  }
457  }
458  else
460  }
461  else // Non-strict mode
462  {
463  unsigned int prod2Count = 0;
464  // Create a copy of the content grammar if and only if there are AT
465  // productions that point to the content grammar rule OR the content index is 0.
466  // The content2 grammar rule is only needed in case the current rule is
467  // equal the content grammar rule. Note that when content index is 0, the entry grammar
468  // is the content2 grammar rule and by default the GR_START_TAG_CONTENT is pointing
469  // to the content2 while GR_CONTENT_2 is pointing to content i.e. the roles are
470  // reversed in this situation. It is implemented in this way in order to keep
471  // all the rule processing in tact in the other parts of the implementation.
472  boolean isContent2Grammar = FALSE;
473 
474  if(strm->gStack->currNonTermID == GR_CONTENT_2)
475  {
477  isContent2Grammar = TRUE;
478  }
481  {
482  isContent2Grammar = TRUE;
483  }
484  prod2Count = 2; // SE(*), CH(untyped) always available
485 
486  if(isContent2Grammar ||
488  {
489  prod2Count += 2; // AT(*), AT(untyped) third level
490  }
491 
492  if(!RULE_CONTAIN_EE(currentRule->meta))
493  prod2Count += 1; // EE
494 
496  {
497  prod2Count += 2; // AT(xsi:type), AT(xsi:nil)
498 
500  prod2Count += 1; // NS
502  prod2Count += 1; // SC
503  }
504 
506  prod2Count += 1; // ER
507 
509  prod2Count += 1; // CM or PI
510 
511  switch(eventClass)
512  {
513  case EVENT_EE_CLASS:
514  assert(!RULE_CONTAIN_EE(currentRule->meta));
515 
517  ec.length = 2;
518  ec.part[1] = 0;
519  ec.bits[1] = getBitsNumber(prod2Count - 1);
521  strm->context.isNilType = FALSE;
522  break;
523  case EVENT_AT_CLASS:
524 
525  if(!lookupUri(&strm->schema->uriTable, *qname->uri, &qnameID.uriId))
526  {
527  qnameID.uriId = strm->schema->uriTable.count;
528  qnameID.lnId = 0;
529  }
530  else if(!lookupLn(&strm->schema->uriTable.uri[qnameID.uriId].lnTable, *qname->localName, &qnameID.lnId))
531  {
532  qnameID.lnId = strm->schema->uriTable.uri[qnameID.uriId].lnTable.count;
533  }
534 
535  if(qnameID.uriId == XML_SCHEMA_INSTANCE_ID)
536  {
537  if(qnameID.lnId == XML_SCHEMA_INSTANCE_NIL_ID)
538  {
541 
543  prodHit->qnameId = qnameID;
544  ec.length = 2;
545  ec.part[1] = 1 + !RULE_CONTAIN_EE(currentRule->meta);
546  ec.bits[1] = getBitsNumber(prod2Count - 1);
547  prodHit->typeId = SIMPLE_TYPE_BOOLEAN;
548  }
549  else if(qnameID.lnId == XML_SCHEMA_INSTANCE_TYPE_ID)
550  {
553 
555  prodHit->qnameId = qnameID;
556  ec.length = 2;
557  ec.part[1] = 0 + !RULE_CONTAIN_EE(currentRule->meta);
558  ec.bits[1] = getBitsNumber(prod2Count - 1);
559  prodHit->typeId = SIMPLE_TYPE_QNAME;
560  }
561  else
563  }
564  else // All other cases of AT events
566  break;
567  case EVENT_NS_CLASS:
571 
573  ec.length = 2;
574  ec.part[1] = !RULE_CONTAIN_EE(currentRule->meta) + 4;
575  ec.bits[1] = getBitsNumber(prod2Count - 1);
577  break;
578  case EVENT_SC_CLASS:
580  break;
581  case EVENT_SE_CLASS:
582  // SE(*) content|same_rule
583  if(isContent2Grammar || strm->gStack->currNonTermID < GET_CONTENT_INDEX(strm->gStack->grammar->props))
584  {
585  // currNonTermID should point to the content grammar rule
588  else
590  }
592  ec.length = 2;
594  ec.bits[1] = getBitsNumber(prod2Count - 1);
595  break;
596  case EVENT_CH_CLASS:
597  // CH [untyped value] content|same_rule
598  if(isContent2Grammar || strm->gStack->currNonTermID < GET_CONTENT_INDEX(strm->gStack->grammar->props))
599  {
600  // currNonTermID should point to the content grammar rule
603  else
605  }
607  ec.length = 2;
609  ec.bits[1] = getBitsNumber(prod2Count - 1);
610  break;
611  case EVENT_ER_CLASS:
613  break;
614  case EVENT_CM_CLASS:
616  break;
617  case EVENT_PI_CLASS:
619  break;
620  default:
622  }
623  }
624  }
625 
626  return writeEventCode(strm, ec);
627 }
628 
629 errorCode encodeQName(EXIStream* strm, QName qname, EventType eventT, QNameID* qnameID)
630 {
631  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
632 
633  DEBUG_MSG(INFO, DEBUG_CONTENT_IO, (">Encoding QName\n"));
634 
635 /******* Start: URI **********/
636  TRY(encodeUri(strm, (String*) qname.uri, &qnameID->uriId));
637 /******* End: URI **********/
638 
639 /******* Start: Local name **********/
640  TRY(encodeLn(strm, (String*) qname.localName, qnameID));
641 /******* End: Local name **********/
642 
643  return encodePfxQName(strm, &qname, eventT, qnameID->uriId);
644 }
645 
647 {
648  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
649  unsigned char uriBits = getBitsNumber(strm->schema->uriTable.count);
650 
651  if(lookupUri(&strm->schema->uriTable, *uri, uriId)) // uri hit
652  {
653  TRY(encodeNBitUnsignedInteger(strm, uriBits, *uriId + 1));
654  }
655  else // uri miss
656  {
657  String copiedURI;
658  TRY(encodeNBitUnsignedInteger(strm, uriBits, 0));
659  TRY(encodeString(strm, uri));
660  TRY(cloneStringManaged(uri, &copiedURI, &strm->memList));
661  TRY(addUriEntry(&strm->schema->uriTable, copiedURI, uriId));
662  }
663 
664  return EXIP_OK;
665 }
666 
668 {
669  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
670 
671  if(lookupLn(&strm->schema->uriTable.uri[qnameID->uriId].lnTable, *ln, &qnameID->lnId)) // local-name table hit
672  {
673  unsigned char lnBits = getBitsNumber((unsigned int)(strm->schema->uriTable.uri[qnameID->uriId].lnTable.count - 1));
674  TRY(encodeUnsignedInteger(strm, 0));
675  TRY(encodeNBitUnsignedInteger(strm, lnBits, (unsigned int)(qnameID->lnId)));
676  }
677  else // local-name table miss
678  {
679  String copiedLN;
680  TRY(encodeUnsignedInteger(strm, (UnsignedInteger)(ln->length + 1)));
681  TRY(encodeStringOnly(strm, ln));
682 
683  if(strm->schema->uriTable.uri[qnameID->uriId].lnTable.ln == NULL)
684  {
685  // Create local name table for this URI entry
687  }
688 
689  TRY(cloneStringManaged(ln, &copiedLN, &strm->memList));
690  TRY(addLnEntry(&strm->schema->uriTable.uri[qnameID->uriId].lnTable, copiedLN, &qnameID->lnId));
691  }
692 
693  return EXIP_OK;
694 }
695 
697 {
698  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
699  unsigned char prefixBits = 0;
700  SmallIndex prefixID = 0;
701 
703  return EXIP_OK;
704 
705  if(strm->schema->uriTable.uri[uriId].pfxTable.count == 0)
706  return EXIP_OK;
707 
708  prefixBits = getBitsNumber(strm->schema->uriTable.uri[uriId].pfxTable.count - 1);
709 
710  if(prefixBits > 0)
711  {
712  if(qname == NULL)
713  return EXIP_NULL_POINTER_REF;
714 
715  if(lookupPfx(&strm->schema->uriTable.uri[uriId].pfxTable, *qname->prefix, &prefixID) == TRUE)
716  {
717  TRY(encodeNBitUnsignedInteger(strm, prefixBits, (unsigned int) prefixID));
718  }
719  else
720  {
721  if(eventT != EVENT_SE_ALL)
723 
724  TRY(encodeNBitUnsignedInteger(strm, prefixBits, 0));
725  }
726  }
727 
728  return EXIP_OK;
729 }
730 
732 {
733  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
734  SmallIndex pfxId;
735  unsigned char pfxBits = getBitsNumber(strm->schema->uriTable.uri[uriId].pfxTable.count);
736 
737  if(lookupPfx(&strm->schema->uriTable.uri[uriId].pfxTable, *prefix, &pfxId)) // prefix hit
738  {
739  TRY(encodeNBitUnsignedInteger(strm, pfxBits, pfxId + 1));
740  }
741  else // prefix miss
742  {
743  String copiedPrefix;
744  TRY(encodeNBitUnsignedInteger(strm, pfxBits, 0));
745  TRY(encodeString(strm, prefix));
746  TRY(cloneStringManaged(prefix, &copiedPrefix, &strm->memList));
747  TRY(addPfxEntry(&strm->schema->uriTable.uri[uriId].pfxTable, copiedPrefix, &pfxId));
748  }
749 
750  return EXIP_OK;
751 }
752 
753 errorCode encodeIntData(EXIStream* strm, Integer int_val, QNameID qnameID, Index typeId)
754 {
755  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
756  EXIType exiType;
757 
758  if(typeId != INDEX_MAX)
759  exiType = GET_EXI_TYPE(strm->schema->simpleTypeTable.sType[typeId].content);
760  else
761  exiType = VALUE_TYPE_NONE;
762 
763  if(exiType == VALUE_TYPE_SMALL_INTEGER)
764  {
765  // TODO: take into account minExclusive and maxExclusive when they are supported
766  unsigned int encoded_val;
767  unsigned char numberOfBits;
768 
769  if(int_val > strm->schema->simpleTypeTable.sType[typeId].max ||
770  int_val < strm->schema->simpleTypeTable.sType[typeId].min)
771  return EXIP_INVALID_EXI_INPUT;
772 
773  encoded_val = (unsigned int) (int_val - strm->schema->simpleTypeTable.sType[typeId].min);
774  numberOfBits = getBitsNumber(strm->schema->simpleTypeTable.sType[typeId].max - strm->schema->simpleTypeTable.sType[typeId].min);
775 
776  return encodeNBitUnsignedInteger(strm, numberOfBits, encoded_val);
777  }
778  else if(exiType == VALUE_TYPE_NON_NEGATIVE_INT)
779  {
780  return encodeUnsignedInteger(strm, (UnsignedInteger) int_val);
781  }
782  else if(exiType == VALUE_TYPE_INTEGER)
783  {
784  return encodeIntegerValue(strm, int_val);
785  }
786  else if(exiType == VALUE_TYPE_STRING || exiType == VALUE_TYPE_UNTYPED || exiType == VALUE_TYPE_NONE)
787  {
788  // 1) Print Warning
789  // 2) convert the int to sting
790  // 3) encode string
791  String tmpStr;
792 
793  DEBUG_MSG(WARNING, DEBUG_CONTENT_IO, ("\n>Integer to String conversion required \n"));
794 #if EXIP_IMPLICIT_DATA_TYPE_CONVERSION
795  TRY(integerToString(int_val, &tmpStr));
796  TRY(encodeStringData(strm, tmpStr, qnameID, typeId));
797  EXIP_MFREE(tmpStr.str);
798 #else
799  return EXIP_INVALID_EXI_INPUT;
800 #endif
801  }
802  else
803  {
804  DEBUG_MSG(ERROR, DEBUG_CONTENT_IO, ("\n>Production type is not an Integer\n"));
806  }
807  return EXIP_OK;
808 }