veriblock-pop-cpp
C++11 Libraries for leveraging VeriBlock Proof-Of-Proof blockchain technology.
read_stream.hpp
1// Copyright (c) 2019-2022 Xenios SEZC
2// https://www.veriblock.org
3// Distributed under the MIT software license, see the accompanying
4// file LICENSE or http://www.opensource.org/licenses/mit-license.php.
5
6#ifndef ALT_INTEGRATION_VERIBLOCK_READ_STREAM_HPP
7#define ALT_INTEGRATION_VERIBLOCK_READ_STREAM_HPP
8
9#include <stdexcept>
10#include <type_traits>
11#include <vector>
12
13#include "assert.hpp"
14#include "slice.hpp"
15#include "validation_state.hpp"
16
17namespace altintegration {
18
22struct ReadStream {
23 public:
24 ReadStream(const void *buff, size_t size);
25
26 explicit ReadStream(Slice<const uint8_t> slice);
27
28 explicit ReadStream(const std::vector<uint8_t> &v);
29
30 explicit ReadStream(const std::string &s);
31
32 // movable
33 explicit ReadStream(ReadStream &&) = default;
34 ReadStream &operator=(ReadStream &&) = default;
35
43 bool read(size_t size, uint8_t *out, ValidationState &state);
44
45 std::vector<uint8_t> assertRead(size_t size);
46
47 bool readSlice(size_t size,
49 ValidationState &state);
50
51 Slice<const uint8_t> assertReadSlice(size_t size);
52
53 template <
54 typename T,
55 typename = typename std::enable_if<std::is_integral<T>::value>::type>
56 T assertReadBE(size_t bytes = sizeof(T)) {
57 ValidationState state;
58 T t = 0;
59 bool result = readBE<T>(t, state, bytes);
60 VBK_ASSERT_MSG(result, "Can't readBE: %s", state.toString());
61 return t;
62 }
63
64 // big endian
65 template <
66 typename T,
67 typename = typename std::enable_if<std::is_integral<T>::value>::type>
68 bool readBE(T &t, ValidationState &state, size_t bytes = sizeof(T)) {
69 if (!hasMore(bytes)) {
70 return state.Invalid(
71 "readbe-underflow",
72 format("Tried to read {} bytes from stream, but it has {} bytes",
73 bytes,
74 remaining()));
75 }
76 t = 0;
77 for (size_t i = 0, shift = (bytes - 1) * 8; i < bytes; i++, shift -= 8) {
78 t += static_cast<T>((static_cast<T>(m_Buffer[m_Pos++])) << shift);
79 }
80 return true;
81 }
82
83 template <
84 typename T,
85 typename = typename std::enable_if<std::is_integral<T>::value>::type>
86 T assertReadLE() {
87 ValidationState state;
88 T t = 0;
89 bool result = readLE<T>(t, state);
90 VBK_ASSERT_MSG(result, "Can't readLE: %s", state.toString());
91 return t;
92 }
93
94 // little endian
95 template <
96 typename T,
97 typename = typename std::enable_if<std::is_integral<T>::value>::type>
98 bool readLE(T &t, ValidationState &state) {
99 if (!hasMore(sizeof(T))) {
100 return state.Invalid(
101 "readle-underflow",
102 format("Tried to read {} bytes from stream, but it has {} bytes",
103 sizeof(T),
104 remaining()));
105 }
106
107 t = 0;
108 for (size_t i = 0, shift = 0; i < sizeof(T); i++, shift += 8) {
109 t += static_cast<T>((static_cast<T>(m_Buffer[m_Pos++])) << shift);
110 }
111 return true;
112 }
113
114 uint32_t getVersion() const noexcept;
115 void setVersion(uint32_t version) noexcept;
116 size_t position() const noexcept;
117 void setPosition(const size_t &) noexcept;
118 size_t remaining() const noexcept { return (m_Size - m_Pos); }
119 bool hasMore(size_t nbytes) const noexcept { return (remaining() >= nbytes); }
120 void reset() noexcept;
121 Slice<const uint8_t> data() const;
122 Slice<const uint8_t> remainingBytes() const;
123
124 private:
125 void assign(const void *buff, size_t numOfBytes);
126
127 // publicly non-copyable
128 ReadStream(const ReadStream &) = default;
129 ReadStream &operator=(const ReadStream &) = default;
130
131 private:
132 uint32_t m_version{0};
133 size_t m_Pos{0};
134 const uint8_t *m_Buffer{nullptr};
135 size_t m_Size{0};
136};
137
138} // namespace altintegration
139
140#endif
Class that is used for storing validation state.
Defines logging helpers.
Definition: block.hpp:14
Binary reading stream, that is useful during binary deserialization.
Definition: read_stream.hpp:22
bool read(size_t size, uint8_t *out, ValidationState &state)
Read type T of 'size' bytes.
Non-owning contiguous array.
Definition: slice.hpp:22