core/CDataPack.cpp
author Scott Ehlert <ds@alliedmods.net>
Sun Mar 30 07:00:22 2008 +0000 (2008-03-30)
changeset 1952 b7aa2b626807
child 2289 44045ead61cd
permissions -rw-r--r--
Spring Cleaning, Part Ichi (1)
Various minor things done to project files
Updated sample extension project file and updated makefile to the new unified version (more changes likely on the way)
Updated regex project file and makefile
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
}