2 #include <msp/strings/formatter.h>
3 #include "binaryparser.h"
11 BinaryParser::BinaryParser(Input &i, const string &s):
15 dict[1] = DictEntry("__kwd", "iss");
16 dict[2] = DictEntry("__str", "is");
19 Statement BinaryParser::parse()
23 Statement st = parse_statement();
24 if(st.keyword=="__kwd")
27 throw_at(TypeError("Keyword definition must have three arguments"), src);
29 const unsigned id = st.args[0].get<unsigned>();
30 const string &kw = st.args[1].get<const string &>();
31 const string &args = st.args[2].get<const string &>();
32 dict[id] = DictEntry(kw, args);
34 else if(st.keyword=="__str")
37 throw_at(TypeError("String definition must have two arguments"), src);
39 const unsigned id = st.args[0].get<unsigned>();
40 strings[id] = st.args[1].get<const string &>();
47 Statement BinaryParser::parse_statement()
49 while(first && in.peek()=='\n')
53 unsigned id = parse_int();
57 Dictionary::const_iterator i = dict.find(id);
59 throw_at(KeyError("Unknown statement ID", lexical_cast(id)), src);
60 const DictEntry &de = i->second;
63 result.keyword = de.keyword;
66 for(unsigned j = 0; j<de.args.size(); ++j)
70 case IntType::signature:
71 result.args.push_back(parse_int());
73 case FloatType::signature:
74 result.args.push_back(parse_float());
76 case StringType::signature:
77 result.args.push_back(parse_string());
79 case BoolType::signature:
80 result.args.push_back(parse_bool());
82 case SymbolType::signature:
83 result.args.push_back(Symbol(parse_enum()));
88 unsigned nsub = parse_int();
89 for(unsigned j = 0; j<nsub; ++j)
90 result.sub.push_back(parse());
97 long long BinaryParser::parse_int()
106 result = (result<<7) | (c&0x7F);
113 const long long mask = 1LL<<(bits-1);
114 result = (result^mask)-mask;
119 float BinaryParser::parse_float()
124 char d[sizeof(float)];
127 #if BYTE_ORDER == LITTLE_ENDIAN
128 for(unsigned i = sizeof(float); i--;)
131 for(unsigned i = 0; i<sizeof(float); ++i)
138 bool BinaryParser::parse_bool()
143 string BinaryParser::parse_string()
145 int len = parse_int();
150 for(int i = 0; i<len; ++i)
155 return lookup_string(-len);
158 string BinaryParser::parse_enum()
160 return lookup_string(parse_int());
163 const string &BinaryParser::lookup_string(unsigned id) const
165 StringMap::const_iterator i = strings.find(id);
167 throw_at(KeyError("Unknown string", lexical_cast(id)), src);
171 } // namespace DataFile