Avro C++
Validator.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_Validating_hh__
00020 #define avro_Validating_hh__
00021 
00022 #include <boost/noncopyable.hpp>
00023 #include <vector>
00024 #include <stdint.h>
00025 
00026 #include "Config.hh"
00027 #include "Types.hh"
00028 #include "ValidSchema.hh"
00029 
00030 namespace avro {
00031 
00032 class AVRO_DECL NullValidator : private boost::noncopyable
00033 {
00034   public:
00035 
00036     explicit NullValidator(const ValidSchema &schema) {}
00037     NullValidator() {}
00038 
00039     void setCount(int64_t val) {}
00040 
00041     bool typeIsExpected(Type type) const {
00042         return true;
00043     }
00044 
00045     Type nextTypeExpected() const {
00046         return AVRO_UNKNOWN;
00047     }
00048 
00049     int nextSizeExpected() const {
00050         return 0;
00051     }
00052 
00053     bool getCurrentRecordName(std::string &name) const {
00054         return true;
00055     }
00056 
00057     bool getNextFieldName(std::string &name) const {
00058         return true;
00059     }
00060 
00061     void checkTypeExpected(Type type) { }
00062     void checkFixedSizeExpected(int size) { }
00063 
00064 
00065 };
00066 
00072 
00073 class AVRO_DECL Validator : private boost::noncopyable
00074 {
00075   public:
00076 
00077     explicit Validator(const ValidSchema &schema);
00078 
00079     void setCount(int64_t val);
00080 
00081     bool typeIsExpected(Type type) const {
00082         return (expectedTypesFlag_ & typeToFlag(type)) != 0;
00083     }
00084 
00085     Type nextTypeExpected() const {
00086         return nextType_;
00087     }
00088 
00089     int nextSizeExpected() const;
00090 
00091     bool getCurrentRecordName(std::string &name) const;
00092     bool getNextFieldName(std::string &name) const;
00093 
00094     void checkTypeExpected(Type type) {
00095         if(! typeIsExpected(type)) {
00096             throw Exception(
00097                 boost::format("Type %1% does not match schema %2%") 
00098                     % type % nextType_
00099             );
00100         }
00101         advance();
00102     }
00103 
00104     void checkFixedSizeExpected(int size) { 
00105         if( nextSizeExpected() != size) {
00106             throw Exception(
00107                 boost::format("Wrong size for fixed, got %1%, expected %2%") 
00108                     % size % nextSizeExpected()
00109             );
00110         }
00111         checkTypeExpected(AVRO_FIXED);
00112     }
00113 
00114   private:
00115 
00116     typedef uint32_t flag_t;
00117 
00118     flag_t typeToFlag(Type type) const {
00119         flag_t flag = (1L << type);
00120         return flag;
00121     }
00122 
00123     void setupOperation(const NodePtr &node);
00124 
00125     void setWaitingForCount();
00126 
00127     void advance();
00128     void doAdvance();
00129 
00130     void enumAdvance();
00131     bool countingSetup();
00132     void countingAdvance();
00133     void unionAdvance();
00134     void fixedAdvance();
00135 
00136     void setupFlag(Type type);
00137 
00138     const ValidSchema schema_;
00139 
00140     Type nextType_; 
00141     flag_t expectedTypesFlag_;
00142     bool compoundStarted_;
00143     bool waitingForCount_;
00144     int64_t count_;
00145 
00146     struct CompoundType {
00147         explicit CompoundType(const NodePtr &n) :
00148             node(n), pos(0)
00149         {}
00150         NodePtr node;  
00151         size_t  pos;   
00152     };
00153 
00154     std::vector<CompoundType> compoundStack_;
00155     std::vector<size_t> counters_;
00156 
00157 };
00158 
00159 } // namespace avro
00160 
00161 #endif