core/CDataPack.cpp
author Scott Ehlert <ds@alliedmods.net>
Sat Jul 12 09:05:19 2008 +0000 (2008-07-12)
changeset 2201 d2b8bc01ccd8
parent 1952 b7aa2b626807
child 2289 44045ead61cd
permissions -rw-r--r--
Builds against latest OB SDK now
ds@1952
     1
/**
ds@1952
     2
 * vim: set ts=4 :
ds@1952
     3
 * =============================================================================
ds@1952
     4
 * SourceMod
ds@1952
     5
 * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
ds@1952
     6
 * =============================================================================
ds@1952
     7
 *
ds@1952
     8
 * This program is free software; you can redistribute it and/or modify it under
ds@1952
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
ds@1952
    10
 * Free Software Foundation.
ds@1952
    11
 * 
ds@1952
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
ds@1952
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
ds@1952
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
ds@1952
    15
 * details.
ds@1952
    16
 *
ds@1952
    17
 * You should have received a copy of the GNU General Public License along with
ds@1952
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
ds@1952
    19
 *
ds@1952
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
ds@1952
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
ds@1952
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
ds@1952
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
ds@1952
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
ds@1952
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
ds@1952
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
ds@1952
    27
 * or <http://www.sourcemod.net/license.php>.
ds@1952
    28
 *
ds@1952
    29
 * Version: $Id$
ds@1952
    30
 */
ds@1952
    31
ds@1952
    32
#include <malloc.h>
ds@1952
    33
#include <string.h>
ds@1952
    34
#include "CDataPack.h"
ds@1952
    35
ds@1952
    36
#define DATAPACK_INITIAL_SIZE		512
ds@1952
    37
ds@1952
    38
CDataPack::CDataPack()
ds@1952
    39
{
ds@1952
    40
	m_pBase = (char *)malloc(DATAPACK_INITIAL_SIZE);
ds@1952
    41
	m_capacity = DATAPACK_INITIAL_SIZE;
ds@1952
    42
	Initialize();
ds@1952
    43
}
ds@1952
    44
ds@1952
    45
CDataPack::~CDataPack()
ds@1952
    46
{
ds@1952
    47
	free(m_pBase);
ds@1952
    48
}
ds@1952
    49
ds@1952
    50
void CDataPack::Initialize()
ds@1952
    51
{
ds@1952
    52
	m_curptr = m_pBase;
ds@1952
    53
	m_size = 0;
ds@1952
    54
}
ds@1952
    55
ds@1952
    56
void CDataPack::CheckSize(size_t typesize)
ds@1952
    57
{
ds@1952
    58
	if (m_curptr - m_pBase + typesize <= m_capacity)
ds@1952
    59
	{
ds@1952
    60
		return;
ds@1952
    61
	}
ds@1952
    62
ds@1952
    63
	size_t pos = m_curptr - m_pBase;
ds@1952
    64
	do
ds@1952
    65
	{
ds@1952
    66
		m_capacity *= 2;
ds@1952
    67
		m_pBase = (char *)realloc(m_pBase, m_capacity);
ds@1952
    68
		m_curptr = m_pBase + pos;
ds@1952
    69
	} while (m_curptr - m_pBase + typesize > m_capacity);
ds@1952
    70
}
ds@1952
    71
ds@1952
    72
void CDataPack::ResetSize()
ds@1952
    73
{
ds@1952
    74
	m_size = 0;
ds@1952
    75
}
ds@1952
    76
ds@1952
    77
size_t CDataPack::CreateMemory(size_t size, void **addr)
ds@1952
    78
{
ds@1952
    79
	CheckSize(sizeof(size_t) + size);
ds@1952
    80
	size_t pos = m_curptr - m_pBase;
ds@1952
    81
ds@1952
    82
	*(size_t *)m_curptr = size;
ds@1952
    83
	m_curptr += sizeof(size_t);
ds@1952
    84
ds@1952
    85
	if (addr)
ds@1952
    86
	{
ds@1952
    87
		*addr = m_curptr;
ds@1952
    88
	}
ds@1952
    89
ds@1952
    90
	m_curptr += size;
ds@1952
    91
	m_size += sizeof(size_t) + size;
ds@1952
    92
ds@1952
    93
	return pos;
ds@1952
    94
}
ds@1952
    95
ds@1952
    96
void CDataPack::PackCell(cell_t cell)
ds@1952
    97
{
ds@1952
    98
	CheckSize(sizeof(size_t) + sizeof(cell_t));
ds@1952
    99
ds@1952
   100
	*(size_t *)m_curptr = sizeof(cell_t);
ds@1952
   101
	m_curptr += sizeof(size_t);
ds@1952
   102
ds@1952
   103
	*(cell_t *)m_curptr = cell;
ds@1952
   104
	m_curptr += sizeof(cell_t);
ds@1952
   105
ds@1952
   106
	m_size += sizeof(size_t) + sizeof(cell_t);
ds@1952
   107
}
ds@1952
   108
ds@1952
   109
void CDataPack::PackFloat(float val)
ds@1952
   110
{
ds@1952
   111
	CheckSize(sizeof(size_t) + sizeof(float));
ds@1952
   112
ds@1952
   113
	*(size_t *)m_curptr = sizeof(float);
ds@1952
   114
	m_curptr += sizeof(size_t);
ds@1952
   115
ds@1952
   116
	*(float *)m_curptr = val;
ds@1952
   117
	m_curptr += sizeof(float);
ds@1952
   118
ds@1952
   119
	m_size += sizeof(size_t) + sizeof(float);
ds@1952
   120
}
ds@1952
   121
ds@1952
   122
void CDataPack::PackString(const char *string)
ds@1952
   123
{
ds@1952
   124
	size_t len = strlen(string);
ds@1952
   125
	size_t maxsize = sizeof(size_t) + len + 1;
ds@1952
   126
	CheckSize(maxsize);
ds@1952
   127
ds@1952
   128
	// Pack the string length first for buffer overrun checking.
ds@1952
   129
	*(size_t *)m_curptr = len;
ds@1952
   130
	m_curptr += sizeof(size_t);
ds@1952
   131
ds@1952
   132
	// Now pack the string.
ds@1952
   133
	memcpy(m_curptr, string, len);
ds@1952
   134
	m_curptr[len] = '\0';
ds@1952
   135
	m_curptr += len + 1;
ds@1952
   136
ds@1952
   137
	m_size += maxsize;
ds@1952
   138
}
ds@1952
   139
ds@1952
   140
void CDataPack::Reset() const
ds@1952
   141
{
ds@1952
   142
	m_curptr = m_pBase;
ds@1952
   143
}
ds@1952
   144
ds@1952
   145
size_t CDataPack::GetPosition() const
ds@1952
   146
{
ds@1952
   147
	return static_cast<size_t>(m_curptr - m_pBase);
ds@1952
   148
}
ds@1952
   149
ds@1952
   150
bool CDataPack::SetPosition(size_t pos) const
ds@1952
   151
{
ds@1952
   152
	if (pos > m_size-1)
ds@1952
   153
	{
ds@1952
   154
		return false;
ds@1952
   155
	}
ds@1952
   156
	m_curptr = m_pBase + pos;
ds@1952
   157
ds@1952
   158
	return true;
ds@1952
   159
}
ds@1952
   160
ds@1952
   161
