RzBuffer consistency and make buffer type public (#4666)
* Make rz_buf_read consistent. The IO buffer did not updated its seek after reading. Although most of the others do. The behavior is now documented. * Partially reverse seek on read for IO_FD and FILE buffers. Because it breaks too many tests. * Add type when initializing RzBuffer. * Remove duplicate documentation of RzBuffer read()
This commit is contained in:
parent
5ee08f716b
commit
08acf54585
8 changed files with 46 additions and 32 deletions
|
|
@ -285,7 +285,7 @@ static const RzBufferMethods buf_methods = {
|
|||
|
||||
RZ_API RzBuffer *rz_dyldcache_new_rebasing_buf(RzDyldCache *cache) {
|
||||
rz_return_val_if_fail(cache, NULL);
|
||||
return rz_buf_new_with_methods(&buf_methods, cache);
|
||||
return rz_buf_new_with_methods(&buf_methods, cache, RZ_BUFFER_CUSTOM);
|
||||
}
|
||||
|
||||
RZ_API bool rz_dyldcache_needs_rebasing(RzDyldCache *cache) {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ typedef struct rz_buf_t RzBuffer;
|
|||
|
||||
typedef bool (*RzBufferInit)(RzBuffer *b, const void *user);
|
||||
typedef bool (*RzBufferFini)(RzBuffer *b);
|
||||
typedef st64 (*RzBufferRead)(RzBuffer *b, ut8 *buf, ut64 len);
|
||||
typedef st64 (*RzBufferRead)(RZ_BORROW RzBuffer *b, RZ_OUT ut8 *buf, ut64 len);
|
||||
typedef st64 (*RzBufferWrite)(RzBuffer *b, const ut8 *buf, ut64 len);
|
||||
typedef ut64 (*RzBufferGetSize)(RzBuffer *b);
|
||||
typedef bool (*RzBufferResize)(RzBuffer *b, ut64 newsize);
|
||||
|
|
@ -31,7 +31,7 @@ typedef RzList *(*RzBufferNonEmptyList)(RzBuffer *b);
|
|||
typedef struct rz_buffer_methods_t {
|
||||
RzBufferInit init;
|
||||
RzBufferFini fini;
|
||||
RzBufferRead read;
|
||||
RzBufferRead read; ///< The buffer read() method. It should behave as rz_buf_read() documents.
|
||||
RzBufferWrite write;
|
||||
RzBufferGetSize get_size;
|
||||
RzBufferResize resize;
|
||||
|
|
@ -40,7 +40,20 @@ typedef struct rz_buffer_methods_t {
|
|||
RzBufferFreeWholeBuf free_whole_buf;
|
||||
} RzBufferMethods;
|
||||
|
||||
typedef enum {
|
||||
RZ_BUFFER_INVALID = 0,
|
||||
RZ_BUFFER_FILE,
|
||||
RZ_BUFFER_IO_FD,
|
||||
RZ_BUFFER_IO, ///< A buffer over RzIO.
|
||||
RZ_BUFFER_BYTES, ///< A buffer over raw bytes.
|
||||
RZ_BUFFER_MMAP,
|
||||
RZ_BUFFER_SPARSE,
|
||||
RZ_BUFFER_REF,
|
||||
RZ_BUFFER_CUSTOM, ///< A buffer with custom methods.
|
||||
} RzBufferType;
|
||||
|
||||
struct rz_buf_t {
|
||||
RzBufferType type;
|
||||
const RzBufferMethods *methods;
|
||||
void *priv;
|
||||
ut8 *whole_buf;
|
||||
|
|
@ -99,7 +112,7 @@ RZ_API RZ_OWN RzBuffer *rz_buf_new_with_buf(RzBuffer *b);
|
|||
RZ_API RZ_OWN RzBuffer *rz_buf_new_with_bytes(RZ_NULLABLE RZ_BORROW const ut8 *bytes, ut64 len);
|
||||
RZ_API RZ_OWN RzBuffer *rz_buf_new_with_io_fd(RZ_NONNULL void /* RzIOBind */ *iob, int fd);
|
||||
RZ_API RZ_OWN RzBuffer *rz_buf_new_with_io(RZ_NONNULL void /* RzIOBind */ *iob);
|
||||
RZ_API RZ_OWN RzBuffer *rz_buf_new_with_methods(RZ_NONNULL const RzBufferMethods *methods, void *init_user);
|
||||
RZ_API RZ_OWN RzBuffer *rz_buf_new_with_methods(RZ_NONNULL const RzBufferMethods *methods, void *init_user, RzBufferType type);
|
||||
RZ_API RZ_OWN RzBuffer *rz_buf_new_with_pointers(const ut8 *bytes, ut64 len, bool steal);
|
||||
RZ_API RZ_OWN RzBuffer *rz_buf_new_with_string(RZ_NONNULL const char *msg);
|
||||
|
||||
|
|
|
|||
|
|
@ -6,16 +6,6 @@
|
|||
#include <rz_util.h>
|
||||
#include <rz_io.h>
|
||||
|
||||
typedef enum {
|
||||
RZ_BUFFER_FILE,
|
||||
RZ_BUFFER_IO_FD,
|
||||
RZ_BUFFER_IO,
|
||||
RZ_BUFFER_BYTES,
|
||||
RZ_BUFFER_MMAP,
|
||||
RZ_BUFFER_SPARSE,
|
||||
RZ_BUFFER_REF,
|
||||
} RzBufferType;
|
||||
|
||||
#include "buf_file.c"
|
||||
#include "buf_sparse.c"
|
||||
#include "buf_bytes.c"
|
||||
|
|
@ -313,7 +303,7 @@ static RzBuffer *new_buffer(RzBufferType type, void *user) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
return rz_buf_new_with_methods(methods, user);
|
||||
return rz_buf_new_with_methods(methods, user, type);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -564,12 +554,13 @@ RZ_API RZ_OWN RzBuffer *rz_buf_new_with_io(RZ_NONNULL void *iob) {
|
|||
* The function creates a new allocated buffer using a custom back end. This function
|
||||
* should only be used when no other back end are appropriate.
|
||||
*/
|
||||
RZ_API RZ_OWN RzBuffer *rz_buf_new_with_methods(RZ_NONNULL const RzBufferMethods *methods, void *init_user) {
|
||||
RZ_API RZ_OWN RzBuffer *rz_buf_new_with_methods(RZ_NONNULL const RzBufferMethods *methods, void *init_user, RzBufferType type) {
|
||||
RzBuffer *b = RZ_NEW0(RzBuffer);
|
||||
if (!b) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
b->type = type;
|
||||
b->methods = methods;
|
||||
|
||||
if (!buf_init(b, init_user)) {
|
||||
|
|
@ -1168,13 +1159,18 @@ RZ_API st64 rz_buf_insert_bytes(RZ_NONNULL RzBuffer *b, ut64 addr, RZ_NONNULL co
|
|||
}
|
||||
|
||||
/**
|
||||
* \brief Read len bytes of the buffer at the cursor.
|
||||
* \param b ...
|
||||
* \param buf ...
|
||||
* \param len ...
|
||||
* \return Return the number of bytes read.
|
||||
* \brief Reads \p len bytes from buffer \p b into \p buf.
|
||||
* \p buf should have enough space to contain the bytes.
|
||||
* The seek of \p b is advanced by \p len bytes.
|
||||
* EXCEPT: RZ_BUF_IO_FD, RZ_BUF_FILE.
|
||||
* Because they were implemented without seek advancement.
|
||||
* And changing it breaks everything. Sorry :/
|
||||
*
|
||||
* ...
|
||||
* \param b The buffer to read from.
|
||||
* \param buf The array to move te bytes into.
|
||||
* \param len The number of bytes to read from the buffer.
|
||||
*
|
||||
* \return The number of bytes read. -1 in case of error and 0 for EOF reached.
|
||||
*/
|
||||
RZ_API st64 rz_buf_read(RZ_NONNULL RzBuffer *b, RZ_NONNULL ut8 RZ_OUT *buf, ut64 len) {
|
||||
rz_return_val_if_fail(b && buf, -1);
|
||||
|
|
|
|||
|
|
@ -73,12 +73,12 @@ static bool buf_bytes_resize(RzBuffer *b, ut64 newsize) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static st64 buf_bytes_read(RzBuffer *b, ut8 *buf, ut64 len) {
|
||||
static st64 buf_bytes_read(RZ_BORROW RzBuffer *b, RZ_OUT ut8 *buf, ut64 len) {
|
||||
struct buf_bytes_priv *priv = get_priv_bytes(b);
|
||||
if (!priv->buf) {
|
||||
// This can happen when called from buf_mmap.c, when you open a 0-length
|
||||
// file.
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
ut64 real_len = priv->length < priv->offset ? 0 : RZ_MIN(priv->length - priv->offset, len);
|
||||
memmove(buf, priv->buf + priv->offset, real_len);
|
||||
|
|
|
|||
|
|
@ -55,9 +55,10 @@ static ut64 buf_file_get_size(RzBuffer *b) {
|
|||
return (ut64)res;
|
||||
}
|
||||
|
||||
static st64 buf_file_read(RzBuffer *b, ut8 *buf, ut64 len) {
|
||||
static st64 buf_file_read(RZ_BORROW RzBuffer *b, RZ_OUT ut8 *buf, ut64 len) {
|
||||
struct buf_file_priv *priv = get_priv_file(b);
|
||||
return read(priv->fd, buf, len);
|
||||
ssize_t result = read(priv->fd, buf, len);
|
||||
return result;
|
||||
}
|
||||
|
||||
static st64 buf_file_write(RzBuffer *b, const ut8 *buf, ut64 len) {
|
||||
|
|
|
|||
|
|
@ -44,8 +44,11 @@ static st64 buf_io_seek(RzBuffer *b, st64 addr, int whence) {
|
|||
static st64 buf_io_read(RzBuffer *b, ut8 *buf, ut64 len) {
|
||||
BufIOPriv *priv = b->priv;
|
||||
len = RZ_MIN(INT_MAX, len); // remove if read_at takes ut64 at some point
|
||||
bool r = priv->iob->read_at(priv->iob->io, priv->offset, buf, len);
|
||||
return r ? len : -1;
|
||||
bool success = priv->iob->read_at(priv->iob->io, priv->offset, buf, len);
|
||||
if (success) {
|
||||
rz_seek_offset(priv->offset, 0, len, RZ_BUF_CUR);
|
||||
}
|
||||
return success ? len : -1;
|
||||
}
|
||||
|
||||
static st64 buf_io_write(RzBuffer *b, const ut8 *buf, ut64 len) {
|
||||
|
|
|
|||
|
|
@ -70,9 +70,10 @@ static bool buf_io_fd_resize(RzBuffer *b, ut64 newsize) {
|
|||
return priv->iob->fd_resize(priv->iob->io, priv->fd, newsize);
|
||||
}
|
||||
|
||||
static st64 buf_io_fd_read(RzBuffer *b, ut8 *buf, ut64 len) {
|
||||
static st64 buf_io_fd_read(RZ_BORROW RzBuffer *b, RZ_OUT ut8 *buf, ut64 len) {
|
||||
struct buf_io_fd_priv *priv = get_priv_io(b);
|
||||
return priv->iob->fd_read(priv->iob->io, priv->fd, buf, len);
|
||||
st64 result = priv->iob->fd_read(priv->iob->io, priv->fd, buf, len);
|
||||
return result;
|
||||
}
|
||||
|
||||
static st64 buf_io_fd_write(RzBuffer *b, const ut8 *buf, ut64 len) {
|
||||
|
|
|
|||
|
|
@ -1271,7 +1271,7 @@ const RzBufferMethods custom_methods = {
|
|||
|
||||
bool test_rz_buf_with_methods(void) {
|
||||
CustomCtx ctx = { 0 };
|
||||
RzBuffer *buf = rz_buf_new_with_methods(&custom_methods, &ctx);
|
||||
RzBuffer *buf = rz_buf_new_with_methods(&custom_methods, &ctx, RZ_BUFFER_CUSTOM);
|
||||
mu_assert_notnull(buf, "buf");
|
||||
mu_assert_eq(ctx.init_count, 1, "init count");
|
||||
mu_assert_eq(ctx.fini_count, 0, "fini count");
|
||||
|
|
@ -1330,7 +1330,7 @@ const RzBufferMethods custom_methods2 = {
|
|||
bool test_rz_buf_whole_buf_alloc(void) {
|
||||
CustomCtx ctx = { 0 };
|
||||
ut64 size;
|
||||
RzBuffer *b = rz_buf_new_with_methods(&custom_methods2, &ctx);
|
||||
RzBuffer *b = rz_buf_new_with_methods(&custom_methods2, &ctx, RZ_BUFFER_CUSTOM);
|
||||
const ut8 *bb1 = rz_buf_data(b, &size);
|
||||
mu_assert_notnull(bb1, "buf_data is not NULL");
|
||||
const ut8 *bb2 = rz_buf_data(b, &size);
|
||||
|
|
|
|||
Loading…
Reference in a new issue