(file) Return to Packer.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Repository

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2