// Variable length quantity
//
// Simplified code as example for the variable length integers.
//
// by feyd//godX.de
#include <cstdint>
#include <stdio.h>
#include <stdlib.h>
class CVariableLengthInteger
{
public:
CVariableLengthInteger() : m_nInteger(0) {}
CVariableLengthInteger(unsigned int nInteger) : m_nInteger(nInteger) {}
virtual ~CVariableLengthInteger() {}
operator unsigned int()
{
return m_nInteger;
}
CVariableLengthInteger& operator=(unsigned int nInteger)
{
m_nInteger = nInteger;
return *this;
}
size_t Encode(uint8_t* pBuffer, size_t nSize)
{
size_t nPos = 0;
unsigned int nCopy = m_nInteger;
while(nSize>0)
{
nSize--;
uint8_t nValue = nCopy&0x7F;
nCopy >>= 7;
if(nCopy>0)
nValue |= 0x80;
pBuffer[nPos++] = nValue;
if(nCopy==0)
break;
}
return nPos;
}
size_t Decode(const uint8_t* pBuffer, size_t nSize)
{
size_t nPos = 0;
m_nInteger = 0;
int nBit = 0;
while(nSize>0)
{
nSize--;
uint8_t nValue = pBuffer[nPos++];
m_nInteger |= (nValue&0x7F)<<nBit;
nBit+=7;
if(!(nValue&0x80))
break;
}
return nPos;
}
private:
unsigned int m_nInteger;
};
const size_t nBufferSize = 1024;
// Application entry point (from libc)
int main(int argc, const char* argv[])
{
printf("Variable length integer test...\r\n\r\n");
uint8_t buffer[nBufferSize];
size_t nBufferInput = 0;
for(int n=1; n<argc; n++)
{
CVariableLengthInteger vli(atoi(argv[n]));
nBufferInput += vli.Encode(&buffer[nBufferInput], nBufferSize-nBufferInput);
}
printf(" Encoded byte stream:\r\n");
printf(" ");
for(size_t n=0; n<nBufferInput; n++)
printf(" %02x", buffer[n]);
printf("\r\n\r\n");
printf(" Decoded values:\r\n");
size_t nBufferOutput = 0;
for(int n=1; n<argc; n++)
{
CVariableLengthInteger vli;
nBufferOutput += vli.Decode(&buffer[nBufferOutput], nBufferSize-nBufferOutput);
printf(" %d. %d\r\n", n, (unsigned int)vli);
}
return 0;
}