cell_t CDataPack::ReadCell() const
ds@1952
   162
{
ds@1952
   163
	if (!IsReadable(sizeof(size_t) + sizeof(cell_t)))
ds@1952
   164
	{
ds@1952
   165
		return 0;
ds@1952
   166
	}
ds@1952
   167
	if (*reinterpret_cast<size_t *>(m_curptr) != sizeof(cell_t))
ds@1952
   168
	{
ds@1952
   169
		return 0;
ds@1952
   170
	}
ds@1952
   171
ds@1952
   172
	m_curptr += sizeof(size_t);
ds@1952
   173
ds@1952
   174
	cell_t val = *reinterpret_cast<cell_t *>(m_curptr);
ds@1952
   175
	m_curptr += sizeof(cell_t);
ds@1952
   176
	return val;
ds@1952
   177
}
ds@1952
   178
ds@1952
   179
float CDataPack::ReadFloat() const
ds@1952
   180
{
ds@1952
   181
	if (!IsReadable(sizeof(size_t) + sizeof(float)))
ds@1952
   182
	{
ds@1952
   183
		return 0;
ds@1952
   184
	}
ds@1952
   185
	if (*reinterpret_cast<size_t *>(m_curptr) != sizeof(float))
ds@1952
   186
	{
ds@1952
   187
		return 0;
ds@1952
   188
	}
ds@1952
   189
ds@1952
   190
	m_curptr += sizeof(size_t);
ds@1952
   191
ds@1952
   192
	float val = *reinterpret_cast<float *>(m_curptr);
ds@1952
   193
	m_curptr += sizeof(float);
ds@1952
   194
	return val;
ds@1952
   195
}
ds@1952
   196
ds@1952
   197
bool CDataPack::IsReadable(size_t bytes) const
ds@1952
   198
{
ds@1952
   199
	return (bytes + (m_curptr - m_pBase) > m_size) ? false : true;
ds@1952
   200
}
ds@1952
   201
ds@1952
   202
const char *CDataPack::ReadString(size_t *len) const
ds@1952
   203
{
ds@1952
   204
	if (!IsReadable(sizeof(size_t)))
ds@1952
   205
	{
ds@1952
   206
		return NULL;
ds@1952
   207
	}
ds@1952
   208
ds@1952
   209
	size_t real_len = *(size_t *)m_curptr;
ds@1952
   210
ds@1952
   211
	m_curptr += sizeof(size_t);
ds@1952
   212
	char *str = (char *)m_curptr;
ds@1952
   213
ds@1952
   214
	if ((strlen(str) != real_len) || !(IsReadable(real_len+1)))
ds@1952
   215
	{
ds@1952
   216
		return NULL;
ds@1952
   217
	}
ds@1952
   218
ds@1952
   219
	if (len)
ds@1952
   220
	{
ds@1952
   221
		*len = real_len;
ds@1952
   222
	}
ds@1952
   223
ds@1952
   224
	m_curptr += real_len + 1;
ds@1952
   225
ds@1952
   226
	return str;
ds@1952
   227
}
ds@1952
   228
ds@1952
   229
void *CDataPack::GetMemory() const
ds@1952
   230
{
ds@1952
   231
	return m_curptr;
ds@1952
   232
}
ds@1952
   233
ds@1952
   234
void *CDataPack::ReadMemory(size_t *size) const
ds@1952
   235
{
ds@1952
   236
	if (!IsReadable(sizeof(size_t)))
ds@1952
   237
	{
ds@1952
   238
		return NULL;
ds@1952
   239
	}
ds@1952
   240
ds@1952
   241
	size_t bytecount = *(size_t *)m_curptr;
ds@1952
   242
	m_curptr += sizeof(size_t);
ds@1952
   243
ds@1952
   244
	if (!IsReadable(bytecount))
ds@1952
   245
	{
ds@1952
   246
		return NULL;
ds@1952
   247
	}
ds@1952
   248
ds@1952
   249
	void *ptr = m_curptr;
ds@1952
   250
ds@1952
   251
	if (size)
ds@1952
   252
	{
ds@1952
   253
		*size = bytecount;
ds@1952
   254
	}
ds@1952
   255
ds@1952
   256
	m_curptr += bytecount;
ds@1952
   257
ds@1952
   258
	return ptr;
ds@1952
   259
}