2
* OpenTyrian: A modern cross-platform port of Tyrian
3
* Copyright (C) 2007-2009 The OpenTyrian Development Team
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License
7
* as published by the Free Software Foundation; either version 2
8
* of the License, or (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21
* This file is largely based on (and named after) a set of common reading/
22
* writing functions used in Quake engines. Its purpose is to allow extraction
23
* of bytes, words, and dwords in a safe, endian adjused environment and should
24
* probably be used in any situation where checking for buffer overflows
25
* manually makes the code a godawful mess.
27
* Currently this is only used by the animation decoding.
29
* This file is written with the intention of being easily converted into a
30
* class capable of throwing exceptions if data is out of range.
32
* If an operation fails, subsequent operations will also fail. The sizebuf
33
* is assumed to be in an invalid state. This COULD be changed pretty easily
34
* and in normal Quake IIRC it is. But our MO is to bail on failure, not
35
* figure out what went wrong (making throws perfect).
41
#include "SDL_endian.h"
43
/* Construct buffer with the passed array and size */
44
void SZ_Init(sizebuf_t * sz, Uint8 * buf, unsigned int size)
51
/* Check error flags */
52
bool SZ_Error(sizebuf_t * sz)
57
void SZ_Memset(sizebuf_t * sz, int value, size_t count)
59
/* Do bounds checking before writing */
60
if (sz->error || sz->bufferPos + count > sz->bufferLen)
66
/* Memset and increment pointer */
67
memset(sz->data + sz->bufferPos, value, count);
68
sz->bufferPos += count;
70
/* Mimic memcpy. Two versions, one for buffers, one for sizebuf objects.
72
void SZ_Memcpy(sizebuf_t * sz, const Uint8 * buf, size_t count)
75
if (sz->error || sz->bufferPos + count > sz->bufferLen)
81
/* Memcpy & increment */
82
memcpy(sz->data + sz->bufferPos, buf, count);
83
sz->bufferPos += count;
85
void SZ_Memcpy2(sizebuf_t * sz, sizebuf_t * bf, size_t count)
88
if (sz->error || sz->bufferPos + count > sz->bufferLen)
93
if (bf->error || bf->bufferPos + count > bf->bufferLen)
99
/* Memcpy & increment */
100
memcpy(sz->data + sz->bufferPos, bf->data + bf->bufferPos, count);
101
sz->bufferPos += count;
102
bf->bufferPos += count;
104
/* Reposition buffer pointer */
105
void SZ_Seek(sizebuf_t * sz, long count, int mode)
107
/* Okay, it's reasonable to reset the error bool on seeking... */
112
sz->bufferPos = count;
115
sz->bufferPos += count;
118
sz->bufferPos = sz->bufferLen - count;
125
if (sz->bufferPos > sz->bufferLen)
132
const Uint8 * SZ_GetCurBufferPtr (sizebuf_t * sz)
137
/* The code below makes use of pointer casts, similar to what is in efread.
138
* It's not the ONLY way to write ints to a stream, but it's probably the
139
* cleanest of the lot. Better to have it here than littered all over the code.
141
void MSG_WriteByte(sizebuf_t * sz, unsigned int value)
143
if (sz->error || sz->bufferPos + 1 > sz->bufferLen)
149
sz->data[sz->bufferPos] = value;
152
void MSG_WriteWord(sizebuf_t * sz, unsigned int value)
154
if (sz->error || sz->bufferPos + 2 > sz->bufferLen)
160
*((Uint16 *)(sz->data + sz->bufferPos)) = SDL_SwapLE16( ((Uint16)value) );
163
void MSG_WriteDWord(sizebuf_t * sz, unsigned int value)
165
if (sz->error || sz->bufferPos + 4 > sz->bufferLen)
171
*((Uint32 *)(sz->data + sz->bufferPos)) = SDL_SwapLE32( ((Uint32)value) );
175
unsigned int MSG_ReadByte(sizebuf_t * sz)
180
if (sz->error || sz->bufferPos + 1 > sz->bufferLen)
186
ret = sz->data[sz->bufferPos];
191
unsigned int MSG_ReadWord(sizebuf_t * sz)
196
if (sz->error || sz->bufferPos + 2 > sz->bufferLen)
202
ret = SDL_SwapLE16(*((Uint16 *)(sz->data + sz->bufferPos)));
207
unsigned int MSG_ReadDWord(sizebuf_t * sz)
212
if (sz->error || sz->bufferPos + 4 > sz->bufferLen)
218
ret = SDL_SwapLE32(*((Uint32 *)(sz->data + sz->bufferPos)));