Avro C++

Reader.hh
1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * https://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 #ifndef avro_Reader_hh__
20 #define avro_Reader_hh__
21
22 #include <array>
23 #include <boost/noncopyable.hpp>
24 #include <cstdint>
25 #include <vector>
26
27 #include "Config.hh"
28 #include "Types.hh"
29 #include "Validator.hh"
30 #include "Zigzag.hh"
31 #include "buffer/BufferReader.hh"
32
33 namespace avro {
34
39
40 template<class ValidatorType>
41 class ReaderImpl : private boost::noncopyable {
42
43 public:
44 explicit ReaderImpl(const InputBuffer &buffer) : reader_(buffer) {}
45
46 ReaderImpl(const ValidSchema &schema, const InputBuffer &buffer) : validator_(schema),
47 reader_(buffer) {}
48
49 void readValue(Null &) {
50 validator_.checkTypeExpected(AVRO_NULL);
51 }
52
53 void readValue(bool &val) {
54 validator_.checkTypeExpected(AVRO_BOOL);
55 uint8_t intVal = 0;
56 reader_.read(intVal);
57 val = (intVal != 0);
58 }
59
60 void readValue(int32_t &val) {
61 validator_.checkTypeExpected(AVRO_INT);
62 auto encoded = static_cast<uint32_t>(readVarInt());
63 val = decodeZigzag32(encoded);
64 }
65
66 void readValue(int64_t &val) {
67 validator_.checkTypeExpected(AVRO_LONG);
68 uint64_t encoded = readVarInt();
69 val = decodeZigzag64(encoded);
70 }
71
72 void readValue(float &val) {
73 validator_.checkTypeExpected(AVRO_FLOAT);
74 union {
75 float f;
76 uint32_t i;
77 } v;
78 reader_.read(v.i);
79 val = v.f;
80 }
81
82 void readValue(double &val) {
83 validator_.checkTypeExpected(AVRO_DOUBLE);
84 union {
85 double d;
86 uint64_t i;
87 } v = { 0 };
88 reader_.read(v.i);
89 val = v.d;
90 }
91
92 void readValue(std::string &val) {
93 validator_.checkTypeExpected(AVRO_STRING);
94 auto size = static_cast<size_t>(readSize());
95 reader_.read(val, size);
96 }
97
98 void readBytes(std::vector<uint8_t> &val) {
99 validator_.checkTypeExpected(AVRO_BYTES);
100 auto size = static_cast<size_t>(readSize());
101 val.resize(size);
102 reader_.read(reinterpret_cast<char *>(val.data()), size);
103 }
104
105 void readFixed(uint8_t *val, size_t size) {
106 validator_.checkFixedSizeExpected(size);
107 reader_.read(reinterpret_cast<char *>(val), size);
108 }
109
110 template<size_t N>
111 void readFixed(uint8_t (&val)[N]) {
112 this->readFixed(val, N);
113 }
114
115 template<size_t N>
116 void readFixed(std::array<uint8_t, N> &val) {
117 this->readFixed(val.data(), N);
118 }
119
120 void readRecord() {
121 validator_.checkTypeExpected(AVRO_RECORD);
122 validator_.checkTypeExpected(AVRO_LONG);
123 validator_.setCount(1);
124 }
125
126 void readRecordEnd() {
127 validator_.checkTypeExpected(AVRO_RECORD);
128 validator_.checkTypeExpected(AVRO_LONG);
129 validator_.setCount(0);
130 }
131
132 int64_t readArrayBlockSize() {
133 validator_.checkTypeExpected(AVRO_ARRAY);
134 return readCount();
135 }
136
137 int64_t readUnion() {
138 validator_.checkTypeExpected(AVRO_UNION);
139 return readCount();
140 }
141
142 int64_t readEnum() {
143 validator_.checkTypeExpected(AVRO_ENUM);
144 return readCount();
145 }
146
147 int64_t readMapBlockSize() {
148 validator_.checkTypeExpected(AVRO_MAP);
149 return readCount();
150 }
151
152 Type nextType() const {
153 return validator_.nextTypeExpected();
154 }
155
156 bool currentRecordName(std::string &name) const {
157 return validator_.getCurrentRecordName(name);
158 }
159
160 bool nextFieldName(std::string &name) const {
161 return validator_.getNextFieldName(name);
162 }
163
164 private:
165 uint64_t readVarInt() {
166 uint64_t encoded = 0;
167 uint8_t val = 0;
168 int shift = 0;
169 do {
170 reader_.read(val);
171 uint64_t newBits = static_cast<uint64_t>(val & 0x7f) << shift;
172 encoded |= newBits;
173 shift += 7;
174 } while (val & 0x80);
175
176 return encoded;
177 }
178
179 int64_t readSize() {
180 uint64_t encoded = readVarInt();
181 int64_t size = decodeZigzag64(encoded);
182 return size;
183 }
184
185 int64_t readCount() {
186 validator_.checkTypeExpected(AVRO_LONG);
187 int64_t count = readSize();
188 validator_.setCount(count);
189 return count;
190 }
191
192 ValidatorType validator_;
193 BufferReader reader_;
194 };
195
196 using Reader = ReaderImpl<NullValidator>;
197 using ValidatingReader = ReaderImpl<Validator>;
198
199 } // namespace avro
200
201 #endif
avro::AVRO_NULL
@ AVRO_NULL
Definition: Types.hh:40
avro::AVRO_LONG
@ AVRO_LONG
Definition: Types.hh:36
avro::AVRO_ENUM
@ AVRO_ENUM
Definition: Types.hh:43
avro::AVRO_FLOAT
@ AVRO_FLOAT
Definition: Types.hh:37
Zigzag.hh
avro::AVRO_BOOL
@ AVRO_BOOL
Definition: Types.hh:39
avro::AVRO_STRING
@ AVRO_STRING
Definition: Types.hh:33
avro::AVRO_BYTES
@ AVRO_BYTES
Definition: Types.hh:34
avro::AVRO_INT
@ AVRO_INT
Definition: Types.hh:35
avro
A bunch of templates and specializations for encoding and decoding specific types.
Definition: AvroParse.hh:30
avro::ValidSchema
A ValidSchema is basically a non-mutable Schema that has passed some minimum of sanity checks.
Definition: ValidSchema.hh:40
avro::AVRO_ARRAY
@ AVRO_ARRAY
Definition: Types.hh:44
avro::AVRO_DOUBLE
@ AVRO_DOUBLE
Definition: Types.hh:38
avro::Null
define a type to represent Avro Null in template functions
Definition: Types.hh:101
avro::AVRO_RECORD
@ AVRO_RECORD
Definition: Types.hh:42
avro::ReaderImpl
Parses from an avro encoding to the requested type.
Definition: Reader.hh:41
avro::Type
Type
The "type" for the schema.
Definition: Types.hh:31
avro::AVRO_UNION
@ AVRO_UNION
Definition: Types.hh:46
avro::AVRO_MAP
@ AVRO_MAP
Definition: Types.hh:45