1/*
2Copyright (c) 2012, Broadcom Europe Ltd
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, 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
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23ON 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
25SOFTWARE, 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 */
46STATIC_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 */
58STATIC_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 */
70STATIC_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 */
82STATIC_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 */
94STATIC_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 */
106STATIC_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 */
123STATIC_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 */
140STATIC_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 */
157STATIC_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 */
174STATIC_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 */
186STATIC_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 */
198STATIC_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 */
210STATIC_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 */
227STATIC_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 */
244STATIC_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 */
261STATIC_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 */
282STATIC_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 */
294STATIC_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 */
306STATIC_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 */
318STATIC_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 */
330STATIC_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 */
347STATIC_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 */
359STATIC_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 */
371STATIC_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 */
383STATIC_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 */
404STATIC_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 */
415STATIC_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 */
426STATIC_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 */
438STATIC_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 */
450STATIC_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 */
462STATIC_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 */
484STATIC_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 */
496STATIC_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 */
508STATIC_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 */
520STATIC_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
707uint64_t vc_container_helper_int_debug(VC_CONTAINER_T *ctx, int type, uint64_t value, const char *name, int indent);
708uint64_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);
710VC_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);
712void 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