From d84673be1c2fe8bd32ddaa7877529855cad6daa0 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Tue, 22 Jul 2008 15:34:59 +0000 Subject: [PATCH] Add reverse name lookup to Collection Make the two-parameter global load function take a reference as the second parameter Use numeric IDs for short strings in binary mode --- source/binaryparser.cpp | 43 +++++++++++++++++++++++--------------- source/binaryparser.h | 5 +++-- source/binarywriter.cpp | 46 +++++++++++++++++++++++++---------------- source/binarywriter.h | 8 +++---- source/collection.h | 16 ++++++++++++++ source/loader.h | 2 +- 6 files changed, 78 insertions(+), 42 deletions(-) diff --git a/source/binaryparser.cpp b/source/binaryparser.cpp index b55c7af..214c35e 100644 --- a/source/binaryparser.cpp +++ b/source/binaryparser.cpp @@ -19,8 +19,8 @@ BinaryParser::BinaryParser(Input &i, const string &s): ParserMode(i, s), first(true) { - dict[1]=DictEntry("__st", "iss"); - dict[2]=DictEntry("__enum", "is"); + dict[1]=DictEntry("__kwd", "iss"); + dict[2]=DictEntry("__str", "is"); } Statement BinaryParser::parse() @@ -28,7 +28,7 @@ Statement BinaryParser::parse() while(1) { Statement st=parse_statement(); - if(st.keyword=="__st") + if(st.keyword=="__kwd") { if(st.args.size()!=3) throw TypeError(src+": Keyword definition must have three arguments"); @@ -38,13 +38,13 @@ Statement BinaryParser::parse() const string &args=st.args[2].get(); dict[id]=DictEntry(kw, args); } - else if(st.keyword=="__enum") + else if(st.keyword=="__str") { if(st.args.size()!=2) - throw TypeError(src+": Enum definition must have three arguments"); + throw TypeError(src+": String definition must have two arguments"); const unsigned id=st.args[0].get(); - enums[id]=st.args[1].get(); + strings[id]=st.args[1].get(); } else return st; @@ -117,7 +117,7 @@ long long BinaryParser::parse_int() break; } - const long long mask=1<<(bits-1); + const long long mask=1LL<<(bits-1); result=(result^mask)-mask; return result; @@ -149,20 +149,29 @@ bool BinaryParser::parse_bool() string BinaryParser::parse_string() { - unsigned len=parse_int(); - string result; - result.reserve(len); - for(unsigned i=0; i=0) + { + string result; + result.reserve(len); + for(int i=0; isecond; } diff --git a/source/binaryparser.h b/source/binaryparser.h index f1d51b2..26fa380 100644 --- a/source/binaryparser.h +++ b/source/binaryparser.h @@ -22,10 +22,10 @@ class BinaryParser: public ParserMode { private: typedef std::map Dictionary; - typedef std::map EnumMap; + typedef std::map StringMap; Dictionary dict; - EnumMap enums; + StringMap strings; bool first; public: @@ -38,6 +38,7 @@ private: std::string parse_string(); bool parse_bool(); std::string parse_enum(); + const std::string &lookup_string(unsigned) const; }; } // namespace DataFile diff --git a/source/binarywriter.cpp b/source/binarywriter.cpp index dd63d3d..98dd2a9 100644 --- a/source/binarywriter.cpp +++ b/source/binarywriter.cpp @@ -15,11 +15,11 @@ namespace DataFile { BinaryWriter::BinaryWriter(IO::Base &o): WriterMode(o), - next_st_id(3), - next_enum_id(1) + next_kwd_id(3), + next_str_id(1) { - dict[DictEntry("__st", "iss")]=1; - dict[DictEntry("__enum", "is")]=2; + dict[DictEntry("__kwd", "iss")]=1; + dict[DictEntry("__str", "is")]=2; } void BinaryWriter::write(const Statement &st) @@ -72,26 +72,30 @@ void BinaryWriter::collect_keywords(const Statement &st) if(!dict.count(de)) { Statement kst; - kst.keyword="__st"; - kst.args.push_back(next_st_id); + kst.keyword="__kwd"; + kst.args.push_back(next_kwd_id); kst.args.push_back(de.keyword); kst.args.push_back(de.args); write_(kst); - dict[de]=next_st_id++; + dict[de]=next_kwd_id++; } for(ValueArray::const_iterator i=st.args.begin(); i!=st.args.end(); ++i) - if(i->get_type()==ENUM && !enums.count(i->get_raw())) + { + const Type t=i->get_type(); + const string &r=i->get_raw(); + if((t==ENUM || (t==STRING && r.size()<32)) && !strings.count(r)) { - Statement est; - est.keyword="__enum"; - est.args.push_back(next_enum_id); - est.args.push_back(i->get_raw()); - write_(est); + Statement sst; + sst.keyword="__str"; + sst.args.push_back(next_str_id); + sst.args.push_back(r); + write_(sst); - enums[i->get_raw()]=next_enum_id++; + strings[r]=next_str_id++; } + } for(list::const_iterator i=st.sub.begin(); i!=st.sub.end(); ++i) collect_keywords(*i); @@ -112,8 +116,14 @@ void BinaryWriter::write_int(long long n) void BinaryWriter::write_string(const string &s) { - write_int(s.size()); - out.write(s.data(), s.size()); + StringMap::const_iterator i=strings.find(s); + if(i!=strings.end()) + write_int(-static_cast(i->second)); + else + { + write_int(s.size()); + out.write(s.data(), s.size()); + } } void BinaryWriter::write_float(float f) @@ -136,8 +146,8 @@ void BinaryWriter::write_float(float f) void BinaryWriter::write_enum(const string &e) { - EnumMap::const_iterator i=enums.find(e); - if(i==enums.end()) + StringMap::const_iterator i=strings.find(e); + if(i==strings.end()) throw InvalidParameterValue("Unknown enum"); write_int(i->second); } diff --git a/source/binarywriter.h b/source/binarywriter.h index 118f66b..c3a2b4c 100644 --- a/source/binarywriter.h +++ b/source/binarywriter.h @@ -22,12 +22,12 @@ class BinaryWriter: public WriterMode { private: typedef std::map Dictionary; - typedef std::map EnumMap; + typedef std::map StringMap; Dictionary dict; - unsigned next_st_id; - EnumMap enums; - unsigned next_enum_id; + unsigned next_kwd_id; + StringMap strings; + unsigned next_str_id; public: BinaryWriter(IO::Base &o); diff --git a/source/collection.h b/source/collection.h index 303697a..fa3a7de 100644 --- a/source/collection.h +++ b/source/collection.h @@ -284,6 +284,22 @@ public: */ bool contains(const std::string &n) const; + /** + Returns the name of an item in the collection. + */ + template + const std::string &get_name(T *d) const + { + typedef typename RemoveConst::Type NCT; + + for(ItemMap::const_iterator i=items.begin(); i!=items.end(); ++i) + if(Item *item=dynamic_cast *>(i->second)) + if(item->data==d) + return i->first; + + throw KeyError("Item not found in collection"); + } + protected: /** Adds a type that can be loaded from datafiles. diff --git a/source/loader.h b/source/loader.h index 5f4037c..5b39212 100644 --- a/source/loader.h +++ b/source/loader.h @@ -361,7 +361,7 @@ void load(T &obj, const std::string &fn) } template -void load(T &obj, const std::string &fn, U arg) +void load(T &obj, const std::string &fn, U &arg) { IO::File in(fn); IO::Buffered buf(in); -- 2.45.2