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] = StatementKey("__kwd", "iss");
31 dict[-2] = StatementKey("__str", "is");
32 dict[-3] = StatementKey("__flt", "i");
35 Statement BinaryParser::parse()
37 while(first && in.peek()=='\n')
45 const StatementKey &key = get_item(dict, id);
48 result.keyword = key.keyword;
51 for(unsigned j=0; j<key.signature.size(); ++j)
53 switch(key.signature[j])
55 case IntType::signature:
56 result.args.push_back(parse_int());
58 case FloatType::signature:
59 result.args.push_back(parse_float());
61 case StringType::signature:
62 result.args.push_back(parse_string());
64 case BoolType::signature:
65 result.args.push_back(parse_bool());
67 case SymbolType::signature:
68 result.args.push_back(parse_symbol());
73 unsigned nsub = parse_int();
74 for(unsigned j = 0; j<nsub; ++j)
75 result.sub.push_back(parse());
82 void BinaryParser::process_control_statement(const Statement &st)
84 if(st.keyword=="__kwd")
86 int id = st.args[0].get<int>();
88 throw bad_definition("__kwd");
90 const string &kw = st.args[1].get<const string &>();
91 const string &args = st.args[2].get<const string &>();
92 for(string::const_iterator i=args.begin(); i!=args.end(); ++i)
93 for(unsigned j=0; valid_signatures[j]!=*i; ++j)
94 if(!valid_signatures[j])
95 throw bad_definition("__kwd");
97 dict[id] = StatementKey(kw, args);
99 else if(st.keyword=="__str")
101 int id = st.args[0].get<int>();
103 throw bad_definition("__str");
105 strings[id] = st.args[1].get<const string &>();
107 else if(st.keyword=="__flt")
108 float_precision = st.args[0].get<unsigned>();
111 IntType::Store BinaryParser::parse_int()
113 IntType::Store result = 0;
120 result = (result<<7) | (c&0x7F);
127 const IntType::Store mask = 1LL<<(bits-1);
128 result = (result^mask)-mask;
133 FloatType::Store BinaryParser::parse_float()
136 for(unsigned i=0; i<float_precision; i+=8)
139 encoded = (encoded<<8) | (c&0xFF);
142 BinFloat bf = BinFloat::explode(encoded, float_precision);
144 if(numeric_limits<FloatType::Store>::is_iec559)
145 return bf.compose_iec559<FloatType::Store>();
148 /* Put the float together with arithmetic since we don't know its
150 FloatType::Store f = 0;
153 if(numeric_limits<FloatType::Store>::has_infinity)
154 f = numeric_limits<FloatType::Store>::infinity();
156 f = numeric_limits<FloatType::Store>::max();
160 for(unsigned i=0; i<64; ++i)
167 for(int i=0; i<bf.exponent; ++i)
169 for(int i=0; i>bf.exponent; --i)
178 BoolType::Store BinaryParser::parse_bool()
183 StringType::Store BinaryParser::parse_string()
185 int len = parse_int();
190 for(int i = 0; i<len; ++i)
195 return get_item(strings, -len);
198 SymbolType::Store BinaryParser::parse_symbol()
200 return get_item(strings, parse_int());
203 } // namespace DataFile