/src/FreeRDP/winpr/libwinpr/utils/collections/BitStream.c
Line  | Count  | Source (jump to first uncovered line)  | 
1  |  | /**  | 
2  |  |  * WinPR: Windows Portable Runtime  | 
3  |  |  * BitStream  | 
4  |  |  *  | 
5  |  |  * Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>  | 
6  |  |  *  | 
7  |  |  * Licensed under the Apache License, Version 2.0 (the "License");  | 
8  |  |  * you may not use this file except in compliance with the License.  | 
9  |  |  * You may obtain a copy of the License at  | 
10  |  |  *  | 
11  |  |  *     http://www.apache.org/licenses/LICENSE-2.0  | 
12  |  |  *  | 
13  |  |  * Unless required by applicable law or agreed to in writing, software  | 
14  |  |  * distributed under the License is distributed on an "AS IS" BASIS,  | 
15  |  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  | 
16  |  |  * See the License for the specific language governing permissions and  | 
17  |  |  * limitations under the License.  | 
18  |  |  */  | 
19  |  |  | 
20  |  | #include <winpr/assert.h>  | 
21  |  | #include <winpr/config.h>  | 
22  |  |  | 
23  |  | #include <winpr/print.h>  | 
24  |  | #include <winpr/bitstream.h>  | 
25  |  |  | 
26  |  | static const char* BYTE_BIT_STRINGS_LSB[256] = { | 
27  |  |   "00000000", "00000001", "00000010", "00000011", "00000100", "00000101", "00000110", "00000111",  | 
28  |  |   "00001000", "00001001", "00001010", "00001011", "00001100", "00001101", "00001110", "00001111",  | 
29  |  |   "00010000", "00010001", "00010010", "00010011", "00010100", "00010101", "00010110", "00010111",  | 
30  |  |   "00011000", "00011001", "00011010", "00011011", "00011100", "00011101", "00011110", "00011111",  | 
31  |  |   "00100000", "00100001", "00100010", "00100011", "00100100", "00100101", "00100110", "00100111",  | 
32  |  |   "00101000", "00101001", "00101010", "00101011", "00101100", "00101101", "00101110", "00101111",  | 
33  |  |   "00110000", "00110001", "00110010", "00110011", "00110100", "00110101", "00110110", "00110111",  | 
34  |  |   "00111000", "00111001", "00111010", "00111011", "00111100", "00111101", "00111110", "00111111",  | 
35  |  |   "01000000", "01000001", "01000010", "01000011", "01000100", "01000101", "01000110", "01000111",  | 
36  |  |   "01001000", "01001001", "01001010", "01001011", "01001100", "01001101", "01001110", "01001111",  | 
37  |  |   "01010000", "01010001", "01010010", "01010011", "01010100", "01010101", "01010110", "01010111",  | 
38  |  |   "01011000", "01011001", "01011010", "01011011", "01011100", "01011101", "01011110", "01011111",  | 
39  |  |   "01100000", "01100001", "01100010", "01100011", "01100100", "01100101", "01100110", "01100111",  | 
40  |  |   "01101000", "01101001", "01101010", "01101011", "01101100", "01101101", "01101110", "01101111",  | 
41  |  |   "01110000", "01110001", "01110010", "01110011", "01110100", "01110101", "01110110", "01110111",  | 
42  |  |   "01111000", "01111001", "01111010", "01111011", "01111100", "01111101", "01111110", "01111111",  | 
43  |  |   "10000000", "10000001", "10000010", "10000011", "10000100", "10000101", "10000110", "10000111",  | 
44  |  |   "10001000", "10001001", "10001010", "10001011", "10001100", "10001101", "10001110", "10001111",  | 
45  |  |   "10010000", "10010001", "10010010", "10010011", "10010100", "10010101", "10010110", "10010111",  | 
46  |  |   "10011000", "10011001", "10011010", "10011011", "10011100", "10011101", "10011110", "10011111",  | 
47  |  |   "10100000", "10100001", "10100010", "10100011", "10100100", "10100101", "10100110", "10100111",  | 
48  |  |   "10101000", "10101001", "10101010", "10101011", "10101100", "10101101", "10101110", "10101111",  | 
49  |  |   "10110000", "10110001", "10110010", "10110011", "10110100", "10110101", "10110110", "10110111",  | 
50  |  |   "10111000", "10111001", "10111010", "10111011", "10111100", "10111101", "10111110", "10111111",  | 
51  |  |   "11000000", "11000001", "11000010", "11000011", "11000100", "11000101", "11000110", "11000111",  | 
52  |  |   "11001000", "11001001", "11001010", "11001011", "11001100", "11001101", "11001110", "11001111",  | 
53  |  |   "11010000", "11010001", "11010010", "11010011", "11010100", "11010101", "11010110", "11010111",  | 
54  |  |   "11011000", "11011001", "11011010", "11011011", "11011100", "11011101", "11011110", "11011111",  | 
55  |  |   "11100000", "11100001", "11100010", "11100011", "11100100", "11100101", "11100110", "11100111",  | 
56  |  |   "11101000", "11101001", "11101010", "11101011", "11101100", "11101101", "11101110", "11101111",  | 
57  |  |   "11110000", "11110001", "11110010", "11110011", "11110100", "11110101", "11110110", "11110111",  | 
58  |  |   "11111000", "11111001", "11111010", "11111011", "11111100", "11111101", "11111110", "11111111"  | 
59  |  | };  | 
60  |  |  | 
61  |  | static const char* BYTE_BIT_STRINGS_MSB[256] = { | 
62  |  |   "00000000", "10000000", "01000000", "11000000", "00100000", "10100000", "01100000", "11100000",  | 
63  |  |   "00010000", "10010000", "01010000", "11010000", "00110000", "10110000", "01110000", "11110000",  | 
64  |  |   "00001000", "10001000", "01001000", "11001000", "00101000", "10101000", "01101000", "11101000",  | 
65  |  |   "00011000", "10011000", "01011000", "11011000", "00111000", "10111000", "01111000", "11111000",  | 
66  |  |   "00000100", "10000100", "01000100", "11000100", "00100100", "10100100", "01100100", "11100100",  | 
67  |  |   "00010100", "10010100", "01010100", "11010100", "00110100", "10110100", "01110100", "11110100",  | 
68  |  |   "00001100", "10001100", "01001100", "11001100", "00101100", "10101100", "01101100", "11101100",  | 
69  |  |   "00011100", "10011100", "01011100", "11011100", "00111100", "10111100", "01111100", "11111100",  | 
70  |  |   "00000010", "10000010", "01000010", "11000010", "00100010", "10100010", "01100010", "11100010",  | 
71  |  |   "00010010", "10010010", "01010010", "11010010", "00110010", "10110010", "01110010", "11110010",  | 
72  |  |   "00001010", "10001010", "01001010", "11001010", "00101010", "10101010", "01101010", "11101010",  | 
73  |  |   "00011010", "10011010", "01011010", "11011010", "00111010", "10111010", "01111010", "11111010",  | 
74  |  |   "00000110", "10000110", "01000110", "11000110", "00100110", "10100110", "01100110", "11100110",  | 
75  |  |   "00010110", "10010110", "01010110", "11010110", "00110110", "10110110", "01110110", "11110110",  | 
76  |  |   "00001110", "10001110", "01001110", "11001110", "00101110", "10101110", "01101110", "11101110",  | 
77  |  |   "00011110", "10011110", "01011110", "11011110", "00111110", "10111110", "01111110", "11111110",  | 
78  |  |   "00000001", "10000001", "01000001", "11000001", "00100001", "10100001", "01100001", "11100001",  | 
79  |  |   "00010001", "10010001", "01010001", "11010001", "00110001", "10110001", "01110001", "11110001",  | 
80  |  |   "00001001", "10001001", "01001001", "11001001", "00101001", "10101001", "01101001", "11101001",  | 
81  |  |   "00011001", "10011001", "01011001", "11011001", "00111001", "10111001", "01111001", "11111001",  | 
82  |  |   "00000101", "10000101", "01000101", "11000101", "00100101", "10100101", "01100101", "11100101",  | 
83  |  |   "00010101", "10010101", "01010101", "11010101", "00110101", "10110101", "01110101", "11110101",  | 
84  |  |   "00001101", "10001101", "01001101", "11001101", "00101101", "10101101", "01101101", "11101101",  | 
85  |  |   "00011101", "10011101", "01011101", "11011101", "00111101", "10111101", "01111101", "11111101",  | 
86  |  |   "00000011", "10000011", "01000011", "11000011", "00100011", "10100011", "01100011", "11100011",  | 
87  |  |   "00010011", "10010011", "01010011", "11010011", "00110011", "10110011", "01110011", "11110011",  | 
88  |  |   "00001011", "10001011", "01001011", "11001011", "00101011", "10101011", "01101011", "11101011",  | 
89  |  |   "00011011", "10011011", "01011011", "11011011", "00111011", "10111011", "01111011", "11111011",  | 
90  |  |   "00000111", "10000111", "01000111", "11000111", "00100111", "10100111", "01100111", "11100111",  | 
91  |  |   "00010111", "10010111", "01010111", "11010111", "00110111", "10110111", "01110111", "11110111",  | 
92  |  |   "00001111", "10001111", "01001111", "11001111", "00101111", "10101111", "01101111", "11101111",  | 
93  |  |   "00011111", "10011111", "01011111", "11011111", "00111111", "10111111", "01111111", "11111111"  | 
94  |  | };  | 
95  |  |  | 
96  |  | void BitDump(const char* tag, UINT32 level, const BYTE* buffer, UINT32 length, UINT32 flags)  | 
97  | 0  | { | 
98  | 0  |   const char** strs = (flags & BITDUMP_MSB_FIRST) ? BYTE_BIT_STRINGS_MSB : BYTE_BIT_STRINGS_LSB;  | 
99  | 0  |   char pbuffer[64 * 8 + 1] = { 0 }; | 
100  | 0  |   size_t pos = 0;  | 
101  |  | 
  | 
102  | 0  |   WINPR_ASSERT(tag);  | 
103  | 0  |   WINPR_ASSERT(buffer || (length == 0));  | 
104  |  |  | 
105  | 0  |   DWORD i = 0;  | 
106  | 0  |   for (; i < length; i += 8)  | 
107  | 0  |   { | 
108  | 0  |     const char* str = strs[buffer[i / 8]];  | 
109  | 0  |     const int nbits = (length - i) > 8 ? 8 : (length - i);  | 
110  | 0  |     const int rc = _snprintf(&pbuffer[pos], length - pos, "%.*s ", nbits, str);  | 
111  | 0  |     if (rc < 0)  | 
112  | 0  |       return;  | 
113  |  |  | 
114  | 0  |     pos += (size_t)rc;  | 
115  | 0  |     if ((i % 64) == 0)  | 
116  | 0  |     { | 
117  | 0  |       pos = 0;  | 
118  | 0  |       WLog_LVL(tag, level, "%s", pbuffer);  | 
119  | 0  |     }  | 
120  | 0  |   }  | 
121  |  |  | 
122  | 0  |   if (i)  | 
123  | 0  |     WLog_LVL(tag, level, "%s ", pbuffer);  | 
124  | 0  | }  | 
125  |  |  | 
126  |  | UINT32 ReverseBits32(UINT32 bits, UINT32 nbits)  | 
127  | 0  | { | 
128  | 0  |   UINT32 rbits = 0;  | 
129  |  | 
  | 
130  | 0  |   do  | 
131  | 0  |   { | 
132  | 0  |     rbits = (rbits | (bits & 1)) << 1;  | 
133  | 0  |     bits >>= 1;  | 
134  | 0  |     nbits--;  | 
135  | 0  |   } while (nbits > 0);  | 
136  |  | 
  | 
137  | 0  |   rbits >>= 1;  | 
138  | 0  |   return rbits;  | 
139  | 0  | }  | 
140  |  |  | 
141  |  | void BitStream_Attach(wBitStream* bs, const BYTE* buffer, UINT32 capacity)  | 
142  | 0  | { | 
143  | 0  |   union  | 
144  | 0  |   { | 
145  | 0  |     const BYTE* cpv;  | 
146  | 0  |     BYTE* pv;  | 
147  | 0  |   } cnv;  | 
148  |  | 
  | 
149  | 0  |   WINPR_ASSERT(bs);  | 
150  | 0  |   WINPR_ASSERT(buffer);  | 
151  |  |  | 
152  | 0  |   cnv.cpv = buffer;  | 
153  |  | 
  | 
154  | 0  |   bs->position = 0;  | 
155  | 0  |   bs->buffer = cnv.pv;  | 
156  | 0  |   bs->offset = 0;  | 
157  | 0  |   bs->accumulator = 0;  | 
158  | 0  |   bs->pointer = cnv.pv;  | 
159  | 0  |   bs->capacity = capacity;  | 
160  | 0  |   bs->length = bs->capacity * 8;  | 
161  | 0  | }  | 
162  |  |  | 
163  |  | wBitStream* BitStream_New(void)  | 
164  | 0  | { | 
165  | 0  |   wBitStream* bs = (wBitStream*)calloc(1, sizeof(wBitStream));  | 
166  |  | 
  | 
167  | 0  |   return bs;  | 
168  | 0  | }  | 
169  |  |  | 
170  |  | void BitStream_Free(wBitStream* bs)  | 
171  | 0  | { | 
172  | 0  |   if (!bs)  | 
173  | 0  |     return;  | 
174  |  |  | 
175  | 0  |   free(bs);  | 
176  | 0  | }  |