blob: 7f64823d42c47c4f3cd15dc5678b7f5beecb5fdb [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>
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +020035#define __STDC_FORMAT_MACROS
36#include <inttypes.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030037#include "csn1.h"
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +040038#include <gprs_debug.h>
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;
Ivan Kluchnikov1b517342013-12-30 14:26:06 +040092 ar->direction = 0;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030093}
94
95static const char* ErrCodes[] =
96{
97 "General 0",
98 "General -1",
99 "DATA_NOT VALID",
100 "IN SCRIPT",
101 "INVALID UNION INDEX",
102 "NEED_MORE BITS TO UNPACK",
103 "ILLEGAL BIT VALUE",
104 "Internal",
105 "STREAM_NOT_SUPPORTED",
106 "MESSAGE_TOO_LONG"
107};
108
109static gint16
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400110ProcessError( unsigned readIndex, const char* sz, gint16 err, const CSN_DESCR* pDescr)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300111{
112 gint16 i = MIN(-err, ((gint16) ElementsOf(ErrCodes)-1));
113 if (i >= 0)
114 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400115 //LOG(ERR) << sz << "Error code: "<< ErrCodes[i] << pDescr?(pDescr->sz):"-";
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300116 }
117 else
118 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400119 //LOG(ERR) << sz << ": " << pDescr?(pDescr->sz):"-";
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300120 }
121 return err;
122}
123
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300124
125/**
126 * ================================================================================================
127 * Return TRUE if tag in bit stream indicates existence of next list element,
128 * otherwise return FALSE.
129 * Will work for tag values equal to both 0 and 1.
130 * ================================================================================================
131 */
132
133static gboolean
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400134existNextElement(bitvec *vector, unsigned& readIndex, guint8 Tag)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300135{
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400136 guint8 res = bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300137 if (Tag == STANDARD_TAG)
138 {
139 return (res > 0);
140 }
141 return (res == 0);
142}
143
144
145gint16
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400146csnStreamDecoder(csnStream_t* ar, const CSN_DESCR* pDescr, bitvec *vector, unsigned& readIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300147{
148 gint remaining_bits_len = ar->remaining_bits_len;
149 gint bit_offset = ar->bit_offset;
150 guint8* pui8;
151 guint16* pui16;
152 guint32* pui32;
153 guint64* pui64;
154 guint8 Tag = STANDARD_TAG;
155
156 if (remaining_bits_len <= 0)
157 {
158 return 0;
159 }
160
161 do
162 {
163 switch (pDescr->type)
164 {
165 case CSN_BIT:
166 {
167 if (remaining_bits_len > 0)
168 {
169 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400170 *pui8 = bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400171 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300172 /* end add the bit value to protocol tree */
173 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400174 else if(pDescr->may_be_null)
175 {
176 pui8 = pui8DATA(data, pDescr->offset);
177 *pui8 = 0;
178 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
179 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300180 else
181 {
182 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
183 }
184
185 pDescr++;
186 remaining_bits_len--;
187 bit_offset++;
188 break;
189 }
190
191 case CSN_NULL:
192 { /* Empty member! */
193 pDescr++;
194 break;
195 }
196
197 case CSN_UINT:
198 {
199 guint8 no_of_bits = (guint8) pDescr->i;
200
201 if (remaining_bits_len >= no_of_bits)
202 {
203 if (no_of_bits <= 8)
204 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400205 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300206 pui8 = pui8DATA(data, pDescr->offset);
207 *pui8 = ui8;
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 }
210 else if (no_of_bits <= 16)
211 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400212 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300213 pui16 = pui16DATA(data, pDescr->offset);
214 *pui16 = ui16;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400215 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300216 }
217 else if (no_of_bits <= 32)
218 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400219 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300220 pui32 = pui32DATA(data, pDescr->offset);
221 *pui32 = ui32;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400222 LOGPC(DCSN1, LOGL_NOTICE, "%s = 0x%08x | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300223 }
224 else
225 {
226 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
227 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400228 remaining_bits_len -= no_of_bits;
229 bit_offset += no_of_bits;
230 }
231 else if(pDescr->may_be_null)
232 {
233 if (no_of_bits <= 8)
234 {
235 pui8 = pui8DATA(data, pDescr->offset);
236 *pui8 = 0;
237 }
238 else if (no_of_bits <= 16)
239 {
240 pui16 = pui16DATA(data, pDescr->offset);
241 *pui16 = 0;
242 }
243 else if (no_of_bits <= 32)
244 {
245 pui32 = pui32DATA(data, pDescr->offset);
246 *pui32 = 0;
247 }
248 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300249 }
250 else
251 {
252 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
253 }
254
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300255 pDescr++;
256 break;
257 }
258
259 case CSN_UINT_OFFSET:
260 {
261 guint8 no_of_bits = (guint8) pDescr->i;
262
263 if (remaining_bits_len >= no_of_bits)
264 {
265 if (no_of_bits <= 8)
266 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400267 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300268 pui8 = pui8DATA(data, pDescr->offset);
269 *pui8 = ui8 + (guint8)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400270 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300271 }
272 else if (no_of_bits <= 16)
273 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400274 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300275 pui16 = pui16DATA(data, pDescr->offset);
276 *pui16 = ui16 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400277 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300278 }
279 else if (no_of_bits <= 32)
280 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400281 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300282 pui32 = pui32DATA(data, pDescr->offset);
283 *pui32 = ui32 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400284 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300285 }
286 else
287 {
288 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
289 }
290 }
291 else
292 {
293 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
294 }
295
296 remaining_bits_len -= no_of_bits;
297 bit_offset += no_of_bits;
298 pDescr++;
299 break;
300 }
301
302 case CSN_UINT_LH:
303 {
304 guint8 no_of_bits = (guint8) pDescr->i;
305
306 if (remaining_bits_len >= no_of_bits)
307 {
308 remaining_bits_len -= no_of_bits;
309 if (no_of_bits <= 8)
310 {
311 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
312 pui8 = pui8DATA(data, pDescr->offset);
313 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400314 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300315 }
316 else
317 {/* Maybe we should support more than 8 bits ? */
318 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
319 }
320 }
321 else
322 {
323 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
324 }
325
326 remaining_bits_len -= no_of_bits;
327 bit_offset += no_of_bits;
328 pDescr++;
329 break;
330 }
331
332 case CSN_UINT_ARRAY:
333 {
334 guint8 no_of_bits = (guint8) pDescr->i;
335 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
336
337 if (pDescr->serialize.value != 0)
338 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
339 nCount = *pui16DATA(data, nCount);
340 }
341
342 if (remaining_bits_len >= no_of_bits)
343 {
344 remaining_bits_len -= (no_of_bits*nCount);
345 if (no_of_bits <= 8)
346 {
347 pui8 = pui8DATA(data, pDescr->offset);
348 do
349 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400350 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400351 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300352 pui8++;
353 bit_offset += no_of_bits;
354 } while (--nCount > 0);
355 }
356 else if (no_of_bits <= 16)
357 {
358 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
359 }
360 else if (no_of_bits <= 32)
361 {
362 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
363 }
364 else
365 {
366 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
367 }
368 }
369 else
370 {
371 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
372 }
373 pDescr++;
374 break;
375 }
376
377 case CSN_VARIABLE_TARRAY_OFFSET:
378 case CSN_VARIABLE_TARRAY:
379 case CSN_TYPE_ARRAY:
380 {
381 gint16 Status;
382 csnStream_t arT = *ar;
383 gint16 nCount = pDescr->i;
384 guint16 nSize = (guint16)(gint32)pDescr->serialize.value;
385
386 pui8 = pui8DATA(data, pDescr->offset);
387 if (pDescr->type == CSN_VARIABLE_TARRAY)
388 { /* Count specified in field */
389 nCount = *pui8DATA(data, pDescr->i);
390 }
391 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
392 { /* Count specified in field */
393 nCount = *pui8DATA(data, pDescr->i);
394 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
395 }
396
397 while (nCount > 0)
398 { /* resulting array of length 0 is possible
399 * but no bits shall be read from bitstream
400 */
401
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400402 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300403 csnStreamInit(&arT, bit_offset, remaining_bits_len);
404 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
405 if (Status >= 0)
406 {
407 pui8 += nSize;
408 remaining_bits_len = arT.remaining_bits_len;
409 bit_offset = arT.bit_offset;
410 }
411 else
412 {
413 return Status;
414 }
415 nCount--;
416 }
417
418 pDescr++;
419 break;
420 }
421
422 case CSN_BITMAP:
423 { /* bitmap with given length. The result is left aligned! */
424 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
425
426 if (no_of_bits > 0)
427 {
428
429 if (no_of_bits <= 32)
430 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400431 for(unsigned ib = 0; ib < 4; ib++)
432 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400433 guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400434 pui8 = pui8DATA(data, pDescr->offset+ib);
435 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400436 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400437 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300438 }
439 else if (no_of_bits <= 64)
440 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400441 for(unsigned ib = 0; ib < 8; 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
450 {
451 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
452 }
453
454 remaining_bits_len -= no_of_bits;
455 assert(remaining_bits_len >= 0);
456 bit_offset += no_of_bits;
457 }
458 /* bitmap was successfully extracted or it was empty */
459
460 pDescr++;
461 break;
462 }
463
464 case CSN_TYPE:
465 {
466 gint16 Status;
467 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400468 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300469 csnStreamInit(&arT, bit_offset, remaining_bits_len);
470 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400471 LOGPC(DCSN1, LOGL_NOTICE, ": End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300472 if (Status >= 0)
473 {
474 remaining_bits_len = arT.remaining_bits_len;
475 bit_offset = arT.bit_offset;
476 pDescr++;
477 }
478 else
479 {
480 /* Has already been processed: ProcessError("csnStreamDecoder", Status, pDescr); */
481 return Status;
482 }
483
484 break;
485 }
486
487 case CSN_CHOICE:
488 {
489 gint16 count = pDescr->i;
490 guint8 i = 0;
491 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
492
493 while (count > 0)
494 {
495 guint8 no_of_bits = pChoice->bits;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400496 guint8 value = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300497 if (value == pChoice->value)
498 {
499 CSN_DESCR descr[2];
500 gint16 Status;
501 csnStream_t arT = *ar;
502
503 descr[0] = pChoice->descr;
504 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
505 descr[1].type = CSN_END;
506 pui8 = pui8DATA(data, pDescr->offset);
507 *pui8 = i;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400508 LOGPC(DCSN1, LOGL_NOTICE, "Choice %s = %u | ", pDescr->sz , (unsigned)value);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300509 bit_offset += no_of_bits;
510 remaining_bits_len -= no_of_bits;
511
512 csnStreamInit(&arT, bit_offset, remaining_bits_len);
513 Status = csnStreamDecoder(&arT, descr, vector, readIndex, data);
514
515 if (Status >= 0)
516 {
517 remaining_bits_len = arT.remaining_bits_len;
518 bit_offset = arT.bit_offset;
519 }
520 else
521 {
522 return Status;
523 }
524 break;
525 }
526
527 readIndex -= no_of_bits;
528 count--;
529 pChoice++;
530 i++;
531 }
532
533 pDescr++;
534 break;
535 }
536
537 case CSN_SERIALIZE:
538 {
539 StreamSerializeFcn_t serialize = pDescr->serialize.fcn;
540 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400541 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300542 gint16 Status = -1;
543
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400544 guint8 length = bitvec_read_field(vector, readIndex, length_len);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300545
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400546 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %d | ", pDescr->sz , (int)length);
547 arT.direction = 1;
548 bit_offset += length_len;
549 remaining_bits_len -= length_len;
550
551 csnStreamInit(&arT, bit_offset, length);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300552 Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset));
553
554 if (Status >= 0)
555 {
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400556 remaining_bits_len -= length;
557 bit_offset += length;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300558 pDescr++;
559 }
560 else
561 {
562 /* Has already been processed: */
563 return Status;
564 }
565
566 break;
567 }
568
569 case CSN_UNION_LH:
570 case CSN_UNION:
571 {
572 gint16 Bits;
573 guint8 index;
574 gint16 count = pDescr->i;
575 const CSN_DESCR* pDescrNext = pDescr;
576
577 pDescrNext += count + 1; /* now this is next after the union */
578 if ((count <= 0) || (count > 16))
579 {
580 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
581 }
582
583 /* Now get the bits to extract the index */
584 Bits = ixBitsTab[count];
585 index = 0;
586
587 while (Bits > 0)
588 {
589 index <<= 1;
590
591 if (CSN_UNION_LH == pDescr->type)
592 {
593 index |= get_masked_bits8(vector,readIndex, bit_offset, 1);
594 }
595 else
596 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400597 index |= bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300598 }
599 remaining_bits_len--;
600 bit_offset++;
601 Bits--;
602 }
603
604 /* Assign UnionType */
605 pui8 = pui8DATA(data, pDescr->offset);
606 *pui8 = index;
607
608
609 /* script index to continue on, limited in case we do not have a power of 2 */
610 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400611 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300612
613 switch (pDescr->type)
614 { /* get the right element of the union based on computed index */
615
616 case CSN_BIT:
617 {
618 pui8 = pui8DATA(data, pDescr->offset);
619 *pui8 = 0x00;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400620 if (bitvec_read_field(vector, readIndex, 1) > 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300621 {
622 *pui8 = 0x01;
623 }
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400624 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300625 remaining_bits_len -= 1;
626 bit_offset++;
627 pDescr++;
628 break;
629 }
630
631 case CSN_NULL:
632 { /* Empty member! */
633 pDescr++;
634 break;
635 }
636
637 case CSN_UINT:
638 {
639 guint8 no_of_bits = (guint8) pDescr->i;
640 if (remaining_bits_len >= no_of_bits)
641 {
642 remaining_bits_len -= no_of_bits;
643
644 if (no_of_bits <= 8)
645 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400646 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300647 pui8 = pui8DATA(data, pDescr->offset);
648 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400649 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300650 }
651 else if (no_of_bits <= 16)
652 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400653 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300654 pui16 = pui16DATA(data, pDescr->offset);
655 *pui16 = ui16;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400656 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300657 }
658 else if (no_of_bits <= 32)
659 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400660 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300661 pui32 = pui32DATA(data, pDescr->offset);
662 *pui32 = ui32;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400663 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300664 }
665 else
666 {
667 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
668 }
669 }
670 else
671 {
672 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
673 }
674
675 bit_offset += no_of_bits;
676 pDescr++;
677 break;
678 }
679
680 case CSN_UINT_OFFSET:
681 {
682 guint8 no_of_bits = (guint8) pDescr->i;
683
684 if (remaining_bits_len >= no_of_bits)
685 {
686 if (no_of_bits <= 8)
687 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400688 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300689 pui8 = pui8DATA(data, pDescr->offset);
690 *pui8 = ui8 + (guint8)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400691 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300692 }
693 else if (no_of_bits <= 16)
694 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400695 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300696 pui16 = pui16DATA(data, pDescr->offset);
697 *pui16 = ui16 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400698 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300699 }
700 else if (no_of_bits <= 32)
701 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400702 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300703 pui32 = pui32DATA(data, pDescr->offset);
704 *pui32 = ui32 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400705 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300706 }
707 else
708 {
709 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
710 }
711 }
712 else
713 {
714 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
715 }
716
717 bit_offset += no_of_bits;
718 pDescr++;
719 break;
720 }
721
722 case CSN_UINT_LH:
723 {
724 guint8 no_of_bits = (guint8) pDescr->i;
725
726 if (remaining_bits_len >= no_of_bits)
727 {
728 if (no_of_bits <= 8)
729 {
730 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
731 pui8 = pui8DATA(data, pDescr->offset);
732 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400733 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300734 }
735 else
736 { /* Maybe we should support more than 8 bits ? */
737 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
738 }
739 }
740 else
741 {
742 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
743 }
744
745 bit_offset += no_of_bits;
746 pDescr++;
747 break;
748 }
749
750 case CSN_UINT_ARRAY:
751 {
752 guint8 no_of_bits = (guint8) pDescr->i;
753 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
754
755 if (pDescr->serialize.value != 0)
756 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
757 nCount = *pui16DATA(data, nCount);
758 }
759
760 if (remaining_bits_len >= no_of_bits)
761 {
762 remaining_bits_len -= (no_of_bits * nCount);
763 if (no_of_bits <= 8)
764 {
765 pui8 = pui8DATA(data, pDescr->offset);
766
767 while (nCount > 0)
768 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400769 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400770 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300771 pui8++;
772 bit_offset += no_of_bits;
773 nCount--;
774 }
775 }
776 else if (no_of_bits <= 16)
777 {
778 pui16 = pui16DATA(data, pDescr->offset);
779
780 while (nCount > 0)
781 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400782 *pui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400783 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300784 pui16++;
785 bit_offset += no_of_bits;
786 nCount--;
787 }
788 }
789 else if (no_of_bits <= 32)
790 { /* not supported */
791 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
792 }
793 else
794 {
795 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
796 }
797 }
798 else
799 {
800 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
801 }
802
803 pDescr++;
804 break;
805 }
806
807 case CSN_VARIABLE_TARRAY_OFFSET:
808 case CSN_VARIABLE_TARRAY:
809 case CSN_TYPE_ARRAY:
810 {
811 gint16 Status;
812 csnStream_t arT = *ar;
813 guint16 nCount = (guint16) pDescr->i;
814 guint16 nSize = (guint16)(guint32)pDescr->serialize.value;
815
816 pui8 = pui8DATA(data, pDescr->offset);
817
818 if (CSN_VARIABLE_TARRAY == pDescr->type)
819 { /* Count specified in field */
820 nCount = *pui8DATA(data, pDescr->i);
821 }
822 else if (CSN_VARIABLE_TARRAY_OFFSET == pDescr->type)
823 { /* Count specified in field */
824 nCount = *pui8DATA(data, pDescr->i);
825 nCount--; /* Offset 1 */
826 }
827
828 while (nCount--) /* Changed to handle length = 0. */
829 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400830 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300831 csnStreamInit(&arT, bit_offset, remaining_bits_len);
832 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
833 if (Status >= 0)
834 {
835 pui8 += nSize;
836 remaining_bits_len = arT.remaining_bits_len;
837 bit_offset = arT.bit_offset;
838 }
839 else
840 {
841 return Status;
842 }
843 }
844
845 pDescr++;
846 break;
847 }
848
849 case CSN_BITMAP:
850 { /* bitmap with given length. The result is left aligned! */
851 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
852
853 if (no_of_bits > 0)
854 {
855
856 if (no_of_bits <= 32)
857 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400858 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300859 pui32 = pui32DATA(data, pDescr->offset);
860 *pui32 = ui32;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300861 }
862 else if (no_of_bits <= 64)
863 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400864 guint64 ui64 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300865 pui64 = pui64DATA(data, pDescr->offset);
866 *pui64 = ui64;
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +0200867 LOGPC(DCSN1, LOGL_NOTICE, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300868 }
869 else
870 {
871 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
872 }
873
874 remaining_bits_len -= no_of_bits;
875 assert(remaining_bits_len >= 0);
876 bit_offset += no_of_bits;
877 }
878 /* bitmap was successfully extracted or it was empty */
879
880 pDescr++;
881 break;
882 }
883
884 case CSN_TYPE:
885 {
886 gint16 Status;
887 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400888 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300889 csnStreamInit(&arT, bit_offset, remaining_bits_len);
890 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400891 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300892 if (Status >= 0)
893 {
894 remaining_bits_len = arT.remaining_bits_len;
895 bit_offset = arT.bit_offset;
896 pDescr++;
897 }
898 else
899 { /* return error code Has already been processed: */
900 return Status;
901 }
902
903 break;
904 }
905
906 default:
907 { /* descriptions of union elements other than above are illegal */
908 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
909 }
910 }
911
912 pDescr = pDescrNext;
913 break;
914 }
915
916 case CSN_EXIST:
917 case CSN_EXIST_LH:
918 {
919 guint8 fExist;
920
921 pui8 = pui8DATA(data, pDescr->offset);
922
923 if (CSN_EXIST_LH == pDescr->type)
924 {
925 fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
926 }
927 else
928 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400929 fExist = bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300930 }
931
932 *pui8 = fExist;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400933 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300934 pDescr++;
935 remaining_bits_len -= 1;
936
937 if (!fExist)
938 {
939 ar->remaining_bits_len = remaining_bits_len;
940 ar->bit_offset = bit_offset;
941 return remaining_bits_len;
942 }
943
944 break;
945 }
946
947 case CSN_NEXT_EXIST:
948 {
949 guint8 fExist;
950
951 pui8 = pui8DATA(data, pDescr->offset);
952
953 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400954 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300955 { /* no more bits to decode is fine here - end of message detected and allowed */
956
957 /* Skip i entries + this entry */
958 pDescr += pDescr->i + 1;
959
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300960 /* Set the data member to "not exist" */
961 *pui8 = 0;
962 break;
963 }
964
965 /* the "regular" M_NEXT_EXIST description element */
966
967 fExist = 0x00;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400968 if (bitvec_read_field(vector, readIndex, 1))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300969 {
970 fExist = 0x01;
971 }
972
973 *pui8 = fExist;
974 remaining_bits_len -= 1;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400975 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300976 ++bit_offset;
977
978 if (fExist == 0)
979 { /* Skip 'i' entries */
980 pDescr += pDescr->i;
981 }
982
983 pDescr++;
984 break;
985 }
986
987 case CSN_NEXT_EXIST_LH:
988 {
989 guint8 fExist;
990 pui8 = pui8DATA(data, pDescr->offset);
991
992 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
993 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
994 { /* no more bits to decode is fine here - end of message detected and allowed */
995
996 /* skip 'i' entries + this entry */
997 pDescr += pDescr->i + 1;
998
999 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
1000 if ( pDescr->type != CSN_END )
1001 { /* substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
1002 remaining_bits_len--;
1003 }
1004
1005 /* set the data member to "not exist" */
1006 *pui8 = 0;
1007 break;
1008 }
1009
1010 /* the "regular" M_NEXT_EXIST_LH description element */
1011 fExist = get_masked_bits8(vector,readIndex,bit_offset, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001012 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)fExist);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001013 *pui8++ = fExist;
1014 remaining_bits_len -= 1;
1015
1016 bit_offset++;
1017
1018 if (fExist == 0)
1019 { /* Skip 'i' entries */
1020 pDescr += pDescr->i;
1021 }
1022 pDescr++;
1023
1024 break;
1025 }
1026
1027 case CSN_VARIABLE_BITMAP_1:
1028 { /* Bitmap from here and to the end of message */
1029
1030 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1031
1032 /*no break -
1033 * with a length set we have a regular variable length bitmap so we continue */
1034 }
1035
1036 case CSN_VARIABLE_BITMAP:
1037 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1038 * <N: bit (5)> <bitmap: bit(N + offset)>
1039 * Bit array with length (in bits) specified in parameter (pDescr->descr)
1040 * The result is right aligned!
1041 */
1042 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
1043
1044 no_of_bits += pDescr->i; /* adjusted by offset */
1045
1046 if (no_of_bits > 0)
1047 {
1048 remaining_bits_len -= no_of_bits;
1049
1050 if (remaining_bits_len < 0)
1051 {
1052 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1053 }
1054
1055 { /* extract bits */
1056 guint8* pui8 = pui8DATA(data, pDescr->offset);
1057 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1058
1059 if (nB1 > 0)
1060 { /* take care of the first byte - it will be right aligned */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001061 *pui8 = bitvec_read_field(vector, readIndex, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001062 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001063 pui8++;
1064 no_of_bits -= nB1;
1065 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1066 }
1067
1068 /* remaining no_of_bits is a multiple of 8 or 0 */
1069 while (no_of_bits > 0)
1070 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001071 *pui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001072 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001073 pui8++;
1074 no_of_bits -= 8;
1075 }
1076 }
1077 }
1078 pDescr++;
1079 break;
1080 }
1081
1082 case CSN_LEFT_ALIGNED_VAR_BMP_1:
1083 { /* Bitmap from here and to the end of message */
1084
1085 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1086
1087 /* no break -
1088 * with a length set we have a regular left aligned variable length bitmap so we continue
1089 */
1090 }
1091
1092 case CSN_LEFT_ALIGNED_VAR_BMP:
1093 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1094 * <N: bit (5)> <bitmap: bit(N + offset)>
1095 * bit array with length (in bits) specified in parameter (pDescr->descr)
1096 */
1097 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
1098
1099 no_of_bits += pDescr->i;/* size adjusted by offset */
1100
1101 if (no_of_bits > 0)
1102 {
1103 remaining_bits_len -= no_of_bits;
1104
1105 if (remaining_bits_len < 0)
1106 {
1107 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1108 }
1109
1110 { /* extract bits */
1111 guint8* pui8 = pui8DATA(data, pDescr->offset);
1112 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1113
1114 while (no_of_bits > 0)
1115 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001116 *pui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001117 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001118 pui8++;
1119 no_of_bits -= 8;
1120 }
1121 if (nB1 > 0)
1122 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001123 *pui8 = bitvec_read_field(vector, readIndex, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001124 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001125 pui8++;
1126 no_of_bits -= nB1;
1127 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1128 }
1129 }
1130 }
1131
1132 /* bitmap was successfully extracted or it was empty */
1133 pDescr++;
1134 break;
1135 }
1136
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001137 case CSN_PADDING_BITS:
1138 { /* Padding from here and to the end of message */
1139 LOGPC(DCSN1, LOGL_NOTICE, "%s = ", pDescr->sz);
1140 if (remaining_bits_len > 0)
1141 {
1142 while (remaining_bits_len > 0)
1143 {
1144 guint8 bits_to_handle = remaining_bits_len%8;
1145 if (bits_to_handle > 0)
1146 {
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +02001147 LOGPC(DCSN1, LOGL_NOTICE, "%"PRIu64"|", bitvec_read_field(vector, readIndex, bits_to_handle));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001148 remaining_bits_len -= bits_to_handle;
1149 bit_offset += bits_to_handle;
1150 }
1151 else if (bits_to_handle == 0)
1152 {
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +02001153 LOGPC(DCSN1, LOGL_NOTICE, "%"PRIu64"|", bitvec_read_field(vector, readIndex, 8));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001154 remaining_bits_len -= 8;
1155 bit_offset += 8;
1156 }
1157 }
1158 }
1159 if (remaining_bits_len < 0)
1160 {
1161 return ProcessError(readIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1162 }
1163
1164 /* Padding was successfully extracted or it was empty */
1165 pDescr++;
1166 break;
1167 }
1168
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001169 case CSN_VARIABLE_ARRAY:
1170 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
1171 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1172 * Array with length specified in parameter:
1173 * <count: bit (x)>
1174 * <list: octet(count + offset)>
1175 */
1176 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
1177
1178 count += pDescr->i; /* Adjusted by offset */
1179
1180 if (count > 0)
1181 {
1182 remaining_bits_len -= count * 8;
1183
1184 if (remaining_bits_len < 0)
1185 {
1186 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1187 }
1188
1189 pui8 = pui8DATA(data, pDescr->offset);
1190
1191 while (count > 0)
1192 {
1193 readIndex -= 8;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001194 *pui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001195 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001196 pui8++;
1197 bit_offset += 8;
1198 count--;
1199 }
1200 }
1201
1202 pDescr++;
1203 break;
1204 }
1205
1206 case CSN_RECURSIVE_ARRAY:
1207 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
1208 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
1209 * where <element> ::= bit(value)
1210 * <tag> ::= 0 | 1
1211 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
1212 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1213 * REMARK: recursive way to specify an array but an iterative implementation!
1214 */
1215 gint16 no_of_bits = pDescr->i;
1216 guint8 ElementCount = 0;
1217
1218 pui8 = pui8DATA(data, pDescr->offset);
1219
1220 while (existNextElement(vector, readIndex, Tag))
1221 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001222 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001223 bit_offset++;
1224 remaining_bits_len--;
1225
1226 /* extract and store no_of_bits long element from bitstream */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001227 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001228 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001229 pui8++;
1230 remaining_bits_len -= no_of_bits;
1231 ElementCount++;
1232
1233 if (remaining_bits_len < 0)
1234 {
1235 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1236 }
1237
1238 bit_offset += no_of_bits;
1239 }
1240
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001241 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)bitvec_read_field(vector, readIndex, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001242 /* existNextElement() returned FALSE, 1 bit consumed */
1243 bit_offset++;
1244
1245 /* Store the counted number of elements of the array */
1246 *pui8DATA(data, (gint16)pDescr->descr.value) = ElementCount;
1247
1248 pDescr++;
1249 break;
1250 }
1251
1252 case CSN_RECURSIVE_TARRAY:
1253 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
1254 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1255 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1256 */
1257 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
1258 guint8 ElementCount = 0;
1259 pui8 = pui8DATA(data, pDescr->offset);
1260
1261 while (existNextElement(vector, readIndex, Tag))
1262 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001263 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001264 /* existNextElement() returned TRUE, 1 bit consumed */
1265 bit_offset++;
1266 remaining_bits_len--;
1267 ElementCount++;
1268
1269 { /* unpack the following data structure */
1270 csnStream_t arT = *ar;
1271 gint16 Status;
1272 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04001273 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001274
1275 if (Status >= 0)
1276 { /* successful completion */
1277 pui8 += nSizeElement; /* -> to next data element */
1278 remaining_bits_len = arT.remaining_bits_len;
1279 bit_offset = arT.bit_offset;
1280 }
1281 else
1282 { /* something went awry */
1283 return Status;
1284 }
1285 }
1286
1287 if (remaining_bits_len < 0)
1288 {
1289 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1290 }
1291 }
1292
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001293 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)bitvec_read_field(vector, readIndex, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001294
1295 /* existNextElement() returned FALSE, 1 bit consumed */
1296 bit_offset++;
1297
1298 /* Store the counted number of elements of the array */
1299 *pui8DATA(data, (gint16)(gint32)pDescr->i) = ElementCount;
1300
1301 pDescr++;
1302 break;
1303 }
1304
1305 case CSN_RECURSIVE_TARRAY_2:
1306 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
1307
1308 Tag = REVERSED_TAG;
1309
1310 /* NO break -
1311 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
1312 */
1313 }
1314
1315 case CSN_RECURSIVE_TARRAY_1:
1316 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
1317 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1318 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1319 */
1320 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
1321 guint8 ElementCount = 0;
1322 csnStream_t arT = *ar;
1323 gboolean EndOfList = FALSE;
1324 gint16 Status;
1325 pui8 = pui8DATA(data, pDescr->offset);
1326
1327 do
1328 { /* get data element */
1329 ElementCount++;
1330
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001331 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
1332
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001333 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04001334 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001335
1336 if (Status >= 0)
1337 { /* successful completion */
1338 pui8 += nSizeElement; /* -> to next */
1339 remaining_bits_len = arT.remaining_bits_len;
1340 bit_offset = arT.bit_offset;
1341 }
1342 else
1343 { /* something went awry */
1344 return Status;
1345 }
1346
1347 if (remaining_bits_len < 0)
1348 {
1349 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1350 }
1351
1352 /* control of next element's tag */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001353 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001354 EndOfList = !(existNextElement(vector, readIndex, Tag));
1355
1356 bit_offset++;
1357 remaining_bits_len--; /* 1 bit consumed (tag) */
1358 } while (!EndOfList);
1359
1360
1361 /* Store the count of the array */
1362 *pui8DATA(data, pDescr->i) = ElementCount;
1363 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
1364 pDescr++;
1365 break;
1366 }
1367
1368 case CSN_FIXED:
1369 { /* Verify the fixed bits */
1370 guint8 no_of_bits = (guint8) pDescr->i;
1371 guint32 ui32;
1372
1373 if (no_of_bits <= 32)
1374 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001375 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001376 }
1377 else
1378 {
1379 return ProcessError(readIndex,"no_of_bits > 32", -1, pDescr);
1380 }
1381 if (ui32 != (unsigned)(gint32)pDescr->offset)
1382 {
1383 return ProcessError(readIndex,"csnStreamDecoder FIXED value does not match", -1, pDescr);
1384 }
1385
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001386 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)ui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001387 remaining_bits_len -= no_of_bits;
1388 bit_offset += no_of_bits;
1389 pDescr++;
1390 break;
1391 }
1392
1393 case CSN_CALLBACK:
1394 {
1395 return ProcessError(readIndex,"csnStreamDecoder Callback not implemented", -1, pDescr);
1396 break;
1397 }
1398
1399 case CSN_TRAP_ERROR:
1400 {
1401 return ProcessError(readIndex,"csnStreamDecoder", pDescr->i, pDescr);
1402 }
1403
1404 case CSN_END:
1405 {
1406 ar->remaining_bits_len = remaining_bits_len;
1407 ar->bit_offset = bit_offset;
1408 return remaining_bits_len;
1409 }
1410
1411 default:
1412 {
1413 assert(0);
1414 }
1415
1416
1417 }
1418
1419 } while (remaining_bits_len >= 0);
1420
1421 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1422}
1423
1424
1425
1426
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001427gint16 csnStreamEncoder(csnStream_t* ar, const CSN_DESCR* pDescr, bitvec *vector, unsigned& writeIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001428{
1429 gint remaining_bits_len = ar->remaining_bits_len;
1430 gint bit_offset = ar->bit_offset;
1431 guint8* pui8;
1432 guint16* pui16;
1433 guint32* pui32;
1434 guint64* pui64;
1435
1436 guint8 Tag = STANDARD_TAG;
1437
1438 if (remaining_bits_len <= 0)
1439 {
1440 return 0;
1441 }
1442
1443 do
1444 {
1445 switch (pDescr->type)
1446 {
1447 case CSN_BIT:
1448 {
1449 if (remaining_bits_len > 0)
1450 {
1451 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001452 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001453 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001454 /* end add the bit value to protocol tree */
1455 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001456 else if(pDescr->may_be_null)
1457 {
1458 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
1459 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001460 else
1461 {
1462 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1463 }
1464
1465 pDescr++;
1466 remaining_bits_len--;
1467 bit_offset++;
1468 break;
1469 }
1470
1471 case CSN_NULL:
1472 { /* Empty member! */
1473 pDescr++;
1474 break;
1475 }
1476
1477 case CSN_UINT:
1478 {
1479 guint8 no_of_bits = (guint8) pDescr->i;
1480
1481 if (remaining_bits_len >= no_of_bits)
1482 {
1483 if (no_of_bits <= 8)
1484 {
1485 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001486 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001487 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001488 }
1489 else if (no_of_bits <= 16)
1490 {
1491 pui16 = pui16DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001492 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001493 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001494 }
1495 else if (no_of_bits <= 32)
1496 {
1497 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001498 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001499 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001500 }
1501 else
1502 {
1503 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1504 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001505
1506 remaining_bits_len -= no_of_bits;
1507 bit_offset += no_of_bits;
1508 }
1509 else if(pDescr->may_be_null)
1510 {
1511 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001512 }
1513 else
1514 {
1515 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1516 }
1517
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001518 pDescr++;
1519 break;
1520 }
1521
1522 case CSN_UINT_OFFSET:
1523 {
1524 guint8 no_of_bits = (guint8) pDescr->i;
1525
1526 if (remaining_bits_len >= no_of_bits)
1527 {
1528 if (no_of_bits <= 8)
1529 {
1530 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001531 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001532 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001533 }
1534 else if (no_of_bits <= 16)
1535 {
1536 pui16 = pui16DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001537 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001538 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001539 }
1540 else if (no_of_bits <= 32)
1541 {
1542 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001543 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001544 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001545 }
1546 else
1547 {
1548 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1549 }
1550 }
1551 else
1552 {
1553 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1554 }
1555
1556 remaining_bits_len -= no_of_bits;
1557 bit_offset += no_of_bits;
1558 pDescr++;
1559 break;
1560 }
1561
1562 case CSN_UINT_LH:
1563 {
1564 guint8 no_of_bits = (guint8) pDescr->i;
1565
1566 if (remaining_bits_len >= no_of_bits)
1567 {
1568 remaining_bits_len -= no_of_bits;
1569 if (no_of_bits <= 8)
1570 {
1571 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001572 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001573 // TODO : Change get_masked_bits8()
1574 writeIndex -= no_of_bits;
1575 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
1576 writeIndex -= no_of_bits;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001577 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001578 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001579
1580 }
1581 else
1582 {/* Maybe we should support more than 8 bits ? */
1583 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1584 }
1585 }
1586 else
1587 {
1588 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1589 }
1590
1591 remaining_bits_len -= no_of_bits;
1592 bit_offset += no_of_bits;
1593 pDescr++;
1594 break;
1595 }
1596
1597 case CSN_UINT_ARRAY:
1598 {
1599 guint8 no_of_bits = (guint8) pDescr->i;
1600 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
1601
1602 if (pDescr->serialize.value != 0)
1603 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
1604 nCount = *pui16DATA(data, nCount);
1605 }
1606
1607 if (remaining_bits_len >= no_of_bits)
1608 {
1609 remaining_bits_len -= (no_of_bits*nCount);
1610 if (no_of_bits <= 8)
1611 {
1612 pui8 = pui8DATA(data, pDescr->offset);
1613 do
1614 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001615 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
1616 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001617 pui8++;
1618 bit_offset += no_of_bits;
1619 } while (--nCount > 0);
1620 }
1621 else if (no_of_bits <= 16)
1622 {
1623 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1624 }
1625 else if (no_of_bits <= 32)
1626 {
1627 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1628 }
1629 else
1630 {
1631 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1632 }
1633 }
1634 else
1635 {
1636 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1637 }
1638 pDescr++;
1639 break;
1640 }
1641
1642 case CSN_VARIABLE_TARRAY_OFFSET:
1643 case CSN_VARIABLE_TARRAY:
1644 case CSN_TYPE_ARRAY:
1645 {
1646 gint16 Status;
1647 csnStream_t arT = *ar;
1648 gint16 nCount = pDescr->i;
1649 guint16 nSize = (guint16)(gint32)pDescr->serialize.value;
1650
1651 pui8 = pui8DATA(data, pDescr->offset);
1652 if (pDescr->type == CSN_VARIABLE_TARRAY)
1653 { /* Count specified in field */
1654 nCount = *pui8DATA(data, pDescr->i);
1655 }
1656 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
1657 { /* Count specified in field */
1658 nCount = *pui8DATA(data, pDescr->i);
1659 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
1660 }
1661
1662 while (nCount > 0)
1663 { /* resulting array of length 0 is possible
1664 * but no bits shall be read from bitstream
1665 */
1666
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001667 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001668 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1669 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
1670 if (Status >= 0)
1671 {
1672 pui8 += nSize;
1673 remaining_bits_len = arT.remaining_bits_len;
1674 bit_offset = arT.bit_offset;
1675
1676 }
1677 else
1678 {
1679 return Status;
1680 }
1681 nCount--;
1682 }
1683
1684 pDescr++;
1685 break;
1686 }
1687
1688 case CSN_BITMAP:
1689 { /* bitmap with given length. The result is left aligned! */
1690 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
1691
1692 if (no_of_bits > 0)
1693 {
1694
1695 if (no_of_bits <= 32)
1696 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001697 for(unsigned ib = 0; ib < 4; ib++)
1698 {
1699 pui8 = pui8DATA(data, pDescr->offset+ib);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001700 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001701 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001702 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001703 }
1704 else if (no_of_bits <= 64)
1705 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001706 for(unsigned ib = 0; ib < 8; ib++)
1707 {
1708 pui8 = pui8DATA(data, pDescr->offset+ib);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001709 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001710 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001711 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001712 }
1713 else
1714 {
1715 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
1716 }
1717
1718 remaining_bits_len -= no_of_bits;
1719 assert(remaining_bits_len >= 0);
1720 bit_offset += no_of_bits;
1721 }
1722 /* bitmap was successfully extracted or it was empty */
1723
1724 pDescr++;
1725 break;
1726 }
1727
1728 case CSN_TYPE:
1729 {
1730 gint16 Status;
1731 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001732 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001733 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1734 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001735 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001736 if (Status >= 0)
1737 {
1738
1739 remaining_bits_len = arT.remaining_bits_len;
1740 bit_offset = arT.bit_offset;
1741 pDescr++;
1742 }
1743 else
1744 {
1745 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
1746 return Status;
1747 }
1748
1749 break;
1750 }
1751
1752 case CSN_CHOICE:
1753 {
1754 //gint16 count = pDescr->i;
1755 guint8 i = 0;
1756 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
1757
1758 pui8 = pui8DATA(data, pDescr->offset);
1759 i = *pui8;
1760 pChoice += i;
1761 guint8 no_of_bits = pChoice->bits;
1762 guint8 value = pChoice->value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001763 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pChoice->descr.sz , (unsigned)value);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001764 bitvec_write_field(vector, writeIndex, value, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001765
1766 CSN_DESCR descr[2];
1767 gint16 Status;
1768 csnStream_t arT = *ar;
1769
1770 descr[0] = pChoice->descr;
1771 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
1772 descr[1].type = CSN_END;
1773 bit_offset += no_of_bits;
1774 remaining_bits_len -= no_of_bits;
1775
1776 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1777 Status = csnStreamEncoder(&arT, descr, vector, writeIndex, data);
1778
1779 if (Status >= 0)
1780 {
1781 remaining_bits_len = arT.remaining_bits_len;
1782 bit_offset = arT.bit_offset;
1783 }
1784 else
1785 {
1786 return Status;
1787 }
1788
1789 pDescr++;
1790 break;
1791 }
1792
1793 case CSN_SERIALIZE:
1794 {
1795 StreamSerializeFcn_t serialize = pDescr->serialize.fcn;
1796 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001797 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001798 gint16 Status = -1;
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001799 unsigned lengthIndex;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001800
1801 // store writeIndex for length value (7 bit)
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001802 lengthIndex = writeIndex;
1803 writeIndex += length_len;
1804 bit_offset += length_len;
1805 remaining_bits_len -= length_len;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001806 arT.direction = 0;
1807 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1808 Status = serialize(&arT, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001809
1810 bitvec_write_field(vector, lengthIndex, writeIndex-lengthIndex-length_len, length_len);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001811 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %u | ", pDescr->sz , (unsigned)(writeIndex-lengthIndex));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001812
1813 if (Status >= 0)
1814 {
1815 remaining_bits_len = arT.remaining_bits_len;
1816 bit_offset = arT.bit_offset;
1817 pDescr++;
1818 }
1819 else
1820 {
1821 // Has already been processed:
1822 return Status;
1823 }
1824
1825 break;
1826 }
1827
1828 case CSN_UNION_LH:
1829 case CSN_UNION:
1830 {
1831 gint16 Bits;
1832 guint8 index;
1833 gint16 count = pDescr->i;
1834 const CSN_DESCR* pDescrNext = pDescr;
1835
1836 pDescrNext += count + 1; /* now this is next after the union */
1837 if ((count <= 0) || (count > 16))
1838 {
1839 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
1840 }
1841
1842 /* Now get the bits to extract the index */
1843 Bits = ixBitsTab[count];
1844 index = 0;
1845
1846 /* Assign UnionType */
1847 pui8 = pui8DATA(data, pDescr->offset);
1848 //read index from data and write to vector
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001849 bitvec_write_field(vector, writeIndex, *pui8, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001850
1851 //decode index
1852 writeIndex -= Bits;
1853
1854 while (Bits > 0)
1855 {
1856 index <<= 1;
1857
1858 if (CSN_UNION_LH == pDescr->type)
1859 {
1860 index |= get_masked_bits8(vector,writeIndex, bit_offset, 1);
1861 }
1862 else
1863 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001864 index |= bitvec_read_field(vector, writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001865 }
1866
1867 remaining_bits_len--;
1868 bit_offset++;
1869 Bits--;
1870 }
1871
1872 writeIndex -= Bits;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001873 bitvec_write_field(vector, writeIndex, index, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001874
1875
1876 /* script index to continue on, limited in case we do not have a power of 2 */
1877 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001878 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)index);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001879
1880 switch (pDescr->type)
1881 { /* get the right element of the union based on computed index */
1882
1883 case CSN_BIT:
1884 {
1885 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001886 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001887 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001888 remaining_bits_len -= 1;
1889 bit_offset++;
1890 pDescr++;
1891 break;
1892 }
1893
1894 case CSN_NULL:
1895 { /* Empty member! */
1896 pDescr++;
1897 break;
1898 }
1899
1900 case CSN_UINT:
1901 {
1902 guint8 no_of_bits = (guint8) pDescr->i;
1903 if (remaining_bits_len >= no_of_bits)
1904 {
1905 remaining_bits_len -= no_of_bits;
1906
1907 if (no_of_bits <= 8)
1908 {
1909 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001910 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001911 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001912 }
1913 else if (no_of_bits <= 16)
1914 {
1915 pui16 = pui16DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001916 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001917 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001918 }
1919 else if (no_of_bits <= 32)
1920 {
1921 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001922 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001923 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001924 }
1925 else
1926 {
1927 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1928 }
1929 }
1930 else
1931 {
1932 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1933 }
1934
1935 bit_offset += no_of_bits;
1936 pDescr++;
1937 break;
1938 }
1939
1940 case CSN_UINT_OFFSET:
1941 {
1942 guint8 no_of_bits = (guint8) pDescr->i;
1943
1944 if (remaining_bits_len >= no_of_bits)
1945 {
1946 if (no_of_bits <= 8)
1947 {
1948 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001949 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001950 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001951 }
1952 else if (no_of_bits <= 16)
1953 {
1954 pui16 = pui16DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001955 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001956 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001957 }
1958 else if (no_of_bits <= 32)
1959 {
1960 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001961 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001962 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001963 }
1964 else
1965 {
1966 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1967 }
1968 }
1969 else
1970 {
1971 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1972 }
1973
1974 remaining_bits_len -= no_of_bits;
1975 bit_offset += no_of_bits;
1976 pDescr++;
1977 break;
1978 }
1979
1980 case CSN_UINT_LH:
1981 {
1982 guint8 no_of_bits = (guint8) pDescr->i;
1983
1984 if (remaining_bits_len >= no_of_bits)
1985 {
1986 remaining_bits_len -= no_of_bits;
1987 if (no_of_bits <= 8)
1988 {
1989 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001990 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001991 // TODO : Change get_masked_bits8()
1992 writeIndex -= no_of_bits;
1993 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
1994 writeIndex -= no_of_bits;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001995 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001996 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001997
1998 }
1999 else
2000 {/* Maybe we should support more than 8 bits ? */
2001 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2002 }
2003 }
2004 else
2005 {
2006 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2007 }
2008
2009 remaining_bits_len -= no_of_bits;
2010 bit_offset += no_of_bits;
2011 pDescr++;
2012 break;
2013 }
2014
2015 case CSN_UINT_ARRAY:
2016 {
2017 guint8 no_of_bits = (guint8) pDescr->i;
2018 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
2019
2020 if (pDescr->serialize.value != 0)
2021 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
2022 nCount = *pui16DATA(data, nCount);
2023 }
2024
2025 if (remaining_bits_len >= no_of_bits)
2026 {
2027 remaining_bits_len -= (no_of_bits*nCount);
2028 if (no_of_bits <= 8)
2029 {
2030 pui8 = pui8DATA(data, pDescr->offset);
2031 do
2032 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002033 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
2034 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002035 pui8++;
2036 bit_offset += no_of_bits;
2037 } while (--nCount > 0);
2038 }
2039 else if (no_of_bits <= 16)
2040 {
2041 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2042 }
2043 else if (no_of_bits <= 32)
2044 {
2045 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2046 }
2047 else
2048 {
2049 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2050 }
2051 }
2052 else
2053 {
2054 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2055 }
2056 pDescr++;
2057 break;
2058 }
2059
2060 case CSN_VARIABLE_TARRAY_OFFSET:
2061 case CSN_VARIABLE_TARRAY:
2062 case CSN_TYPE_ARRAY:
2063 {
2064 gint16 Status;
2065 csnStream_t arT = *ar;
2066 gint16 nCount = pDescr->i;
2067 guint16 nSize = (guint16)(gint32)pDescr->serialize.value;
2068
2069 pui8 = pui8DATA(data, pDescr->offset);
2070 if (pDescr->type == CSN_VARIABLE_TARRAY)
2071 { /* Count specified in field */
2072 nCount = *pui8DATA(data, pDescr->i);
2073 }
2074 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
2075 { /* Count specified in field */
2076 nCount = *pui8DATA(data, pDescr->i);
2077 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
2078 }
2079
2080 while (nCount > 0)
2081 { /* resulting array of length 0 is possible
2082 * but no bits shall be read from bitstream
2083 */
2084
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002085 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002086 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2087 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
2088 if (Status >= 0)
2089 {
2090 pui8 += nSize;
2091 remaining_bits_len = arT.remaining_bits_len;
2092 bit_offset = arT.bit_offset;
2093 }
2094 else
2095 {
2096 return Status;
2097 }
2098 nCount--;
2099 }
2100
2101 pDescr++;
2102 break;
2103 }
2104
2105 case CSN_BITMAP:
2106 { /* bitmap with given length. The result is left aligned! */
2107 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
2108
2109 if (no_of_bits > 0)
2110 {
2111
2112 if (no_of_bits <= 32)
2113 {
2114 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002115 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002116 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002117 }
2118 else if (no_of_bits <= 64)
2119 {
2120 pui64 = pui64DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002121 bitvec_write_field(vector, writeIndex, *pui64, no_of_bits);
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +02002122 LOGPC(DCSN1, LOGL_NOTICE, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002123 }
2124 else
2125 {
2126 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
2127 }
2128
2129 remaining_bits_len -= no_of_bits;
2130 assert(remaining_bits_len >= 0);
2131 bit_offset += no_of_bits;
2132 }
2133 /* bitmap was successfully extracted or it was empty */
2134
2135 pDescr++;
2136 break;
2137 }
2138
2139 case CSN_TYPE:
2140 {
2141 gint16 Status;
2142 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002143 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002144 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2145 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002146 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002147 if (Status >= 0)
2148 {
2149 remaining_bits_len = arT.remaining_bits_len;
2150 bit_offset = arT.bit_offset;
2151 pDescr++;
2152 }
2153 else
2154 {
2155 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
2156 return Status;
2157 }
2158
2159 break;
2160 }
2161
2162 default:
2163 { /* descriptions of union elements other than above are illegal */
2164 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
2165 }
2166 }
2167
2168 pDescr = pDescrNext;
2169 break;
2170 }
2171
2172 case CSN_EXIST:
2173 case CSN_EXIST_LH:
2174 {
2175 guint8 fExist;
2176 unsigned exist = 0;
2177 pui8 = pui8DATA(data, pDescr->offset);
2178 exist = *pui8;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002179 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002180 writeIndex--;
2181 if (CSN_EXIST_LH == pDescr->type)
2182 {
2183 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
2184 }
2185 else
2186 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002187 fExist = bitvec_read_field(vector, writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002188 }
2189 writeIndex--;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002190 bitvec_write_field(vector, writeIndex, fExist, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002191 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz, (unsigned)fExist);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002192 pDescr++;
2193 remaining_bits_len -= 1;
2194
2195 if (!exist)
2196 {
2197 ar->remaining_bits_len = remaining_bits_len;
2198 ar->bit_offset = bit_offset;
2199 return remaining_bits_len;
2200 }
2201 break;
2202 }
2203
2204 case CSN_NEXT_EXIST:
2205 {
2206 guint8 fExist;
2207
2208 pui8 = pui8DATA(data, pDescr->offset);
2209
2210 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002211 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002212 { /* no more bits to decode is fine here - end of message detected and allowed */
2213
2214 /* Skip i entries + this entry */
2215 pDescr += pDescr->i + 1;
2216
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002217 break;
2218 }
2219
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002220 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002221 fExist = *pui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002222 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002223 remaining_bits_len -= 1;
2224
2225 ++bit_offset;
2226
2227 if (fExist == 0)
2228 { /* Skip 'i' entries */
2229 pDescr += pDescr->i;
2230 }
2231
2232 pDescr++;
2233 break;
2234 }
2235
2236 case CSN_NEXT_EXIST_LH:
2237 {
2238 guint8 fExist;
2239 pui8 = pui8DATA(data, pDescr->offset);
2240
2241 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
2242 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
2243 { /* no more bits to decode is fine here - end of message detected and allowed */
2244
2245 /* skip 'i' entries + this entry */
2246 pDescr += pDescr->i + 1;
2247
2248 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
2249 if ( pDescr->type != CSN_END )
2250 { /* substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
2251 remaining_bits_len--;
2252 }
2253
2254 /* set the data member to "not exist" */
2255 //*pui8 = 0;
2256 break;
2257 }
2258
2259 /* the "regular" M_NEXT_EXIST_LH description element */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002260 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002261 writeIndex--;
2262 fExist = get_masked_bits8(vector,writeIndex, bit_offset, 1);
2263 writeIndex--;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002264 bitvec_write_field(vector, writeIndex, fExist, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002265 pui8++;
2266 remaining_bits_len -= 1;
2267
2268 bit_offset++;
2269
2270 if (fExist == 0)
2271 { /* Skip 'i' entries */
2272 pDescr += pDescr->i;
2273 }
2274 pDescr++;
2275
2276 break;
2277 }
2278
2279 case CSN_VARIABLE_BITMAP_1:
2280 { /* Bitmap from here and to the end of message */
2281
2282 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2283
2284 /*no break -
2285 * with a length set we have a regular variable length bitmap so we continue */
2286 }
2287
2288 case CSN_VARIABLE_BITMAP:
2289 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2290 * <N: bit (5)> <bitmap: bit(N + offset)>
2291 * Bit array with length (in bits) specified in parameter (pDescr->descr)
2292 * The result is right aligned!
2293 */
2294 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
2295
2296 no_of_bits += pDescr->i; /* adjusted by offset */
2297
2298 if (no_of_bits > 0)
2299 {
2300 remaining_bits_len -= no_of_bits;
2301
2302 if (remaining_bits_len < 0)
2303 {
2304 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2305 }
2306
2307 { /* extract bits */
2308 guint8* pui8 = pui8DATA(data, pDescr->offset);
2309 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2310
2311 if (nB1 > 0)
2312 { /* take care of the first byte - it will be right aligned */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002313 bitvec_write_field(vector, writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002314 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002315 pui8++;
2316 no_of_bits -= nB1;
2317 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2318 }
2319
2320 /* remaining no_of_bits is a multiple of 8 or 0 */
2321 while (no_of_bits > 0)
2322 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002323 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002324 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002325 pui8++;
2326 no_of_bits -= 8;
2327 }
2328 }
2329 }
2330 pDescr++;
2331 break;
2332 }
2333
2334 case CSN_LEFT_ALIGNED_VAR_BMP_1:
2335 { /* Bitmap from here and to the end of message */
2336
2337 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2338
2339 /* no break -
2340 * with a length set we have a regular left aligned variable length bitmap so we continue
2341 */
2342 }
2343
2344 case CSN_LEFT_ALIGNED_VAR_BMP:
2345 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2346 * <N: bit (5)> <bitmap: bit(N + offset)>
2347 * bit array with length (in bits) specified in parameter (pDescr->descr)
2348 */
2349
2350 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
2351
2352 no_of_bits += pDescr->i;/* size adjusted by offset */
2353
2354 if (no_of_bits > 0)
2355 {
2356 remaining_bits_len -= no_of_bits;
2357
2358 if (remaining_bits_len < 0)
2359 {
2360 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2361 }
2362
2363 { /* extract bits */
2364 guint8* pui8 = pui8DATA(data, pDescr->offset);
2365 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2366
2367 while (no_of_bits > 0)
2368 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002369 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002370 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002371 pui8++;
2372 no_of_bits -= 8;
2373 }
2374 if (nB1 > 0)
2375 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002376 bitvec_write_field(vector, writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002377 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002378 pui8++;
2379 no_of_bits -= nB1;
2380 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2381 }
2382 }
2383
2384 }
2385
2386 /* bitmap was successfully extracted or it was empty */
2387 pDescr++;
2388 break;
2389 }
2390
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002391 case CSN_PADDING_BITS:
2392 { /* Padding from here and to the end of message */
2393 LOGPC(DCSN1, LOGL_NOTICE, "%s = ", pDescr->sz);
2394 guint8 filler = 0x2b;
2395 if (remaining_bits_len > 0)
2396 {
2397 while (remaining_bits_len > 0)
2398 {
2399 guint8 bits_to_handle = remaining_bits_len%8;
2400 if (bits_to_handle > 0)
2401 {
2402 guint8 fl = filler&(0xff>>(8-bits_to_handle));
2403 bitvec_write_field(vector, writeIndex, fl, bits_to_handle);
2404 LOGPC(DCSN1, LOGL_NOTICE, "%u|", fl);
2405 remaining_bits_len -= bits_to_handle;
2406 bit_offset += bits_to_handle;
2407 }
2408 else if (bits_to_handle == 0)
2409 {
2410 bitvec_write_field(vector, writeIndex, filler, 8);
2411 LOGPC(DCSN1, LOGL_NOTICE, "%u|", filler);
2412 remaining_bits_len -= 8;
2413 bit_offset += 8;
2414 }
2415 }
2416 }
2417 if (remaining_bits_len < 0)
2418 {
2419 return ProcessError(writeIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2420 }
2421
2422 /* Padding was successfully extracted or it was empty */
2423 pDescr++;
2424 break;
2425 }
2426
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002427 case CSN_VARIABLE_ARRAY:
2428 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
2429 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2430 * Array with length specified in parameter:
2431 * <count: bit (x)>
2432 * <list: octet(count + offset)>
2433 */
2434 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
2435
2436 count += pDescr->i; /* Adjusted by offset */
2437
2438 if (count > 0)
2439 {
2440 remaining_bits_len -= count * 8;
2441
2442 if (remaining_bits_len < 0)
2443 {
2444 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2445 }
2446
2447 pui8 = pui8DATA(data, pDescr->offset);
2448
2449 while (count > 0)
2450 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002451 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002452 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002453 pui8++;
2454 bit_offset += 8;
2455 count--;
2456 }
2457 }
2458
2459 pDescr++;
2460 break;
2461 }
2462
2463 case CSN_RECURSIVE_ARRAY:
2464 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
2465 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
2466 * where <element> ::= bit(value)
2467 * <tag> ::= 0 | 1
2468 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
2469 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2470 * REMARK: recursive way to specify an array but an iterative implementation!
2471 */
2472 gint16 no_of_bits = pDescr->i;
2473 guint8 ElementCount = 0;
2474 pui8 = pui8DATA(data, pDescr->offset);
2475 ElementCount = *pui8DATA(data, (gint16)pDescr->descr.value);
2476 while (ElementCount > 0)
2477 { /* tag control shows existence of next list elements */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002478 bitvec_write_field(vector, writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002479 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002480 bit_offset++;
2481 remaining_bits_len--;
2482
2483 /* extract and store no_of_bits long element from bitstream */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002484 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002485 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002486 pui8++;
2487 remaining_bits_len -= no_of_bits;
2488 ElementCount--;
2489
2490 if (remaining_bits_len < 0)
2491 {
2492 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2493 }
2494
2495 bit_offset += no_of_bits;
2496 }
2497
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002498 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002499 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002500 bit_offset++;
2501
2502 pDescr++;
2503 break;
2504 }
2505
2506 case CSN_RECURSIVE_TARRAY:
2507 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
2508 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2509 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2510 */
2511 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
2512 guint8 ElementCount = 0;
2513 pui8 = pui8DATA(data, pDescr->offset);
2514 /* Store the counted number of elements of the array */
2515 ElementCount = *pui8DATA(data, (gint16)(gint32)pDescr->i);
2516
2517 while (ElementCount > 0)
2518 { /* tag control shows existence of next list elements */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002519 bitvec_write_field(vector, writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002520 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002521 bit_offset++;
2522
2523 remaining_bits_len--;
2524 ElementCount--;
2525
2526 { /* unpack the following data structure */
2527 csnStream_t arT = *ar;
2528 gint16 Status;
2529 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002530 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002531
2532 if (Status >= 0)
2533 { /* successful completion */
2534 pui8 += nSizeElement; /* -> to next data element */
2535 remaining_bits_len = arT.remaining_bits_len;
2536 bit_offset = arT.bit_offset;
2537 }
2538 else
2539 { /* something went awry */
2540 return Status;
2541 }
2542 }
2543
2544 if (remaining_bits_len < 0)
2545 {
2546 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2547 }
2548 }
2549
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002550 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002551 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002552 bit_offset++;
2553
2554 pDescr++;
2555 break;
2556 }
2557
2558 case CSN_RECURSIVE_TARRAY_2:
2559 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
2560
2561 Tag = REVERSED_TAG;
2562
2563 /* NO break -
2564 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
2565 */
2566 }
2567
2568 case CSN_RECURSIVE_TARRAY_1:
2569 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
2570 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2571 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2572 */
2573 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
2574 guint8 ElementCount = 0;
2575 guint8 ElementNum = 0;
2576 csnStream_t arT = *ar;
2577 gint16 Status;
2578
2579 pui8 = pui8DATA(data, pDescr->offset);
2580 /* Store the count of the array */
2581 ElementCount = *pui8DATA(data, pDescr->i);
2582 ElementNum = ElementCount;
2583
2584 while (ElementCount > 0)
2585 { /* get data element */
2586 if (ElementCount != ElementNum)
2587 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002588 bitvec_write_field(vector, writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002589 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002590 bit_offset++;
2591 remaining_bits_len--;
2592 }
2593 ElementCount--;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002594 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002595 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002596 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002597 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002598 if (Status >= 0)
2599 { /* successful completion */
2600 pui8 += nSizeElement; /* -> to next */
2601 remaining_bits_len = arT.remaining_bits_len;
2602 bit_offset = arT.bit_offset;
2603 }
2604 else
2605 { /* something went awry */
2606 return Status;
2607 }
2608
2609 if (remaining_bits_len < 0)
2610 {
2611 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2612 }
2613
2614 }
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002615 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002616 bit_offset++;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002617 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002618 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
2619 pDescr++;
2620 break;
2621 }
2622
2623 case CSN_FIXED:
2624 { /* Verify the fixed bits */
2625 guint8 no_of_bits = (guint8) pDescr->i;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002626 bitvec_write_field(vector, writeIndex, pDescr->offset, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002627 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002628 remaining_bits_len -= no_of_bits;
2629 bit_offset += no_of_bits;
2630 pDescr++;
2631 break;
2632 }
2633
2634 case CSN_CALLBACK:
2635 {
2636 return ProcessError(writeIndex,"csnStreamEncoder Callback not implemented", -1, pDescr);
2637 break;
2638 }
2639
2640 case CSN_TRAP_ERROR:
2641 {
2642 return ProcessError(writeIndex,"csnStreamEncoder", pDescr->i, pDescr);
2643 }
2644
2645 case CSN_END:
2646 {
2647 ar->remaining_bits_len = remaining_bits_len;
2648 ar->bit_offset = bit_offset;
2649 return remaining_bits_len;
2650 }
2651
2652 default:
2653 {
2654 assert(0);
2655 }
2656
2657 }
2658
2659 } while (remaining_bits_len >= 0);
2660
2661 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2662}
2663