exip  Alpha 0.5.4
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
streamDecode.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 "streamDecode.h"
19 #include "streamRead.h"
20 #include "stringManipulate.h"
21 #include "ioUtil.h"
22 #include <math.h>
23 
24 errorCode decodeNBitUnsignedInteger(EXIStream* strm, unsigned char n, unsigned int* int_val)
25 {
26  DEBUG_MSG(INFO, DEBUG_STREAM_IO, (">> (%d-bits uint)", n));
27  if(n == 0)
28  {
29  *int_val = 0;
30  return EXIP_OK;
31  }
32 
34  {
35  return readBits(strm, n, int_val);
36  }
37  else
38  {
39  unsigned int byte_number = ((unsigned int) n) / 8 + (n % 8 != 0);
40  unsigned long tmp_byte_buf = 0;
41  unsigned int i = 0;
42 
43  if(strm->buffer.bufContent < strm->context.bufferIndx + byte_number)
44  {
45  // The buffer end is reached: there are fewer than byte_number left unparsed
46  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
47 
48  TRY(readEXIChunkForParsing(strm, byte_number));
49  }
50 
51  *int_val = 0;
52  for(i = 0; i < byte_number*8; i += 8)
53  {
54  tmp_byte_buf = strm->buffer.buf[strm->context.bufferIndx] << i;
55  *int_val = *int_val | tmp_byte_buf;
56  strm->context.bufferIndx++;
57  }
58  }
59  return EXIP_OK;
60 }
61 
62 errorCode decodeBoolean(EXIStream* strm, boolean* bool_val)
63 {
64  //TODO: when pattern facets are available in the schema datatype - handle it differently
65  DEBUG_MSG(INFO, DEBUG_STREAM_IO, (">> (bool)"));
66  return decodeNBitUnsignedInteger(strm, 1, bool_val);
67 }
68 
70 {
71  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
72  unsigned int i = 0;
73  unsigned int tmp_byte_buf = 0;
74  *int_val = 0;
75 
76  DEBUG_MSG(INFO, DEBUG_STREAM_IO, (">> (uint)"));
77  do
78  {
79  TRY(readBits(strm, 8, &tmp_byte_buf));
80 
81  *int_val += ((UnsignedInteger) (tmp_byte_buf & 0x7F)) << i;
82  i += 7;
83  }
84  while(tmp_byte_buf & 0x80);
85 
86  return EXIP_OK;
87 }
88 
90 {
91  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
92  UnsignedInteger string_length = 0;
93  DEBUG_MSG(INFO, DEBUG_STREAM_IO, (">> (string)"));
94  TRY(decodeUnsignedInteger(strm, &string_length));
95  TRY(allocateStringMemoryManaged(&(string_val->str),(Index) string_length, &strm->memList));
96 
97  return decodeStringOnly(strm,(Index) string_length, string_val);
98 }
99 
100 errorCode decodeStringOnly(EXIStream* strm, Index str_length, String* string_val)
101 {
102  // Assume no Restricted Character Set is defined
103  //TODO: Handle the case when Restricted Character Set is defined
104 
105  // The exact size of the string is known at this point. This means that
106  // this is the place to allocate the memory for the { CharType* str; }!!!
107  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
108  Index i = 0;
109  Index writerPosition = 0;
110  UnsignedInteger tmp_code_point = 0;
111 
112  string_val->length = str_length;
113 
114  for(i = 0; i < str_length; i++)
115  {
116  TRY(decodeUnsignedInteger(strm, &tmp_code_point));
117  TRY(writeCharToString(string_val, (uint32_t) tmp_code_point, &writerPosition));
118  }
119  return EXIP_OK;
120 }
121 
122 errorCode decodeBinary(EXIStream* strm, char** binary_val, Index* nbytes)
123 {
124  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
125  UnsignedInteger length = 0;
126  unsigned int int_val = 0;
127  UnsignedInteger i = 0;
128 
129  DEBUG_MSG(INFO, DEBUG_STREAM_IO, (">> (binary)"));
130  TRY(decodeUnsignedInteger(strm, &length));
131  *nbytes = (Index) length;
132  (*binary_val) = (char*) EXIP_MALLOC(length); // This memory should be manually freed after the content handler is invoked
133  if((*binary_val) == NULL)
135 
136  for(i = 0; i < length; i++)
137  {
138  TRY_CATCH(readBits(strm, 8, &int_val), EXIP_MFREE(*binary_val));
139  (*binary_val)[i]=(char) int_val;
140  }
141  return EXIP_OK;
142 }
143 
145 {
146  // TODO: If there is associated schema datatype handle differently!
147  // TODO: check if the result fit into int type
148  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
149  boolean bool_val = 0;
150  UnsignedInteger val;
151 
152  DEBUG_MSG(INFO, DEBUG_STREAM_IO, (">> (int)"));
153 
154  TRY(decodeBoolean(strm, &bool_val));
155  TRY(decodeUnsignedInteger(strm, &val));
156 
157  if(bool_val == 0) // A sign value of zero (0) is used to represent positive integers
158  *sint_val = (Integer) val;
159  else if(bool_val == 1) // A sign value of one (1) is used to represent negative integers
160  {
161  val += 1;
162  *sint_val = -((Integer) val);
163  }
164  else
165  return EXIP_UNEXPECTED_ERROR;
166  return EXIP_OK;
167 }
168 
170 {
171  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
172  boolean sign;
173  UnsignedInteger integr_part = 0;
174  UnsignedInteger fract_part = 0;
175  UnsignedInteger fract_part_rev = 0;
176  unsigned int e;
177 
178  DEBUG_MSG(INFO, DEBUG_STREAM_IO, (">> (decimal)"));
179 
180  // TODO: implement checks on type overflow
181 
182  TRY(decodeBoolean(strm, &sign));
183  TRY(decodeUnsignedInteger(strm, &integr_part));
184  TRY(decodeUnsignedInteger(strm, &fract_part));
185 
186  dec_val->exponent = 0;
187  fract_part_rev = 0;
188  while(fract_part > 0)
189  {
190  fract_part_rev = fract_part_rev*10 + fract_part%10;
191  fract_part = fract_part/10;
192  dec_val->exponent -= 1;
193  }
194 
195  dec_val->mantissa = integr_part;
196 
197  e = dec_val->exponent;
198  if(e != 0)
199  {
200  while(e)
201  {
202  dec_val->mantissa *= 10;
203  e++;
204  }
205 
206  dec_val->mantissa += fract_part_rev;
207  }
208 
209  if(sign == TRUE) // negative number
210  dec_val->mantissa = -dec_val->mantissa;
211 
212  return EXIP_OK;
213 }
214 
216 {
217  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
218  Integer mantissa;
219  Integer exponent;
220 
221  DEBUG_MSG(INFO, DEBUG_STREAM_IO, (">> (float)"));
222 
223  TRY(decodeIntegerValue(strm, &mantissa)); //decode mantissa
224  TRY(decodeIntegerValue(strm, &exponent)); //decode exponent
225 
226  DEBUG_MSG(ERROR, DEBUG_STREAM_IO, (">Float value: %ldE%ld\n", (long int)mantissa, (long int)exponent));
227 
228 // TODO: Improve the below validation: it should be independent of how the Float is defined
229 //
230 // if(exponent >= (1 << 14) || exponent < -(1 << 14)
231 // || mantissa >= ((uint64_t) 1 << 63) ||
232 // (mantissa < 0 && -mantissa > ((uint64_t) 1 << 63))
233 // )
234 // {
235 // DEBUG_MSG(ERROR, DEBUG_STREAM_IO, (">Invalid float value: %lldE%lld\n", mantissa, exponent));
236 // return EXIP_INVALID_EXI_INPUT;
237 // }
238 
239  fl_val->mantissa = mantissa;
240  fl_val->exponent = (int16_t)exponent; /* TODO not using exip_config.h */
241 
242  return EXIP_OK;
243 }
244 
246 {
247  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
248  Integer year;
249  unsigned int monDay = 0;
250  unsigned int timeVal = 0;
251  boolean presence = FALSE;
252 
253  dt_val->presenceMask = 0;
254 
255  DEBUG_MSG(INFO, DEBUG_STREAM_IO, (">> (dateTime)"));
256 
257  if(dtType == VALUE_TYPE_DATE_TIME || dtType == VALUE_TYPE_DATE || dtType == VALUE_TYPE_YEAR)
258  {
259  /* Year component */
260  TRY(decodeIntegerValue(strm, &year));
261  dt_val->dateTime.tm_year = (int) year + 100;
262  }
263  else
264  {
265  dt_val->dateTime.tm_year = INT_MIN;
266  }
267 
268  if(dtType == VALUE_TYPE_DATE_TIME || dtType == VALUE_TYPE_DATE || dtType == VALUE_TYPE_MONTH)
269  {
270  /* MonthDay component */
271  TRY(decodeNBitUnsignedInteger(strm, 9, &monDay));
272  dt_val->dateTime.tm_mon = monDay / 32 - 1;
273  dt_val->dateTime.tm_mday = monDay % 32;
274  }
275  else
276  {
277  dt_val->dateTime.tm_mon = INT_MIN;
278  dt_val->dateTime.tm_mday = INT_MIN;
279  }
280 
281  if(dtType == VALUE_TYPE_DATE_TIME || dtType == VALUE_TYPE_TIME)
282  {
283  /* Time component */
284  TRY(decodeNBitUnsignedInteger(strm, 17, &timeVal));
285  dt_val->dateTime.tm_hour = (timeVal / 64) / 64;
286  dt_val->dateTime.tm_min = (timeVal / 64) % 64;
287  dt_val->dateTime.tm_sec = timeVal % 64;
288 
289  /* FractionalSecs presence component */
290  TRY(decodeBoolean(strm, &presence));
291  if(presence)
292  {
293  UnsignedInteger fSecs = 0;
294  unsigned int tmp = 0;
295 
296  dt_val->presenceMask = dt_val->presenceMask | FRACT_PRESENCE;
297  dt_val->fSecs.offset = 0;
298  dt_val->fSecs.value = 0;
299 
300  /* FractionalSecs component */
301  TRY(decodeUnsignedInteger(strm, &fSecs));
302 
303  while(fSecs != 0)
304  {
305  tmp = fSecs % 10;
306  dt_val->fSecs.offset++;
307 
308  if(tmp != 0)
309  {
310  dt_val->fSecs.value = dt_val->fSecs.value*10 + tmp;
311  }
312 
313  fSecs = fSecs / 10;
314  }
315  dt_val->fSecs.offset -= 1;
316  }
317  }
318  else
319  {
320  dt_val->dateTime.tm_hour = INT_MIN;
321  dt_val->dateTime.tm_min = INT_MIN;
322  dt_val->dateTime.tm_sec = INT_MIN;
323  }
324 
325  /* TimeZone presence component */
326  TRY(decodeBoolean(strm, &presence));
327 
328  if(presence)
329  {
330  unsigned int tzone = 0;
331  dt_val->presenceMask = dt_val->presenceMask | TZONE_PRESENCE;
332  TRY(decodeNBitUnsignedInteger(strm, 11, &tzone));
333 
334  if(tzone > 1851)
335  {
336  tzone = 1851;
337  DEBUG_MSG(WARNING, DEBUG_STREAM_IO, (">Invalid TimeZone value: %d\n", tzone));
338  }
339 
340  dt_val->TimeZone = tzone - 896;
341  }
342 
343  return EXIP_OK;
344 }