Implement first/last/next/prev fd APIs ##io

This commit is contained in:
condret 2020-11-01 02:39:32 +01:00 committed by pancake
parent d08ea37ae9
commit 965b0fa4e0
4 changed files with 132 additions and 11 deletions

View File

@ -37,11 +37,15 @@ R_API RIDStorage *r_id_storage_new(ut32 start_id, ut32 last_id);
R_API bool r_id_storage_set(RIDStorage *storage, void *data, ut32 id);
R_API bool r_id_storage_add(RIDStorage *storage, void *data, ut32 *id);
R_API void *r_id_storage_get(RIDStorage *storage, ut32 id);
R_API bool r_id_storage_get_next(RIDStorage *storage, ut32 *id);
R_API bool r_id_storage_get_prev(RIDStorage *storage, ut32 *id);
R_API void r_id_storage_delete(RIDStorage *storage, ut32 id);
R_API void *r_id_storage_take(RIDStorage *storage, ut32 id);
R_API bool r_id_storage_foreach(RIDStorage *storage, RIDStorageForeachCb cb, void *user);
R_API void r_id_storage_free(RIDStorage *storage);
R_API RList *r_id_storage_list(RIDStorage *s);
R_API bool r_id_storage_get_lowest(RIDStorage *storage, ut32 *id);
R_API bool r_id_storage_get_highest(RIDStorage *storage, ut32 *id);
typedef struct r_ordered_id_storage_t {
ut32 *permutation;

View File

@ -72,6 +72,40 @@ R_API RIODesc* r_io_desc_get(RIO* io, int fd) {
return (RIODesc*) r_id_storage_get (io->files, fd);
}
R_API RIODesc *r_io_desc_get_next(RIO *io, RIODesc *desc) {
r_return_val_if_fail (desc && io && io->files, NULL);
const int next_fd = r_io_fd_get_next (io, desc->fd);
if (next_fd == -1) {
return NULL;
}
return (RIODesc*) r_id_storage_get (io->files, next_fd);
}
R_API RIODesc *r_io_desc_get_prev(RIO *io, RIODesc *desc) {
r_return_val_if_fail (desc && io && io->files, NULL);
const int prev_fd = r_io_fd_get_prev (io, desc->fd);
if (prev_fd == -1) {
return NULL;
}
return (RIODesc*) r_id_storage_get (io->files, prev_fd);
}
R_API RIODesc *r_io_desc_get_highest(RIO *io) {
int fd = r_io_fd_get_highest (io);
if (fd == -1) {
return NULL;
}
return r_io_desc_get (io, fd);
}
R_API RIODesc *r_io_desc_get_lowest(RIO *io) {
int fd = r_io_fd_get_lowest (io);
if (fd == -1) {
return NULL;
}
return r_io_desc_get (io, fd);
}
R_API RIODesc *r_io_desc_open(RIO *io, const char *uri, int perm, int mode) {
r_return_val_if_fail (io && uri, NULL);
RIOPlugin *plugin = r_io_plugin_resolve (io, uri, 0);

View File

@ -1,4 +1,4 @@
/* radare2 - LGPL - Copyright 2017 - condret */
/* radare2 - LGPL - Copyright 2017-2020 - condret */
#include <r_io.h>
@ -126,3 +126,39 @@ R_API int r_io_fd_get_current(RIO *io) {
}
return -1;
}
R_API int r_io_fd_get_next(RIO *io, int fd) {
r_return_val_if_fail (io, -1);
int ret = fd;
if (!r_id_storage_get_next (io->files, (ut32 *)&ret)) {
return -1;
}
return ret;
}
R_API int r_io_fd_get_prev(RIO *io, int fd) {
r_return_val_if_fail (io, -1);
int ret = fd;
if (!r_id_storage_get_prev (io->files, (ut32 *)&ret)) {
return -1;
}
return ret;
}
R_API int r_io_fd_get_highest(RIO *io) {
r_return_val_if_fail (io, -1);
int fd = -1;
if (!r_id_storage_get_highest (io->files, (ut32 *)&fd)) {
return -1;
}
return fd;
}
R_API int r_io_fd_get_lowest(RIO *io) {
r_return_val_if_fail (io, -1);
int fd = -1;
if (!r_id_storage_get_lowest (io->files, (ut32 *)&fd)) {
return -1;
}
return fd;
}

View File

@ -1,4 +1,4 @@
/* radare2 - LGPL - Copyright 2017-2018 - condret */
/* radare2 - LGPL - Copyright 2017-2020 - condret */
#include <r_util.h>
#include <r_types.h>
@ -22,19 +22,18 @@ R_API RIDPool* r_id_pool_new(ut32 start_id, ut32 last_id) {
RIDPool* pool = NULL;
if (start_id < last_id) {
pool = R_NEW0 (RIDPool);
if (!pool) {
return NULL;
if (pool) {
pool->next_id = pool->start_id = start_id;
pool->last_id = last_id;
}
pool->next_id = pool->start_id = start_id;
pool->last_id = last_id;
}
return pool;
}
R_API bool r_id_pool_grab_id(RIDPool* pool, ut32* grabber) {
if (!pool || !grabber) {
return false;
}
r_return_val_if_fail (pool && grabber, false);
*grabber = UT32_MAX;
if (pool->freed_ids) {
ut32 grab = (ut32) (size_t)r_queue_dequeue (pool->freed_ids);
*grabber = (ut32) grab;
@ -75,9 +74,9 @@ R_API void r_id_pool_free(RIDPool* pool) {
}
R_API RIDStorage* r_id_storage_new(ut32 start_id, ut32 last_id) {
RIDPool* pool;
RIDStorage* storage = NULL;
if ((start_id < 16) && (pool = r_id_pool_new (start_id, last_id))) {
RIDPool *pool = r_id_pool_new (start_id, last_id);
if (pool) {
storage = R_NEW0 (RIDStorage);
if (!storage) {
r_id_pool_free (pool);
@ -163,6 +162,54 @@ R_API void* r_id_storage_get(RIDStorage* storage, ut32 id) {
return storage->data[id];
}
R_API bool r_id_storage_get_lowest(RIDStorage *storage, ut32 *id) {
r_return_val_if_fail (storage, false);
ut32 i;
for (i = 0; i < storage->size && !storage->data[i]; i++);
*id = i;
return i < storage->size;
}
R_API bool r_id_storage_get_highest(RIDStorage *storage, ut32 *id) {
r_return_val_if_fail (storage, false);
size_t i = 0;
if (storage->size > 0) {
for (i = storage->size - 1; !storage->data[i] && i > 0; i--);
*id = i;
return storage->data[i] != NULL;
}
// *id = i;
return false;
}
R_API bool r_id_storage_get_next(RIDStorage *storage, ut32 *idref) {
r_return_val_if_fail (idref && storage, false);
ut32 id = *idref;
if (storage->size < 1 || id >= storage->size || !storage->data) {
return false;
}
for (id = *idref + 1; id < storage->size && !storage->data[id]; id++);
if (id < storage->size) {
*idref = id;
return true;
}
return false;
}
R_API bool r_id_storage_get_prev(RIDStorage *storage, ut32 *idref) {
r_return_val_if_fail (idref && storage, false);
ut32 id = *idref;
if (id == 0 || id >= storage->size || storage->size < 1 || !storage->data) {
return false;
}
for (id = *idref - 1; id > 0 && !storage->data[id]; id--);
if (storage->data[id]) {
*idref = id;
return true;
}
return false;
}
R_API void r_id_storage_delete(RIDStorage* storage, ut32 id) {
if (!storage || !storage->data || (storage->size <= id)) {
return;