faluco@490: /** ds@653: * vim: set ts=4 : ds@653: * =============================================================== ds@653: * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved. ds@653: * =============================================================== ds@653: * ds@653: * This file is not open source and may not be copied without explicit ds@653: * written permission of AlliedModders LLC. This file may not be redistributed ds@653: * in whole or significant part. ds@653: * For information, see LICENSE.txt or http://www.sourcemod.net/license.php ds@653: * ds@653: * Version: $Id$ ds@653: */ faluco@490: faluco@484: #include faluco@484: #include faluco@484: #include "CDataPack.h" faluco@484: faluco@489: #define DATAPACK_INITIAL_SIZE 512 faluco@484: faluco@484: CDataPack::CDataPack() faluco@484: { faluco@484: m_pBase = (char *)malloc(DATAPACK_INITIAL_SIZE); faluco@484: m_capacity = DATAPACK_INITIAL_SIZE; faluco@484: Initialize(); faluco@484: } faluco@484: faluco@484: CDataPack::~CDataPack() faluco@484: { faluco@484: free(m_pBase); faluco@484: } faluco@484: faluco@484: void CDataPack::Initialize() faluco@484: { faluco@484: m_curptr = m_pBase; faluco@484: m_size = 0; faluco@484: } faluco@484: faluco@484: void CDataPack::CheckSize(size_t typesize) faluco@484: { faluco@484: if (m_curptr - m_pBase + typesize <= m_capacity) faluco@484: { faluco@484: return; faluco@484: } faluco@484: faluco@484: size_t pos = m_curptr - m_pBase; faluco@484: do faluco@484: { faluco@484: m_capacity *= 2; faluco@484: m_pBase = (char *)realloc(m_pBase, m_capacity); faluco@484: m_curptr = m_pBase + pos; faluco@484: } while (m_curptr - m_pBase + typesize > m_capacity); faluco@484: } faluco@484: faluco@484: void CDataPack::ResetSize() faluco@484: { faluco@484: m_size = 0; faluco@484: } faluco@484: faluco@484: size_t CDataPack::CreateMemory(size_t size, void **addr) faluco@484: { faluco@488: CheckSize(sizeof(size_t) + size); faluco@484: size_t pos = m_curptr - m_pBase; faluco@484: faluco@488: *(size_t *)m_curptr = size; faluco@488: m_curptr += sizeof(size_t); faluco@484: faluco@484: if (addr) faluco@484: { faluco@488: *addr = m_curptr; faluco@484: } faluco@484: faluco@488: m_curptr += size; faluco@488: m_size += sizeof(size_t) + size; faluco@488: faluco@484: return pos; faluco@484: } faluco@484: faluco@484: void CDataPack::PackCell(cell_t cell) faluco@484: { faluco@488: CheckSize(sizeof(size_t) + sizeof(cell_t)); faluco@488: faluco@488: *(size_t *)m_curptr = sizeof(cell_t); faluco@488: m_curptr += sizeof(size_t); faluco@484: faluco@484: *(cell_t *)m_curptr = cell; faluco@484: m_curptr += sizeof(cell_t); faluco@488: faluco@488: m_size += sizeof(size_t) + sizeof(cell_t); faluco@484: } faluco@484: faluco@484: void CDataPack::PackFloat(float val) faluco@484: { faluco@488: CheckSize(sizeof(size_t) + sizeof(float)); faluco@488: faluco@488: *(size_t *)m_curptr = sizeof(float); faluco@488: m_curptr += sizeof(size_t); faluco@484: faluco@484: *(float *)m_curptr = val; faluco@484: m_curptr += sizeof(float); faluco@488: faluco@488: m_size += sizeof(size_t) + sizeof(float); faluco@484: } faluco@484: faluco@484: void CDataPack::PackString(const char *string) faluco@484: { faluco@484: size_t len = strlen(string); faluco@484: size_t maxsize = sizeof(size_t) + len + 1; faluco@484: CheckSize(maxsize); faluco@484: faluco@484: // Pack the string length first for buffer overrun checking. faluco@484: *(size_t *)m_curptr = len; faluco@484: m_curptr += sizeof(size_t); faluco@484: faluco@484: // Now pack the string. faluco@484: memcpy(m_curptr, string, len); faluco@484: m_curptr[len] = '\0'; faluco@484: m_curptr += len + 1; faluco@484: faluco@484: m_size += maxsize; faluco@484: } faluco@484: faluco@484: void CDataPack::Reset() const faluco@484: { faluco@484: m_curptr = m_pBase; faluco@484: } faluco@484: faluco@484: size_t CDataPack::GetPosition() const faluco@484: { faluco@484: return static_cast(m_curptr - m_pBase); faluco@484: } faluco@484: faluco@484: bool CDataPack::SetPosition(size_t pos) const faluco@484: { faluco@484: if (pos > m_size-1) faluco@484: { faluco@484: return false; faluco@484: } faluco@484: m_curptr = m_pBase + pos; faluco@484: faluco@484: return true; faluco@484: } faluco@484: faluco@484: cell_t CDataPack::ReadCell() const faluco@484: { faluco@488: if (!IsReadable(sizeof(size_t) + sizeof(cell_t))) faluco@484: { faluco@484: return 0; faluco@484: } faluco@488: if (*reinterpret_cast(m_curptr) != sizeof(cell_t)) faluco@488: { faluco@488: return 0; faluco@488: } faluco@488: faluco@488: m_curptr += sizeof(size_t); faluco@488: faluco@484: cell_t val = *reinterpret_cast(m_curptr); faluco@484: m_curptr += sizeof(cell_t); faluco@484: return val; faluco@484: } faluco@484: faluco@484: float CDataPack::ReadFloat() const faluco@484: { faluco@488: if (!IsReadable(sizeof(size_t) + sizeof(float))) faluco@484: { faluco@484: return 0; faluco@484: } faluco@488: if (*reinterpret_cast(m_curptr) != sizeof(float)) faluco@488: { faluco@488: return 0; faluco@488: } faluco@488: faluco@488: m_curptr += sizeof(size_t); faluco@488: faluco@484: float val = *reinterpret_cast(m_curptr); faluco@484: m_curptr += sizeof(float); faluco@484: return val; faluco@484: } faluco@484: faluco@484: bool CDataPack::IsReadable(size_t bytes) const faluco@484: { faluco@484: return (bytes + (m_curptr - m_pBase) > m_size) ? false : true; faluco@484: } faluco@484: faluco@484: const char *CDataPack::ReadString(size_t *len) const faluco@484: { faluco@484: if (!IsReadable(sizeof(size_t))) faluco@484: { faluco@488: return NULL; faluco@484: } faluco@484: faluco@484: size_t real_len = *(size_t *)m_curptr; faluco@484: faluco@484: m_curptr += sizeof(size_t); faluco@484: char *str = (char *)m_curptr; faluco@484: faluco@484: if ((strlen(str) != real_len) || !(IsReadable(real_len+1))) faluco@484: { faluco@484: return NULL; faluco@484: } faluco@484: faluco@484: if (len) faluco@484: { faluco@484: *len = real_len; faluco@484: } faluco@484: faluco@484: m_curptr += real_len + 1; faluco@484: faluco@484: return str; faluco@484: } faluco@484: faluco@484: void *CDataPack::GetMemory() const faluco@484: { faluco@484: return m_curptr; faluco@484: } faluco@488: faluco@488: void *CDataPack::ReadMemory(size_t *size) const faluco@488: { faluco@488: if (!IsReadable(sizeof(size_t))) faluco@488: { faluco@488: return NULL; faluco@488: } faluco@488: faluco@488: size_t bytecount = *(size_t *)m_curptr; faluco@488: m_curptr += sizeof(size_t); faluco@488: faluco@488: if (!IsReadable(bytecount)) faluco@488: { faluco@488: return NULL; faluco@488: } faluco@488: faluco@488: void *ptr = m_curptr; faluco@488: faluco@488: if (size) faluco@488: { faluco@488: *size = bytecount; faluco@488: } faluco@488: faluco@488: m_curptr += bytecount; faluco@488: faluco@488: return ptr; faluco@488: }