2 * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton)
4 * ShapeFusion is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * ShapeFusion is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with ShapeFusion; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "GenericEndianBuffer.h"
23 GenericEndianBuffer::GenericEndianBuffer(unsigned int _size):
24 mSize(0), mSelfAllocated(true)
26 mData = new unsigned char[_size];
33 GenericEndianBuffer::GenericEndianBuffer(unsigned char *_data, unsigned int _size):
34 mData(_data), mPosition(_data), mSize(_size), mSelfAllocated(false)
39 GenericEndianBuffer::~GenericEndianBuffer(void)
41 if (mSelfAllocated && mData != NULL) {
47 char GenericEndianBuffer::ReadChar(void)
49 if ((unsigned int)(mPosition - mData) < mSize) {
50 unsigned char v = *mPosition;
55 std::cerr << "GenericEndianBuffer: attempted read beyond buffer limits\n";
60 unsigned char GenericEndianBuffer::ReadUChar(void)
62 if ((unsigned int)(mPosition - mData) < mSize) {
63 unsigned char v = *mPosition;
68 std::cerr << "GenericEndianBuffer: attempted read beyond buffer limits\n";
73 void GenericEndianBuffer::ReadBlock(unsigned long _size, unsigned char *dest)
75 if ((unsigned int)(mPosition - mData + _size - 1) < mSize) {
76 memcpy(dest, mPosition, _size);
79 std::cerr << "GenericEndianBuffer: attempted read beyond buffer limits\n";
83 void GenericEndianBuffer::WriteChar(char v)
85 if ((unsigned int)(mPosition - mData) < mSize)
88 std::cerr << "GenericEndianBuffer: attempted write beyond buffer limits\n";
91 void GenericEndianBuffer::WriteUChar(unsigned char v)
93 if ((unsigned int)(mPosition - mData) < mSize)
96 std::cerr << "GenericEndianBuffer: attempted write beyond buffer limits\n";
99 void GenericEndianBuffer::Write4CharCode(char c1, char c2, char c3, char c4)
101 if ((unsigned int)(mPosition - mData + 4 - 1) < mSize) {
107 std::cerr << "GenericEndianBuffer: attempted write beyond buffer limits\n";
111 void GenericEndianBuffer::WriteBlock(unsigned long _size, const void *src)
113 if ((unsigned int)(mPosition - mData + _size - 1) < mSize) {
114 memcpy(mPosition, src, _size);
117 std::cerr << "GenericEndianBuffer: attempted write beyond buffer limits\n";
121 void GenericEndianBuffer::WriteZeroes(unsigned int n)
123 if ((unsigned int)(mPosition - mData + n - 1) < mSize) {
124 memset(mPosition, 0, n);
127 std::cerr << "GenericEndianBuffer: attempted write beyond buffer limits\n";
131 unsigned char *GenericEndianBuffer::Data(void) const
136 unsigned int GenericEndianBuffer::Size(void) const
141 void GenericEndianBuffer::Position(unsigned int pos)
144 mPosition = mData + pos;
146 std::cerr << "GenericEndianBuffer: attempted to position beyond buffer limits (" << pos << "/" << (mSize-1) << ")\n";
149 unsigned int GenericEndianBuffer::Position(void) const
151 return mPosition - mData;
154 static const unsigned long CRC32_POLYNOMIAL = 0xEDB88320L;
155 static std::vector<unsigned long> crc_table;
157 static void BuildCRCTable()
159 if (crc_table.empty()) {
160 crc_table.resize(256);
162 for (unsigned int i = 0; i < crc_table.size(); ++i) {
163 unsigned long crc = i;
164 for (int j = 0; j < 8; ++j) {
166 crc = (crc >> 1) ^ CRC32_POLYNOMIAL;
176 unsigned long GenericEndianBuffer::CalculateCRC() const
180 unsigned long crc = 0xFFFFFFFFL;
182 unsigned char* p = mData;
183 for (unsigned int i = 0; i < mSize; ++i) {
184 unsigned long a = (crc >> 8) & 0x00FFFFFFL;
185 unsigned long b = crc_table[((int) crc ^ *p++) & 0xff];
188 return crc ^ 0xFFFFFFFFL;