core/CDataPack.cpp
author Scott Ehlert <ds@alliedmods.net>
Mon May 14 21:29:17 2007 +0000 (2007-05-14)
changeset 794 5947b0ee60bb
parent 653 ef60870067ff
child 1231 17badaf66ce4
permissions -rw-r--r--
Implemented amb286 - .smx extension no longer required with "sm plugins load"
faluco@490
     1
/**
ds@653
     2
 * vim: set ts=4 :
ds@653
     3
 * ===============================================================
ds@653
     4
 * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
ds@653
     5
 * ===============================================================
ds@653
     6
 *
ds@653
     7
 * This file is not open source and may not be copied without explicit
ds@653
     8
 * written permission of AlliedModders LLC.  This file may not be redistributed 
ds@653
     9
 * in whole or significant part.
ds@653
    10
 * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
ds@653
    11
 *
ds@653
    12
 * Version: $Id$
ds@653
    13
 */
faluco@490
    14
faluco@484
    15
#include <malloc.h>
faluco@484
    16
#include <string.h>
faluco@484
    17
#include "CDataPack.h"
faluco@484
    18
faluco@489
    19
#define DATAPACK_INITIAL_SIZE		512
faluco@484
    20
faluco@484
    21
CDataPack::CDataPack()
faluco@484
    22
{
faluco@484
    23
	m_pBase = (char *)malloc(DATAPACK_INITIAL_SIZE);
faluco@484
    24
	m_capacity = DATAPACK_INITIAL_SIZE;
faluco@484
    25
	Initialize();
faluco@484
    26
}
faluco@484
    27
faluco@484
    28
CDataPack::~CDataPack()
faluco@484
    29
{
faluco@484
    30
	free(m_pBase);
faluco@484
    31
}
faluco@484
    32
faluco@484
    33
void CDataPack::Initialize()
faluco@484
    34
{
faluco@484
    35
	m_curptr = m_pBase;
faluco@484
    36
	m_size = 0;
faluco@484
    37
}
faluco@484
    38
faluco@484
    39
void CDataPack::CheckSize(size_t typesize)
faluco@484
    40
{
faluco@484
    41
	if (m_curptr - m_pBase + typesize <= m_capacity)
faluco@484
    42
	{
faluco@484
    43
		return;
faluco@484
    44
	}
faluco@484
    45
faluco@484
    46
	size_t pos = m_curptr - m_pBase;
faluco@484
    47
	do
faluco@484
    48
	{
faluco@484
    49
		m_capacity *= 2;
faluco@484
    50
		m_pBase = (char *)realloc(m_pBase, m_capacity);
faluco@484
    51
		m_curptr = m_pBase + pos;
faluco@484
    52
	} while (m_curptr - m_pBase + typesize > m_capacity);
faluco@484
    53
}
faluco@484
    54
faluco@484
    55
void CDataPack::ResetSize()
faluco@484
    56
{
faluco@484
    57
	m_size = 0;
faluco@484
    58
}
faluco@484
    59
faluco@484
    60
size_t CDataPack::CreateMemory(size_t size, void **addr)
faluco@484
    61
{
faluco@488
    62
	CheckSize(sizeof(size_t) + size);
faluco@484
    63
	size_t pos = m_curptr - m_pBase;
faluco@484
    64
faluco@488
    65
	*(size_t *)m_curptr = size;
faluco@488
    66
	m_curptr += sizeof(size_t);
faluco@484
    67
faluco@484
    68
	if (addr)
faluco@484
    69
	{
faluco@488
    70
		*addr = m_curptr;
faluco@484
    71
	}
faluco@484
    72
faluco@488
    73
	m_curptr += size;
faluco@488
    74
	m_size += sizeof(size_t) + size;
faluco@488
    75
faluco@484
    76
	return pos;
faluco@484
    77
}
faluco@484
    78
faluco@484
    79
void CDataPack::PackCell(cell_t cell)
faluco@484
    80
{
faluco@488
    81
	CheckSize(sizeof(size_t) + sizeof(cell_t));
faluco@488
    82
faluco@488
    83
	*(size_t *)m_curptr = sizeof(cell_t);
faluco@488
    84
	m_curptr += sizeof(size_t);
faluco@484
    85
faluco@484
    86
	*(cell_t *)m_curptr = cell;
faluco@484
    87
	m_curptr += sizeof(cell_t);
faluco@488
    88
faluco@488
    89
	m_size += sizeof(size_t) + sizeof(cell_t);
faluco@484
    90
}
faluco@484
    91
faluco@484
    92
void CDataPack::PackFloat(float val)
faluco@484
    93
{
faluco@488
    94
	CheckSize(sizeof(size_t) + sizeof(float));
faluco@488
    95
faluco@488
    96
	*(size_t *)m_curptr = sizeof(float);
faluco@488
    97
	m_curptr += sizeof(size_t);
faluco@484
    98
faluco@484
    99
	*(float *)m_curptr = val;
faluco@484
   100
	m_curptr += sizeof(float);
faluco@488
   101
faluco@488
   102
	m_size += sizeof(size_t) + sizeof(float);
faluco@484
   103
}
faluco@484
   104
faluco@484
   105
