BitOutputStream.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  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 "BitOutputStream.h"
  29. #include "EXIConfig.h"
  30. #include "EXITypes.h"
  31. #include "ErrorCodes.h"
  32. #ifndef BIT_OUTPUT_STREAM_C
  33. #define BIT_OUTPUT_STREAM_C
  34. int writeBits(bitstream_t* stream, size_t nbits, uint32_t val) {
  35. int errn = 0;
  36. /* is there enough space in the buffer */
  37. if (nbits <= stream->capacity) {
  38. /* all bits fit into the current buffer */
  39. stream->buffer = (uint8_t)(stream->buffer << (nbits)) | (uint8_t)(val & (uint32_t)(0xff >> (uint32_t)(BITS_IN_BYTE - nbits)));
  40. stream->capacity = (uint8_t)(stream->capacity - nbits);
  41. /* if the buffer is full write byte */
  42. if (stream->capacity == 0) {
  43. #if EXI_STREAM == BYTE_ARRAY
  44. if ((*stream->pos) >= stream->size) {
  45. errn = EXI_ERROR_OUTPUT_STREAM_EOF;
  46. } else {
  47. stream->data[(*stream->pos)++] = stream->buffer;
  48. }
  49. #endif
  50. #if EXI_STREAM == FILE_STREAM
  51. if ( putc(stream->buffer, stream->file) == EOF ) {
  52. errn = EXI_ERROR_OUTPUT_STREAM_EOF;
  53. }
  54. #endif
  55. stream->capacity = BITS_IN_BYTE;
  56. stream->buffer = 0;
  57. }
  58. } else {
  59. /* the buffer is not enough
  60. * fill the buffer */
  61. stream->buffer = (uint8_t)(stream->buffer << stream->capacity) |
  62. ( (uint8_t)(val >> (nbits - stream->capacity)) & (uint8_t)(0xff >> (BITS_IN_BYTE - stream->capacity)) );
  63. nbits = (nbits - stream->capacity);
  64. #if EXI_STREAM == BYTE_ARRAY
  65. if ((*stream->pos) >= stream->size) {
  66. errn = EXI_ERROR_OUTPUT_STREAM_EOF;
  67. } else {
  68. stream->data[(*stream->pos)++] = stream->buffer;
  69. }
  70. #endif
  71. #if EXI_STREAM == FILE_STREAM
  72. if ( putc(stream->buffer, stream->file) == EOF ) {
  73. errn = EXI_ERROR_OUTPUT_STREAM_EOF;
  74. }
  75. #endif
  76. stream->buffer = 0;
  77. /* write whole bytes */
  78. while (errn == 0 && nbits >= BITS_IN_BYTE) {
  79. nbits = (nbits - BITS_IN_BYTE);
  80. #if EXI_STREAM == BYTE_ARRAY
  81. if ((*stream->pos) >= stream->size) {
  82. errn = EXI_ERROR_OUTPUT_STREAM_EOF;
  83. } else {
  84. stream->data[(*stream->pos)++] = (uint8_t)(val >> (nbits));
  85. }
  86. #endif
  87. #if EXI_STREAM == FILE_STREAM
  88. if ( putc((int)(val >> (nbits)), stream->file) == EOF ) {
  89. errn = EXI_ERROR_OUTPUT_STREAM_EOF;
  90. }
  91. #endif
  92. }
  93. /* spared bits are kept in the buffer */
  94. stream->buffer = (uint8_t)val; /* Note: the high bits will be shifted out during further filling */
  95. stream->capacity = (uint8_t)(BITS_IN_BYTE - (nbits));
  96. }
  97. return errn;
  98. }
  99. /**
  100. * Flush output
  101. */
  102. int flush(bitstream_t* stream) {
  103. int errn = 0;
  104. if (stream->capacity == BITS_IN_BYTE) {
  105. /* nothing to do, no bits in buffer */
  106. } else {
  107. errn = writeBits(stream, stream->capacity, 0);
  108. }
  109. return errn;
  110. }
  111. #endif