blob: 45cc84871e1b9e1b3977944e41efb17b894bca9d [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;
92}
93
94static const char* ErrCodes[] =
95{
96 "General 0",
97 "General -1",
98 "DATA_NOT VALID",
99 "IN SCRIPT",
100 "INVALID UNION INDEX",
101 "NEED_MORE BITS TO UNPACK",
102 "ILLEGAL BIT VALUE",
103 "Internal",
104 "STREAM_NOT_SUPPORTED",
105 "MESSAGE_TOO_LONG"
106};
107
108static gint16
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400109ProcessError( unsigned readIndex, const char* sz, gint16 err, const CSN_DESCR* pDescr)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300110{
111 gint16 i = MIN(-err, ((gint16) ElementsOf(ErrCodes)-1));
112 if (i >= 0)
113 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400114 //LOG(ERR) << sz << "Error code: "<< ErrCodes[i] << pDescr?(pDescr->sz):"-";
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300115 }
116 else
117 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400118 //LOG(ERR) << sz << ": " << pDescr?(pDescr->sz):"-";
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300119 }
120 return err;
121}
122
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300123
124/**
125 * ================================================================================================
126 * Return TRUE if tag in bit stream indicates existence of next list element,
127 * otherwise return FALSE.
128 * Will work for tag values equal to both 0 and 1.
129 * ================================================================================================
130 */
131
132static gboolean
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400133existNextElement(bitvec *vector, unsigned& readIndex, guint8 Tag)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300134{
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400135 guint8 res = bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300136 if (Tag == STANDARD_TAG)
137 {
138 return (res > 0);
139 }
140 return (res == 0);
141}
142
143
144gint16
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400145csnStreamDecoder(csnStream_t* ar, const CSN_DESCR* pDescr, bitvec *vector, unsigned& readIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300146{
147 gint remaining_bits_len = ar->remaining_bits_len;
148 gint bit_offset = ar->bit_offset;
149 guint8* pui8;
150 guint16* pui16;
151 guint32* pui32;
152 guint64* pui64;
153 guint8 Tag = STANDARD_TAG;
154
155 if (remaining_bits_len <= 0)
156 {
157 return 0;
158 }
159
160 do
161 {
162 switch (pDescr->type)
163 {
164 case CSN_BIT:
165 {
166 if (remaining_bits_len > 0)
167 {
168 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400169 *pui8 = bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400170 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300171 /* end add the bit value to protocol tree */
172 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400173 else if(pDescr->may_be_null)
174 {
175 pui8 = pui8DATA(data, pDescr->offset);
176 *pui8 = 0;
177 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
178 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300179 else
180 {
181 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
182 }
183
184 pDescr++;
185 remaining_bits_len--;
186 bit_offset++;
187 break;
188 }
189
190 case CSN_NULL:
191 { /* Empty member! */
192 pDescr++;
193 break;
194 }
195
196 case CSN_UINT:
197 {
198 guint8 no_of_bits = (guint8) pDescr->i;
199
200 if (remaining_bits_len >= no_of_bits)
201 {
202 if (no_of_bits <= 8)
203 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400204 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300205 pui8 = pui8DATA(data, pDescr->offset);
206 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400207 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300208 }
209 else if (no_of_bits <= 16)
210 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400211 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300212 pui16 = pui16DATA(data, pDescr->offset);
213 *pui16 = ui16;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400214 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300215 }
216 else if (no_of_bits <= 32)
217 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400218 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300219 pui32 = pui32DATA(data, pDescr->offset);
220 *pui32 = ui32;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400221 LOGPC(DCSN1, LOGL_NOTICE, "%s = 0x%08x | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300222 }
223 else
224 {
225 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
226 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400227 remaining_bits_len -= no_of_bits;
228 bit_offset += no_of_bits;
229 }
230 else if(pDescr->may_be_null)
231 {
232 if (no_of_bits <= 8)
233 {
234 pui8 = pui8DATA(data, pDescr->offset);
235 *pui8 = 0;
236 }
237 else if (no_of_bits <= 16)
238 {
239 pui16 = pui16DATA(data, pDescr->offset);
240 *pui16 = 0;
241 }
242 else if (no_of_bits <= 32)
243 {
244 pui32 = pui32DATA(data, pDescr->offset);
245 *pui32 = 0;
246 }
247 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300248 }
249 else
250 {
251 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
252 }
253
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300254 pDescr++;
255 break;
256 }
257
258 case CSN_UINT_OFFSET:
259 {
260 guint8 no_of_bits = (guint8) pDescr->i;
261
262 if (remaining_bits_len >= no_of_bits)
263 {
264 if (no_of_bits <= 8)
265 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400266 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300267 pui8 = pui8DATA(data, pDescr->offset);
268 *pui8 = ui8 + (guint8)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400269 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300270 }
271 else if (no_of_bits <= 16)
272 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400273 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300274 pui16 = pui16DATA(data, pDescr->offset);
275 *pui16 = ui16 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400276 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300277 }
278 else if (no_of_bits <= 32)
279 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400280 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300281 pui32 = pui32DATA(data, pDescr->offset);
282 *pui32 = ui32 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400283 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300284 }
285 else
286 {
287 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
288 }
289 }
290 else
291 {
292 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
293 }
294
295 remaining_bits_len -= no_of_bits;
296 bit_offset += no_of_bits;
297 pDescr++;
298 break;
299 }
300
301 case CSN_UINT_LH:
302 {
303 guint8 no_of_bits = (guint8) pDescr->i;
304
305 if (remaining_bits_len >= no_of_bits)
306 {
307 remaining_bits_len -= no_of_bits;
308 if (no_of_bits <= 8)
309 {
310 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
311 pui8 = pui8DATA(data, pDescr->offset);
312 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400313 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300314 }
315 else
316 {/* Maybe we should support more than 8 bits ? */
317 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
318 }
319 }
320 else
321 {
322 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
323 }
324
325 remaining_bits_len -= no_of_bits;
326 bit_offset += no_of_bits;
327 pDescr++;
328 break;
329 }
330
331 case CSN_UINT_ARRAY:
332 {
333 guint8 no_of_bits = (guint8) pDescr->i;
334 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
335
336 if (pDescr->serialize.value != 0)
337 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
338 nCount = *pui16DATA(data, nCount);
339 }
340
341 if (remaining_bits_len >= no_of_bits)
342 {
343 remaining_bits_len -= (no_of_bits*nCount);
344 if (no_of_bits <= 8)
345 {
346 pui8 = pui8DATA(data, pDescr->offset);
347 do
348 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400349 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400350 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300351 pui8++;
352 bit_offset += no_of_bits;
353 } while (--nCount > 0);
354 }
355 else if (no_of_bits <= 16)
356 {
357 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
358 }
359 else if (no_of_bits <= 32)
360 {
361 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
362 }
363 else
364 {
365 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
366 }
367 }
368 else
369 {
370 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
371 }
372 pDescr++;
373 break;
374 }
375
376 case CSN_VARIABLE_TARRAY_OFFSET:
377 case CSN_VARIABLE_TARRAY:
378 case CSN_TYPE_ARRAY:
379 {
380 gint16 Status;
381 csnStream_t arT = *ar;
382 gint16 nCount = pDescr->i;
383 guint16 nSize = (guint16)(gint32)pDescr->serialize.value;
384
385 pui8 = pui8DATA(data, pDescr->offset);
386 if (pDescr->type == CSN_VARIABLE_TARRAY)
387 { /* Count specified in field */
388 nCount = *pui8DATA(data, pDescr->i);
389 }
390 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
391 { /* Count specified in field */
392 nCount = *pui8DATA(data, pDescr->i);
393 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
394 }
395
396 while (nCount > 0)
397 { /* resulting array of length 0 is possible
398 * but no bits shall be read from bitstream
399 */
400
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400401 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300402 csnStreamInit(&arT, bit_offset, remaining_bits_len);
403 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
404 if (Status >= 0)
405 {
406 pui8 += nSize;
407 remaining_bits_len = arT.remaining_bits_len;
408 bit_offset = arT.bit_offset;
409 }
410 else
411 {
412 return Status;
413 }
414 nCount--;
415 }
416
417 pDescr++;
418 break;
419 }
420
421 case CSN_BITMAP:
422 { /* bitmap with given length. The result is left aligned! */
423 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
424
425 if (no_of_bits > 0)
426 {
427
428 if (no_of_bits <= 32)
429 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400430 for(unsigned ib = 0; ib < 4; ib++)
431 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400432 guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400433 pui8 = pui8DATA(data, pDescr->offset+ib);
434 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400435 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400436 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300437 }
438 else if (no_of_bits <= 64)
439 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400440 for(unsigned ib = 0; ib < 8; ib++)
441 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400442 guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400443 pui8 = pui8DATA(data, pDescr->offset+ib);
444 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400445 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400446 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300447 }
448 else
449 {
450 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
451 }
452
453 remaining_bits_len -= no_of_bits;
454 assert(remaining_bits_len >= 0);
455 bit_offset += no_of_bits;
456 }
457 /* bitmap was successfully extracted or it was empty */
458
459 pDescr++;
460 break;
461 }
462
463 case CSN_TYPE:
464 {
465 gint16 Status;
466 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400467 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300468 csnStreamInit(&arT, bit_offset, remaining_bits_len);
469 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400470 LOGPC(DCSN1, LOGL_NOTICE, ": End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300471 if (Status >= 0)
472 {
473 remaining_bits_len = arT.remaining_bits_len;
474 bit_offset = arT.bit_offset;
475 pDescr++;
476 }
477 else
478 {
479 /* Has already been processed: ProcessError("csnStreamDecoder", Status, pDescr); */
480 return Status;
481 }
482
483 break;
484 }
485
486 case CSN_CHOICE:
487 {
488 gint16 count = pDescr->i;
489 guint8 i = 0;
490 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
491
492 while (count > 0)
493 {
494 guint8 no_of_bits = pChoice->bits;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400495 guint8 value = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300496 if (value == pChoice->value)
497 {
498 CSN_DESCR descr[2];
499 gint16 Status;
500 csnStream_t arT = *ar;
501
502 descr[0] = pChoice->descr;
503 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
504 descr[1].type = CSN_END;
505 pui8 = pui8DATA(data, pDescr->offset);
506 *pui8 = i;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400507 LOGPC(DCSN1, LOGL_NOTICE, "Choice %s = %u | ", pDescr->sz , (unsigned)value);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300508 bit_offset += no_of_bits;
509 remaining_bits_len -= no_of_bits;
510
511 csnStreamInit(&arT, bit_offset, remaining_bits_len);
512 Status = csnStreamDecoder(&arT, descr, vector, readIndex, data);
513
514 if (Status >= 0)
515 {
516 remaining_bits_len = arT.remaining_bits_len;
517 bit_offset = arT.bit_offset;
518 }
519 else
520 {
521 return Status;
522 }
523 break;
524 }
525
526 readIndex -= no_of_bits;
527 count--;
528 pChoice++;
529 i++;
530 }
531
532 pDescr++;
533 break;
534 }
535
536 case CSN_SERIALIZE:
537 {
538 StreamSerializeFcn_t serialize = pDescr->serialize.fcn;
539 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400540 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300541 gint16 Status = -1;
542
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400543 guint8 length = bitvec_read_field(vector, readIndex, length_len);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300544
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400545 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %d | ", pDescr->sz , (int)length);
546 arT.direction = 1;
547 bit_offset += length_len;
548 remaining_bits_len -= length_len;
549
550 csnStreamInit(&arT, bit_offset, length);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300551 Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset));
552
553 if (Status >= 0)
554 {
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400555 remaining_bits_len -= length;
556 bit_offset += length;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300557 pDescr++;
558 }
559 else
560 {
561 /* Has already been processed: */
562 return Status;
563 }
564
565 break;
566 }
567
568 case CSN_UNION_LH:
569 case CSN_UNION:
570 {
571 gint16 Bits;
572 guint8 index;
573 gint16 count = pDescr->i;
574 const CSN_DESCR* pDescrNext = pDescr;
575
576 pDescrNext += count + 1; /* now this is next after the union */
577 if ((count <= 0) || (count > 16))
578 {
579 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
580 }
581
582 /* Now get the bits to extract the index */
583 Bits = ixBitsTab[count];
584 index = 0;
585
586 while (Bits > 0)
587 {
588 index <<= 1;
589
590 if (CSN_UNION_LH == pDescr->type)
591 {
592 index |= get_masked_bits8(vector,readIndex, bit_offset, 1);
593 }
594 else
595 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400596 index |= bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300597 }
598 remaining_bits_len--;
599 bit_offset++;
600 Bits--;
601 }
602
603 /* Assign UnionType */
604 pui8 = pui8DATA(data, pDescr->offset);
605 *pui8 = index;
606
607
608 /* script index to continue on, limited in case we do not have a power of 2 */
609 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400610 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300611
612 switch (pDescr->type)
613 { /* get the right element of the union based on computed index */
614
615 case CSN_BIT:
616 {
617 pui8 = pui8DATA(data, pDescr->offset);
618 *pui8 = 0x00;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400619 if (bitvec_read_field(vector, readIndex, 1) > 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300620 {
621 *pui8 = 0x01;
622 }
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400623 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300624 remaining_bits_len -= 1;
625 bit_offset++;
626 pDescr++;
627 break;
628 }
629
630 case CSN_NULL:
631 { /* Empty member! */
632 pDescr++;
633 break;
634 }
635
636 case CSN_UINT:
637 {
638 guint8 no_of_bits = (guint8) pDescr->i;
639 if (remaining_bits_len >= no_of_bits)
640 {
641 remaining_bits_len -= no_of_bits;
642
643 if (no_of_bits <= 8)
644 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400645 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300646 pui8 = pui8DATA(data, pDescr->offset);
647 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400648 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300649 }
650 else if (no_of_bits <= 16)
651 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400652 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300653 pui16 = pui16DATA(data, pDescr->offset);
654 *pui16 = ui16;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400655 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300656 }
657 else if (no_of_bits <= 32)
658 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400659 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300660 pui32 = pui32DATA(data, pDescr->offset);
661 *pui32 = ui32;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400662 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300663 }
664 else
665 {
666 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
667 }
668 }
669 else
670 {
671 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
672 }
673
674 bit_offset += no_of_bits;
675 pDescr++;
676 break;
677 }
678
679 case CSN_UINT_OFFSET:
680 {
681 guint8 no_of_bits = (guint8) pDescr->i;
682
683 if (remaining_bits_len >= no_of_bits)
684 {
685 if (no_of_bits <= 8)
686 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400687 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300688 pui8 = pui8DATA(data, pDescr->offset);
689 *pui8 = ui8 + (guint8)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400690 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300691 }
692 else if (no_of_bits <= 16)
693 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400694 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300695 pui16 = pui16DATA(data, pDescr->offset);
696 *pui16 = ui16 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400697 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300698 }
699 else if (no_of_bits <= 32)
700 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400701 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300702 pui32 = pui32DATA(data, pDescr->offset);
703 *pui32 = ui32 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400704 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300705 }
706 else
707 {
708 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
709 }
710 }
711 else
712 {
713 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
714 }
715
716 bit_offset += no_of_bits;
717 pDescr++;
718 break;
719 }
720
721 case CSN_UINT_LH:
722 {
723 guint8 no_of_bits = (guint8) pDescr->i;
724
725 if (remaining_bits_len >= no_of_bits)
726 {
727 if (no_of_bits <= 8)
728 {
729 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
730 pui8 = pui8DATA(data, pDescr->offset);
731 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400732 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300733 }
734 else
735 { /* Maybe we should support more than 8 bits ? */
736 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
737 }
738 }
739 else
740 {
741 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
742 }
743
744 bit_offset += no_of_bits;
745 pDescr++;
746 break;
747 }
748
749 case CSN_UINT_ARRAY:
750 {
751 guint8 no_of_bits = (guint8) pDescr->i;
752 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
753
754 if (pDescr->serialize.value != 0)
755 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
756 nCount = *pui16DATA(data, nCount);
757 }
758
759 if (remaining_bits_len >= no_of_bits)
760 {
761 remaining_bits_len -= (no_of_bits * nCount);
762 if (no_of_bits <= 8)
763 {
764 pui8 = pui8DATA(data, pDescr->offset);
765
766 while (nCount > 0)
767 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400768 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400769 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300770 pui8++;
771 bit_offset += no_of_bits;
772 nCount--;
773 }
774 }
775 else if (no_of_bits <= 16)
776 {
777 pui16 = pui16DATA(data, pDescr->offset);
778
779 while (nCount > 0)
780 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400781 *pui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400782 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300783 pui16++;
784 bit_offset += no_of_bits;
785 nCount--;
786 }
787 }
788 else if (no_of_bits <= 32)
789 { /* not supported */
790 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
791 }
792 else
793 {
794 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
795 }
796 }
797 else
798 {
799 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
800 }
801
802 pDescr++;
803 break;
804 }
805
806 case CSN_VARIABLE_TARRAY_OFFSET:
807 case CSN_VARIABLE_TARRAY:
808 case CSN_TYPE_ARRAY:
809 {
810 gint16 Status;
811 csnStream_t arT = *ar;
812 guint16 nCount = (guint16) pDescr->i;
813 guint16 nSize = (guint16)(guint32)pDescr->serialize.value;
814
815 pui8 = pui8DATA(data, pDescr->offset);
816
817 if (CSN_VARIABLE_TARRAY == pDescr->type)
818 { /* Count specified in field */
819 nCount = *pui8DATA(data, pDescr->i);
820 }
821 else if (CSN_VARIABLE_TARRAY_OFFSET == pDescr->type)
822 { /* Count specified in field */
823 nCount = *pui8DATA(data, pDescr->i);
824 nCount--; /* Offset 1 */
825 }
826
827 while (nCount--) /* Changed to handle length = 0. */
828 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400829 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300830 csnStreamInit(&arT, bit_offset, remaining_bits_len);
831 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
832 if (Status >= 0)
833 {
834 pui8 += nSize;
835 remaining_bits_len = arT.remaining_bits_len;
836 bit_offset = arT.bit_offset;
837 }
838 else
839 {
840 return Status;
841 }
842 }
843
844 pDescr++;
845 break;
846 }
847
848 case CSN_BITMAP:
849 { /* bitmap with given length. The result is left aligned! */
850 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
851
852 if (no_of_bits > 0)
853 {
854
855 if (no_of_bits <= 32)
856 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400857 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300858 pui32 = pui32DATA(data, pDescr->offset);
859 *pui32 = ui32;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300860 }
861 else if (no_of_bits <= 64)
862 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400863 guint64 ui64 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300864 pui64 = pui64DATA(data, pDescr->offset);
865 *pui64 = ui64;
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +0200866 LOGPC(DCSN1, LOGL_NOTICE, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300867 }
868 else
869 {
870 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
871 }
872
873 remaining_bits_len -= no_of_bits;
874 assert(remaining_bits_len >= 0);
875 bit_offset += no_of_bits;
876 }
877 /* bitmap was successfully extracted or it was empty */
878
879 pDescr++;
880 break;
881 }
882
883 case CSN_TYPE:
884 {
885 gint16 Status;
886 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400887 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300888 csnStreamInit(&arT, bit_offset, remaining_bits_len);
889 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400890 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300891 if (Status >= 0)
892 {
893 remaining_bits_len = arT.remaining_bits_len;
894 bit_offset = arT.bit_offset;
895 pDescr++;
896 }
897 else
898 { /* return error code Has already been processed: */
899 return Status;
900 }
901
902 break;
903 }
904
905 default:
906 { /* descriptions of union elements other than above are illegal */
907 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
908 }
909 }
910
911 pDescr = pDescrNext;
912 break;
913 }
914
915 case CSN_EXIST:
916 case CSN_EXIST_LH:
917 {
918 guint8 fExist;
919
920 pui8 = pui8DATA(data, pDescr->offset);
921
922 if (CSN_EXIST_LH == pDescr->type)
923 {
924 fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
925 }
926 else
927 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400928 fExist = bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300929 }
930
931 *pui8 = fExist;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400932 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300933 pDescr++;
934 remaining_bits_len -= 1;
935
936 if (!fExist)
937 {
938 ar->remaining_bits_len = remaining_bits_len;
939 ar->bit_offset = bit_offset;
940 return remaining_bits_len;
941 }
942
943 break;
944 }
945
946 case CSN_NEXT_EXIST:
947 {
948 guint8 fExist;
949
950 pui8 = pui8DATA(data, pDescr->offset);
951
952 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400953 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300954 { /* no more bits to decode is fine here - end of message detected and allowed */
955
956 /* Skip i entries + this entry */
957 pDescr += pDescr->i + 1;
958
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300959 /* Set the data member to "not exist" */
960 *pui8 = 0;
961 break;
962 }
963
964 /* the "regular" M_NEXT_EXIST description element */
965
966 fExist = 0x00;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400967 if (bitvec_read_field(vector, readIndex, 1))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300968 {
969 fExist = 0x01;
970 }
971
972 *pui8 = fExist;
973 remaining_bits_len -= 1;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400974 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300975 ++bit_offset;
976
977 if (fExist == 0)
978 { /* Skip 'i' entries */
979 pDescr += pDescr->i;
980 }
981
982 pDescr++;
983 break;
984 }
985
986 case CSN_NEXT_EXIST_LH:
987 {
988 guint8 fExist;
989 pui8 = pui8DATA(data, pDescr->offset);
990
991 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
992 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
993 { /* no more bits to decode is fine here - end of message detected and allowed */
994
995 /* skip 'i' entries + this entry */
996 pDescr += pDescr->i + 1;
997
998 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
999 if ( pDescr->type != CSN_END )
1000 { /* substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
1001 remaining_bits_len--;
1002 }
1003
1004 /* set the data member to "not exist" */
1005 *pui8 = 0;
1006 break;
1007 }
1008
1009 /* the "regular" M_NEXT_EXIST_LH description element */
1010 fExist = get_masked_bits8(vector,readIndex,bit_offset, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001011 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)fExist);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001012 *pui8++ = fExist;
1013 remaining_bits_len -= 1;
1014
1015 bit_offset++;
1016
1017 if (fExist == 0)
1018 { /* Skip 'i' entries */
1019 pDescr += pDescr->i;
1020 }
1021 pDescr++;
1022
1023 break;
1024 }
1025
1026 case CSN_VARIABLE_BITMAP_1:
1027 { /* Bitmap from here and to the end of message */
1028
1029 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1030
1031 /*no break -
1032 * with a length set we have a regular variable length bitmap so we continue */
1033 }
1034
1035 case CSN_VARIABLE_BITMAP:
1036 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1037 * <N: bit (5)> <bitmap: bit(N + offset)>
1038 * Bit array with length (in bits) specified in parameter (pDescr->descr)
1039 * The result is right aligned!
1040 */
1041 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
1042
1043 no_of_bits += pDescr->i; /* adjusted by offset */
1044
1045 if (no_of_bits > 0)
1046 {
1047 remaining_bits_len -= no_of_bits;
1048
1049 if (remaining_bits_len < 0)
1050 {
1051 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1052 }
1053
1054 { /* extract bits */
1055 guint8* pui8 = pui8DATA(data, pDescr->offset);
1056 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1057
1058 if (nB1 > 0)
1059 { /* take care of the first byte - it will be right aligned */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001060 *pui8 = bitvec_read_field(vector, readIndex, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001061 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001062 pui8++;
1063 no_of_bits -= nB1;
1064 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1065 }
1066
1067 /* remaining no_of_bits is a multiple of 8 or 0 */
1068 while (no_of_bits > 0)
1069 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001070 *pui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001071 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001072 pui8++;
1073 no_of_bits -= 8;
1074 }
1075 }
1076 }
1077 pDescr++;
1078 break;
1079 }
1080
1081 case CSN_LEFT_ALIGNED_VAR_BMP_1:
1082 { /* Bitmap from here and to the end of message */
1083
1084 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1085
1086 /* no break -
1087 * with a length set we have a regular left aligned variable length bitmap so we continue
1088 */
1089 }
1090
1091 case CSN_LEFT_ALIGNED_VAR_BMP:
1092 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1093 * <N: bit (5)> <bitmap: bit(N + offset)>
1094 * bit array with length (in bits) specified in parameter (pDescr->descr)
1095 */
1096 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
1097
1098 no_of_bits += pDescr->i;/* size adjusted by offset */
1099
1100 if (no_of_bits > 0)
1101 {
1102 remaining_bits_len -= no_of_bits;
1103
1104 if (remaining_bits_len < 0)
1105 {
1106 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1107 }
1108
1109 { /* extract bits */
1110 guint8* pui8 = pui8DATA(data, pDescr->offset);
1111 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1112
1113 while (no_of_bits > 0)
1114 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001115 *pui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001116 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001117 pui8++;
1118 no_of_bits -= 8;
1119 }
1120 if (nB1 > 0)
1121 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001122 *pui8 = bitvec_read_field(vector, readIndex, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001123 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001124 pui8++;
1125 no_of_bits -= nB1;
1126 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1127 }
1128 }
1129 }
1130
1131 /* bitmap was successfully extracted or it was empty */
1132 pDescr++;
1133 break;
1134 }
1135
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001136 case CSN_PADDING_BITS:
1137 { /* Padding from here and to the end of message */
1138 LOGPC(DCSN1, LOGL_NOTICE, "%s = ", pDescr->sz);
1139 if (remaining_bits_len > 0)
1140 {
1141 while (remaining_bits_len > 0)
1142 {
1143 guint8 bits_to_handle = remaining_bits_len%8;
1144 if (bits_to_handle > 0)
1145 {
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +02001146 LOGPC(DCSN1, LOGL_NOTICE, "%"PRIu64"|", bitvec_read_field(vector, readIndex, bits_to_handle));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001147 remaining_bits_len -= bits_to_handle;
1148 bit_offset += bits_to_handle;
1149 }
1150 else if (bits_to_handle == 0)
1151 {
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +02001152 LOGPC(DCSN1, LOGL_NOTICE, "%"PRIu64"|", bitvec_read_field(vector, readIndex, 8));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001153 remaining_bits_len -= 8;
1154 bit_offset += 8;
1155 }
1156 }
1157 }
1158 if (remaining_bits_len < 0)
1159 {
1160 return ProcessError(readIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1161 }
1162
1163 /* Padding was successfully extracted or it was empty */
1164 pDescr++;
1165 break;
1166 }
1167
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001168 case CSN_VARIABLE_ARRAY:
1169 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
1170 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1171 * Array with length specified in parameter:
1172 * <count: bit (x)>
1173 * <list: octet(count + offset)>
1174 */
1175 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
1176
1177 count += pDescr->i; /* Adjusted by offset */
1178
1179 if (count > 0)
1180 {
1181 remaining_bits_len -= count * 8;
1182
1183 if (remaining_bits_len < 0)
1184 {
1185 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1186 }
1187
1188 pui8 = pui8DATA(data, pDescr->offset);
1189
1190 while (count > 0)
1191 {
1192 readIndex -= 8;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001193 *pui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001194 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001195 pui8++;
1196 bit_offset += 8;
1197 count--;
1198 }
1199 }
1200
1201 pDescr++;
1202 break;
1203 }
1204
1205 case CSN_RECURSIVE_ARRAY:
1206 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
1207 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
1208 * where <element> ::= bit(value)
1209 * <tag> ::= 0 | 1
1210 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
1211 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1212 * REMARK: recursive way to specify an array but an iterative implementation!
1213 */
1214 gint16 no_of_bits = pDescr->i;
1215 guint8 ElementCount = 0;
1216
1217 pui8 = pui8DATA(data, pDescr->offset);
1218
1219 while (existNextElement(vector, readIndex, Tag))
1220 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001221 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001222 bit_offset++;
1223 remaining_bits_len--;
1224
1225 /* extract and store no_of_bits long element from bitstream */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001226 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001227 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001228 pui8++;
1229 remaining_bits_len -= no_of_bits;
1230 ElementCount++;
1231
1232 if (remaining_bits_len < 0)
1233 {
1234 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1235 }
1236
1237 bit_offset += no_of_bits;
1238 }
1239
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001240 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)bitvec_read_field(vector, readIndex, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001241 /* existNextElement() returned FALSE, 1 bit consumed */
1242 bit_offset++;
1243
1244 /* Store the counted number of elements of the array */
1245 *pui8DATA(data, (gint16)pDescr->descr.value) = ElementCount;
1246
1247 pDescr++;
1248 break;
1249 }
1250
1251 case CSN_RECURSIVE_TARRAY:
1252 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
1253 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1254 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1255 */
1256 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
1257 guint8 ElementCount = 0;
1258 pui8 = pui8DATA(data, pDescr->offset);
1259
1260 while (existNextElement(vector, readIndex, Tag))
1261 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001262 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001263 /* existNextElement() returned TRUE, 1 bit consumed */
1264 bit_offset++;
1265 remaining_bits_len--;
1266 ElementCount++;
1267
1268 { /* unpack the following data structure */
1269 csnStream_t arT = *ar;
1270 gint16 Status;
1271 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04001272 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001273
1274 if (Status >= 0)
1275 { /* successful completion */
1276 pui8 += nSizeElement; /* -> to next data element */
1277 remaining_bits_len = arT.remaining_bits_len;
1278 bit_offset = arT.bit_offset;
1279 }
1280 else
1281 { /* something went awry */
1282 return Status;
1283 }
1284 }
1285
1286 if (remaining_bits_len < 0)
1287 {
1288 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1289 }
1290 }
1291
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001292 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)bitvec_read_field(vector, readIndex, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001293
1294 /* existNextElement() returned FALSE, 1 bit consumed */
1295 bit_offset++;
1296
1297 /* Store the counted number of elements of the array */
1298 *pui8DATA(data, (gint16)(gint32)pDescr->i) = ElementCount;
1299
1300 pDescr++;
1301 break;
1302 }
1303
1304 case CSN_RECURSIVE_TARRAY_2:
1305 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
1306
1307 Tag = REVERSED_TAG;
1308
1309 /* NO break -
1310 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
1311 */
1312 }
1313
1314 case CSN_RECURSIVE_TARRAY_1:
1315 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
1316 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1317 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1318 */
1319 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
1320 guint8 ElementCount = 0;
1321 csnStream_t arT = *ar;
1322 gboolean EndOfList = FALSE;
1323 gint16 Status;
1324 pui8 = pui8DATA(data, pDescr->offset);
1325
1326 do
1327 { /* get data element */
1328 ElementCount++;
1329
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001330 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
1331
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001332 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04001333 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001334
1335 if (Status >= 0)
1336 { /* successful completion */
1337 pui8 += nSizeElement; /* -> to next */
1338 remaining_bits_len = arT.remaining_bits_len;
1339 bit_offset = arT.bit_offset;
1340 }
1341 else
1342 { /* something went awry */
1343 return Status;
1344 }
1345
1346 if (remaining_bits_len < 0)
1347 {
1348 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1349 }
1350
1351 /* control of next element's tag */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001352 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001353 EndOfList = !(existNextElement(vector, readIndex, Tag));
1354
1355 bit_offset++;
1356 remaining_bits_len--; /* 1 bit consumed (tag) */
1357 } while (!EndOfList);
1358
1359
1360 /* Store the count of the array */
1361 *pui8DATA(data, pDescr->i) = ElementCount;
1362 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
1363 pDescr++;
1364 break;
1365 }
1366
1367 case CSN_FIXED:
1368 { /* Verify the fixed bits */
1369 guint8 no_of_bits = (guint8) pDescr->i;
1370 guint32 ui32;
1371
1372 if (no_of_bits <= 32)
1373 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001374 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001375 }
1376 else
1377 {
1378 return ProcessError(readIndex,"no_of_bits > 32", -1, pDescr);
1379 }
1380 if (ui32 != (unsigned)(gint32)pDescr->offset)
1381 {
1382 return ProcessError(readIndex,"csnStreamDecoder FIXED value does not match", -1, pDescr);
1383 }
1384
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001385 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)ui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001386 remaining_bits_len -= no_of_bits;
1387 bit_offset += no_of_bits;
1388 pDescr++;
1389 break;
1390 }
1391
1392 case CSN_CALLBACK:
1393 {
1394 return ProcessError(readIndex,"csnStreamDecoder Callback not implemented", -1, pDescr);
1395 break;
1396 }
1397
1398 case CSN_TRAP_ERROR:
1399 {
1400 return ProcessError(readIndex,"csnStreamDecoder", pDescr->i, pDescr);
1401 }
1402
1403 case CSN_END:
1404 {
1405 ar->remaining_bits_len = remaining_bits_len;
1406 ar->bit_offset = bit_offset;
1407 return remaining_bits_len;
1408 }
1409
1410 default:
1411 {
1412 assert(0);
1413 }
1414
1415
1416 }
1417
1418 } while (remaining_bits_len >= 0);
1419
1420 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1421}
1422
1423
1424
1425
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001426gint16 csnStreamEncoder(csnStream_t* ar, const CSN_DESCR* pDescr, bitvec *vector, unsigned& writeIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001427{
1428 gint remaining_bits_len = ar->remaining_bits_len;
1429 gint bit_offset = ar->bit_offset;
1430 guint8* pui8;
1431 guint16* pui16;
1432 guint32* pui32;
1433 guint64* pui64;
1434
1435 guint8 Tag = STANDARD_TAG;
1436
1437 if (remaining_bits_len <= 0)
1438 {
1439 return 0;
1440 }
1441
1442 do
1443 {
1444 switch (pDescr->type)
1445 {
1446 case CSN_BIT:
1447 {
1448 if (remaining_bits_len > 0)
1449 {
1450 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001451 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001452 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001453 /* end add the bit value to protocol tree */
1454 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001455 else if(pDescr->may_be_null)
1456 {
1457 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
1458 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001459 else
1460 {
1461 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1462 }
1463
1464 pDescr++;
1465 remaining_bits_len--;
1466 bit_offset++;
1467 break;
1468 }
1469
1470 case CSN_NULL:
1471 { /* Empty member! */
1472 pDescr++;
1473 break;
1474 }
1475
1476 case CSN_UINT:
1477 {
1478 guint8 no_of_bits = (guint8) pDescr->i;
1479
1480 if (remaining_bits_len >= no_of_bits)
1481 {
1482 if (no_of_bits <= 8)
1483 {
1484 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001485 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001486 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001487 }
1488 else if (no_of_bits <= 16)
1489 {
1490 pui16 = pui16DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001491 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001492 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001493 }
1494 else if (no_of_bits <= 32)
1495 {
1496 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001497 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001498 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001499 }
1500 else
1501 {
1502 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1503 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001504
1505 remaining_bits_len -= no_of_bits;
1506 bit_offset += no_of_bits;
1507 }
1508 else if(pDescr->may_be_null)
1509 {
1510 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001511 }
1512 else
1513 {
1514 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1515 }
1516
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001517 pDescr++;
1518 break;
1519 }
1520
1521 case CSN_UINT_OFFSET:
1522 {
1523 guint8 no_of_bits = (guint8) pDescr->i;
1524
1525 if (remaining_bits_len >= no_of_bits)
1526 {
1527 if (no_of_bits <= 8)
1528 {
1529 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001530 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001531 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001532 }
1533 else if (no_of_bits <= 16)
1534 {
1535 pui16 = pui16DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001536 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001537 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001538 }
1539 else if (no_of_bits <= 32)
1540 {
1541 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001542 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001543 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001544 }
1545 else
1546 {
1547 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1548 }
1549 }
1550 else
1551 {
1552 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1553 }
1554
1555 remaining_bits_len -= no_of_bits;
1556 bit_offset += no_of_bits;
1557 pDescr++;
1558 break;
1559 }
1560
1561 case CSN_UINT_LH:
1562 {
1563 guint8 no_of_bits = (guint8) pDescr->i;
1564
1565 if (remaining_bits_len >= no_of_bits)
1566 {
1567 remaining_bits_len -= no_of_bits;
1568 if (no_of_bits <= 8)
1569 {
1570 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001571 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001572 // TODO : Change get_masked_bits8()
1573 writeIndex -= no_of_bits;
1574 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
1575 writeIndex -= no_of_bits;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001576 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001577 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001578
1579 }
1580 else
1581 {/* Maybe we should support more than 8 bits ? */
1582 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1583 }
1584 }
1585 else
1586 {
1587 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1588 }
1589
1590 remaining_bits_len -= no_of_bits;
1591 bit_offset += no_of_bits;
1592 pDescr++;
1593 break;
1594 }
1595
1596 case CSN_UINT_ARRAY:
1597 {
1598 guint8 no_of_bits = (guint8) pDescr->i;
1599 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
1600
1601 if (pDescr->serialize.value != 0)
1602 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
1603 nCount = *pui16DATA(data, nCount);
1604 }
1605
1606 if (remaining_bits_len >= no_of_bits)
1607 {
1608 remaining_bits_len -= (no_of_bits*nCount);
1609 if (no_of_bits <= 8)
1610 {
1611 pui8 = pui8DATA(data, pDescr->offset);
1612 do
1613 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001614 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
1615 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001616 pui8++;
1617 bit_offset += no_of_bits;
1618 } while (--nCount > 0);
1619 }
1620 else if (no_of_bits <= 16)
1621 {
1622 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1623 }
1624 else if (no_of_bits <= 32)
1625 {
1626 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1627 }
1628 else
1629 {
1630 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1631 }
1632 }
1633 else
1634 {
1635 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1636 }
1637 pDescr++;
1638 break;
1639 }
1640
1641 case CSN_VARIABLE_TARRAY_OFFSET:
1642 case CSN_VARIABLE_TARRAY:
1643 case CSN_TYPE_ARRAY:
1644 {
1645 gint16 Status;
1646 csnStream_t arT = *ar;
1647 gint16 nCount = pDescr->i;
1648 guint16 nSize = (guint16)(gint32)pDescr->serialize.value;
1649
1650 pui8 = pui8DATA(data, pDescr->offset);
1651 if (pDescr->type == CSN_VARIABLE_TARRAY)
1652 { /* Count specified in field */
1653 nCount = *pui8DATA(data, pDescr->i);
1654 }
1655 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
1656 { /* Count specified in field */
1657 nCount = *pui8DATA(data, pDescr->i);
1658 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
1659 }
1660
1661 while (nCount > 0)
1662 { /* resulting array of length 0 is possible
1663 * but no bits shall be read from bitstream
1664 */
1665
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001666 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001667 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1668 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
1669 if (Status >= 0)
1670 {
1671 pui8 += nSize;
1672 remaining_bits_len = arT.remaining_bits_len;
1673 bit_offset = arT.bit_offset;
1674
1675 }
1676 else
1677 {
1678 return Status;
1679 }
1680 nCount--;
1681 }
1682
1683 pDescr++;
1684 break;
1685 }
1686
1687 case CSN_BITMAP:
1688 { /* bitmap with given length. The result is left aligned! */
1689 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
1690
1691 if (no_of_bits > 0)
1692 {
1693
1694 if (no_of_bits <= 32)
1695 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001696 for(unsigned ib = 0; ib < 4; ib++)
1697 {
1698 pui8 = pui8DATA(data, pDescr->offset+ib);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001699 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001700 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001701 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001702 }
1703 else if (no_of_bits <= 64)
1704 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001705 for(unsigned ib = 0; ib < 8; ib++)
1706 {
1707 pui8 = pui8DATA(data, pDescr->offset+ib);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001708 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001709 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001710 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001711 }
1712 else
1713 {
1714 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
1715 }
1716
1717 remaining_bits_len -= no_of_bits;
1718 assert(remaining_bits_len >= 0);
1719 bit_offset += no_of_bits;
1720 }
1721 /* bitmap was successfully extracted or it was empty */
1722
1723 pDescr++;
1724 break;
1725 }
1726
1727 case CSN_TYPE:
1728 {
1729 gint16 Status;
1730 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001731 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001732 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1733 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001734 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001735 if (Status >= 0)
1736 {
1737
1738 remaining_bits_len = arT.remaining_bits_len;
1739 bit_offset = arT.bit_offset;
1740 pDescr++;
1741 }
1742 else
1743 {
1744 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
1745 return Status;
1746 }
1747
1748 break;
1749 }
1750
1751 case CSN_CHOICE:
1752 {
1753 //gint16 count = pDescr->i;
1754 guint8 i = 0;
1755 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
1756
1757 pui8 = pui8DATA(data, pDescr->offset);
1758 i = *pui8;
1759 pChoice += i;
1760 guint8 no_of_bits = pChoice->bits;
1761 guint8 value = pChoice->value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001762 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pChoice->descr.sz , (unsigned)value);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001763 bitvec_write_field(vector, writeIndex, value, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001764
1765 CSN_DESCR descr[2];
1766 gint16 Status;
1767 csnStream_t arT = *ar;
1768
1769 descr[0] = pChoice->descr;
1770 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
1771 descr[1].type = CSN_END;
1772 bit_offset += no_of_bits;
1773 remaining_bits_len -= no_of_bits;
1774
1775 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1776 Status = csnStreamEncoder(&arT, descr, vector, writeIndex, data);
1777
1778 if (Status >= 0)
1779 {
1780 remaining_bits_len = arT.remaining_bits_len;
1781 bit_offset = arT.bit_offset;
1782 }
1783 else
1784 {
1785 return Status;
1786 }
1787
1788 pDescr++;
1789 break;
1790 }
1791
1792 case CSN_SERIALIZE:
1793 {
1794 StreamSerializeFcn_t serialize = pDescr->serialize.fcn;
1795 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001796 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001797 gint16 Status = -1;
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001798 unsigned lengthIndex;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001799
1800 // store writeIndex for length value (7 bit)
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001801 lengthIndex = writeIndex;
1802 writeIndex += length_len;
1803 bit_offset += length_len;
1804 remaining_bits_len -= length_len;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001805 arT.direction = 0;
1806 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1807 Status = serialize(&arT, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001808
1809 bitvec_write_field(vector, lengthIndex, writeIndex-lengthIndex-length_len, length_len);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001810 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %u | ", pDescr->sz , (unsigned)(writeIndex-lengthIndex));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001811
1812 if (Status >= 0)
1813 {
1814 remaining_bits_len = arT.remaining_bits_len;
1815 bit_offset = arT.bit_offset;
1816 pDescr++;
1817 }
1818 else
1819 {
1820 // Has already been processed:
1821 return Status;
1822 }
1823
1824 break;
1825 }
1826
1827 case CSN_UNION_LH:
1828 case CSN_UNION:
1829 {
1830 gint16 Bits;
1831 guint8 index;
1832 gint16 count = pDescr->i;
1833 const CSN_DESCR* pDescrNext = pDescr;
1834
1835 pDescrNext += count + 1; /* now this is next after the union */
1836 if ((count <= 0) || (count > 16))
1837 {
1838 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
1839 }
1840
1841 /* Now get the bits to extract the index */
1842 Bits = ixBitsTab[count];
1843 index = 0;
1844
1845 /* Assign UnionType */
1846 pui8 = pui8DATA(data, pDescr->offset);
1847 //read index from data and write to vector
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001848 bitvec_write_field(vector, writeIndex, *pui8, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001849
1850 //decode index
1851 writeIndex -= Bits;
1852
1853 while (Bits > 0)
1854 {
1855 index <<= 1;
1856
1857 if (CSN_UNION_LH == pDescr->type)
1858 {
1859 index |= get_masked_bits8(vector,writeIndex, bit_offset, 1);
1860 }
1861 else
1862 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001863 index |= bitvec_read_field(vector, writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001864 }
1865
1866 remaining_bits_len--;
1867 bit_offset++;
1868 Bits--;
1869 }
1870
1871 writeIndex -= Bits;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001872 bitvec_write_field(vector, writeIndex, index, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001873
1874
1875 /* script index to continue on, limited in case we do not have a power of 2 */
1876 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001877 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)index);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001878
1879 switch (pDescr->type)
1880 { /* get the right element of the union based on computed index */
1881
1882 case CSN_BIT:
1883 {
1884 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001885 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001886 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001887 remaining_bits_len -= 1;
1888 bit_offset++;
1889 pDescr++;
1890 break;
1891 }
1892
1893 case CSN_NULL:
1894 { /* Empty member! */
1895 pDescr++;
1896 break;
1897 }
1898
1899 case CSN_UINT:
1900 {
1901 guint8 no_of_bits = (guint8) pDescr->i;
1902 if (remaining_bits_len >= no_of_bits)
1903 {
1904 remaining_bits_len -= no_of_bits;
1905
1906 if (no_of_bits <= 8)
1907 {
1908 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001909 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001910 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001911 }
1912 else if (no_of_bits <= 16)
1913 {
1914 pui16 = pui16DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001915 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001916 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001917 }
1918 else if (no_of_bits <= 32)
1919 {
1920 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001921 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001922 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001923 }
1924 else
1925 {
1926 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1927 }
1928 }
1929 else
1930 {
1931 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1932 }
1933
1934 bit_offset += no_of_bits;
1935 pDescr++;
1936 break;
1937 }
1938
1939 case CSN_UINT_OFFSET:
1940 {
1941 guint8 no_of_bits = (guint8) pDescr->i;
1942
1943 if (remaining_bits_len >= no_of_bits)
1944 {
1945 if (no_of_bits <= 8)
1946 {
1947 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001948 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001949 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001950 }
1951 else if (no_of_bits <= 16)
1952 {
1953 pui16 = pui16DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001954 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001955 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001956 }
1957 else if (no_of_bits <= 32)
1958 {
1959 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001960 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001961 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001962 }
1963 else
1964 {
1965 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1966 }
1967 }
1968 else
1969 {
1970 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1971 }
1972
1973 remaining_bits_len -= no_of_bits;
1974 bit_offset += no_of_bits;
1975 pDescr++;
1976 break;
1977 }
1978
1979 case CSN_UINT_LH:
1980 {
1981 guint8 no_of_bits = (guint8) pDescr->i;
1982
1983 if (remaining_bits_len >= no_of_bits)
1984 {
1985 remaining_bits_len -= no_of_bits;
1986 if (no_of_bits <= 8)
1987 {
1988 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001989 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001990 // TODO : Change get_masked_bits8()
1991 writeIndex -= no_of_bits;
1992 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
1993 writeIndex -= no_of_bits;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001994 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001995 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001996
1997 }
1998 else
1999 {/* Maybe we should support more than 8 bits ? */
2000 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2001 }
2002 }
2003 else
2004 {
2005 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2006 }
2007
2008 remaining_bits_len -= no_of_bits;
2009 bit_offset += no_of_bits;
2010 pDescr++;
2011 break;
2012 }
2013
2014 case CSN_UINT_ARRAY:
2015 {
2016 guint8 no_of_bits = (guint8) pDescr->i;
2017 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
2018
2019 if (pDescr->serialize.value != 0)
2020 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
2021 nCount = *pui16DATA(data, nCount);
2022 }
2023
2024 if (remaining_bits_len >= no_of_bits)
2025 {
2026 remaining_bits_len -= (no_of_bits*nCount);
2027 if (no_of_bits <= 8)
2028 {
2029 pui8 = pui8DATA(data, pDescr->offset);
2030 do
2031 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002032 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
2033 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002034 pui8++;
2035 bit_offset += no_of_bits;
2036 } while (--nCount > 0);
2037 }
2038 else if (no_of_bits <= 16)
2039 {
2040 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2041 }
2042 else if (no_of_bits <= 32)
2043 {
2044 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2045 }
2046 else
2047 {
2048 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2049 }
2050 }
2051 else
2052 {
2053 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2054 }
2055 pDescr++;
2056 break;
2057 }
2058
2059 case CSN_VARIABLE_TARRAY_OFFSET:
2060 case CSN_VARIABLE_TARRAY:
2061 case CSN_TYPE_ARRAY:
2062 {
2063 gint16 Status;
2064 csnStream_t arT = *ar;
2065 gint16 nCount = pDescr->i;
2066 guint16 nSize = (guint16)(gint32)pDescr->serialize.value;
2067
2068 pui8 = pui8DATA(data, pDescr->offset);
2069 if (pDescr->type == CSN_VARIABLE_TARRAY)
2070 { /* Count specified in field */
2071 nCount = *pui8DATA(data, pDescr->i);
2072 }
2073 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
2074 { /* Count specified in field */
2075 nCount = *pui8DATA(data, pDescr->i);
2076 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
2077 }
2078
2079 while (nCount > 0)
2080 { /* resulting array of length 0 is possible
2081 * but no bits shall be read from bitstream
2082 */
2083
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002084 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002085 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2086 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
2087 if (Status >= 0)
2088 {
2089 pui8 += nSize;
2090 remaining_bits_len = arT.remaining_bits_len;
2091 bit_offset = arT.bit_offset;
2092 }
2093 else
2094 {
2095 return Status;
2096 }
2097 nCount--;
2098 }
2099
2100 pDescr++;
2101 break;
2102 }
2103
2104 case CSN_BITMAP:
2105 { /* bitmap with given length. The result is left aligned! */
2106 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
2107
2108 if (no_of_bits > 0)
2109 {
2110
2111 if (no_of_bits <= 32)
2112 {
2113 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002114 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002115 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002116 }
2117 else if (no_of_bits <= 64)
2118 {
2119 pui64 = pui64DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002120 bitvec_write_field(vector, writeIndex, *pui64, no_of_bits);
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +02002121 LOGPC(DCSN1, LOGL_NOTICE, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002122 }
2123 else
2124 {
2125 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
2126 }
2127
2128 remaining_bits_len -= no_of_bits;
2129 assert(remaining_bits_len >= 0);
2130 bit_offset += no_of_bits;
2131 }
2132 /* bitmap was successfully extracted or it was empty */
2133
2134 pDescr++;
2135 break;
2136 }
2137
2138 case CSN_TYPE:
2139 {
2140 gint16 Status;
2141 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002142 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002143 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2144 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002145 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002146 if (Status >= 0)
2147 {
2148 remaining_bits_len = arT.remaining_bits_len;
2149 bit_offset = arT.bit_offset;
2150 pDescr++;
2151 }
2152 else
2153 {
2154 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
2155 return Status;
2156 }
2157
2158 break;
2159 }
2160
2161 default:
2162 { /* descriptions of union elements other than above are illegal */
2163 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
2164 }
2165 }
2166
2167 pDescr = pDescrNext;
2168 break;
2169 }
2170
2171 case CSN_EXIST:
2172 case CSN_EXIST_LH:
2173 {
2174 guint8 fExist;
2175 unsigned exist = 0;
2176 pui8 = pui8DATA(data, pDescr->offset);
2177 exist = *pui8;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002178 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002179 writeIndex--;
2180 if (CSN_EXIST_LH == pDescr->type)
2181 {
2182 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
2183 }
2184 else
2185 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002186 fExist = bitvec_read_field(vector, writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002187 }
2188 writeIndex--;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002189 bitvec_write_field(vector, writeIndex, fExist, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002190 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz, (unsigned)fExist);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002191 pDescr++;
2192 remaining_bits_len -= 1;
2193
2194 if (!exist)
2195 {
2196 ar->remaining_bits_len = remaining_bits_len;
2197 ar->bit_offset = bit_offset;
2198 return remaining_bits_len;
2199 }
2200 break;
2201 }
2202
2203 case CSN_NEXT_EXIST:
2204 {
2205 guint8 fExist;
2206
2207 pui8 = pui8DATA(data, pDescr->offset);
2208
2209 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002210 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002211 { /* no more bits to decode is fine here - end of message detected and allowed */
2212
2213 /* Skip i entries + this entry */
2214 pDescr += pDescr->i + 1;
2215
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002216 break;
2217 }
2218
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002219 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002220 fExist = *pui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002221 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002222 remaining_bits_len -= 1;
2223
2224 ++bit_offset;
2225
2226 if (fExist == 0)
2227 { /* Skip 'i' entries */
2228 pDescr += pDescr->i;
2229 }
2230
2231 pDescr++;
2232 break;
2233 }
2234
2235 case CSN_NEXT_EXIST_LH:
2236 {
2237 guint8 fExist;
2238 pui8 = pui8DATA(data, pDescr->offset);
2239
2240 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
2241 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
2242 { /* no more bits to decode is fine here - end of message detected and allowed */
2243
2244 /* skip 'i' entries + this entry */
2245 pDescr += pDescr->i + 1;
2246
2247 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
2248 if ( pDescr->type != CSN_END )
2249 { /* substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
2250 remaining_bits_len--;
2251 }
2252
2253 /* set the data member to "not exist" */
2254 //*pui8 = 0;
2255 break;
2256 }
2257
2258 /* the "regular" M_NEXT_EXIST_LH description element */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002259 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002260 writeIndex--;
2261 fExist = get_masked_bits8(vector,writeIndex, bit_offset, 1);
2262 writeIndex--;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002263 bitvec_write_field(vector, writeIndex, fExist, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002264 pui8++;
2265 remaining_bits_len -= 1;
2266
2267 bit_offset++;
2268
2269 if (fExist == 0)
2270 { /* Skip 'i' entries */
2271 pDescr += pDescr->i;
2272 }
2273 pDescr++;
2274
2275 break;
2276 }
2277
2278 case CSN_VARIABLE_BITMAP_1:
2279 { /* Bitmap from here and to the end of message */
2280
2281 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2282
2283 /*no break -
2284 * with a length set we have a regular variable length bitmap so we continue */
2285 }
2286
2287 case CSN_VARIABLE_BITMAP:
2288 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2289 * <N: bit (5)> <bitmap: bit(N + offset)>
2290 * Bit array with length (in bits) specified in parameter (pDescr->descr)
2291 * The result is right aligned!
2292 */
2293 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
2294
2295 no_of_bits += pDescr->i; /* adjusted by offset */
2296
2297 if (no_of_bits > 0)
2298 {
2299 remaining_bits_len -= no_of_bits;
2300
2301 if (remaining_bits_len < 0)
2302 {
2303 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2304 }
2305
2306 { /* extract bits */
2307 guint8* pui8 = pui8DATA(data, pDescr->offset);
2308 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2309
2310 if (nB1 > 0)
2311 { /* take care of the first byte - it will be right aligned */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002312 bitvec_write_field(vector, writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002313 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002314 pui8++;
2315 no_of_bits -= nB1;
2316 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2317 }
2318
2319 /* remaining no_of_bits is a multiple of 8 or 0 */
2320 while (no_of_bits > 0)
2321 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002322 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002323 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002324 pui8++;
2325 no_of_bits -= 8;
2326 }
2327 }
2328 }
2329 pDescr++;
2330 break;
2331 }
2332
2333 case CSN_LEFT_ALIGNED_VAR_BMP_1:
2334 { /* Bitmap from here and to the end of message */
2335
2336 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2337
2338 /* no break -
2339 * with a length set we have a regular left aligned variable length bitmap so we continue
2340 */
2341 }
2342
2343 case CSN_LEFT_ALIGNED_VAR_BMP:
2344 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2345 * <N: bit (5)> <bitmap: bit(N + offset)>
2346 * bit array with length (in bits) specified in parameter (pDescr->descr)
2347 */
2348
2349 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
2350
2351 no_of_bits += pDescr->i;/* size adjusted by offset */
2352
2353 if (no_of_bits > 0)
2354 {
2355 remaining_bits_len -= no_of_bits;
2356
2357 if (remaining_bits_len < 0)
2358 {
2359 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2360 }
2361
2362 { /* extract bits */
2363 guint8* pui8 = pui8DATA(data, pDescr->offset);
2364 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2365
2366 while (no_of_bits > 0)
2367 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002368 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002369 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002370 pui8++;
2371 no_of_bits -= 8;
2372 }
2373 if (nB1 > 0)
2374 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002375 bitvec_write_field(vector, writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002376 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002377 pui8++;
2378 no_of_bits -= nB1;
2379 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2380 }
2381 }
2382
2383 }
2384
2385 /* bitmap was successfully extracted or it was empty */
2386 pDescr++;
2387 break;
2388 }
2389
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002390 case CSN_PADDING_BITS:
2391 { /* Padding from here and to the end of message */
2392 LOGPC(DCSN1, LOGL_NOTICE, "%s = ", pDescr->sz);
2393 guint8 filler = 0x2b;
2394 if (remaining_bits_len > 0)
2395 {
2396 while (remaining_bits_len > 0)
2397 {
2398 guint8 bits_to_handle = remaining_bits_len%8;
2399 if (bits_to_handle > 0)
2400 {
2401 guint8 fl = filler&(0xff>>(8-bits_to_handle));
2402 bitvec_write_field(vector, writeIndex, fl, bits_to_handle);
2403 LOGPC(DCSN1, LOGL_NOTICE, "%u|", fl);
2404 remaining_bits_len -= bits_to_handle;
2405 bit_offset += bits_to_handle;
2406 }
2407 else if (bits_to_handle == 0)
2408 {
2409 bitvec_write_field(vector, writeIndex, filler, 8);
2410 LOGPC(DCSN1, LOGL_NOTICE, "%u|", filler);
2411 remaining_bits_len -= 8;
2412 bit_offset += 8;
2413 }
2414 }
2415 }
2416 if (remaining_bits_len < 0)
2417 {
2418 return ProcessError(writeIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2419 }
2420
2421 /* Padding was successfully extracted or it was empty */
2422 pDescr++;
2423 break;
2424 }
2425
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002426 case CSN_VARIABLE_ARRAY:
2427 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
2428 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2429 * Array with length specified in parameter:
2430 * <count: bit (x)>
2431 * <list: octet(count + offset)>
2432 */
2433 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
2434
2435 count += pDescr->i; /* Adjusted by offset */
2436
2437 if (count > 0)
2438 {
2439 remaining_bits_len -= count * 8;
2440
2441 if (remaining_bits_len < 0)
2442 {
2443 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2444 }
2445
2446 pui8 = pui8DATA(data, pDescr->offset);
2447
2448 while (count > 0)
2449 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002450 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002451 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002452 pui8++;
2453 bit_offset += 8;
2454 count--;
2455 }
2456 }
2457
2458 pDescr++;
2459 break;
2460 }
2461
2462 case CSN_RECURSIVE_ARRAY:
2463 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
2464 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
2465 * where <element> ::= bit(value)
2466 * <tag> ::= 0 | 1
2467 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
2468 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2469 * REMARK: recursive way to specify an array but an iterative implementation!
2470 */
2471 gint16 no_of_bits = pDescr->i;
2472 guint8 ElementCount = 0;
2473 pui8 = pui8DATA(data, pDescr->offset);
2474 ElementCount = *pui8DATA(data, (gint16)pDescr->descr.value);
2475 while (ElementCount > 0)
2476 { /* tag control shows existence of next list elements */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002477 bitvec_write_field(vector, writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002478 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002479 bit_offset++;
2480 remaining_bits_len--;
2481
2482 /* extract and store no_of_bits long element from bitstream */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002483 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002484 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002485 pui8++;
2486 remaining_bits_len -= no_of_bits;
2487 ElementCount--;
2488
2489 if (remaining_bits_len < 0)
2490 {
2491 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2492 }
2493
2494 bit_offset += no_of_bits;
2495 }
2496
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002497 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002498 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002499 bit_offset++;
2500
2501 pDescr++;
2502 break;
2503 }
2504
2505 case CSN_RECURSIVE_TARRAY:
2506 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
2507 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2508 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2509 */
2510 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
2511 guint8 ElementCount = 0;
2512 pui8 = pui8DATA(data, pDescr->offset);
2513 /* Store the counted number of elements of the array */
2514 ElementCount = *pui8DATA(data, (gint16)(gint32)pDescr->i);
2515
2516 while (ElementCount > 0)
2517 { /* tag control shows existence of next list elements */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002518 bitvec_write_field(vector, writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002519 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002520 bit_offset++;
2521
2522 remaining_bits_len--;
2523 ElementCount--;
2524
2525 { /* unpack the following data structure */
2526 csnStream_t arT = *ar;
2527 gint16 Status;
2528 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002529 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002530
2531 if (Status >= 0)
2532 { /* successful completion */
2533 pui8 += nSizeElement; /* -> to next data element */
2534 remaining_bits_len = arT.remaining_bits_len;
2535 bit_offset = arT.bit_offset;
2536 }
2537 else
2538 { /* something went awry */
2539 return Status;
2540 }
2541 }
2542
2543 if (remaining_bits_len < 0)
2544 {
2545 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2546 }
2547 }
2548
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002549 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002550 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002551 bit_offset++;
2552
2553 pDescr++;
2554 break;
2555 }
2556
2557 case CSN_RECURSIVE_TARRAY_2:
2558 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
2559
2560 Tag = REVERSED_TAG;
2561
2562 /* NO break -
2563 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
2564 */
2565 }
2566
2567 case CSN_RECURSIVE_TARRAY_1:
2568 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
2569 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2570 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2571 */
2572 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
2573 guint8 ElementCount = 0;
2574 guint8 ElementNum = 0;
2575 csnStream_t arT = *ar;
2576 gint16 Status;
2577
2578 pui8 = pui8DATA(data, pDescr->offset);
2579 /* Store the count of the array */
2580 ElementCount = *pui8DATA(data, pDescr->i);
2581 ElementNum = ElementCount;
2582
2583 while (ElementCount > 0)
2584 { /* get data element */
2585 if (ElementCount != ElementNum)
2586 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002587 bitvec_write_field(vector, writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002588 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002589 bit_offset++;
2590 remaining_bits_len--;
2591 }
2592 ElementCount--;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002593 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002594 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002595 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002596 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002597 if (Status >= 0)
2598 { /* successful completion */
2599 pui8 += nSizeElement; /* -> to next */
2600 remaining_bits_len = arT.remaining_bits_len;
2601 bit_offset = arT.bit_offset;
2602 }
2603 else
2604 { /* something went awry */
2605 return Status;
2606 }
2607
2608 if (remaining_bits_len < 0)
2609 {
2610 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2611 }
2612
2613 }
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002614 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002615 bit_offset++;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002616 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002617 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
2618 pDescr++;
2619 break;
2620 }
2621
2622 case CSN_FIXED:
2623 { /* Verify the fixed bits */
2624 guint8 no_of_bits = (guint8) pDescr->i;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002625 bitvec_write_field(vector, writeIndex, pDescr->offset, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002626 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002627 remaining_bits_len -= no_of_bits;
2628 bit_offset += no_of_bits;
2629 pDescr++;
2630 break;
2631 }
2632
2633 case CSN_CALLBACK:
2634 {
2635 return ProcessError(writeIndex,"csnStreamEncoder Callback not implemented", -1, pDescr);
2636 break;
2637 }
2638
2639 case CSN_TRAP_ERROR:
2640 {
2641 return ProcessError(writeIndex,"csnStreamEncoder", pDescr->i, pDescr);
2642 }
2643
2644 case CSN_END:
2645 {
2646 ar->remaining_bits_len = remaining_bits_len;
2647 ar->bit_offset = bit_offset;
2648 return remaining_bits_len;
2649 }
2650
2651 default:
2652 {
2653 assert(0);
2654 }
2655
2656 }
2657
2658 } while (remaining_bits_len >= 0);
2659
2660 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2661}
2662