EncoderChannel.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704
  1. /*
  2. * Copyright (C) 2007-2018 Siemens AG
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Lesser General Public License as published
  6. * by the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. /*******************************************************************
  18. *
  19. * @author Daniel.Peintner.EXT@siemens.com
  20. * @version 2017-03-02
  21. * @contact Richard.Kuntschke@siemens.com
  22. *
  23. * <p>Code generated by EXIdizer</p>
  24. * <p>Schema: V2G_CI_MsgDef.xsd</p>
  25. *
  26. *
  27. ********************************************************************/
  28. #include "EncoderChannel.h"
  29. #include "EXIOptions.h"
  30. #include "BitOutputStream.h"
  31. #include "EXITypes.h"
  32. #include "ErrorCodes.h"
  33. #include "MethodsBag.h"
  34. /*#include "v2gEXICoder.h"*/
  35. #ifndef ENCODER_CHANNEL_C
  36. #define ENCODER_CHANNEL_C
  37. int encodeUnsignedInteger(bitstream_t* stream, exi_integer_t* iv) {
  38. int errn = 0;
  39. switch (iv->type) {
  40. /* Unsigned Integer */
  41. case EXI_UNSIGNED_INTEGER_8:
  42. errn = encodeUnsignedInteger32(stream, iv->val.uint8);
  43. break;
  44. case EXI_UNSIGNED_INTEGER_16:
  45. errn = encodeUnsignedInteger32(stream, iv->val.uint16);
  46. break;
  47. case EXI_UNSIGNED_INTEGER_32:
  48. errn = encodeUnsignedInteger32(stream, iv->val.uint32);
  49. break;
  50. case EXI_UNSIGNED_INTEGER_64:
  51. errn = encodeUnsignedInteger64(stream, iv->val.uint64);
  52. break;
  53. /* (Signed) Integer */
  54. case EXI_INTEGER_8:
  55. if (iv->val.int8 < 0) {
  56. return EXI_NEGATIVE_UNSIGNED_INTEGER_VALUE;
  57. }
  58. errn = encodeUnsignedInteger32(stream, (uint32_t)(iv->val.int8));
  59. break;
  60. case EXI_INTEGER_16:
  61. if (iv->val.int16 < 0) {
  62. return EXI_NEGATIVE_UNSIGNED_INTEGER_VALUE;
  63. }
  64. errn = encodeUnsignedInteger32(stream, (uint32_t)(iv->val.int16));
  65. break;
  66. case EXI_INTEGER_32:
  67. if (iv->val.int32 < 0) {
  68. return EXI_NEGATIVE_UNSIGNED_INTEGER_VALUE;
  69. }
  70. errn = encodeUnsignedInteger32(stream, (uint32_t)(iv->val.int32));
  71. break;
  72. case EXI_INTEGER_64:
  73. if (iv->val.int64 < 0) {
  74. return EXI_NEGATIVE_UNSIGNED_INTEGER_VALUE;
  75. }
  76. errn = encodeUnsignedInteger64(stream, (uint64_t)(iv->val.int64));
  77. break;
  78. default:
  79. errn = EXI_UNSUPPORTED_INTEGER_VALUE_TYPE;
  80. break;
  81. }
  82. return errn;
  83. }
  84. /**
  85. * Encode an arbitrary precision non negative integer using a sequence of
  86. * octets. The most significant bit of the last octet is set to zero to
  87. * indicate sequence termination. Only seven bits per octet are used to
  88. * store the integer's value.
  89. */
  90. int encodeUnsignedInteger16(bitstream_t* stream, uint16_t n) {
  91. int errn = 0;
  92. if (n < 128) {
  93. /* write byte as is */
  94. errn = encode(stream, (uint8_t) n);
  95. } else {
  96. uint8_t n7BitBlocks = numberOf7BitBlocksToRepresent(n);
  97. switch (n7BitBlocks) {
  98. case 3:
  99. errn = encode(stream, (uint8_t) (128 | n));
  100. n = n >> 7;
  101. if (errn != 0) {
  102. break;
  103. }
  104. /* no break */
  105. case 2:
  106. errn = encode(stream, (uint8_t) (128 | n));
  107. n = n >> 7;
  108. if (errn != 0) {
  109. break;
  110. }
  111. /* no break */
  112. case 1:
  113. /* 0 .. 7 (last byte) */
  114. errn = encode(stream, (uint8_t) (0 | n));
  115. /* no break */
  116. }
  117. }
  118. return errn;
  119. }
  120. /**
  121. * Encode an arbitrary precision non negative integer using a sequence of
  122. * octets. The most significant bit of the last octet is set to zero to
  123. * indicate sequence termination. Only seven bits per octet are used to
  124. * store the integer's value.
  125. */
  126. int encodeUnsignedInteger32(bitstream_t* stream, uint32_t n) {
  127. int errn = 0;
  128. if (n < 128) {
  129. /* write byte as is */
  130. errn = encode(stream, (uint8_t) n);
  131. } else {
  132. uint8_t n7BitBlocks = numberOf7BitBlocksToRepresent(n);
  133. switch (n7BitBlocks) {
  134. case 5:
  135. errn = encode(stream, (uint8_t) (128 | n));
  136. n = n >> 7;
  137. if (errn != 0) {
  138. break;
  139. }
  140. /* no break */
  141. case 4:
  142. errn = encode(stream, (uint8_t) (128 | n));
  143. n = n >> 7;
  144. if (errn != 0) {
  145. break;
  146. }
  147. /* no break */
  148. case 3:
  149. errn = encode(stream, (uint8_t) (128 | n));
  150. n = n >> 7;
  151. if (errn != 0) {
  152. break;
  153. }
  154. /* no break */
  155. case 2:
  156. errn = encode(stream, (uint8_t) (128 | n));
  157. n = n >> 7;
  158. if (errn != 0) {
  159. break;
  160. }
  161. /* no break */
  162. case 1:
  163. /* 0 .. 7 (last byte) */
  164. errn = encode(stream, (uint8_t) (0 | n));
  165. /* no break */
  166. }
  167. }
  168. return errn;
  169. }
  170. /**
  171. * Encode an arbitrary precision non negative integer using a sequence of
  172. * octets. The most significant bit of the last octet is set to zero to
  173. * indicate sequence termination. Only seven bits per octet are used to
  174. * store the integer's value.
  175. */
  176. int encodeUnsignedInteger64(bitstream_t* stream, uint64_t n) {
  177. int errn = 0;
  178. uint8_t lastEncode = (uint8_t) n;
  179. n >>= 7;
  180. while (n != 0 && errn == 0) {
  181. errn = encode(stream, lastEncode | 128);
  182. lastEncode = (uint8_t) n;
  183. n >>= 7;
  184. }
  185. if (errn == 0) {
  186. errn = encode(stream, lastEncode);
  187. }
  188. return errn;
  189. }
  190. void _shiftRight7(uint8_t* buf, int len) {
  191. const int shift = 7;
  192. unsigned char tmp = 0x00, tmp2 = 0x00;
  193. for (int k = 0; k <= len; k++) {
  194. if (k == 0) {
  195. tmp = buf[k];
  196. buf[k] >>= shift;
  197. } else {
  198. tmp2 = buf[k];
  199. buf[k] >>= shift;
  200. buf[k] |= ((tmp & 0x7F) << (8 - shift));
  201. if (k != len) {
  202. tmp = tmp2;
  203. }
  204. }
  205. }
  206. }
  207. /**
  208. * Encode an arbitrary precision non negative integer using a sequence of
  209. * octets. The most significant bit of the last octet is set to zero to
  210. * indicate sequence termination. Only seven bits per octet are used to
  211. * store the integer's value.
  212. */
  213. int encodeUnsignedIntegerBig(bitstream_t* stream, size_t size, uint8_t* data, size_t len) {
  214. int errn = 0;
  215. int i;
  216. int lenM1 = len - 1;
  217. const int MAX_BIGINT_ARRAY = 25;
  218. uint8_t lastEncode = 0;
  219. uint8_t bytesToShift[MAX_BIGINT_ARRAY]; // MAXIMUM
  220. size_t bitsToEncode = len * 8;
  221. if(MAX_BIGINT_ARRAY <= len) {
  222. return -1;
  223. }
  224. /* init */
  225. for(i=0; i<MAX_BIGINT_ARRAY; i++) {
  226. bytesToShift[i] = 0;
  227. }
  228. /* copy bytes first in same order for shifting */
  229. for(i=0; i < len; i++) {
  230. bytesToShift[i] = data[i];
  231. }
  232. while(bitsToEncode > 7) {
  233. lastEncode = bytesToShift[lenM1];
  234. lastEncode = lastEncode | 128;
  235. errn = encode(stream, lastEncode);
  236. _shiftRight7(bytesToShift, len);
  237. bitsToEncode -= 7;
  238. }
  239. if (errn == 0) {
  240. errn = encode(stream, bytesToShift[lenM1]);
  241. }
  242. return errn;
  243. }
  244. int encodeInteger(bitstream_t* stream, exi_integer_t* iv) {
  245. int errn = 0;
  246. switch (iv->type) {
  247. /* Unsigned Integer */
  248. case EXI_UNSIGNED_INTEGER_8:
  249. errn = encodeInteger32(stream, iv->val.uint8);
  250. break;
  251. case EXI_UNSIGNED_INTEGER_16:
  252. errn = encodeInteger32(stream, iv->val.uint16);
  253. break;
  254. case EXI_UNSIGNED_INTEGER_32:
  255. errn = encodeInteger64(stream, iv->val.uint32);
  256. break;
  257. case EXI_UNSIGNED_INTEGER_64:
  258. errn = encodeInteger64(stream, (int64_t)(iv->val.uint64));
  259. break;
  260. /* (Signed) Integer */
  261. case EXI_INTEGER_8:
  262. errn = encodeInteger32(stream, iv->val.int8);
  263. break;
  264. case EXI_INTEGER_16:
  265. errn = encodeInteger32(stream, iv->val.int16);
  266. break;
  267. case EXI_INTEGER_32:
  268. errn = encodeInteger32(stream, iv->val.int32);
  269. break;
  270. case EXI_INTEGER_64:
  271. errn = encodeInteger64(stream, iv->val.int64);
  272. break;
  273. default:
  274. errn = EXI_UNSUPPORTED_INTEGER_VALUE_TYPE;
  275. break;
  276. }
  277. return errn;
  278. }
  279. /**
  280. * Encode an arbitrary precision integer using a sign bit followed by a
  281. * sequence of octets. The most significant bit of the last octet is set to
  282. * zero to indicate sequence termination. Only seven bits per octet are used
  283. * to store the integer's value.
  284. */
  285. int encodeInteger16(bitstream_t* stream, int16_t n) {
  286. int errn;
  287. /* signalize sign */
  288. if (n < 0) {
  289. errn = encodeBoolean(stream, 1);
  290. /* For negative values, the Unsigned Integer holds the
  291. * magnitude of the value minus 1 */
  292. n = (int16_t)((-n) - 1);
  293. } else {
  294. errn = encodeBoolean(stream, 0);
  295. }
  296. if (errn == 0) {
  297. errn = encodeUnsignedInteger16(stream, (uint16_t)n);
  298. }
  299. return errn;
  300. }
  301. /**
  302. * Encode an arbitrary precision integer using a sign bit followed by a
  303. * sequence of octets. The most significant bit of the last octet is set to
  304. * zero to indicate sequence termination. Only seven bits per octet are used
  305. * to store the integer's value.
  306. */
  307. int encodeInteger32(bitstream_t* stream, int32_t n) {
  308. int errn;
  309. /* signalize sign */
  310. if (n < 0) {
  311. errn = encodeBoolean(stream, 1);
  312. /* For negative values, the Unsigned Integer holds the
  313. * magnitude of the value minus 1 */
  314. n = (-n) - 1;
  315. } else {
  316. errn = encodeBoolean(stream, 0);
  317. }
  318. if (errn == 0) {
  319. errn = encodeUnsignedInteger32(stream, (uint32_t)n);
  320. }
  321. return errn;
  322. }
  323. /**
  324. * Encode an arbitrary precision integer using a sign bit followed by a
  325. * sequence of octets. The most significant bit of the last octet is set to
  326. * zero to indicate sequence termination. Only seven bits per octet are used
  327. * to store the integer's value.
  328. */
  329. int encodeInteger64(bitstream_t* stream, int64_t n) {
  330. int errn;
  331. /* signalize sign */
  332. if (n < 0) {
  333. errn = encodeBoolean(stream, 1);
  334. /* For negative values, the Unsigned Integer holds the
  335. * magnitude of the value minus 1 */
  336. n = (-n) - 1;
  337. } else {
  338. errn = encodeBoolean(stream, 0);
  339. }
  340. if (errn == 0) {
  341. errn = encodeUnsignedInteger64(stream, (uint64_t)n);
  342. }
  343. return errn;
  344. }
  345. /**
  346. * Encode an arbitrary precision integer using a sign bit followed by a
  347. * sequence of octets. The most significant bit of the last octet is set to
  348. * zero to indicate sequence termination. Only seven bits per octet are used
  349. * to store the integer's value.
  350. */
  351. int encodeIntegerBig(bitstream_t* stream, int negative, size_t size, uint8_t* data, size_t len) {
  352. int errn;
  353. /* signalize sign */
  354. if (negative) {
  355. errn = encodeBoolean(stream, 1);
  356. /* For negative values, the Unsigned Integer holds the
  357. * magnitude of the value minus 1 */
  358. /* n = (-n) - 1; */
  359. } else {
  360. errn = encodeBoolean(stream, 0);
  361. }
  362. if (errn == 0) {
  363. errn = encodeUnsignedIntegerBig(stream, size, data, len);
  364. }
  365. return errn;
  366. }
  367. /**
  368. * The Float datatype representation is two consecutive Integers.
  369. * The first Integer represents the mantissa of the floating point
  370. * number and the second Integer represents the base-10 exponent
  371. * of the floating point number.
  372. */
  373. int encodeFloat(bitstream_t* stream, exi_float_me_t* f) {
  374. int errn = encodeInteger64(stream, f->mantissa);
  375. if (errn == 0) {
  376. errn = encodeInteger32(stream, f->exponent);
  377. }
  378. return errn;
  379. }
  380. /**
  381. * Encode a decimal represented as a Boolean sign followed by two Unsigned
  382. * Integers. A sign value of zero (0) is used to represent positive Decimal
  383. * values and a sign value of one (1) is used to represent negative Decimal
  384. * values The first Integer represents the integral portion of the Decimal
  385. * value. The second positive integer represents the fractional portion of
  386. * the decimal with the digits in reverse order to preserve leading zeros.
  387. */
  388. int encodeDecimal(bitstream_t* stream, exi_decimal_t* d) {
  389. /* sign, integral, reverse fractional */
  390. int errn = encodeBoolean(stream, d->negative);
  391. if (errn == 0) {
  392. errn = encodeUnsignedInteger(stream, &d->integral);
  393. if (errn == 0) {
  394. errn = encodeUnsignedInteger(stream, &d->reverseFraction);
  395. }
  396. }
  397. return errn;
  398. }
  399. /**
  400. * Encode a length prefixed sequence of characters.
  401. */
  402. int encodeString(bitstream_t* stream, exi_string_t* string) {
  403. int errn = encodeUnsignedInteger32(stream, string->len);
  404. if (errn == 0) {
  405. errn = encodeCharacters(stream, string->characters, string->len);
  406. }
  407. return errn;
  408. }
  409. /**
  410. * Encode a sequence of characters according to a given length.
  411. * Each character is represented by its UCS [ISO/IEC 10646]
  412. * code point encoded as an Unsigned Integer
  413. */
  414. int encodeCharacters(bitstream_t* stream, exi_string_character_t* chars, size_t len) {
  415. unsigned int i;
  416. int errn = 0;
  417. for (i = 0; i < len && errn == 0; i++) {
  418. #if STRING_REPRESENTATION == STRING_REPRESENTATION_ASCII
  419. errn = encode(stream, (uint8_t)chars[i]);
  420. #endif /* STRING_REPRESENTATION_ASCII */
  421. #if STRING_REPRESENTATION == STRING_REPRESENTATION_UCS
  422. errn = encodeUnsignedInteger32(stream, chars[i]);
  423. #endif /* STRING_REPRESENTATION_UCS */
  424. }
  425. return errn;
  426. }
  427. int encodeRCSCharacters(bitstream_t* stream, exi_string_character_t* chars, size_t len, size_t rcsCodeLength, size_t rcsSize, const exi_string_character_t rcsSet[]) {
  428. unsigned int i;
  429. unsigned int k;
  430. int errn = 0;
  431. size_t rcsCode = SIZE_MAX;
  432. for (i = 0; i < len && errn == 0; i++) {
  433. /* try to find short code */
  434. rcsCode = SIZE_MAX;
  435. for(k=0; k<rcsSize && rcsCode == SIZE_MAX; k++) {
  436. if(rcsSet[k] == chars[i]) {
  437. rcsCode = k;
  438. }
  439. }
  440. if( rcsCode == SIZE_MAX) {
  441. /* RCS mis-match */
  442. errn = encodeNBitUnsignedInteger(stream, rcsCodeLength, rcsSize);
  443. #if STRING_REPRESENTATION == STRING_REPRESENTATION_ASCII
  444. errn = encode(stream, (uint8_t)chars[i]);
  445. #endif /* STRING_REPRESENTATION_ASCII */
  446. #if STRING_REPRESENTATION == STRING_REPRESENTATION_UCS
  447. errn = encodeUnsignedInteger32(stream, chars[i]);
  448. #endif /* STRING_REPRESENTATION_UCS */
  449. } else {
  450. /* RCS match */
  451. errn = encodeNBitUnsignedInteger(stream, rcsCodeLength, (uint32_t)rcsCode);
  452. }
  453. }
  454. return errn;
  455. }
  456. /**
  457. * Encode a binary value as a length-prefixed sequence of octets.
  458. */
  459. int encodeBinary(bitstream_t* stream, exi_bytes_t* bytes) {
  460. int errn = encodeUnsignedInteger32(stream, bytes->len);
  461. if(errn == 0) {
  462. errn = encodeBytes(stream, bytes->data, bytes->len);
  463. }
  464. return errn;
  465. }
  466. int encodeBytes(bitstream_t* stream, uint8_t* data, size_t len) {
  467. unsigned int i;
  468. int errn = 0;
  469. for (i = 0; i < len && errn == 0; i++) {
  470. errn = encode(stream, data[i]);
  471. }
  472. return errn;
  473. }
  474. /**
  475. * Encode a datetime representation which is a sequence of values
  476. * representing the individual components of the Date-Time
  477. */
  478. int encodeDateTime(bitstream_t* stream, exi_datetime_t* datetime) {
  479. int errn = 0;
  480. switch (datetime->type) {
  481. case EXI_DATETIME_GYEAR: /* Year, [Time-Zone] */
  482. errn = encodeInteger32(stream, datetime->year - DATETIME_YEAR_OFFSET);
  483. break;
  484. case EXI_DATETIME_GYEARMONTH: /* Year, MonthDay, [TimeZone] */
  485. case EXI_DATETIME_DATE: /* Year, MonthDay, [TimeZone] */
  486. errn = encodeInteger32(stream, datetime->year - DATETIME_YEAR_OFFSET);
  487. if (errn == 0) {
  488. errn = encodeNBitUnsignedInteger(stream, DATETIME_NUMBER_BITS_MONTHDAY,
  489. datetime->monthDay);
  490. }
  491. break;
  492. case EXI_DATETIME_DATETIME: /* Year, MonthDay, Time, [FractionalSecs], [TimeZone] */
  493. errn = encodeInteger32(stream, datetime->year - DATETIME_YEAR_OFFSET);
  494. if (errn == 0) {
  495. errn = encodeNBitUnsignedInteger(stream, DATETIME_NUMBER_BITS_MONTHDAY,
  496. datetime->monthDay);
  497. if (errn != 0) {
  498. break;
  499. }
  500. }
  501. /* no break */
  502. case EXI_DATETIME_TIME: /* Time, [FractionalSecs], [TimeZone] */
  503. errn = encodeNBitUnsignedInteger(stream, DATETIME_NUMBER_BITS_TIME,
  504. datetime->time);
  505. if (errn == 0) {
  506. if (datetime->presenceFractionalSecs) {
  507. errn = encodeBoolean(stream, 1);
  508. if (errn == 0) {
  509. errn = encodeUnsignedInteger32(stream, datetime->fractionalSecs);
  510. }
  511. } else {
  512. errn = encodeBoolean(stream, 0);
  513. }
  514. }
  515. break;
  516. case EXI_DATETIME_GMONTH: /* MonthDay, [TimeZone] */
  517. case EXI_DATETIME_GMONTHDAY: /* MonthDay, [TimeZone] */
  518. case EXI_DATETIME_GDAY: /* MonthDay, [TimeZone] */
  519. errn = encodeNBitUnsignedInteger(stream, DATETIME_NUMBER_BITS_MONTHDAY,
  520. datetime->monthDay);
  521. break;
  522. default:
  523. errn = EXI_UNSUPPORTED_DATETIME_TYPE;
  524. break;
  525. }
  526. if (errn == 0) {
  527. /* [TimeZone] */
  528. if (datetime->presenceTimezone) {
  529. errn = encodeBoolean(stream, 1);
  530. if (errn == 0) {
  531. errn = encodeNBitUnsignedInteger(stream, DATETIME_NUMBER_BITS_TIMEZONE,
  532. datetime->timezone + DATETIME_TIMEZONE_OFFSET_IN_MINUTES);
  533. }
  534. } else {
  535. errn = encodeBoolean(stream, 0);
  536. }
  537. }
  538. return errn;
  539. }
  540. int encode(bitstream_t* stream, uint8_t b) {
  541. #if EXI_OPTION_ALIGNMENT == BIT_PACKED
  542. return writeBits(stream, 8, b);
  543. #endif /* EXI_OPTION_ALIGNMENT == BIT_PACKED */
  544. #if EXI_OPTION_ALIGNMENT == BYTE_ALIGNMENT
  545. int errn = 0;
  546. #if EXI_STREAM == BYTE_ARRAY
  547. if ( (*stream->pos) < stream->size ) {
  548. stream->data[(*stream->pos)++] = b;
  549. } else {
  550. errn = EXI_ERROR_OUTPUT_STREAM_EOF;
  551. }
  552. #endif /* EXI_STREAM == BYTE_ARRAY */
  553. #if EXI_STREAM == FILE_STREAM
  554. if ( putc(b, stream->file) == EOF ) {
  555. errn = EXI_ERROR_OUTPUT_STREAM_EOF;
  556. }
  557. #endif /* EXI_STREAM == FILE_STREAM */
  558. return errn;
  559. #endif /* EXI_OPTION_ALIGNMENT == BYTE_ALIGNMENT */
  560. }
  561. /**
  562. * Encode a single boolean value. A false value is encoded as bit 0 and true
  563. * value is encode as bit 1.
  564. */
  565. int encodeBoolean(bitstream_t* stream, int b) {
  566. #if EXI_OPTION_ALIGNMENT == BIT_PACKED
  567. uint8_t val = b ? 1 : 0;
  568. return writeBits(stream, 1, val);
  569. #endif /* EXI_OPTION_ALIGNMENT == BIT_PACKED */
  570. #if EXI_OPTION_ALIGNMENT == BYTE_ALIGNMENT
  571. uint8_t val = b ? 1 : 0;
  572. return encode(stream, val);
  573. #endif /* EXI_OPTION_ALIGNMENT == BYTE_ALIGNMENT */
  574. }
  575. /**
  576. * Encode n-bit unsigned integer. The n least significant bits of parameter
  577. * b starting with the most significant, i.e. from left to right.
  578. */
  579. int encodeNBitUnsignedInteger(bitstream_t* stream, size_t nbits, uint32_t val) {
  580. #if EXI_OPTION_ALIGNMENT == BIT_PACKED
  581. int errn = 0;
  582. if (nbits > 0) {
  583. errn = writeBits(stream, nbits, val);
  584. }
  585. return errn;
  586. #endif /* EXI_OPTION_ALIGNMENT == BIT_PACKED */
  587. #if EXI_OPTION_ALIGNMENT == BYTE_ALIGNMENT
  588. int errn = 0;
  589. if (nbits > 0) {
  590. if (nbits < 9) {
  591. /* 1 byte */
  592. errn = encode(stream, val & 0xff);
  593. } else if (nbits < 17) {
  594. /* 2 bytes */
  595. errn = encode(stream, val & 0x00ff);
  596. if(errn == 0) {
  597. errn = encode(stream, (uint8_t)((val & 0xff00) >> 8));
  598. }
  599. } else if (nbits < 25) {
  600. /* 3 bytes */
  601. errn = encode(stream, val & 0x0000ff);
  602. if(errn == 0) {
  603. errn = encode(stream, (uint8_t)((val & 0x00ff00) >> 8));
  604. if(errn == 0) {
  605. errn = encode(stream, (uint8_t)((val & 0xff0000) >> 16));
  606. }
  607. }
  608. } else if (nbits < 33) {
  609. /* 4 bytes */
  610. errn = encode(stream, val & 0x000000ff);
  611. if(errn == 0) {
  612. errn = encode(stream, (uint8_t)((val & 0x0000ff00) >> 8));
  613. if(errn == 0) {
  614. errn = encode(stream, (uint8_t)((val & 0x00ff0000) >> 16));
  615. if(errn == 0) {
  616. errn = encode(stream, (uint8_t)((val & 0xff000000) >> 24));
  617. }
  618. }
  619. }
  620. } else {
  621. /* TODO Currently not more than 4 Bytes allowed for NBitUnsignedInteger */
  622. errn = EXI_UNSUPPORTED_NBIT_INTEGER_LENGTH;
  623. }
  624. }
  625. return errn;
  626. #endif /* EXI_OPTION_ALIGNMENT == BYTE_ALIGNMENT */
  627. }
  628. /**
  629. * Flush underlying output stream.
  630. */
  631. int encodeFinish(bitstream_t* stream) {
  632. #if EXI_OPTION_ALIGNMENT == BIT_PACKED
  633. #endif /* EXI_OPTION_ALIGNMENT == BIT_PACKED */
  634. return flush(stream);
  635. #if EXI_OPTION_ALIGNMENT == BYTE_ALIGNMENT
  636. /* no pending bits in byte-aligned mode */
  637. return 0;
  638. #endif /* EXI_OPTION_ALIGNMENT == BYTE_ALIGNMENT */
  639. }
  640. #endif