16#ifndef LIEF_BINARY_STREAM_H
17#define LIEF_BINARY_STREAM_H
27#include "LIEF/BinaryStream/Convert.hpp"
28#include "LIEF/errors.hpp"
37 enum class STREAM_TYPE {
49 virtual uint64_t size()
const = 0;
51 STREAM_TYPE type()
const {
62 result<std::string> peek_string_at(
size_t offset,
size_t maxsize = ~
static_cast<size_t>(0))
const;
74 virtual ok_error_t peek_data(std::vector<uint8_t>& container,
75 uint64_t offset, uint64_t size)
83 const bool read_ok = offset <= this->size() && (offset + size) <= this->size()
85 && (
static_cast<int64_t
>(offset) >= 0 &&
static_cast<int64_t
>(size) >= 0)
86 && (
static_cast<int64_t
>(offset + size) >= 0);
88 return make_error_code(lief_errors::read_error);
90 container.resize(size);
91 if (peek_in(container.data(), offset, size)) {
94 return make_error_code(lief_errors::read_error);
97 virtual ok_error_t read_data(std::vector<uint8_t>& container, uint64_t size) {
98 if (!peek_data(container, pos(), size)) {
99 return make_error_code(lief_errors::read_error);
106 void setpos(
size_t pos)
const;
107 void increment_pos(
size_t value)
const;
108 void decrement_pos(
size_t value)
const;
111 operator bool()
const;
114 const T* read_array(
size_t size)
const;
123 const T* peek_array(
size_t size)
const;
126 const T* peek_array(
size_t offset,
size_t size)
const;
132 bool can_read()
const;
135 bool can_read(
size_t offset)
const;
137 size_t align(
size_t align_on)
const;
141 typename std::enable_if<std::is_integral<T>::value,
result<T>>::type
145 typename std::enable_if<!std::is_integral<T>::value,
result<T>>::type
149 result<T> peek_conv(
size_t offset)
const;
156 std::unique_ptr<T[]> read_conv_array(
size_t size)
const;
159 std::unique_ptr<T[]> peek_conv_array(
size_t offset,
size_t size)
const;
162 static T swap_endian(T u);
164 void set_endian_swap(
bool swap);
167 static bool is_all_zero(
const T& buffer) {
168 const auto* ptr =
reinterpret_cast<const uint8_t *const
>(&buffer);
169 return std::all_of(ptr, ptr +
sizeof(T),
170 [] (uint8_t x) {
return x == 0; });
173 bool should_swap()
const {
177 virtual const uint8_t* p()
const {
181 virtual uint8_t* start() {
182 return const_cast<uint8_t*
>(
static_cast<const BinaryStream*
>(
this)->start());
185 virtual uint8_t* p() {
186 return const_cast<uint8_t*
>(
static_cast<const BinaryStream*
>(
this)->p());
189 virtual uint8_t* end() {
190 return const_cast<uint8_t*
>(
static_cast<const BinaryStream*
>(
this)->end());
193 virtual const uint8_t* start()
const {
197 virtual const uint8_t* end()
const {
203 virtual ok_error_t peek_in(
void* dst, uint64_t offset, uint64_t size)
const {
204 if (
auto raw = read_at(offset, size)) {
205 if (dst ==
nullptr) {
206 return make_error_code(lief_errors::read_error);
209 const void* ptr = *raw;
211 if (ptr ==
nullptr) {
212 return make_error_code(lief_errors::read_error);
215 memcpy(dst, ptr, size);
218 return make_error_code(lief_errors::read_error);
220 mutable size_t pos_ = 0;
221 bool endian_swap_ =
false;
222 STREAM_TYPE stype_ = STREAM_TYPE::UNKNOWN;
246 stream_.setpos(pos_);
273 this->increment_pos(
sizeof(T));
278result<T> BinaryStream::peek()
const {
279 const auto current_p = pos();
281 if (
auto res = peek_in(&ret, pos(),
sizeof(T))) {
287 return make_error_code(lief_errors::read_error);
291result<T> BinaryStream::peek(
size_t offset)
const {
292 const size_t saved_offset = this->pos();
293 this->setpos(offset);
294 result<T> r = this->peek<T>();
295 this->setpos(saved_offset);
301const T* BinaryStream::peek_array(
size_t size)
const {
302 result<const void*> raw = this->read_at(this->pos(),
sizeof(T) * size);
306 return reinterpret_cast<const T*
>(raw.value());
310const T* BinaryStream::peek_array(
size_t offset,
size_t size)
const {
311 const size_t saved_offset = this->pos();
312 this->setpos(offset);
313 const T* r = this->peek_array<T>(size);
314 this->setpos(saved_offset);
320bool BinaryStream::can_read()
const {
323 return pos_ < size() && (pos_ +
sizeof(T)) < size();
328bool BinaryStream::can_read(
size_t offset)
const {
331 return offset < size() && (offset +
sizeof(T)) < size();
336const T* BinaryStream::read_array(
size_t size)
const {
337 const T* tmp = this->peek_array<T>(size);
338 this->increment_pos(
sizeof(T) * size);
344result<T> BinaryStream::read_conv()
const {
345 result<T> tmp = this->peek_conv<T>();
349 this->increment_pos(
sizeof(T));
354typename std::enable_if<std::is_integral<T>::value, result<T>>::type
355BinaryStream::peek_conv()
const {
357 if (
auto res = peek_in(&ret, pos(),
sizeof(T))) {
358 return endian_swap_ ? swap_endian<T>(ret) : ret;
360 return make_error_code(lief_errors::read_error);
364typename std::enable_if<!std::is_integral<T>::value, result<T>>::type
365BinaryStream::peek_conv()
const {
367 if (
auto res = peek_in(&ret, pos(),
sizeof(T))) {
369 LIEF::Convert::swap_endian<T>(&ret);
373 return make_error_code(lief_errors::read_error);
378result<T> BinaryStream::peek_conv(
size_t offset)
const {
379 const size_t saved_offset = this->pos();
380 this->setpos(offset);
381 result<T> r = this->peek_conv<T>();
382 this->setpos(saved_offset);
388std::unique_ptr<T[]> BinaryStream::read_conv_array(
size_t size)
const {
389 const T *t = this->read_array<T>(size);
395 std::unique_ptr<T[]> uptr(
new T[size]);
397 for (
size_t i = 0; i < size; i++) {
399 if (this->endian_swap_) {
400 LIEF::Convert::swap_endian<T>(& uptr[i]);
408std::unique_ptr<T[]> BinaryStream::peek_conv_array(
size_t offset,
size_t size)
const {
409 const T *t = this->peek_array<T>(offset, size);
415 std::unique_ptr<T[]> uptr(
new T[size]);
417 for (
size_t i = 0; i < size; i++) {
419 if (this->endian_swap_) {
420 LIEF::Convert::swap_endian<T>(& uptr[i]);
Definition ASN1Reader.hpp:32
Class that is used to a read stream of data from different sources.
Definition BinaryStream.hpp:34
Definition BinaryStream.hpp:225
LIEF namespace.
Definition Abstract/Binary.hpp:32
result< ok_t > ok_error_t
Opaque structure that is used by LIEF to avoid writing result<void> f(...). Instead,...
Definition errors.hpp:106
ok_t ok()
Return success for function with return type ok_error_t.
Definition errors.hpp:90
tl::expected< T, lief_errors > result
Wrapper that contains an Object (T) or an error.
Definition errors.hpp:72