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