1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
#pragma once
#include <forstio/buffer.hpp>
#include "data.hpp"
namespace saw {
namespace trans {
template<uint64_t Len = 8u>
struct FixedLength {};
template<uint64_t Len = 8u>
struct VarLength {};
struct NewLine {};
struct CarriageReturnNewLine {};
}
template<typename T>
class transport;
template<uint64_t Len>
class transport<trans::FixedLength<Len>> final {
private:
public:
error_or<buffer_view> view_slice(buffer& buff) const {
typename native_data_type<schema::Primitive<schema::UnsignedInteger, Len>>::type val{};
buffer_view view{buff};
auto eov = stream_value<schema::Primitive<schema::UnsignedInteger, Len>>::decode(val, view);
if(eov.is_error()){
return std::move(eov.get_error());
}
if(view.read_composite_length() < val){
return make_error<err::buffer_exhausted>();
}
buff.read_advance(Len);
buffer_view data_view{buff, val, 0u};
return data_view;
}
error_or<uint64_t> wrap(buffer& out_buff, buffer& in_buff){
using trans_type = typename native_data_type<schema::Primitive<schema::UnsignedInteger, Len>>::type;
trans_type val{};
val = static_cast<trans_type>(in_buff.read_composite_length());
auto eov = stream_value<schema::Primitive<schema::UnsignedInteger, Len>>::encode(val, out_buff);
if(eov.is_error()){
auto& err = eov.get_error();
return std::move(err);
}
return Len;
}
error_or<array_buffer> chain_slice(chain_array_buffer& buff) const {
(void) buff;
return make_error<err::not_implemented>();
}
};
template<uint64_t Len>
class transport<trans::VarLength<Len>> final {
public:
error_or<buffer_view> view_slice(buffer& buff) const {
using var_max_t = typename native_data_type<schema::Primitive<schema::UnsignedInteger, Len>>::type;
var_max_t val{};
buffer_view view{buff};
std::array<uint8_t,Len> val_array;
for(uint64_t i = 0; i < Len && view.read_composite_length() > 0u; ++i){
uint8_t len_byte = view.read();
val |= static_cast<var_max_t>(len_byte & 0x7F) << i*7;
if( (len_byte & 0x80 ) == 0 ){
if( (i+1u) == Len ) {
return make_error<err::invalid_state>("Last VarLength Continue Bit is set.");
}
}
view.read_advance(1u);
}
if( val > view.read_composite_length() ){
return make_error<err::buffer_exhausted>();
}
return buffer_view{buff, val, 0u};
}
error_or<uint64_t> wrap(buffer& out_buff, buffer& in_buff){
using var_max_t = typename native_data_type<schema::Primitive<schema::UnsignedInteger, Len>>::type;
uint64_t len = in_buff.read_composite_length();
var_max_t val = len;
if(len != val){
return make_error<err::invalid_state>("Number too large");
}
buffer_view view{out_buff};
uint64_t i = 0u;
for(i = 0u; i < Len && view.write_composite_length() > 0u; ++i){
view.write() = (val & 0x7F);
if( ( val & ~0x7F ) == 0u ){
++i;
break;
}
view.write() |= 0x80;
val = (val >> (i * 7u));
view.write_advance(1u);
}
return i;
}
error_or<array_buffer> chain_slice(chain_array_buffer& buff) const {
(void) buff;
return make_error<err::not_implemented>();
}
};
}
|