1 /*
2 ===============================================================================
3
4 FILE: bytestreamin_array.hpp
5
6 CONTENTS:
7
8 PROGRAMMERS:
9
10 martin.isenburg@rapidlasso.com - http://rapidlasso.com
11
12 COPYRIGHT:
13
14 (c) 2007-2017, martin isenburg, rapidlasso - fast tools to catch reality
15
16 This is free software; you can redistribute and/or modify it under the
17 terms of the GNU Lesser General Licence as published by the Free Software
18 Foundation. See the COPYING file for more information.
19
20 This software is distributed WITHOUT ANY WARRANTY and without even the
21 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
22
23 CHANGE HISTORY:
24
25 23 June 2016 -- alternative init option for "native LAS 1.4 compressor"
26 19 July 2015 -- moved from LASlib to LASzip for "compatibility mode" in DLL
27 9 April 2012 -- created after cooking Zuccini/Onion/Potatoe dinner for Mara
28
29 ===============================================================================
30 */
31 #ifndef BYTE_STREAM_IN_ARRAY_H
32 #define BYTE_STREAM_IN_ARRAY_H
33
34 #include "bytestreamin.hpp"
35
36 #include <stdio.h>
37 #include <string.h>
38
39 class ByteStreamInArray : public ByteStreamIn
40 {
41 public:
42 ByteStreamInArray();
43 ByteStreamInArray(const U8* data, I64 size);
44 /* init the array */
45 BOOL init(const U8* data, I64 size);
46 /* read a single byte */
47 U32 getByte();
48 /* read an array of bytes */
49 void getBytes(U8* bytes, const U32 num_bytes);
50 /* is the stream seekable (e.g. stdin is not) */
51 BOOL isSeekable() const;
52 /* get current position of stream */
53 I64 tell() const;
54 /* seek to this position in the stream */
55 BOOL seek(const I64 position);
56 /* seek to the end of the stream */
57 BOOL seekEnd(const I64 distance=0);
58 /* destructor */
~ByteStreamInArray()59 ~ByteStreamInArray(){};
60 protected:
61 const U8* data;
62 I64 size;
63 I64 curr;
64 };
65
66 class ByteStreamInArrayLE : public ByteStreamInArray
67 {
68 public:
69 ByteStreamInArrayLE();
70 ByteStreamInArrayLE(const U8* data, I64 size);
71 /* read 16 bit low-endian field */
72 void get16bitsLE(U8* bytes);
73 /* read 32 bit low-endian field */
74 void get32bitsLE(U8* bytes);
75 /* read 64 bit low-endian field */
76 void get64bitsLE(U8* bytes);
77 /* read 16 bit big-endian field */
78 void get16bitsBE(U8* bytes);
79 /* read 32 bit big-endian field */
80 void get32bitsBE(U8* bytes);
81 /* read 64 bit big-endian field */
82 void get64bitsBE(U8* bytes);
83 private:
84 U8 swapped[8];
85 };
86
87 class ByteStreamInArrayBE : public ByteStreamInArray
88 {
89 public:
90 ByteStreamInArrayBE();
91 ByteStreamInArrayBE(const U8* data, I64 size);
92 /* read 16 bit low-endian field */
93 void get16bitsLE(U8* bytes);
94 /* read 32 bit low-endian field */
95 void get32bitsLE(U8* bytes);
96 /* read 64 bit low-endian field */
97 void get64bitsLE(U8* bytes);
98 /* read 16 bit big-endian field */
99 void get16bitsBE(U8* bytes);
100 /* read 32 bit big-endian field */
101 void get32bitsBE(U8* bytes);
102 /* read 64 bit big-endian field */
103 void get64bitsBE(U8* bytes);
104 private:
105 U8 swapped[8];
106 };
107
ByteStreamInArray()108 inline ByteStreamInArray::ByteStreamInArray()
109 {
110 this->data = 0;
111 this->size = 0;
112 this->curr = 0;
113 }
114
ByteStreamInArray(const U8 * data,I64 size)115 inline ByteStreamInArray::ByteStreamInArray(const U8* data, I64 size)
116 {
117 init(data, size);
118 }
119
init(const U8 * data,I64 size)120 inline BOOL ByteStreamInArray::init(const U8* data, I64 size)
121 {
122 this->curr = 0;
123 if (data)
124 {
125 this->data = data;
126 this->size = size;
127 }
128 else
129 {
130 this->data = 0;
131 this->size = 0;
132 if (size) return FALSE;
133 }
134 return TRUE;
135 }
136
getByte()137 inline U32 ByteStreamInArray::getByte()
138 {
139 if (curr == size)
140 {
141 throw EOF;
142 }
143 U32 byte = data[curr];
144 curr++;
145 return byte;
146 }
147
getBytes(U8 * bytes,const U32 num_bytes)148 inline void ByteStreamInArray::getBytes(U8* bytes, const U32 num_bytes)
149 {
150 if ((curr + num_bytes) > size)
151 {
152 throw EOF;
153 }
154 memcpy((void*)bytes, (void*)(data+curr), num_bytes);
155 curr += num_bytes;
156 }
157
isSeekable() const158 inline BOOL ByteStreamInArray::isSeekable() const
159 {
160 return TRUE;
161 }
162
tell() const163 inline I64 ByteStreamInArray::tell() const
164 {
165 return curr;
166 }
167
seek(const I64 position)168 inline BOOL ByteStreamInArray::seek(const I64 position)
169 {
170 if ((0 <= position) && (position <= size))
171 {
172 curr = position;
173 return TRUE;
174 }
175 return FALSE;
176 }
177
seekEnd(const I64 distance)178 inline BOOL ByteStreamInArray::seekEnd(const I64 distance)
179 {
180 if ((0 <= distance) && (distance <= size))
181 {
182 curr = size - distance;
183 return TRUE;
184 }
185 return FALSE;
186 }
187
ByteStreamInArrayLE()188 inline ByteStreamInArrayLE::ByteStreamInArrayLE() : ByteStreamInArray()
189 {
190 }
191
ByteStreamInArrayLE(const U8 * data,I64 size)192 inline ByteStreamInArrayLE::ByteStreamInArrayLE(const U8* data, I64 size) : ByteStreamInArray(data, size)
193 {
194 }
195
get16bitsLE(U8 * bytes)196 inline void ByteStreamInArrayLE::get16bitsLE(U8* bytes)
197 {
198 getBytes(bytes, 2);
199 }
200
get32bitsLE(U8 * bytes)201 inline void ByteStreamInArrayLE::get32bitsLE(U8* bytes)
202 {
203 getBytes(bytes, 4);
204 }
205
get64bitsLE(U8 * bytes)206 inline void ByteStreamInArrayLE::get64bitsLE(U8* bytes)
207 {
208 getBytes(bytes, 8);
209 }
210
get16bitsBE(U8 * bytes)211 inline void ByteStreamInArrayLE::get16bitsBE(U8* bytes)
212 {
213 getBytes(swapped, 2);
214 bytes[0] = swapped[1];
215 bytes[1] = swapped[0];
216 }
217
get32bitsBE(U8 * bytes)218 inline void ByteStreamInArrayLE::get32bitsBE(U8* bytes)
219 {
220 getBytes(swapped, 4);
221 bytes[0] = swapped[3];
222 bytes[1] = swapped[2];
223 bytes[2] = swapped[1];
224 bytes[3] = swapped[0];
225 }
226
get64bitsBE(U8 * bytes)227 inline void ByteStreamInArrayLE::get64bitsBE(U8* bytes)
228 {
229 getBytes(swapped, 8);
230 bytes[0] = swapped[7];
231 bytes[1] = swapped[6];
232 bytes[2] = swapped[5];
233 bytes[3] = swapped[4];
234 bytes[4] = swapped[3];
235 bytes[5] = swapped[2];
236 bytes[6] = swapped[1];
237 bytes[7] = swapped[0];
238 }
239
ByteStreamInArrayBE()240 inline ByteStreamInArrayBE::ByteStreamInArrayBE() : ByteStreamInArray()
241 {
242 }
243
ByteStreamInArrayBE(const U8 * data,I64 size)244 inline ByteStreamInArrayBE::ByteStreamInArrayBE(const U8* data, I64 size) : ByteStreamInArray(data, size)
245 {
246 }
247
get16bitsLE(U8 * bytes)248 inline void ByteStreamInArrayBE::get16bitsLE(U8* bytes)
249 {
250 getBytes(swapped, 2);
251 bytes[0] = swapped[1];
252 bytes[1] = swapped[0];
253 }
254
get32bitsLE(U8 * bytes)255 inline void ByteStreamInArrayBE::get32bitsLE(U8* bytes)
256 {
257 getBytes(swapped, 4);
258 bytes[0] = swapped[3];
259 bytes[1] = swapped[2];
260 bytes[2] = swapped[1];
261 bytes[3] = swapped[0];
262 }
263
get64bitsLE(U8 * bytes)264 inline void ByteStreamInArrayBE::get64bitsLE(U8* bytes)
265 {
266 getBytes(swapped, 8);
267 bytes[0] = swapped[7];
268 bytes[1] = swapped[6];
269 bytes[2] = swapped[5];
270 bytes[3] = swapped[4];
271 bytes[4] = swapped[3];
272 bytes[5] = swapped[2];
273 bytes[6] = swapped[1];
274 bytes[7] = swapped[0];
275 }
276
get16bitsBE(U8 * bytes)277 inline void ByteStreamInArrayBE::get16bitsBE(U8* bytes)
278 {
279 getBytes(bytes, 2);
280 }
281
get32bitsBE(U8 * bytes)282 inline void ByteStreamInArrayBE::get32bitsBE(U8* bytes)
283 {
284 getBytes(bytes, 4);
285 }
286
get64bitsBE(U8 * bytes)287 inline void ByteStreamInArrayBE::get64bitsBE(U8* bytes)
288 {
289 getBytes(bytes, 8);
290 }
291
292 #endif
293