OSDN Git Service

ゴミデーターを削除
[marathon/ShapeFusion.git] / GenericEndianBuffer.cpp
1 /*
2  * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton)
3  *
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.
8  *
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.
13  *
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
17 */
18 #include <iostream>
19 #include <cstring>
20 #include <vector>
21 #include "GenericEndianBuffer.h"
22
23 GenericEndianBuffer::GenericEndianBuffer(unsigned int _size):
24                 mSize(0), mSelfAllocated(true)
25 {
26         mData = new unsigned char[_size];
27         if (mData != NULL) {
28                 mPosition = mData;
29                 mSize = _size;
30         }
31 }
32
33 GenericEndianBuffer::GenericEndianBuffer(unsigned char *_data, unsigned int _size):
34                 mData(_data), mPosition(_data), mSize(_size), mSelfAllocated(false)
35 {
36         
37 }
38
39 GenericEndianBuffer::~GenericEndianBuffer(void)
40 {
41         if (mSelfAllocated && mData != NULL) {
42                 delete[] mData;
43                 mData = NULL;
44         }
45 }
46
47 char GenericEndianBuffer::ReadChar(void)
48 {
49         if ((unsigned int)(mPosition - mData) < mSize) {
50                 unsigned char   v = *mPosition;
51
52                 mPosition++;
53                 return (char)v;
54         } else {
55                 std::cerr << "GenericEndianBuffer: attempted read beyond buffer limits\n";
56                 return 0;
57         }
58 }
59
60 unsigned char GenericEndianBuffer::ReadUChar(void)
61 {
62         if ((unsigned int)(mPosition - mData) < mSize) {
63                 unsigned char   v = *mPosition;
64
65                 mPosition++;
66                 return v;
67         } else {
68                 std::cerr << "GenericEndianBuffer: attempted read beyond buffer limits\n";
69                 return 0;
70         }
71 }
72
73 void GenericEndianBuffer::ReadBlock(unsigned long _size, unsigned char *dest)
74 {
75         if ((unsigned int)(mPosition - mData + _size - 1) < mSize) {
76                 memcpy(dest, mPosition, _size);
77                 mPosition += _size;
78         } else {
79                 std::cerr << "GenericEndianBuffer: attempted read beyond buffer limits\n";
80         }
81 }
82
83 void GenericEndianBuffer::WriteChar(char v)
84 {
85         if ((unsigned int)(mPosition - mData) < mSize)
86                 *mPosition++ = v;
87         else
88                 std::cerr << "GenericEndianBuffer: attempted write beyond buffer limits\n";
89 }
90
91 void GenericEndianBuffer::WriteUChar(unsigned char v)
92 {
93         if ((unsigned int)(mPosition - mData) < mSize)
94                 *mPosition++ = v;
95         else
96                 std::cerr << "GenericEndianBuffer: attempted write beyond buffer limits\n";
97 }
98
99 void GenericEndianBuffer::Write4CharCode(char c1, char c2, char c3, char c4)
100 {
101         if ((unsigned int)(mPosition - mData + 4 - 1) < mSize) {
102                 *mPosition++ = c1;
103                 *mPosition++ = c2;
104                 *mPosition++ = c3;
105                 *mPosition++ = c4;
106         } else {
107                 std::cerr << "GenericEndianBuffer: attempted write beyond buffer limits\n";
108         }
109 }
110
111 void GenericEndianBuffer::WriteBlock(unsigned long _size, const void *src)
112 {
113         if ((unsigned int)(mPosition - mData + _size - 1) < mSize) {
114                 memcpy(mPosition, src, _size);
115                 mPosition += _size;
116         } else {
117                 std::cerr << "GenericEndianBuffer: attempted write beyond buffer limits\n";
118         }
119 }
120
121 void GenericEndianBuffer::WriteZeroes(unsigned int n)
122 {
123         if ((unsigned int)(mPosition - mData + n - 1) < mSize) {
124                 memset(mPosition, 0, n);
125                 mPosition += n;
126         } else {
127                 std::cerr << "GenericEndianBuffer: attempted write beyond buffer limits\n";
128         }
129 }
130
131 unsigned char *GenericEndianBuffer::Data(void) const
132 {
133         return mData;
134 }
135
136 unsigned int GenericEndianBuffer::Size(void) const
137 {
138         return mSize;
139 }
140
141 void GenericEndianBuffer::Position(unsigned int pos)
142 {
143         if (pos < mSize)
144                 mPosition = mData + pos;
145         else
146                 std::cerr << "GenericEndianBuffer: attempted to position beyond buffer limits (" << pos << "/" << (mSize-1) << ")\n";
147 }
148
149 unsigned int GenericEndianBuffer::Position(void) const
150 {
151         return mPosition - mData;
152 }
153
154 static const unsigned long CRC32_POLYNOMIAL = 0xEDB88320L;
155 static std::vector<unsigned long> crc_table;
156
157 static void BuildCRCTable()
158 {
159         if (crc_table.empty()) {
160                 crc_table.resize(256);
161
162                 for (unsigned int i = 0; i < crc_table.size(); ++i) {
163                         unsigned long crc = i;
164                         for (int j = 0; j < 8; ++j) {
165                                 if (crc & 1) {
166                                         crc = (crc >> 1) ^ CRC32_POLYNOMIAL;
167                                 } else {
168                                         crc >>= 1;
169                                 }
170                                 crc_table[i] = crc;
171                         }
172                 }
173         }
174 }
175
176 unsigned long GenericEndianBuffer::CalculateCRC() const 
177 {
178         BuildCRCTable();
179
180         unsigned long crc = 0xFFFFFFFFL;
181         
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];
186                 crc = a^b;
187         }
188         return crc ^ 0xFFFFFFFFL;
189 }