Initial setup for CLion
This commit is contained in:
378
anslicensing/bitstruct.h
Normal file
378
anslicensing/bitstruct.h
Normal file
@@ -0,0 +1,378 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <map>
|
||||
|
||||
#include "bitstream.h"
|
||||
#include "uniconv.h"
|
||||
#include "except.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <alloca.h>
|
||||
#else
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
class BitStruct {
|
||||
|
||||
public:
|
||||
enum FIELD_TYPE
|
||||
{
|
||||
RAW,
|
||||
INTEGER,
|
||||
STRING,
|
||||
DATE14,
|
||||
DATE13,
|
||||
DATE16,
|
||||
};
|
||||
|
||||
private:
|
||||
class Field {
|
||||
public:
|
||||
Field():
|
||||
m_fieldType(FIELD_TYPE::INTEGER),
|
||||
m_offset(0),
|
||||
m_size(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Field(FIELD_TYPE fieldType, int offset, int size)
|
||||
{
|
||||
m_fieldType = fieldType;
|
||||
m_offset = offset;
|
||||
m_size = size;
|
||||
}
|
||||
|
||||
public:
|
||||
FIELD_TYPE m_fieldType;
|
||||
int m_offset;
|
||||
int m_size;
|
||||
};
|
||||
|
||||
typedef std::map<string, Field> FieldMap;
|
||||
|
||||
public:
|
||||
BitStruct(int bitSize = 0) :
|
||||
m_bits(bitSize)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BitStruct(vector<unsigned char>& buf, int bitSize):
|
||||
m_bits(buf, bitSize)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Create(int bitSize = 0)
|
||||
{
|
||||
m_bits.Create(bitSize);
|
||||
}
|
||||
|
||||
void Attach(vector<unsigned char>& buf, int bitSize)
|
||||
{
|
||||
m_bits.Attach(buf, bitSize);
|
||||
}
|
||||
|
||||
void AddField(const char * fieldName, FIELD_TYPE fieldType, int fieldBitSize, int offset = -1 )
|
||||
{
|
||||
if (offset == -1)
|
||||
offset = currentFieldOffset;
|
||||
|
||||
m_fieldMap.insert(FieldMap::value_type(fieldName, Field(fieldType, offset, fieldBitSize)));
|
||||
|
||||
currentFieldOffset = offset + fieldBitSize;
|
||||
}
|
||||
|
||||
bool GetField(const char * fieldName, FIELD_TYPE * fieldType, int * fieldSize, int * fieldOffset) const
|
||||
{
|
||||
FieldMap::const_iterator iter = m_fieldMap.find(fieldName);
|
||||
|
||||
if (iter == m_fieldMap.end())
|
||||
return false;
|
||||
|
||||
*fieldType = iter->second.m_fieldType;
|
||||
*fieldSize = iter->second.m_size;
|
||||
*fieldOffset = iter->second.m_offset;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EnumFields(void **enumHandle, const char **fieldName, FIELD_TYPE * fieldType, int * fieldSize, int * offset)
|
||||
{
|
||||
FieldMap::iterator * pIter;
|
||||
static string name;
|
||||
|
||||
if (*enumHandle == NULL)
|
||||
{
|
||||
pIter = new FieldMap::iterator(m_fieldMap.begin());
|
||||
if (!pIter)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
pIter = (FieldMap::iterator *)(*enumHandle);
|
||||
|
||||
if (*pIter == m_fieldMap.end())
|
||||
{
|
||||
delete pIter;
|
||||
return false;
|
||||
}
|
||||
|
||||
name = (*pIter)->first;
|
||||
*fieldName = name.c_str();
|
||||
|
||||
*fieldType = (*pIter)->second.m_fieldType;
|
||||
*fieldSize = (*pIter)->second.m_size;
|
||||
*offset = (*pIter)->second.m_offset;
|
||||
|
||||
pIter->operator ++(); // *Iter++ does not work. Think why :)
|
||||
|
||||
*enumHandle = pIter;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Set(const char * fieldName, const void * buf, unsigned len)
|
||||
{
|
||||
int offset = 0, size = m_bits.GetSize();
|
||||
|
||||
if (fieldName)
|
||||
{
|
||||
FieldMap::iterator iter;
|
||||
iter = m_fieldMap.find(fieldName);
|
||||
if (iter == m_fieldMap.end())
|
||||
throw new LicensingException(STATUS_FIELD_NOT_FOUND);
|
||||
|
||||
offset = iter->second.m_offset;
|
||||
size = iter->second.m_size;
|
||||
}
|
||||
|
||||
m_bits.Seek(offset);
|
||||
|
||||
int bitlen = len << 3;
|
||||
|
||||
if (bitlen >= size)
|
||||
m_bits.Write(buf, size);
|
||||
else
|
||||
{
|
||||
int bits = size - bitlen;
|
||||
unsigned char * zeroes = (unsigned char *)_alloca((bits + 7) >> 3);
|
||||
memset(zeroes, 0, (bits + 7) >> 3);
|
||||
m_bits.Write(buf, bitlen);
|
||||
m_bits.Write(zeroes, bits);
|
||||
}
|
||||
}
|
||||
|
||||
void Set(const char * fieldName, const char * data)
|
||||
{
|
||||
Set(fieldName, data, (unsigned)strlen(data));
|
||||
}
|
||||
|
||||
void Set(const char * fieldName, int data)
|
||||
{
|
||||
#ifndef LICENSING_BIG_ENDIAN
|
||||
Set(fieldName, &data, sizeof(data));
|
||||
#else
|
||||
unsigned char buf[sizeof(int)] = { 0, 0, 0, 0 };
|
||||
|
||||
buf[0] = (unsigned char)(data & 0xFF);
|
||||
buf[1] = (unsigned char)((data >> 8) & 0xFF);
|
||||
buf[2] = (unsigned char)((data >> 16) & 0xFF);
|
||||
buf[3] = (unsigned char)((data >> 24) & 0xFF);
|
||||
|
||||
Set(fieldName, buf, sizeof(data));
|
||||
#endif
|
||||
}
|
||||
|
||||
void Set(const char * fieldName, int year, int month, int day)
|
||||
{
|
||||
FieldMap::iterator iter;
|
||||
iter = m_fieldMap.find(fieldName);
|
||||
if (iter == m_fieldMap.end() )
|
||||
throw new LicensingException(STATUS_FIELD_NOT_FOUND);
|
||||
|
||||
int date;
|
||||
|
||||
switch (iter->second.m_fieldType)
|
||||
{
|
||||
case FIELD_TYPE_DATE13:
|
||||
date = PackDate13(year, month, day);
|
||||
break;
|
||||
|
||||
case FIELD_TYPE_DATE14:
|
||||
date = PackDate14(year, month, day);
|
||||
break;
|
||||
|
||||
case FIELD_TYPE_DATE16:
|
||||
date = PackDate16(year, month, day);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new LicensingException(STATUS_INVALID_PARAM, "A data value is being set to a non-date field");
|
||||
}
|
||||
|
||||
Set(fieldName, date);
|
||||
}
|
||||
|
||||
void Get(const char * dataField, void * buf, int * len)
|
||||
{
|
||||
if (dataField)
|
||||
{
|
||||
FieldMap::const_iterator iter;
|
||||
|
||||
iter = m_fieldMap.find(dataField);
|
||||
if ( iter == m_fieldMap.end() )
|
||||
throw new LicensingException(STATUS_FIELD_NOT_FOUND);
|
||||
|
||||
if ( *len < ( iter->second.m_size + 7 ) >> 3 )
|
||||
throw new LicensingException(STATUS_BUFFER_TOO_SMALL);
|
||||
|
||||
m_bits.Seek(iter->second.m_offset);
|
||||
m_bits.Read(buf, iter->second.m_size);
|
||||
|
||||
*len = (iter->second.m_size + 7) >> 3;
|
||||
} else
|
||||
{
|
||||
int validationDataLen = (m_bits.GetSize() + 7) >> 3;
|
||||
|
||||
if (*len < validationDataLen)
|
||||
{
|
||||
*len = validationDataLen;
|
||||
throw new LicensingException(STATUS_BUFFER_TOO_SMALL);
|
||||
}
|
||||
|
||||
memcpy(buf, m_bits.GetBuffer(), validationDataLen);
|
||||
*len = validationDataLen;
|
||||
}
|
||||
}
|
||||
|
||||
int GetInt(const char * dataField)
|
||||
{
|
||||
FieldMap::const_iterator iter;
|
||||
|
||||
iter = m_fieldMap.find(dataField);
|
||||
if ( iter == m_fieldMap.end() )
|
||||
throw new LicensingException(STATUS_FIELD_NOT_FOUND);
|
||||
|
||||
unsigned char buf[sizeof(int)] = {0, 0, 0, 0};
|
||||
|
||||
if ( sizeof(buf) < ( iter->second.m_size + 7 ) >> 3 )
|
||||
throw new LicensingException(STATUS_BUFFER_TOO_SMALL);
|
||||
|
||||
m_bits.Seek(iter->second.m_offset);
|
||||
m_bits.Read(buf, iter->second.m_size);
|
||||
|
||||
#ifndef LICENSING_BIG_ENDIAN
|
||||
return *(int *)buf;
|
||||
#else
|
||||
return ((int)buf[3] << 24) | ((int)buf[2] << 16) | ((int)buf[1] << 8) | (int)buf[0];
|
||||
#endif
|
||||
}
|
||||
|
||||
void GetDate(const char * dataField, int * year, int * month, int * day)
|
||||
{
|
||||
FieldMap::const_iterator iter;
|
||||
|
||||
iter = m_fieldMap.find(dataField);
|
||||
if ( iter == m_fieldMap.end() )
|
||||
throw new LicensingException(STATUS_FIELD_NOT_FOUND);
|
||||
|
||||
unsigned short packedDate = (unsigned short)GetInt(dataField);
|
||||
|
||||
switch (iter->second.m_fieldType)
|
||||
{
|
||||
case FIELD_TYPE_DATE13:
|
||||
UnpackDate13(packedDate, year, month, day);
|
||||
break;
|
||||
|
||||
case FIELD_TYPE_DATE14:
|
||||
UnpackDate14(packedDate, year, month, day);
|
||||
break;
|
||||
|
||||
case FIELD_TYPE_DATE16:
|
||||
UnpackDate16(packedDate, year, month, day);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new LicensingException(STATUS_INVALID_PARAM, "An attempt was made to query a date from a non-date field");
|
||||
}
|
||||
}
|
||||
|
||||
void * GetBuffer(int * sizeInBits = NULL)
|
||||
{
|
||||
return m_bits.GetBuffer(sizeInBits);
|
||||
}
|
||||
|
||||
BitStream& GetBitStream()
|
||||
{
|
||||
return m_bits;
|
||||
}
|
||||
|
||||
int GetCurrentFieldOffset()
|
||||
{
|
||||
return currentFieldOffset;
|
||||
}
|
||||
|
||||
void ResetFieldOffset()
|
||||
{
|
||||
currentFieldOffset = 0;
|
||||
}
|
||||
|
||||
int GetSize()
|
||||
{
|
||||
return m_bits.GetSize();
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned short PackDate13(int year, int month, int day)
|
||||
{
|
||||
if (year < 2012 || year > 2027)
|
||||
throw new LicensingException(STATUS_INVALID_PARAM, "Invalid year for a 13-bit date. Allowed values are 2012-2027");
|
||||
|
||||
return (unsigned short)(((month - 1) << 9) | ((day - 1) << 4) | (year - 2012));
|
||||
}
|
||||
|
||||
void UnpackDate13(unsigned short packedDate, int * year, int * month, int * day)
|
||||
{
|
||||
*year = 2012 + (packedDate & 0x0F);
|
||||
*month = 1 + (packedDate >> 9);
|
||||
*day = 1 + ((packedDate >> 4) & 0x1F);
|
||||
}
|
||||
|
||||
unsigned short PackDate14(int year, int month, int day)
|
||||
{
|
||||
if (year < 2010 || year > 2041)
|
||||
throw new LicensingException(STATUS_INVALID_PARAM, "Invalid year for a 14-bit date. Allowed values are 2010-2041");
|
||||
|
||||
return (unsigned short)(((month - 1) << 10) | ((day - 1) << 5) | (year - 2010));
|
||||
}
|
||||
|
||||
void UnpackDate14(unsigned short packedDate, int * year, int * month, int * day)
|
||||
{
|
||||
*year = 2010 + (packedDate & 0x1F);
|
||||
*month = 1 + (packedDate >> 10);
|
||||
*day = 1 + ((packedDate >> 5) & 0x1F);
|
||||
}
|
||||
|
||||
unsigned short PackDate16(int year, int month, int day)
|
||||
{
|
||||
if (year < 2000 || year > 2127)
|
||||
throw new LicensingException(STATUS_INVALID_PARAM, "Invalid year for a 16-bit date. Allowed values are 2010-2127");
|
||||
|
||||
return (unsigned short)(((year - 2000) << 9) | (month << 5) | day);
|
||||
}
|
||||
|
||||
void UnpackDate16(unsigned short packedDate, int * year, int * month, int * day)
|
||||
{
|
||||
*year = 2000 + (packedDate >> 9);
|
||||
*month = (packedDate & 0x01FF) >> 5;
|
||||
*day = packedDate & 0x001F;
|
||||
}
|
||||
|
||||
FieldMap m_fieldMap;
|
||||
BitStream m_bits;
|
||||
int currentFieldOffset;
|
||||
};
|
||||
Reference in New Issue
Block a user