Avro C++
Writer.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_Writer_hh__
20 #define avro_Writer_hh__
21 
22 #include <array>
23 #include <boost/noncopyable.hpp>
24 
25 #include "Config.hh"
26 #include "Types.hh"
27 #include "Validator.hh"
28 #include "Zigzag.hh"
29 #include "buffer/Buffer.hh"
30 
31 namespace avro {
32 
34 
35 template<class ValidatorType>
36 class WriterImpl : private boost::noncopyable {
37 
38 public:
39  WriterImpl() = default;
40 
41  explicit WriterImpl(const ValidSchema &schema) : validator_(schema) {}
42 
43  void writeValue(const Null &) {
44  validator_.checkTypeExpected(AVRO_NULL);
45  }
46 
47  void writeValue(bool val) {
48  validator_.checkTypeExpected(AVRO_BOOL);
49  int8_t byte = (val != 0);
50  buffer_.writeTo(byte);
51  }
52 
53  void writeValue(int32_t val) {
54  validator_.checkTypeExpected(AVRO_INT);
55  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
56  std::array<uint8_t, 5> bytes;
57  size_t size = encodeInt32(val, bytes);
58  buffer_.writeTo(reinterpret_cast<const char *>(bytes.data()), size);
59  }
60 
61  void writeValue(int64_t val) {
62  validator_.checkTypeExpected(AVRO_LONG);
63  putLong(val);
64  }
65 
66  void writeValue(float val) {
67  validator_.checkTypeExpected(AVRO_FLOAT);
68  union {
69  float f;
70  int32_t i;
71  } v;
72 
73  v.f = val;
74  buffer_.writeTo(v.i);
75  }
76 
77  void writeValue(double val) {
78  validator_.checkTypeExpected(AVRO_DOUBLE);
79  union {
80  double d;
81  int64_t i;
82  } v;
83 
84  v.d = val;
85  buffer_.writeTo(v.i);
86  }
87 
88  void writeValue(const std::string &val) {
89  validator_.checkTypeExpected(AVRO_STRING);
90  putBytes(val.c_str(), val.size());
91  }
92 
93  void writeBytes(const void *val, size_t size) {
94  validator_.checkTypeExpected(AVRO_BYTES);
95  putBytes(val, size);
96  }
97 
98  template<size_t N>
99  void writeFixed(const uint8_t (&val)[N]) {
100  validator_.checkFixedSizeExpected(N);
101  buffer_.writeTo(reinterpret_cast<const char *>(val), N);
102  }
103 
104  template<size_t N>
105  void writeFixed(const std::array<uint8_t, N> &val) {
106  validator_.checkFixedSizeExpected(val.size());
107  buffer_.writeTo(reinterpret_cast<const char *>(val.data()), val.size());
108  }
109 
110  void writeRecord() {
111  validator_.checkTypeExpected(AVRO_RECORD);
112  validator_.checkTypeExpected(AVRO_LONG);
113  validator_.setCount(1);
114  }
115 
116  void writeRecordEnd() {
117  validator_.checkTypeExpected(AVRO_RECORD);
118  validator_.checkTypeExpected(AVRO_LONG);
119  validator_.setCount(0);
120  }
121 
122  void writeArrayBlock(int64_t size) {
123  validator_.checkTypeExpected(AVRO_ARRAY);
124  writeCount(size);
125  }
126 
127  void writeArrayEnd() {
128  writeArrayBlock(0);
129  }
130 
131  void writeMapBlock(int64_t size) {
132  validator_.checkTypeExpected(AVRO_MAP);
133  writeCount(size);
134  }
135 
136  void writeMapEnd() {
137  writeMapBlock(0);
138  }
139 
140  void writeUnion(int64_t choice) {
141  validator_.checkTypeExpected(AVRO_UNION);
142  writeCount(choice);
143  }
144 
145  void writeEnum(int64_t choice) {
146  validator_.checkTypeExpected(AVRO_ENUM);
147  writeCount(choice);
148  }
149 
150  InputBuffer buffer() const {
151  return buffer_;
152  }
153 
154 private:
155  void putLong(int64_t val) {
156  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
157  std::array<uint8_t, 10> bytes;
158  size_t size = encodeInt64(val, bytes);
159  buffer_.writeTo(reinterpret_cast<const char *>(bytes.data()), size);
160  }
161 
162  void putBytes(const void *val, size_t size) {
163  putLong(size);
164  buffer_.writeTo(reinterpret_cast<const char *>(val), size);
165  }
166 
167  void writeCount(int64_t count) {
168  validator_.checkTypeExpected(AVRO_LONG);
169  validator_.setCount(count);
170  putLong(count);
171  }
172 
173  ValidatorType validator_;
174  OutputBuffer buffer_;
175 };
176 
179 
180 } // namespace avro
181 
182 #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::WriterImpl
Class for writing avro data to a stream.
Definition: Writer.hh:36
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::AVRO_UNION
@ AVRO_UNION
Definition: Types.hh:46
avro::AVRO_MAP
@ AVRO_MAP
Definition: Types.hh:45