blob: 1859bebd950dfc7ad3914a5d5145d5de7a0086bb [file] [log] [blame]
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001/* csn1.cpp
2 * Routines for CSN1 dissection in wireshark.
3 *
4 * Copyright (C) 2011 Ivan Klyuchnikov
5 *
6 * By Vincent Helfre, based on original code by Jari Sassi
7 * with the gracious authorization of STE
8 * Copyright (c) 2011 ST-Ericsson
9 *
10 * $Id: packet-csn1.c 39140 2011-09-25 22:01:50Z wmeier $
11 *
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */
30
31#include <iostream>
32#include <cstdlib>
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +040033#include <assert.h>
34#include <string.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030035#include "csn1.h"
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +040036#include <gprs_debug.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030037
38
39#define pvDATA(_pv, _offset) ((void*) ((unsigned char*)_pv + _offset))
40#define pui8DATA(_pv, _offset) ((guint8*) pvDATA(_pv, _offset))
41#define pui16DATA(_pv, _offset) ((guint16*) pvDATA(_pv, _offset))
42#define pui32DATA(_pv, _offset) ((guint32*) pvDATA(_pv, _offset))
43#define pui64DATA(_pv, _offset) ((guint64*) pvDATA(_pv, _offset))
44/* used to tag existence of next element in variable length lists */
45#define STANDARD_TAG 1
46#define REVERSED_TAG 0
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030047
48using namespace std;
49static const unsigned char ixBitsTab[] = {0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5};
50
51
52/* Returns no_of_bits (up to 8) masked with 0x2B */
53
54static guint8
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +040055get_masked_bits8( bitvec *vector, unsigned& readIndex, gint bit_offset, const gint no_of_bits)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030056{
57 static const guint8 maskBits[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
58 //gint byte_offset = bit_offset >> 3; /* divide by 8 */
59 gint relative_bit_offset = bit_offset & 0x07; /* modulo 8 */
60 guint8 result;
61 gint bit_shift = 8 - relative_bit_offset - (gint) no_of_bits;
62 readIndex -= relative_bit_offset;
63 if (bit_shift >= 0)
64 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +040065 result = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) >> bit_shift;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030066 readIndex-= bit_shift;
67 result &= maskBits[no_of_bits];
68 }
69 else
70 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +040071 guint8 hight_part = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) & maskBits[8 - relative_bit_offset];
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030072 hight_part = (guint8) (hight_part << (-bit_shift));
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +040073 result = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) >> (8 + bit_shift);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030074 readIndex = readIndex - (8 - (-bit_shift));
75 result |= hight_part;
76 }
77 return result;
78}
79
80/**
81 * ================================================================================================
82 * set initial/start values in help data structure used for packing/unpacking operation
83 * ================================================================================================
84 */
85void
86csnStreamInit(csnStream_t* ar, gint bit_offset, gint remaining_bits_len)
87{
88 ar->remaining_bits_len = remaining_bits_len;
89 ar->bit_offset = bit_offset;
90}
91
92static const char* ErrCodes[] =
93{
94 "General 0",
95 "General -1",
96 "DATA_NOT VALID",
97 "IN SCRIPT",
98 "INVALID UNION INDEX",
99 "NEED_MORE BITS TO UNPACK",
100 "ILLEGAL BIT VALUE",
101 "Internal",
102 "STREAM_NOT_SUPPORTED",
103 "MESSAGE_TOO_LONG"
104};
105
106static gint16
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400107ProcessError( unsigned readIndex, const char* sz, gint16 err, const CSN_DESCR* pDescr)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300108{
109 gint16 i = MIN(-err, ((gint16) ElementsOf(ErrCodes)-1));
110 if (i >= 0)
111 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400112 //LOG(ERR) << sz << "Error code: "<< ErrCodes[i] << pDescr?(pDescr->sz):"-";
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300113 }
114 else
115 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400116 //LOG(ERR) << sz << ": " << pDescr?(pDescr->sz):"-";
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300117 }
118 return err;
119}
120
121//#if 0
122static const char* CSN_DESCR_type[]=
123{
124 "CSN_END",
125 "CSN_BIT",
126 "CSN_UINT",
127 "CSN_TYPE",
128 "CSN_CHOICE",
129 "CSN_UNION",
130 "CSN_UNION_LH",
131 "CSN_UINT_ARRAY",
132 "CSN_TYPE_ARRAY",
133 "CSN_BITMAP",
134 "CSN_VARIABLE_BITMAP",
135 "CSN_VARIABLE_BITMAP_1",
136 "CSN_LEFT_ALIGNED_VAR_BMP",
137 "CSN_LEFT_ALIGNED_VAR_BMP_1",
138 "CSN_VARIABLE_ARRAY",
139 "CSN_VARIABLE_TARRAY",
140 "CSN_VARIABLE_TARRAY_OFFSET",
141 "CSN_RECURSIVE_ARRAY",
142 "CSN_RECURSIVE_TARRAY",
143 "CSN_RECURSIVE_TARRAY_1",
144 "CSN_RECURSIVE_TARRAY_2",
145 "CSN_EXIST",
146 "CSN_EXIST_LH",
147 "CSN_NEXT_EXIST",
148 "CSN_NEXT_EXIST_LH",
149 "CSN_NULL",
150 "CSN_FIXED",
151 "CSN_CALLBACK",
152 "CSN_UINT_OFFSET",
153 "CSN_UINT_LH",
154 "CSN_SERIALIZE",
155 "CSN_TRAP_ERROR"
156 "CSN_???"
157};
158//#endif
159
160/**
161 * ================================================================================================
162 * Return TRUE if tag in bit stream indicates existence of next list element,
163 * otherwise return FALSE.
164 * Will work for tag values equal to both 0 and 1.
165 * ================================================================================================
166 */
167
168static gboolean
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400169existNextElement(bitvec *vector, unsigned& readIndex, guint8 Tag)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300170{
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400171 guint8 res = bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300172 if (Tag == STANDARD_TAG)
173 {
174 return (res > 0);
175 }
176 return (res == 0);
177}
178
179
180gint16
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400181csnStreamDecoder(csnStream_t* ar, const CSN_DESCR* pDescr, bitvec *vector, unsigned& readIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300182{
183 gint remaining_bits_len = ar->remaining_bits_len;
184 gint bit_offset = ar->bit_offset;
185 guint8* pui8;
186 guint16* pui16;
187 guint32* pui32;
188 guint64* pui64;
189 guint8 Tag = STANDARD_TAG;
190
191 if (remaining_bits_len <= 0)
192 {
193 return 0;
194 }
195
196 do
197 {
198 switch (pDescr->type)
199 {
200 case CSN_BIT:
201 {
202 if (remaining_bits_len > 0)
203 {
204 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400205 *pui8 = bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400206 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300207 /* end add the bit value to protocol tree */
208 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400209 else if(pDescr->may_be_null)
210 {
211 pui8 = pui8DATA(data, pDescr->offset);
212 *pui8 = 0;
213 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
214 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300215 else
216 {
217 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
218 }
219
220 pDescr++;
221 remaining_bits_len--;
222 bit_offset++;
223 break;
224 }
225
226 case CSN_NULL:
227 { /* Empty member! */
228 pDescr++;
229 break;
230 }
231
232 case CSN_UINT:
233 {
234 guint8 no_of_bits = (guint8) pDescr->i;
235
236 if (remaining_bits_len >= no_of_bits)
237 {
238 if (no_of_bits <= 8)
239 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400240 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300241 pui8 = pui8DATA(data, pDescr->offset);
242 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400243 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300244 }
245 else if (no_of_bits <= 16)
246 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400247 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300248 pui16 = pui16DATA(data, pDescr->offset);
249 *pui16 = ui16;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400250 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300251 }
252 else if (no_of_bits <= 32)
253 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400254 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300255 pui32 = pui32DATA(data, pDescr->offset);
256 *pui32 = ui32;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400257 LOGPC(DCSN1, LOGL_NOTICE, "%s = 0x%08x | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300258 }
259 else
260 {
261 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
262 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400263 remaining_bits_len -= no_of_bits;
264 bit_offset += no_of_bits;
265 }
266 else if(pDescr->may_be_null)
267 {
268 if (no_of_bits <= 8)
269 {
270 pui8 = pui8DATA(data, pDescr->offset);
271 *pui8 = 0;
272 }
273 else if (no_of_bits <= 16)
274 {
275 pui16 = pui16DATA(data, pDescr->offset);
276 *pui16 = 0;
277 }
278 else if (no_of_bits <= 32)
279 {
280 pui32 = pui32DATA(data, pDescr->offset);
281 *pui32 = 0;
282 }
283 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300284 }
285 else
286 {
287 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
288 }
289
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300290 pDescr++;
291 break;
292 }
293
294 case CSN_UINT_OFFSET:
295 {
296 guint8 no_of_bits = (guint8) pDescr->i;
297
298 if (remaining_bits_len >= no_of_bits)
299 {
300 if (no_of_bits <= 8)
301 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400302 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300303 pui8 = pui8DATA(data, pDescr->offset);
304 *pui8 = ui8 + (guint8)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400305 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300306 }
307 else if (no_of_bits <= 16)
308 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400309 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300310 pui16 = pui16DATA(data, pDescr->offset);
311 *pui16 = ui16 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400312 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300313 }
314 else if (no_of_bits <= 32)
315 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400316 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300317 pui32 = pui32DATA(data, pDescr->offset);
318 *pui32 = ui32 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400319 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300320 }
321 else
322 {
323 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
324 }
325 }
326 else
327 {
328 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
329 }
330
331 remaining_bits_len -= no_of_bits;
332 bit_offset += no_of_bits;
333 pDescr++;
334 break;
335 }
336
337 case CSN_UINT_LH:
338 {
339 guint8 no_of_bits = (guint8) pDescr->i;
340
341 if (remaining_bits_len >= no_of_bits)
342 {
343 remaining_bits_len -= no_of_bits;
344 if (no_of_bits <= 8)
345 {
346 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
347 pui8 = pui8DATA(data, pDescr->offset);
348 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400349 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300350 }
351 else
352 {/* Maybe we should support more than 8 bits ? */
353 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
354 }
355 }
356 else
357 {
358 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
359 }
360
361 remaining_bits_len -= no_of_bits;
362 bit_offset += no_of_bits;
363 pDescr++;
364 break;
365 }
366
367 case CSN_UINT_ARRAY:
368 {
369 guint8 no_of_bits = (guint8) pDescr->i;
370 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
371
372 if (pDescr->serialize.value != 0)
373 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
374 nCount = *pui16DATA(data, nCount);
375 }
376
377 if (remaining_bits_len >= no_of_bits)
378 {
379 remaining_bits_len -= (no_of_bits*nCount);
380 if (no_of_bits <= 8)
381 {
382 pui8 = pui8DATA(data, pDescr->offset);
383 do
384 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400385 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400386 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300387 pui8++;
388 bit_offset += no_of_bits;
389 } while (--nCount > 0);
390 }
391 else if (no_of_bits <= 16)
392 {
393 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
394 }
395 else if (no_of_bits <= 32)
396 {
397 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
398 }
399 else
400 {
401 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
402 }
403 }
404 else
405 {
406 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
407 }
408 pDescr++;
409 break;
410 }
411
412 case CSN_VARIABLE_TARRAY_OFFSET:
413 case CSN_VARIABLE_TARRAY:
414 case CSN_TYPE_ARRAY:
415 {
416 gint16 Status;
417 csnStream_t arT = *ar;
418 gint16 nCount = pDescr->i;
419 guint16 nSize = (guint16)(gint32)pDescr->serialize.value;
420
421 pui8 = pui8DATA(data, pDescr->offset);
422 if (pDescr->type == CSN_VARIABLE_TARRAY)
423 { /* Count specified in field */
424 nCount = *pui8DATA(data, pDescr->i);
425 }
426 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
427 { /* Count specified in field */
428 nCount = *pui8DATA(data, pDescr->i);
429 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
430 }
431
432 while (nCount > 0)
433 { /* resulting array of length 0 is possible
434 * but no bits shall be read from bitstream
435 */
436
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400437 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300438 csnStreamInit(&arT, bit_offset, remaining_bits_len);
439 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
440 if (Status >= 0)
441 {
442 pui8 += nSize;
443 remaining_bits_len = arT.remaining_bits_len;
444 bit_offset = arT.bit_offset;
445 }
446 else
447 {
448 return Status;
449 }
450 nCount--;
451 }
452
453 pDescr++;
454 break;
455 }
456
457 case CSN_BITMAP:
458 { /* bitmap with given length. The result is left aligned! */
459 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
460
461 if (no_of_bits > 0)
462 {
463
464 if (no_of_bits <= 32)
465 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400466 for(unsigned ib = 0; ib < 4; ib++)
467 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400468 guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400469 pui8 = pui8DATA(data, pDescr->offset+ib);
470 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400471 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400472 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300473 }
474 else if (no_of_bits <= 64)
475 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400476 for(unsigned ib = 0; ib < 8; ib++)
477 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400478 guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400479 pui8 = pui8DATA(data, pDescr->offset+ib);
480 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400481 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400482 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300483 }
484 else
485 {
486 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
487 }
488
489 remaining_bits_len -= no_of_bits;
490 assert(remaining_bits_len >= 0);
491 bit_offset += no_of_bits;
492 }
493 /* bitmap was successfully extracted or it was empty */
494
495 pDescr++;
496 break;
497 }
498
499 case CSN_TYPE:
500 {
501 gint16 Status;
502 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400503 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300504 csnStreamInit(&arT, bit_offset, remaining_bits_len);
505 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400506 LOGPC(DCSN1, LOGL_NOTICE, ": End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300507 if (Status >= 0)
508 {
509 remaining_bits_len = arT.remaining_bits_len;
510 bit_offset = arT.bit_offset;
511 pDescr++;
512 }
513 else
514 {
515 /* Has already been processed: ProcessError("csnStreamDecoder", Status, pDescr); */
516 return Status;
517 }
518
519 break;
520 }
521
522 case CSN_CHOICE:
523 {
524 gint16 count = pDescr->i;
525 guint8 i = 0;
526 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
527
528 while (count > 0)
529 {
530 guint8 no_of_bits = pChoice->bits;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400531 guint8 value = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300532 if (value == pChoice->value)
533 {
534 CSN_DESCR descr[2];
535 gint16 Status;
536 csnStream_t arT = *ar;
537
538 descr[0] = pChoice->descr;
539 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
540 descr[1].type = CSN_END;
541 pui8 = pui8DATA(data, pDescr->offset);
542 *pui8 = i;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400543 LOGPC(DCSN1, LOGL_NOTICE, "Choice %s = %u | ", pDescr->sz , (unsigned)value);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300544 bit_offset += no_of_bits;
545 remaining_bits_len -= no_of_bits;
546
547 csnStreamInit(&arT, bit_offset, remaining_bits_len);
548 Status = csnStreamDecoder(&arT, descr, vector, readIndex, data);
549
550 if (Status >= 0)
551 {
552 remaining_bits_len = arT.remaining_bits_len;
553 bit_offset = arT.bit_offset;
554 }
555 else
556 {
557 return Status;
558 }
559 break;
560 }
561
562 readIndex -= no_of_bits;
563 count--;
564 pChoice++;
565 i++;
566 }
567
568 pDescr++;
569 break;
570 }
571
572 case CSN_SERIALIZE:
573 {
574 StreamSerializeFcn_t serialize = pDescr->serialize.fcn;
575 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400576 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300577 gint16 Status = -1;
578
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400579 guint8 length = bitvec_read_field(vector, readIndex, length_len);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300580
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400581 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %d | ", pDescr->sz , (int)length);
582 arT.direction = 1;
583 bit_offset += length_len;
584 remaining_bits_len -= length_len;
585
586 csnStreamInit(&arT, bit_offset, length);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300587 Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset));
588
589 if (Status >= 0)
590 {
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400591 remaining_bits_len -= length;
592 bit_offset += length;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300593 pDescr++;
594 }
595 else
596 {
597 /* Has already been processed: */
598 return Status;
599 }
600
601 break;
602 }
603
604 case CSN_UNION_LH:
605 case CSN_UNION:
606 {
607 gint16 Bits;
608 guint8 index;
609 gint16 count = pDescr->i;
610 const CSN_DESCR* pDescrNext = pDescr;
611
612 pDescrNext += count + 1; /* now this is next after the union */
613 if ((count <= 0) || (count > 16))
614 {
615 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
616 }
617
618 /* Now get the bits to extract the index */
619 Bits = ixBitsTab[count];
620 index = 0;
621
622 while (Bits > 0)
623 {
624 index <<= 1;
625
626 if (CSN_UNION_LH == pDescr->type)
627 {
628 index |= get_masked_bits8(vector,readIndex, bit_offset, 1);
629 }
630 else
631 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400632 index |= bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300633 }
634 remaining_bits_len--;
635 bit_offset++;
636 Bits--;
637 }
638
639 /* Assign UnionType */
640 pui8 = pui8DATA(data, pDescr->offset);
641 *pui8 = index;
642
643
644 /* script index to continue on, limited in case we do not have a power of 2 */
645 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400646 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300647
648 switch (pDescr->type)
649 { /* get the right element of the union based on computed index */
650
651 case CSN_BIT:
652 {
653 pui8 = pui8DATA(data, pDescr->offset);
654 *pui8 = 0x00;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400655 if (bitvec_read_field(vector, readIndex, 1) > 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300656 {
657 *pui8 = 0x01;
658 }
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400659 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300660 remaining_bits_len -= 1;
661 bit_offset++;
662 pDescr++;
663 break;
664 }
665
666 case CSN_NULL:
667 { /* Empty member! */
668 pDescr++;
669 break;
670 }
671
672 case CSN_UINT:
673 {
674 guint8 no_of_bits = (guint8) pDescr->i;
675 if (remaining_bits_len >= no_of_bits)
676 {
677 remaining_bits_len -= no_of_bits;
678
679 if (no_of_bits <= 8)
680 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400681 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300682 pui8 = pui8DATA(data, pDescr->offset);
683 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400684 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300685 }
686 else if (no_of_bits <= 16)
687 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400688 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300689 pui16 = pui16DATA(data, pDescr->offset);
690 *pui16 = ui16;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400691 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300692 }
693 else if (no_of_bits <= 32)
694 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400695 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300696 pui32 = pui32DATA(data, pDescr->offset);
697 *pui32 = ui32;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400698 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300699 }
700 else
701 {
702 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
703 }
704 }
705 else
706 {
707 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
708 }
709
710 bit_offset += no_of_bits;
711 pDescr++;
712 break;
713 }
714
715 case CSN_UINT_OFFSET:
716 {
717 guint8 no_of_bits = (guint8) pDescr->i;
718
719 if (remaining_bits_len >= no_of_bits)
720 {
721 if (no_of_bits <= 8)
722 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400723 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300724 pui8 = pui8DATA(data, pDescr->offset);
725 *pui8 = ui8 + (guint8)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400726 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300727 }
728 else if (no_of_bits <= 16)
729 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400730 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300731 pui16 = pui16DATA(data, pDescr->offset);
732 *pui16 = ui16 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400733 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300734 }
735 else if (no_of_bits <= 32)
736 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400737 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300738 pui32 = pui32DATA(data, pDescr->offset);
739 *pui32 = ui32 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400740 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300741 }
742 else
743 {
744 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
745 }
746 }
747 else
748 {
749 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
750 }
751
752 bit_offset += no_of_bits;
753 pDescr++;
754 break;
755 }
756
757 case CSN_UINT_LH:
758 {
759 guint8 no_of_bits = (guint8) pDescr->i;
760
761 if (remaining_bits_len >= no_of_bits)
762 {
763 if (no_of_bits <= 8)
764 {
765 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
766 pui8 = pui8DATA(data, pDescr->offset);
767 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400768 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300769 }
770 else
771 { /* Maybe we should support more than 8 bits ? */
772 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
773 }
774 }
775 else
776 {
777 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
778 }
779
780 bit_offset += no_of_bits;
781 pDescr++;
782 break;
783 }
784
785 case CSN_UINT_ARRAY:
786 {
787 guint8 no_of_bits = (guint8) pDescr->i;
788 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
789
790 if (pDescr->serialize.value != 0)
791 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
792 nCount = *pui16DATA(data, nCount);
793 }
794
795 if (remaining_bits_len >= no_of_bits)
796 {
797 remaining_bits_len -= (no_of_bits * nCount);
798 if (no_of_bits <= 8)
799 {
800 pui8 = pui8DATA(data, pDescr->offset);
801
802 while (nCount > 0)
803 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400804 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400805 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300806 pui8++;
807 bit_offset += no_of_bits;
808 nCount--;
809 }
810 }
811 else if (no_of_bits <= 16)
812 {
813 pui16 = pui16DATA(data, pDescr->offset);
814
815 while (nCount > 0)
816 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400817 *pui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400818 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300819 pui16++;
820 bit_offset += no_of_bits;
821 nCount--;
822 }
823 }
824 else if (no_of_bits <= 32)
825 { /* not supported */
826 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
827 }
828 else
829 {
830 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
831 }
832 }
833 else
834 {
835 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
836 }
837
838 pDescr++;
839 break;
840 }
841
842 case CSN_VARIABLE_TARRAY_OFFSET:
843 case CSN_VARIABLE_TARRAY:
844 case CSN_TYPE_ARRAY:
845 {
846 gint16 Status;
847 csnStream_t arT = *ar;
848 guint16 nCount = (guint16) pDescr->i;
849 guint16 nSize = (guint16)(guint32)pDescr->serialize.value;
850
851 pui8 = pui8DATA(data, pDescr->offset);
852
853 if (CSN_VARIABLE_TARRAY == pDescr->type)
854 { /* Count specified in field */
855 nCount = *pui8DATA(data, pDescr->i);
856 }
857 else if (CSN_VARIABLE_TARRAY_OFFSET == pDescr->type)
858 { /* Count specified in field */
859 nCount = *pui8DATA(data, pDescr->i);
860 nCount--; /* Offset 1 */
861 }
862
863 while (nCount--) /* Changed to handle length = 0. */
864 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400865 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300866 csnStreamInit(&arT, bit_offset, remaining_bits_len);
867 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
868 if (Status >= 0)
869 {
870 pui8 += nSize;
871 remaining_bits_len = arT.remaining_bits_len;
872 bit_offset = arT.bit_offset;
873 }
874 else
875 {
876 return Status;
877 }
878 }
879
880 pDescr++;
881 break;
882 }
883
884 case CSN_BITMAP:
885 { /* bitmap with given length. The result is left aligned! */
886 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
887
888 if (no_of_bits > 0)
889 {
890
891 if (no_of_bits <= 32)
892 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400893 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300894 pui32 = pui32DATA(data, pDescr->offset);
895 *pui32 = ui32;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300896 }
897 else if (no_of_bits <= 64)
898 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400899 guint64 ui64 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300900 pui64 = pui64DATA(data, pDescr->offset);
901 *pui64 = ui64;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400902 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300903 }
904 else
905 {
906 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
907 }
908
909 remaining_bits_len -= no_of_bits;
910 assert(remaining_bits_len >= 0);
911 bit_offset += no_of_bits;
912 }
913 /* bitmap was successfully extracted or it was empty */
914
915 pDescr++;
916 break;
917 }
918
919 case CSN_TYPE:
920 {
921 gint16 Status;
922 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400923 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300924 csnStreamInit(&arT, bit_offset, remaining_bits_len);
925 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400926 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300927 if (Status >= 0)
928 {
929 remaining_bits_len = arT.remaining_bits_len;
930 bit_offset = arT.bit_offset;
931 pDescr++;
932 }
933 else
934 { /* return error code Has already been processed: */
935 return Status;
936 }
937
938 break;
939 }
940
941 default:
942 { /* descriptions of union elements other than above are illegal */
943 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
944 }
945 }
946
947 pDescr = pDescrNext;
948 break;
949 }
950
951 case CSN_EXIST:
952 case CSN_EXIST_LH:
953 {
954 guint8 fExist;
955
956 pui8 = pui8DATA(data, pDescr->offset);
957
958 if (CSN_EXIST_LH == pDescr->type)
959 {
960 fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
961 }
962 else
963 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400964 fExist = bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300965 }
966
967 *pui8 = fExist;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400968 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300969 pDescr++;
970 remaining_bits_len -= 1;
971
972 if (!fExist)
973 {
974 ar->remaining_bits_len = remaining_bits_len;
975 ar->bit_offset = bit_offset;
976 return remaining_bits_len;
977 }
978
979 break;
980 }
981
982 case CSN_NEXT_EXIST:
983 {
984 guint8 fExist;
985
986 pui8 = pui8DATA(data, pDescr->offset);
987
988 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400989 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300990 { /* no more bits to decode is fine here - end of message detected and allowed */
991
992 /* Skip i entries + this entry */
993 pDescr += pDescr->i + 1;
994
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300995 /* Set the data member to "not exist" */
996 *pui8 = 0;
997 break;
998 }
999
1000 /* the "regular" M_NEXT_EXIST description element */
1001
1002 fExist = 0x00;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001003 if (bitvec_read_field(vector, readIndex, 1))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001004 {
1005 fExist = 0x01;
1006 }
1007
1008 *pui8 = fExist;
1009 remaining_bits_len -= 1;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001010 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001011 ++bit_offset;
1012
1013 if (fExist == 0)
1014 { /* Skip 'i' entries */
1015 pDescr += pDescr->i;
1016 }
1017
1018 pDescr++;
1019 break;
1020 }
1021
1022 case CSN_NEXT_EXIST_LH:
1023 {
1024 guint8 fExist;
1025 pui8 = pui8DATA(data, pDescr->offset);
1026
1027 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
1028 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
1029 { /* no more bits to decode is fine here - end of message detected and allowed */
1030
1031 /* skip 'i' entries + this entry */
1032 pDescr += pDescr->i + 1;
1033
1034 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
1035 if ( pDescr->type != CSN_END )
1036 { /* substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
1037 remaining_bits_len--;
1038 }
1039
1040 /* set the data member to "not exist" */
1041 *pui8 = 0;
1042 break;
1043 }
1044
1045 /* the "regular" M_NEXT_EXIST_LH description element */
1046 fExist = get_masked_bits8(vector,readIndex,bit_offset, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001047 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)fExist);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001048 *pui8++ = fExist;
1049 remaining_bits_len -= 1;
1050
1051 bit_offset++;
1052
1053 if (fExist == 0)
1054 { /* Skip 'i' entries */
1055 pDescr += pDescr->i;
1056 }
1057 pDescr++;
1058
1059 break;
1060 }
1061
1062 case CSN_VARIABLE_BITMAP_1:
1063 { /* Bitmap from here and to the end of message */
1064
1065 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1066
1067 /*no break -
1068 * with a length set we have a regular variable length bitmap so we continue */
1069 }
1070
1071 case CSN_VARIABLE_BITMAP:
1072 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1073 * <N: bit (5)> <bitmap: bit(N + offset)>
1074 * Bit array with length (in bits) specified in parameter (pDescr->descr)
1075 * The result is right aligned!
1076 */
1077 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
1078
1079 no_of_bits += pDescr->i; /* adjusted by offset */
1080
1081 if (no_of_bits > 0)
1082 {
1083 remaining_bits_len -= no_of_bits;
1084
1085 if (remaining_bits_len < 0)
1086 {
1087 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1088 }
1089
1090 { /* extract bits */
1091 guint8* pui8 = pui8DATA(data, pDescr->offset);
1092 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1093
1094 if (nB1 > 0)
1095 { /* take care of the first byte - it will be right aligned */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001096 *pui8 = bitvec_read_field(vector, readIndex, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001097 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001098 pui8++;
1099 no_of_bits -= nB1;
1100 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1101 }
1102
1103 /* remaining no_of_bits is a multiple of 8 or 0 */
1104 while (no_of_bits > 0)
1105 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001106 *pui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001107 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001108 pui8++;
1109 no_of_bits -= 8;
1110 }
1111 }
1112 }
1113 pDescr++;
1114 break;
1115 }
1116
1117 case CSN_LEFT_ALIGNED_VAR_BMP_1:
1118 { /* Bitmap from here and to the end of message */
1119
1120 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1121
1122 /* no break -
1123 * with a length set we have a regular left aligned variable length bitmap so we continue
1124 */
1125 }
1126
1127 case CSN_LEFT_ALIGNED_VAR_BMP:
1128 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1129 * <N: bit (5)> <bitmap: bit(N + offset)>
1130 * bit array with length (in bits) specified in parameter (pDescr->descr)
1131 */
1132 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
1133
1134 no_of_bits += pDescr->i;/* size adjusted by offset */
1135
1136 if (no_of_bits > 0)
1137 {
1138 remaining_bits_len -= no_of_bits;
1139
1140 if (remaining_bits_len < 0)
1141 {
1142 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1143 }
1144
1145 { /* extract bits */
1146 guint8* pui8 = pui8DATA(data, pDescr->offset);
1147 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1148
1149 while (no_of_bits > 0)
1150 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001151 *pui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001152 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001153 pui8++;
1154 no_of_bits -= 8;
1155 }
1156 if (nB1 > 0)
1157 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001158 *pui8 = bitvec_read_field(vector, readIndex, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001159 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001160 pui8++;
1161 no_of_bits -= nB1;
1162 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1163 }
1164 }
1165 }
1166
1167 /* bitmap was successfully extracted or it was empty */
1168 pDescr++;
1169 break;
1170 }
1171
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001172 case CSN_PADDING_BITS:
1173 { /* Padding from here and to the end of message */
1174 LOGPC(DCSN1, LOGL_NOTICE, "%s = ", pDescr->sz);
1175 if (remaining_bits_len > 0)
1176 {
1177 while (remaining_bits_len > 0)
1178 {
1179 guint8 bits_to_handle = remaining_bits_len%8;
1180 if (bits_to_handle > 0)
1181 {
1182 LOGPC(DCSN1, LOGL_NOTICE, "%u|", bitvec_read_field(vector, readIndex, bits_to_handle));
1183 remaining_bits_len -= bits_to_handle;
1184 bit_offset += bits_to_handle;
1185 }
1186 else if (bits_to_handle == 0)
1187 {
1188 LOGPC(DCSN1, LOGL_NOTICE, "%u|", bitvec_read_field(vector, readIndex, 8));
1189 remaining_bits_len -= 8;
1190 bit_offset += 8;
1191 }
1192 }
1193 }
1194 if (remaining_bits_len < 0)
1195 {
1196 return ProcessError(readIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1197 }
1198
1199 /* Padding was successfully extracted or it was empty */
1200 pDescr++;
1201 break;
1202 }
1203
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001204 case CSN_VARIABLE_ARRAY:
1205 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
1206 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1207 * Array with length specified in parameter:
1208 * <count: bit (x)>
1209 * <list: octet(count + offset)>
1210 */
1211 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
1212
1213 count += pDescr->i; /* Adjusted by offset */
1214
1215 if (count > 0)
1216 {
1217 remaining_bits_len -= count * 8;
1218
1219 if (remaining_bits_len < 0)
1220 {
1221 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1222 }
1223
1224 pui8 = pui8DATA(data, pDescr->offset);
1225
1226 while (count > 0)
1227 {
1228 readIndex -= 8;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001229 *pui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001230 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001231 pui8++;
1232 bit_offset += 8;
1233 count--;
1234 }
1235 }
1236
1237 pDescr++;
1238 break;
1239 }
1240
1241 case CSN_RECURSIVE_ARRAY:
1242 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
1243 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
1244 * where <element> ::= bit(value)
1245 * <tag> ::= 0 | 1
1246 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
1247 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1248 * REMARK: recursive way to specify an array but an iterative implementation!
1249 */
1250 gint16 no_of_bits = pDescr->i;
1251 guint8 ElementCount = 0;
1252
1253 pui8 = pui8DATA(data, pDescr->offset);
1254
1255 while (existNextElement(vector, readIndex, Tag))
1256 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001257 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001258 bit_offset++;
1259 remaining_bits_len--;
1260
1261 /* extract and store no_of_bits long element from bitstream */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001262 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001263 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001264 pui8++;
1265 remaining_bits_len -= no_of_bits;
1266 ElementCount++;
1267
1268 if (remaining_bits_len < 0)
1269 {
1270 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1271 }
1272
1273 bit_offset += no_of_bits;
1274 }
1275
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001276 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)bitvec_read_field(vector, readIndex, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001277 /* existNextElement() returned FALSE, 1 bit consumed */
1278 bit_offset++;
1279
1280 /* Store the counted number of elements of the array */
1281 *pui8DATA(data, (gint16)pDescr->descr.value) = ElementCount;
1282
1283 pDescr++;
1284 break;
1285 }
1286
1287 case CSN_RECURSIVE_TARRAY:
1288 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
1289 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1290 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1291 */
1292 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
1293 guint8 ElementCount = 0;
1294 pui8 = pui8DATA(data, pDescr->offset);
1295
1296 while (existNextElement(vector, readIndex, Tag))
1297 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001298 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001299 /* existNextElement() returned TRUE, 1 bit consumed */
1300 bit_offset++;
1301 remaining_bits_len--;
1302 ElementCount++;
1303
1304 { /* unpack the following data structure */
1305 csnStream_t arT = *ar;
1306 gint16 Status;
1307 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1308 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
1309
1310 if (Status >= 0)
1311 { /* successful completion */
1312 pui8 += nSizeElement; /* -> to next data element */
1313 remaining_bits_len = arT.remaining_bits_len;
1314 bit_offset = arT.bit_offset;
1315 }
1316 else
1317 { /* something went awry */
1318 return Status;
1319 }
1320 }
1321
1322 if (remaining_bits_len < 0)
1323 {
1324 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1325 }
1326 }
1327
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001328 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)bitvec_read_field(vector, readIndex, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001329
1330 /* existNextElement() returned FALSE, 1 bit consumed */
1331 bit_offset++;
1332
1333 /* Store the counted number of elements of the array */
1334 *pui8DATA(data, (gint16)(gint32)pDescr->i) = ElementCount;
1335
1336 pDescr++;
1337 break;
1338 }
1339
1340 case CSN_RECURSIVE_TARRAY_2:
1341 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
1342
1343 Tag = REVERSED_TAG;
1344
1345 /* NO break -
1346 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
1347 */
1348 }
1349
1350 case CSN_RECURSIVE_TARRAY_1:
1351 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
1352 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1353 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1354 */
1355 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
1356 guint8 ElementCount = 0;
1357 csnStream_t arT = *ar;
1358 gboolean EndOfList = FALSE;
1359 gint16 Status;
1360 pui8 = pui8DATA(data, pDescr->offset);
1361
1362 do
1363 { /* get data element */
1364 ElementCount++;
1365
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001366 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
1367
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001368 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1369 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
1370
1371 if (Status >= 0)
1372 { /* successful completion */
1373 pui8 += nSizeElement; /* -> to next */
1374 remaining_bits_len = arT.remaining_bits_len;
1375 bit_offset = arT.bit_offset;
1376 }
1377 else
1378 { /* something went awry */
1379 return Status;
1380 }
1381
1382 if (remaining_bits_len < 0)
1383 {
1384 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1385 }
1386
1387 /* control of next element's tag */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001388 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001389 EndOfList = !(existNextElement(vector, readIndex, Tag));
1390
1391 bit_offset++;
1392 remaining_bits_len--; /* 1 bit consumed (tag) */
1393 } while (!EndOfList);
1394
1395
1396 /* Store the count of the array */
1397 *pui8DATA(data, pDescr->i) = ElementCount;
1398 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
1399 pDescr++;
1400 break;
1401 }
1402
1403 case CSN_FIXED:
1404 { /* Verify the fixed bits */
1405 guint8 no_of_bits = (guint8) pDescr->i;
1406 guint32 ui32;
1407
1408 if (no_of_bits <= 32)
1409 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001410 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001411 }
1412 else
1413 {
1414 return ProcessError(readIndex,"no_of_bits > 32", -1, pDescr);
1415 }
1416 if (ui32 != (unsigned)(gint32)pDescr->offset)
1417 {
1418 return ProcessError(readIndex,"csnStreamDecoder FIXED value does not match", -1, pDescr);
1419 }
1420
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001421 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)ui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001422 remaining_bits_len -= no_of_bits;
1423 bit_offset += no_of_bits;
1424 pDescr++;
1425 break;
1426 }
1427
1428 case CSN_CALLBACK:
1429 {
1430 return ProcessError(readIndex,"csnStreamDecoder Callback not implemented", -1, pDescr);
1431 break;
1432 }
1433
1434 case CSN_TRAP_ERROR:
1435 {
1436 return ProcessError(readIndex,"csnStreamDecoder", pDescr->i, pDescr);
1437 }
1438
1439 case CSN_END:
1440 {
1441 ar->remaining_bits_len = remaining_bits_len;
1442 ar->bit_offset = bit_offset;
1443 return remaining_bits_len;
1444 }
1445
1446 default:
1447 {
1448 assert(0);
1449 }
1450
1451
1452 }
1453
1454 } while (remaining_bits_len >= 0);
1455
1456 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1457}
1458
1459
1460
1461
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001462gint16 csnStreamEncoder(csnStream_t* ar, const CSN_DESCR* pDescr, bitvec *vector, unsigned& writeIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001463{
1464 gint remaining_bits_len = ar->remaining_bits_len;
1465 gint bit_offset = ar->bit_offset;
1466 guint8* pui8;
1467 guint16* pui16;
1468 guint32* pui32;
1469 guint64* pui64;
1470
1471 guint8 Tag = STANDARD_TAG;
1472
1473 if (remaining_bits_len <= 0)
1474 {
1475 return 0;
1476 }
1477
1478 do
1479 {
1480 switch (pDescr->type)
1481 {
1482 case CSN_BIT:
1483 {
1484 if (remaining_bits_len > 0)
1485 {
1486 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001487 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001488 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001489 /* end add the bit value to protocol tree */
1490 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001491 else if(pDescr->may_be_null)
1492 {
1493 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
1494 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001495 else
1496 {
1497 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1498 }
1499
1500 pDescr++;
1501 remaining_bits_len--;
1502 bit_offset++;
1503 break;
1504 }
1505
1506 case CSN_NULL:
1507 { /* Empty member! */
1508 pDescr++;
1509 break;
1510 }
1511
1512 case CSN_UINT:
1513 {
1514 guint8 no_of_bits = (guint8) pDescr->i;
1515
1516 if (remaining_bits_len >= no_of_bits)
1517 {
1518 if (no_of_bits <= 8)
1519 {
1520 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001521 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001522 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001523 }
1524 else if (no_of_bits <= 16)
1525 {
1526 pui16 = pui16DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001527 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001528 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001529 }
1530 else if (no_of_bits <= 32)
1531 {
1532 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001533 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001534 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001535 }
1536 else
1537 {
1538 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1539 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001540
1541 remaining_bits_len -= no_of_bits;
1542 bit_offset += no_of_bits;
1543 }
1544 else if(pDescr->may_be_null)
1545 {
1546 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001547 }
1548 else
1549 {
1550 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1551 }
1552
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001553 pDescr++;
1554 break;
1555 }
1556
1557 case CSN_UINT_OFFSET:
1558 {
1559 guint8 no_of_bits = (guint8) pDescr->i;
1560
1561 if (remaining_bits_len >= no_of_bits)
1562 {
1563 if (no_of_bits <= 8)
1564 {
1565 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001566 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001567 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001568 }
1569 else if (no_of_bits <= 16)
1570 {
1571 pui16 = pui16DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001572 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001573 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001574 }
1575 else if (no_of_bits <= 32)
1576 {
1577 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001578 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001579 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001580 }
1581 else
1582 {
1583 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1584 }
1585 }
1586 else
1587 {
1588 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1589 }
1590
1591 remaining_bits_len -= no_of_bits;
1592 bit_offset += no_of_bits;
1593 pDescr++;
1594 break;
1595 }
1596
1597 case CSN_UINT_LH:
1598 {
1599 guint8 no_of_bits = (guint8) pDescr->i;
1600
1601 if (remaining_bits_len >= no_of_bits)
1602 {
1603 remaining_bits_len -= no_of_bits;
1604 if (no_of_bits <= 8)
1605 {
1606 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001607 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001608 // TODO : Change get_masked_bits8()
1609 writeIndex -= no_of_bits;
1610 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
1611 writeIndex -= no_of_bits;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001612 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001613 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001614
1615 }
1616 else
1617 {/* Maybe we should support more than 8 bits ? */
1618 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1619 }
1620 }
1621 else
1622 {
1623 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1624 }
1625
1626 remaining_bits_len -= no_of_bits;
1627 bit_offset += no_of_bits;
1628 pDescr++;
1629 break;
1630 }
1631
1632 case CSN_UINT_ARRAY:
1633 {
1634 guint8 no_of_bits = (guint8) pDescr->i;
1635 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
1636
1637 if (pDescr->serialize.value != 0)
1638 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
1639 nCount = *pui16DATA(data, nCount);
1640 }
1641
1642 if (remaining_bits_len >= no_of_bits)
1643 {
1644 remaining_bits_len -= (no_of_bits*nCount);
1645 if (no_of_bits <= 8)
1646 {
1647 pui8 = pui8DATA(data, pDescr->offset);
1648 do
1649 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001650 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
1651 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001652 pui8++;
1653 bit_offset += no_of_bits;
1654 } while (--nCount > 0);
1655 }
1656 else if (no_of_bits <= 16)
1657 {
1658 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1659 }
1660 else if (no_of_bits <= 32)
1661 {
1662 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1663 }
1664 else
1665 {
1666 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1667 }
1668 }
1669 else
1670 {
1671 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1672 }
1673 pDescr++;
1674 break;
1675 }
1676
1677 case CSN_VARIABLE_TARRAY_OFFSET:
1678 case CSN_VARIABLE_TARRAY:
1679 case CSN_TYPE_ARRAY:
1680 {
1681 gint16 Status;
1682 csnStream_t arT = *ar;
1683 gint16 nCount = pDescr->i;
1684 guint16 nSize = (guint16)(gint32)pDescr->serialize.value;
1685
1686 pui8 = pui8DATA(data, pDescr->offset);
1687 if (pDescr->type == CSN_VARIABLE_TARRAY)
1688 { /* Count specified in field */
1689 nCount = *pui8DATA(data, pDescr->i);
1690 }
1691 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
1692 { /* Count specified in field */
1693 nCount = *pui8DATA(data, pDescr->i);
1694 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
1695 }
1696
1697 while (nCount > 0)
1698 { /* resulting array of length 0 is possible
1699 * but no bits shall be read from bitstream
1700 */
1701
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001702 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001703 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1704 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
1705 if (Status >= 0)
1706 {
1707 pui8 += nSize;
1708 remaining_bits_len = arT.remaining_bits_len;
1709 bit_offset = arT.bit_offset;
1710
1711 }
1712 else
1713 {
1714 return Status;
1715 }
1716 nCount--;
1717 }
1718
1719 pDescr++;
1720 break;
1721 }
1722
1723 case CSN_BITMAP:
1724 { /* bitmap with given length. The result is left aligned! */
1725 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
1726
1727 if (no_of_bits > 0)
1728 {
1729
1730 if (no_of_bits <= 32)
1731 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001732 for(unsigned ib = 0; ib < 4; ib++)
1733 {
1734 pui8 = pui8DATA(data, pDescr->offset+ib);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001735 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001736 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001737 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001738 }
1739 else if (no_of_bits <= 64)
1740 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001741 for(unsigned ib = 0; ib < 8; ib++)
1742 {
1743 pui8 = pui8DATA(data, pDescr->offset+ib);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001744 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001745 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001746 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001747 }
1748 else
1749 {
1750 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
1751 }
1752
1753 remaining_bits_len -= no_of_bits;
1754 assert(remaining_bits_len >= 0);
1755 bit_offset += no_of_bits;
1756 }
1757 /* bitmap was successfully extracted or it was empty */
1758
1759 pDescr++;
1760 break;
1761 }
1762
1763 case CSN_TYPE:
1764 {
1765 gint16 Status;
1766 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001767 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001768 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1769 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001770 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001771 if (Status >= 0)
1772 {
1773
1774 remaining_bits_len = arT.remaining_bits_len;
1775 bit_offset = arT.bit_offset;
1776 pDescr++;
1777 }
1778 else
1779 {
1780 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
1781 return Status;
1782 }
1783
1784 break;
1785 }
1786
1787 case CSN_CHOICE:
1788 {
1789 //gint16 count = pDescr->i;
1790 guint8 i = 0;
1791 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
1792
1793 pui8 = pui8DATA(data, pDescr->offset);
1794 i = *pui8;
1795 pChoice += i;
1796 guint8 no_of_bits = pChoice->bits;
1797 guint8 value = pChoice->value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001798 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pChoice->descr.sz , (unsigned)value);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001799 bitvec_write_field(vector, writeIndex, value, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001800
1801 CSN_DESCR descr[2];
1802 gint16 Status;
1803 csnStream_t arT = *ar;
1804
1805 descr[0] = pChoice->descr;
1806 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
1807 descr[1].type = CSN_END;
1808 bit_offset += no_of_bits;
1809 remaining_bits_len -= no_of_bits;
1810
1811 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1812 Status = csnStreamEncoder(&arT, descr, vector, writeIndex, data);
1813
1814 if (Status >= 0)
1815 {
1816 remaining_bits_len = arT.remaining_bits_len;
1817 bit_offset = arT.bit_offset;
1818 }
1819 else
1820 {
1821 return Status;
1822 }
1823
1824 pDescr++;
1825 break;
1826 }
1827
1828 case CSN_SERIALIZE:
1829 {
1830 StreamSerializeFcn_t serialize = pDescr->serialize.fcn;
1831 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001832 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001833 gint16 Status = -1;
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001834 unsigned lengthIndex;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001835
1836 // store writeIndex for length value (7 bit)
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001837 lengthIndex = writeIndex;
1838 writeIndex += length_len;
1839 bit_offset += length_len;
1840 remaining_bits_len -= length_len;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001841 arT.direction = 0;
1842 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1843 Status = serialize(&arT, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001844
1845 bitvec_write_field(vector, lengthIndex, writeIndex-lengthIndex-length_len, length_len);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001846 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %u | ", pDescr->sz , (unsigned)(writeIndex-lengthIndex));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001847
1848 if (Status >= 0)
1849 {
1850 remaining_bits_len = arT.remaining_bits_len;
1851 bit_offset = arT.bit_offset;
1852 pDescr++;
1853 }
1854 else
1855 {
1856 // Has already been processed:
1857 return Status;
1858 }
1859
1860 break;
1861 }
1862
1863 case CSN_UNION_LH:
1864 case CSN_UNION:
1865 {
1866 gint16 Bits;
1867 guint8 index;
1868 gint16 count = pDescr->i;
1869 const CSN_DESCR* pDescrNext = pDescr;
1870
1871 pDescrNext += count + 1; /* now this is next after the union */
1872 if ((count <= 0) || (count > 16))
1873 {
1874 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
1875 }
1876
1877 /* Now get the bits to extract the index */
1878 Bits = ixBitsTab[count];
1879 index = 0;
1880
1881 /* Assign UnionType */
1882 pui8 = pui8DATA(data, pDescr->offset);
1883 //read index from data and write to vector
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001884 bitvec_write_field(vector, writeIndex, *pui8, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001885
1886 //decode index
1887 writeIndex -= Bits;
1888
1889 while (Bits > 0)
1890 {
1891 index <<= 1;
1892
1893 if (CSN_UNION_LH == pDescr->type)
1894 {
1895 index |= get_masked_bits8(vector,writeIndex, bit_offset, 1);
1896 }
1897 else
1898 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001899 index |= bitvec_read_field(vector, writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001900 }
1901
1902 remaining_bits_len--;
1903 bit_offset++;
1904 Bits--;
1905 }
1906
1907 writeIndex -= Bits;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001908 bitvec_write_field(vector, writeIndex, index, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001909
1910
1911 /* script index to continue on, limited in case we do not have a power of 2 */
1912 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001913 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)index);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001914
1915 switch (pDescr->type)
1916 { /* get the right element of the union based on computed index */
1917
1918 case CSN_BIT:
1919 {
1920 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001921 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001922 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001923 remaining_bits_len -= 1;
1924 bit_offset++;
1925 pDescr++;
1926 break;
1927 }
1928
1929 case CSN_NULL:
1930 { /* Empty member! */
1931 pDescr++;
1932 break;
1933 }
1934
1935 case CSN_UINT:
1936 {
1937 guint8 no_of_bits = (guint8) pDescr->i;
1938 if (remaining_bits_len >= no_of_bits)
1939 {
1940 remaining_bits_len -= no_of_bits;
1941
1942 if (no_of_bits <= 8)
1943 {
1944 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001945 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001946 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001947 }
1948 else if (no_of_bits <= 16)
1949 {
1950 pui16 = pui16DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001951 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001952 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001953 }
1954 else if (no_of_bits <= 32)
1955 {
1956 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001957 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001958 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001959 }
1960 else
1961 {
1962 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1963 }
1964 }
1965 else
1966 {
1967 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1968 }
1969
1970 bit_offset += no_of_bits;
1971 pDescr++;
1972 break;
1973 }
1974
1975 case CSN_UINT_OFFSET:
1976 {
1977 guint8 no_of_bits = (guint8) pDescr->i;
1978
1979 if (remaining_bits_len >= no_of_bits)
1980 {
1981 if (no_of_bits <= 8)
1982 {
1983 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001984 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001985 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001986 }
1987 else if (no_of_bits <= 16)
1988 {
1989 pui16 = pui16DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001990 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001991 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001992 }
1993 else if (no_of_bits <= 32)
1994 {
1995 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001996 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001997 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001998 }
1999 else
2000 {
2001 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2002 }
2003 }
2004 else
2005 {
2006 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2007 }
2008
2009 remaining_bits_len -= no_of_bits;
2010 bit_offset += no_of_bits;
2011 pDescr++;
2012 break;
2013 }
2014
2015 case CSN_UINT_LH:
2016 {
2017 guint8 no_of_bits = (guint8) pDescr->i;
2018
2019 if (remaining_bits_len >= no_of_bits)
2020 {
2021 remaining_bits_len -= no_of_bits;
2022 if (no_of_bits <= 8)
2023 {
2024 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002025 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002026 // TODO : Change get_masked_bits8()
2027 writeIndex -= no_of_bits;
2028 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
2029 writeIndex -= no_of_bits;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002030 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002031 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002032
2033 }
2034 else
2035 {/* Maybe we should support more than 8 bits ? */
2036 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2037 }
2038 }
2039 else
2040 {
2041 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2042 }
2043
2044 remaining_bits_len -= no_of_bits;
2045 bit_offset += no_of_bits;
2046 pDescr++;
2047 break;
2048 }
2049
2050 case CSN_UINT_ARRAY:
2051 {
2052 guint8 no_of_bits = (guint8) pDescr->i;
2053 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
2054
2055 if (pDescr->serialize.value != 0)
2056 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
2057 nCount = *pui16DATA(data, nCount);
2058 }
2059
2060 if (remaining_bits_len >= no_of_bits)
2061 {
2062 remaining_bits_len -= (no_of_bits*nCount);
2063 if (no_of_bits <= 8)
2064 {
2065 pui8 = pui8DATA(data, pDescr->offset);
2066 do
2067 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002068 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
2069 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002070 pui8++;
2071 bit_offset += no_of_bits;
2072 } while (--nCount > 0);
2073 }
2074 else if (no_of_bits <= 16)
2075 {
2076 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2077 }
2078 else if (no_of_bits <= 32)
2079 {
2080 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2081 }
2082 else
2083 {
2084 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2085 }
2086 }
2087 else
2088 {
2089 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2090 }
2091 pDescr++;
2092 break;
2093 }
2094
2095 case CSN_VARIABLE_TARRAY_OFFSET:
2096 case CSN_VARIABLE_TARRAY:
2097 case CSN_TYPE_ARRAY:
2098 {
2099 gint16 Status;
2100 csnStream_t arT = *ar;
2101 gint16 nCount = pDescr->i;
2102 guint16 nSize = (guint16)(gint32)pDescr->serialize.value;
2103
2104 pui8 = pui8DATA(data, pDescr->offset);
2105 if (pDescr->type == CSN_VARIABLE_TARRAY)
2106 { /* Count specified in field */
2107 nCount = *pui8DATA(data, pDescr->i);
2108 }
2109 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
2110 { /* Count specified in field */
2111 nCount = *pui8DATA(data, pDescr->i);
2112 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
2113 }
2114
2115 while (nCount > 0)
2116 { /* resulting array of length 0 is possible
2117 * but no bits shall be read from bitstream
2118 */
2119
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002120 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002121 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2122 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
2123 if (Status >= 0)
2124 {
2125 pui8 += nSize;
2126 remaining_bits_len = arT.remaining_bits_len;
2127 bit_offset = arT.bit_offset;
2128 }
2129 else
2130 {
2131 return Status;
2132 }
2133 nCount--;
2134 }
2135
2136 pDescr++;
2137 break;
2138 }
2139
2140 case CSN_BITMAP:
2141 { /* bitmap with given length. The result is left aligned! */
2142 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
2143
2144 if (no_of_bits > 0)
2145 {
2146
2147 if (no_of_bits <= 32)
2148 {
2149 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002150 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002151 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002152 }
2153 else if (no_of_bits <= 64)
2154 {
2155 pui64 = pui64DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002156 bitvec_write_field(vector, writeIndex, *pui64, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002157 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002158 }
2159 else
2160 {
2161 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
2162 }
2163
2164 remaining_bits_len -= no_of_bits;
2165 assert(remaining_bits_len >= 0);
2166 bit_offset += no_of_bits;
2167 }
2168 /* bitmap was successfully extracted or it was empty */
2169
2170 pDescr++;
2171 break;
2172 }
2173
2174 case CSN_TYPE:
2175 {
2176 gint16 Status;
2177 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002178 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002179 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2180 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002181 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002182 if (Status >= 0)
2183 {
2184 remaining_bits_len = arT.remaining_bits_len;
2185 bit_offset = arT.bit_offset;
2186 pDescr++;
2187 }
2188 else
2189 {
2190 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
2191 return Status;
2192 }
2193
2194 break;
2195 }
2196
2197 default:
2198 { /* descriptions of union elements other than above are illegal */
2199 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
2200 }
2201 }
2202
2203 pDescr = pDescrNext;
2204 break;
2205 }
2206
2207 case CSN_EXIST:
2208 case CSN_EXIST_LH:
2209 {
2210 guint8 fExist;
2211 unsigned exist = 0;
2212 pui8 = pui8DATA(data, pDescr->offset);
2213 exist = *pui8;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002214 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002215 writeIndex--;
2216 if (CSN_EXIST_LH == pDescr->type)
2217 {
2218 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
2219 }
2220 else
2221 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002222 fExist = bitvec_read_field(vector, writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002223 }
2224 writeIndex--;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002225 bitvec_write_field(vector, writeIndex, fExist, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002226 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz, (unsigned)fExist);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002227 pDescr++;
2228 remaining_bits_len -= 1;
2229
2230 if (!exist)
2231 {
2232 ar->remaining_bits_len = remaining_bits_len;
2233 ar->bit_offset = bit_offset;
2234 return remaining_bits_len;
2235 }
2236 break;
2237 }
2238
2239 case CSN_NEXT_EXIST:
2240 {
2241 guint8 fExist;
2242
2243 pui8 = pui8DATA(data, pDescr->offset);
2244
2245 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002246 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002247 { /* no more bits to decode is fine here - end of message detected and allowed */
2248
2249 /* Skip i entries + this entry */
2250 pDescr += pDescr->i + 1;
2251
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002252 break;
2253 }
2254
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002255 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002256 fExist = *pui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002257 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002258 remaining_bits_len -= 1;
2259
2260 ++bit_offset;
2261
2262 if (fExist == 0)
2263 { /* Skip 'i' entries */
2264 pDescr += pDescr->i;
2265 }
2266
2267 pDescr++;
2268 break;
2269 }
2270
2271 case CSN_NEXT_EXIST_LH:
2272 {
2273 guint8 fExist;
2274 pui8 = pui8DATA(data, pDescr->offset);
2275
2276 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
2277 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
2278 { /* no more bits to decode is fine here - end of message detected and allowed */
2279
2280 /* skip 'i' entries + this entry */
2281 pDescr += pDescr->i + 1;
2282
2283 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
2284 if ( pDescr->type != CSN_END )
2285 { /* substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
2286 remaining_bits_len--;
2287 }
2288
2289 /* set the data member to "not exist" */
2290 //*pui8 = 0;
2291 break;
2292 }
2293
2294 /* the "regular" M_NEXT_EXIST_LH description element */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002295 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002296 writeIndex--;
2297 fExist = get_masked_bits8(vector,writeIndex, bit_offset, 1);
2298 writeIndex--;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002299 bitvec_write_field(vector, writeIndex, fExist, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002300 pui8++;
2301 remaining_bits_len -= 1;
2302
2303 bit_offset++;
2304
2305 if (fExist == 0)
2306 { /* Skip 'i' entries */
2307 pDescr += pDescr->i;
2308 }
2309 pDescr++;
2310
2311 break;
2312 }
2313
2314 case CSN_VARIABLE_BITMAP_1:
2315 { /* Bitmap from here and to the end of message */
2316
2317 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2318
2319 /*no break -
2320 * with a length set we have a regular variable length bitmap so we continue */
2321 }
2322
2323 case CSN_VARIABLE_BITMAP:
2324 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2325 * <N: bit (5)> <bitmap: bit(N + offset)>
2326 * Bit array with length (in bits) specified in parameter (pDescr->descr)
2327 * The result is right aligned!
2328 */
2329 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
2330
2331 no_of_bits += pDescr->i; /* adjusted by offset */
2332
2333 if (no_of_bits > 0)
2334 {
2335 remaining_bits_len -= no_of_bits;
2336
2337 if (remaining_bits_len < 0)
2338 {
2339 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2340 }
2341
2342 { /* extract bits */
2343 guint8* pui8 = pui8DATA(data, pDescr->offset);
2344 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2345
2346 if (nB1 > 0)
2347 { /* take care of the first byte - it will be right aligned */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002348 bitvec_write_field(vector, writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002349 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002350 pui8++;
2351 no_of_bits -= nB1;
2352 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2353 }
2354
2355 /* remaining no_of_bits is a multiple of 8 or 0 */
2356 while (no_of_bits > 0)
2357 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002358 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002359 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002360 pui8++;
2361 no_of_bits -= 8;
2362 }
2363 }
2364 }
2365 pDescr++;
2366 break;
2367 }
2368
2369 case CSN_LEFT_ALIGNED_VAR_BMP_1:
2370 { /* Bitmap from here and to the end of message */
2371
2372 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2373
2374 /* no break -
2375 * with a length set we have a regular left aligned variable length bitmap so we continue
2376 */
2377 }
2378
2379 case CSN_LEFT_ALIGNED_VAR_BMP:
2380 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2381 * <N: bit (5)> <bitmap: bit(N + offset)>
2382 * bit array with length (in bits) specified in parameter (pDescr->descr)
2383 */
2384
2385 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
2386
2387 no_of_bits += pDescr->i;/* size adjusted by offset */
2388
2389 if (no_of_bits > 0)
2390 {
2391 remaining_bits_len -= no_of_bits;
2392
2393 if (remaining_bits_len < 0)
2394 {
2395 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2396 }
2397
2398 { /* extract bits */
2399 guint8* pui8 = pui8DATA(data, pDescr->offset);
2400 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2401
2402 while (no_of_bits > 0)
2403 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002404 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002405 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002406 pui8++;
2407 no_of_bits -= 8;
2408 }
2409 if (nB1 > 0)
2410 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002411 bitvec_write_field(vector, writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002412 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002413 pui8++;
2414 no_of_bits -= nB1;
2415 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2416 }
2417 }
2418
2419 }
2420
2421 /* bitmap was successfully extracted or it was empty */
2422 pDescr++;
2423 break;
2424 }
2425
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002426 case CSN_PADDING_BITS:
2427 { /* Padding from here and to the end of message */
2428 LOGPC(DCSN1, LOGL_NOTICE, "%s = ", pDescr->sz);
2429 guint8 filler = 0x2b;
2430 if (remaining_bits_len > 0)
2431 {
2432 while (remaining_bits_len > 0)
2433 {
2434 guint8 bits_to_handle = remaining_bits_len%8;
2435 if (bits_to_handle > 0)
2436 {
2437 guint8 fl = filler&(0xff>>(8-bits_to_handle));
2438 bitvec_write_field(vector, writeIndex, fl, bits_to_handle);
2439 LOGPC(DCSN1, LOGL_NOTICE, "%u|", fl);
2440 remaining_bits_len -= bits_to_handle;
2441 bit_offset += bits_to_handle;
2442 }
2443 else if (bits_to_handle == 0)
2444 {
2445 bitvec_write_field(vector, writeIndex, filler, 8);
2446 LOGPC(DCSN1, LOGL_NOTICE, "%u|", filler);
2447 remaining_bits_len -= 8;
2448 bit_offset += 8;
2449 }
2450 }
2451 }
2452 if (remaining_bits_len < 0)
2453 {
2454 return ProcessError(writeIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2455 }
2456
2457 /* Padding was successfully extracted or it was empty */
2458 pDescr++;
2459 break;
2460 }
2461
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002462 case CSN_VARIABLE_ARRAY:
2463 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
2464 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2465 * Array with length specified in parameter:
2466 * <count: bit (x)>
2467 * <list: octet(count + offset)>
2468 */
2469 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
2470
2471 count += pDescr->i; /* Adjusted by offset */
2472
2473 if (count > 0)
2474 {
2475 remaining_bits_len -= count * 8;
2476
2477 if (remaining_bits_len < 0)
2478 {
2479 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2480 }
2481
2482 pui8 = pui8DATA(data, pDescr->offset);
2483
2484 while (count > 0)
2485 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002486 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002487 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002488 pui8++;
2489 bit_offset += 8;
2490 count--;
2491 }
2492 }
2493
2494 pDescr++;
2495 break;
2496 }
2497
2498 case CSN_RECURSIVE_ARRAY:
2499 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
2500 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
2501 * where <element> ::= bit(value)
2502 * <tag> ::= 0 | 1
2503 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
2504 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2505 * REMARK: recursive way to specify an array but an iterative implementation!
2506 */
2507 gint16 no_of_bits = pDescr->i;
2508 guint8 ElementCount = 0;
2509 pui8 = pui8DATA(data, pDescr->offset);
2510 ElementCount = *pui8DATA(data, (gint16)pDescr->descr.value);
2511 while (ElementCount > 0)
2512 { /* tag control shows existence of next list elements */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002513 bitvec_write_field(vector, writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002514 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002515 bit_offset++;
2516 remaining_bits_len--;
2517
2518 /* extract and store no_of_bits long element from bitstream */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002519 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002520 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002521 pui8++;
2522 remaining_bits_len -= no_of_bits;
2523 ElementCount--;
2524
2525 if (remaining_bits_len < 0)
2526 {
2527 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2528 }
2529
2530 bit_offset += no_of_bits;
2531 }
2532
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002533 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002534 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002535 bit_offset++;
2536
2537 pDescr++;
2538 break;
2539 }
2540
2541 case CSN_RECURSIVE_TARRAY:
2542 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
2543 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2544 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2545 */
2546 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
2547 guint8 ElementCount = 0;
2548 pui8 = pui8DATA(data, pDescr->offset);
2549 /* Store the counted number of elements of the array */
2550 ElementCount = *pui8DATA(data, (gint16)(gint32)pDescr->i);
2551
2552 while (ElementCount > 0)
2553 { /* tag control shows existence of next list elements */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002554 bitvec_write_field(vector, writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002555 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002556 bit_offset++;
2557
2558 remaining_bits_len--;
2559 ElementCount--;
2560
2561 { /* unpack the following data structure */
2562 csnStream_t arT = *ar;
2563 gint16 Status;
2564 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2565 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
2566
2567 if (Status >= 0)
2568 { /* successful completion */
2569 pui8 += nSizeElement; /* -> to next data element */
2570 remaining_bits_len = arT.remaining_bits_len;
2571 bit_offset = arT.bit_offset;
2572 }
2573 else
2574 { /* something went awry */
2575 return Status;
2576 }
2577 }
2578
2579 if (remaining_bits_len < 0)
2580 {
2581 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2582 }
2583 }
2584
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002585 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002586 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002587 bit_offset++;
2588
2589 pDescr++;
2590 break;
2591 }
2592
2593 case CSN_RECURSIVE_TARRAY_2:
2594 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
2595
2596 Tag = REVERSED_TAG;
2597
2598 /* NO break -
2599 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
2600 */
2601 }
2602
2603 case CSN_RECURSIVE_TARRAY_1:
2604 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
2605 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2606 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2607 */
2608 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
2609 guint8 ElementCount = 0;
2610 guint8 ElementNum = 0;
2611 csnStream_t arT = *ar;
2612 gint16 Status;
2613
2614 pui8 = pui8DATA(data, pDescr->offset);
2615 /* Store the count of the array */
2616 ElementCount = *pui8DATA(data, pDescr->i);
2617 ElementNum = ElementCount;
2618
2619 while (ElementCount > 0)
2620 { /* get data element */
2621 if (ElementCount != ElementNum)
2622 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002623 bitvec_write_field(vector, writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002624 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002625 bit_offset++;
2626 remaining_bits_len--;
2627 }
2628 ElementCount--;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002629 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002630 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2631 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002632 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002633 if (Status >= 0)
2634 { /* successful completion */
2635 pui8 += nSizeElement; /* -> to next */
2636 remaining_bits_len = arT.remaining_bits_len;
2637 bit_offset = arT.bit_offset;
2638 }
2639 else
2640 { /* something went awry */
2641 return Status;
2642 }
2643
2644 if (remaining_bits_len < 0)
2645 {
2646 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2647 }
2648
2649 }
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002650 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002651 bit_offset++;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002652 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002653 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
2654 pDescr++;
2655 break;
2656 }
2657
2658 case CSN_FIXED:
2659 { /* Verify the fixed bits */
2660 guint8 no_of_bits = (guint8) pDescr->i;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002661 bitvec_write_field(vector, writeIndex, pDescr->offset, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002662 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002663 remaining_bits_len -= no_of_bits;
2664 bit_offset += no_of_bits;
2665 pDescr++;
2666 break;
2667 }
2668
2669 case CSN_CALLBACK:
2670 {
2671 return ProcessError(writeIndex,"csnStreamEncoder Callback not implemented", -1, pDescr);
2672 break;
2673 }
2674
2675 case CSN_TRAP_ERROR:
2676 {
2677 return ProcessError(writeIndex,"csnStreamEncoder", pDescr->i, pDescr);
2678 }
2679
2680 case CSN_END:
2681 {
2682 ar->remaining_bits_len = remaining_bits_len;
2683 ar->bit_offset = bit_offset;
2684 return remaining_bits_len;
2685 }
2686
2687 default:
2688 {
2689 assert(0);
2690 }
2691
2692 }
2693
2694 } while (remaining_bits_len >= 0);
2695
2696 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2697}
2698