2 #include <msp/core/maputils.h>
3 #include <msp/strings/format.h>
4 #include "binaryparser.h"
12 BinaryParser::BinaryParser(Input &i, const string &s):
16 dict[1] = DictEntry("__kwd", "iss");
17 dict[2] = DictEntry("__str", "is");
20 Statement BinaryParser::parse()
24 Statement st = parse_statement();
25 if(st.keyword=="__kwd")
28 throw_at(TypeError("Keyword definition must have three arguments"), src);
30 const unsigned id = st.args[0].get<unsigned>();
31 const string &kw = st.args[1].get<const string &>();
32 const string &args = st.args[2].get<const string &>();
33 dict[id] = DictEntry(kw, args);
35 else if(st.keyword=="__str")
38 throw_at(TypeError("String definition must have two arguments"), src);
40 const unsigned id = st.args[0].get<unsigned>();
41 strings[id] = st.args[1].get<const string &>();
48 Statement BinaryParser::parse_statement()
50 while(first && in.peek()=='\n')
54 unsigned id = parse_int();
58 const DictEntry &de = get_item(dict, id);
61 result.keyword = de.keyword;
64 for(unsigned j = 0; j<de.args.size(); ++j)
68 case IntType::signature:
69 result.args.push_back(parse_int());
71 case FloatType::signature:
72 result.args.push_back(parse_float());
74 case StringType::signature:
75 result.args.push_back(parse_string());
77 case BoolType::signature:
78 result.args.push_back(parse_bool());
80 case SymbolType::signature:
81 result.args.push_back(Symbol(parse_enum()));
86 unsigned nsub = parse_int();
87 for(unsigned j = 0; j<nsub; ++j)
88 result.sub.push_back(parse());
95 long long BinaryParser::parse_int()
104 result = (result<<7) | (c&0x7F);
111 const long long mask = 1LL<<(bits-1);
112 result = (result^mask)-mask;
117 float BinaryParser::parse_float()
122 char d[sizeof(float)];
125 #if BYTE_ORDER == LITTLE_ENDIAN
126 for(unsigned i = sizeof(float); i--;)
129 for(unsigned i = 0; i<sizeof(float); ++i)
136 bool BinaryParser::parse_bool()
141 string BinaryParser::parse_string()
143 int len = parse_int();
148 for(int i = 0; i<len; ++i)
153 return get_item(strings, -len);
156 string BinaryParser::parse_enum()
158 return get_item(strings, parse_int());
161 } // namespace DataFile