vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / translators / raw / ReadHelper.h
blob94904438ba52ef8ca345610d262f0cfabae557b9
1 /*
2 * Copyright 2004-2008, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5 #ifndef READ_HELPER_H
6 #define READ_HELPER_H
9 #include "TIFF.h"
11 #include <BufferIO.h>
12 #include <ByteOrder.h>
15 template<class T>
16 inline void
17 byte_swap(T &/*data*/)
19 // Specialize for data types which actually swap
20 // printf("DEAD MEAT!\n");
21 // exit(1);
25 template<>
26 inline void
27 byte_swap(float &data)
29 data = __swap_float(data);
33 template<>
34 inline void
35 byte_swap(int32 &data)
37 data = __swap_int32(data);
41 template<>
42 inline void
43 byte_swap(uint32 &data)
45 data = __swap_int32(data);
49 template<>
50 inline void
51 byte_swap(int16 &data)
53 data = __swap_int16(data);
57 template<>
58 inline void
59 byte_swap(uint16 &data)
61 data = __swap_int16(data);
65 class TReadHelper {
66 public:
67 TReadHelper(BPositionIO& stream)
69 fStream(&stream, 65536, false),
70 fError(B_OK),
71 fSwap(false)
75 template<class T> inline void
76 operator()(T &data)
78 fError = fStream.Read((void *)&data, sizeof(T));
79 if (fError >= B_OK) {
80 if (IsSwapping())
81 byte_swap(data);
82 return;
85 if (fError == 0)
86 fError = B_ERROR;
87 throw fError;
90 template<class T> inline void
91 operator()(T data, size_t length)
93 fError = fStream.Read((void *)data, length);
94 if (fError < (ssize_t)length)
95 fError = B_ERROR;
97 if (fError >= B_OK)
98 return;
100 throw fError;
103 template<class T> inline T
104 Next()
106 T value;
107 fError = fStream.Read((void *)&value, sizeof(T));
108 if (fError > B_OK) {
109 if (IsSwapping())
110 byte_swap(value);
111 return value;
114 if (fError == 0)
115 fError = B_ERROR;
116 throw fError;
119 inline uint32
120 Next(uint16 type)
122 if (type == TIFF_UINT16_TYPE || type == TIFF_INT16_TYPE)
123 return Next<uint16>();
125 return Next<uint32>();
128 inline double
129 NextDouble(uint16 type)
131 switch (type) {
132 case TIFF_UINT16_TYPE:
133 return Next<uint16>();
134 case TIFF_UINT32_TYPE:
135 return Next<uint32>();
136 case TIFF_UFRACTION_TYPE:
138 double value = Next<uint32>();
139 return value / Next<uint32>();
141 case TIFF_INT16_TYPE:
142 return Next<int16>();
143 case TIFF_INT32_TYPE:
144 return Next<int32>();
145 case TIFF_FRACTION_TYPE:
147 double value = Next<int32>();
148 return value / Next<int32>();
150 case TIFF_FLOAT_TYPE:
151 return Next<float>();
152 case TIFF_DOUBLE_TYPE:
153 return Next<double>();
155 default:
156 return Next<uint8>();
160 inline void
161 NextShorts(uint16* data, size_t length)
163 fError = fStream.Read(data, length * 2);
164 if (fError < (ssize_t)length * 2)
165 fError = B_ERROR;
167 if (fError >= B_OK) {
168 if (IsSwapping())
169 swap_data(B_INT16_TYPE, data, length * 2, B_SWAP_ALWAYS);
170 return;
173 throw fError;
176 status_t Status() const
177 { return fError >= B_OK ? B_OK : fError; };
179 off_t Seek(off_t offset, int32 mode)
180 { return fStream.Seek(offset, mode); }
181 off_t Position() const
182 { return fStream.Position(); }
184 void SetSwap(bool yesNo) { fSwap = yesNo; };
185 bool IsSwapping() const { return fSwap; };
187 BPositionIO& Stream() { return fStream; }
189 private:
190 BBufferIO fStream;
191 status_t fError;
192 bool fSwap;
195 #endif // READ_HELPER_H