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