X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fbinaryparser.cpp;h=796a592d3e84d05a70e2e8316abdcccbe543f3bf;hb=835fcd2f79e8848fa0d92be667c0e02952e23436;hp=81a86ea9a3b66b7ae9c9a6ba0a3dfff4f134ff17;hpb=e0af585ed57bdb5b1ea4f4a415fda13b5d99d2dc;p=libs%2Fdatafile.git diff --git a/source/binaryparser.cpp b/source/binaryparser.cpp index 81a86ea..796a592 100644 --- a/source/binaryparser.cpp +++ b/source/binaryparser.cpp @@ -1,7 +1,9 @@ +#include #include #include #include #include "binaryparser.h" +#include "binfloat.h" #include "input.h" using namespace std; @@ -22,41 +24,53 @@ public: BinaryParser::BinaryParser(Input &i, const string &s): ParserMode(i, s), - first(true) + first(true), + float_precision(32) { dict[-1] = DictEntry("__kwd", "iss"); dict[-2] = DictEntry("__str", "is"); + dict[-3] = DictEntry("__flt", "i"); } -Statement BinaryParser::parse() +Statement BinaryParser::parse(bool raw) { while(1) { - Statement st = parse_statement(); + Statement st = parse_statement(raw); if(st.keyword=="__kwd") { - if(st.args.size()!=3) + int id = st.args[0].get(); + if(id<=0) throw bad_definition("__kwd"); - const int id = st.args[0].get(); const string &kw = st.args[1].get(); const string &args = st.args[2].get(); + for(string::const_iterator i=args.begin(); i!=args.end(); ++i) + for(unsigned j=0; valid_signatures[j]!=*i; ++j) + if(!valid_signatures[j]) + throw bad_definition("__kwd"); + dict[id] = DictEntry(kw, args); } else if(st.keyword=="__str") { - if(st.args.size()!=2) + int id = st.args[0].get(); + if(id<=0) throw bad_definition("__str"); - const unsigned id = st.args[0].get(); strings[id] = st.args[1].get(); } + else if(st.keyword=="__flt") + float_precision = st.args[0].get(); else return st; + + if(raw) + return st; } } -Statement BinaryParser::parse_statement() +Statement BinaryParser::parse_statement(bool raw) { while(first && in.peek()=='\n') in.get(); @@ -96,7 +110,7 @@ Statement BinaryParser::parse_statement() unsigned nsub = parse_int(); for(unsigned j = 0; j::is_iec559) + return bf.compose_iec559(); + else + { + /* Put the float together with arithmetic since we don't know its + internal layout */ + FloatType::Store f = 0; + if(bf.infinity) + { + if(numeric_limits::has_infinity) + f = numeric_limits::infinity(); + else + f = numeric_limits::max(); + } + else + { + for(unsigned i=0; i<64; ++i) + { + f /= 2; + if(bf.mantissa&1) + f += 1; + bf.mantissa >>= 1; + } + for(int i=0; ibf.exponent; --i) + f /= 2; + } + if(bf.sign) + f = -f; + return f; + } } BoolType::Store BinaryParser::parse_bool()