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

  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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2