Avro C++
Reader.hh
00001 /*
00002  * Licensed to the Apache Software Foundation (ASF) under one
00003  * or more contributor license agreements.  See the NOTICE file
00004  * distributed with this work for additional information
00005  * regarding copyright ownership.  The ASF licenses this file
00006  * to you under the Apache License, Version 2.0 (the
00007  * "License"); you may not use this file except in compliance
00008  * with the License.  You may obtain a copy of the License at
00009  *
00010  *     http://www.apache.org/licenses/LICENSE-2.0
00011  *
00012  * Unless required by applicable law or agreed to in writing, software
00013  * distributed under the License is distributed on an "AS IS" BASIS,
00014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015  * See the License for the specific language governing permissions and
00016  * limitations under the License.
00017  */
00018 
00019 #ifndef avro_Reader_hh__
00020 #define avro_Reader_hh__
00021 
00022 #include <stdint.h>
00023 #include <vector>
00024 #include <boost/noncopyable.hpp>
00025 
00026 #include "Config.hh"
00027 #include "Zigzag.hh"
00028 #include "Types.hh"
00029 #include "Validator.hh"
00030 #include "buffer/BufferReader.hh"
00031 
00032 namespace avro {
00033 
00038 
00039 template<class ValidatorType>
00040 class ReaderImpl : private boost::noncopyable
00041 {
00042 
00043   public:
00044 
00045     explicit ReaderImpl(const InputBuffer &buffer) :
00046         reader_(buffer)
00047     {}
00048 
00049     ReaderImpl(const ValidSchema &schema, const InputBuffer &buffer) :
00050         validator_(schema),
00051         reader_(buffer)
00052     {}
00053 
00054     void readValue(Null &) {
00055         validator_.checkTypeExpected(AVRO_NULL);
00056     }
00057 
00058     void readValue(bool &val) {
00059         validator_.checkTypeExpected(AVRO_BOOL);
00060         uint8_t ival = 0;
00061         reader_.read(ival);
00062         val = (ival != 0);
00063     }
00064 
00065     void readValue(int32_t &val) {
00066         validator_.checkTypeExpected(AVRO_INT);
00067         uint32_t encoded = static_cast<uint32_t>(readVarInt());
00068         val = decodeZigzag32(encoded);
00069     }
00070 
00071     void readValue(int64_t &val) {
00072         validator_.checkTypeExpected(AVRO_LONG);
00073         uint64_t encoded = readVarInt();
00074         val = decodeZigzag64(encoded);
00075     }
00076 
00077     void readValue(float &val) {
00078         validator_.checkTypeExpected(AVRO_FLOAT);
00079         union { 
00080             float f;
00081             uint32_t i;
00082         } v;
00083         reader_.read(v.i);
00084         val = v.f;
00085     }
00086 
00087     void readValue(double &val) {
00088         validator_.checkTypeExpected(AVRO_DOUBLE);
00089         union { 
00090             double d;
00091             uint64_t i;
00092         } v;
00093         reader_.read(v.i);
00094         val = v.d;
00095     }
00096 
00097     void readValue(std::string &val) {
00098         validator_.checkTypeExpected(AVRO_STRING);
00099         size_t size = static_cast<size_t>(readSize());
00100         reader_.read(val, size);
00101     }
00102 
00103     void readBytes(std::vector<uint8_t> &val) {
00104         validator_.checkTypeExpected(AVRO_BYTES);
00105         size_t size = static_cast<size_t>(readSize());
00106         val.resize(size);
00107         reader_.read(reinterpret_cast<char *>(&val[0]), size);
00108     }
00109 
00110     void readFixed(uint8_t *val, size_t size) {
00111         validator_.checkFixedSizeExpected(size);
00112         reader_.read(reinterpret_cast<char *>(val), size);
00113     }
00114 
00115     template <size_t N>
00116     void readFixed(uint8_t (&val)[N]) {
00117         this->readFixed(val, N);
00118     }
00119   
00120     template <size_t N>
00121     void readFixed(boost::array<uint8_t, N> &val) {
00122         this->readFixed(val.c_array(), N);
00123     }
00124   
00125     void readRecord() { 
00126         validator_.checkTypeExpected(AVRO_RECORD);
00127         validator_.checkTypeExpected(AVRO_LONG);
00128         validator_.setCount(1);
00129     }
00130 
00131     void readRecordEnd() { 
00132         validator_.checkTypeExpected(AVRO_RECORD);
00133         validator_.checkTypeExpected(AVRO_LONG);
00134         validator_.setCount(0);
00135     }
00136 
00137     int64_t readArrayBlockSize() {
00138         validator_.checkTypeExpected(AVRO_ARRAY);
00139         return readCount();
00140     }
00141 
00142     int64_t readUnion() { 
00143         validator_.checkTypeExpected(AVRO_UNION);
00144         return readCount();
00145     }
00146 
00147     int64_t readEnum() {
00148         validator_.checkTypeExpected(AVRO_ENUM);
00149         return readCount();
00150     }
00151 
00152     int64_t readMapBlockSize() {
00153         validator_.checkTypeExpected(AVRO_MAP);
00154         return readCount();
00155     }
00156 
00157     Type nextType() const {
00158         return validator_.nextTypeExpected();
00159     }
00160 
00161     bool currentRecordName(std::string &name) const {
00162         return validator_.getCurrentRecordName(name);
00163     }
00164 
00165     bool nextFieldName(std::string &name) const {
00166         return validator_.getNextFieldName(name);
00167     }
00168 
00169   private:
00170 
00171     uint64_t readVarInt() {
00172         uint64_t encoded = 0;
00173         uint8_t val = 0;
00174         int shift = 0;
00175         do {
00176             reader_.read(val);
00177             uint64_t newbits = static_cast<uint64_t>(val & 0x7f) << shift;
00178             encoded |= newbits;
00179             shift += 7;
00180         } while (val & 0x80);
00181 
00182         return encoded;
00183     }
00184 
00185     int64_t readSize() {
00186         uint64_t encoded = readVarInt();
00187         int64_t size = decodeZigzag64(encoded);
00188         return size;
00189     }
00190 
00191     int64_t readCount() {
00192         validator_.checkTypeExpected(AVRO_LONG);
00193         int64_t count = readSize();
00194         validator_.setCount(count);
00195         return count;
00196     }
00197 
00198     ValidatorType validator_;
00199     BufferReader  reader_;
00200 
00201 };
00202 
00203 typedef ReaderImpl<NullValidator> Reader;
00204 typedef ReaderImpl<Validator> ValidatingReader;
00205 
00206 } // namespace avro
00207 
00208 #endif