/* $Id$
This file is part of libmspdatafile
-Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Copyright © 2007-2008 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
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()
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");
+ throw_at(TypeError("Keyword definition must have three arguments"), src);
const unsigned id=st.args[0].get<unsigned>();
const string &kw=st.args[1].get<const string &>();
const string &args=st.args[2].get<const string &>();
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_at(TypeError("String definition must have two arguments"), src);
const unsigned id=st.args[0].get<unsigned>();
- enums[id]=st.args[1].get<const std::string &>();
+ strings[id]=st.args[1].get<const string &>();
}
else
return st;
Dictionary::const_iterator i=dict.find(id);
if(i==dict.end())
- throw ParseError(format("%s: Unknown statement ID %d", src, id), src, 0);
+ throw_at(KeyError("Unknown statement ID", lexical_cast(id)), src);
const DictEntry &de=i->second;
Statement result;
break;
}
- const long long mask=1<<(bits-1);
+ const long long mask=1LL<<(bits-1);
result=(result^mask)-mask;
return result;
string BinaryParser::parse_string()
{
- unsigned len=parse_int();
- string result;
- result.reserve(len);
- for(unsigned i=0; i<len; ++i)
- result+=in.get();
- return result;
+ int len=parse_int();
+ if(len>=0)
+ {
+ string result;
+ result.reserve(len);
+ for(int i=0; i<len; ++i)
+ result+=in.get();
+ return result;
+ }
+ else
+ return lookup_string(-len);
}
string BinaryParser::parse_enum()
{
- unsigned id=parse_int();
- EnumMap::iterator i=enums.find(id);
- if(i==enums.end())
- throw KeyError("Unknown enum", lexical_cast(id));
+ return lookup_string(parse_int());
+}
+
+const string &BinaryParser::lookup_string(unsigned id) const
+{
+ StringMap::const_iterator i=strings.find(id);
+ if(i==strings.end())
+ throw_at(KeyError("Unknown string", lexical_cast(id)), src);
return i->second;
}