/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef rmf_avro_Reader_hh__ #define rmf_avro_Reader_hh__ #include #include #include "Config.hh" #include "Zigzag.hh" #include "Types.hh" #include "Validator.hh" #include "buffer/BufferReader.hh" namespace rmf_avro { /// /// Parses from an avro encoding to the requested type. Assumes the next item /// in the avro binary data is the expected type. /// template class ReaderImpl : private boost::noncopyable { public: explicit ReaderImpl(const InputBuffer &buffer) : reader_(buffer) {} ReaderImpl(const ValidSchema &schema, const InputBuffer &buffer) : validator_(schema), reader_(buffer) {} void readValue(Null &) { validator_.checkTypeExpected(AVRO_NULL); } void readValue(bool &val) { validator_.checkTypeExpected(AVRO_BOOL); uint8_t ival = 0; reader_.read(ival); val = (ival != 0); } void readValue(int32_t &val) { validator_.checkTypeExpected(AVRO_INT); uint32_t encoded = static_cast(readVarInt()); val = decodeZigzag32(encoded); } void readValue(int64_t &val) { validator_.checkTypeExpected(AVRO_LONG); uint64_t encoded = readVarInt(); val = decodeZigzag64(encoded); } void readValue(float &val) { validator_.checkTypeExpected(AVRO_FLOAT); union { float f; uint32_t i; } v; reader_.read(v.i); val = v.f; } void readValue(double &val) { validator_.checkTypeExpected(AVRO_DOUBLE); union { double d; uint64_t i; } v; reader_.read(v.i); val = v.d; } void readValue(std::string &val) { validator_.checkTypeExpected(AVRO_STRING); size_t size = static_cast(readSize()); reader_.read(val, size); } void readBytes(std::vector &val) { validator_.checkTypeExpected(AVRO_BYTES); size_t size = static_cast(readSize()); val.resize(size); reader_.read(reinterpret_cast(&val[0]), size); } void readFixed(uint8_t *val, size_t size) { validator_.checkFixedSizeExpected(size); reader_.read(reinterpret_cast(val), size); } template void readFixed(uint8_t (&val)[N]) { this->readFixed(val, N); } template void readFixed(boost::array &val) { this->readFixed(val.c_array(), N); } void readRecord() { validator_.checkTypeExpected(AVRO_RECORD); validator_.checkTypeExpected(AVRO_LONG); validator_.setCount(1); } void readRecordEnd() { validator_.checkTypeExpected(AVRO_RECORD); validator_.checkTypeExpected(AVRO_LONG); validator_.setCount(0); } int64_t readArrayBlockSize() { validator_.checkTypeExpected(AVRO_ARRAY); return readCount(); } int64_t readUnion() { validator_.checkTypeExpected(AVRO_UNION); return readCount(); } int64_t readEnum() { validator_.checkTypeExpected(AVRO_ENUM); return readCount(); } int64_t readMapBlockSize() { validator_.checkTypeExpected(AVRO_MAP); return readCount(); } Type nextType() const { return validator_.nextTypeExpected(); } bool currentRecordName(std::string &name) const { return validator_.getCurrentRecordName(name); } bool nextFieldName(std::string &name) const { return validator_.getNextFieldName(name); } private: uint64_t readVarInt() { uint64_t encoded = 0; uint8_t val = 0; int shift = 0; do { reader_.read(val); uint64_t newbits = static_cast(val & 0x7f) << shift; encoded |= newbits; shift += 7; } while (val & 0x80); return encoded; } int64_t readSize() { uint64_t encoded = readVarInt(); int64_t size = decodeZigzag64(encoded); return size; } int64_t readCount() { validator_.checkTypeExpected(AVRO_LONG); int64_t count = readSize(); validator_.setCount(count); return count; } ValidatorType validator_; BufferReader reader_; }; typedef ReaderImpl Reader; typedef ReaderImpl ValidatingReader; } // namespace rmf_avro #endif