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