core/CDataPack.cpp
author Borja Ferrer <faluco@alliedmods.net>
Tue Feb 13 16:11:04 2007 +0000 (2007-02-13)
changeset 484 d254e257cac2
child 488 daf1bd692ef3
permissions -rw-r--r--
initial implementation of data packs
     1 #include <malloc.h>
     2 #include <string.h>
     3 #include "CDataPack.h"
     4 
     5 #define DATAPACK_INITIAL_SIZE		512
     6 
     7 CDataPack::CDataPack()
     8 {
     9 	m_pBase = (char *)malloc(DATAPACK_INITIAL_SIZE);
    10 	m_capacity = DATAPACK_INITIAL_SIZE;
    11 	Initialize();
    12 }
    13 
    14 CDataPack::~CDataPack()
    15 {
    16 	free(m_pBase);
    17 }
    18 
    19 void CDataPack::Initialize()
    20 {
    21 	m_curptr = m_pBase;
    22 	m_size = 0;
    23 }
    24 
    25 void CDataPack::CheckSize(size_t typesize)
    26 {
    27 	if (m_curptr - m_pBase + typesize <= m_capacity)
    28 	{
    29 		return;
    30 	}
    31 
    32 	size_t pos = m_curptr - m_pBase;
    33 	do
    34 	{
    35 		m_capacity *= 2;
    36 		m_pBase = (char *)realloc(m_pBase, m_capacity);
    37 		m_curptr = m_pBase + pos;
    38 	} while (m_curptr - m_pBase + typesize > m_capacity);
    39 }
    40 
    41 void CDataPack::ResetSize()
    42 {
    43 	m_size = 0;
    44 }
    45 
    46 size_t CDataPack::CreateMemory(size_t size, void **addr)
    47 {
    48 	size_t pos = m_curptr - m_pBase;
    49 
    50 	m_pBase = (char *)realloc(m_pBase, size);
    51 	m_curptr = m_pBase + pos;
    52 	m_capacity = size;
    53 
    54 	if (addr)
    55 	{
    56 		*addr = m_pBase;
    57 	}
    58 
    59 	return pos;
    60 }
    61 
    62 void CDataPack::PackCell(cell_t cell)
    63 {
    64 	CheckSize(sizeof(cell_t));
    65 
    66 	*(cell_t *)m_curptr = cell;
    67 	m_curptr += sizeof(cell_t);
    68 	m_size += sizeof(cell_t);
    69 }
    70 
    71 void CDataPack::PackFloat(float val)
    72 {
    73 	CheckSize(sizeof(float));
    74 
    75 	*(float *)m_curptr = val;
    76 	m_curptr += sizeof(float);
    77 	m_size += sizeof(float);
    78 }
    79 
    80 void CDataPack::PackString(const char *string)
    81 {
    82 	size_t len = strlen(string);
    83 	size_t maxsize = sizeof(size_t) + len + 1;
    84 	CheckSize(maxsize);
    85 
    86 	// Pack the string length first for buffer overrun checking.
    87 	*(size_t *)m_curptr = len;
    88 	m_curptr += sizeof(size_t);
    89 
    90 	// Now pack the string.
    91 	memcpy(m_curptr, string, len);
    92 	m_curptr[len] = '\0';
    93 	m_curptr += len + 1;
    94 
    95 	m_size += maxsize;
    96 }
    97 
    98 void CDataPack::Reset() const
    99 {
   100 	m_curptr = m_pBase;
   101 }
   102 
   103 size_t CDataPack::GetPosition() const
   104 {
   105 	return static_cast<size_t>(m_curptr - m_pBase);
   106 }
   107 
   108 bool CDataPack::SetPosition(size_t pos) const
   109 {
   110 	if (pos > m_size-1)
   111 	{
   112 		return false;
   113 	}
   114 	m_curptr = m_pBase + pos;
   115 
   116 	return true;
   117 }
   118 
   119 cell_t CDataPack::ReadCell() const
   120 {
   121 	if (!IsReadable(sizeof(cell_t)))
   122 	{
   123 		return 0;
   124 	}
   125 	cell_t val = *reinterpret_cast<cell_t *>(m_curptr);
   126 	m_curptr += sizeof(cell_t);
   127 	return val;
   128 }
   129 
   130 float CDataPack::ReadFloat() const
   131 {
   132 	if (!IsReadable(sizeof(float)))
   133 	{
   134 		return 0;
   135 	}
   136 	float val = *reinterpret_cast<float *>(m_curptr);
   137 	m_curptr += sizeof(float);
   138 	return val;
   139 }
   140 
   141 bool CDataPack::IsReadable(size_t bytes) const
   142 {
   143 	return (bytes + (m_curptr - m_pBase) > m_size) ? false : true;
   144 }
   145 
   146 const char *CDataPack::ReadString(size_t *len) const
   147 {
   148 	if (!IsReadable(sizeof(size_t)))
   149 	{
   150 		return 0;
   151 	}
   152 
   153 	size_t real_len = *(size_t *)m_curptr;
   154 
   155 	m_curptr += sizeof(size_t);
   156 	char *str = (char *)m_curptr;
   157 
   158 	if ((strlen(str) != real_len) || !(IsReadable(real_len+1)))
   159 	{
   160 		return NULL;
   161 	}
   162 
   163 	if (len)
   164 	{
   165 		*len = real_len;
   166 	}
   167 
   168 	m_curptr += real_len + 1;
   169 
   170 	return str;
   171 }
   172 
   173 void *CDataPack::GetMemory() const
   174 {
   175 	return m_curptr;
   176 }