exip  Alpha 0.5.4
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
headerEncode.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 "headerEncode.h"
19 #include "streamWrite.h"
20 #include "memManagement.h"
21 #include "grammars.h"
22 #include "sTables.h"
23 #include "EXISerializer.h"
24 #include "stringManipulate.h"
25 #include "bodyEncode.h"
26 #include "ioUtil.h"
27 #include "streamEncode.h"
28 
30 extern const EXIPSchema ops_schema;
31 
32 static void closeOptionsStream(EXIStream* strm);
33 static errorCode serializeOptionsStream(EXIStream* options_strm, EXIOptions* opts, UriTable* uriTbl);
34 
36 {
37  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
38 
39  DEBUG_MSG(INFO, DEBUG_CONTENT_IO, (">Start EXI header encoding\n"));
40 
41  if(strm->header.has_cookie)
42  {
43  TRY(writeNBits(strm, 8, 36)); // ASCII code for $ = 00100100 (36)
44  TRY(writeNBits(strm, 8, 69)); // ASCII code for E = 01000101 (69)
45  TRY(writeNBits(strm, 8, 88)); // ASCII code for X = 01011000 (88)
46  TRY(writeNBits(strm, 8, 73)); // ASCII code for I = 01001001 (73)
47  }
48 
49  DEBUG_MSG(INFO, DEBUG_CONTENT_IO, (">Encoding the header Distinguishing Bits\n"));
50  TRY(writeNBits(strm, 2, 2));
51 
52  DEBUG_MSG(INFO, DEBUG_CONTENT_IO, (">Write the Presence Bit for EXI Options\n"));
53  TRY(writeNextBit(strm, strm->header.has_options));
54 
55  DEBUG_MSG(INFO, DEBUG_CONTENT_IO, (">Encode EXI version\n"));
57 
58  if(strm->header.version_number > 15)
59  {
60  TRY(writeNBits(strm, 4, 15));
61  TRY(writeNBits(strm, 4, strm->header.version_number - 15 - 1));
62  }
63  else
64  {
65  TRY(writeNBits(strm, 4, strm->header.version_number - 1));
66  }
67 
68  DEBUG_MSG(INFO, DEBUG_CONTENT_IO, (">Encode EXI options\n"));
69  if(strm->header.has_options)
70  {
71  EXIStream options_strm;
72  QNameID emptyQnameID = {URI_MAX, LN_MAX};
73 
74  makeDefaultOpts(&options_strm.header.opts);
75  SET_STRICT(options_strm.header.opts.enumOpt);
76  TRY(initAllocList(&options_strm.memList));
77 
78  options_strm.buffer = strm->buffer;
79  options_strm.context.bitPointer = strm->context.bitPointer;
80  options_strm.context.bufferIndx = strm->context.bufferIndx;
81  options_strm.context.currAttr.lnId = LN_MAX;
82  options_strm.context.currAttr.uriId = URI_MAX;
83  options_strm.context.expectATData = FALSE;
84  options_strm.context.isNilType = FALSE;
85  options_strm.context.attrTypeId = 0;
86  options_strm.gStack = NULL;
87  options_strm.schema = (EXIPSchema*) &ops_schema;
88 
89  TRY_CATCH(createValueTable(&options_strm.valueTable), closeOptionsStream(&options_strm));
90  TRY_CATCH(pushGrammar(&options_strm.gStack, emptyQnameID, (EXIGrammar*) &ops_schema.docGrammar), closeOptionsStream(&options_strm));
91  TRY_CATCH(serializeOptionsStream(&options_strm, &strm->header.opts, &strm->schema->uriTable), closeOptionsStream(&options_strm));
92 
93  strm->buffer.bufContent = options_strm.buffer.bufContent;
94  strm->context.bitPointer = options_strm.context.bitPointer;
95  strm->context.bufferIndx = options_strm.context.bufferIndx;
96 
97  if(WITH_COMPRESSION(strm->header.opts.enumOpt) ||
99  {
100  // Padding bits
101  if(strm->context.bitPointer != 0)
102  {
103  strm->context.bitPointer = 0;
104  strm->context.bufferIndx += 1;
105  }
106  }
107 
108  closeOptionsStream(&options_strm);
109  }
110 
111  return EXIP_OK;
112 }
113 
114 static void closeOptionsStream(EXIStream* strm)
115 {
116  while(strm->gStack != NULL)
117  {
118  popGrammar(&strm->gStack);
119  }
120  freeAllMem(strm);
121 }
122 
123 static errorCode serializeOptionsStream(EXIStream* options_strm, EXIOptions* opts, UriTable* uriTbl)
124 {
125  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
126  EventCode tmpEvCode;
127  boolean hasUncommon = FALSE;
128  boolean hasLesscommon = FALSE;
129  boolean hasCommon = FALSE;
130  unsigned int ruleContext = 0;
131 
132  // Implicit serialize.startDocument (0 bits)
133  tmpEvCode.length = 1;
134  tmpEvCode.part[0] = 0;
135  tmpEvCode.bits[0] = 1;
136  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.startElement <header>
137 
138  // uncommon options
139  if(GET_ALIGNMENT(opts->enumOpt) != BIT_PACKED ||
140  WITH_SELF_CONTAINED(opts->enumOpt) ||
141  opts->valueMaxLength != INDEX_MAX ||
143  opts->drMap != NULL)
144  {
145  hasUncommon = TRUE;
146  hasLesscommon = TRUE;
147  }
148  else if(opts->preserve != 0 || opts->blockSize != 1000000)
149  {
150  // lesscommon options
151  hasLesscommon = TRUE;
152  }
153 
154  if(hasLesscommon)
155  {
156  tmpEvCode.length = 1;
157  tmpEvCode.part[0] = 0;
158  tmpEvCode.bits[0] = 2;
159  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.startElement <lesscommon>
160  if(hasUncommon)
161  {
162  tmpEvCode.length = 1;
163  tmpEvCode.part[0] = 0;
164  tmpEvCode.bits[0] = 2;
165  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.startElement <uncommon>
166  ruleContext = 0;
167  if(GET_ALIGNMENT(opts->enumOpt) != BIT_PACKED)
168  {
169  tmpEvCode.length = 1;
170  tmpEvCode.part[0] = 0;
171  tmpEvCode.bits[0] = 3;
172  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.startElement <alignment>
173  ruleContext = 1;
174  if(GET_ALIGNMENT(opts->enumOpt) == BYTE_ALIGNMENT)
175  {
176  tmpEvCode.length = 1;
177  tmpEvCode.part[0] = 0;
178  tmpEvCode.bits[0] = 1;
179  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.startElement <byte>
180  }
181  else
182  {
183  tmpEvCode.length = 1;
184  tmpEvCode.part[0] = 1;
185  tmpEvCode.bits[0] = 1;
186  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.startElement <pre-compress>
187  }
188  tmpEvCode.length = 1;
189  tmpEvCode.part[0] = 0;
190  tmpEvCode.bits[0] = 0;
191  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.endElement <byte> or <pre-compress>
192  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.endElement <alignment>
193  }
194  if(WITH_SELF_CONTAINED(opts->enumOpt))
195  {
196  tmpEvCode.length = 1;
197  tmpEvCode.part[0] = 1 - ruleContext;
198  tmpEvCode.bits[0] = 3;
199  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.startElement <selfContained>
200  ruleContext = 2;
201  tmpEvCode.length = 1;
202  tmpEvCode.part[0] = 0;
203  tmpEvCode.bits[0] = 0;
204  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.endElement <selfContained>
205  }
206  if(opts->valueMaxLength != INDEX_MAX)
207  {
208  tmpEvCode.length = 1;
209  tmpEvCode.part[0] = 2 - ruleContext;
210  tmpEvCode.bits[0] = 3 - (ruleContext == 2);
211  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.startElement <valueMaxLength>
212  ruleContext = 3;
213  TRY(serialize.intData(options_strm, opts->valueMaxLength));
214  tmpEvCode.length = 1;
215  tmpEvCode.part[0] = 0;
216  tmpEvCode.bits[0] = 0;
217  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.endElement <valueMaxLength>
218  }
219  if(opts->valuePartitionCapacity != INDEX_MAX)
220  {
221  tmpEvCode.length = 1;
222  tmpEvCode.part[0] = 3 - ruleContext;
223  tmpEvCode.bits[0] = 3 - (tmpEvCode.part[0] < 2);
224  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.startElement <valuePartitionCapacity>
225  ruleContext = 4;
226  TRY(serialize.intData(options_strm, opts->valuePartitionCapacity));
227  tmpEvCode.length = 1;
228  tmpEvCode.part[0] = 0;
229  tmpEvCode.bits[0] = 0;
230  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.endElement <valuePartitionCapacity>
231  }
232  if(opts->drMap != NULL)
233  {
234  tmpEvCode.length = 1;
235  tmpEvCode.part[0] = 4 - ruleContext;
236  tmpEvCode.bits[0] = 3 - (tmpEvCode.part[0] < 3) - (tmpEvCode.part[0] == 0);
237  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.startElement <datatypeRepresentationMap>
238  ruleContext = 5;
239  // TODO: not ready yet!
241  }
242  tmpEvCode.length = 1;
243  tmpEvCode.part[0] = 6 - ruleContext - (ruleContext > 0);
244  tmpEvCode.bits[0] = getBitsNumber(tmpEvCode.part[0]);
245  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.endElement <uncommon>
246  }
247  if(opts->preserve != 0)
248  {
249  tmpEvCode.length = 1;
250  tmpEvCode.part[0] = 1 - hasUncommon;
251  tmpEvCode.bits[0] = 2;
252  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.startElement <preserve>
253  ruleContext = 0;
255  {
256  tmpEvCode.length = 1;
257  tmpEvCode.part[0] = 0;
258  tmpEvCode.bits[0] = 3;
259  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.startElement <dtd>
260  ruleContext = 1;
261  tmpEvCode.bits[0] = 0;
262  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.endElement <dtd>
263  }
265  {
266  tmpEvCode.length = 1;
267  tmpEvCode.part[0] = 1 - ruleContext;
268  tmpEvCode.bits[0] = 3;
269  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.startElement <prefixes>
270  ruleContext = 2;
271  tmpEvCode.length = 1;
272  tmpEvCode.part[0] = 0;
273  tmpEvCode.bits[0] = 0;
274  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.endElement <prefixes>
275  }
277  {
278  tmpEvCode.length = 1;
279  tmpEvCode.part[0] = 2 - ruleContext;
280  tmpEvCode.bits[0] = 3 - (ruleContext == 2);
281  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.startElement <lexicalValues>
282  ruleContext = 3;
283  tmpEvCode.length = 1;
284  tmpEvCode.part[0] = 0;
285  tmpEvCode.bits[0] = 0;
286  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.endElement <lexicalValues>
287  }
289  {
290  tmpEvCode.length = 1;
291  tmpEvCode.part[0] = 3 - ruleContext;
292  tmpEvCode.bits[0] = 3 - (tmpEvCode.part[0] < 2);
293  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.startElement <comments>
294  ruleContext = 4;
295  tmpEvCode.length = 1;
296  tmpEvCode.part[0] = 0;
297  tmpEvCode.bits[0] = 0;
298  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.endElement <comments>
299  }
301  {
302  tmpEvCode.length = 1;
303  tmpEvCode.part[0] = 4 - ruleContext;
304  tmpEvCode.bits[0] = 3 - (tmpEvCode.part[0] < 3) - (tmpEvCode.part[0] == 0);
305  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.startElement <pis>
306  ruleContext = 5;
307  tmpEvCode.length = 1;
308  tmpEvCode.part[0] = 0;
309  tmpEvCode.bits[0] = 0;
310  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.endElement <pis>
311  }
312  tmpEvCode.length = 1;
313  tmpEvCode.part[0] = 5 - ruleContext;
314  tmpEvCode.bits[0] = getBitsNumber(tmpEvCode.part[0]);
315  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.endElement <preserve>
316  }
317  if(opts->blockSize != 1000000)
318  {
319  tmpEvCode.length = 1;
320  tmpEvCode.part[0] = opts->preserve != 0 ? 0 : (2 - hasUncommon);
321  tmpEvCode.bits[0] = 2 - (opts->preserve != 0);
322  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.startElement <blockSize>
323  TRY(serialize.intData(options_strm, opts->blockSize));
324  tmpEvCode.length = 1;
325  tmpEvCode.part[0] = 0;
326  tmpEvCode.bits[0] = 0;
327  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.endElement <blockSize>
328  }
329  tmpEvCode.length = 1;
330  tmpEvCode.part[0] = opts->blockSize != 1000000 ? 0 : (opts->preserve != 0 ? 1 : 3 - hasUncommon);
331  tmpEvCode.bits[0] = getBitsNumber(tmpEvCode.part[0]);
332  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.endElement <lesscommon>
333  }
334 
335  // common options if any...
337  {
338  hasCommon = TRUE;
339  }
340 
341  if(hasCommon)
342  {
343  tmpEvCode.length = 1;
344  tmpEvCode.part[0] = 1 - hasLesscommon;
345  tmpEvCode.bits[0] = 2;
346  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.startElement <common>
347  ruleContext = 0;
348  if(WITH_COMPRESSION(opts->enumOpt))
349  {
350  tmpEvCode.length = 1;
351  tmpEvCode.part[0] = 0;
352  tmpEvCode.bits[0] = 2;
353  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.startElement <compression>
354  ruleContext = 1;
355  tmpEvCode.bits[0] = 0;
356  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.endElement <compression>
357  }
358  if(WITH_FRAGMENT(opts->enumOpt))
359  {
360  tmpEvCode.length = 1;
361  tmpEvCode.part[0] = 1 - ruleContext;
362  tmpEvCode.bits[0] = 2;
363  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.startElement <fragment>
364  ruleContext = 2;
365  tmpEvCode.length = 1;
366  tmpEvCode.part[0] = 0;
367  tmpEvCode.bits[0] = 0;
368  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.endElement <fragment>
369  }
370  if(opts->schemaIDMode != SCHEMA_ID_ABSENT)
371  {
372  tmpEvCode.length = 1;
373  tmpEvCode.part[0] = 2 - ruleContext;
374  tmpEvCode.bits[0] = 2 - (ruleContext == 2);
375  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.startElement <schemaId>
376  ruleContext = 3;
377 
378  if(opts->schemaIDMode == SCHEMA_ID_EMPTY)
379  {
380  String empty;
381  getEmptyString(&empty);
382  TRY(serialize.stringData(options_strm, empty));
383  }
384  else if(opts->schemaID.length == SCHEMA_ID_NIL)
385  {
386  QName nil;
387  nil.uri = &uriTbl->uri[XML_SCHEMA_INSTANCE_ID].uriStr;
389  nil.prefix = &uriTbl->uri[XML_SCHEMA_INSTANCE_ID].pfxTable.pfx[0];
390  tmpEvCode.length = 2;
391  tmpEvCode.part[0] = 1;
392  tmpEvCode.bits[0] = 1;
393  tmpEvCode.part[1] = 0;
394  tmpEvCode.bits[1] = 0;
395  TRY(serializeEvent(options_strm, tmpEvCode, &nil)); // serialize.attribute nil="true"
396  TRY(serialize.booleanData(options_strm, TRUE));
397  }
398  else
399  {
400  TRY(serialize.stringData(options_strm, opts->schemaID));
401  }
402 
403  tmpEvCode.length = 1;
404  tmpEvCode.part[0] = 0;
405  tmpEvCode.bits[0] = 0;
406  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.endElement <schemaId>
407  }
408  tmpEvCode.length = 1;
409  tmpEvCode.part[0] = 3 - ruleContext;
410  tmpEvCode.bits[0] = getBitsNumber(tmpEvCode.part[0]);
411  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.endElement <common>
412  }
413 
414  if(WITH_STRICT(opts->enumOpt))
415  {
416  tmpEvCode.length = 1;
417  tmpEvCode.part[0] = hasCommon? 0 : 2 - hasLesscommon;
418  tmpEvCode.bits[0] = 2 - hasCommon;
419  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.startElement <strict>
420  tmpEvCode.length = 1;
421  tmpEvCode.part[0] = 0;
422  tmpEvCode.bits[0] = 0;
423  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.endElement <strict>
424  }
425 
426  tmpEvCode.length = 1;
427  tmpEvCode.part[0] = WITH_STRICT(opts->enumOpt)? 0 : (hasCommon? 1 : 3 - hasLesscommon);
428  tmpEvCode.bits[0] = getBitsNumber(tmpEvCode.part[0]);
429  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.endElement <header>
430 
431  tmpEvCode.length = 1;
432  tmpEvCode.part[0] = 0;
433  tmpEvCode.bits[0] = 0;
434  TRY(serializeEvent(options_strm, tmpEvCode, NULL)); // serialize.endDocument
435 
436  return tmp_err_code;
437 }