VariableLengthSerialise.h
// VariableLengthSerialise.h
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2009
#pragma once
#ifndef Ceda_cxUtils_VariableLengthSerialise_H
#define Ceda_cxUtils_VariableLengthSerialise_H
#include "cxUtils.h"
#include "BasicTypeSizes.h"
/*
Overflow version
----------------
Allows for sending of unsigned integer values in the range 0..2^29-1 (0..536870911) - i.e.
up to about 500 million, using less bytes for smaller numbers if possible.
Byte order : Send the most significant byte first
Range Num bytes Format
to send
--------------------------------------------------
0..2^7-1 send 1 byte 0 + 7 bits
2^7..2^14-1 send 2 bytes 10 + 14=6+8 bits
2^14..2^21-1 send 3 bytes 110 + 21=5+8+8 bits
2^21..2^28-1 send 4 bytes 111 + 29=5+8+8+8 bits
2^7 = 1000 0000 = 0x00000080
2^14 = 0100 0000 0000 0000 = 0x00004000
2^21 = 0010 0000 0000 0000 0000 0000 = 0x00200000
2^29 = 0010 0000 0000 0000 0000 0000 0000 0000 = 0x20000000
1110 0000 0000 0000 0000 0000 0000 0000 = 0xE0000000
No overflow version
-------------------
Similar to the above except we allow for 5 bytes to be written to the archive to accomodate
the full range of an unsigned int32.
Byte order : Send the most significant byte first
Range Num bytes Format
to send
--------------------------------------------------
0..2^7-1 send 1 byte 0 + 7 bits
2^7..2^14-1 send 2 bytes 10 + 14=6+8 bits
2^14..2^21-1 send 3 bytes 110 + 21=5+8+8 bits
2^21..2^28-1 send 4 bytes 1110 + 28=4+8+8+8 bits
2^28..2^32-1 send 5 bytes 11110000 + 32=8+8+8+8 bits
Escape code support
-------------------
The no overflow version can represent up to 15 "escape codes" that only take up a single byte
In binary representation these are of the form
1111XXXX
where XXXX is not equal to 0000 (since 0xF0 is reserved for sending the 5 byte sequence)
An implementation could use these for efficient "escape codes", that cannot be confused with values
in the range 0..2^32-1
*/
namespace ceda
{
const ssize_t MAX_VARIABLE_LENGTH_UINT_SIZE = 5;
/////////// uint32
// Calculates the number of bytes uses for the variable length representation of v
// Returns a value in range 1..5 inclusive
cxUtils_API ssize_t GetSizeVariableLengthUint32(uint32 v);
// Write the variable length representation of v at memory address p and returns the
// next memory address write position, which is p+n where 1 <= n <= 5
cxUtils_API octet_t* SerialiseVariableLengthUint32(octet_t* p, uint32 v);
// Reads a variable length integer at memory address p into out-parameter v.
// Returns the next memory read position which is p+n where 1 <= n <= 5.
cxUtils_API const octet_t* DeserialiseVariableLengthUint32(const octet_t* p, uint32& v);
// Version that allows for escape codes
cxUtils_API const octet_t* DeserialiseVariableLengthUint32(const octet_t* p, uint32& v, bool& escape);
/////////// T
template<typename T>
inline ssize_t GetSizeVariableLengthInteger(T v)
{
return GetSizeVariableLengthUint32( (uint32) v );
}
template<typename T>
inline octet_t* SerialiseVariableLengthInteger(octet_t* p, T v)
{
return SerialiseVariableLengthUint32(p, (uint32) v);
}
template<typename T>
inline const octet_t* DeserialiseVariableLengthInteger(const octet_t* p, T& v)
{
uint32 v32;
p = DeserialiseVariableLengthUint32(p,v32);
v = (T) v32;
return p;
}
template<typename T>
inline const octet_t* DeserialiseVariableLengthInteger(const octet_t* p, T& v, bool& escape)
{
uint32 v32;
p = DeserialiseVariableLengthUint32(p,v32,escape);
v = (T) v32;
return p;
}
} // namespace ceda
#endif // include guard