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