blob: 432f0afc41d7d8b93e13012087030baaf0456a9e [file] [log] [blame]
/*
* 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
*
* https://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 avro_Validating_hh__
#define avro_Validating_hh__
#include <boost/noncopyable.hpp>
#include <vector>
#include <stdint.h>
#include "Config.hh"
#include "Types.hh"
#include "ValidSchema.hh"
namespace avro {
class AVRO_DECL NullValidator : private boost::noncopyable
{
public:
explicit NullValidator(const ValidSchema &schema) {}
NullValidator() {}
void setCount(int64_t val) {}
bool typeIsExpected(Type type) const {
return true;
}
Type nextTypeExpected() const {
return AVRO_UNKNOWN;
}
int nextSizeExpected() const {
return 0;
}
bool getCurrentRecordName(std::string &name) const {
return true;
}
bool getNextFieldName(std::string &name) const {
return true;
}
void checkTypeExpected(Type type) { }
void checkFixedSizeExpected(int size) { }
};
/// This class is used by both the ValidatingSerializer and ValidationParser
/// objects. It advances the parse tree (containing logic how to advance
/// through the various compound types, for example a record must advance
/// through all leaf nodes but a union only skips to one), and reports which
/// type is next.
class AVRO_DECL Validator : private boost::noncopyable
{
public:
explicit Validator(const ValidSchema &schema);
void setCount(int64_t val);
bool typeIsExpected(Type type) const {
return (expectedTypesFlag_ & typeToFlag(type)) != 0;
}
Type nextTypeExpected() const {
return nextType_;
}
int nextSizeExpected() const;
bool getCurrentRecordName(std::string &name) const;
bool getNextFieldName(std::string &name) const;
void checkTypeExpected(Type type) {
if(! typeIsExpected(type)) {
throw Exception(
boost::format("Type %1% does not match schema %2%")
% type % nextType_
);
}
advance();
}
void checkFixedSizeExpected(int size) {
if( nextSizeExpected() != size) {
throw Exception(
boost::format("Wrong size for fixed, got %1%, expected %2%")
% size % nextSizeExpected()
);
}
checkTypeExpected(AVRO_FIXED);
}
private:
typedef uint32_t flag_t;
flag_t typeToFlag(Type type) const {
flag_t flag = (1L << type);
return flag;
}
void setupOperation(const NodePtr &node);
void setWaitingForCount();
void advance();
void doAdvance();
void enumAdvance();
bool countingSetup();
void countingAdvance();
void unionAdvance();
void fixedAdvance();
void setupFlag(Type type);
const ValidSchema schema_;
Type nextType_;
flag_t expectedTypesFlag_;
bool compoundStarted_;
bool waitingForCount_;
int64_t count_;
struct CompoundType {
explicit CompoundType(const NodePtr &n) :
node(n), pos(0)
{}
NodePtr node; ///< save the node
size_t pos; ///< track the leaf position to visit
};
std::vector<CompoundType> compoundStack_;
std::vector<size_t> counters_;
};
} // namespace avro
#endif