From 2cd9649f37e665bec0f73ac1aad6e4d3f7fcd30e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 4 Mar 2014 18:15:03 -0500 Subject: [PATCH] libwinpr-utils: start new BitStream util --- winpr/include/winpr/collections.h | 16 ++ winpr/libwinpr/utils/CMakeLists.txt | 1 + winpr/libwinpr/utils/collections/BitStream.c | 46 +++++ winpr/libwinpr/utils/test/CMakeLists.txt | 1 + winpr/libwinpr/utils/test/TestBitStream.c | 174 +++++++++++++++++++ 5 files changed, 238 insertions(+) create mode 100644 winpr/libwinpr/utils/collections/BitStream.c create mode 100644 winpr/libwinpr/utils/test/TestBitStream.c diff --git a/winpr/include/winpr/collections.h b/winpr/include/winpr/collections.h index 6e7568dbe..2641299b7 100644 --- a/winpr/include/winpr/collections.h +++ b/winpr/include/winpr/collections.h @@ -596,6 +596,22 @@ WINPR_API int PubSub_OnEvent(wPubSub* pubSub, const char* EventName, void* conte WINPR_API wPubSub* PubSub_New(BOOL synchronized); WINPR_API void PubSub_Free(wPubSub* pubSub); +/* BitStream */ + +struct _wBitStream +{ + BYTE* buffer; + BYTE* pointer; + DWORD boffset; + DWORD position; + DWORD length; + DWORD capacity; +}; +typedef struct _wBitStream wBitStream; + +WINPR_API wBitStream* BitStream_New(); +WINPR_API void BitStream_Free(wBitStream* bs); + #ifdef __cplusplus } #endif diff --git a/winpr/libwinpr/utils/CMakeLists.txt b/winpr/libwinpr/utils/CMakeLists.txt index adb2bbcca..7827293b4 100644 --- a/winpr/libwinpr/utils/CMakeLists.txt +++ b/winpr/libwinpr/utils/CMakeLists.txt @@ -24,6 +24,7 @@ set(${MODULE_PREFIX}_COLLECTIONS_SRCS collections/Queue.c collections/Stack.c collections/PubSub.c + collections/BitStream.c collections/Reference.c collections/ArrayList.c collections/Dictionary.c diff --git a/winpr/libwinpr/utils/collections/BitStream.c b/winpr/libwinpr/utils/collections/BitStream.c new file mode 100644 index 000000000..d01a63756 --- /dev/null +++ b/winpr/libwinpr/utils/collections/BitStream.c @@ -0,0 +1,46 @@ +/** + * WinPR: Windows Portable Runtime + * BitStream + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +wBitStream* BitStream_New() +{ + wBitStream* bs = NULL; + + bs = (wBitStream*) calloc(1, sizeof(wBitStream)); + + if (bs) + { + + } + + return bs; +} + +void BitStream_Free(wBitStream* bs) +{ + if (bs) + { + free(bs); + } +} diff --git a/winpr/libwinpr/utils/test/CMakeLists.txt b/winpr/libwinpr/utils/test/CMakeLists.txt index c1e454065..ef54e2e08 100644 --- a/winpr/libwinpr/utils/test/CMakeLists.txt +++ b/winpr/libwinpr/utils/test/CMakeLists.txt @@ -8,6 +8,7 @@ set(${MODULE_PREFIX}_TESTS TestQueue.c TestPrint.c TestPubSub.c + TestBitStream.c TestArrayList.c TestLinkedList.c TestListDictionary.c diff --git a/winpr/libwinpr/utils/test/TestBitStream.c b/winpr/libwinpr/utils/test/TestBitStream.c new file mode 100644 index 000000000..ff313d283 --- /dev/null +++ b/winpr/libwinpr/utils/test/TestBitStream.c @@ -0,0 +1,174 @@ + +#include +#include +#include +#include + +const char* BYTE_BIT_STRINGS[256] = +{ + "00000000", "00000001", "00000010", "00000011", + "00000100", "00000101", "00000110", "00000111", + "00001000", "00001001", "00001010", "00001011", + "00001100", "00001101", "00001110", "00001111", + "00010000", "00010001", "00010010", "00010011", + "00010100", "00010101", "00010110", "00010111", + "00011000", "00011001", "00011010", "00011011", + "00011100", "00011101", "00011110", "00011111", + "00100000", "00100001", "00100010", "00100011", + "00100100", "00100101", "00100110", "00100111", + "00101000", "00101001", "00101010", "00101011", + "00101100", "00101101", "00101110", "00101111", + "00110000", "00110001", "00110010", "00110011", + "00110100", "00110101", "00110110", "00110111", + "00111000", "00111001", "00111010", "00111011", + "00111100", "00111101", "00111110", "00111111", + "01000000", "01000001", "01000010", "01000011", + "01000100", "01000101", "01000110", "01000111", + "01001000", "01001001", "01001010", "01001011", + "01001100", "01001101", "01001110", "01001111", + "01010000", "01010001", "01010010", "01010011", + "01010100", "01010101", "01010110", "01010111", + "01011000", "01011001", "01011010", "01011011", + "01011100", "01011101", "01011110", "01011111", + "01100000", "01100001", "01100010", "01100011", + "01100100", "01100101", "01100110", "01100111", + "01101000", "01101001", "01101010", "01101011", + "01101100", "01101101", "01101110", "01101111", + "01110000", "01110001", "01110010", "01110011", + "01110100", "01110101", "01110110", "01110111", + "01111000", "01111001", "01111010", "01111011", + "01111100", "01111101", "01111110", "01111111", + "10000000", "10000001", "10000010", "10000011", + "10000100", "10000101", "10000110", "10000111", + "10001000", "10001001", "10001010", "10001011", + "10001100", "10001101", "10001110", "10001111", + "10010000", "10010001", "10010010", "10010011", + "10010100", "10010101", "10010110", "10010111", + "10011000", "10011001", "10011010", "10011011", + "10011100", "10011101", "10011110", "10011111", + "10100000", "10100001", "10100010", "10100011", + "10100100", "10100101", "10100110", "10100111", + "10101000", "10101001", "10101010", "10101011", + "10101100", "10101101", "10101110", "10101111", + "10110000", "10110001", "10110010", "10110011", + "10110100", "10110101", "10110110", "10110111", + "10111000", "10111001", "10111010", "10111011", + "10111100", "10111101", "10111110", "10111111", + "11000000", "11000001", "11000010", "11000011", + "11000100", "11000101", "11000110", "11000111", + "11001000", "11001001", "11001010", "11001011", + "11001100", "11001101", "11001110", "11001111", + "11010000", "11010001", "11010010", "11010011", + "11010100", "11010101", "11010110", "11010111", + "11011000", "11011001", "11011010", "11011011", + "11011100", "11011101", "11011110", "11011111", + "11100000", "11100001", "11100010", "11100011", + "11100100", "11100101", "11100110", "11100111", + "11101000", "11101001", "11101010", "11101011", + "11101100", "11101101", "11101110", "11101111", + "11110000", "11110001", "11110010", "11110011", + "11110100", "11110101", "11110110", "11110111", + "11111000", "11111001", "11111010", "11111011", + "11111100", "11111101", "11111110", "11111111" +}; + +void BitStrGen() +{ + DWORD i = 0; + char str[64]; + + for (i = 0; i < 256; i++) + { + str[0] = (i & (1 << 7)) ? '1' : '0'; + str[1] = (i & (1 << 6)) ? '1' : '0'; + str[2] = (i & (1 << 5)) ? '1' : '0'; + str[3] = (i & (1 << 4)) ? '1' : '0'; + str[4] = (i & (1 << 3)) ? '1' : '0'; + str[5] = (i & (1 << 2)) ? '1' : '0'; + str[6] = (i & (1 << 1)) ? '1' : '0'; + str[7] = (i & (1 << 0)) ? '1' : '0'; + str[8] = '\0'; + + printf("\t\"%s\",\n", str); + } +} + +void BitDump(BYTE* buffer, DWORD length) +{ + DWORD i; + int nbits; + const char* str; + + for (i = 0; i < length; i += 8) + { + str = BYTE_BIT_STRINGS[buffer[i / 8]]; + + nbits = (length - i) > 8 ? 8 : (length - i); + + printf("%.*s ", nbits, str); + } + + printf("\n"); +} + +void BitStream_Attach(wBitStream* bs, BYTE* buffer, DWORD capacity) +{ + bs->boffset = 0; + bs->position = 0; + bs->buffer = buffer; + bs->pointer = bs->buffer; + bs->capacity = capacity; + bs->length = bs->capacity; +} + +void BitStream_Write_NBits(wBitStream* bs, UINT32 bits, UINT32 nbits) +{ + if ((bs->boffset + nbits) > 8) + { + *(bs->pointer) |= (bits << bs->boffset); + bs->position += (8 - bs->boffset); + nbits -= (8 - bs->boffset); + bs->boffset = 0; + bs->pointer++; + } + + if (nbits) + { + *(bs->pointer) |= (bits << bs->boffset); + bs->position += nbits; + bs->boffset += nbits; + + if (bs->boffset >= 8) + { + bs->boffset = bs->boffset % 8; + bs->pointer++; + } + } +} + +int TestBitStream(int argc, char* argv[]) +{ + wBitStream* bs; + BYTE buffer[1024]; + + ZeroMemory(buffer, sizeof(buffer)); + + bs = BitStream_New(); + + BitStream_Attach(bs, buffer, sizeof(buffer)); + + BitStream_Write_NBits(bs, 0xAF, 8); + BitStream_Write_NBits(bs, 0xF, 4); + BitStream_Write_NBits(bs, 0xA, 4); + + BitStream_Write_NBits(bs, 3, 2); /* 11 */ + BitStream_Write_NBits(bs, 0, 3); /* 000 */ + BitStream_Write_NBits(bs, 0x2D, 6); /* 101101 */ + + BitDump(buffer, bs->position); + + BitStream_Free(bs); + + return 0; +} +