Commit 7f39d401 by Maarten L. Hekkelman

Optimised assigning data

parent af412c28
......@@ -244,7 +244,7 @@ class Datablock
bool isValid();
void validateLinks() const;
void setValidator(Validator *v);
void setValidator(const Validator *v);
// this one only looks up a Category, returns nullptr if it does not exist
const Category *get(std::string_view name) const;
......@@ -266,7 +266,7 @@ class Datablock
CategoryList mCategories; // LRU
mutable std::shared_mutex mLock;
std::string mName;
Validator *mValidator;
const Validator *mValidator;
Datablock *mNext;
};
......@@ -1816,7 +1816,7 @@ class Category
friend class Row;
friend class detail::ItemReference;
Category(Datablock &db, const std::string_view name, Validator *Validator);
Category(Datablock &db, const std::string_view name, const Validator *Validator);
Category(const Category &) = delete;
Category &operator=(const Category &) = delete;
~Category();
......@@ -2064,7 +2064,7 @@ class Category
Datablock &db() { return mDb; }
void setValidator(Validator *v);
void setValidator(const Validator *v);
iset fields() const;
iset mandatoryFields() const;
......@@ -2121,14 +2121,24 @@ class Category
size_t addColumn(std::string_view name);
struct Linked
{
Category *linked;
const ValidateLink *v;
};
void updateLinks();
Datablock &mDb;
std::string mName;
Validator *mValidator;
const Validator *mValidator;
const ValidateCategory *mCatValidator = nullptr;
std::vector<ItemColumn> mColumns;
ItemRow *mHead;
ItemRow *mTail;
class CatIndex *mIndex;
std::vector<Linked> mParentLinks, mChildLinks;
};
// --------------------------------------------------------------------
......@@ -2162,7 +2172,8 @@ class File
void loadDictionary(); // load the default dictionary, that is mmcifDdl in this case
void loadDictionary(const char *dict); // load one of the compiled in dictionaries
void loadDictionary(std::istream &is); // load dictionary from input stream
void setValidator(const Validator *v);
bool isValid();
void validateLinks() const;
......@@ -2226,10 +2237,8 @@ class File
void getTagOrder(std::vector<std::string> &tags) const;
private:
void setValidator(Validator *v);
Datablock *mHead;
Validator *mValidator;
const Validator *mValidator;
};
// --------------------------------------------------------------------
......
......@@ -28,8 +28,8 @@
#include "cif++/Cif++.hpp"
#include <stack>
#include <map>
#include <stack>
namespace cif
{
......@@ -39,7 +39,7 @@ namespace cif
class CifParserError : public std::runtime_error
{
public:
CifParserError(uint32_t lineNr, const std::string& message);
CifParserError(uint32_t lineNr, const std::string &message);
};
// --------------------------------------------------------------------
......@@ -48,7 +48,8 @@ extern const uint32_t kMaxLineLength;
extern const uint8_t kCharTraitsTable[128];
enum CharTraitsMask: uint8_t {
enum CharTraitsMask : uint8_t
{
kOrdinaryMask = 1 << 0,
kNonBlankMask = 1 << 1,
kTextLeadMask = 1 << 2,
......@@ -75,13 +76,13 @@ inline bool isTextLead(int ch)
return ch >= 0x20 and ch <= 0x7f and (kCharTraitsTable[ch - 0x20] & kTextLeadMask) != 0;
}
inline bool isAnyPrint(int ch)
inline bool isAnyPrint(int ch)
{
return ch == '\t' or
(ch >= 0x20 and ch <= 0x7f and (kCharTraitsTable[ch - 0x20] & kAnyPrintMask) != 0);
return ch == '\t' or
(ch >= 0x20 and ch <= 0x7f and (kCharTraitsTable[ch - 0x20] & kAnyPrintMask) != 0);
}
inline bool isUnquotedString(const char* s)
inline bool isUnquotedString(const char *s)
{
bool result = isOrdinary(*s++);
while (result and *s != 0)
......@@ -94,7 +95,7 @@ inline bool isUnquotedString(const char* s)
// --------------------------------------------------------------------
using DatablockIndex = std::map<std::string,std::size_t>;
using DatablockIndex = std::map<std::string, std::size_t>;
// --------------------------------------------------------------------
// sac Parser, analogous to SAX Parser (simple api for xml)
......@@ -102,15 +103,15 @@ using DatablockIndex = std::map<std::string,std::size_t>;
class SacParser
{
public:
SacParser(std::istream& is, bool init = true);
SacParser(std::istream &is, bool init = true);
virtual ~SacParser() {}
enum CIFToken
{
eCIFTokenUnknown,
eCIFTokenEOF,
eCIFTokenDATA,
eCIFTokenLOOP,
eCIFTokenGLOBAL,
......@@ -120,7 +121,7 @@ class SacParser
eCIFTokenValue,
};
static const char* kTokenName[];
static const char *kTokenName[];
enum CIFValueType
{
......@@ -133,40 +134,39 @@ class SacParser
eCIFValueUnknown
};
static const char* kValueName[];
static const char *kValueName[];
int getNextChar();
void retract();
void restart();
CIFToken getNextToken();
void match(CIFToken token);
bool parseSingleDatablock(const std::string& datablock);
bool parseSingleDatablock(const std::string &datablock);
DatablockIndex indexDatablocks();
bool parseSingleDatablock(const std::string& datablock, const DatablockIndex &index);
bool parseSingleDatablock(const std::string &datablock, const DatablockIndex &index);
void parseFile();
void parseGlobal();
void parseDataBlock();
virtual void parseSaveFrame();
void parseDictionary();
void error(const std::string& msg);
void error(const std::string &msg);
// production methods, these are pure virtual here
virtual void produceDatablock(const std::string& name) = 0;
virtual void produceCategory(const std::string& name) = 0;
virtual void produceDatablock(const std::string &name) = 0;
virtual void produceCategory(const std::string &name) = 0;
virtual void produceRow() = 0;
virtual void produceItem(const std::string& category, const std::string& item, const std::string& value) = 0;
virtual void produceItem(const std::string &category, const std::string &item, const std::string &value) = 0;
protected:
enum State
{
eStateStart,
......@@ -181,21 +181,21 @@ class SacParser
eStateTextField,
eStateFloat = 100,
eStateInt = 110,
// eStateNumericSuffix = 200,
// eStateNumericSuffix = 200,
eStateValue = 300
};
std::istream& mData;
std::istream &mData;
// Parser state
bool mValidate;
uint32_t mLineNr;
bool mBol;
int mState, mStart;
CIFToken mLookahead;
std::string mTokenValue;
CIFValueType mTokenType;
std::stack<int> mBuffer;
bool mValidate;
uint32_t mLineNr;
bool mBol;
int mState, mStart;
CIFToken mLookahead;
std::string mTokenValue;
CIFValueType mTokenType;
std::stack<int> mBuffer;
};
// --------------------------------------------------------------------
......@@ -203,18 +203,18 @@ class SacParser
class Parser : public SacParser
{
public:
Parser(std::istream& is, File& f, bool init = true);
Parser(std::istream &is, File &f, bool init = true);
virtual void produceDatablock(const std::string& name);
virtual void produceCategory(const std::string& name);
virtual void produceDatablock(const std::string &name);
virtual void produceCategory(const std::string &name);
virtual void produceRow();
virtual void produceItem(const std::string& category, const std::string& item, const std::string& value);
virtual void produceItem(const std::string &category, const std::string &item, const std::string &value);
protected:
File& mFile;
Datablock* mDataBlock;
Datablock::iterator mCat;
Row mRow;
File &mFile;
Datablock *mDataBlock;
Datablock::iterator mCat;
Row mRow;
};
// --------------------------------------------------------------------
......@@ -222,23 +222,21 @@ class Parser : public SacParser
class DictParser : public Parser
{
public:
DictParser(Validator& validator, std::istream& is);
DictParser(Validator &validator, std::istream &is);
~DictParser();
void loadDictionary();
private:
private:
virtual void parseSaveFrame();
bool collectItemTypes();
void linkItems();
Validator& mValidator;
File mFile;
struct DictParserDataImpl* mImpl;
bool mCollectedItemTypes = false;
Validator &mValidator;
File mFile;
struct DictParserDataImpl *mImpl;
bool mCollectedItemTypes = false;
};
}
} // namespace cif
......@@ -38,6 +38,7 @@ namespace cif
{
struct ValidateCategory;
class ValidatorFactory;
// --------------------------------------------------------------------
......@@ -154,9 +155,8 @@ struct ValidateLink
class Validator
{
public:
friend class DictParser;
Validator();
Validator(std::string_view name, std::istream &is);
~Validator();
Validator(const Validator &rhs) = delete;
......@@ -165,6 +165,9 @@ class Validator
Validator(Validator &&rhs);
Validator &operator=(Validator &&rhs);
friend class DictParser;
friend class ValidatorFactory;
void addTypeValidator(ValidateType &&v);
const ValidateType *getValidatorForType(std::string_view typeCode) const;
......@@ -175,7 +178,7 @@ class Validator
std::vector<const ValidateLink *> getLinksForParent(std::string_view category) const;
std::vector<const ValidateLink *> getLinksForChild(std::string_view category) const;
void reportError(const std::string &msg, bool fatal);
void reportError(const std::string &msg, bool fatal) const;
std::string dictName() const { return mName; }
void dictName(const std::string &name) { mName = name; }
......@@ -184,6 +187,7 @@ class Validator
void dictVersion(const std::string &version) { mVersion = version; }
private:
// name is fully qualified here:
ValidateItem *getValidatorForItem(std::string_view name) const;
......@@ -196,4 +200,27 @@ class Validator
std::vector<ValidateLink> mLinkValidators;
};
// --------------------------------------------------------------------
class ValidatorFactory
{
public:
static ValidatorFactory &instance()
{
return sInstance;
}
const Validator &operator[](std::string_view dictionary);
private:
static ValidatorFactory sInstance;
ValidatorFactory();
std::mutex mMutex;
std::list<Validator> mValidators;
};
} // namespace cif
......@@ -392,8 +392,13 @@ auto Datablock::emplace(std::string_view name) -> std::tuple<iterator, bool>
}
if (isNew)
{
mCategories.emplace(begin(), *this, std::string(name), mValidator);
for (auto &cat : mCategories)
cat.updateLinks();
}
return std::make_tuple(begin(), isNew);
}
......@@ -406,17 +411,28 @@ Category &Datablock::operator[](std::string_view name)
Category *Datablock::get(std::string_view name)
{
return &operator[](name);
std::shared_lock lock(mLock);
for (auto &cat : mCategories)
{
if (iequals(cat.name(), name))
return &cat;
}
return nullptr;
}
const Category *Datablock::get(std::string_view name) const
{
std::shared_lock lock(mLock);
auto i = find_if(begin(), end(), [name](const Category &cat) -> bool
{ return iequals(cat.name(), name); });
for (auto &cat : mCategories)
{
if (iequals(cat.name(), name))
return &cat;
}
return i == end() ? nullptr : &*i;
return nullptr;
}
bool Datablock::isValid()
......@@ -440,7 +456,7 @@ void Datablock::validateLinks() const
cat.validateLinks();
}
void Datablock::setValidator(Validator *v)
void Datablock::setValidator(const Validator *v)
{
std::shared_lock lock(mLock);
......@@ -1322,7 +1338,7 @@ RowSet &RowSet::orderBy(std::initializer_list<std::string> items)
// --------------------------------------------------------------------
Category::Category(Datablock &db, const std::string_view name, Validator *Validator)
Category::Category(Datablock &db, const std::string_view name, const Validator *Validator)
: mDb(db)
, mName(name)
, mValidator(Validator)
......@@ -1357,7 +1373,7 @@ Category::~Category()
delete mIndex;
}
void Category::setValidator(Validator *v)
void Category::setValidator(const Validator *v)
{
mValidator = v;
......@@ -1382,6 +1398,33 @@ void Category::setValidator(Validator *v)
}
else
mCatValidator = nullptr;
updateLinks();
}
void Category::updateLinks()
{
mChildLinks.clear();
mParentLinks.clear();
if (mValidator != nullptr)
{
for (auto link : mValidator->getLinksForParent(mName))
{
auto childCat = mDb.get(link->mChildCategory);
if (childCat == nullptr)
continue;
mChildLinks.push_back({ childCat, link });
}
for (auto link : mValidator->getLinksForChild(mName))
{
auto parentCat = mDb.get(link->mParentCategory);
if (parentCat == nullptr)
continue;
mParentLinks.push_back({ parentCat, link });
}
}
}
bool Category::hasColumn(std::string_view name) const
......@@ -1827,12 +1870,8 @@ auto Category::erase(iterator pos) -> iterator
if (mValidator != nullptr)
{
for (auto &link : mValidator->getLinksForParent(mName))
for (auto &&[childCat, link] : mChildLinks)
{
auto childCat = mDb.get(link->mChildCategory);
if (childCat == nullptr)
continue;
Condition cond;
for (size_t ix = 0; ix < link->mParentKeys.size(); ++ix)
......@@ -1970,12 +2009,8 @@ bool Category::isOrphan(Row r)
return false;
bool isOrphan = true;
for (auto &link : mValidator->getLinksForChild(mName))
for (auto &&[parentCat, link] : mParentLinks)
{
auto parentCat = mDb.get(link->mParentCategory);
if (parentCat == nullptr)
continue;
Condition cond;
for (size_t ix = 0; ix < link->mChildKeys.size(); ++ix)
{
......@@ -2006,12 +2041,8 @@ bool Category::hasChildren(Row r) const
bool result = false;
for (auto &link : mValidator->getLinksForParent(mName))
for (auto &&[childCat, link] : mChildLinks)
{
auto childCat = mDb.get(link->mChildCategory);
if (childCat == nullptr)
continue;
Condition cond;
for (size_t ix = 0; ix < link->mParentKeys.size(); ++ix)
......@@ -2037,12 +2068,8 @@ bool Category::hasParents(Row r) const
bool result = false;
for (auto &link : mValidator->getLinksForChild(mName))
for (auto &&[parentCat, link] : mParentLinks)
{
auto parentCat = mDb.get(link->mParentCategory);
if (parentCat == nullptr)
continue;
Condition cond;
for (size_t ix = 0; ix < link->mChildKeys.size(); ++ix)
......@@ -2251,23 +2278,17 @@ bool Category::isValid()
void Category::validateLinks() const
{
auto &validator = getValidator();
for (auto linkValidator : validator.getLinksForChild(mName))
for (auto &&[parentCat, link] : mParentLinks)
{
auto parent = mDb.get(linkValidator->mParentCategory);
if (parent == nullptr)
continue;
size_t missing = 0;
for (auto r : *this)
if (not hasParent(r, *parent, *linkValidator))
if (not hasParent(r, *parentCat, *link))
++missing;
if (missing)
{
std::cerr << "Links for " << linkValidator->mLinkGroupLabel << " are incomplete" << std::endl
<< " There are " << missing << " items in " << mName << " that don't have matching parent items in " << parent->mName << std::endl;
std::cerr << "Links for " << link->mLinkGroupLabel << " are incomplete" << std::endl
<< " There are " << missing << " items in " << mName << " that don't have matching parent items in " << parentCat->mName << std::endl;
}
}
}
......@@ -2708,17 +2729,10 @@ void Category::update_value(RowSet &&rows, const std::string &tag, const std::st
row.assign(colIx, value, true);
// see if we need to update any child categories that depend on this value
auto &validator = getValidator();
auto &db = mDb;
for (auto parent : rows)
{
for (auto linked : validator.getLinksForParent(mName))
for (auto &&[childCat, linked] : mChildLinks)
{
auto childCat = db.get(linked->mChildCategory);
if (childCat == nullptr)
continue;
if (std::find(linked->mParentKeys.begin(), linked->mParentKeys.end(), tag) == linked->mParentKeys.end())
continue;
......@@ -2875,18 +2889,8 @@ void Row::assign(const std::vector<Item> &values)
// auto iv = col.mValidator;
if (mCascade)
{
auto &validator = cat->getValidator();
auto &db = cat->db();
for (auto linked : validator.getLinksForParent(cat->mName))
for (auto &&[childCat, linked] : cat->mChildLinks)
{
auto childCat = db.get(linked->mChildCategory);
if (childCat == nullptr)
continue;
// if (find(linked->mParentKeys.begin(), linked->mParentKeys.end(), iv->mTag) == linked->mParentKeys.end())
// continue;
Condition cond;
std::string childTag;
......@@ -3027,15 +3031,8 @@ void Row::assign(size_t column, const std::string &value, bool skipUpdateLinked)
auto iv = col.mValidator;
if (not skipUpdateLinked and iv != nullptr and mCascade)
{
auto &validator = cat->getValidator();
auto &db = cat->db();
for (auto linked : validator.getLinksForParent(cat->mName))
for (auto &&[childCat, linked] : cat->mChildLinks)
{
auto childCat = db.get(linked->mChildCategory);
if (childCat == nullptr)
continue;
if (find(linked->mParentKeys.begin(), linked->mParentKeys.end(), iv->mTag) == linked->mParentKeys.end())
continue;
......@@ -3214,18 +3211,13 @@ void Row::swap(size_t cix, ItemRow *a, ItemRow *b)
auto parentColName = cat->getColumnName(cix);
// see if we need to update any child categories that depend on these values
auto &validator = cat->getValidator();
auto parentCatValidator = cat->getCatValidator();
for (auto &link : validator.getLinksForParent(cat->mName))
for (auto &&[childCat, link] : cat->mChildLinks)
{
if (find(link->mParentKeys.begin(), link->mParentKeys.end(), parentColName) == link->mParentKeys.end())
continue;
auto childCat = cat->db().get(link->mChildCategory);
if (childCat == nullptr or childCat->empty())
continue;
auto childCatValidator = childCat->getCatValidator();
if (childCatValidator == nullptr)
continue;
......@@ -3437,7 +3429,6 @@ File::File(File &&rhs)
File::~File()
{
delete mHead;
delete mValidator;
}
void File::append(Datablock *e)
......@@ -3514,7 +3505,7 @@ void File::save(const std::filesystem::path &p)
void File::load(std::istream &is)
{
Validator *saved = mValidator;
auto saved = mValidator;
setValidator(nullptr);
Parser p(is, *this);
......@@ -3529,7 +3520,7 @@ void File::load(std::istream &is)
void File::load(std::istream &is, const std::string &datablock)
{
Validator *saved = mValidator;
auto saved = mValidator;
setValidator(nullptr);
Parser p(is, *this);
......@@ -3618,67 +3609,10 @@ void File::loadDictionary()
void File::loadDictionary(const char *dict)
{
fs::path dict_name(dict);
auto data = loadResource(dict);
if (not data and dict_name.extension().string() != ".dic")
data = loadResource(dict_name.parent_path() / (dict_name.filename().string() + ".dic"));
if (data)
loadDictionary(*data);
else
{
// might be a compressed dictionary on disk
fs::path p = dict;
if (p.extension() == ".dic")
p = p.parent_path() / (p.filename().string() + ".gz");
else
p = p.parent_path() / (p.filename().string() + ".dic.gz");
#if defined(CACHE_DIR) and defined(DATA_DIR)
if (not fs::exists(p))
{
for (const char *dir : {CACHE_DIR, DATA_DIR})
{
auto p2 = fs::path(dir) / p;
if (fs::exists(p2))
{
swap(p, p2);
break;
}
}
}
#endif
if (fs::exists(p))
{
std::ifstream file(p, std::ios::binary);
if (not file.is_open())
throw std::runtime_error("Could not open dictionary (" + p.string() + ")");
io::filtering_stream<io::input> in;
in.push(io::gzip_decompressor());
in.push(file);
loadDictionary(in);
}
else
throw std::runtime_error("Dictionary not found or defined (" + dict_name.string() + ")");
}
}
void File::loadDictionary(std::istream &is)
{
std::unique_ptr<Validator> v(new Validator());
DictParser p(*v, is);
p.loadDictionary();
setValidator(v.release());
setValidator(&ValidatorFactory::instance()[dict]);
}
void File::setValidator(Validator *v)
void File::setValidator(const Validator *v)
{
mValidator = v;
......
......@@ -126,8 +126,9 @@ const uint8_t kCharToLowerMap[256] =
bool iequals(std::string_view a, std::string_view b)
{
bool result = a.length() == b.length();
for (auto ai = a.begin(), bi = b.begin(); result and ai != a.end() and bi != b.end(); ++ai, ++bi)
result = tolower(*ai) == tolower(*bi);
for (auto ai = a.begin(), bi = b.begin(); result and ai != a.end(); ++ai, ++bi)
result = kCharToLowerMap[uint8_t(*ai)] == kCharToLowerMap[uint8_t(*bi)];
// result = tolower(*ai) == tolower(*bi);
return result;
}
......
......@@ -24,13 +24,20 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <fstream>
#include <filesystem>
#include <boost/algorithm/string.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include "cif++/Cif++.hpp"
#include "cif++/CifParser.hpp"
#include "cif++/CifValidator.hpp"
namespace ba = boost::algorithm;
namespace fs = std::filesystem;
namespace io = boost::iostreams;
extern int VERBOSE;
......@@ -219,8 +226,11 @@ const ValidateItem *ValidateCategory::getValidatorForItem(std::string_view tag)
// --------------------------------------------------------------------
Validator::Validator()
Validator::Validator(std::string_view name, std::istream &is)
: mName(name)
{
DictParser p(*this, is);
p.loadDictionary();
}
Validator::~Validator()
......@@ -340,7 +350,7 @@ std::vector<const ValidateLink *> Validator::getLinksForChild(std::string_view c
return result;
}
void Validator::reportError(const std::string &msg, bool fatal)
void Validator::reportError(const std::string &msg, bool fatal) const
{
if (mStrict or fatal)
throw ValidationError(msg);
......@@ -348,4 +358,78 @@ void Validator::reportError(const std::string &msg, bool fatal)
std::cerr << msg << std::endl;
}
// --------------------------------------------------------------------
ValidatorFactory ValidatorFactory::sInstance;
ValidatorFactory::ValidatorFactory()
{
}
const Validator &ValidatorFactory::operator[](std::string_view dictionary)
{
std::lock_guard lock(mMutex);
for (auto &validator : mValidators)
{
if (iequals(validator.mName, dictionary))
return validator;
}
// not found, add it
fs::path dict_name(dictionary);
auto data = loadResource(dictionary);
if (not data and dict_name.extension().string() != ".dic")
data = loadResource(dict_name.parent_path() / (dict_name.filename().string() + ".dic"));
if (data)
mValidators.emplace_back(dictionary, *data);
else
{
// might be a compressed dictionary on disk
fs::path p = dictionary;
if (p.extension() == ".dic")
p = p.parent_path() / (p.filename().string() + ".gz");
else
p = p.parent_path() / (p.filename().string() + ".dic.gz");
#if defined(CACHE_DIR) and defined(DATA_DIR)
if (not fs::exists(p))
{
for (const char *dir : {CACHE_DIR, DATA_DIR})
{
auto p2 = fs::path(dir) / p;
if (fs::exists(p2))
{
swap(p, p2);
break;
}
}
}
#endif
if (fs::exists(p))
{
std::ifstream file(p, std::ios::binary);
if (not file.is_open())
throw std::runtime_error("Could not open dictionary (" + p.string() + ")");
io::filtering_stream<io::input> in;
in.push(io::gzip_decompressor());
in.push(file);
mValidators.emplace_back(dictionary, in);
}
else
throw std::runtime_error("Dictionary not found or defined (" + dict_name.string() + ")");
}
assert(iequals(mValidators.back().mName, dictionary));
return mValidators.back();
}
} // namespace cif
......@@ -18,7 +18,6 @@ int main(int argc, char* argv[])
desc.add_options()
("input,i", po::value<std::string>(), "Input file")
("help,h", "Display help message")
("version", "Print version")
("verbose,v", "Verbose output")
("debug,d", po::value<int>(), "Debug level (for even more verbose output)");
......@@ -29,12 +28,6 @@ int main(int argc, char* argv[])
po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
po::notify(vm);
if (vm.count("version"))
{
std::cout << argv[0] << " version " PACKAGE_VERSION << std::endl;
exit(0);
}
if (vm.count("help") or vm.count("input") == 0)
{
std::cerr << desc << std::endl;
......
......@@ -33,6 +33,7 @@
// #include "cif++/DistanceMap.hpp"
#include "cif++/Cif++.hpp"
#include "cif++/BondMap.hpp"
#include "cif++/CifValidator.hpp"
std::filesystem::path gTestDir = std::filesystem::current_path(); // filled in first test
......@@ -259,8 +260,10 @@ save__cat_2.desc
std::istream is_dict(&buffer);
cif::Validator validator("test", is_dict);
cif::File f;
f.loadDictionary(is_dict);
f.setValidator(&validator);
// --------------------------------------------------------------------
......@@ -387,8 +390,10 @@ save__cat_1.c
std::istream is_dict(&buffer);
cif::Validator validator("test", is_dict);
cif::File f;
f.loadDictionary(is_dict);
f.setValidator(&validator);
// --------------------------------------------------------------------
......@@ -535,8 +540,10 @@ save__cat_2.desc
std::istream is_dict(&buffer);
cif::Validator validator("test", is_dict);
cif::File f;
f.loadDictionary(is_dict);
f.setValidator(&validator);
// --------------------------------------------------------------------
......@@ -741,8 +748,10 @@ save__cat_2.parent_id3
std::istream is_dict(&buffer);
cif::Validator validator("test", is_dict);
cif::File f;
f.loadDictionary(is_dict);
f.setValidator(&validator);
// --------------------------------------------------------------------
......@@ -963,8 +972,10 @@ cat_2 3 cat_2:cat_1:3
std::istream is_dict(&buffer);
cif::Validator validator("test", is_dict);
cif::File f;
f.loadDictionary(is_dict);
f.setValidator(&validator);
// --------------------------------------------------------------------
......@@ -1389,9 +1400,10 @@ cat_2 1 '_cat_2.num' '_cat_3.num' cat_3
} buffer(const_cast<char*>(dict), sizeof(dict) - 1);
std::istream is_dict(&buffer);
cif::Validator validator("test", is_dict);
cif::File f;
f.loadDictionary(is_dict);
f.setValidator(&validator);
// --------------------------------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment