3 #include <msp/core/maputils.h>
4 #include <msp/strings/format.h>
5 #include "binaryparser.h"
14 class bad_definition: public runtime_error
17 bad_definition(const std::string &w):
21 virtual ~bad_definition() throw() { }
25 BinaryParser::BinaryParser(Input &i, const string &s):
30 dict[-1] = DictEntry("__kwd", "iss");
31 dict[-2] = DictEntry("__str", "is");
32 dict[-3] = DictEntry("__flt", "i");
35 Statement BinaryParser::parse(bool raw)
39 Statement st = parse_statement(raw);
40 if(st.keyword=="__kwd")
42 int id = st.args[0].get<int>();
44 throw bad_definition("__kwd");
46 const string &kw = st.args[1].get<const string &>();
47 const string &args = st.args[2].get<const string &>();
48 for(string::const_iterator i=args.begin(); i!=args.end(); ++i)
49 for(unsigned j=0; valid_signatures[j]!=*i; ++j)
50 if(!valid_signatures[j])
51 throw bad_definition("__kwd");
53 dict[id] = DictEntry(kw, args);
55 else if(st.keyword=="__str")
57 int id = st.args[0].get<int>();
59 throw bad_definition("__str");
61 strings[id] = st.args[1].get<const string &>();
63 else if(st.keyword=="__flt")
64 float_precision = st.args[0].get<unsigned>();
73 Statement BinaryParser::parse_statement(bool raw)
75 while(first && in.peek()=='\n')
83 const DictEntry &de = get_item(dict, id);
86 result.keyword = de.keyword;
89 for(unsigned j = 0; j<de.args.size(); ++j)
93 case IntType::signature:
94 result.args.push_back(parse_int());
96 case FloatType::signature:
97 result.args.push_back(parse_float());
99 case StringType::signature:
100 result.args.push_back(parse_string());
102 case BoolType::signature:
103 result.args.push_back(parse_bool());
105 case SymbolType::signature:
106 result.args.push_back(parse_symbol());
111 unsigned nsub = parse_int();
112 for(unsigned j = 0; j<nsub; ++j)
113 result.sub.push_back(parse(raw));
120 IntType::Store BinaryParser::parse_int()
122 IntType::Store result = 0;
129 result = (result<<7) | (c&0x7F);
136 const IntType::Store mask = 1LL<<(bits-1);
137 result = (result^mask)-mask;
142 FloatType::Store BinaryParser::parse_float()
145 for(unsigned i=0; i<float_precision; i+=8)
148 encoded = (encoded<<8) | (c&0xFF);
151 BinFloat bf = BinFloat::explode(encoded, float_precision);
153 if(numeric_limits<FloatType::Store>::is_iec559)
154 return bf.compose_iec559<FloatType::Store>();
157 /* Put the float together with arithmetic since we don't know its
159 FloatType::Store f = 0;
162 if(numeric_limits<FloatType::Store>::has_infinity)
163 f = numeric_limits<FloatType::Store>::infinity();
165 f = numeric_limits<FloatType::Store>::max();
169 for(unsigned i=0; i<64; ++i)
176 for(int i=0; i<bf.exponent; ++i)
178 for(int i=0; i>bf.exponent; --i)
187 BoolType::Store BinaryParser::parse_bool()
192 StringType::Store BinaryParser::parse_string()
194 int len = parse_int();
199 for(int i = 0; i<len; ++i)
204 return get_item(strings, -len);
207 SymbolType::Store BinaryParser::parse_symbol()
209 return get_item(strings, parse_int());
212 } // namespace DataFile