Fix sequential extraction, and include progress info
[wimlib] / src / io.h
1 /*
2  * io.h
3  *
4  * A few endianness-aware macros for reading and writing data from in-memory
5  * buffers.
6  */
7
8 #ifndef _WIMLIB_IO_H
9 #define _WIMLIB_IO_H
10
11 #include "util.h"
12 #include "endianness.h"
13 #include <string.h>
14
15 /* Note that in the WIM format, integers are always in little-endian format. */
16
17 /* The get_u8, get_u16, get_u32, get_u56, and get_u64 functions take in a
18  * pointer to an input location as the first argument and a pointer to an output
19  * location as the second argument.  The data in the input location is copied to
20  * the output location, with the size indicated in the function name, in little
21  * endian format.  A pointer to the input location directly following the bytes
22  * read is returned. */
23 static inline const u8 *get_u8(const u8 *p, u8 *res)
24 {
25         *res = *p;
26         return p + 1;
27 }
28
29
30 static inline const u8 *get_u16(const u8 *p, u16 *res)
31 {
32         *res = le16_to_cpu(*(u16*)p);
33         return p + 2;
34 }
35
36
37
38 static inline const u8 *get_u32(const u8 *p, u32 *res)
39 {
40         *res = le32_to_cpu(*(u32*)p);
41         return p + 4;
42 }
43
44
45 static inline const u8 *get_u56(const u8 *p, u64 *res)
46 {
47         *res = le64_to_cpu(*(u64*)p) & 0x00ffffffffffffff;
48         return p + 7;
49 }
50
51
52 static inline const u8 *get_u64(const u8 *p, u64 *res)
53 {
54         *res = le64_to_cpu(*(u64*)p);
55         return p + 8;
56 }
57
58 /* The put_u8, put_u16, put_u32, put_u56, and put_u64 functions take in a
59  * pointer to an output location as the first argument and a value for the
60  * second argument.  The value of the second argument is written to the output
61  * location in little-endian format as the data type indicated in the function
62  * name, and a pointer to the output location directory following the bytes
63  * written is returned. */
64 static inline u8 *put_u8(u8 *res, u8 val)
65 {
66         *res = val;
67         return res + 1;
68 }
69
70 static inline u8 *put_u16(u8 *res, u16 val)
71 {
72         *(uint16_t*)res = cpu_to_le16(val);
73         return res + 2;
74 }
75
76 static inline u8 *put_u32(u8 *res, u32 val)
77 {
78         *(uint32_t*)res = cpu_to_le32(val);
79         return res + 4;
80 }
81
82 static inline u8 *put_u56(u8 *res, u64 val)
83 {
84         const u8 *__p = (const u8*)&val;
85 #ifdef WORDS_BIGENDIAN
86         res[0] = __p[6];
87         res[1] = __p[5];
88         res[2] = __p[4];
89         res[3] = __p[3];
90         res[4] = __p[2];
91         res[5] = __p[1];
92         res[6] = __p[0];
93 #else
94         memcpy(res, __p, 7);
95 #endif
96         return res + 7;
97 }
98
99 static inline u8 *put_u64(u8 *res, u64 val)
100 {
101         *(u64*)res = cpu_to_le64(val);
102         return res + 8;
103 }
104
105 static inline const u8 *get_bytes(const u8 *p, size_t num_bytes, void *res)
106 {
107         memcpy(res, p, num_bytes);
108         return p + num_bytes;
109 }
110
111 static inline u8 *put_zeroes(u8 *p, size_t num_bytes)
112 {
113         return (u8*)memset(p, 0, num_bytes) + num_bytes;
114 }
115
116 static inline u8 *put_bytes(u8 *p, size_t num_bytes, const u8 *input)
117 {
118         return (u8*)memcpy(p, input, num_bytes) + num_bytes;
119 }
120 #endif /* _WIMLIB_IO_H */