]> wimlib.net Git - wimlib/blob - src/buffer_io.h
Refactor Win32 capture/apply, UNIX apply
[wimlib] / src / buffer_io.h
1 /*
2  * buffer_io.h
3  *
4  * A few endianness-aware macros for reading and writing data from in-memory
5  * buffers.
6  */
7
8 #ifndef _WIMLIB_BUFFER_IO_H
9 #define _WIMLIB_BUFFER_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 void *
24 get_u8(const void *p, u8 *res)
25 {
26         *res = *(const u8*)p;
27         return p + 1;
28 }
29
30 static inline const void *
31 get_u16(const void *p, u16 *res)
32 {
33         *res = le16_to_cpu(*(const u16*)p);
34         return p + 2;
35 }
36
37
38
39 static inline const void *
40 get_u32(const void *p, u32 *res)
41 {
42         *res = le32_to_cpu(*(const u32*)p);
43         return p + 4;
44 }
45
46
47 static inline const void *
48 get_u56(const void *p, u64 *res)
49 {
50         *res = le64_to_cpu(*(const u64*)p) & 0x00ffffffffffffff;
51         return p + 7;
52 }
53
54
55 static inline const void *
56 get_u64(const void *p, u64 *res)
57 {
58         *res = le64_to_cpu(*(const u64*)p);
59         return p + 8;
60 }
61
62 /* The put_u8, put_u16, put_u32, put_u56, and put_u64 functions take in a
63  * pointer to an output location as the first argument and a value for the
64  * second argument.  The value of the second argument is written to the output
65  * location in little-endian format as the data type indicated in the function
66  * name, and a pointer to the output location directory following the bytes
67  * written is returned. */
68 static inline void *
69 put_u8(void *res, u8 val)
70 {
71         *(u8*)res = val;
72         return res + 1;
73 }
74
75 static inline void *
76 put_u16(void *res, u16 val)
77 {
78         *(uint16_t*)res = cpu_to_le16(val);
79         return res + 2;
80 }
81
82 static inline void *
83 put_u32(void *res, u32 val)
84 {
85         *(uint32_t*)res = cpu_to_le32(val);
86         return res + 4;
87 }
88
89 static inline void *
90 put_u56(void *res, u64 val)
91 {
92         const u8 *__p = (const u8*)&val;
93 #ifdef WORDS_BIGENDIAN
94         res[0] = __p[6];
95         res[1] = __p[5];
96         res[2] = __p[4];
97         res[3] = __p[3];
98         res[4] = __p[2];
99         res[5] = __p[1];
100         res[6] = __p[0];
101 #else
102         memcpy(res, __p, 7);
103 #endif
104         return res + 7;
105 }
106
107 static inline void *
108 put_u64(void *res, u64 val)
109 {
110         *(u64*)res = cpu_to_le64(val);
111         return res + 8;
112 }
113
114 static inline const void *
115 get_bytes(const void *p, size_t num_bytes, void *res)
116 {
117         memcpy(res, p, num_bytes);
118         return p + num_bytes;
119 }
120
121 static inline void *
122 put_zeroes(void *p, size_t num_bytes)
123 {
124         return memset(p, 0, num_bytes) + num_bytes;
125 }
126
127 static inline void *
128 put_bytes(void *p, size_t num_bytes, const void *input)
129 {
130         return memcpy(p, input, num_bytes) + num_bytes;
131 }
132 #endif /* _WIMLIB_BUFFER_IO_H */