blob: 2dfa6cac2de2d8e46fb9e6a13e1384ff3d5f71a0 [file] [log] [blame]
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001/* csn1.cpp
2 * Routines for CSN1 dissection in wireshark.
3 *
4 * Copyright (C) 2011 Ivan Klyuchnikov
5 *
6 * By Vincent Helfre, based on original code by Jari Sassi
7 * with the gracious authorization of STE
8 * Copyright (c) 2011 ST-Ericsson
9 *
10 * $Id: packet-csn1.c 39140 2011-09-25 22:01:50Z wmeier $
11 *
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */
30
31#include <iostream>
32#include <cstdlib>
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +040033#include <assert.h>
34#include <string.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030035#include "csn1.h"
Andreas Eversberg31dcbb62012-07-26 13:18:48 +020036extern "C" {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +040037#include <gprs_debug.h>
Andreas Eversberg31dcbb62012-07-26 13:18:48 +020038}
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030039
40
41#define pvDATA(_pv, _offset) ((void*) ((unsigned char*)_pv + _offset))
42#define pui8DATA(_pv, _offset) ((guint8*) pvDATA(_pv, _offset))
43#define pui16DATA(_pv, _offset) ((guint16*) pvDATA(_pv, _offset))
44#define pui32DATA(_pv, _offset) ((guint32*) pvDATA(_pv, _offset))
45#define pui64DATA(_pv, _offset) ((guint64*) pvDATA(_pv, _offset))
46/* used to tag existence of next element in variable length lists */
47#define STANDARD_TAG 1
48#define REVERSED_TAG 0
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030049
50using namespace std;
51static const unsigned char ixBitsTab[] = {0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5};
52
53
54/* Returns no_of_bits (up to 8) masked with 0x2B */
55
56static guint8
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +040057get_masked_bits8( bitvec *vector, unsigned& readIndex, gint bit_offset, const gint no_of_bits)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030058{
59 static const guint8 maskBits[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
60 //gint byte_offset = bit_offset >> 3; /* divide by 8 */
61 gint relative_bit_offset = bit_offset & 0x07; /* modulo 8 */
62 guint8 result;
63 gint bit_shift = 8 - relative_bit_offset - (gint) no_of_bits;
64 readIndex -= relative_bit_offset;
65 if (bit_shift >= 0)
66 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +040067 result = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) >> bit_shift;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030068 readIndex-= bit_shift;
69 result &= maskBits[no_of_bits];
70 }
71 else
72 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +040073 guint8 hight_part = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) & maskBits[8 - relative_bit_offset];
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030074 hight_part = (guint8) (hight_part << (-bit_shift));
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +040075 result = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) >> (8 + bit_shift);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030076 readIndex = readIndex - (8 - (-bit_shift));
77 result |= hight_part;
78 }
79 return result;
80}
81
82/**
83 * ================================================================================================
84 * set initial/start values in help data structure used for packing/unpacking operation
85 * ================================================================================================
86 */
87void
88csnStreamInit(csnStream_t* ar, gint bit_offset, gint remaining_bits_len)
89{
90 ar->remaining_bits_len = remaining_bits_len;
91 ar->bit_offset = bit_offset;
92}
93
94static const char* ErrCodes[] =
95{
96 "General 0",
97 "General -1",
98 "DATA_NOT VALID",
99 "IN SCRIPT",
100 "INVALID UNION INDEX",
101 "NEED_MORE BITS TO UNPACK",
102 "ILLEGAL BIT VALUE",
103 "Internal",
104 "STREAM_NOT_SUPPORTED",
105 "MESSAGE_TOO_LONG"
106};
107
108static gint16
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400109ProcessError( unsigned readIndex, const char* sz, gint16 err, const CSN_DESCR* pDescr)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300110{
111 gint16 i = MIN(-err, ((gint16) ElementsOf(ErrCodes)-1));
112 if (i >= 0)
113 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400114 //LOG(ERR) << sz << "Error code: "<< ErrCodes[i] << pDescr?(pDescr->sz):"-";
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300115 }
116 else
117 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400118 //LOG(ERR) << sz << ": " << pDescr?(pDescr->sz):"-";
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300119 }
120 return err;
121}
122
123//#if 0
124static const char* CSN_DESCR_type[]=
125{
126 "CSN_END",
127 "CSN_BIT",
128 "CSN_UINT",
129 "CSN_TYPE",
130 "CSN_CHOICE",
131 "CSN_UNION",
132 "CSN_UNION_LH",
133 "CSN_UINT_ARRAY",
134 "CSN_TYPE_ARRAY",
135 "CSN_BITMAP",
136 "CSN_VARIABLE_BITMAP",
137 "CSN_VARIABLE_BITMAP_1",
138 "CSN_LEFT_ALIGNED_VAR_BMP",
139 "CSN_LEFT_ALIGNED_VAR_BMP_1",
140 "CSN_VARIABLE_ARRAY",
141 "CSN_VARIABLE_TARRAY",
142 "CSN_VARIABLE_TARRAY_OFFSET",
143 "CSN_RECURSIVE_ARRAY",
144 "CSN_RECURSIVE_TARRAY",
145 "CSN_RECURSIVE_TARRAY_1",
146 "CSN_RECURSIVE_TARRAY_2",
147 "CSN_EXIST",
148 "CSN_EXIST_LH",
149 "CSN_NEXT_EXIST",
150 "CSN_NEXT_EXIST_LH",
151 "CSN_NULL",
152 "CSN_FIXED",
153 "CSN_CALLBACK",
154 "CSN_UINT_OFFSET",
155 "CSN_UINT_LH",
156 "CSN_SERIALIZE",
157 "CSN_TRAP_ERROR"
158 "CSN_???"
159};
160//#endif
161
162/**
163 * ================================================================================================
164 * Return TRUE if tag in bit stream indicates existence of next list element,
165 * otherwise return FALSE.
166 * Will work for tag values equal to both 0 and 1.
167 * ================================================================================================
168 */
169
170static gboolean
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400171existNextElement(bitvec *vector, unsigned& readIndex, guint8 Tag)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300172{
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400173 guint8 res = bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300174 if (Tag == STANDARD_TAG)
175 {
176 return (res > 0);
177 }
178 return (res == 0);
179}
180
181
182gint16
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400183csnStreamDecoder(csnStream_t* ar, const CSN_DESCR* pDescr, bitvec *vector, unsigned& readIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300184{
185 gint remaining_bits_len = ar->remaining_bits_len;
186 gint bit_offset = ar->bit_offset;
187 guint8* pui8;
188 guint16* pui16;
189 guint32* pui32;
190 guint64* pui64;
191 guint8 Tag = STANDARD_TAG;
192
193 if (remaining_bits_len <= 0)
194 {
195 return 0;
196 }
197
198 do
199 {
200 switch (pDescr->type)
201 {
202 case CSN_BIT:
203 {
204 if (remaining_bits_len > 0)
205 {
206 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400207 *pui8 = bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400208 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300209 /* end add the bit value to protocol tree */
210 }
211 else
212 {
213 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
214 }
215
216 pDescr++;
217 remaining_bits_len--;
218 bit_offset++;
219 break;
220 }
221
222 case CSN_NULL:
223 { /* Empty member! */
224 pDescr++;
225 break;
226 }
227
228 case CSN_UINT:
229 {
230 guint8 no_of_bits = (guint8) pDescr->i;
231
232 if (remaining_bits_len >= no_of_bits)
233 {
234 if (no_of_bits <= 8)
235 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400236 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300237 pui8 = pui8DATA(data, pDescr->offset);
238 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400239 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300240 }
241 else if (no_of_bits <= 16)
242 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400243 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300244 pui16 = pui16DATA(data, pDescr->offset);
245 *pui16 = ui16;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400246 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300247 }
248 else if (no_of_bits <= 32)
249 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400250 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300251 pui32 = pui32DATA(data, pDescr->offset);
252 *pui32 = ui32;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400253 LOGPC(DCSN1, LOGL_NOTICE, "%s = 0x%08x | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300254 }
255 else
256 {
257 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
258 }
259 }
260 else
261 {
262 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
263 }
264
265 remaining_bits_len -= no_of_bits;
266 bit_offset += no_of_bits;
267 pDescr++;
268 break;
269 }
270
271 case CSN_UINT_OFFSET:
272 {
273 guint8 no_of_bits = (guint8) pDescr->i;
274
275 if (remaining_bits_len >= no_of_bits)
276 {
277 if (no_of_bits <= 8)
278 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400279 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300280 pui8 = pui8DATA(data, pDescr->offset);
281 *pui8 = ui8 + (guint8)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400282 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300283 }
284 else if (no_of_bits <= 16)
285 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400286 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300287 pui16 = pui16DATA(data, pDescr->offset);
288 *pui16 = ui16 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400289 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300290 }
291 else if (no_of_bits <= 32)
292 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400293 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300294 pui32 = pui32DATA(data, pDescr->offset);
295 *pui32 = ui32 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400296 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300297 }
298 else
299 {
300 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
301 }
302 }
303 else
304 {
305 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
306 }
307
308 remaining_bits_len -= no_of_bits;
309 bit_offset += no_of_bits;
310 pDescr++;
311 break;
312 }
313
314 case CSN_UINT_LH:
315 {
316 guint8 no_of_bits = (guint8) pDescr->i;
317
318 if (remaining_bits_len >= no_of_bits)
319 {
320 remaining_bits_len -= no_of_bits;
321 if (no_of_bits <= 8)
322 {
323 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
324 pui8 = pui8DATA(data, pDescr->offset);
325 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400326 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300327 }
328 else
329 {/* Maybe we should support more than 8 bits ? */
330 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
331 }
332 }
333 else
334 {
335 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
336 }
337
338 remaining_bits_len -= no_of_bits;
339 bit_offset += no_of_bits;
340 pDescr++;
341 break;
342 }
343
344 case CSN_UINT_ARRAY:
345 {
346 guint8 no_of_bits = (guint8) pDescr->i;
347 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
348
349 if (pDescr->serialize.value != 0)
350 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
351 nCount = *pui16DATA(data, nCount);
352 }
353
354 if (remaining_bits_len >= no_of_bits)
355 {
356 remaining_bits_len -= (no_of_bits*nCount);
357 if (no_of_bits <= 8)
358 {
359 pui8 = pui8DATA(data, pDescr->offset);
360 do
361 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400362 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400363 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300364 pui8++;
365 bit_offset += no_of_bits;
366 } while (--nCount > 0);
367 }
368 else if (no_of_bits <= 16)
369 {
370 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
371 }
372 else if (no_of_bits <= 32)
373 {
374 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
375 }
376 else
377 {
378 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
379 }
380 }
381 else
382 {
383 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
384 }
385 pDescr++;
386 break;
387 }
388
389 case CSN_VARIABLE_TARRAY_OFFSET:
390 case CSN_VARIABLE_TARRAY:
391 case CSN_TYPE_ARRAY:
392 {
393 gint16 Status;
394 csnStream_t arT = *ar;
395 gint16 nCount = pDescr->i;
396 guint16 nSize = (guint16)(gint32)pDescr->serialize.value;
397
398 pui8 = pui8DATA(data, pDescr->offset);
399 if (pDescr->type == CSN_VARIABLE_TARRAY)
400 { /* Count specified in field */
401 nCount = *pui8DATA(data, pDescr->i);
402 }
403 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
404 { /* Count specified in field */
405 nCount = *pui8DATA(data, pDescr->i);
406 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
407 }
408
409 while (nCount > 0)
410 { /* resulting array of length 0 is possible
411 * but no bits shall be read from bitstream
412 */
413
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400414 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300415 csnStreamInit(&arT, bit_offset, remaining_bits_len);
416 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
417 if (Status >= 0)
418 {
419 pui8 += nSize;
420 remaining_bits_len = arT.remaining_bits_len;
421 bit_offset = arT.bit_offset;
422 }
423 else
424 {
425 return Status;
426 }
427 nCount--;
428 }
429
430 pDescr++;
431 break;
432 }
433
434 case CSN_BITMAP:
435 { /* bitmap with given length. The result is left aligned! */
436 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
437
438 if (no_of_bits > 0)
439 {
440
441 if (no_of_bits <= 32)
442 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400443 for(unsigned ib = 0; ib < 4; ib++)
444 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400445 guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400446 pui8 = pui8DATA(data, pDescr->offset+ib);
447 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400448 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400449 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300450 }
451 else if (no_of_bits <= 64)
452 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400453 for(unsigned ib = 0; ib < 8; ib++)
454 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400455 guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400456 pui8 = pui8DATA(data, pDescr->offset+ib);
457 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400458 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400459 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300460 }
461 else
462 {
463 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
464 }
465
466 remaining_bits_len -= no_of_bits;
467 assert(remaining_bits_len >= 0);
468 bit_offset += no_of_bits;
469 }
470 /* bitmap was successfully extracted or it was empty */
471
472 pDescr++;
473 break;
474 }
475
476 case CSN_TYPE:
477 {
478 gint16 Status;
479 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400480 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300481 csnStreamInit(&arT, bit_offset, remaining_bits_len);
482 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400483 LOGPC(DCSN1, LOGL_NOTICE, ": End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300484 if (Status >= 0)
485 {
486 remaining_bits_len = arT.remaining_bits_len;
487 bit_offset = arT.bit_offset;
488 pDescr++;
489 }
490 else
491 {
492 /* Has already been processed: ProcessError("csnStreamDecoder", Status, pDescr); */
493 return Status;
494 }
495
496 break;
497 }
498
499 case CSN_CHOICE:
500 {
501 gint16 count = pDescr->i;
502 guint8 i = 0;
503 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
504
505 while (count > 0)
506 {
507 guint8 no_of_bits = pChoice->bits;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400508 guint8 value = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300509 if (value == pChoice->value)
510 {
511 CSN_DESCR descr[2];
512 gint16 Status;
513 csnStream_t arT = *ar;
514
515 descr[0] = pChoice->descr;
516 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
517 descr[1].type = CSN_END;
518 pui8 = pui8DATA(data, pDescr->offset);
519 *pui8 = i;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400520 LOGPC(DCSN1, LOGL_NOTICE, "Choice %s = %u | ", pDescr->sz , (unsigned)value);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300521 bit_offset += no_of_bits;
522 remaining_bits_len -= no_of_bits;
523
524 csnStreamInit(&arT, bit_offset, remaining_bits_len);
525 Status = csnStreamDecoder(&arT, descr, vector, readIndex, data);
526
527 if (Status >= 0)
528 {
529 remaining_bits_len = arT.remaining_bits_len;
530 bit_offset = arT.bit_offset;
531 }
532 else
533 {
534 return Status;
535 }
536 break;
537 }
538
539 readIndex -= no_of_bits;
540 count--;
541 pChoice++;
542 i++;
543 }
544
545 pDescr++;
546 break;
547 }
548
549 case CSN_SERIALIZE:
550 {
551 StreamSerializeFcn_t serialize = pDescr->serialize.fcn;
552 csnStream_t arT = *ar;
553 gint16 Status = -1;
554
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400555 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %d | ", pDescr->sz , (int)bitvec_read_field(vector, readIndex, 7));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300556 arT.direction = 1;
557 bit_offset += 7;
558 remaining_bits_len -= 7;
559
560 csnStreamInit(&arT, bit_offset, remaining_bits_len);
561 Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset));
562
563 if (Status >= 0)
564 {
565 remaining_bits_len = arT.remaining_bits_len;
566 bit_offset = arT.bit_offset;
567 pDescr++;
568 }
569 else
570 {
571 /* Has already been processed: */
572 return Status;
573 }
574
575 break;
576 }
577
578 case CSN_UNION_LH:
579 case CSN_UNION:
580 {
581 gint16 Bits;
582 guint8 index;
583 gint16 count = pDescr->i;
584 const CSN_DESCR* pDescrNext = pDescr;
585
586 pDescrNext += count + 1; /* now this is next after the union */
587 if ((count <= 0) || (count > 16))
588 {
589 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
590 }
591
592 /* Now get the bits to extract the index */
593 Bits = ixBitsTab[count];
594 index = 0;
595
596 while (Bits > 0)
597 {
598 index <<= 1;
599
600 if (CSN_UNION_LH == pDescr->type)
601 {
602 index |= get_masked_bits8(vector,readIndex, bit_offset, 1);
603 }
604 else
605 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400606 index |= bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300607 }
608 remaining_bits_len--;
609 bit_offset++;
610 Bits--;
611 }
612
613 /* Assign UnionType */
614 pui8 = pui8DATA(data, pDescr->offset);
615 *pui8 = index;
616
617
618 /* script index to continue on, limited in case we do not have a power of 2 */
619 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400620 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300621
622 switch (pDescr->type)
623 { /* get the right element of the union based on computed index */
624
625 case CSN_BIT:
626 {
627 pui8 = pui8DATA(data, pDescr->offset);
628 *pui8 = 0x00;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400629 if (bitvec_read_field(vector, readIndex, 1) > 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300630 {
631 *pui8 = 0x01;
632 }
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400633 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300634 remaining_bits_len -= 1;
635 bit_offset++;
636 pDescr++;
637 break;
638 }
639
640 case CSN_NULL:
641 { /* Empty member! */
642 pDescr++;
643 break;
644 }
645
646 case CSN_UINT:
647 {
648 guint8 no_of_bits = (guint8) pDescr->i;
649 if (remaining_bits_len >= no_of_bits)
650 {
651 remaining_bits_len -= no_of_bits;
652
653 if (no_of_bits <= 8)
654 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400655 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300656 pui8 = pui8DATA(data, pDescr->offset);
657 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400658 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300659 }
660 else if (no_of_bits <= 16)
661 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400662 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300663 pui16 = pui16DATA(data, pDescr->offset);
664 *pui16 = ui16;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400665 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300666 }
667 else if (no_of_bits <= 32)
668 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400669 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300670 pui32 = pui32DATA(data, pDescr->offset);
671 *pui32 = ui32;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400672 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300673 }
674 else
675 {
676 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
677 }
678 }
679 else
680 {
681 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
682 }
683
684 bit_offset += no_of_bits;
685 pDescr++;
686 break;
687 }
688
689 case CSN_UINT_OFFSET:
690 {
691 guint8 no_of_bits = (guint8) pDescr->i;
692
693 if (remaining_bits_len >= no_of_bits)
694 {
695 if (no_of_bits <= 8)
696 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400697 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300698 pui8 = pui8DATA(data, pDescr->offset);
699 *pui8 = ui8 + (guint8)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400700 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300701 }
702 else if (no_of_bits <= 16)
703 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400704 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300705 pui16 = pui16DATA(data, pDescr->offset);
706 *pui16 = ui16 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400707 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300708 }
709 else if (no_of_bits <= 32)
710 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400711 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300712 pui32 = pui32DATA(data, pDescr->offset);
713 *pui32 = ui32 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400714 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300715 }
716 else
717 {
718 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
719 }
720 }
721 else
722 {
723 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
724 }
725
726 bit_offset += no_of_bits;
727 pDescr++;
728 break;
729 }
730
731 case CSN_UINT_LH:
732 {
733 guint8 no_of_bits = (guint8) pDescr->i;
734
735 if (remaining_bits_len >= no_of_bits)
736 {
737 if (no_of_bits <= 8)
738 {
739 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
740 pui8 = pui8DATA(data, pDescr->offset);
741 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400742 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300743 }
744 else
745 { /* Maybe we should support more than 8 bits ? */
746 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
747 }
748 }
749 else
750 {
751 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
752 }
753
754 bit_offset += no_of_bits;
755 pDescr++;
756 break;
757 }
758
759 case CSN_UINT_ARRAY:
760 {
761 guint8 no_of_bits = (guint8) pDescr->i;
762 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
763
764 if (pDescr->serialize.value != 0)
765 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
766 nCount = *pui16DATA(data, nCount);
767 }
768
769 if (remaining_bits_len >= no_of_bits)
770 {
771 remaining_bits_len -= (no_of_bits * nCount);
772 if (no_of_bits <= 8)
773 {
774 pui8 = pui8DATA(data, pDescr->offset);
775
776 while (nCount > 0)
777 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400778 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400779 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300780 pui8++;
781 bit_offset += no_of_bits;
782 nCount--;
783 }
784 }
785 else if (no_of_bits <= 16)
786 {
787 pui16 = pui16DATA(data, pDescr->offset);
788
789 while (nCount > 0)
790 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400791 *pui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400792 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300793 pui16++;
794 bit_offset += no_of_bits;
795 nCount--;
796 }
797 }
798 else if (no_of_bits <= 32)
799 { /* not supported */
800 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
801 }
802 else
803 {
804 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
805 }
806 }
807 else
808 {
809 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
810 }
811
812 pDescr++;
813 break;
814 }
815
816 case CSN_VARIABLE_TARRAY_OFFSET:
817 case CSN_VARIABLE_TARRAY:
818 case CSN_TYPE_ARRAY:
819 {
820 gint16 Status;
821 csnStream_t arT = *ar;
822 guint16 nCount = (guint16) pDescr->i;
823 guint16 nSize = (guint16)(guint32)pDescr->serialize.value;
824
825 pui8 = pui8DATA(data, pDescr->offset);
826
827 if (CSN_VARIABLE_TARRAY == pDescr->type)
828 { /* Count specified in field */
829 nCount = *pui8DATA(data, pDescr->i);
830 }
831 else if (CSN_VARIABLE_TARRAY_OFFSET == pDescr->type)
832 { /* Count specified in field */
833 nCount = *pui8DATA(data, pDescr->i);
834 nCount--; /* Offset 1 */
835 }
836
837 while (nCount--) /* Changed to handle length = 0. */
838 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400839 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300840 csnStreamInit(&arT, bit_offset, remaining_bits_len);
841 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
842 if (Status >= 0)
843 {
844 pui8 += nSize;
845 remaining_bits_len = arT.remaining_bits_len;
846 bit_offset = arT.bit_offset;
847 }
848 else
849 {
850 return Status;
851 }
852 }
853
854 pDescr++;
855 break;
856 }
857
858 case CSN_BITMAP:
859 { /* bitmap with given length. The result is left aligned! */
860 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
861
862 if (no_of_bits > 0)
863 {
864
865 if (no_of_bits <= 32)
866 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400867 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300868 pui32 = pui32DATA(data, pDescr->offset);
869 *pui32 = ui32;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300870 }
871 else if (no_of_bits <= 64)
872 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400873 guint64 ui64 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300874 pui64 = pui64DATA(data, pDescr->offset);
875 *pui64 = ui64;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400876 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300877 }
878 else
879 {
880 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
881 }
882
883 remaining_bits_len -= no_of_bits;
884 assert(remaining_bits_len >= 0);
885 bit_offset += no_of_bits;
886 }
887 /* bitmap was successfully extracted or it was empty */
888
889 pDescr++;
890 break;
891 }
892
893 case CSN_TYPE:
894 {
895 gint16 Status;
896 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400897 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300898 csnStreamInit(&arT, bit_offset, remaining_bits_len);
899 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400900 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300901 if (Status >= 0)
902 {
903 remaining_bits_len = arT.remaining_bits_len;
904 bit_offset = arT.bit_offset;
905 pDescr++;
906 }
907 else
908 { /* return error code Has already been processed: */
909 return Status;
910 }
911
912 break;
913 }
914
915 default:
916 { /* descriptions of union elements other than above are illegal */
917 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
918 }
919 }
920
921 pDescr = pDescrNext;
922 break;
923 }
924
925 case CSN_EXIST:
926 case CSN_EXIST_LH:
927 {
928 guint8 fExist;
929
930 pui8 = pui8DATA(data, pDescr->offset);
931
932 if (CSN_EXIST_LH == pDescr->type)
933 {
934 fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
935 }
936 else
937 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400938 fExist = bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300939 }
940
941 *pui8 = fExist;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400942 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300943 pDescr++;
944 remaining_bits_len -= 1;
945
946 if (!fExist)
947 {
948 ar->remaining_bits_len = remaining_bits_len;
949 ar->bit_offset = bit_offset;
950 return remaining_bits_len;
951 }
952
953 break;
954 }
955
956 case CSN_NEXT_EXIST:
957 {
958 guint8 fExist;
959
960 pui8 = pui8DATA(data, pDescr->offset);
961
962 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
963 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
964 { /* no more bits to decode is fine here - end of message detected and allowed */
965
966 /* Skip i entries + this entry */
967 pDescr += pDescr->i + 1;
968
969 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
970 if ( pDescr->type != CSN_END )
971 { /* Substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
972 remaining_bits_len--;
973 }
974
975 /* Set the data member to "not exist" */
976 *pui8 = 0;
977 break;
978 }
979
980 /* the "regular" M_NEXT_EXIST description element */
981
982 fExist = 0x00;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400983 if (bitvec_read_field(vector, readIndex, 1))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300984 {
985 fExist = 0x01;
986 }
987
988 *pui8 = fExist;
989 remaining_bits_len -= 1;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400990 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300991 ++bit_offset;
992
993 if (fExist == 0)
994 { /* Skip 'i' entries */
995 pDescr += pDescr->i;
996 }
997
998 pDescr++;
999 break;
1000 }
1001
1002 case CSN_NEXT_EXIST_LH:
1003 {
1004 guint8 fExist;
1005 pui8 = pui8DATA(data, pDescr->offset);
1006
1007 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
1008 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
1009 { /* no more bits to decode is fine here - end of message detected and allowed */
1010
1011 /* skip 'i' entries + this entry */
1012 pDescr += pDescr->i + 1;
1013
1014 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
1015 if ( pDescr->type != CSN_END )
1016 { /* substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
1017 remaining_bits_len--;
1018 }
1019
1020 /* set the data member to "not exist" */
1021 *pui8 = 0;
1022 break;
1023 }
1024
1025 /* the "regular" M_NEXT_EXIST_LH description element */
1026 fExist = get_masked_bits8(vector,readIndex,bit_offset, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001027 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)fExist);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001028 *pui8++ = fExist;
1029 remaining_bits_len -= 1;
1030
1031 bit_offset++;
1032
1033 if (fExist == 0)
1034 { /* Skip 'i' entries */
1035 pDescr += pDescr->i;
1036 }
1037 pDescr++;
1038
1039 break;
1040 }
1041
1042 case CSN_VARIABLE_BITMAP_1:
1043 { /* Bitmap from here and to the end of message */
1044
1045 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1046
1047 /*no break -
1048 * with a length set we have a regular variable length bitmap so we continue */
1049 }
1050
1051 case CSN_VARIABLE_BITMAP:
1052 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1053 * <N: bit (5)> <bitmap: bit(N + offset)>
1054 * Bit array with length (in bits) specified in parameter (pDescr->descr)
1055 * The result is right aligned!
1056 */
1057 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
1058
1059 no_of_bits += pDescr->i; /* adjusted by offset */
1060
1061 if (no_of_bits > 0)
1062 {
1063 remaining_bits_len -= no_of_bits;
1064
1065 if (remaining_bits_len < 0)
1066 {
1067 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1068 }
1069
1070 { /* extract bits */
1071 guint8* pui8 = pui8DATA(data, pDescr->offset);
1072 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1073
1074 if (nB1 > 0)
1075 { /* take care of the first byte - it will be right aligned */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001076 *pui8 = bitvec_read_field(vector, readIndex, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001077 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001078 pui8++;
1079 no_of_bits -= nB1;
1080 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1081 }
1082
1083 /* remaining no_of_bits is a multiple of 8 or 0 */
1084 while (no_of_bits > 0)
1085 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001086 *pui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001087 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001088 pui8++;
1089 no_of_bits -= 8;
1090 }
1091 }
1092 }
1093 pDescr++;
1094 break;
1095 }
1096
1097 case CSN_LEFT_ALIGNED_VAR_BMP_1:
1098 { /* Bitmap from here and to the end of message */
1099
1100 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1101
1102 /* no break -
1103 * with a length set we have a regular left aligned variable length bitmap so we continue
1104 */
1105 }
1106
1107 case CSN_LEFT_ALIGNED_VAR_BMP:
1108 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1109 * <N: bit (5)> <bitmap: bit(N + offset)>
1110 * bit array with length (in bits) specified in parameter (pDescr->descr)
1111 */
1112 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
1113
1114 no_of_bits += pDescr->i;/* size adjusted by offset */
1115
1116 if (no_of_bits > 0)
1117 {
1118 remaining_bits_len -= no_of_bits;
1119
1120 if (remaining_bits_len < 0)
1121 {
1122 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1123 }
1124
1125 { /* extract bits */
1126 guint8* pui8 = pui8DATA(data, pDescr->offset);
1127 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1128
1129 while (no_of_bits > 0)
1130 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001131 *pui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001132 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001133 pui8++;
1134 no_of_bits -= 8;
1135 }
1136 if (nB1 > 0)
1137 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001138 *pui8 = bitvec_read_field(vector, readIndex, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001139 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001140 pui8++;
1141 no_of_bits -= nB1;
1142 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1143 }
1144 }
1145 }
1146
1147 /* bitmap was successfully extracted or it was empty */
1148 pDescr++;
1149 break;
1150 }
1151
1152 case CSN_VARIABLE_ARRAY:
1153 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
1154 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1155 * Array with length specified in parameter:
1156 * <count: bit (x)>
1157 * <list: octet(count + offset)>
1158 */
1159 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
1160
1161 count += pDescr->i; /* Adjusted by offset */
1162
1163 if (count > 0)
1164 {
1165 remaining_bits_len -= count * 8;
1166
1167 if (remaining_bits_len < 0)
1168 {
1169 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1170 }
1171
1172 pui8 = pui8DATA(data, pDescr->offset);
1173
1174 while (count > 0)
1175 {
1176 readIndex -= 8;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001177 *pui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001178 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001179 pui8++;
1180 bit_offset += 8;
1181 count--;
1182 }
1183 }
1184
1185 pDescr++;
1186 break;
1187 }
1188
1189 case CSN_RECURSIVE_ARRAY:
1190 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
1191 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
1192 * where <element> ::= bit(value)
1193 * <tag> ::= 0 | 1
1194 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
1195 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1196 * REMARK: recursive way to specify an array but an iterative implementation!
1197 */
1198 gint16 no_of_bits = pDescr->i;
1199 guint8 ElementCount = 0;
1200
1201 pui8 = pui8DATA(data, pDescr->offset);
1202
1203 while (existNextElement(vector, readIndex, Tag))
1204 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001205 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001206 bit_offset++;
1207 remaining_bits_len--;
1208
1209 /* extract and store no_of_bits long element from bitstream */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001210 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001211 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001212 pui8++;
1213 remaining_bits_len -= no_of_bits;
1214 ElementCount++;
1215
1216 if (remaining_bits_len < 0)
1217 {
1218 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1219 }
1220
1221 bit_offset += no_of_bits;
1222 }
1223
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001224 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)bitvec_read_field(vector, readIndex, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001225 /* existNextElement() returned FALSE, 1 bit consumed */
1226 bit_offset++;
1227
1228 /* Store the counted number of elements of the array */
1229 *pui8DATA(data, (gint16)pDescr->descr.value) = ElementCount;
1230
1231 pDescr++;
1232 break;
1233 }
1234
1235 case CSN_RECURSIVE_TARRAY:
1236 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
1237 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1238 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1239 */
1240 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
1241 guint8 ElementCount = 0;
1242 pui8 = pui8DATA(data, pDescr->offset);
1243
1244 while (existNextElement(vector, readIndex, Tag))
1245 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001246 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001247 /* existNextElement() returned TRUE, 1 bit consumed */
1248 bit_offset++;
1249 remaining_bits_len--;
1250 ElementCount++;
1251
1252 { /* unpack the following data structure */
1253 csnStream_t arT = *ar;
1254 gint16 Status;
1255 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1256 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
1257
1258 if (Status >= 0)
1259 { /* successful completion */
1260 pui8 += nSizeElement; /* -> to next data element */
1261 remaining_bits_len = arT.remaining_bits_len;
1262 bit_offset = arT.bit_offset;
1263 }
1264 else
1265 { /* something went awry */
1266 return Status;
1267 }
1268 }
1269
1270 if (remaining_bits_len < 0)
1271 {
1272 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1273 }
1274 }
1275
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001276 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)bitvec_read_field(vector, readIndex, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001277
1278 /* existNextElement() returned FALSE, 1 bit consumed */
1279 bit_offset++;
1280
1281 /* Store the counted number of elements of the array */
1282 *pui8DATA(data, (gint16)(gint32)pDescr->i) = ElementCount;
1283
1284 pDescr++;
1285 break;
1286 }
1287
1288 case CSN_RECURSIVE_TARRAY_2:
1289 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
1290
1291 Tag = REVERSED_TAG;
1292
1293 /* NO break -
1294 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
1295 */
1296 }
1297
1298 case CSN_RECURSIVE_TARRAY_1:
1299 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
1300 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1301 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1302 */
1303 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
1304 guint8 ElementCount = 0;
1305 csnStream_t arT = *ar;
1306 gboolean EndOfList = FALSE;
1307 gint16 Status;
1308 pui8 = pui8DATA(data, pDescr->offset);
1309
1310 do
1311 { /* get data element */
1312 ElementCount++;
1313
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001314 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
1315
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001316 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1317 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
1318
1319 if (Status >= 0)
1320 { /* successful completion */
1321 pui8 += nSizeElement; /* -> to next */
1322 remaining_bits_len = arT.remaining_bits_len;
1323 bit_offset = arT.bit_offset;
1324 }
1325 else
1326 { /* something went awry */
1327 return Status;
1328 }
1329
1330 if (remaining_bits_len < 0)
1331 {
1332 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1333 }
1334
1335 /* control of next element's tag */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001336 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001337 EndOfList = !(existNextElement(vector, readIndex, Tag));
1338
1339 bit_offset++;
1340 remaining_bits_len--; /* 1 bit consumed (tag) */
1341 } while (!EndOfList);
1342
1343
1344 /* Store the count of the array */
1345 *pui8DATA(data, pDescr->i) = ElementCount;
1346 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
1347 pDescr++;
1348 break;
1349 }
1350
1351 case CSN_FIXED:
1352 { /* Verify the fixed bits */
1353 guint8 no_of_bits = (guint8) pDescr->i;
1354 guint32 ui32;
1355
1356 if (no_of_bits <= 32)
1357 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001358 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001359 }
1360 else
1361 {
1362 return ProcessError(readIndex,"no_of_bits > 32", -1, pDescr);
1363 }
1364 if (ui32 != (unsigned)(gint32)pDescr->offset)
1365 {
1366 return ProcessError(readIndex,"csnStreamDecoder FIXED value does not match", -1, pDescr);
1367 }
1368
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001369 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)ui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001370 remaining_bits_len -= no_of_bits;
1371 bit_offset += no_of_bits;
1372 pDescr++;
1373 break;
1374 }
1375
1376 case CSN_CALLBACK:
1377 {
1378 return ProcessError(readIndex,"csnStreamDecoder Callback not implemented", -1, pDescr);
1379 break;
1380 }
1381
1382 case CSN_TRAP_ERROR:
1383 {
1384 return ProcessError(readIndex,"csnStreamDecoder", pDescr->i, pDescr);
1385 }
1386
1387 case CSN_END:
1388 {
1389 ar->remaining_bits_len = remaining_bits_len;
1390 ar->bit_offset = bit_offset;
1391 return remaining_bits_len;
1392 }
1393
1394 default:
1395 {
1396 assert(0);
1397 }
1398
1399
1400 }
1401
1402 } while (remaining_bits_len >= 0);
1403
1404 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1405}
1406
1407
1408
1409
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001410gint16 csnStreamEncoder(csnStream_t* ar, const CSN_DESCR* pDescr, bitvec *vector, unsigned& writeIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001411{
1412 gint remaining_bits_len = ar->remaining_bits_len;
1413 gint bit_offset = ar->bit_offset;
1414 guint8* pui8;
1415 guint16* pui16;
1416 guint32* pui32;
1417 guint64* pui64;
1418
1419 guint8 Tag = STANDARD_TAG;
1420
1421 if (remaining_bits_len <= 0)
1422 {
1423 return 0;
1424 }
1425
1426 do
1427 {
1428 switch (pDescr->type)
1429 {
1430 case CSN_BIT:
1431 {
1432 if (remaining_bits_len > 0)
1433 {
1434 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001435 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001436 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001437 /* end add the bit value to protocol tree */
1438 }
1439 else
1440 {
1441 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1442 }
1443
1444 pDescr++;
1445 remaining_bits_len--;
1446 bit_offset++;
1447 break;
1448 }
1449
1450 case CSN_NULL:
1451 { /* Empty member! */
1452 pDescr++;
1453 break;
1454 }
1455
1456 case CSN_UINT:
1457 {
1458 guint8 no_of_bits = (guint8) pDescr->i;
1459
1460 if (remaining_bits_len >= no_of_bits)
1461 {
1462 if (no_of_bits <= 8)
1463 {
1464 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001465 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001466 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001467 }
1468 else if (no_of_bits <= 16)
1469 {
1470 pui16 = pui16DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001471 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001472 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001473 }
1474 else if (no_of_bits <= 32)
1475 {
1476 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001477 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001478 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001479 }
1480 else
1481 {
1482 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1483 }
1484 }
1485 else
1486 {
1487 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1488 }
1489
1490 remaining_bits_len -= no_of_bits;
1491 bit_offset += no_of_bits;
1492 pDescr++;
1493 break;
1494 }
1495
1496 case CSN_UINT_OFFSET:
1497 {
1498 guint8 no_of_bits = (guint8) pDescr->i;
1499
1500 if (remaining_bits_len >= no_of_bits)
1501 {
1502 if (no_of_bits <= 8)
1503 {
1504 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001505 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001506 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001507 }
1508 else if (no_of_bits <= 16)
1509 {
1510 pui16 = pui16DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001511 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001512 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001513 }
1514 else if (no_of_bits <= 32)
1515 {
1516 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001517 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001518 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001519 }
1520 else
1521 {
1522 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1523 }
1524 }
1525 else
1526 {
1527 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1528 }
1529
1530 remaining_bits_len -= no_of_bits;
1531 bit_offset += no_of_bits;
1532 pDescr++;
1533 break;
1534 }
1535
1536 case CSN_UINT_LH:
1537 {
1538 guint8 no_of_bits = (guint8) pDescr->i;
1539
1540 if (remaining_bits_len >= no_of_bits)
1541 {
1542 remaining_bits_len -= no_of_bits;
1543 if (no_of_bits <= 8)
1544 {
1545 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001546 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001547 // TODO : Change get_masked_bits8()
1548 writeIndex -= no_of_bits;
1549 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
1550 writeIndex -= no_of_bits;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001551 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001552 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001553
1554 }
1555 else
1556 {/* Maybe we should support more than 8 bits ? */
1557 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1558 }
1559 }
1560 else
1561 {
1562 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1563 }
1564
1565 remaining_bits_len -= no_of_bits;
1566 bit_offset += no_of_bits;
1567 pDescr++;
1568 break;
1569 }
1570
1571 case CSN_UINT_ARRAY:
1572 {
1573 guint8 no_of_bits = (guint8) pDescr->i;
1574 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
1575
1576 if (pDescr->serialize.value != 0)
1577 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
1578 nCount = *pui16DATA(data, nCount);
1579 }
1580
1581 if (remaining_bits_len >= no_of_bits)
1582 {
1583 remaining_bits_len -= (no_of_bits*nCount);
1584 if (no_of_bits <= 8)
1585 {
1586 pui8 = pui8DATA(data, pDescr->offset);
1587 do
1588 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001589 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
1590 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001591 pui8++;
1592 bit_offset += no_of_bits;
1593 } while (--nCount > 0);
1594 }
1595 else if (no_of_bits <= 16)
1596 {
1597 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1598 }
1599 else if (no_of_bits <= 32)
1600 {
1601 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1602 }
1603 else
1604 {
1605 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1606 }
1607 }
1608 else
1609 {
1610 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1611 }
1612 pDescr++;
1613 break;
1614 }
1615
1616 case CSN_VARIABLE_TARRAY_OFFSET:
1617 case CSN_VARIABLE_TARRAY:
1618 case CSN_TYPE_ARRAY:
1619 {
1620 gint16 Status;
1621 csnStream_t arT = *ar;
1622 gint16 nCount = pDescr->i;
1623 guint16 nSize = (guint16)(gint32)pDescr->serialize.value;
1624
1625 pui8 = pui8DATA(data, pDescr->offset);
1626 if (pDescr->type == CSN_VARIABLE_TARRAY)
1627 { /* Count specified in field */
1628 nCount = *pui8DATA(data, pDescr->i);
1629 }
1630 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
1631 { /* Count specified in field */
1632 nCount = *pui8DATA(data, pDescr->i);
1633 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
1634 }
1635
1636 while (nCount > 0)
1637 { /* resulting array of length 0 is possible
1638 * but no bits shall be read from bitstream
1639 */
1640
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001641 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001642 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1643 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
1644 if (Status >= 0)
1645 {
1646 pui8 += nSize;
1647 remaining_bits_len = arT.remaining_bits_len;
1648 bit_offset = arT.bit_offset;
1649
1650 }
1651 else
1652 {
1653 return Status;
1654 }
1655 nCount--;
1656 }
1657
1658 pDescr++;
1659 break;
1660 }
1661
1662 case CSN_BITMAP:
1663 { /* bitmap with given length. The result is left aligned! */
1664 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
1665
1666 if (no_of_bits > 0)
1667 {
1668
1669 if (no_of_bits <= 32)
1670 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001671 for(unsigned ib = 0; ib < 4; ib++)
1672 {
1673 pui8 = pui8DATA(data, pDescr->offset+ib);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001674 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001675 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001676 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001677 }
1678 else if (no_of_bits <= 64)
1679 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001680 for(unsigned ib = 0; ib < 8; ib++)
1681 {
1682 pui8 = pui8DATA(data, pDescr->offset+ib);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001683 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001684 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001685 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001686 }
1687 else
1688 {
1689 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
1690 }
1691
1692 remaining_bits_len -= no_of_bits;
1693 assert(remaining_bits_len >= 0);
1694 bit_offset += no_of_bits;
1695 }
1696 /* bitmap was successfully extracted or it was empty */
1697
1698 pDescr++;
1699 break;
1700 }
1701
1702 case CSN_TYPE:
1703 {
1704 gint16 Status;
1705 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001706 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001707 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1708 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001709 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001710 if (Status >= 0)
1711 {
1712
1713 remaining_bits_len = arT.remaining_bits_len;
1714 bit_offset = arT.bit_offset;
1715 pDescr++;
1716 }
1717 else
1718 {
1719 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
1720 return Status;
1721 }
1722
1723 break;
1724 }
1725
1726 case CSN_CHOICE:
1727 {
1728 //gint16 count = pDescr->i;
1729 guint8 i = 0;
1730 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
1731
1732 pui8 = pui8DATA(data, pDescr->offset);
1733 i = *pui8;
1734 pChoice += i;
1735 guint8 no_of_bits = pChoice->bits;
1736 guint8 value = pChoice->value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001737 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pChoice->descr.sz , (unsigned)value);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001738 bitvec_write_field(vector, writeIndex, value, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001739
1740 CSN_DESCR descr[2];
1741 gint16 Status;
1742 csnStream_t arT = *ar;
1743
1744 descr[0] = pChoice->descr;
1745 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
1746 descr[1].type = CSN_END;
1747 bit_offset += no_of_bits;
1748 remaining_bits_len -= no_of_bits;
1749
1750 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1751 Status = csnStreamEncoder(&arT, descr, vector, writeIndex, data);
1752
1753 if (Status >= 0)
1754 {
1755 remaining_bits_len = arT.remaining_bits_len;
1756 bit_offset = arT.bit_offset;
1757 }
1758 else
1759 {
1760 return Status;
1761 }
1762
1763 pDescr++;
1764 break;
1765 }
1766
1767 case CSN_SERIALIZE:
1768 {
1769 StreamSerializeFcn_t serialize = pDescr->serialize.fcn;
1770 csnStream_t arT = *ar;
1771 gint16 Status = -1;
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001772 unsigned lengthIndex;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001773
1774 // store writeIndex for length value (7 bit)
1775 lengthIndex = writeIndex;
1776 writeIndex += 7;
1777 bit_offset += 7;
1778 remaining_bits_len -= 7;
1779 arT.direction = 0;
1780 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1781 Status = serialize(&arT, vector, writeIndex, pvDATA(data, pDescr->offset));
1782
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001783 bitvec_write_field(vector, lengthIndex, writeIndex-lengthIndex-7, 7);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001784 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %u | ", pDescr->sz , (unsigned)(writeIndex-lengthIndex));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001785
1786 if (Status >= 0)
1787 {
1788 remaining_bits_len = arT.remaining_bits_len;
1789 bit_offset = arT.bit_offset;
1790 pDescr++;
1791 }
1792 else
1793 {
1794 // Has already been processed:
1795 return Status;
1796 }
1797
1798 break;
1799 }
1800
1801 case CSN_UNION_LH:
1802 case CSN_UNION:
1803 {
1804 gint16 Bits;
1805 guint8 index;
1806 gint16 count = pDescr->i;
1807 const CSN_DESCR* pDescrNext = pDescr;
1808
1809 pDescrNext += count + 1; /* now this is next after the union */
1810 if ((count <= 0) || (count > 16))
1811 {
1812 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
1813 }
1814
1815 /* Now get the bits to extract the index */
1816 Bits = ixBitsTab[count];
1817 index = 0;
1818
1819 /* Assign UnionType */
1820 pui8 = pui8DATA(data, pDescr->offset);
1821 //read index from data and write to vector
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001822 bitvec_write_field(vector, writeIndex, *pui8, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001823
1824 //decode index
1825 writeIndex -= Bits;
1826
1827 while (Bits > 0)
1828 {
1829 index <<= 1;
1830
1831 if (CSN_UNION_LH == pDescr->type)
1832 {
1833 index |= get_masked_bits8(vector,writeIndex, bit_offset, 1);
1834 }
1835 else
1836 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001837 index |= bitvec_read_field(vector, writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001838 }
1839
1840 remaining_bits_len--;
1841 bit_offset++;
1842 Bits--;
1843 }
1844
1845 writeIndex -= Bits;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001846 bitvec_write_field(vector, writeIndex, index, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001847
1848
1849 /* script index to continue on, limited in case we do not have a power of 2 */
1850 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001851 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)index);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001852
1853 switch (pDescr->type)
1854 { /* get the right element of the union based on computed index */
1855
1856 case CSN_BIT:
1857 {
1858 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001859 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001860 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001861 remaining_bits_len -= 1;
1862 bit_offset++;
1863 pDescr++;
1864 break;
1865 }
1866
1867 case CSN_NULL:
1868 { /* Empty member! */
1869 pDescr++;
1870 break;
1871 }
1872
1873 case CSN_UINT:
1874 {
1875 guint8 no_of_bits = (guint8) pDescr->i;
1876 if (remaining_bits_len >= no_of_bits)
1877 {
1878 remaining_bits_len -= no_of_bits;
1879
1880 if (no_of_bits <= 8)
1881 {
1882 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001883 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001884 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001885 }
1886 else if (no_of_bits <= 16)
1887 {
1888 pui16 = pui16DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001889 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001890 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001891 }
1892 else if (no_of_bits <= 32)
1893 {
1894 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001895 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001896 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001897 }
1898 else
1899 {
1900 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1901 }
1902 }
1903 else
1904 {
1905 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1906 }
1907
1908 bit_offset += no_of_bits;
1909 pDescr++;
1910 break;
1911 }
1912
1913 case CSN_UINT_OFFSET:
1914 {
1915 guint8 no_of_bits = (guint8) pDescr->i;
1916
1917 if (remaining_bits_len >= no_of_bits)
1918 {
1919 if (no_of_bits <= 8)
1920 {
1921 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001922 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001923 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001924 }
1925 else if (no_of_bits <= 16)
1926 {
1927 pui16 = pui16DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001928 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001929 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001930 }
1931 else if (no_of_bits <= 32)
1932 {
1933 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001934 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001935 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001936 }
1937 else
1938 {
1939 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1940 }
1941 }
1942 else
1943 {
1944 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1945 }
1946
1947 remaining_bits_len -= no_of_bits;
1948 bit_offset += no_of_bits;
1949 pDescr++;
1950 break;
1951 }
1952
1953 case CSN_UINT_LH:
1954 {
1955 guint8 no_of_bits = (guint8) pDescr->i;
1956
1957 if (remaining_bits_len >= no_of_bits)
1958 {
1959 remaining_bits_len -= no_of_bits;
1960 if (no_of_bits <= 8)
1961 {
1962 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001963 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001964 // TODO : Change get_masked_bits8()
1965 writeIndex -= no_of_bits;
1966 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
1967 writeIndex -= no_of_bits;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001968 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001969 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001970
1971 }
1972 else
1973 {/* Maybe we should support more than 8 bits ? */
1974 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1975 }
1976 }
1977 else
1978 {
1979 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1980 }
1981
1982 remaining_bits_len -= no_of_bits;
1983 bit_offset += no_of_bits;
1984 pDescr++;
1985 break;
1986 }
1987
1988 case CSN_UINT_ARRAY:
1989 {
1990 guint8 no_of_bits = (guint8) pDescr->i;
1991 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
1992
1993 if (pDescr->serialize.value != 0)
1994 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
1995 nCount = *pui16DATA(data, nCount);
1996 }
1997
1998 if (remaining_bits_len >= no_of_bits)
1999 {
2000 remaining_bits_len -= (no_of_bits*nCount);
2001 if (no_of_bits <= 8)
2002 {
2003 pui8 = pui8DATA(data, pDescr->offset);
2004 do
2005 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002006 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
2007 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002008 pui8++;
2009 bit_offset += no_of_bits;
2010 } while (--nCount > 0);
2011 }
2012 else if (no_of_bits <= 16)
2013 {
2014 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2015 }
2016 else if (no_of_bits <= 32)
2017 {
2018 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2019 }
2020 else
2021 {
2022 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2023 }
2024 }
2025 else
2026 {
2027 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2028 }
2029 pDescr++;
2030 break;
2031 }
2032
2033 case CSN_VARIABLE_TARRAY_OFFSET:
2034 case CSN_VARIABLE_TARRAY:
2035 case CSN_TYPE_ARRAY:
2036 {
2037 gint16 Status;
2038 csnStream_t arT = *ar;
2039 gint16 nCount = pDescr->i;
2040 guint16 nSize = (guint16)(gint32)pDescr->serialize.value;
2041
2042 pui8 = pui8DATA(data, pDescr->offset);
2043 if (pDescr->type == CSN_VARIABLE_TARRAY)
2044 { /* Count specified in field */
2045 nCount = *pui8DATA(data, pDescr->i);
2046 }
2047 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
2048 { /* Count specified in field */
2049 nCount = *pui8DATA(data, pDescr->i);
2050 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
2051 }
2052
2053 while (nCount > 0)
2054 { /* resulting array of length 0 is possible
2055 * but no bits shall be read from bitstream
2056 */
2057
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002058 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002059 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2060 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
2061 if (Status >= 0)
2062 {
2063 pui8 += nSize;
2064 remaining_bits_len = arT.remaining_bits_len;
2065 bit_offset = arT.bit_offset;
2066 }
2067 else
2068 {
2069 return Status;
2070 }
2071 nCount--;
2072 }
2073
2074 pDescr++;
2075 break;
2076 }
2077
2078 case CSN_BITMAP:
2079 { /* bitmap with given length. The result is left aligned! */
2080 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
2081
2082 if (no_of_bits > 0)
2083 {
2084
2085 if (no_of_bits <= 32)
2086 {
2087 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002088 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002089 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002090 }
2091 else if (no_of_bits <= 64)
2092 {
2093 pui64 = pui64DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002094 bitvec_write_field(vector, writeIndex, *pui64, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002095 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002096 }
2097 else
2098 {
2099 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
2100 }
2101
2102 remaining_bits_len -= no_of_bits;
2103 assert(remaining_bits_len >= 0);
2104 bit_offset += no_of_bits;
2105 }
2106 /* bitmap was successfully extracted or it was empty */
2107
2108 pDescr++;
2109 break;
2110 }
2111
2112 case CSN_TYPE:
2113 {
2114 gint16 Status;
2115 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002116 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002117 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2118 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002119 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002120 if (Status >= 0)
2121 {
2122 remaining_bits_len = arT.remaining_bits_len;
2123 bit_offset = arT.bit_offset;
2124 pDescr++;
2125 }
2126 else
2127 {
2128 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
2129 return Status;
2130 }
2131
2132 break;
2133 }
2134
2135 default:
2136 { /* descriptions of union elements other than above are illegal */
2137 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
2138 }
2139 }
2140
2141 pDescr = pDescrNext;
2142 break;
2143 }
2144
2145 case CSN_EXIST:
2146 case CSN_EXIST_LH:
2147 {
2148 guint8 fExist;
2149 unsigned exist = 0;
2150 pui8 = pui8DATA(data, pDescr->offset);
2151 exist = *pui8;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002152 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002153 writeIndex--;
2154 if (CSN_EXIST_LH == pDescr->type)
2155 {
2156 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
2157 }
2158 else
2159 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002160 fExist = bitvec_read_field(vector, writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002161 }
2162 writeIndex--;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002163 bitvec_write_field(vector, writeIndex, fExist, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002164 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz, (unsigned)fExist);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002165 pDescr++;
2166 remaining_bits_len -= 1;
2167
2168 if (!exist)
2169 {
2170 ar->remaining_bits_len = remaining_bits_len;
2171 ar->bit_offset = bit_offset;
2172 return remaining_bits_len;
2173 }
2174 break;
2175 }
2176
2177 case CSN_NEXT_EXIST:
2178 {
2179 guint8 fExist;
2180
2181 pui8 = pui8DATA(data, pDescr->offset);
2182
2183 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
2184 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
2185 { /* no more bits to decode is fine here - end of message detected and allowed */
2186
2187 /* Skip i entries + this entry */
2188 pDescr += pDescr->i + 1;
2189
2190 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
2191 if ( pDescr->type != CSN_END )
2192 { /* Substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
2193 remaining_bits_len--;
2194 }
2195
2196 break;
2197 }
2198
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002199 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002200 fExist = *pui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002201 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002202 remaining_bits_len -= 1;
2203
2204 ++bit_offset;
2205
2206 if (fExist == 0)
2207 { /* Skip 'i' entries */
2208 pDescr += pDescr->i;
2209 }
2210
2211 pDescr++;
2212 break;
2213 }
2214
2215 case CSN_NEXT_EXIST_LH:
2216 {
2217 guint8 fExist;
2218 pui8 = pui8DATA(data, pDescr->offset);
2219
2220 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
2221 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
2222 { /* no more bits to decode is fine here - end of message detected and allowed */
2223
2224 /* skip 'i' entries + this entry */
2225 pDescr += pDescr->i + 1;
2226
2227 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
2228 if ( pDescr->type != CSN_END )
2229 { /* substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
2230 remaining_bits_len--;
2231 }
2232
2233 /* set the data member to "not exist" */
2234 //*pui8 = 0;
2235 break;
2236 }
2237
2238 /* the "regular" M_NEXT_EXIST_LH description element */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002239 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002240 writeIndex--;
2241 fExist = get_masked_bits8(vector,writeIndex, bit_offset, 1);
2242 writeIndex--;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002243 bitvec_write_field(vector, writeIndex, fExist, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002244 pui8++;
2245 remaining_bits_len -= 1;
2246
2247 bit_offset++;
2248
2249 if (fExist == 0)
2250 { /* Skip 'i' entries */
2251 pDescr += pDescr->i;
2252 }
2253 pDescr++;
2254
2255 break;
2256 }
2257
2258 case CSN_VARIABLE_BITMAP_1:
2259 { /* Bitmap from here and to the end of message */
2260
2261 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2262
2263 /*no break -
2264 * with a length set we have a regular variable length bitmap so we continue */
2265 }
2266
2267 case CSN_VARIABLE_BITMAP:
2268 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2269 * <N: bit (5)> <bitmap: bit(N + offset)>
2270 * Bit array with length (in bits) specified in parameter (pDescr->descr)
2271 * The result is right aligned!
2272 */
2273 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
2274
2275 no_of_bits += pDescr->i; /* adjusted by offset */
2276
2277 if (no_of_bits > 0)
2278 {
2279 remaining_bits_len -= no_of_bits;
2280
2281 if (remaining_bits_len < 0)
2282 {
2283 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2284 }
2285
2286 { /* extract bits */
2287 guint8* pui8 = pui8DATA(data, pDescr->offset);
2288 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2289
2290 if (nB1 > 0)
2291 { /* take care of the first byte - it will be right aligned */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002292 bitvec_write_field(vector, writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002293 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002294 pui8++;
2295 no_of_bits -= nB1;
2296 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2297 }
2298
2299 /* remaining no_of_bits is a multiple of 8 or 0 */
2300 while (no_of_bits > 0)
2301 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002302 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002303 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002304 pui8++;
2305 no_of_bits -= 8;
2306 }
2307 }
2308 }
2309 pDescr++;
2310 break;
2311 }
2312
2313 case CSN_LEFT_ALIGNED_VAR_BMP_1:
2314 { /* Bitmap from here and to the end of message */
2315
2316 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2317
2318 /* no break -
2319 * with a length set we have a regular left aligned variable length bitmap so we continue
2320 */
2321 }
2322
2323 case CSN_LEFT_ALIGNED_VAR_BMP:
2324 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2325 * <N: bit (5)> <bitmap: bit(N + offset)>
2326 * bit array with length (in bits) specified in parameter (pDescr->descr)
2327 */
2328
2329 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
2330
2331 no_of_bits += pDescr->i;/* size adjusted by offset */
2332
2333 if (no_of_bits > 0)
2334 {
2335 remaining_bits_len -= no_of_bits;
2336
2337 if (remaining_bits_len < 0)
2338 {
2339 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2340 }
2341
2342 { /* extract bits */
2343 guint8* pui8 = pui8DATA(data, pDescr->offset);
2344 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2345
2346 while (no_of_bits > 0)
2347 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002348 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002349 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002350 pui8++;
2351 no_of_bits -= 8;
2352 }
2353 if (nB1 > 0)
2354 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002355 bitvec_write_field(vector, writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002356 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002357 pui8++;
2358 no_of_bits -= nB1;
2359 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2360 }
2361 }
2362
2363 }
2364
2365 /* bitmap was successfully extracted or it was empty */
2366 pDescr++;
2367 break;
2368 }
2369
2370 case CSN_VARIABLE_ARRAY:
2371 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
2372 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2373 * Array with length specified in parameter:
2374 * <count: bit (x)>
2375 * <list: octet(count + offset)>
2376 */
2377 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
2378
2379 count += pDescr->i; /* Adjusted by offset */
2380
2381 if (count > 0)
2382 {
2383 remaining_bits_len -= count * 8;
2384
2385 if (remaining_bits_len < 0)
2386 {
2387 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2388 }
2389
2390 pui8 = pui8DATA(data, pDescr->offset);
2391
2392 while (count > 0)
2393 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002394 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002395 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002396 pui8++;
2397 bit_offset += 8;
2398 count--;
2399 }
2400 }
2401
2402 pDescr++;
2403 break;
2404 }
2405
2406 case CSN_RECURSIVE_ARRAY:
2407 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
2408 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
2409 * where <element> ::= bit(value)
2410 * <tag> ::= 0 | 1
2411 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
2412 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2413 * REMARK: recursive way to specify an array but an iterative implementation!
2414 */
2415 gint16 no_of_bits = pDescr->i;
2416 guint8 ElementCount = 0;
2417 pui8 = pui8DATA(data, pDescr->offset);
2418 ElementCount = *pui8DATA(data, (gint16)pDescr->descr.value);
2419 while (ElementCount > 0)
2420 { /* tag control shows existence of next list elements */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002421 bitvec_write_field(vector, writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002422 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002423 bit_offset++;
2424 remaining_bits_len--;
2425
2426 /* extract and store no_of_bits long element from bitstream */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002427 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002428 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002429 pui8++;
2430 remaining_bits_len -= no_of_bits;
2431 ElementCount--;
2432
2433 if (remaining_bits_len < 0)
2434 {
2435 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2436 }
2437
2438 bit_offset += no_of_bits;
2439 }
2440
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002441 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002442 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002443 bit_offset++;
2444
2445 pDescr++;
2446 break;
2447 }
2448
2449 case CSN_RECURSIVE_TARRAY:
2450 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
2451 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2452 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2453 */
2454 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
2455 guint8 ElementCount = 0;
2456 pui8 = pui8DATA(data, pDescr->offset);
2457 /* Store the counted number of elements of the array */
2458 ElementCount = *pui8DATA(data, (gint16)(gint32)pDescr->i);
2459
2460 while (ElementCount > 0)
2461 { /* tag control shows existence of next list elements */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002462 bitvec_write_field(vector, writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002463 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002464 bit_offset++;
2465
2466 remaining_bits_len--;
2467 ElementCount--;
2468
2469 { /* unpack the following data structure */
2470 csnStream_t arT = *ar;
2471 gint16 Status;
2472 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2473 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
2474
2475 if (Status >= 0)
2476 { /* successful completion */
2477 pui8 += nSizeElement; /* -> to next data element */
2478 remaining_bits_len = arT.remaining_bits_len;
2479 bit_offset = arT.bit_offset;
2480 }
2481 else
2482 { /* something went awry */
2483 return Status;
2484 }
2485 }
2486
2487 if (remaining_bits_len < 0)
2488 {
2489 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2490 }
2491 }
2492
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002493 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002494 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002495 bit_offset++;
2496
2497 pDescr++;
2498 break;
2499 }
2500
2501 case CSN_RECURSIVE_TARRAY_2:
2502 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
2503
2504 Tag = REVERSED_TAG;
2505
2506 /* NO break -
2507 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
2508 */
2509 }
2510
2511 case CSN_RECURSIVE_TARRAY_1:
2512 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
2513 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2514 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2515 */
2516 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
2517 guint8 ElementCount = 0;
2518 guint8 ElementNum = 0;
2519 csnStream_t arT = *ar;
2520 gint16 Status;
2521
2522 pui8 = pui8DATA(data, pDescr->offset);
2523 /* Store the count of the array */
2524 ElementCount = *pui8DATA(data, pDescr->i);
2525 ElementNum = ElementCount;
2526
2527 while (ElementCount > 0)
2528 { /* get data element */
2529 if (ElementCount != ElementNum)
2530 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002531 bitvec_write_field(vector, writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002532 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002533 bit_offset++;
2534 remaining_bits_len--;
2535 }
2536 ElementCount--;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002537 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002538 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2539 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002540 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002541 if (Status >= 0)
2542 { /* successful completion */
2543 pui8 += nSizeElement; /* -> to next */
2544 remaining_bits_len = arT.remaining_bits_len;
2545 bit_offset = arT.bit_offset;
2546 }
2547 else
2548 { /* something went awry */
2549 return Status;
2550 }
2551
2552 if (remaining_bits_len < 0)
2553 {
2554 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2555 }
2556
2557 }
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002558 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002559 bit_offset++;
2560 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
2561 pDescr++;
2562 break;
2563 }
2564
2565 case CSN_FIXED:
2566 { /* Verify the fixed bits */
2567 guint8 no_of_bits = (guint8) pDescr->i;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002568 bitvec_write_field(vector, writeIndex, pDescr->offset, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002569 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002570 remaining_bits_len -= no_of_bits;
2571 bit_offset += no_of_bits;
2572 pDescr++;
2573 break;
2574 }
2575
2576 case CSN_CALLBACK:
2577 {
2578 return ProcessError(writeIndex,"csnStreamEncoder Callback not implemented", -1, pDescr);
2579 break;
2580 }
2581
2582 case CSN_TRAP_ERROR:
2583 {
2584 return ProcessError(writeIndex,"csnStreamEncoder", pDescr->i, pDescr);
2585 }
2586
2587 case CSN_END:
2588 {
2589 ar->remaining_bits_len = remaining_bits_len;
2590 ar->bit_offset = bit_offset;
2591 return remaining_bits_len;
2592 }
2593
2594 default:
2595 {
2596 assert(0);
2597 }
2598
2599 }
2600
2601 } while (remaining_bits_len >= 0);
2602
2603 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2604}
2605