void CDataPack::PackString(const char *string)
faluco@484
   106
{
faluco@484
   107
	size_t len = strlen(string);
faluco@484
   108
	size_t maxsize = sizeof(size_t) + len + 1;
faluco@484
   109
	CheckSize(maxsize);
faluco@484
   110
faluco@484
   111
	// Pack the string length first for buffer overrun checking.
faluco@484
   112
	*(size_t *)m_curptr = len;
faluco@484
   113
	m_curptr += sizeof(size_t);
faluco@484
   114
faluco@484
   115
	// Now pack the string.
faluco@484
   116
	memcpy(m_curptr, string, len);
faluco@484
   117
	m_curptr[len] = '\0';
faluco@484
   118
	m_curptr += len + 1;
faluco@484
   119
faluco@484
   120
	m_size += maxsize;
faluco@484
   121
}
faluco@484
   122
faluco@484
   123
void CDataPack::Reset() const
faluco@484
   124
{
faluco@484
   125
	m_curptr = m_pBase;
faluco@484
   126
}
faluco@484
   127
faluco@484
   128
size_t CDataPack::GetPosition() const
faluco@484
   129
{
faluco@484
   130
	return static_cast<size_t>(m_curptr - m_pBase);
faluco@484
   131
}
faluco@484
   132
faluco@484
   133
bool CDataPack::SetPosition(size_t pos) const
faluco@484
   134
{
faluco@484
   135
	if (pos > m_size-1)
faluco@484
   136
	{
faluco@484
   137
		return false;
faluco@484
   138
	}
faluco@484
   139
	m_curptr = m_pBase + pos;
faluco@484
   140
faluco@484
   141
	return true;
faluco@484
   142
}
faluco@484
   143
faluco@484
   144
cell_t CDataPack::ReadCell() const
faluco@484
   145
{
faluco@488
   146
	if (!IsReadable(sizeof(size_t) + sizeof(cell_t)))
faluco@484
   147
	{
faluco@484
   148
		return 0;
faluco@484
   149
	}
faluco@488
   150
	if (*reinterpret_cast<size_t *>(m_curptr) != sizeof(cell_t))
faluco@488
   151
	{
faluco@488
   152
		return 0;
faluco@488
   153
	}
faluco@488
   154
faluco@488
   155
	m_curptr += sizeof(size_t);
faluco@488
   156
faluco@484
   157
	cell_t val = *reinterpret_cast<cell_t *>(m_curptr);
faluco@484
   158
	m_curptr += sizeof(cell_t);
faluco@484
   159
	return val;
faluco@484
   160
}
faluco@484
   161
faluco@484
   162
float CDataPack::ReadFloat() const
faluco@484
   163
{
faluco@488
   164
	if (!IsReadable(sizeof(size_t) + sizeof(float)))
faluco@484
   165
	{
faluco@484
   166
		return 0;
faluco@484
   167
	}
faluco@488
   168
	if (*reinterpret_cast<size_t *>(m_curptr) != sizeof(float))
faluco@488
   169
	{
faluco@488
   170
		return 0;
faluco@488
   171
	}
faluco@488
   172
faluco@488
   173
	m_curptr += sizeof(size_t);
faluco@488
   174
faluco@484
   175
	float val = *reinterpret_cast<float *>(m_curptr);
faluco@484
   176
	m_curptr += sizeof(float);
faluco@484
   177
	return val;
faluco@484
   178
}
faluco@484
   179
faluco@484
   180
bool CDataPack::IsReadable(size_t bytes) const
faluco@484
   181
{
faluco@484
   182
	return (bytes + (m_curptr - m_pBase) > m_size) ? false : true;
faluco@484
   183
}
faluco@484
   184
faluco@484
   185
const char *CDataPack::ReadString(size_t *len) const
faluco@484
   186
{
faluco@484
   187
	if (!IsReadable(sizeof(size_t)))
faluco@484
   188
	{
faluco@488
   189
		return NULL;
faluco@484
   190
	}
faluco@484
   191
faluco@484
   192
	size_t real_len = *(size_t *)m_curptr;
faluco@484
   193
faluco@484
   194
	m_curptr += sizeof(size_t);
faluco@484
   195
	char *str = (char *)m_curptr;
faluco@484
   196
faluco@484
   197
	if ((strlen(str) != real_len) || !(IsReadable(real_len+1)))
faluco@484
   198
	{
faluco@484
   199
		return NULL;
faluco@484
   200
	}
faluco@484
   201
faluco@484
   202
	if (len)
faluco@484
   203
	{
faluco@484
   204
		*len = real_len;
faluco@484
   205
	}
faluco@484
   206
faluco@484
   207
	m_curptr += real_len + 1;
faluco@484
   208
faluco@484
   209
	return str;
faluco@484
   210
}
faluco@484
   211
faluco@484
   212
void *CDataPack::GetMemory() const
faluco@484
   213
{
faluco@484
   214
	return m_curptr;
faluco@484
   215
}
faluco@488
   216
faluco@488
   217
void *CDataPack::ReadMemory(size_t *size) const
faluco@488
   218
{
faluco@488
   219
	if (!IsReadable(sizeof(size_t)))
faluco@488
   220
	{
faluco@488
   221
		return NULL;
faluco@488
   222
	}
faluco@488
   223
faluco@488
   224
	size_t bytecount = *(size_t *)m_curptr;
faluco@488
   225
	m_curptr += sizeof(size_t);
faluco@488
   226
faluco@488
   227
	if (!IsReadable(bytecount))
faluco@488
   228
	{
faluco@488
   229
		return NULL;
faluco@488
   230
	}
faluco@488
   231
faluco@488
   232
	void *ptr = m_curptr;
faluco@488
   233
faluco@488
   234
	if (size)
faluco@488
   235
	{
faluco@488
   236
		*size = bytecount;
faluco@488
   237
	}
faluco@488
   238
faluco@488
   239
	m_curptr += bytecount;
faluco@488
   240
faluco@488
   241
	return ptr;
faluco@488
   242
}