mirror of
https://github.com/radareorg/radare2.git
synced 2025-03-05 12:57:34 +00:00
123 lines
2.7 KiB
C
123 lines
2.7 KiB
C
/* radare - LGPL - Copyright 2015-2016 - pancake */
|
|
|
|
#include "r_io.h"
|
|
#include "r_lib.h"
|
|
#include "r_util.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <sys/types.h>
|
|
|
|
typedef struct {
|
|
int fd;
|
|
RBuffer *buf;
|
|
ut64 offset;
|
|
} RIOSparse;
|
|
|
|
#define RIOSPARSE_FD(x) (((RIOSparse*)x->data)->fd)
|
|
#define RIOSPARSE_BUF(x) (((RIOSparse*)x->data)->buf)
|
|
#define RIOSPARSE_OFF(x) (((RIOSparse*)x->data)->offset)
|
|
|
|
static int __write(RIO *io, RIODesc *fd, const ut8 *buf, int count) {
|
|
ut64 o;
|
|
RBuffer *b;
|
|
if (!fd || !fd->data)
|
|
return -1;
|
|
b = RIOSPARSE_BUF(fd);
|
|
o = RIOSPARSE_OFF(fd);
|
|
return r_buf_write_at (b, o, buf, count);
|
|
}
|
|
|
|
static int __read(RIO *io, RIODesc *fd, ut8 *buf, int count) {
|
|
ut64 o;
|
|
RBuffer *b;
|
|
if (!fd || !fd->data)
|
|
return -1;
|
|
b = RIOSPARSE_BUF(fd);
|
|
o = RIOSPARSE_OFF(fd);
|
|
(void)r_buf_read_at (b, o, buf, count);
|
|
return count;
|
|
}
|
|
|
|
static int __close(RIODesc *fd) {
|
|
RIOSparse *riom;
|
|
if (!fd || !fd->data)
|
|
return -1;
|
|
riom = fd->data;
|
|
free (riom->buf);
|
|
riom->buf = NULL;
|
|
free (fd->data);
|
|
fd->data = NULL;
|
|
fd->state = R_IO_DESC_TYPE_CLOSED;
|
|
return 0;
|
|
}
|
|
|
|
static ut64 __lseek(RIO* io, RIODesc *fd, ut64 offset, int whence) {
|
|
RBuffer *b;
|
|
ut64 r_offset = offset;
|
|
if (!fd->data)
|
|
return offset;
|
|
b = RIOSPARSE_BUF(fd);
|
|
r_offset = r_buf_seek (b, offset, whence);
|
|
//if (r_offset != UT64_MAX)
|
|
RIOSPARSE_OFF (fd) = r_offset;
|
|
return r_offset;
|
|
}
|
|
|
|
static bool __plugin_open(struct r_io_t *io, const char *pathname, bool many) {
|
|
return (!strncmp (pathname, "sparse://", 9));
|
|
}
|
|
|
|
static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) {
|
|
if (__plugin_open (io, pathname,0)) {
|
|
RIOSparse *mal = R_NEW0 (RIOSparse);
|
|
if (!mal) return NULL;
|
|
mal->fd = -2; /* causes r_io_desc_new() to set the correct fd */
|
|
int size = (int)r_num_math (NULL, pathname+9);
|
|
mal->buf = r_buf_new_sparse ();
|
|
if (!mal->buf) {
|
|
free (mal);
|
|
return NULL;
|
|
}
|
|
if (size>0) {
|
|
ut8 *data = malloc (size);
|
|
if (!data) {
|
|
eprintf ("Cannot allocate (%s) %d bytes\n",
|
|
pathname+9, size);
|
|
mal->offset = 0;
|
|
} else {
|
|
memset (data, 0x00, size);
|
|
r_buf_write_at (mal->buf, 0, data, size);
|
|
free (data);
|
|
}
|
|
}
|
|
if (mal->buf) {
|
|
RETURN_IO_DESC_NEW (&r_io_plugin_sparse,
|
|
mal->fd, pathname, rw, mode, mal);
|
|
}
|
|
r_buf_free (mal->buf);
|
|
free (mal);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
RIOPlugin r_io_plugin_sparse = {
|
|
.name = "sparse",
|
|
.desc = "sparse buffer allocation (sparse://1024 sparse://)",
|
|
.license = "LGPL3",
|
|
.open = __open,
|
|
.close = __close,
|
|
.read = __read,
|
|
.check = __plugin_open,
|
|
.lseek = __lseek,
|
|
.write = __write,
|
|
.resize = NULL,
|
|
};
|
|
|
|
#ifndef CORELIB
|
|
struct r_lib_struct_t radare_plugin = {
|
|
.type = R_LIB_TYPE_IO,
|
|
.data = &r_io_plugin_sparse,
|
|
.version = R2_VERSION
|
|
};
|
|
#endif
|