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):
29 dict[-1] = StatementKey("__kwd", "iss");
30 dict[-2] = StatementKey("__str", "is");
31 dict[-3] = StatementKey("__flt", "i");
34 Statement BinaryParser::parse()
40 const StatementKey &key = get_item(dict, id);
43 result.keyword = key.keyword;
46 for(unsigned j=0; j<key.signature.size(); ++j)
48 switch(key.signature[j])
50 case IntType::signature:
51 result.args.push_back(parse_int());
53 case FloatType::signature:
54 result.args.push_back(parse_float());
56 case StringType::signature:
57 result.args.push_back(parse_string());
59 case BoolType::signature:
60 result.args.push_back(parse_bool());
62 case SymbolType::signature:
63 result.args.push_back(parse_symbol());
68 unsigned nsub = parse_int();
69 for(unsigned j = 0; j<nsub; ++j)
70 result.sub.push_back(parse());
77 void BinaryParser::process_control_statement(const Statement &st)
79 if(st.keyword=="__kwd")
81 int id = st.args[0].get<int>();
83 throw bad_definition("__kwd");
85 const string &kw = st.args[1].get<const string &>();
86 const string &args = st.args[2].get<const string &>();
87 for(string::const_iterator i=args.begin(); i!=args.end(); ++i)
88 for(unsigned j=0; valid_signatures[j]!=*i; ++j)
89 if(!valid_signatures[j])
90 throw bad_definition("__kwd");
92 dict[id] = StatementKey(kw, args);
94 else if(st.keyword=="__str")
96 int id = st.args[0].get<int>();
98 throw bad_definition("__str");
100 strings[id] = st.args[1].get<const string &>();
102 else if(st.keyword=="__flt")
103 float_precision = st.args[0].get<unsigned>();
106 IntType::Store BinaryParser::parse_int()
108 IntType::Store result = 0;
115 result = (result<<7) | (c&0x7F);
122 const IntType::Store mask = 1LL<<(bits-1);
123 result = (result^mask)-mask;
128 FloatType::Store BinaryParser::parse_float()
131 for(unsigned i=0; i<float_precision; i+=8)
134 encoded = (encoded<<8) | (c&0xFF);
137 BinFloat bf = BinFloat::explode(encoded, float_precision);
139 if(numeric_limits<FloatType::Store>::is_iec559)
140 return bf.compose_iec559<FloatType::Store>();
143 /* Put the float together with arithmetic since we don't know its
145 FloatType::Store f = 0;
148 if(numeric_limits<FloatType::Store>::has_infinity)
149 f = numeric_limits<FloatType::Store>::infinity();
151 f = numeric_limits<FloatType::Store>::max();
155 for(unsigned i=0; i<64; ++i)
162 for(int i=0; i<bf.exponent; ++i)
164 for(int i=0; i>bf.exponent; --i)
173 BoolType::Store BinaryParser::parse_bool()
178 StringType::Store BinaryParser::parse_string()
180 int len = parse_int();
185 for(int i = 0; i<len; ++i)
190 return get_item(strings, -len);
193 SymbolType::Store BinaryParser::parse_symbol()
195 return get_item(strings, parse_int());
198 } // namespace DataFile