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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2