1 | /* |
---|
2 | * Copyright (c) 2016, Chris Johns <chrisj@rtems.org> |
---|
3 | * |
---|
4 | * Permission to use, copy, modify, and/or distribute this software for any |
---|
5 | * purpose with or without fee is hereby granted, provided that the above |
---|
6 | * copyright notice and this permission notice appear in all copies. |
---|
7 | * |
---|
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
---|
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
---|
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
---|
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
---|
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
---|
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
---|
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
---|
15 | */ |
---|
16 | /** |
---|
17 | * @file |
---|
18 | * |
---|
19 | * @ingroup rtems-ld |
---|
20 | * |
---|
21 | * @brief A buffer of data. |
---|
22 | * |
---|
23 | */ |
---|
24 | |
---|
25 | #if !defined (_RLD_BUFFER_H_) |
---|
26 | #define _RLD_BUFFER_H_ |
---|
27 | |
---|
28 | #include <string> |
---|
29 | |
---|
30 | #include <rld-files.h> |
---|
31 | |
---|
32 | namespace rld |
---|
33 | { |
---|
34 | namespace buffer |
---|
35 | { |
---|
36 | /** |
---|
37 | * A buffer to help manage formats. |
---|
38 | */ |
---|
39 | class buffer |
---|
40 | { |
---|
41 | public: |
---|
42 | /** |
---|
43 | * Create a buffer. |
---|
44 | */ |
---|
45 | buffer (const size_t size, bool le = true); |
---|
46 | |
---|
47 | /** |
---|
48 | * An empty buffer |
---|
49 | */ |
---|
50 | buffer (); |
---|
51 | |
---|
52 | /** |
---|
53 | * Copy a buffer. |
---|
54 | */ |
---|
55 | buffer (const buffer& orig); |
---|
56 | |
---|
57 | /* |
---|
58 | * Destory the buffer. |
---|
59 | */ |
---|
60 | ~buffer (); |
---|
61 | |
---|
62 | /* |
---|
63 | * Return true if the byte order is little-endian. |
---|
64 | */ |
---|
65 | bool little_endian () const { |
---|
66 | return le; |
---|
67 | } |
---|
68 | |
---|
69 | /** |
---|
70 | * Clear the buffer reseting the level to zero. |
---|
71 | */ |
---|
72 | void clear (); |
---|
73 | |
---|
74 | /** |
---|
75 | * Write the data to the buffer. |
---|
76 | * |
---|
77 | * @param data The data to write to the buffer. |
---|
78 | * @param length The amount of data in bytes to write. |
---|
79 | */ |
---|
80 | void write (const void* data_, const size_t length); |
---|
81 | |
---|
82 | /** |
---|
83 | * Read the data from the buffer. |
---|
84 | * |
---|
85 | * @param data Read from the buffer in the data. |
---|
86 | * @param length The amount of data in bytes to read. |
---|
87 | */ |
---|
88 | void read (void* data_, const size_t length); |
---|
89 | |
---|
90 | /** |
---|
91 | * Fill the data to the buffer. |
---|
92 | * |
---|
93 | * @param length The amount of data in bytes to fill with. |
---|
94 | * @param value The value to fill the buffer with. |
---|
95 | */ |
---|
96 | void fill (const size_t length, const uint8_t value = 0); |
---|
97 | |
---|
98 | /** |
---|
99 | * Set the write pointer in the buffer to the level provided filing with |
---|
100 | * the value also provided. |
---|
101 | * |
---|
102 | * @param out_ The new out pointer. |
---|
103 | * @param value The value to fill the buffer with. |
---|
104 | */ |
---|
105 | void set (const size_t out_, const uint8_t value = 0); |
---|
106 | |
---|
107 | /** |
---|
108 | * Skip the data in the buffer moving the read pointer. |
---|
109 | * |
---|
110 | * @param length The amount of data in bytes to skip. |
---|
111 | */ |
---|
112 | void skip (const size_t length); |
---|
113 | |
---|
114 | /** |
---|
115 | * Rewind the in pointer the buffer to the pointer. |
---|
116 | * |
---|
117 | * @param in_ The new in pointer. |
---|
118 | */ |
---|
119 | void rewind (const size_t in_); |
---|
120 | |
---|
121 | /* |
---|
122 | * The level in the buffer. |
---|
123 | */ |
---|
124 | size_t level () const; |
---|
125 | |
---|
126 | /* |
---|
127 | * Write the data buffered to the image. Clear the buffer after. |
---|
128 | */ |
---|
129 | void write (files::image& img); |
---|
130 | |
---|
131 | /* |
---|
132 | * Read the data from the image into the start of buffer. |
---|
133 | */ |
---|
134 | void read (files::image& img, size_t length = 0); |
---|
135 | |
---|
136 | /* |
---|
137 | * Dump. |
---|
138 | */ |
---|
139 | void dump (); |
---|
140 | |
---|
141 | private: |
---|
142 | uint8_t* data; //< The data held in the buffer. |
---|
143 | size_t size; //< The zie of the date the buffer hold. |
---|
144 | bool le; //< True is little endian else it is big. |
---|
145 | size_t in; //< The data in pointer, used when writing. |
---|
146 | size_t out; //< The data out ponter, used when reading. |
---|
147 | size_t level_; //< The level of data in the buffer. |
---|
148 | }; |
---|
149 | |
---|
150 | /** |
---|
151 | * Buffer template function for writing data to the buffer. |
---|
152 | */ |
---|
153 | template < typename T > |
---|
154 | void write (buffer& buf, const T value) |
---|
155 | { |
---|
156 | uint8_t bytes[sizeof (T)]; |
---|
157 | T v = value; |
---|
158 | if (buf.little_endian ()) |
---|
159 | { |
---|
160 | size_t b = sizeof (T); |
---|
161 | while (b != 0) |
---|
162 | { |
---|
163 | bytes[--b] = (uint8_t) v; |
---|
164 | v >>= 8; |
---|
165 | } |
---|
166 | } |
---|
167 | else |
---|
168 | { |
---|
169 | size_t b = 0; |
---|
170 | while (b < sizeof (T)) |
---|
171 | { |
---|
172 | bytes[b++] = (uint8_t) v; |
---|
173 | v >>= 8; |
---|
174 | } |
---|
175 | } |
---|
176 | buf.write (bytes, sizeof (T)); |
---|
177 | } |
---|
178 | |
---|
179 | /** |
---|
180 | * Buffer template function for reading data to the buffer. |
---|
181 | */ |
---|
182 | template < typename T > |
---|
183 | void read (buffer& buf, T& value) |
---|
184 | { |
---|
185 | uint8_t bytes[sizeof (T)]; |
---|
186 | buf.read (bytes, sizeof (T)); |
---|
187 | value = 0; |
---|
188 | if (buf.little_endian ()) |
---|
189 | { |
---|
190 | size_t b = sizeof (T); |
---|
191 | while (b != 0) |
---|
192 | { |
---|
193 | value <<= 8; |
---|
194 | value |= (T) bytes[--b]; |
---|
195 | } |
---|
196 | } |
---|
197 | else |
---|
198 | { |
---|
199 | size_t b = 0; |
---|
200 | while (b < sizeof (T)) |
---|
201 | { |
---|
202 | value <<= 8; |
---|
203 | value |= (T) bytes[b++]; |
---|
204 | } |
---|
205 | } |
---|
206 | } |
---|
207 | |
---|
208 | /* |
---|
209 | * Insertion operators. |
---|
210 | */ |
---|
211 | buffer& operator<< (buffer& buf, const uint64_t value); |
---|
212 | buffer& operator<< (buffer& buf, const uint32_t value); |
---|
213 | buffer& operator<< (buffer& buf, const uint16_t value); |
---|
214 | buffer& operator<< (buffer& buf, const uint8_t value); |
---|
215 | buffer& operator<< (buffer& buf, const std::string& str); |
---|
216 | |
---|
217 | /* |
---|
218 | * Extraction operators. |
---|
219 | */ |
---|
220 | buffer& operator>> (buffer& buf, uint64_t& value); |
---|
221 | buffer& operator>> (buffer& buf, uint32_t& value); |
---|
222 | buffer& operator>> (buffer& buf, uint16_t& value); |
---|
223 | buffer& operator>> (buffer& buf, uint8_t& value); |
---|
224 | |
---|
225 | /* |
---|
226 | * Buffer fill manipulator. |
---|
227 | */ |
---|
228 | struct b_fill |
---|
229 | { |
---|
230 | const uint8_t value; |
---|
231 | const size_t amount; |
---|
232 | |
---|
233 | b_fill (const size_t amount, const uint8_t value) |
---|
234 | : value (value), |
---|
235 | amount (amount) { |
---|
236 | } |
---|
237 | |
---|
238 | friend buffer& operator<< (buffer& buf, const b_fill& bf) { |
---|
239 | buf.fill (bf.amount, bf.value); |
---|
240 | return buf; |
---|
241 | } |
---|
242 | }; |
---|
243 | |
---|
244 | b_fill fill (const size_t amount, const uint8_t value = 0); |
---|
245 | |
---|
246 | /* |
---|
247 | * Buffer set manipulator. |
---|
248 | */ |
---|
249 | struct b_set |
---|
250 | { |
---|
251 | const uint8_t value; |
---|
252 | const size_t level; |
---|
253 | |
---|
254 | b_set (const size_t level, const uint8_t value) |
---|
255 | : value (value), |
---|
256 | level (level) { |
---|
257 | } |
---|
258 | |
---|
259 | friend buffer& operator<< (buffer& buf, const b_set& bs) { |
---|
260 | buf.set (bs.level, bs.value); |
---|
261 | return buf; |
---|
262 | } |
---|
263 | }; |
---|
264 | |
---|
265 | b_set set (const size_t level, const uint8_t value = 0); |
---|
266 | |
---|
267 | /* |
---|
268 | * Buffer skip manipulator. |
---|
269 | */ |
---|
270 | struct b_skip |
---|
271 | { |
---|
272 | const size_t amount; |
---|
273 | |
---|
274 | b_skip (const size_t amount) |
---|
275 | : amount (amount) { |
---|
276 | } |
---|
277 | |
---|
278 | friend buffer& operator>> (buffer& buf, const b_skip& bs) { |
---|
279 | buf.skip (bs.amount); |
---|
280 | return buf; |
---|
281 | } |
---|
282 | }; |
---|
283 | |
---|
284 | b_skip skip (const size_t amount); |
---|
285 | } |
---|
286 | } |
---|
287 | |
---|
288 | #endif |
---|