1 karl 1.6 //%2006////////////////////////////////////////////////////////////////////////
|
2 jim.wunderlich 1.1 //
3 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
6 // IBM Corp.; EMC Corporation, The Open Group.
7 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
9 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.6 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 jim.wunderlich 1.1 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
18 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
20 //
21 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
24 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 //%/////////////////////////////////////////////////////////////////////////////
33
|
34 jim.wunderlich 1.2 #include <string.h>
|
35 jim.wunderlich 1.1 #include "Packer.h"
36
37 PEGASUS_NAMESPACE_BEGIN
38
39 static bool _constains16BitChars(const String& x)
40 {
41 const Char16* p = x.getChar16Data();
42 Uint32 n = x.size();
43
44 while (n--)
45 {
|
46 kumpf 1.7 if (Uint16(*p++) > 0xFF)
47 return true;
|
48 jim.wunderlich 1.1 }
49
50 return false;
51 }
52
|
53 mike 1.3 void Packer::packString(Buffer& out, const String& x)
|
54 jim.wunderlich 1.1 {
55 Uint32 n = x.size();
56
57 if (_constains16BitChars(x))
58 {
|
59 kumpf 1.7 packUint8(out, 16);
60 packSize(out, n);
61 packChar16(out, x.getChar16Data(), n);
|
62 jim.wunderlich 1.1 }
63 else
64 {
|
65 kumpf 1.7 packUint8(out, 8);
66 packSize(out, n);
67 const Char16* data = x.getChar16Data();
|
68 jim.wunderlich 1.1
|
69 kumpf 1.7 for (Uint32 i = 0; i < n; i++)
70 Packer::packUint8(out, (Uint8)data[i]);
|
71 jim.wunderlich 1.1 }
72 }
73
|
74 mike 1.3 void Packer::packSize(Buffer& out, Uint32 x)
|
75 jim.wunderlich 1.1 {
76 // Top two bits indicate the number of bytes used to
77 // pack this size:
78 //
79 // 00 : 1 byte
80 // 01 : 2 bytes
81 // 10 : 4 bytes
82 // 11 : illegal
83
84 if (x > 16383)
85 {
|
86 kumpf 1.7 // Use four bytes for size (tag == '1')
87 packUint32(out, 0x80000000 | x);
|
88 jim.wunderlich 1.1 }
89 else if (x > 63)
90 {
|
91 kumpf 1.7 // Use two bytes for size.
92 packUint16(out, 0x4000 | Uint16(x));
|
93 jim.wunderlich 1.1 }
94 else /* x > 1073741823 */
95 {
|
96 kumpf 1.7 // Use one byte for size.
97 packUint8(out, 0x00 | Uint8(x));
|
98 jim.wunderlich 1.1 }
99 }
100
|
101 mike 1.3 void Packer::unpackSize(const Buffer& in, Uint32& pos, Uint32& x)
|
102 jim.wunderlich 1.1 {
103 // Top two bits form a tag that indicates the number of bytes used to
104 // pack this size:
105 //
106 // 00 : 1 byte
107 // 01 : 2 bytes
108 // 10 : 4 bytes
109 // 11 : illegal
110
111 // Unpack first byte.
112
|
113 mike 1.4 Uint8 byte = Uint8(in[pos++]);
|
114 jim.wunderlich 1.1 Uint8 tag = byte & 0xC0;
115
|
116 mike 1.4 if (!tag)
117 {
|
118 kumpf 1.7 // One-byte size:
119 x = byte;
|
120 mike 1.4 }
121 else if (tag == 0x80)
|
122 jim.wunderlich 1.1 {
|
123 kumpf 1.7 // Four-byte size:
124 Uint8 b0 = tag ^ byte;
125 Uint8 b1;
126 Uint8 b2;
127 Uint8 b3;
128
129 Packer::unpackUint8(in, pos, b1);
130 Packer::unpackUint8(in, pos, b2);
131 Packer::unpackUint8(in, pos, b3);
132 Uint32 tmp = (Uint32(b0) << 24) |
133 (Uint32(b1) << 16) |
134 (Uint32(b2) << 8) |
135 (Uint32(b3));
|
136 jim.wunderlich 1.1
|
137 kumpf 1.7 x = tmp;
|
138 jim.wunderlich 1.1 }
139 else if (tag == 0x40)
140 {
|
141 kumpf 1.7 // Two-byte size:
142 x = (tag ^ byte) << 8;
143 Packer::unpackUint8(in, pos, byte);
144 x |= byte;
|
145 jim.wunderlich 1.1 }
146 else
147 {
|
148 kumpf 1.7 PEGASUS_DEBUG_ASSERT(0);
|
149 jim.wunderlich 1.1 }
150
|
151 jim.wunderlich 1.5 PEGASUS_DEBUG_ASSERT(pos <= in.size());
|
152 jim.wunderlich 1.1 }
153
154 template<class T>
|
155 mike 1.3 void _pack_array(Buffer& out, const T* x, Uint32 n)
|
156 jim.wunderlich 1.1 {
157 Uint32 bytes = n * sizeof(T);
158 out.reserveCapacity(out.size() + bytes);
159
160 if (Packer::isLittleEndian())
161 {
|
162 kumpf 1.7 for (size_t i = 0; i < n; i++)
163 {
164 T tmp = Packer::swap(x[i]);
165 out.append((char*)&tmp, sizeof(tmp));
166 }
|
167 jim.wunderlich 1.1 }
168 else
|
169 kumpf 1.7 out.append((char*)x, bytes);
|
170 jim.wunderlich 1.1 }
171
|
172 mike 1.3 void Packer::packBoolean(Buffer& out, const Boolean* x, Uint32 n)
|
173 jim.wunderlich 1.1 {
174 out.reserveCapacity(out.size() + n);
175
176 for (size_t i = 0; i < n; i++)
177 {
|
178 kumpf 1.7 Uint8 tmp = Uint8(x[i]);
179 out.append((char*)&tmp, sizeof(tmp));
|
180 jim.wunderlich 1.1 }
181 }
182
|
183 mike 1.3 void Packer::packUint8(Buffer& out, const Uint8* x, Uint32 n)
|
184 jim.wunderlich 1.1 {
185 out.append((char*)x, n);
186 }
187
|
188 mike 1.3 void Packer::packUint16(Buffer& out, const Uint16* x, Uint32 n)
|
189 jim.wunderlich 1.1 {
190 _pack_array(out, x, n);
191 }
192
|
193 mike 1.3 void Packer::packUint32(Buffer& out, const Uint32* x, Uint32 n)
|
194 jim.wunderlich 1.1 {
195 _pack_array(out, x, n);
196 }
197
|
198 mike 1.3 void Packer::packUint64(Buffer& out, const Uint64* x, Uint32 n)
|
199 jim.wunderlich 1.1 {
200 _pack_array(out, x, n);
201 }
202
|
203 mike 1.3 void Packer::packString(Buffer& out, const String* x, Uint32 n)
|
204 jim.wunderlich 1.1 {
205 for (size_t i = 0; i < n; i++)
|
206 kumpf 1.7 packString(out, x[i]);
|
207 jim.wunderlich 1.1 }
208
209 void Packer::unpackUint16(
|
210 mike 1.3 const Buffer& in, Uint32& pos, Uint16& x)
|
211 jim.wunderlich 1.1 {
212 memcpy(&x, &in[pos], sizeof(x));
213 pos += sizeof(x);
214
215 if (isLittleEndian())
|
216 kumpf 1.7 x = Packer::swapUint16(x);
|
217 jim.wunderlich 1.1 }
218
219 void Packer::unpackUint32(
|
220 mike 1.3 const Buffer& in, Uint32& pos, Uint32& x)
|
221 jim.wunderlich 1.1 {
222 memcpy(&x, &in[pos], sizeof(x));
223 pos += sizeof(x);
224
225 if (isLittleEndian())
|
226 kumpf 1.7 x = Packer::swapUint32(x);
|
227 jim.wunderlich 1.1
|
228 jim.wunderlich 1.5 PEGASUS_DEBUG_ASSERT(pos <= in.size());
|
229 jim.wunderlich 1.1 }
230
231 void Packer::unpackUint64(
|
232 mike 1.3 const Buffer& in, Uint32& pos, Uint64& x)
|
233 jim.wunderlich 1.1 {
234 memcpy(&x, &in[pos], sizeof(x));
235 pos += sizeof(x);
236
237 if (isLittleEndian())
|
238 kumpf 1.7 x = Packer::swapUint64(x);
|
239 jim.wunderlich 1.1
|
240 jim.wunderlich 1.5 PEGASUS_DEBUG_ASSERT(pos <= in.size());
|
241 jim.wunderlich 1.1 }
242
|
243 mike 1.3 void Packer::unpackString(const Buffer& in, Uint32& pos, String& x)
|
244 jim.wunderlich 1.1 {
245 // Determine whether packed as 8-bit or 16-bit.
246
|
247 mike 1.4 Uint8 bits = Uint8(in[pos++]);
|
248 jim.wunderlich 1.1
|
249 jim.wunderlich 1.5 PEGASUS_DEBUG_ASSERT(bits == 16 || bits == 8);
|
250 jim.wunderlich 1.1
251 // Unpack array size.
252
253 Uint32 n;
254 unpackSize(in, pos, n);
255
|
256 mike 1.4 if (bits & 8)
|
257 jim.wunderlich 1.1 {
|
258 kumpf 1.7 x.assign(&in[pos], n);
259 pos += n;
|
260 jim.wunderlich 1.1 }
261 else
262 {
|
263 kumpf 1.7 x.clear();
264 x.reserveCapacity(n);
|
265 jim.wunderlich 1.1
|
266 kumpf 1.7 for (size_t i = 0; i < n; i++)
267 {
268 Char16 tmp;
269 unpackChar16(in , pos, tmp);
270 x.append(tmp);
271 }
|
272 jim.wunderlich 1.1 }
273
|
274 jim.wunderlich 1.5 PEGASUS_DEBUG_ASSERT(pos <= in.size());
|
275 jim.wunderlich 1.1 }
276
277 void Packer::unpackBoolean(
|
278 mike 1.3 Buffer& in, Uint32& pos, Boolean* x, Uint32 n)
|
279 jim.wunderlich 1.1 {
280 for (size_t i = 0; i < n; i++)
|
281 kumpf 1.7 unpackBoolean(in, pos, x[i]);
|
282 jim.wunderlich 1.1
|
283 jim.wunderlich 1.5 PEGASUS_DEBUG_ASSERT(pos <= in.size());
|
284 jim.wunderlich 1.1 }
285
286 void Packer::unpackUint8(
|
287 mike 1.3 Buffer& in, Uint32& pos, Uint8* x, Uint32 n)
|
288 jim.wunderlich 1.1 {
289 for (size_t i = 0; i < n; i++)
|
290 kumpf 1.7 unpackUint8(in, pos, x[i]);
|
291 jim.wunderlich 1.1
|
292 jim.wunderlich 1.5 PEGASUS_DEBUG_ASSERT(pos <= in.size());
|
293 jim.wunderlich 1.1 }
294
295 void Packer::unpackUint16(
|
296 mike 1.3 Buffer& in, Uint32& pos, Uint16* x, Uint32 n)
|
297 jim.wunderlich 1.1 {
298 for (size_t i = 0; i < n; i++)
|
299 kumpf 1.7 unpackUint16(in, pos, x[i]);
|
300 jim.wunderlich 1.1
|
301 jim.wunderlich 1.5 PEGASUS_DEBUG_ASSERT(pos <= in.size());
|
302 jim.wunderlich 1.1 }
303
304 void Packer::unpackUint32(
|
305 mike 1.3 Buffer& in, Uint32& pos, Uint32* x, Uint32 n)
|
306 jim.wunderlich 1.1 {
307 for (size_t i = 0; i < n; i++)
|
308 kumpf 1.7 unpackUint32(in, pos, x[i]);
|
309 jim.wunderlich 1.1
|
310 jim.wunderlich 1.5 PEGASUS_DEBUG_ASSERT(pos <= in.size());
|
311 jim.wunderlich 1.1 }
312
313 void Packer::unpackUint64(
|
314 mike 1.3 Buffer& in, Uint32& pos, Uint64* x, Uint32 n)
|
315 jim.wunderlich 1.1 {
316 for (size_t i = 0; i < n; i++)
|
317 kumpf 1.7 unpackUint64(in, pos, x[i]);
|
318 jim.wunderlich 1.1
|
319 jim.wunderlich 1.5 PEGASUS_DEBUG_ASSERT(pos <= in.size());
|
320 jim.wunderlich 1.1 }
321
322 void Packer::unpackString(
|
323 mike 1.3 Buffer& in, Uint32& pos, String* x, Uint32 n)
|
324 jim.wunderlich 1.1 {
325 for (size_t i = 0; i < n; i++)
|
326 kumpf 1.7 unpackString(in, pos, x[i]);
|
327 jim.wunderlich 1.1
|
328 jim.wunderlich 1.5 PEGASUS_DEBUG_ASSERT(pos <= in.size());
|
329 jim.wunderlich 1.1 }
330
331 PEGASUS_NAMESPACE_END
|