1 | /* |
2 | Copyright (c) 2012, Broadcom Europe Ltd |
3 | All rights reserved. |
4 | |
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the following conditions are met: |
7 | * Redistributions of source code must retain the above copyright |
8 | notice, this list of conditions and the following disclaimer. |
9 | * Redistributions in binary form must reproduce the above copyright |
10 | notice, this list of conditions and the following disclaimer in the |
11 | documentation and/or other materials provided with the distribution. |
12 | * Neither the name of the copyright holder nor the |
13 | names of its contributors may be used to endorse or promote products |
14 | derived from this software without specific prior written permission. |
15 | |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY |
20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ |
27 | #ifndef VC_CONTAINERS_IO_HELPERS_H |
28 | #define VC_CONTAINERS_IO_HELPERS_H |
29 | |
30 | /** \file containers_io_helpers.h |
31 | * Helper functions and macros which provide functionality which is often used by containers |
32 | */ |
33 | |
34 | #include "containers/core/containers_io.h" |
35 | #include "containers/core/containers_utils.h" |
36 | |
37 | /***************************************************************************** |
38 | * Helper inline functions to read integers from an i/o stream |
39 | *****************************************************************************/ |
40 | |
41 | /** Reads an unsigned 8 bits integer from an i/o stream. |
42 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
43 | * \return The integer read. In case of failure during the read, |
44 | * this will return a value of 0. |
45 | */ |
46 | STATIC_INLINE uint8_t vc_container_io_read_uint8(VC_CONTAINER_IO_T *io) |
47 | { |
48 | uint8_t value; |
49 | size_t ret = vc_container_io_read(io, &value, 1); |
50 | return ret == 1 ? value : 0; |
51 | } |
52 | |
53 | /** Reads a FOURCC from an i/o stream. |
54 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
55 | * \return The FOURCC to read. In case of failure during the read, |
56 | * this will return a value of 0. |
57 | */ |
58 | STATIC_INLINE VC_CONTAINER_FOURCC_T vc_container_io_read_fourcc(VC_CONTAINER_IO_T *io) |
59 | { |
60 | VC_CONTAINER_FOURCC_T value; |
61 | size_t ret = vc_container_io_read(io, (int8_t *)&value, 4); |
62 | return ret == 4 ? value : 0; |
63 | } |
64 | |
65 | /** Reads an unsigned 16 bits big endian integer from an i/o stream. |
66 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
67 | * \return The integer read. In case of failure during the read, |
68 | * this will return a value of 0. |
69 | */ |
70 | STATIC_INLINE uint16_t vc_container_io_read_be_uint16(VC_CONTAINER_IO_T *io) |
71 | { |
72 | uint8_t value[2]; |
73 | size_t ret = vc_container_io_read(io, value, 2); |
74 | return ret == 2 ? (value[0] << 8) | value[1] : 0; |
75 | } |
76 | |
77 | /** Reads an unsigned 24 bits big endian integer from an i/o stream. |
78 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
79 | * \return The integer read. In case of failure during the read, |
80 | * this will return a value of 0. |
81 | */ |
82 | STATIC_INLINE uint32_t vc_container_io_read_be_uint24(VC_CONTAINER_IO_T *io) |
83 | { |
84 | uint8_t value[3]; |
85 | size_t ret = vc_container_io_read(io, value, 3); |
86 | return ret == 3 ? (value[0] << 16) | (value[1] << 8) | value[2] : 0; |
87 | } |
88 | |
89 | /** Reads an unsigned 32 bits big endian integer from an i/o stream. |
90 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
91 | * \return The integer read. In case of failure during the read, |
92 | * this will return a value of 0. |
93 | */ |
94 | STATIC_INLINE uint32_t vc_container_io_read_be_uint32(VC_CONTAINER_IO_T *io) |
95 | { |
96 | uint8_t value[4]; |
97 | size_t ret = vc_container_io_read(io, value, 4); |
98 | return ret == 4 ? (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3] : 0; |
99 | } |
100 | |
101 | /** Reads an unsigned 40 bits big endian integer from an i/o stream. |
102 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
103 | * \return The integer read. In case of failure during the read, |
104 | * this will return a value of 0. |
105 | */ |
106 | STATIC_INLINE uint64_t vc_container_io_read_be_uint40(VC_CONTAINER_IO_T *io) |
107 | { |
108 | uint8_t value[5]; |
109 | uint32_t value1, value2; |
110 | size_t ret = vc_container_io_read(io, value, 5); |
111 | |
112 | value1 = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3]; |
113 | value2 = value[4]; |
114 | |
115 | return ret == 5 ? (((uint64_t)value1) << 8)|value2 : 0; |
116 | } |
117 | |
118 | /** Reads an unsigned 48 bits big endian integer from an i/o stream. |
119 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
120 | * \return The integer read. In case of failure during the read, |
121 | * this will return a value of 0. |
122 | */ |
123 | STATIC_INLINE uint64_t vc_container_io_read_be_uint48(VC_CONTAINER_IO_T *io) |
124 | { |
125 | uint8_t value[6]; |
126 | uint32_t value1, value2; |
127 | size_t ret = vc_container_io_read(io, value, 6); |
128 | |
129 | value1 = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3]; |
130 | value2 = (value[4] << 8) | value[5]; |
131 | |
132 | return ret == 6 ? (((uint64_t)value1) << 16)|value2 : 0; |
133 | } |
134 | |
135 | /** Reads an unsigned 56 bits big endian integer from an i/o stream. |
136 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
137 | * \return The integer read. In case of failure during the read, |
138 | * this will return a value of 0. |
139 | */ |
140 | STATIC_INLINE uint64_t vc_container_io_read_be_uint56(VC_CONTAINER_IO_T *io) |
141 | { |
142 | uint8_t value[7]; |
143 | uint32_t value1, value2; |
144 | size_t ret = vc_container_io_read(io, value, 7); |
145 | |
146 | value1 = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3]; |
147 | value2 = (value[4] << 16) | (value[5] << 8) | value[6]; |
148 | |
149 | return ret == 7 ? (((uint64_t)value1) << 24)|value2 : 0; |
150 | } |
151 | |
152 | /** Reads an unsigned 64 bits big endian integer from an i/o stream. |
153 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
154 | * \return The integer read. In case of failure during the read, |
155 | * this will return a value of 0. |
156 | */ |
157 | STATIC_INLINE uint64_t vc_container_io_read_be_uint64(VC_CONTAINER_IO_T *io) |
158 | { |
159 | uint8_t value[8]; |
160 | uint32_t value1, value2; |
161 | size_t ret = vc_container_io_read(io, value, 8); |
162 | |
163 | value1 = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3]; |
164 | value2 = (value[4] << 24) | (value[5] << 16) | (value[6] << 8) | value[7]; |
165 | |
166 | return ret == 8 ? (((uint64_t)value1) << 32)|value2 : 0; |
167 | } |
168 | |
169 | /** Reads an unsigned 16 bits little endian integer from an i/o stream. |
170 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
171 | * \return The integer read. In case of failure during the read, |
172 | * this will return a value of 0. |
173 | */ |
174 | STATIC_INLINE uint16_t vc_container_io_read_le_uint16(VC_CONTAINER_IO_T *io) |
175 | { |
176 | uint8_t value[2]; |
177 | size_t ret = vc_container_io_read(io, value, 2); |
178 | return ret == 2 ? (value[1] << 8) | value[0] : 0; |
179 | } |
180 | |
181 | /** Reads an unsigned 24 bits little endian integer from an i/o stream. |
182 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
183 | * \return The integer read. In case of failure during the read, |
184 | * this will return a value of 0. |
185 | */ |
186 | STATIC_INLINE uint32_t vc_container_io_read_le_uint24(VC_CONTAINER_IO_T *io) |
187 | { |
188 | uint8_t value[3]; |
189 | size_t ret = vc_container_io_read(io, value, 3); |
190 | return ret == 3 ? (value[2] << 16) | (value[1] << 8) | value[0] : 0; |
191 | } |
192 | |
193 | /** Reads an unsigned 32 bits little endian integer from an i/o stream. |
194 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
195 | * \return The integer read. In case of failure during the read, |
196 | * this will return a value of 0. |
197 | */ |
198 | STATIC_INLINE uint32_t vc_container_io_read_le_uint32(VC_CONTAINER_IO_T *io) |
199 | { |
200 | uint8_t value[4]; |
201 | size_t ret = vc_container_io_read(io, value, 4); |
202 | return ret == 4 ? (value[3] << 24) | (value[2] << 16) | (value[1] << 8) | value[0] : 0; |
203 | } |
204 | |
205 | /** Reads an unsigned 40 bits little endian integer from an i/o stream. |
206 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
207 | * \return The integer read. In case of failure during the read, |
208 | * this will return a value of 0. |
209 | */ |
210 | STATIC_INLINE uint64_t vc_container_io_read_le_uint40(VC_CONTAINER_IO_T *io) |
211 | { |
212 | uint8_t value[5]; |
213 | uint32_t value1, value2; |
214 | size_t ret = vc_container_io_read(io, value, 5); |
215 | |
216 | value1 = (value[3] << 24) | (value[2] << 16) | (value[1] << 8) | value[0]; |
217 | value2 = value[4]; |
218 | |
219 | return ret == 5 ? (((uint64_t)value2) << 32)|value1 : 0; |
220 | } |
221 | |
222 | /** Reads an unsigned 48 bits little endian integer from an i/o stream. |
223 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
224 | * \return The integer read. In case of failure during the read, |
225 | * this will return a value of 0. |
226 | */ |
227 | STATIC_INLINE uint64_t vc_container_io_read_le_uint48(VC_CONTAINER_IO_T *io) |
228 | { |
229 | uint8_t value[6]; |
230 | uint32_t value1, value2; |
231 | size_t ret = vc_container_io_read(io, value, 6); |
232 | |
233 | value1 = (value[3] << 24) | (value[2] << 16) | (value[1] << 8) | value[0]; |
234 | value2 = (value[5] << 8) | value[4]; |
235 | |
236 | return ret == 6 ? (((uint64_t)value2) << 32)|value1 : 0; |
237 | } |
238 | |
239 | /** Reads an unsigned 56 bits little endian integer from an i/o stream. |
240 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
241 | * \return The integer read. In case of failure during the read, |
242 | * this will return a value of 0. |
243 | */ |
244 | STATIC_INLINE uint64_t vc_container_io_read_le_uint56(VC_CONTAINER_IO_T *io) |
245 | { |
246 | uint8_t value[7]; |
247 | uint32_t value1, value2; |
248 | size_t ret = vc_container_io_read(io, value, 7); |
249 | |
250 | value1 = (value[3] << 24) | (value[2] << 16) | (value[1] << 8) | value[0]; |
251 | value2 = (value[6] << 16) | (value[5] << 8) | value[4]; |
252 | |
253 | return ret == 7 ? (((uint64_t)value2) << 32)|value1 : 0; |
254 | } |
255 | |
256 | /** Reads an unsigned 64 bits little endian integer from an i/o stream. |
257 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
258 | * \return The integer read. In case of failure during the read, |
259 | * this will return a value of 0. |
260 | */ |
261 | STATIC_INLINE uint64_t vc_container_io_read_le_uint64(VC_CONTAINER_IO_T *io) |
262 | { |
263 | uint8_t value[8]; |
264 | uint32_t value1, value2; |
265 | size_t ret = vc_container_io_read(io, value, 8); |
266 | |
267 | value1 = (value[3] << 24) | (value[2] << 16) | (value[1] << 8) | value[0]; |
268 | value2 = (value[7] << 24) | (value[6] << 16) | (value[5] << 8) | value[4]; |
269 | |
270 | return ret == 8 ? (((uint64_t)value2) << 32)|value1 : 0; |
271 | } |
272 | |
273 | /***************************************************************************** |
274 | * Helper inline functions to peek integers from an i/o stream |
275 | *****************************************************************************/ |
276 | |
277 | /** Peeks an unsigned 8 bits integer from an i/o stream. |
278 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
279 | * \return The integer read. In case of failure during the read, |
280 | * this will return a value of 0. |
281 | */ |
282 | STATIC_INLINE uint8_t vc_container_io_peek_uint8(VC_CONTAINER_IO_T *io) |
283 | { |
284 | uint8_t value; |
285 | size_t ret = vc_container_io_peek(io, &value, 1); |
286 | return ret == 1 ? value : 0; |
287 | } |
288 | |
289 | /** Peeks an unsigned 16 bits big endian integer from an i/o stream. |
290 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
291 | * \return The integer read. In case of failure during the read, |
292 | * this will return a value of 0. |
293 | */ |
294 | STATIC_INLINE uint16_t vc_container_io_peek_be_uint16(VC_CONTAINER_IO_T *io) |
295 | { |
296 | uint8_t value[2]; |
297 | size_t ret = vc_container_io_peek(io, value, 2); |
298 | return ret == 2 ? (value[0] << 8) | value[1] : 0; |
299 | } |
300 | |
301 | /** Peeks an unsigned 24 bits big endian integer from an i/o stream. |
302 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
303 | * \return The integer read. In case of failure during the read, |
304 | * this will return a value of 0. |
305 | */ |
306 | STATIC_INLINE uint32_t vc_container_io_peek_be_uint24(VC_CONTAINER_IO_T *io) |
307 | { |
308 | uint8_t value[3]; |
309 | size_t ret = vc_container_io_peek(io, value, 3); |
310 | return ret == 3 ? (value[0] << 16) | (value[1] << 8) | value[2] : 0; |
311 | } |
312 | |
313 | /** Peeks an unsigned 32 bits big endian integer from an i/o stream. |
314 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
315 | * \return The integer read. In case of failure during the read, |
316 | * this will return a value of 0. |
317 | */ |
318 | STATIC_INLINE uint32_t vc_container_io_peek_be_uint32(VC_CONTAINER_IO_T *io) |
319 | { |
320 | uint8_t value[4]; |
321 | size_t ret = vc_container_io_peek(io, value, 4); |
322 | return ret == 4 ? (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3] : 0; |
323 | } |
324 | |
325 | /** Peeks an unsigned 64 bits big endian integer from an i/o stream. |
326 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
327 | * \return The integer read. In case of failure during the read, |
328 | * this will return a value of 0. |
329 | */ |
330 | STATIC_INLINE uint64_t vc_container_io_peek_be_uint64(VC_CONTAINER_IO_T *io) |
331 | { |
332 | uint8_t value[8]; |
333 | uint32_t value1, value2; |
334 | size_t ret = vc_container_io_peek(io, value, 8); |
335 | |
336 | value1 = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3]; |
337 | value2 = (value[4] << 24) | (value[5] << 16) | (value[6] << 8) | value[7]; |
338 | |
339 | return ret == 8 ? (((uint64_t)value1) << 32)|value2 : 0; |
340 | } |
341 | |
342 | /** Peeks an unsigned 16 bits little endian integer from an i/o stream. |
343 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
344 | * \return The integer read. In case of failure during the read, |
345 | * this will return a value of 0. |
346 | */ |
347 | STATIC_INLINE uint16_t vc_container_io_peek_le_uint16(VC_CONTAINER_IO_T *io) |
348 | { |
349 | uint8_t value[2]; |
350 | size_t ret = vc_container_io_peek(io, value, 2); |
351 | return ret == 2 ? (value[1] << 8) | value[0] : 0; |
352 | } |
353 | |
354 | /** Peeks an unsigned 24 bits little endian integer from an i/o stream. |
355 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
356 | * \return The integer read. In case of failure during the read, |
357 | * this will return a value of 0. |
358 | */ |
359 | STATIC_INLINE uint32_t vc_container_io_peek_le_uint24(VC_CONTAINER_IO_T *io) |
360 | { |
361 | uint8_t value[3]; |
362 | size_t ret = vc_container_io_peek(io, value, 3); |
363 | return ret == 3 ? (value[2] << 16) | (value[1] << 8) | value[0] : 0; |
364 | } |
365 | |
366 | /** Peeks an unsigned 32 bits little endian integer from an i/o stream. |
367 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
368 | * \return The integer read. In case of failure during the read, |
369 | * this will return a value of 0. |
370 | */ |
371 | STATIC_INLINE uint32_t vc_container_io_peek_le_uint32(VC_CONTAINER_IO_T *io) |
372 | { |
373 | uint8_t value[4]; |
374 | size_t ret = vc_container_io_peek(io, value, 4); |
375 | return ret == 4 ? (value[3] << 24) | (value[2] << 16) | (value[1] << 8) | value[0] : 0; |
376 | } |
377 | |
378 | /** Peeks an unsigned 64 bits little endian integer from an i/o stream. |
379 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
380 | * \return The integer read. In case of failure during the read, |
381 | * this will return a value of 0. |
382 | */ |
383 | STATIC_INLINE uint64_t vc_container_io_peek_le_uint64(VC_CONTAINER_IO_T *io) |
384 | { |
385 | uint8_t value[8]; |
386 | uint32_t value1, value2; |
387 | size_t ret = vc_container_io_peek(io, value, 8); |
388 | |
389 | value1 = (value[3] << 24) | (value[2] << 16) | (value[1] << 8) | value[0]; |
390 | value2 = (value[7] << 24) | (value[6] << 16) | (value[5] << 8) | value[4]; |
391 | |
392 | return ret == 8 ? (((uint64_t)value2) << 32)|value1 : 0; |
393 | } |
394 | |
395 | /***************************************************************************** |
396 | * Helper inline functions to write integers to an i/o stream |
397 | *****************************************************************************/ |
398 | |
399 | /** Writes an unsigned 8 bits integer to an i/o stream. |
400 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
401 | * \param value The integer to write. |
402 | * \return The status of the operation. |
403 | */ |
404 | STATIC_INLINE VC_CONTAINER_STATUS_T vc_container_io_write_uint8(VC_CONTAINER_IO_T *io, uint8_t value) |
405 | { |
406 | size_t ret = vc_container_io_write(io, &value, 1); |
407 | return ret == 1 ? VC_CONTAINER_SUCCESS : VC_CONTAINER_ERROR_FAILED; |
408 | } |
409 | |
410 | /** Writes a FOURCC to an i/o stream. |
411 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
412 | * \param value The FOURCC to write. |
413 | * \return The status of the operation. |
414 | */ |
415 | STATIC_INLINE VC_CONTAINER_STATUS_T vc_container_io_write_fourcc(VC_CONTAINER_IO_T *io, VC_CONTAINER_FOURCC_T value) |
416 | { |
417 | size_t ret = vc_container_io_write(io, (uint8_t *)&value, 4); |
418 | return ret == 4 ? VC_CONTAINER_SUCCESS : VC_CONTAINER_ERROR_FAILED; |
419 | } |
420 | |
421 | /** Writes an unsigned 16 bits big endian integer to an i/o stream. |
422 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
423 | * \param value The integer to write. |
424 | * \return The status of the operation. |
425 | */ |
426 | STATIC_INLINE VC_CONTAINER_STATUS_T vc_container_io_write_be_uint16(VC_CONTAINER_IO_T *io, uint16_t value) |
427 | { |
428 | uint8_t bytes[2] = {(uint8_t)(value >> 8), (uint8_t)value}; |
429 | size_t ret = vc_container_io_write(io, bytes, 2); |
430 | return ret == 2 ? VC_CONTAINER_SUCCESS : VC_CONTAINER_ERROR_FAILED; |
431 | } |
432 | |
433 | /** Writes an unsigned 24 bits big endian integer to an i/o stream. |
434 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
435 | * \param value The integer to write. |
436 | * \return The status of the operation. |
437 | */ |
438 | STATIC_INLINE VC_CONTAINER_STATUS_T vc_container_io_write_be_uint24(VC_CONTAINER_IO_T *io, uint32_t value) |
439 | { |
440 | uint8_t bytes[3] = {(uint8_t)(value >> 16), (uint8_t)(value >> 8), (uint8_t)value}; |
441 | size_t ret = vc_container_io_write(io, bytes, 3); |
442 | return ret == 3 ? VC_CONTAINER_SUCCESS : VC_CONTAINER_ERROR_FAILED; |
443 | } |
444 | |
445 | /** Writes an unsigned 32 bits big endian integer to an i/o stream. |
446 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
447 | * \param value The integer to write. |
448 | * \return The status of the operation. |
449 | */ |
450 | STATIC_INLINE VC_CONTAINER_STATUS_T vc_container_io_write_be_uint32(VC_CONTAINER_IO_T *io, uint32_t value) |
451 | { |
452 | uint8_t bytes[4] = {value >> 24, value >> 16, value >> 8, value}; |
453 | size_t ret = vc_container_io_write(io, bytes, 4); |
454 | return ret == 4 ? VC_CONTAINER_SUCCESS : VC_CONTAINER_ERROR_FAILED; |
455 | } |
456 | |
457 | /** Writes an unsigned 64 bits big endian integer to an i/o stream. |
458 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
459 | * \param value The integer to write. |
460 | * \return The status of the operation. |
461 | */ |
462 | STATIC_INLINE VC_CONTAINER_STATUS_T vc_container_io_write_be_uint64(VC_CONTAINER_IO_T *io, uint64_t value) |
463 | { |
464 | uint8_t bytes[8] = |
465 | { |
466 | (uint8_t)(value >> 56), |
467 | (uint8_t)(value >> 48), |
468 | (uint8_t)(value >> 40), |
469 | (uint8_t)(value >> 32), |
470 | (uint8_t)(value >> 24), |
471 | (uint8_t)(value >> 16), |
472 | (uint8_t)(value >> 8), |
473 | (uint8_t) value |
474 | }; |
475 | size_t ret = vc_container_io_write(io, bytes, 8); |
476 | return ret == 8 ? VC_CONTAINER_SUCCESS : VC_CONTAINER_ERROR_FAILED; |
477 | } |
478 | |
479 | /** Writes an unsigned 16 bits little endian integer to an i/o stream. |
480 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
481 | * \param value The integer to write. |
482 | * \return The status of the operation. |
483 | */ |
484 | STATIC_INLINE VC_CONTAINER_STATUS_T vc_container_io_write_le_uint16(VC_CONTAINER_IO_T *io, uint16_t value) |
485 | { |
486 | uint8_t bytes[2] = {(uint8_t)value, (uint8_t)(value >> 8)}; |
487 | size_t ret = vc_container_io_write(io, bytes, 2); |
488 | return ret == 2 ? VC_CONTAINER_SUCCESS : VC_CONTAINER_ERROR_FAILED; |
489 | } |
490 | |
491 | /** Writes an unsigned 24 bits little endian integer to an i/o stream. |
492 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
493 | * \param value The integer to write. |
494 | * \return The status of the operation. |
495 | */ |
496 | STATIC_INLINE VC_CONTAINER_STATUS_T vc_container_io_write_le_uint24(VC_CONTAINER_IO_T *io, uint32_t value) |
497 | { |
498 | uint8_t bytes[3] = {value, value >> 8, value >> 16}; |
499 | size_t ret = vc_container_io_write(io, bytes, 3); |
500 | return ret == 3 ? VC_CONTAINER_SUCCESS : VC_CONTAINER_ERROR_FAILED; |
501 | } |
502 | |
503 | /** Writes an unsigned 32 bits little endian integer to an i/o stream. |
504 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
505 | * \param value The integer to write. |
506 | * \return The status of the operation. |
507 | */ |
508 | STATIC_INLINE VC_CONTAINER_STATUS_T vc_container_io_write_le_uint32(VC_CONTAINER_IO_T *io, uint32_t value) |
509 | { |
510 | uint8_t bytes[4] = {value, value >> 8, value >> 16, value >> 24}; |
511 | size_t ret = vc_container_io_write(io, bytes, 4); |
512 | return ret == 4 ? VC_CONTAINER_SUCCESS : VC_CONTAINER_ERROR_FAILED; |
513 | } |
514 | |
515 | /** Writes an unsigned 64 bits little endian integer to an i/o stream. |
516 | * \param io Pointer to the VC_CONTAINER_IO_T instance to use |
517 | * \param value The integer to write. |
518 | * \return The status of the operation. |
519 | */ |
520 | STATIC_INLINE VC_CONTAINER_STATUS_T vc_container_io_write_le_uint64(VC_CONTAINER_IO_T *io, uint64_t value) |
521 | { |
522 | uint8_t bytes[8] = |
523 | { |
524 | (uint8_t) value, |
525 | (uint8_t)(value >> 8), |
526 | (uint8_t)(value >> 16), |
527 | (uint8_t)(value >> 24), |
528 | (uint8_t)(value >> 32), |
529 | (uint8_t)(value >> 40), |
530 | (uint8_t)(value >> 48), |
531 | (uint8_t)(value >> 56) |
532 | }; |
533 | size_t ret = vc_container_io_write(io, bytes, 8); |
534 | return ret == 8 ? VC_CONTAINER_SUCCESS : VC_CONTAINER_ERROR_FAILED; |
535 | } |
536 | |
537 | /***************************************************************************** |
538 | * Helper macros for accessing the i/o stream. These will also call the right |
539 | * functions depending on the endianness defined. |
540 | *****************************************************************************/ |
541 | |
542 | /** Macro which returns the current position within the stream */ |
543 | #define STREAM_POSITION(ctx) (ctx)->priv->io->offset |
544 | /** Macro which returns true if the end of stream has been reached */ |
545 | #define STREAM_EOS(ctx) ((ctx)->priv->io->status == VC_CONTAINER_ERROR_EOS) |
546 | /** Macro which returns the status of the stream */ |
547 | #define STREAM_STATUS(ctx) (ctx)->priv->io->status |
548 | /** Macro which returns true if an error other than end of stream has occurred */ |
549 | #define STREAM_ERROR(ctx) ((ctx)->priv->io->status && (ctx)->priv->io->status != VC_CONTAINER_ERROR_EOS) |
550 | /** Macro which returns true if we can seek into the stream */ |
551 | #define STREAM_SEEKABLE(ctx) (!((ctx)->priv->io->capabilities & VC_CONTAINER_IO_CAPS_CANT_SEEK)) |
552 | |
553 | #define PEEK_BYTES(ctx, buffer, size) vc_container_io_peek((ctx)->priv->io, buffer, (size_t)(size)) |
554 | #define READ_BYTES(ctx, buffer, size) vc_container_io_read((ctx)->priv->io, buffer, (size_t)(size)) |
555 | #define SKIP_BYTES(ctx, size) vc_container_io_skip((ctx)->priv->io, (size_t)(size)) |
556 | #define SEEK(ctx, off) vc_container_io_seek((ctx)->priv->io, (int64_t)(off)) |
557 | #define CACHE_BYTES(ctx, size) vc_container_io_cache((ctx)->priv->io, (size_t)(size)) |
558 | |
559 | #define _SKIP_GUID(ctx) vc_container_io_skip((ctx)->priv->io, 16) |
560 | #define _SKIP_U8(ctx) (vc_container_io_skip((ctx)->priv->io, 1) != 1) |
561 | #define _SKIP_U16(ctx) (vc_container_io_skip((ctx)->priv->io, 2) != 2) |
562 | #define _SKIP_U24(ctx) (vc_container_io_skip((ctx)->priv->io, 3) != 3) |
563 | #define _SKIP_U32(ctx) (vc_container_io_skip((ctx)->priv->io, 4) != 4) |
564 | #define _SKIP_U64(ctx) (vc_container_io_skip((ctx)->priv->io, 8) != 8) |
565 | #define _SKIP_FOURCC(ctx) (vc_container_io_skip((ctx)->priv->io, 4) != 4) |
566 | |
567 | #define _READ_GUID(ctx, buffer) vc_container_io_read((ctx)->priv->io, buffer, 16) |
568 | #define _READ_U8(ctx) vc_container_io_read_uint8((ctx)->priv->io) |
569 | #define _READ_FOURCC(ctx) vc_container_io_read_fourcc((ctx)->priv->io) |
570 | #define PEEK_GUID(ctx, buffer) vc_container_io_peek((ctx)->priv->io, buffer, 16) |
571 | #define PEEK_U8(ctx) vc_container_io_peek_uint8((ctx)->priv->io) |
572 | #ifdef CONTAINER_IS_BIG_ENDIAN |
573 | # define _READ_U16(ctx) vc_container_io_read_be_uint16((ctx)->priv->io) |
574 | # define _READ_U24(ctx) vc_container_io_read_be_uint24((ctx)->priv->io) |
575 | # define _READ_U32(ctx) vc_container_io_read_be_uint32((ctx)->priv->io) |
576 | # define _READ_U40(ctx) vc_container_io_read_be_uint40((ctx)->priv->io) |
577 | # define _READ_U48(ctx) vc_container_io_read_be_uint48((ctx)->priv->io) |
578 | # define _READ_U56(ctx) vc_container_io_read_be_uint56((ctx)->priv->io) |
579 | # define _READ_U64(ctx) vc_container_io_read_be_uint64((ctx)->priv->io) |
580 | # define PEEK_U16(ctx) vc_container_io_peek_be_uint16((ctx)->priv->io) |
581 | # define PEEK_U24(ctx) vc_container_io_peek_be_uint24((ctx)->priv->io) |
582 | # define PEEK_U32(ctx) vc_container_io_peek_be_uint32((ctx)->priv->io) |
583 | # define PEEK_U64(ctx) vc_container_io_peek_be_uint64((ctx)->priv->io) |
584 | #else |
585 | # define _READ_U16(ctx) vc_container_io_read_le_uint16((ctx)->priv->io) |
586 | # define _READ_U24(ctx) vc_container_io_read_le_uint24((ctx)->priv->io) |
587 | # define _READ_U32(ctx) vc_container_io_read_le_uint32((ctx)->priv->io) |
588 | # define _READ_U40(ctx) vc_container_io_read_le_uint40((ctx)->priv->io) |
589 | # define _READ_U48(ctx) vc_container_io_read_le_uint48((ctx)->priv->io) |
590 | # define _READ_U56(ctx) vc_container_io_read_le_uint56((ctx)->priv->io) |
591 | # define _READ_U64(ctx) vc_container_io_read_le_uint64((ctx)->priv->io) |
592 | # define PEEK_U16(ctx) vc_container_io_peek_le_uint16((ctx)->priv->io) |
593 | # define PEEK_U24(ctx) vc_container_io_peek_le_uint24((ctx)->priv->io) |
594 | # define PEEK_U32(ctx) vc_container_io_peek_le_uint32((ctx)->priv->io) |
595 | # define PEEK_U64(ctx) vc_container_io_peek_le_uint64((ctx)->priv->io) |
596 | #endif |
597 | |
598 | #define WRITE_BYTES(ctx, buffer, size) vc_container_io_write((ctx)->priv->io, buffer, (size_t)(size)) |
599 | #define _WRITE_GUID(ctx, buffer) vc_container_io_write((ctx)->priv->io, buffer, 16) |
600 | #define _WRITE_U8(ctx, v) vc_container_io_write_uint8((ctx)->priv->io, v) |
601 | #define _WRITE_FOURCC(ctx, v) vc_container_io_write_fourcc((ctx)->priv->io, v) |
602 | #ifdef CONTAINER_IS_BIG_ENDIAN |
603 | # define _WRITE_U16(ctx, v) vc_container_io_write_be_uint16((ctx)->priv->io, v) |
604 | # define _WRITE_U24(ctx, v) vc_container_io_write_be_uint24((ctx)->priv->io, v) |
605 | # define _WRITE_U32(ctx, v) vc_container_io_write_be_uint32((ctx)->priv->io, v) |
606 | # define _WRITE_U64(ctx, v) vc_container_io_write_be_uint64((ctx)->priv->io, v) |
607 | #else |
608 | # define _WRITE_U16(ctx, v) vc_container_io_write_le_uint16((ctx)->priv->io, v) |
609 | # define _WRITE_U24(ctx, v) vc_container_io_write_le_uint24((ctx)->priv->io, v) |
610 | # define _WRITE_U32(ctx, v) vc_container_io_write_le_uint32((ctx)->priv->io, v) |
611 | # define _WRITE_U64(ctx, v) vc_container_io_write_le_uint64((ctx)->priv->io, v) |
612 | #endif |
613 | |
614 | #ifndef CONTAINER_HELPER_LOG_INDENT |
615 | # define CONTAINER_HELPER_LOG_INDENT(a) 0 |
616 | #endif |
617 | |
618 | #ifdef CONTAINER_IS_BIG_ENDIAN |
619 | # define LOG_FORMAT_TYPE_UINT LOG_FORMAT_TYPE_UINT_BE |
620 | # define LOG_FORMAT_TYPE_STRING_UTF16 LOG_FORMAT_TYPE_STRING_UTF16_BE |
621 | #else |
622 | # define LOG_FORMAT_TYPE_UINT LOG_FORMAT_TYPE_UINT_LE |
623 | # define LOG_FORMAT_TYPE_STRING_UTF16 LOG_FORMAT_TYPE_STRING_UTF16_LE |
624 | #endif |
625 | |
626 | #ifndef ENABLE_CONTAINERS_LOG_FORMAT |
627 | #define SKIP_GUID(ctx,n) _SKIP_GUID(ctx) |
628 | #define SKIP_U8(ctx,n) _SKIP_U8(ctx) |
629 | #define SKIP_U16(ctx,n) _SKIP_U16(ctx) |
630 | #define SKIP_U24(ctx,n) _SKIP_U24(ctx) |
631 | #define SKIP_U32(ctx,n) _SKIP_U32(ctx) |
632 | #define SKIP_U64(ctx,n) _SKIP_U64(ctx) |
633 | #define SKIP_FOURCC(ctx,n) _SKIP_FOURCC(ctx) |
634 | #define READ_GUID(ctx,buffer,n) _READ_GUID(ctx,(uint8_t *)buffer) |
635 | #define READ_U8(ctx,n) _READ_U8(ctx) |
636 | #define READ_U16(ctx,n) _READ_U16(ctx) |
637 | #define READ_U24(ctx,n) _READ_U24(ctx) |
638 | #define READ_U32(ctx,n) _READ_U32(ctx) |
639 | #define READ_U40(ctx,n) _READ_U40(ctx) |
640 | #define READ_U48(ctx,n) _READ_U48(ctx) |
641 | #define READ_U56(ctx,n) _READ_U56(ctx) |
642 | #define READ_U64(ctx,n) _READ_U64(ctx) |
643 | #define READ_FOURCC(ctx,n) _READ_FOURCC(ctx) |
644 | #define READ_STRING(ctx,buffer,sz,n) READ_BYTES(ctx,buffer,sz) |
645 | #define READ_STRING_UTF16(ctx,buffer,sz,n) READ_BYTES(ctx,buffer,sz) |
646 | #define SKIP_STRING(ctx,sz,n) SKIP_BYTES(ctx,sz) |
647 | #define SKIP_STRING_UTF16(ctx,sz,n) SKIP_BYTES(ctx,sz) |
648 | #else |
649 | #define SKIP_GUID(ctx,n) vc_container_helper_read_debug(ctx, LOG_FORMAT_TYPE_GUID, 16, n, 0, CONTAINER_HELPER_LOG_INDENT(ctx), 1) |
650 | #define SKIP_U8(ctx,n) vc_container_helper_read_debug(ctx, LOG_FORMAT_TYPE_UINT, 1, n, 0, CONTAINER_HELPER_LOG_INDENT(ctx), 1) |
651 | #define SKIP_U16(ctx,n) vc_container_helper_read_debug(ctx, LOG_FORMAT_TYPE_UINT, 2, n, 0, CONTAINER_HELPER_LOG_INDENT(ctx), 1) |
652 | #define SKIP_U24(ctx,n) vc_container_helper_read_debug(ctx, LOG_FORMAT_TYPE_UINT, 3, n, 0, CONTAINER_HELPER_LOG_INDENT(ctx), 1) |
653 | #define SKIP_U32(ctx,n) vc_container_helper_read_debug(ctx, LOG_FORMAT_TYPE_UINT, 4, n, 0, CONTAINER_HELPER_LOG_INDENT(ctx), 1) |
654 | #define SKIP_U64(ctx,n) vc_container_helper_read_debug(ctx, LOG_FORMAT_TYPE_UINT, 8, n, 0, CONTAINER_HELPER_LOG_INDENT(ctx), 1) |
655 | #define SKIP_FOURCC(ctx,n) vc_container_helper_read_debug(ctx, LOG_FORMAT_TYPE_FOURCC, 4, n, 0, CONTAINER_HELPER_LOG_INDENT(ctx), 1) |
656 | #define READ_GUID(ctx,buffer,n) vc_container_helper_read_debug(ctx, LOG_FORMAT_TYPE_GUID, 16, n, (uint8_t *)buffer, CONTAINER_HELPER_LOG_INDENT(ctx), 0) |
657 | #define READ_U8(ctx,n) (uint8_t)vc_container_helper_read_debug(ctx, LOG_FORMAT_TYPE_UINT, 1, n, 0, CONTAINER_HELPER_LOG_INDENT(ctx), 0) |
658 | #define READ_U16(ctx,n) (uint16_t)vc_container_helper_read_debug(ctx, LOG_FORMAT_TYPE_UINT, 2, n, 0, CONTAINER_HELPER_LOG_INDENT(ctx), 0) |
659 | #define READ_U24(ctx,n) (uint32_t)vc_container_helper_read_debug(ctx, LOG_FORMAT_TYPE_UINT, 3, n, 0, CONTAINER_HELPER_LOG_INDENT(ctx), 0) |
660 | #define READ_U32(ctx,n) (uint32_t)vc_container_helper_read_debug(ctx, LOG_FORMAT_TYPE_UINT, 4, n, 0, CONTAINER_HELPER_LOG_INDENT(ctx), 0) |
661 | #define READ_U40(ctx,n) vc_container_helper_read_debug(ctx, LOG_FORMAT_TYPE_UINT, 5, n, 0, CONTAINER_HELPER_LOG_INDENT(ctx), 0) |
662 | #define READ_U48(ctx,n) vc_container_helper_read_debug(ctx, LOG_FORMAT_TYPE_UINT, 6, n, 0, CONTAINER_HELPER_LOG_INDENT(ctx), 0) |
663 | #define READ_U56(ctx,n) vc_container_helper_read_debug(ctx, LOG_FORMAT_TYPE_UINT, 7, n, 0, CONTAINER_HELPER_LOG_INDENT(ctx), 0) |
664 | #define READ_U64(ctx,n) vc_container_helper_read_debug(ctx, LOG_FORMAT_TYPE_UINT, 8, n, 0, CONTAINER_HELPER_LOG_INDENT(ctx), 0) |
665 | #define READ_FOURCC(ctx,n) vc_container_helper_read_debug(ctx, LOG_FORMAT_TYPE_FOURCC, 4, n, 0, CONTAINER_HELPER_LOG_INDENT(ctx), 0) |
666 | #define READ_STRING_UTF16(ctx,buffer,sz,n) vc_container_helper_read_debug(ctx, LOG_FORMAT_TYPE_STRING_UTF16, sz, n, (uint8_t *)buffer, CONTAINER_HELPER_LOG_INDENT(ctx), 0) |
667 | #define READ_STRING(ctx,buffer,sz,n) vc_container_helper_read_debug(ctx, LOG_FORMAT_TYPE_STRING, sz, n, (uint8_t *)buffer, CONTAINER_HELPER_LOG_INDENT(ctx), 0) |
668 | #define SKIP_STRING_UTF16(ctx,sz,n) vc_container_helper_read_debug(ctx, LOG_FORMAT_TYPE_STRING_UTF16, sz, n, 0, CONTAINER_HELPER_LOG_INDENT(ctx), 1) |
669 | #define SKIP_STRING(ctx,sz,n) vc_container_helper_read_debug(ctx, LOG_FORMAT_TYPE_STRING, sz, n, 0, CONTAINER_HELPER_LOG_INDENT(ctx), 1) |
670 | #endif |
671 | |
672 | #ifndef ENABLE_CONTAINERS_LOG_FORMAT |
673 | #define WRITE_GUID(ctx,buffer,n) _WRITE_GUID(ctx,(const uint8_t *)buffer) |
674 | #define WRITE_U8(ctx,v,n) _WRITE_U8(ctx,(uint8_t)(v)) |
675 | #define WRITE_FOURCC(ctx,v,n) _WRITE_FOURCC(ctx,(uint32_t)(v)) |
676 | #define WRITE_U16(ctx,v,n) _WRITE_U16(ctx,(uint16_t)(v)) |
677 | #define WRITE_U24(ctx,v,n) _WRITE_U24(ctx,(uint32_t)(v)) |
678 | #define WRITE_U32(ctx,v,n) _WRITE_U32(ctx,(uint32_t)(v)) |
679 | #define WRITE_U64(ctx,v,n) _WRITE_U64(ctx,(uint64_t)(v)) |
680 | #define WRITE_STRING(ctx,buffer,size,n) WRITE_BYTES(ctx, buffer, size) |
681 | #else |
682 | #define WRITE_GUID(ctx,buffer,n) (vc_container_helper_write_debug(ctx, LOG_FORMAT_TYPE_GUID, 16, n, UINT64_C(0), (const uint8_t *)buffer, CONTAINER_HELPER_LOG_INDENT(ctx), !(ctx)->priv->io->module) ? 0 : 16) |
683 | #define WRITE_U8(ctx,v,n) vc_container_helper_write_debug(ctx, LOG_FORMAT_TYPE_UINT, 1, n, (uint64_t)(v), 0, CONTAINER_HELPER_LOG_INDENT(ctx), !(ctx)->priv->io->module) |
684 | #define WRITE_FOURCC(ctx,v,n) vc_container_helper_write_debug(ctx, LOG_FORMAT_TYPE_FOURCC, 4, n, (uint64_t)(v), 0, CONTAINER_HELPER_LOG_INDENT(ctx), !(ctx)->priv->io->module) |
685 | #define WRITE_U16(ctx,v,n) (uint16_t)vc_container_helper_write_debug(ctx, LOG_FORMAT_TYPE_UINT, 2, n, (uint64_t)(v), 0, CONTAINER_HELPER_LOG_INDENT(ctx), !(ctx)->priv->io->module) |
686 | #define WRITE_U24(ctx,v,n) vc_container_helper_write_debug(ctx, LOG_FORMAT_TYPE_UINT, 3, n, (uint64_t)(v), 0, CONTAINER_HELPER_LOG_INDENT(ctx), !(ctx)->priv->io->module) |
687 | #define WRITE_U32(ctx,v,n) vc_container_helper_write_debug(ctx, LOG_FORMAT_TYPE_UINT, 4, n, (uint64_t)(v), 0, CONTAINER_HELPER_LOG_INDENT(ctx), !(ctx)->priv->io->module) |
688 | #define WRITE_U64(ctx,v,n) vc_container_helper_write_debug(ctx, LOG_FORMAT_TYPE_UINT, 8, n, (uint64_t)(v), 0, CONTAINER_HELPER_LOG_INDENT(ctx), !(ctx)->priv->io->module) |
689 | #define WRITE_STRING(ctx,buffer,size,n) (vc_container_helper_write_debug(ctx, LOG_FORMAT_TYPE_STRING, size, n, UINT64_C(0), (const uint8_t *)buffer, CONTAINER_HELPER_LOG_INDENT(ctx), !(ctx)->priv->io->module) ? 0 : size) |
690 | #endif |
691 | |
692 | #ifdef ENABLE_CONTAINERS_LOG_FORMAT |
693 | #define LOG_FORMAT(ctx, ...) do { if((ctx)->priv->io->module) vc_container_helper_format_debug(ctx, CONTAINER_HELPER_LOG_INDENT(ctx), __VA_ARGS__); } while(0) |
694 | #else |
695 | #define LOG_FORMAT(ctx, ...) do {} while (0) |
696 | #endif |
697 | |
698 | #define LOG_FORMAT_TYPE_UINT_LE 0 |
699 | #define LOG_FORMAT_TYPE_UINT_BE 1 |
700 | #define LOG_FORMAT_TYPE_STRING 2 |
701 | #define LOG_FORMAT_TYPE_STRING_UTF16_LE 3 |
702 | #define LOG_FORMAT_TYPE_STRING_UTF16_BE 4 |
703 | #define LOG_FORMAT_TYPE_FOURCC 5 |
704 | #define LOG_FORMAT_TYPE_GUID 6 |
705 | #define LOG_FORMAT_TYPE_HEX 0x100 |
706 | |
707 | uint64_t vc_container_helper_int_debug(VC_CONTAINER_T *ctx, int type, uint64_t value, const char *name, int indent); |
708 | uint64_t vc_container_helper_read_debug(VC_CONTAINER_T *ctx, int type, int size, const char *name, |
709 | uint8_t *buffer, int indent, int b_skip); |
710 | VC_CONTAINER_STATUS_T vc_container_helper_write_debug(VC_CONTAINER_T *ctx, int type, int size, const char *name, |
711 | uint64_t value, const uint8_t *buffer, int indent, int silent); |
712 | void vc_container_helper_format_debug(VC_CONTAINER_T *ctx, int indent, const char *format, ...); |
713 | |
714 | #endif /* VC_CONTAINERS_IO_HELPERS_H */ |
715 | /* End of file */ |
716 | /*-----------------------------------------------------------------------------*/ |
717 | |