blob: b0ed73de503720ae3269add86b5a6315be25389c [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"
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +040036#include <gprs_debug.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030037
38
39#define pvDATA(_pv, _offset) ((void*) ((unsigned char*)_pv + _offset))
40#define pui8DATA(_pv, _offset) ((guint8*) pvDATA(_pv, _offset))
41#define pui16DATA(_pv, _offset) ((guint16*) pvDATA(_pv, _offset))
42#define pui32DATA(_pv, _offset) ((guint32*) pvDATA(_pv, _offset))
43#define pui64DATA(_pv, _offset) ((guint64*) pvDATA(_pv, _offset))
44/* used to tag existence of next element in variable length lists */
45#define STANDARD_TAG 1
46#define REVERSED_TAG 0
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030047
48using namespace std;
49static const unsigned char ixBitsTab[] = {0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5};
50
51
52/* Returns no_of_bits (up to 8) masked with 0x2B */
53
54static guint8
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +040055get_masked_bits8( bitvec *vector, unsigned& readIndex, gint bit_offset, const gint no_of_bits)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030056{
57 static const guint8 maskBits[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
58 //gint byte_offset = bit_offset >> 3; /* divide by 8 */
59 gint relative_bit_offset = bit_offset & 0x07; /* modulo 8 */
60 guint8 result;
61 gint bit_shift = 8 - relative_bit_offset - (gint) no_of_bits;
62 readIndex -= relative_bit_offset;
63 if (bit_shift >= 0)
64 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +040065 result = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) >> bit_shift;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030066 readIndex-= bit_shift;
67 result &= maskBits[no_of_bits];
68 }
69 else
70 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +040071 guint8 hight_part = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) & maskBits[8 - relative_bit_offset];
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030072 hight_part = (guint8) (hight_part << (-bit_shift));
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +040073 result = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) >> (8 + bit_shift);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030074 readIndex = readIndex - (8 - (-bit_shift));
75 result |= hight_part;
76 }
77 return result;
78}
79
80/**
81 * ================================================================================================
82 * set initial/start values in help data structure used for packing/unpacking operation
83 * ================================================================================================
84 */
85void
86csnStreamInit(csnStream_t* ar, gint bit_offset, gint remaining_bits_len)
87{
88 ar->remaining_bits_len = remaining_bits_len;
89 ar->bit_offset = bit_offset;
90}
91
92static const char* ErrCodes[] =
93{
94 "General 0",
95 "General -1",
96 "DATA_NOT VALID",
97 "IN SCRIPT",
98 "INVALID UNION INDEX",
99 "NEED_MORE BITS TO UNPACK",
100 "ILLEGAL BIT VALUE",
101 "Internal",
102 "STREAM_NOT_SUPPORTED",
103 "MESSAGE_TOO_LONG"
104};
105
106static gint16
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400107ProcessError( unsigned readIndex, const char* sz, gint16 err, const CSN_DESCR* pDescr)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300108{
109 gint16 i = MIN(-err, ((gint16) ElementsOf(ErrCodes)-1));
110 if (i >= 0)
111 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400112 //LOG(ERR) << sz << "Error code: "<< ErrCodes[i] << pDescr?(pDescr->sz):"-";
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300113 }
114 else
115 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400116 //LOG(ERR) << sz << ": " << pDescr?(pDescr->sz):"-";
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300117 }
118 return err;
119}
120
121//#if 0
122static const char* CSN_DESCR_type[]=
123{
124 "CSN_END",
125 "CSN_BIT",
126 "CSN_UINT",
127 "CSN_TYPE",
128 "CSN_CHOICE",
129 "CSN_UNION",
130 "CSN_UNION_LH",
131 "CSN_UINT_ARRAY",
132 "CSN_TYPE_ARRAY",
133 "CSN_BITMAP",
134 "CSN_VARIABLE_BITMAP",
135 "CSN_VARIABLE_BITMAP_1",
136 "CSN_LEFT_ALIGNED_VAR_BMP",
137 "CSN_LEFT_ALIGNED_VAR_BMP_1",
138 "CSN_VARIABLE_ARRAY",
139 "CSN_VARIABLE_TARRAY",
140 "CSN_VARIABLE_TARRAY_OFFSET",
141 "CSN_RECURSIVE_ARRAY",
142 "CSN_RECURSIVE_TARRAY",
143 "CSN_RECURSIVE_TARRAY_1",
144 "CSN_RECURSIVE_TARRAY_2",
145 "CSN_EXIST",
146 "CSN_EXIST_LH",
147 "CSN_NEXT_EXIST",
148 "CSN_NEXT_EXIST_LH",
149 "CSN_NULL",
150 "CSN_FIXED",
151 "CSN_CALLBACK",
152 "CSN_UINT_OFFSET",
153 "CSN_UINT_LH",
154 "CSN_SERIALIZE",
155 "CSN_TRAP_ERROR"
156 "CSN_???"
157};
158//#endif
159
160/**
161 * ================================================================================================
162 * Return TRUE if tag in bit stream indicates existence of next list element,
163 * otherwise return FALSE.
164 * Will work for tag values equal to both 0 and 1.
165 * ================================================================================================
166 */
167
168static gboolean
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400169existNextElement(bitvec *vector, unsigned& readIndex, guint8 Tag)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300170{
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400171 guint8 res = bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300172 if (Tag == STANDARD_TAG)
173 {
174 return (res > 0);
175 }
176 return (res == 0);
177}
178
179
180gint16
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400181csnStreamDecoder(csnStream_t* ar, const CSN_DESCR* pDescr, bitvec *vector, unsigned& readIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300182{
183 gint remaining_bits_len = ar->remaining_bits_len;
184 gint bit_offset = ar->bit_offset;
185 guint8* pui8;
186 guint16* pui16;
187 guint32* pui32;
188 guint64* pui64;
189 guint8 Tag = STANDARD_TAG;
190
191 if (remaining_bits_len <= 0)
192 {
193 return 0;
194 }
195
196 do
197 {
198 switch (pDescr->type)
199 {
200 case CSN_BIT:
201 {
202 if (remaining_bits_len > 0)
203 {
204 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400205 *pui8 = bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400206 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300207 /* end add the bit value to protocol tree */
208 }
209 else
210 {
211 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
212 }
213
214 pDescr++;
215 remaining_bits_len--;
216 bit_offset++;
217 break;
218 }
219
220 case CSN_NULL:
221 { /* Empty member! */
222 pDescr++;
223 break;
224 }
225
226 case CSN_UINT:
227 {
228 guint8 no_of_bits = (guint8) pDescr->i;
229
230 if (remaining_bits_len >= no_of_bits)
231 {
232 if (no_of_bits <= 8)
233 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400234 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300235 pui8 = pui8DATA(data, pDescr->offset);
236 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400237 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300238 }
239 else if (no_of_bits <= 16)
240 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400241 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300242 pui16 = pui16DATA(data, pDescr->offset);
243 *pui16 = ui16;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400244 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300245 }
246 else if (no_of_bits <= 32)
247 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400248 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300249 pui32 = pui32DATA(data, pDescr->offset);
250 *pui32 = ui32;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400251 LOGPC(DCSN1, LOGL_NOTICE, "%s = 0x%08x | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300252 }
253 else
254 {
255 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
256 }
257 }
258 else
259 {
260 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
261 }
262
263 remaining_bits_len -= no_of_bits;
264 bit_offset += no_of_bits;
265 pDescr++;
266 break;
267 }
268
269 case CSN_UINT_OFFSET:
270 {
271 guint8 no_of_bits = (guint8) pDescr->i;
272
273 if (remaining_bits_len >= no_of_bits)
274 {
275 if (no_of_bits <= 8)
276 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400277 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300278 pui8 = pui8DATA(data, pDescr->offset);
279 *pui8 = ui8 + (guint8)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400280 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300281 }
282 else if (no_of_bits <= 16)
283 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400284 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300285 pui16 = pui16DATA(data, pDescr->offset);
286 *pui16 = ui16 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400287 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300288 }
289 else if (no_of_bits <= 32)
290 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400291 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300292 pui32 = pui32DATA(data, pDescr->offset);
293 *pui32 = ui32 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400294 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300295 }
296 else
297 {
298 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
299 }
300 }
301 else
302 {
303 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
304 }
305
306 remaining_bits_len -= no_of_bits;
307 bit_offset += no_of_bits;
308 pDescr++;
309 break;
310 }
311
312 case CSN_UINT_LH:
313 {
314 guint8 no_of_bits = (guint8) pDescr->i;
315
316 if (remaining_bits_len >= no_of_bits)
317 {
318 remaining_bits_len -= no_of_bits;
319 if (no_of_bits <= 8)
320 {
321 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
322 pui8 = pui8DATA(data, pDescr->offset);
323 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400324 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300325 }
326 else
327 {/* Maybe we should support more than 8 bits ? */
328 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
329 }
330 }
331 else
332 {
333 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
334 }
335
336 remaining_bits_len -= no_of_bits;
337 bit_offset += no_of_bits;
338 pDescr++;
339 break;
340 }
341
342 case CSN_UINT_ARRAY:
343 {
344 guint8 no_of_bits = (guint8) pDescr->i;
345 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
346
347 if (pDescr->serialize.value != 0)
348 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
349 nCount = *pui16DATA(data, nCount);
350 }
351
352 if (remaining_bits_len >= no_of_bits)
353 {
354 remaining_bits_len -= (no_of_bits*nCount);
355 if (no_of_bits <= 8)
356 {
357 pui8 = pui8DATA(data, pDescr->offset);
358 do
359 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400360 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400361 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300362 pui8++;
363 bit_offset += no_of_bits;
364 } while (--nCount > 0);
365 }
366 else if (no_of_bits <= 16)
367 {
368 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
369 }
370 else if (no_of_bits <= 32)
371 {
372 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
373 }
374 else
375 {
376 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
377 }
378 }
379 else
380 {
381 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
382 }
383 pDescr++;
384 break;
385 }
386
387 case CSN_VARIABLE_TARRAY_OFFSET:
388 case CSN_VARIABLE_TARRAY:
389 case CSN_TYPE_ARRAY:
390 {
391 gint16 Status;
392 csnStream_t arT = *ar;
393 gint16 nCount = pDescr->i;
394 guint16 nSize = (guint16)(gint32)pDescr->serialize.value;
395
396 pui8 = pui8DATA(data, pDescr->offset);
397 if (pDescr->type == CSN_VARIABLE_TARRAY)
398 { /* Count specified in field */
399 nCount = *pui8DATA(data, pDescr->i);
400 }
401 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
402 { /* Count specified in field */
403 nCount = *pui8DATA(data, pDescr->i);
404 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
405 }
406
407 while (nCount > 0)
408 { /* resulting array of length 0 is possible
409 * but no bits shall be read from bitstream
410 */
411
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400412 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300413 csnStreamInit(&arT, bit_offset, remaining_bits_len);
414 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
415 if (Status >= 0)
416 {
417 pui8 += nSize;
418 remaining_bits_len = arT.remaining_bits_len;
419 bit_offset = arT.bit_offset;
420 }
421 else
422 {
423 return Status;
424 }
425 nCount--;
426 }
427
428 pDescr++;
429 break;
430 }
431
432 case CSN_BITMAP:
433 { /* bitmap with given length. The result is left aligned! */
434 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
435
436 if (no_of_bits > 0)
437 {
438
439 if (no_of_bits <= 32)
440 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400441 for(unsigned ib = 0; ib < 4; ib++)
442 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400443 guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400444 pui8 = pui8DATA(data, pDescr->offset+ib);
445 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400446 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400447 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300448 }
449 else if (no_of_bits <= 64)
450 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400451 for(unsigned ib = 0; ib < 8; ib++)
452 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400453 guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400454 pui8 = pui8DATA(data, pDescr->offset+ib);
455 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400456 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400457 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300458 }
459 else
460 {
461 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
462 }
463
464 remaining_bits_len -= no_of_bits;
465 assert(remaining_bits_len >= 0);
466 bit_offset += no_of_bits;
467 }
468 /* bitmap was successfully extracted or it was empty */
469
470 pDescr++;
471 break;
472 }
473
474 case CSN_TYPE:
475 {
476 gint16 Status;
477 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400478 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300479 csnStreamInit(&arT, bit_offset, remaining_bits_len);
480 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400481 LOGPC(DCSN1, LOGL_NOTICE, ": End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300482 if (Status >= 0)
483 {
484 remaining_bits_len = arT.remaining_bits_len;
485 bit_offset = arT.bit_offset;
486 pDescr++;
487 }
488 else
489 {
490 /* Has already been processed: ProcessError("csnStreamDecoder", Status, pDescr); */
491 return Status;
492 }
493
494 break;
495 }
496
497 case CSN_CHOICE:
498 {
499 gint16 count = pDescr->i;
500 guint8 i = 0;
501 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
502
503 while (count > 0)
504 {
505 guint8 no_of_bits = pChoice->bits;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400506 guint8 value = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300507 if (value == pChoice->value)
508 {
509 CSN_DESCR descr[2];
510 gint16 Status;
511 csnStream_t arT = *ar;
512
513 descr[0] = pChoice->descr;
514 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
515 descr[1].type = CSN_END;
516 pui8 = pui8DATA(data, pDescr->offset);
517 *pui8 = i;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400518 LOGPC(DCSN1, LOGL_NOTICE, "Choice %s = %u | ", pDescr->sz , (unsigned)value);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300519 bit_offset += no_of_bits;
520 remaining_bits_len -= no_of_bits;
521
522 csnStreamInit(&arT, bit_offset, remaining_bits_len);
523 Status = csnStreamDecoder(&arT, descr, vector, readIndex, data);
524
525 if (Status >= 0)
526 {
527 remaining_bits_len = arT.remaining_bits_len;
528 bit_offset = arT.bit_offset;
529 }
530 else
531 {
532 return Status;
533 }
534 break;
535 }
536
537 readIndex -= no_of_bits;
538 count--;
539 pChoice++;
540 i++;
541 }
542
543 pDescr++;
544 break;
545 }
546
547 case CSN_SERIALIZE:
548 {
549 StreamSerializeFcn_t serialize = pDescr->serialize.fcn;
550 csnStream_t arT = *ar;
551 gint16 Status = -1;
552
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400553 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %d | ", pDescr->sz , (int)bitvec_read_field(vector, readIndex, 7));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300554 arT.direction = 1;
555 bit_offset += 7;
556 remaining_bits_len -= 7;
557
558 csnStreamInit(&arT, bit_offset, remaining_bits_len);
559 Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset));
560
561 if (Status >= 0)
562 {
563 remaining_bits_len = arT.remaining_bits_len;
564 bit_offset = arT.bit_offset;
565 pDescr++;
566 }
567 else
568 {
569 /* Has already been processed: */
570 return Status;
571 }
572
573 break;
574 }
575
576 case CSN_UNION_LH:
577 case CSN_UNION:
578 {
579 gint16 Bits;
580 guint8 index;
581 gint16 count = pDescr->i;
582 const CSN_DESCR* pDescrNext = pDescr;
583
584 pDescrNext += count + 1; /* now this is next after the union */
585 if ((count <= 0) || (count > 16))
586 {
587 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
588 }
589
590 /* Now get the bits to extract the index */
591 Bits = ixBitsTab[count];
592 index = 0;
593
594 while (Bits > 0)
595 {
596 index <<= 1;
597
598 if (CSN_UNION_LH == pDescr->type)
599 {
600 index |= get_masked_bits8(vector,readIndex, bit_offset, 1);
601 }
602 else
603 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400604 index |= bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300605 }
606 remaining_bits_len--;
607 bit_offset++;
608 Bits--;
609 }
610
611 /* Assign UnionType */
612 pui8 = pui8DATA(data, pDescr->offset);
613 *pui8 = index;
614
615
616 /* script index to continue on, limited in case we do not have a power of 2 */
617 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400618 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300619
620 switch (pDescr->type)
621 { /* get the right element of the union based on computed index */
622
623 case CSN_BIT:
624 {
625 pui8 = pui8DATA(data, pDescr->offset);
626 *pui8 = 0x00;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400627 if (bitvec_read_field(vector, readIndex, 1) > 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300628 {
629 *pui8 = 0x01;
630 }
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400631 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300632 remaining_bits_len -= 1;
633 bit_offset++;
634 pDescr++;
635 break;
636 }
637
638 case CSN_NULL:
639 { /* Empty member! */
640 pDescr++;
641 break;
642 }
643
644 case CSN_UINT:
645 {
646 guint8 no_of_bits = (guint8) pDescr->i;
647 if (remaining_bits_len >= no_of_bits)
648 {
649 remaining_bits_len -= no_of_bits;
650
651 if (no_of_bits <= 8)
652 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400653 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300654 pui8 = pui8DATA(data, pDescr->offset);
655 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400656 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300657 }
658 else if (no_of_bits <= 16)
659 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400660 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300661 pui16 = pui16DATA(data, pDescr->offset);
662 *pui16 = ui16;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400663 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300664 }
665 else if (no_of_bits <= 32)
666 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400667 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300668 pui32 = pui32DATA(data, pDescr->offset);
669 *pui32 = ui32;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400670 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300671 }
672 else
673 {
674 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
675 }
676 }
677 else
678 {
679 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
680 }
681
682 bit_offset += no_of_bits;
683 pDescr++;
684 break;
685 }
686
687 case CSN_UINT_OFFSET:
688 {
689 guint8 no_of_bits = (guint8) pDescr->i;
690
691 if (remaining_bits_len >= no_of_bits)
692 {
693 if (no_of_bits <= 8)
694 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400695 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300696 pui8 = pui8DATA(data, pDescr->offset);
697 *pui8 = ui8 + (guint8)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400698 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300699 }
700 else if (no_of_bits <= 16)
701 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400702 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300703 pui16 = pui16DATA(data, pDescr->offset);
704 *pui16 = ui16 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400705 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300706 }
707 else if (no_of_bits <= 32)
708 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400709 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300710 pui32 = pui32DATA(data, pDescr->offset);
711 *pui32 = ui32 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400712 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300713 }
714 else
715 {
716 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
717 }
718 }
719 else
720 {
721 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
722 }
723
724 bit_offset += no_of_bits;
725 pDescr++;
726 break;
727 }
728
729 case CSN_UINT_LH:
730 {
731 guint8 no_of_bits = (guint8) pDescr->i;
732
733 if (remaining_bits_len >= no_of_bits)
734 {
735 if (no_of_bits <= 8)
736 {
737 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
738 pui8 = pui8DATA(data, pDescr->offset);
739 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400740 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300741 }
742 else
743 { /* Maybe we should support more than 8 bits ? */
744 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
745 }
746 }
747 else
748 {
749 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
750 }
751
752 bit_offset += no_of_bits;
753 pDescr++;
754 break;
755 }
756
757 case CSN_UINT_ARRAY:
758 {
759 guint8 no_of_bits = (guint8) pDescr->i;
760 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
761
762 if (pDescr->serialize.value != 0)
763 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
764 nCount = *pui16DATA(data, nCount);
765 }
766
767 if (remaining_bits_len >= no_of_bits)
768 {
769 remaining_bits_len -= (no_of_bits * nCount);
770 if (no_of_bits <= 8)
771 {
772 pui8 = pui8DATA(data, pDescr->offset);
773
774 while (nCount > 0)
775 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400776 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400777 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300778 pui8++;
779 bit_offset += no_of_bits;
780 nCount--;
781 }
782 }
783 else if (no_of_bits <= 16)
784 {
785 pui16 = pui16DATA(data, pDescr->offset);
786
787 while (nCount > 0)
788 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400789 *pui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400790 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300791 pui16++;
792 bit_offset += no_of_bits;
793 nCount--;
794 }
795 }
796 else if (no_of_bits <= 32)
797 { /* not supported */
798 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
799 }
800 else
801 {
802 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
803 }
804 }
805 else
806 {
807 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
808 }
809
810 pDescr++;
811 break;
812 }
813
814 case CSN_VARIABLE_TARRAY_OFFSET:
815 case CSN_VARIABLE_TARRAY:
816 case CSN_TYPE_ARRAY:
817 {
818 gint16 Status;
819 csnStream_t arT = *ar;
820 guint16 nCount = (guint16) pDescr->i;
821 guint16 nSize = (guint16)(guint32)pDescr->serialize.value;
822
823 pui8 = pui8DATA(data, pDescr->offset);
824
825 if (CSN_VARIABLE_TARRAY == pDescr->type)
826 { /* Count specified in field */
827 nCount = *pui8DATA(data, pDescr->i);
828 }
829 else if (CSN_VARIABLE_TARRAY_OFFSET == pDescr->type)
830 { /* Count specified in field */
831 nCount = *pui8DATA(data, pDescr->i);
832 nCount--; /* Offset 1 */
833 }
834
835 while (nCount--) /* Changed to handle length = 0. */
836 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400837 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300838 csnStreamInit(&arT, bit_offset, remaining_bits_len);
839 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
840 if (Status >= 0)
841 {
842 pui8 += nSize;
843 remaining_bits_len = arT.remaining_bits_len;
844 bit_offset = arT.bit_offset;
845 }
846 else
847 {
848 return Status;
849 }
850 }
851
852 pDescr++;
853 break;
854 }
855
856 case CSN_BITMAP:
857 { /* bitmap with given length. The result is left aligned! */
858 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
859
860 if (no_of_bits > 0)
861 {
862
863 if (no_of_bits <= 32)
864 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400865 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300866 pui32 = pui32DATA(data, pDescr->offset);
867 *pui32 = ui32;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300868 }
869 else if (no_of_bits <= 64)
870 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400871 guint64 ui64 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300872 pui64 = pui64DATA(data, pDescr->offset);
873 *pui64 = ui64;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400874 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300875 }
876 else
877 {
878 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
879 }
880
881 remaining_bits_len -= no_of_bits;
882 assert(remaining_bits_len >= 0);
883 bit_offset += no_of_bits;
884 }
885 /* bitmap was successfully extracted or it was empty */
886
887 pDescr++;
888 break;
889 }
890
891 case CSN_TYPE:
892 {
893 gint16 Status;
894 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400895 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300896 csnStreamInit(&arT, bit_offset, remaining_bits_len);
897 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400898 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300899 if (Status >= 0)
900 {
901 remaining_bits_len = arT.remaining_bits_len;
902 bit_offset = arT.bit_offset;
903 pDescr++;
904 }
905 else
906 { /* return error code Has already been processed: */
907 return Status;
908 }
909
910 break;
911 }
912
913 default:
914 { /* descriptions of union elements other than above are illegal */
915 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
916 }
917 }
918
919 pDescr = pDescrNext;
920 break;
921 }
922
923 case CSN_EXIST:
924 case CSN_EXIST_LH:
925 {
926 guint8 fExist;
927
928 pui8 = pui8DATA(data, pDescr->offset);
929
930 if (CSN_EXIST_LH == pDescr->type)
931 {
932 fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
933 }
934 else
935 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400936 fExist = bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300937 }
938
939 *pui8 = fExist;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400940 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300941 pDescr++;
942 remaining_bits_len -= 1;
943
944 if (!fExist)
945 {
946 ar->remaining_bits_len = remaining_bits_len;
947 ar->bit_offset = bit_offset;
948 return remaining_bits_len;
949 }
950
951 break;
952 }
953
954 case CSN_NEXT_EXIST:
955 {
956 guint8 fExist;
957
958 pui8 = pui8DATA(data, pDescr->offset);
959
960 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
961 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
962 { /* no more bits to decode is fine here - end of message detected and allowed */
963
964 /* Skip i entries + this entry */
965 pDescr += pDescr->i + 1;
966
967 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
968 if ( pDescr->type != CSN_END )
969 { /* Substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
970 remaining_bits_len--;
971 }
972
973 /* Set the data member to "not exist" */
974 *pui8 = 0;
975 break;
976 }
977
978 /* the "regular" M_NEXT_EXIST description element */
979
980 fExist = 0x00;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400981 if (bitvec_read_field(vector, readIndex, 1))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300982 {
983 fExist = 0x01;
984 }
985
986 *pui8 = fExist;
987 remaining_bits_len -= 1;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400988 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300989 ++bit_offset;
990
991 if (fExist == 0)
992 { /* Skip 'i' entries */
993 pDescr += pDescr->i;
994 }
995
996 pDescr++;
997 break;
998 }
999
1000 case CSN_NEXT_EXIST_LH:
1001 {
1002 guint8 fExist;
1003 pui8 = pui8DATA(data, pDescr->offset);
1004
1005 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
1006 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
1007 { /* no more bits to decode is fine here - end of message detected and allowed */
1008
1009 /* skip 'i' entries + this entry */
1010 pDescr += pDescr->i + 1;
1011
1012 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
1013 if ( pDescr->type != CSN_END )
1014 { /* substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
1015 remaining_bits_len--;
1016 }
1017
1018 /* set the data member to "not exist" */
1019 *pui8 = 0;
1020 break;
1021 }
1022
1023 /* the "regular" M_NEXT_EXIST_LH description element */
1024 fExist = get_masked_bits8(vector,readIndex,bit_offset, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001025 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)fExist);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001026 *pui8++ = fExist;
1027 remaining_bits_len -= 1;
1028
1029 bit_offset++;
1030
1031 if (fExist == 0)
1032 { /* Skip 'i' entries */
1033 pDescr += pDescr->i;
1034 }
1035 pDescr++;
1036
1037 break;
1038 }
1039
1040 case CSN_VARIABLE_BITMAP_1:
1041 { /* Bitmap from here and to the end of message */
1042
1043 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1044
1045 /*no break -
1046 * with a length set we have a regular variable length bitmap so we continue */
1047 }
1048
1049 case CSN_VARIABLE_BITMAP:
1050 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1051 * <N: bit (5)> <bitmap: bit(N + offset)>
1052 * Bit array with length (in bits) specified in parameter (pDescr->descr)
1053 * The result is right aligned!
1054 */
1055 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
1056
1057 no_of_bits += pDescr->i; /* adjusted by offset */
1058
1059 if (no_of_bits > 0)
1060 {
1061 remaining_bits_len -= no_of_bits;
1062
1063 if (remaining_bits_len < 0)
1064 {
1065 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1066 }
1067
1068 { /* extract bits */
1069 guint8* pui8 = pui8DATA(data, pDescr->offset);
1070 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1071
1072 if (nB1 > 0)
1073 { /* take care of the first byte - it will be right aligned */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001074 *pui8 = bitvec_read_field(vector, readIndex, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001075 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001076 pui8++;
1077 no_of_bits -= nB1;
1078 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1079 }
1080
1081 /* remaining no_of_bits is a multiple of 8 or 0 */
1082 while (no_of_bits > 0)
1083 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001084 *pui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001085 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001086 pui8++;
1087 no_of_bits -= 8;
1088 }
1089 }
1090 }
1091 pDescr++;
1092 break;
1093 }
1094
1095 case CSN_LEFT_ALIGNED_VAR_BMP_1:
1096 { /* Bitmap from here and to the end of message */
1097
1098 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1099
1100 /* no break -
1101 * with a length set we have a regular left aligned variable length bitmap so we continue
1102 */
1103 }
1104
1105 case CSN_LEFT_ALIGNED_VAR_BMP:
1106 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1107 * <N: bit (5)> <bitmap: bit(N + offset)>
1108 * bit array with length (in bits) specified in parameter (pDescr->descr)
1109 */
1110 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
1111
1112 no_of_bits += pDescr->i;/* size adjusted by offset */
1113
1114 if (no_of_bits > 0)
1115 {
1116 remaining_bits_len -= no_of_bits;
1117
1118 if (remaining_bits_len < 0)
1119 {
1120 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1121 }
1122
1123 { /* extract bits */
1124 guint8* pui8 = pui8DATA(data, pDescr->offset);
1125 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1126
1127 while (no_of_bits > 0)
1128 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001129 *pui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001130 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001131 pui8++;
1132 no_of_bits -= 8;
1133 }
1134 if (nB1 > 0)
1135 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001136 *pui8 = bitvec_read_field(vector, readIndex, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001137 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001138 pui8++;
1139 no_of_bits -= nB1;
1140 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1141 }
1142 }
1143 }
1144
1145 /* bitmap was successfully extracted or it was empty */
1146 pDescr++;
1147 break;
1148 }
1149
1150 case CSN_VARIABLE_ARRAY:
1151 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
1152 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1153 * Array with length specified in parameter:
1154 * <count: bit (x)>
1155 * <list: octet(count + offset)>
1156 */
1157 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
1158
1159 count += pDescr->i; /* Adjusted by offset */
1160
1161 if (count > 0)
1162 {
1163 remaining_bits_len -= count * 8;
1164
1165 if (remaining_bits_len < 0)
1166 {
1167 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1168 }
1169
1170 pui8 = pui8DATA(data, pDescr->offset);
1171
1172 while (count > 0)
1173 {
1174 readIndex -= 8;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001175 *pui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001176 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001177 pui8++;
1178 bit_offset += 8;
1179 count--;
1180 }
1181 }
1182
1183 pDescr++;
1184 break;
1185 }
1186
1187 case CSN_RECURSIVE_ARRAY:
1188 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
1189 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
1190 * where <element> ::= bit(value)
1191 * <tag> ::= 0 | 1
1192 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
1193 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1194 * REMARK: recursive way to specify an array but an iterative implementation!
1195 */
1196 gint16 no_of_bits = pDescr->i;
1197 guint8 ElementCount = 0;
1198
1199 pui8 = pui8DATA(data, pDescr->offset);
1200
1201 while (existNextElement(vector, readIndex, Tag))
1202 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001203 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001204 bit_offset++;
1205 remaining_bits_len--;
1206
1207 /* extract and store no_of_bits long element from bitstream */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001208 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001209 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001210 pui8++;
1211 remaining_bits_len -= no_of_bits;
1212 ElementCount++;
1213
1214 if (remaining_bits_len < 0)
1215 {
1216 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1217 }
1218
1219 bit_offset += no_of_bits;
1220 }
1221
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001222 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)bitvec_read_field(vector, readIndex, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001223 /* existNextElement() returned FALSE, 1 bit consumed */
1224 bit_offset++;
1225
1226 /* Store the counted number of elements of the array */
1227 *pui8DATA(data, (gint16)pDescr->descr.value) = ElementCount;
1228
1229 pDescr++;
1230 break;
1231 }
1232
1233 case CSN_RECURSIVE_TARRAY:
1234 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
1235 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1236 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1237 */
1238 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
1239 guint8 ElementCount = 0;
1240 pui8 = pui8DATA(data, pDescr->offset);
1241
1242 while (existNextElement(vector, readIndex, Tag))
1243 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001244 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001245 /* existNextElement() returned TRUE, 1 bit consumed */
1246 bit_offset++;
1247 remaining_bits_len--;
1248 ElementCount++;
1249
1250 { /* unpack the following data structure */
1251 csnStream_t arT = *ar;
1252 gint16 Status;
1253 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1254 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
1255
1256 if (Status >= 0)
1257 { /* successful completion */
1258 pui8 += nSizeElement; /* -> to next data element */
1259 remaining_bits_len = arT.remaining_bits_len;
1260 bit_offset = arT.bit_offset;
1261 }
1262 else
1263 { /* something went awry */
1264 return Status;
1265 }
1266 }
1267
1268 if (remaining_bits_len < 0)
1269 {
1270 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1271 }
1272 }
1273
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001274 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)bitvec_read_field(vector, readIndex, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001275
1276 /* existNextElement() returned FALSE, 1 bit consumed */
1277 bit_offset++;
1278
1279 /* Store the counted number of elements of the array */
1280 *pui8DATA(data, (gint16)(gint32)pDescr->i) = ElementCount;
1281
1282 pDescr++;
1283 break;
1284 }
1285
1286 case CSN_RECURSIVE_TARRAY_2:
1287 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
1288
1289 Tag = REVERSED_TAG;
1290
1291 /* NO break -
1292 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
1293 */
1294 }
1295
1296 case CSN_RECURSIVE_TARRAY_1:
1297 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
1298 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1299 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1300 */
1301 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
1302 guint8 ElementCount = 0;
1303 csnStream_t arT = *ar;
1304 gboolean EndOfList = FALSE;
1305 gint16 Status;
1306 pui8 = pui8DATA(data, pDescr->offset);
1307
1308 do
1309 { /* get data element */
1310 ElementCount++;
1311
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001312 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
1313
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001314 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1315 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
1316
1317 if (Status >= 0)
1318 { /* successful completion */
1319 pui8 += nSizeElement; /* -> to next */
1320 remaining_bits_len = arT.remaining_bits_len;
1321 bit_offset = arT.bit_offset;
1322 }
1323 else
1324 { /* something went awry */
1325 return Status;
1326 }
1327
1328 if (remaining_bits_len < 0)
1329 {
1330 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1331 }
1332
1333 /* control of next element's tag */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001334 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001335 EndOfList = !(existNextElement(vector, readIndex, Tag));
1336
1337 bit_offset++;
1338 remaining_bits_len--; /* 1 bit consumed (tag) */
1339 } while (!EndOfList);
1340
1341
1342 /* Store the count of the array */
1343 *pui8DATA(data, pDescr->i) = ElementCount;
1344 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
1345 pDescr++;
1346 break;
1347 }
1348
1349 case CSN_FIXED:
1350 { /* Verify the fixed bits */
1351 guint8 no_of_bits = (guint8) pDescr->i;
1352 guint32 ui32;
1353
1354 if (no_of_bits <= 32)
1355 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001356 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001357 }
1358 else
1359 {
1360 return ProcessError(readIndex,"no_of_bits > 32", -1, pDescr);
1361 }
1362 if (ui32 != (unsigned)(gint32)pDescr->offset)
1363 {
1364 return ProcessError(readIndex,"csnStreamDecoder FIXED value does not match", -1, pDescr);
1365 }
1366
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001367 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)ui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001368 remaining_bits_len -= no_of_bits;
1369 bit_offset += no_of_bits;
1370 pDescr++;
1371 break;
1372 }
1373
1374 case CSN_CALLBACK:
1375 {
1376 return ProcessError(readIndex,"csnStreamDecoder Callback not implemented", -1, pDescr);
1377 break;
1378 }
1379
1380 case CSN_TRAP_ERROR:
1381 {
1382 return ProcessError(readIndex,"csnStreamDecoder", pDescr->i, pDescr);
1383 }
1384
1385 case CSN_END:
1386 {
1387 ar->remaining_bits_len = remaining_bits_len;
1388 ar->bit_offset = bit_offset;
1389 return remaining_bits_len;
1390 }
1391
1392 default:
1393 {
1394 assert(0);
1395 }
1396
1397
1398 }
1399
1400 } while (remaining_bits_len >= 0);
1401
1402 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1403}
1404
1405
1406
1407
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001408gint16 csnStreamEncoder(csnStream_t* ar, const CSN_DESCR* pDescr, bitvec *vector, unsigned& writeIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001409{
1410 gint remaining_bits_len = ar->remaining_bits_len;
1411 gint bit_offset = ar->bit_offset;
1412 guint8* pui8;
1413 guint16* pui16;
1414 guint32* pui32;
1415 guint64* pui64;
1416
1417 guint8 Tag = STANDARD_TAG;
1418
1419 if (remaining_bits_len <= 0)
1420 {
1421 return 0;
1422 }
1423
1424 do
1425 {
1426 switch (pDescr->type)
1427 {
1428 case CSN_BIT:
1429 {
1430 if (remaining_bits_len > 0)
1431 {
1432 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001433 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001434 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001435 /* end add the bit value to protocol tree */
1436 }
1437 else
1438 {
1439 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1440 }
1441
1442 pDescr++;
1443 remaining_bits_len--;
1444 bit_offset++;
1445 break;
1446 }
1447
1448 case CSN_NULL:
1449 { /* Empty member! */
1450 pDescr++;
1451 break;
1452 }
1453
1454 case CSN_UINT:
1455 {
1456 guint8 no_of_bits = (guint8) pDescr->i;
1457
1458 if (remaining_bits_len >= no_of_bits)
1459 {
1460 if (no_of_bits <= 8)
1461 {
1462 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001463 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001464 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001465 }
1466 else if (no_of_bits <= 16)
1467 {
1468 pui16 = pui16DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001469 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001470 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001471 }
1472 else if (no_of_bits <= 32)
1473 {
1474 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001475 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001476 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001477 }
1478 else
1479 {
1480 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1481 }
1482 }
1483 else
1484 {
1485 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1486 }
1487
1488 remaining_bits_len -= no_of_bits;
1489 bit_offset += no_of_bits;
1490 pDescr++;
1491 break;
1492 }
1493
1494 case CSN_UINT_OFFSET:
1495 {
1496 guint8 no_of_bits = (guint8) pDescr->i;
1497
1498 if (remaining_bits_len >= no_of_bits)
1499 {
1500 if (no_of_bits <= 8)
1501 {
1502 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001503 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001504 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001505 }
1506 else if (no_of_bits <= 16)
1507 {
1508 pui16 = pui16DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001509 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001510 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001511 }
1512 else if (no_of_bits <= 32)
1513 {
1514 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001515 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001516 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001517 }
1518 else
1519 {
1520 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1521 }
1522 }
1523 else
1524 {
1525 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1526 }
1527
1528 remaining_bits_len -= no_of_bits;
1529 bit_offset += no_of_bits;
1530 pDescr++;
1531 break;
1532 }
1533
1534 case CSN_UINT_LH:
1535 {
1536 guint8 no_of_bits = (guint8) pDescr->i;
1537
1538 if (remaining_bits_len >= no_of_bits)
1539 {
1540 remaining_bits_len -= no_of_bits;
1541 if (no_of_bits <= 8)
1542 {
1543 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001544 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001545 // TODO : Change get_masked_bits8()
1546 writeIndex -= no_of_bits;
1547 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
1548 writeIndex -= no_of_bits;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001549 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001550 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001551
1552 }
1553 else
1554 {/* Maybe we should support more than 8 bits ? */
1555 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1556 }
1557 }
1558 else
1559 {
1560 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1561 }
1562
1563 remaining_bits_len -= no_of_bits;
1564 bit_offset += no_of_bits;
1565 pDescr++;
1566 break;
1567 }
1568
1569 case CSN_UINT_ARRAY:
1570 {
1571 guint8 no_of_bits = (guint8) pDescr->i;
1572 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
1573
1574 if (pDescr->serialize.value != 0)
1575 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
1576 nCount = *pui16DATA(data, nCount);
1577 }
1578
1579 if (remaining_bits_len >= no_of_bits)
1580 {
1581 remaining_bits_len -= (no_of_bits*nCount);
1582 if (no_of_bits <= 8)
1583 {
1584 pui8 = pui8DATA(data, pDescr->offset);
1585 do
1586 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001587 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
1588 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001589 pui8++;
1590 bit_offset += no_of_bits;
1591 } while (--nCount > 0);
1592 }
1593 else if (no_of_bits <= 16)
1594 {
1595 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1596 }
1597 else if (no_of_bits <= 32)
1598 {
1599 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1600 }
1601 else
1602 {
1603 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1604 }
1605 }
1606 else
1607 {
1608 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1609 }
1610 pDescr++;
1611 break;
1612 }
1613
1614 case CSN_VARIABLE_TARRAY_OFFSET:
1615 case CSN_VARIABLE_TARRAY:
1616 case CSN_TYPE_ARRAY:
1617 {
1618 gint16 Status;
1619 csnStream_t arT = *ar;
1620 gint16 nCount = pDescr->i;
1621 guint16 nSize = (guint16)(gint32)pDescr->serialize.value;
1622
1623 pui8 = pui8DATA(data, pDescr->offset);
1624 if (pDescr->type == CSN_VARIABLE_TARRAY)
1625 { /* Count specified in field */
1626 nCount = *pui8DATA(data, pDescr->i);
1627 }
1628 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
1629 { /* Count specified in field */
1630 nCount = *pui8DATA(data, pDescr->i);
1631 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
1632 }
1633
1634 while (nCount > 0)
1635 { /* resulting array of length 0 is possible
1636 * but no bits shall be read from bitstream
1637 */
1638
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001639 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001640 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1641 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
1642 if (Status >= 0)
1643 {
1644 pui8 += nSize;
1645 remaining_bits_len = arT.remaining_bits_len;
1646 bit_offset = arT.bit_offset;
1647
1648 }
1649 else
1650 {
1651 return Status;
1652 }
1653 nCount--;
1654 }
1655
1656 pDescr++;
1657 break;
1658 }
1659
1660 case CSN_BITMAP:
1661 { /* bitmap with given length. The result is left aligned! */
1662 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
1663
1664 if (no_of_bits > 0)
1665 {
1666
1667 if (no_of_bits <= 32)
1668 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001669 for(unsigned ib = 0; ib < 4; ib++)
1670 {
1671 pui8 = pui8DATA(data, pDescr->offset+ib);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001672 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001673 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001674 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001675 }
1676 else if (no_of_bits <= 64)
1677 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001678 for(unsigned ib = 0; ib < 8; ib++)
1679 {
1680 pui8 = pui8DATA(data, pDescr->offset+ib);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001681 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001682 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001683 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001684 }
1685 else
1686 {
1687 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
1688 }
1689
1690 remaining_bits_len -= no_of_bits;
1691 assert(remaining_bits_len >= 0);
1692 bit_offset += no_of_bits;
1693 }
1694 /* bitmap was successfully extracted or it was empty */
1695
1696 pDescr++;
1697 break;
1698 }
1699
1700 case CSN_TYPE:
1701 {
1702 gint16 Status;
1703 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001704 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001705 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1706 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001707 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001708 if (Status >= 0)
1709 {
1710
1711 remaining_bits_len = arT.remaining_bits_len;
1712 bit_offset = arT.bit_offset;
1713 pDescr++;
1714 }
1715 else
1716 {
1717 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
1718 return Status;
1719 }
1720
1721 break;
1722 }
1723
1724 case CSN_CHOICE:
1725 {
1726 //gint16 count = pDescr->i;
1727 guint8 i = 0;
1728 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
1729
1730 pui8 = pui8DATA(data, pDescr->offset);
1731 i = *pui8;
1732 pChoice += i;
1733 guint8 no_of_bits = pChoice->bits;
1734 guint8 value = pChoice->value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001735 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pChoice->descr.sz , (unsigned)value);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001736 bitvec_write_field(vector, writeIndex, value, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001737
1738 CSN_DESCR descr[2];
1739 gint16 Status;
1740 csnStream_t arT = *ar;
1741
1742 descr[0] = pChoice->descr;
1743 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
1744 descr[1].type = CSN_END;
1745 bit_offset += no_of_bits;
1746 remaining_bits_len -= no_of_bits;
1747
1748 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1749 Status = csnStreamEncoder(&arT, descr, vector, writeIndex, data);
1750
1751 if (Status >= 0)
1752 {
1753 remaining_bits_len = arT.remaining_bits_len;
1754 bit_offset = arT.bit_offset;
1755 }
1756 else
1757 {
1758 return Status;
1759 }
1760
1761 pDescr++;
1762 break;
1763 }
1764
1765 case CSN_SERIALIZE:
1766 {
1767 StreamSerializeFcn_t serialize = pDescr->serialize.fcn;
1768 csnStream_t arT = *ar;
1769 gint16 Status = -1;
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001770 unsigned lengthIndex;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001771
1772 // store writeIndex for length value (7 bit)
1773 lengthIndex = writeIndex;
1774 writeIndex += 7;
1775 bit_offset += 7;
1776 remaining_bits_len -= 7;
1777 arT.direction = 0;
1778 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1779 Status = serialize(&arT, vector, writeIndex, pvDATA(data, pDescr->offset));
1780
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001781 bitvec_write_field(vector, lengthIndex, writeIndex-lengthIndex-7, 7);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001782 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %u | ", pDescr->sz , (unsigned)(writeIndex-lengthIndex));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001783
1784 if (Status >= 0)
1785 {
1786 remaining_bits_len = arT.remaining_bits_len;
1787 bit_offset = arT.bit_offset;
1788 pDescr++;
1789 }
1790 else
1791 {
1792 // Has already been processed:
1793 return Status;
1794 }
1795
1796 break;
1797 }
1798
1799 case CSN_UNION_LH:
1800 case CSN_UNION:
1801 {
1802 gint16 Bits;
1803 guint8 index;
1804 gint16 count = pDescr->i;
1805 const CSN_DESCR* pDescrNext = pDescr;
1806
1807 pDescrNext += count + 1; /* now this is next after the union */
1808 if ((count <= 0) || (count > 16))
1809 {
1810 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
1811 }
1812
1813 /* Now get the bits to extract the index */
1814 Bits = ixBitsTab[count];
1815 index = 0;
1816
1817 /* Assign UnionType */
1818 pui8 = pui8DATA(data, pDescr->offset);
1819 //read index from data and write to vector
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001820 bitvec_write_field(vector, writeIndex, *pui8, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001821
1822 //decode index
1823 writeIndex -= Bits;
1824
1825 while (Bits > 0)
1826 {
1827 index <<= 1;
1828
1829 if (CSN_UNION_LH == pDescr->type)
1830 {
1831 index |= get_masked_bits8(vector,writeIndex, bit_offset, 1);
1832 }
1833 else
1834 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001835 index |= bitvec_read_field(vector, writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001836 }
1837
1838 remaining_bits_len--;
1839 bit_offset++;
1840 Bits--;
1841 }
1842
1843 writeIndex -= Bits;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001844 bitvec_write_field(vector, writeIndex, index, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001845
1846
1847 /* script index to continue on, limited in case we do not have a power of 2 */
1848 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001849 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)index);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001850
1851 switch (pDescr->type)
1852 { /* get the right element of the union based on computed index */
1853
1854 case CSN_BIT:
1855 {
1856 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001857 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001858 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001859 remaining_bits_len -= 1;
1860 bit_offset++;
1861 pDescr++;
1862 break;
1863 }
1864
1865 case CSN_NULL:
1866 { /* Empty member! */
1867 pDescr++;
1868 break;
1869 }
1870
1871 case CSN_UINT:
1872 {
1873 guint8 no_of_bits = (guint8) pDescr->i;
1874 if (remaining_bits_len >= no_of_bits)
1875 {
1876 remaining_bits_len -= no_of_bits;
1877
1878 if (no_of_bits <= 8)
1879 {
1880 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001881 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001882 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001883 }
1884 else if (no_of_bits <= 16)
1885 {
1886 pui16 = pui16DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001887 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001888 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001889 }
1890 else if (no_of_bits <= 32)
1891 {
1892 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001893 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001894 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001895 }
1896 else
1897 {
1898 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1899 }
1900 }
1901 else
1902 {
1903 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1904 }
1905
1906 bit_offset += no_of_bits;
1907 pDescr++;
1908 break;
1909 }
1910
1911 case CSN_UINT_OFFSET:
1912 {
1913 guint8 no_of_bits = (guint8) pDescr->i;
1914
1915 if (remaining_bits_len >= no_of_bits)
1916 {
1917 if (no_of_bits <= 8)
1918 {
1919 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001920 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001921 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001922 }
1923 else if (no_of_bits <= 16)
1924 {
1925 pui16 = pui16DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001926 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001927 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001928 }
1929 else if (no_of_bits <= 32)
1930 {
1931 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001932 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001933 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001934 }
1935 else
1936 {
1937 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1938 }
1939 }
1940 else
1941 {
1942 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1943 }
1944
1945 remaining_bits_len -= no_of_bits;
1946 bit_offset += no_of_bits;
1947 pDescr++;
1948 break;
1949 }
1950
1951 case CSN_UINT_LH:
1952 {
1953 guint8 no_of_bits = (guint8) pDescr->i;
1954
1955 if (remaining_bits_len >= no_of_bits)
1956 {
1957 remaining_bits_len -= no_of_bits;
1958 if (no_of_bits <= 8)
1959 {
1960 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001961 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001962 // TODO : Change get_masked_bits8()
1963 writeIndex -= no_of_bits;
1964 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
1965 writeIndex -= no_of_bits;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001966 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001967 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001968
1969 }
1970 else
1971 {/* Maybe we should support more than 8 bits ? */
1972 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1973 }
1974 }
1975 else
1976 {
1977 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1978 }
1979
1980 remaining_bits_len -= no_of_bits;
1981 bit_offset += no_of_bits;
1982 pDescr++;
1983 break;
1984 }
1985
1986 case CSN_UINT_ARRAY:
1987 {
1988 guint8 no_of_bits = (guint8) pDescr->i;
1989 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
1990
1991 if (pDescr->serialize.value != 0)
1992 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
1993 nCount = *pui16DATA(data, nCount);
1994 }
1995
1996 if (remaining_bits_len >= no_of_bits)
1997 {
1998 remaining_bits_len -= (no_of_bits*nCount);
1999 if (no_of_bits <= 8)
2000 {
2001 pui8 = pui8DATA(data, pDescr->offset);
2002 do
2003 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002004 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
2005 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002006 pui8++;
2007 bit_offset += no_of_bits;
2008 } while (--nCount > 0);
2009 }
2010 else if (no_of_bits <= 16)
2011 {
2012 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2013 }
2014 else if (no_of_bits <= 32)
2015 {
2016 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2017 }
2018 else
2019 {
2020 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2021 }
2022 }
2023 else
2024 {
2025 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2026 }
2027 pDescr++;
2028 break;
2029 }
2030
2031 case CSN_VARIABLE_TARRAY_OFFSET:
2032 case CSN_VARIABLE_TARRAY:
2033 case CSN_TYPE_ARRAY:
2034 {
2035 gint16 Status;
2036 csnStream_t arT = *ar;
2037 gint16 nCount = pDescr->i;
2038 guint16 nSize = (guint16)(gint32)pDescr->serialize.value;
2039
2040 pui8 = pui8DATA(data, pDescr->offset);
2041 if (pDescr->type == CSN_VARIABLE_TARRAY)
2042 { /* Count specified in field */
2043 nCount = *pui8DATA(data, pDescr->i);
2044 }
2045 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
2046 { /* Count specified in field */
2047 nCount = *pui8DATA(data, pDescr->i);
2048 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
2049 }
2050
2051 while (nCount > 0)
2052 { /* resulting array of length 0 is possible
2053 * but no bits shall be read from bitstream
2054 */
2055
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002056 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002057 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2058 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
2059 if (Status >= 0)
2060 {
2061 pui8 += nSize;
2062 remaining_bits_len = arT.remaining_bits_len;
2063 bit_offset = arT.bit_offset;
2064 }
2065 else
2066 {
2067 return Status;
2068 }
2069 nCount--;
2070 }
2071
2072 pDescr++;
2073 break;
2074 }
2075
2076 case CSN_BITMAP:
2077 { /* bitmap with given length. The result is left aligned! */
2078 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
2079
2080 if (no_of_bits > 0)
2081 {
2082
2083 if (no_of_bits <= 32)
2084 {
2085 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002086 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002087 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002088 }
2089 else if (no_of_bits <= 64)
2090 {
2091 pui64 = pui64DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002092 bitvec_write_field(vector, writeIndex, *pui64, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002093 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002094 }
2095 else
2096 {
2097 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
2098 }
2099
2100 remaining_bits_len -= no_of_bits;
2101 assert(remaining_bits_len >= 0);
2102 bit_offset += no_of_bits;
2103 }
2104 /* bitmap was successfully extracted or it was empty */
2105
2106 pDescr++;
2107 break;
2108 }
2109
2110 case CSN_TYPE:
2111 {
2112 gint16 Status;
2113 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002114 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002115 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2116 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002117 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002118 if (Status >= 0)
2119 {
2120 remaining_bits_len = arT.remaining_bits_len;
2121 bit_offset = arT.bit_offset;
2122 pDescr++;
2123 }
2124 else
2125 {
2126 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
2127 return Status;
2128 }
2129
2130 break;
2131 }
2132
2133 default:
2134 { /* descriptions of union elements other than above are illegal */
2135 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
2136 }
2137 }
2138
2139 pDescr = pDescrNext;
2140 break;
2141 }
2142
2143 case CSN_EXIST:
2144 case CSN_EXIST_LH:
2145 {
2146 guint8 fExist;
2147 unsigned exist = 0;
2148 pui8 = pui8DATA(data, pDescr->offset);
2149 exist = *pui8;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002150 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002151 writeIndex--;
2152 if (CSN_EXIST_LH == pDescr->type)
2153 {
2154 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
2155 }
2156 else
2157 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002158 fExist = bitvec_read_field(vector, writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002159 }
2160 writeIndex--;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002161 bitvec_write_field(vector, writeIndex, fExist, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002162 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz, (unsigned)fExist);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002163 pDescr++;
2164 remaining_bits_len -= 1;
2165
2166 if (!exist)
2167 {
2168 ar->remaining_bits_len = remaining_bits_len;
2169 ar->bit_offset = bit_offset;
2170 return remaining_bits_len;
2171 }
2172 break;
2173 }
2174
2175 case CSN_NEXT_EXIST:
2176 {
2177 guint8 fExist;
2178
2179 pui8 = pui8DATA(data, pDescr->offset);
2180
2181 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
2182 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
2183 { /* no more bits to decode is fine here - end of message detected and allowed */
2184
2185 /* Skip i entries + this entry */
2186 pDescr += pDescr->i + 1;
2187
2188 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
2189 if ( pDescr->type != CSN_END )
2190 { /* Substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
2191 remaining_bits_len--;
2192 }
2193
2194 break;
2195 }
2196
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002197 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002198 fExist = *pui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002199 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002200 remaining_bits_len -= 1;
2201
2202 ++bit_offset;
2203
2204 if (fExist == 0)
2205 { /* Skip 'i' entries */
2206 pDescr += pDescr->i;
2207 }
2208
2209 pDescr++;
2210 break;
2211 }
2212
2213 case CSN_NEXT_EXIST_LH:
2214 {
2215 guint8 fExist;
2216 pui8 = pui8DATA(data, pDescr->offset);
2217
2218 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
2219 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
2220 { /* no more bits to decode is fine here - end of message detected and allowed */
2221
2222 /* skip 'i' entries + this entry */
2223 pDescr += pDescr->i + 1;
2224
2225 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
2226 if ( pDescr->type != CSN_END )
2227 { /* substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
2228 remaining_bits_len--;
2229 }
2230
2231 /* set the data member to "not exist" */
2232 //*pui8 = 0;
2233 break;
2234 }
2235
2236 /* the "regular" M_NEXT_EXIST_LH description element */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002237 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002238 writeIndex--;
2239 fExist = get_masked_bits8(vector,writeIndex, bit_offset, 1);
2240 writeIndex--;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002241 bitvec_write_field(vector, writeIndex, fExist, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002242 pui8++;
2243 remaining_bits_len -= 1;
2244
2245 bit_offset++;
2246
2247 if (fExist == 0)
2248 { /* Skip 'i' entries */
2249 pDescr += pDescr->i;
2250 }
2251 pDescr++;
2252
2253 break;
2254 }
2255
2256 case CSN_VARIABLE_BITMAP_1:
2257 { /* Bitmap from here and to the end of message */
2258
2259 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2260
2261 /*no break -
2262 * with a length set we have a regular variable length bitmap so we continue */
2263 }
2264
2265 case CSN_VARIABLE_BITMAP:
2266 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2267 * <N: bit (5)> <bitmap: bit(N + offset)>
2268 * Bit array with length (in bits) specified in parameter (pDescr->descr)
2269 * The result is right aligned!
2270 */
2271 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
2272
2273 no_of_bits += pDescr->i; /* adjusted by offset */
2274
2275 if (no_of_bits > 0)
2276 {
2277 remaining_bits_len -= no_of_bits;
2278
2279 if (remaining_bits_len < 0)
2280 {
2281 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2282 }
2283
2284 { /* extract bits */
2285 guint8* pui8 = pui8DATA(data, pDescr->offset);
2286 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2287
2288 if (nB1 > 0)
2289 { /* take care of the first byte - it will be right aligned */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002290 bitvec_write_field(vector, writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002291 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002292 pui8++;
2293 no_of_bits -= nB1;
2294 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2295 }
2296
2297 /* remaining no_of_bits is a multiple of 8 or 0 */
2298 while (no_of_bits > 0)
2299 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002300 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002301 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002302 pui8++;
2303 no_of_bits -= 8;
2304 }
2305 }
2306 }
2307 pDescr++;
2308 break;
2309 }
2310
2311 case CSN_LEFT_ALIGNED_VAR_BMP_1:
2312 { /* Bitmap from here and to the end of message */
2313
2314 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2315
2316 /* no break -
2317 * with a length set we have a regular left aligned variable length bitmap so we continue
2318 */
2319 }
2320
2321 case CSN_LEFT_ALIGNED_VAR_BMP:
2322 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2323 * <N: bit (5)> <bitmap: bit(N + offset)>
2324 * bit array with length (in bits) specified in parameter (pDescr->descr)
2325 */
2326
2327 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
2328
2329 no_of_bits += pDescr->i;/* size adjusted by offset */
2330
2331 if (no_of_bits > 0)
2332 {
2333 remaining_bits_len -= no_of_bits;
2334
2335 if (remaining_bits_len < 0)
2336 {
2337 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2338 }
2339
2340 { /* extract bits */
2341 guint8* pui8 = pui8DATA(data, pDescr->offset);
2342 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2343
2344 while (no_of_bits > 0)
2345 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002346 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002347 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002348 pui8++;
2349 no_of_bits -= 8;
2350 }
2351 if (nB1 > 0)
2352 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002353 bitvec_write_field(vector, writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002354 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002355 pui8++;
2356 no_of_bits -= nB1;
2357 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2358 }
2359 }
2360
2361 }
2362
2363 /* bitmap was successfully extracted or it was empty */
2364 pDescr++;
2365 break;
2366 }
2367
2368 case CSN_VARIABLE_ARRAY:
2369 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
2370 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2371 * Array with length specified in parameter:
2372 * <count: bit (x)>
2373 * <list: octet(count + offset)>
2374 */
2375 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
2376
2377 count += pDescr->i; /* Adjusted by offset */
2378
2379 if (count > 0)
2380 {
2381 remaining_bits_len -= count * 8;
2382
2383 if (remaining_bits_len < 0)
2384 {
2385 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2386 }
2387
2388 pui8 = pui8DATA(data, pDescr->offset);
2389
2390 while (count > 0)
2391 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002392 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002393 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002394 pui8++;
2395 bit_offset += 8;
2396 count--;
2397 }
2398 }
2399
2400 pDescr++;
2401 break;
2402 }
2403
2404 case CSN_RECURSIVE_ARRAY:
2405 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
2406 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
2407 * where <element> ::= bit(value)
2408 * <tag> ::= 0 | 1
2409 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
2410 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2411 * REMARK: recursive way to specify an array but an iterative implementation!
2412 */
2413 gint16 no_of_bits = pDescr->i;
2414 guint8 ElementCount = 0;
2415 pui8 = pui8DATA(data, pDescr->offset);
2416 ElementCount = *pui8DATA(data, (gint16)pDescr->descr.value);
2417 while (ElementCount > 0)
2418 { /* tag control shows existence of next list elements */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002419 bitvec_write_field(vector, writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002420 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002421 bit_offset++;
2422 remaining_bits_len--;
2423
2424 /* extract and store no_of_bits long element from bitstream */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002425 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002426 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002427 pui8++;
2428 remaining_bits_len -= no_of_bits;
2429 ElementCount--;
2430
2431 if (remaining_bits_len < 0)
2432 {
2433 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2434 }
2435
2436 bit_offset += no_of_bits;
2437 }
2438
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002439 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002440 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002441 bit_offset++;
2442
2443 pDescr++;
2444 break;
2445 }
2446
2447 case CSN_RECURSIVE_TARRAY:
2448 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
2449 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2450 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2451 */
2452 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
2453 guint8 ElementCount = 0;
2454 pui8 = pui8DATA(data, pDescr->offset);
2455 /* Store the counted number of elements of the array */
2456 ElementCount = *pui8DATA(data, (gint16)(gint32)pDescr->i);
2457
2458 while (ElementCount > 0)
2459 { /* tag control shows existence of next list elements */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002460 bitvec_write_field(vector, writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002461 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002462 bit_offset++;
2463
2464 remaining_bits_len--;
2465 ElementCount--;
2466
2467 { /* unpack the following data structure */
2468 csnStream_t arT = *ar;
2469 gint16 Status;
2470 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2471 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
2472
2473 if (Status >= 0)
2474 { /* successful completion */
2475 pui8 += nSizeElement; /* -> to next data element */
2476 remaining_bits_len = arT.remaining_bits_len;
2477 bit_offset = arT.bit_offset;
2478 }
2479 else
2480 { /* something went awry */
2481 return Status;
2482 }
2483 }
2484
2485 if (remaining_bits_len < 0)
2486 {
2487 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2488 }
2489 }
2490
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002491 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002492 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002493 bit_offset++;
2494
2495 pDescr++;
2496 break;
2497 }
2498
2499 case CSN_RECURSIVE_TARRAY_2:
2500 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
2501
2502 Tag = REVERSED_TAG;
2503
2504 /* NO break -
2505 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
2506 */
2507 }
2508
2509 case CSN_RECURSIVE_TARRAY_1:
2510 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
2511 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2512 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2513 */
2514 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
2515 guint8 ElementCount = 0;
2516 guint8 ElementNum = 0;
2517 csnStream_t arT = *ar;
2518 gint16 Status;
2519
2520 pui8 = pui8DATA(data, pDescr->offset);
2521 /* Store the count of the array */
2522 ElementCount = *pui8DATA(data, pDescr->i);
2523 ElementNum = ElementCount;
2524
2525 while (ElementCount > 0)
2526 { /* get data element */
2527 if (ElementCount != ElementNum)
2528 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002529 bitvec_write_field(vector, writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002530 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002531 bit_offset++;
2532 remaining_bits_len--;
2533 }
2534 ElementCount--;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002535 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002536 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2537 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002538 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002539 if (Status >= 0)
2540 { /* successful completion */
2541 pui8 += nSizeElement; /* -> to next */
2542 remaining_bits_len = arT.remaining_bits_len;
2543 bit_offset = arT.bit_offset;
2544 }
2545 else
2546 { /* something went awry */
2547 return Status;
2548 }
2549
2550 if (remaining_bits_len < 0)
2551 {
2552 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2553 }
2554
2555 }
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002556 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002557 bit_offset++;
2558 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
2559 pDescr++;
2560 break;
2561 }
2562
2563 case CSN_FIXED:
2564 { /* Verify the fixed bits */
2565 guint8 no_of_bits = (guint8) pDescr->i;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002566 bitvec_write_field(vector, writeIndex, pDescr->offset, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002567 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002568 remaining_bits_len -= no_of_bits;
2569 bit_offset += no_of_bits;
2570 pDescr++;
2571 break;
2572 }
2573
2574 case CSN_CALLBACK:
2575 {
2576 return ProcessError(writeIndex,"csnStreamEncoder Callback not implemented", -1, pDescr);
2577 break;
2578 }
2579
2580 case CSN_TRAP_ERROR:
2581 {
2582 return ProcessError(writeIndex,"csnStreamEncoder", pDescr->i, pDescr);
2583 }
2584
2585 case CSN_END:
2586 {
2587 ar->remaining_bits_len = remaining_bits_len;
2588 ar->bit_offset = bit_offset;
2589 return remaining_bits_len;
2590 }
2591
2592 default:
2593 {
2594 assert(0);
2595 }
2596
2597 }
2598
2599 } while (remaining_bits_len >= 0);
2600
2601 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2602}
2603