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;
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 
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