1 /* radare - LGPL - Copyright 2008-2020 - pancake */
2 
3 #include "io_memory.h"
4 
_io_malloc_sz(RIODesc * desc)5 static inline ut32 _io_malloc_sz(RIODesc *desc) {
6 	if (!desc) {
7 		return 0;
8 	}
9 	RIOMalloc *mal = (RIOMalloc*)desc->data;
10 	return mal? mal->size: 0;
11 }
12 
_io_malloc_set_sz(RIODesc * desc,ut32 sz)13 static inline void _io_malloc_set_sz(RIODesc *desc, ut32 sz) {
14 	if (!desc) {
15 		return;
16 	}
17 	RIOMalloc *mal = (RIOMalloc*)desc->data;
18 	if (mal) {
19 		mal->size = sz;
20 	}
21 }
22 
_io_malloc_buf(RIODesc * desc)23 static inline ut8* _io_malloc_buf(RIODesc *desc) {
24 	if (!desc) {
25 		return NULL;
26 	}
27 	RIOMalloc *mal = (RIOMalloc*)desc->data;
28 	return mal->buf;
29 }
30 
31 
_io_malloc_set_buf(RIODesc * desc,ut8 * buf)32 static inline ut8* _io_malloc_set_buf(RIODesc *desc, ut8* buf) {
33 	if (!desc) {
34 		return NULL;
35 	}
36 	RIOMalloc *mal = (RIOMalloc*)desc->data;
37 	return mal->buf = buf;
38 }
39 
_io_malloc_off(RIODesc * desc)40 static inline ut64 _io_malloc_off(RIODesc *desc) {
41 	if (!desc) {
42 		return 0;
43 	}
44 	RIOMalloc *mal = (RIOMalloc*)desc->data;
45 	return mal->offset;
46 }
47 
_io_malloc_set_off(RIODesc * desc,ut64 off)48 static inline void _io_malloc_set_off(RIODesc *desc, ut64 off) {
49 	if (!desc) {
50 		return;
51 	}
52 	RIOMalloc *mal = (RIOMalloc*)desc->data;
53 	mal->offset = off;
54 }
55 
io_memory_write(RIO * io,RIODesc * fd,const ut8 * buf,int count)56 int io_memory_write(RIO *io, RIODesc *fd, const ut8 *buf, int count) {
57 	if (!fd || !buf || count < 0 || !fd->data) {
58 		return -1;
59 	}
60 	if (_io_malloc_off (fd) > _io_malloc_sz (fd)) {
61 		return -1;
62 	}
63 	if (_io_malloc_off (fd) + count > _io_malloc_sz (fd)) {
64 		count -= (_io_malloc_off (fd) + count -_io_malloc_sz (fd));
65 	}
66 	if (count > 0) {
67 		memcpy (_io_malloc_buf (fd) + _io_malloc_off (fd), buf, count);
68 		_io_malloc_set_off (fd, _io_malloc_off (fd) + count);
69 		return count;
70 	}
71 	return -1;
72 }
73 
io_memory_resize(RIO * io,RIODesc * fd,ut64 count)74 bool io_memory_resize(RIO *io, RIODesc *fd, ut64 count) {
75 	ut8 * new_buf = NULL;
76 	if (!fd || !fd->data || count == 0) {
77 		return false;
78 	}
79 	ut32 mallocsz = _io_malloc_sz (fd);
80 	if (_io_malloc_off (fd) > mallocsz) {
81 		return false;
82 	}
83 	new_buf = malloc (count);
84 	if (!new_buf) {
85 		return false;
86 	}
87 	memcpy (new_buf, _io_malloc_buf (fd), R_MIN (count, mallocsz));
88 	if (count > mallocsz) {
89 		memset (new_buf + mallocsz, 0, count - mallocsz);
90 	}
91 	free (_io_malloc_buf (fd));
92 	_io_malloc_set_buf (fd, new_buf);
93 	_io_malloc_set_sz (fd, count);
94 	return true;
95 }
96 
io_memory_read(RIO * io,RIODesc * fd,ut8 * buf,int count)97 int io_memory_read(RIO *io, RIODesc *fd, ut8 *buf, int count) {
98 	memset (buf, 0xff, count);
99 	if (!fd || !fd->data) {
100 		return -1;
101 	}
102 	ut32 mallocsz = _io_malloc_sz (fd);
103 	if (_io_malloc_off (fd) > mallocsz) {
104 		return -1;
105 	}
106 	if (_io_malloc_off (fd) + count >= mallocsz) {
107 		count = mallocsz - _io_malloc_off (fd);
108 	}
109 	memcpy (buf, _io_malloc_buf (fd) + _io_malloc_off (fd), count);
110 	_io_malloc_set_off (fd, _io_malloc_off (fd) + count);
111 	return count;
112 }
113 
io_memory_close(RIODesc * fd)114 int io_memory_close(RIODesc *fd) {
115 	RIOMalloc *riom;
116 	if (!fd || !fd->data) {
117 		return -1;
118 	}
119 	riom = fd->data;
120 	R_FREE (riom->buf);
121 	R_FREE (fd->data);
122 	return 0;
123 }
124 
io_memory_lseek(RIO * io,RIODesc * fd,ut64 offset,int whence)125 ut64 io_memory_lseek(RIO* io, RIODesc *fd, ut64 offset, int whence) {
126 	ut64 r_offset = offset;
127 	if (!fd || !fd->data) {
128 		return offset;
129 	}
130 	ut32 mallocsz = _io_malloc_sz (fd);
131 	switch (whence) {
132 	case SEEK_SET:
133 		r_offset = (offset <= mallocsz) ? offset : mallocsz;
134 		break;
135 	case SEEK_CUR:
136 		r_offset = (_io_malloc_off (fd) + offset <= mallocsz ) ? _io_malloc_off (fd) + offset : mallocsz;
137 		break;
138 	case SEEK_END:
139 		r_offset = _io_malloc_sz (fd);
140 		break;
141 	}
142 	_io_malloc_set_off (fd, r_offset);
143 	return r_offset;
144 }
145