1 #ifndef R_BUF_H
2 #define R_BUF_H
3 #include <r_util/r_mem.h>
4 
5 #ifdef __cplusplus
6 extern "C" {
7 #endif
8 
9 // TODO: choose whether the _at operations should preserve the current seek or not
10 
11 #define R_BUF_SET 0
12 #define R_BUF_CUR 1
13 #define R_BUF_END 2
14 
15 typedef struct r_buf_t RBuffer;
16 
17 typedef bool (*RBufferInit)(RBuffer *b, const void *user);
18 typedef bool (*RBufferFini)(RBuffer *b);
19 typedef st64 (*RBufferRead)(RBuffer *b, ut8 *buf, ut64 len);
20 typedef st64 (*RBufferWrite)(RBuffer *b, const ut8 *buf, ut64 len);
21 typedef ut64 (*RBufferGetSize)(RBuffer *b);
22 typedef bool (*RBufferResize)(RBuffer *b, ut64 newsize);
23 typedef st64 (*RBufferSeek)(RBuffer *b, st64 addr, int whence);
24 typedef ut8 *(*RBufferGetWholeBuf)(RBuffer *b, ut64 *sz);
25 typedef void (*RBufferFreeWholeBuf)(RBuffer *b);
26 typedef RList *(*RBufferNonEmptyList)(RBuffer *b);
27 
28 typedef struct r_buffer_methods_t {
29 	RBufferInit init;
30 	RBufferFini fini;
31 	RBufferRead read;
32 	RBufferWrite write;
33 	RBufferGetSize get_size;
34 	RBufferResize resize;
35 	RBufferSeek seek;
36 	RBufferGetWholeBuf get_whole_buf;
37 	RBufferFreeWholeBuf free_whole_buf;
38 	RBufferNonEmptyList nonempty_list;
39 } RBufferMethods;
40 
41 struct r_buf_t {
42 	const RBufferMethods *methods;
43 	void *priv;
44 	ut8 *whole_buf;
45 	bool readonly;
46 	ut8 Oxff_priv;
47 	int refctr;
48 };
49 
50 // XXX: this should not be public
51 typedef struct r_buf_cache_t {
52 	ut64 from;
53 	ut64 to;
54 	int size;
55 	ut8 *data;
56 	int written;
57 } RBufferSparse;
58 
59 /* constructors */
60 R_API RBuffer *r_buf_new(void);
61 R_API RBuffer *r_buf_new_with_io(void *iob, int fd);
62 R_API RBuffer *r_buf_new_with_bytes(const ut8* bytes, ut64 len);
63 R_API RBuffer *r_buf_new_with_string(const char *msg);
64 R_API RBuffer *r_buf_new_with_pointers(const ut8 *bytes, ut64 len, bool steal);
65 R_API RBuffer *r_buf_new_file(const char *file, int perm, int mode);
66 R_API RBuffer *r_buf_new_with_buf(RBuffer *b);
67 R_API RBuffer *r_buf_new_slurp(const char *file);
68 R_API RBuffer *r_buf_new_slice(RBuffer *b, ut64 offset, ut64 size);
69 R_API RBuffer *r_buf_new_empty(ut64 len);
70 R_API RBuffer *r_buf_new_mmap(const char *file, int flags);
71 R_API RBuffer *r_buf_new_sparse(ut8 Oxff);
72 
73 /* methods */
74 R_API bool r_buf_dump(RBuffer *buf, const char *file);
75 R_API bool r_buf_set_bytes(RBuffer *b, const ut8 *buf, ut64 length);
76 R_API st64 r_buf_append_string(RBuffer *b, const char *str);
77 R_API bool r_buf_append_buf(RBuffer *b, RBuffer *a);
78 R_API bool r_buf_append_bytes(RBuffer *b, const ut8 *buf, ut64 length);
79 R_API bool r_buf_append_nbytes(RBuffer *b, ut64 length);
80 R_API bool r_buf_append_ut16(RBuffer *b, ut16 n);
81 R_API bool r_buf_append_buf_slice(RBuffer *b, RBuffer *a, ut64 offset, ut64 size);
82 R_API bool r_buf_append_ut32(RBuffer *b, ut32 n);
83 R_API bool r_buf_append_ut64(RBuffer *b, ut64 n);
84 R_API bool r_buf_prepend_bytes(RBuffer *b, const ut8 *buf, ut64 length);
85 R_API st64 r_buf_insert_bytes(RBuffer *b, ut64 addr, const ut8 *buf, ut64 length);
86 R_API char *r_buf_to_string(RBuffer *b);
87 R_API char *r_buf_get_string(RBuffer *b, ut64 addr);
88 R_API st64 r_buf_read(RBuffer *b, ut8 *buf, ut64 len);
89 R_API ut8 r_buf_read8(RBuffer *b);
90 R_API st64 r_buf_fread(RBuffer *b, ut8 *buf, const char *fmt, int n);
91 R_API st64 r_buf_read_at(RBuffer *b, ut64 addr, ut8 *buf, ut64 len);
92 R_API ut8 r_buf_read8_at(RBuffer *b, ut64 addr);
93 R_API ut64 r_buf_tell(RBuffer *b);
94 R_API st64 r_buf_seek(RBuffer *b, st64 addr, int whence);
95 R_API st64 r_buf_fread_at(RBuffer *b, ut64 addr, ut8 *buf, const char *fmt, int n);
96 R_API st64 r_buf_write(RBuffer *b, const ut8 *buf, ut64 len);
97 R_API st64 r_buf_fwrite(RBuffer *b, const ut8 *buf, const char *fmt, int n);
98 R_API st64 r_buf_write_at(RBuffer *b, ut64 addr, const ut8 *buf, ut64 len);
99 R_API st64 r_buf_fwrite_at(RBuffer *b, ut64 addr, const ut8 *buf, const char *fmt, int n);
100 // WARNING: this function should be used with care because it may allocate the
101 // entire buffer in memory. Consider using the r_buf_read* APIs instead and read
102 // only the chunks you need.
103 R_DEPRECATE R_API const ut8 *r_buf_data(RBuffer *b, ut64 *size);
104 R_API ut64 r_buf_size(RBuffer *b);
105 R_API bool r_buf_resize(RBuffer *b, ut64 newsize);
106 R_API RBuffer *r_buf_ref(RBuffer *b);
107 R_API void r_buf_free(RBuffer *b);
108 R_API bool r_buf_fini(RBuffer *b);
109 R_API RList *r_buf_nonempty_list(RBuffer *b);
110 
r_buf_read_be16(RBuffer * b)111 static inline ut16 r_buf_read_be16(RBuffer *b) {
112 	ut8 buf[sizeof (ut16)];
113 	int r = (int) r_buf_read (b, buf, sizeof (buf));
114 	return r == sizeof (buf)? r_read_be16 (buf): UT16_MAX;
115 }
116 
r_buf_read_be16_at(RBuffer * b,ut64 addr)117 static inline ut16 r_buf_read_be16_at(RBuffer *b, ut64 addr) {
118 	ut8 buf[sizeof (ut16)];
119 	int r = (int) r_buf_read_at (b, addr, buf, sizeof (buf));
120 	return r == sizeof (buf)? r_read_be16 (buf): UT16_MAX;
121 }
122 
r_buf_read_be32(RBuffer * b)123 static inline ut32 r_buf_read_be32(RBuffer *b) {
124 	ut8 buf[sizeof (ut32)];
125 	int r = (int) r_buf_read (b, buf, sizeof (buf));
126 	return r == sizeof (buf)? r_read_be32 (buf): UT32_MAX;
127 }
128 
r_buf_read_be32_at(RBuffer * b,ut64 addr)129 static inline ut32 r_buf_read_be32_at(RBuffer *b, ut64 addr) {
130 	ut8 buf[sizeof (ut32)];
131 	int r = (int) r_buf_read_at (b, addr, buf, sizeof (buf));
132 	return r == sizeof (buf)? r_read_be32 (buf): UT32_MAX;
133 }
134 
r_buf_read_be64(RBuffer * b)135 static inline ut64 r_buf_read_be64(RBuffer *b) {
136 	ut8 buf[sizeof (ut64)];
137 	int r = (int) r_buf_read (b, buf, sizeof (buf));
138 	return r == sizeof (buf)? r_read_be64 (buf): UT64_MAX;
139 }
140 
r_buf_read_be64_at(RBuffer * b,ut64 addr)141 static inline ut64 r_buf_read_be64_at(RBuffer *b, ut64 addr) {
142 	ut8 buf[sizeof (ut64)];
143 	int r = (int) r_buf_read_at (b, addr, buf, sizeof (buf));
144 	return r == sizeof (buf)? r_read_be64 (buf): UT64_MAX;
145 }
146 
r_buf_read_le16(RBuffer * b)147 static inline ut16 r_buf_read_le16(RBuffer *b) {
148 	ut8 buf[sizeof (ut16)];
149 	int r = (int) r_buf_read (b, buf, sizeof (buf));
150 	return r == sizeof (buf)? r_read_le16 (buf): UT16_MAX;
151 }
152 
r_buf_read_le16_at(RBuffer * b,ut64 addr)153 static inline ut16 r_buf_read_le16_at(RBuffer *b, ut64 addr) {
154 	ut8 buf[sizeof (ut16)];
155 	int r = (int) r_buf_read_at (b, addr, buf, sizeof (buf));
156 	return r == sizeof (buf)? r_read_le16 (buf): UT16_MAX;
157 }
158 
r_buf_read_le32(RBuffer * b)159 static inline ut32 r_buf_read_le32(RBuffer *b) {
160 	ut8 buf[sizeof (ut32)];
161 	int r = (int) r_buf_read (b, buf, sizeof (buf));
162 	return r == sizeof (buf)? r_read_le32 (buf): UT32_MAX;
163 }
164 
r_buf_read_le32_at(RBuffer * b,ut64 addr)165 static inline ut32 r_buf_read_le32_at(RBuffer *b, ut64 addr) {
166 	ut8 buf[sizeof (ut32)];
167 	int r = (int) r_buf_read_at (b, addr, buf, sizeof (buf));
168 	return r == sizeof (buf)? r_read_le32 (buf): UT32_MAX;
169 }
170 
r_buf_read_le64(RBuffer * b)171 static inline ut64 r_buf_read_le64(RBuffer *b) {
172 	ut8 buf[sizeof (ut64)];
173 	int r = (int) r_buf_read (b, buf, sizeof (buf));
174 	return r == sizeof (buf)? r_read_le64 (buf): UT64_MAX;
175 }
176 
r_buf_read_le64_at(RBuffer * b,ut64 addr)177 static inline ut64 r_buf_read_le64_at(RBuffer *b, ut64 addr) {
178 	ut8 buf[sizeof (ut64)];
179 	int r = (int) r_buf_read_at (b, addr, buf, sizeof (buf));
180 	return r == sizeof (buf)? r_read_le64 (buf): UT64_MAX;
181 }
182 
r_buf_read_ble16_at(RBuffer * b,ut64 addr,bool big_endian)183 static inline ut16 r_buf_read_ble16_at(RBuffer *b, ut64 addr, bool big_endian) {
184 	ut8 buf[sizeof (ut16)];
185 	int r = (int) r_buf_read_at (b, addr, buf, sizeof (buf));
186 	return r == sizeof (buf)? r_read_ble16 (buf, big_endian): UT16_MAX;
187 }
188 
r_buf_read_ble32_at(RBuffer * b,ut64 addr,bool big_endian)189 static inline ut32 r_buf_read_ble32_at(RBuffer *b, ut64 addr, bool big_endian) {
190 	ut8 buf[sizeof (ut32)];
191 	int r = (int) r_buf_read_at (b, addr, buf, sizeof (buf));
192 	return r == sizeof (buf)? r_read_ble32 (buf, big_endian): UT32_MAX;
193 }
194 
r_buf_read_ble64_at(RBuffer * b,ut64 addr,bool big_endian)195 static inline ut64 r_buf_read_ble64_at(RBuffer *b, ut64 addr, bool big_endian) {
196 	ut8 buf[sizeof (ut64)];
197 	int r = (int) r_buf_read_at (b, addr, buf, sizeof (buf));
198 	return r == sizeof (buf)? r_read_ble64 (buf, big_endian): UT64_MAX;
199 }
200 
201 R_API st64 r_buf_uleb128(RBuffer *b, ut64 *v);
202 R_API st64 r_buf_sleb128(RBuffer *b, st64 *v);
203 
r_buf_uleb128_at(RBuffer * b,ut64 addr,ut64 * v)204 static inline st64 r_buf_uleb128_at(RBuffer *b, ut64 addr, ut64 *v) {
205 	r_buf_seek (b, addr, R_BUF_SET);
206 	return r_buf_uleb128 (b, v);
207 }
r_buf_sleb128_at(RBuffer * b,ut64 addr,st64 * v)208 static inline st64 r_buf_sleb128_at(RBuffer *b, ut64 addr, st64 *v) {
209 	r_buf_seek (b, addr, R_BUF_SET);
210 	return r_buf_sleb128 (b, v);
211 }
212 
213 #ifdef __cplusplus
214 }
215 #endif
216 
217 #endif //  R_BUF_H
218