aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/bitpack.h
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llcommon/bitpack.h')
-rw-r--r--linden/indra/llcommon/bitpack.h209
1 files changed, 209 insertions, 0 deletions
diff --git a/linden/indra/llcommon/bitpack.h b/linden/indra/llcommon/bitpack.h
new file mode 100644
index 0000000..9a32a07
--- /dev/null
+++ b/linden/indra/llcommon/bitpack.h
@@ -0,0 +1,209 @@
1/**
2 * @file bitpack.h
3 * @brief Convert data to packed bit stream
4 *
5 * Copyright (c) 2000-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#ifndef LL_BITPACK_H
29#define LL_BITPACK_H
30
31#include "llerror.h"
32
33const U32 MAX_DATA_BITS = 8;
34
35
36class LLBitPack
37{
38public:
39 LLBitPack(U8 *buffer, U32 max_size) : mBuffer(buffer), mBufferSize(0), mLoad(0), mLoadSize(0), mTotalBits(0), mMaxSize(max_size)
40 {
41 }
42
43 ~LLBitPack()
44 {
45 }
46
47 void resetBitPacking()
48 {
49 mLoad = 0;
50 mLoadSize = 0;
51 mTotalBits = 0;
52 mBufferSize = 0;
53 }
54
55 U32 bitPack(U8 *total_data, U32 total_dsize)
56 {
57 U32 dsize;
58 U8 data;
59
60 while (total_dsize > 0)
61 {
62 if (total_dsize > MAX_DATA_BITS)
63 {
64 dsize = MAX_DATA_BITS;
65 total_dsize -= MAX_DATA_BITS;
66 }
67 else
68 {
69 dsize = total_dsize;
70 total_dsize = 0;
71 }
72
73 data = *total_data++;
74
75 data <<= (MAX_DATA_BITS - dsize);
76 while (dsize > 0)
77 {
78 if (mLoadSize == MAX_DATA_BITS)
79 {
80 *(mBuffer + mBufferSize++) = mLoad;
81 if (mBufferSize > mMaxSize)
82 {
83 llerror("mBufferSize exceeding mMaxSize!", 0);
84 }
85 mLoadSize = 0;
86 mLoad = 0x00;
87 }
88 mLoad <<= 1;
89 mLoad |= (data >> (MAX_DATA_BITS - 1));
90 data <<= 1;
91 mLoadSize++;
92 mTotalBits++;
93 dsize--;
94 }
95 }
96 return mBufferSize;
97 }
98
99 U32 bitCopy(U8 *total_data, U32 total_dsize)
100 {
101 U32 dsize;
102 U8 data;
103
104 while (total_dsize > 0)
105 {
106 if (total_dsize > MAX_DATA_BITS)
107 {
108 dsize = MAX_DATA_BITS;
109 total_dsize -= MAX_DATA_BITS;
110 }
111 else
112 {
113 dsize = total_dsize;
114 total_dsize = 0;
115 }
116
117 data = *total_data++;
118
119 while (dsize > 0)
120 {
121 if (mLoadSize == MAX_DATA_BITS)
122 {
123 *(mBuffer + mBufferSize++) = mLoad;
124 if (mBufferSize > mMaxSize)
125 {
126 llerror("mBufferSize exceeding mMaxSize!", 0);
127 }
128 mLoadSize = 0;
129 mLoad = 0x00;
130 }
131 mLoad <<= 1;
132 mLoad |= (data >> (MAX_DATA_BITS - 1));
133 data <<= 1;
134 mLoadSize++;
135 mTotalBits++;
136 dsize--;
137 }
138 }
139 return mBufferSize;
140 }
141
142 U32 bitUnpack(U8 *total_retval, U32 total_dsize)
143 {
144 U32 dsize;
145 U8 *retval;
146
147 while (total_dsize > 0)
148 {
149 if (total_dsize > MAX_DATA_BITS)
150 {
151 dsize = MAX_DATA_BITS;
152 total_dsize -= MAX_DATA_BITS;
153 }
154 else
155 {
156 dsize = total_dsize;
157 total_dsize = 0;
158 }
159
160 retval = total_retval++;
161 *retval = 0x00;
162 while (dsize > 0)
163 {
164 if (mLoadSize == 0)
165 {
166#ifdef _DEBUG
167 if (mBufferSize > mMaxSize)
168 {
169 llerrs << "mBufferSize exceeding mMaxSize" << llendl;
170 llerrs << mBufferSize << " > " << mMaxSize << llendl;
171 }
172#endif
173 mLoad = *(mBuffer + mBufferSize++);
174 mLoadSize = MAX_DATA_BITS;
175 }
176 *retval <<= 1;
177 *retval |= (mLoad >> (MAX_DATA_BITS - 1));
178 mLoadSize--;
179 mLoad <<= 1;
180 dsize--;
181 }
182 }
183 return mBufferSize;
184 }
185
186 U32 flushBitPack()
187 {
188 if (mLoadSize)
189 {
190 mLoad <<= (MAX_DATA_BITS - mLoadSize);
191 *(mBuffer + mBufferSize++) = mLoad;
192 if (mBufferSize > mMaxSize)
193 {
194 llerror("mBufferSize exceeding mMaxSize!", 0);
195 }
196 mLoadSize = 0;
197 }
198 return mBufferSize;
199 }
200
201 U8 *mBuffer;
202 U32 mBufferSize;
203 U8 mLoad;
204 U32 mLoadSize;
205 U32 mTotalBits;
206 U32 mMaxSize;
207};
208
209#endif