]> wimlib.net Git - wimlib/blob - src/io.h
Allow writing to empty files in mounted WIM
[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  * Copyright (C) 2012 Eric Biggers
8  *
9  * wimlib - Library for working with WIM files 
10  *
11  * This library is free software; you can redistribute it and/or modify it under
12  * the terms of the GNU Lesser General Public License as published by the Free
13  * Software Foundation; either version 2.1 of the License, or (at your option) any
14  * later version.
15  *
16  * This library is distributed in the hope that it will be useful, but WITHOUT ANY
17  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
18  * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License along
21  * with this library; if not, write to the Free Software Foundation, Inc., 59
22  * Temple Place, Suite 330, Boston, MA 02111-1307 USA 
23  */
24
25 #ifndef _WIMLIB_IO_H
26 #define _WIMLIB_IO_H
27
28 #include "util.h"
29 #include "endianness.h"
30 #include <string.h>
31
32 /* Note that in the WIM format, integers are always in little-endian format. */
33
34 /* The get_u8, get_u16, get_u32, get_u56, and get_u64 functions take in a
35  * pointer to an input location as the first argument and a pointer to an output
36  * location as the second argument.  The data in the input location is copied to
37  * the output location, with the size indicated in the function name, in little
38  * endian format.  A pointer to the input location directly following the bytes
39  * read is returned. */
40 static inline const u8 *get_u8(const u8 *p, u8 *res)
41 {
42         *res = *p;
43         return p + 1;
44 }
45
46
47 static inline const u8 *get_u16(const u8 *p, u16 *res)
48 {
49         *res = to_le16(*(u16*)p);
50         return p + 2;
51 }
52
53
54
55 static inline const u8 *get_u32(const u8 *p, u32 *res)
56 {
57         *res = to_le32(*(u32*)p);
58         return p + 4;
59 }
60
61
62 static inline const u8 *get_u56(const u8 *p, u64 *res)
63 {
64         *res = to_le64(*(u64*)p) & 0x00ffffffffffffff;
65         return p + 7;
66 }
67
68
69 static inline const u8 *get_u64(const u8 *p, u64 *res)
70 {
71         *res = to_le64(*(u64*)p);
72         return p + 8;
73 }
74
75 /* The put_u8, put_u16, put_u32, put_u56, and put_u64 functions take in a
76  * pointer to an output location as the first argument and a value for the
77  * second argument.  The value of the second argument is written to the output
78  * location in little-endian format as the data type indicated in the function
79  * name, and a pointer to the output location directory following the bytes
80  * written is returned. */
81 static inline u8 *put_u8(u8 *res, u8 val)
82 {
83         *res = val;
84         return res + 1;
85 }
86
87 static inline u8 *put_u16(u8 *res, u16 val)
88 {
89         *(uint16_t*)res = to_le16(val);
90         return res + 2;
91 }
92
93 static inline u8 *put_u32(u8 *res, u32 val)
94 {
95         *(uint32_t*)res = to_le32(val);
96         return res + 4;
97 }
98
99 static inline u8 *put_u56(u8 *res, u64 val)
100 {
101         const u8 *__p = (const u8*)&val;
102 #ifdef WORDS_BIGENDIAN
103         res[0] = __p[6];
104         res[1] = __p[5];
105         res[2] = __p[4];
106         res[3] = __p[3];
107         res[4] = __p[2];
108         res[5] = __p[1];
109         res[6] = __p[0];
110 #else
111         memcpy(res, __p, 7);
112 #endif
113         return res + 7;
114 }
115
116 static inline u8 *put_u64(u8 *res, u64 val)
117 {
118         *(u64*)res = to_le64(val);
119         return res + 8;
120 }
121
122 static inline const u8 *get_bytes(const u8 *p, size_t num_bytes, void *res)
123 {
124         memcpy(res, p, num_bytes);
125         return p + num_bytes;
126 }
127
128 static inline u8 *put_bytes(u8 *p, size_t num_bytes, const u8 *input)
129 {
130         memcpy(p, input, num_bytes);
131         return p + num_bytes;
132 }
133 #endif /* _WIMLIB_IO_H */