X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fbinaryparser.cpp;h=25edd63a15060d96bb5bcc95775cc3241dc9ce36;hb=29fafaa2c570b0cf92f41eeb534cfb65a841a892;hp=73bb5cb664c32ba5ecda25ca9aa047c16e2610bd;hpb=6f94aaece716a31e75166e261cc47579288892b4;p=libs%2Fdatafile.git diff --git a/source/binaryparser.cpp b/source/binaryparser.cpp index 73bb5cb..25edd63 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,59 +24,33 @@ 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[-1] = StatementKey("__kwd", "iss"); + dict[-2] = StatementKey("__str", "is"); + dict[-3] = StatementKey("__flt", "i"); } Statement BinaryParser::parse() -{ - while(1) - { - Statement st = parse_statement(); - if(st.keyword=="__kwd") - { - if(st.args.size()!=3) - throw bad_definition("__kwd"); - - const unsigned id = st.args[0].get(); - const string &kw = st.args[1].get(); - const string &args = st.args[2].get(); - dict[id] = DictEntry(kw, args); - } - else if(st.keyword=="__str") - { - if(st.args.size()!=2) - throw bad_definition("__str"); - - const unsigned id = st.args[0].get(); - strings[id] = st.args[1].get(); - } - else - return st; - } -} - -Statement BinaryParser::parse_statement() { while(first && in.peek()=='\n') in.get(); first = false; - unsigned id = parse_int(); + int id = parse_int(); if(!in) return Statement(); - const DictEntry &de = get_item(dict, id); + const StatementKey &key = get_item(dict, id); Statement result; - result.keyword = de.keyword; + result.keyword = key.keyword; result.source = src; - for(unsigned j = 0; j(); + if(id<=0) + throw bad_definition("__kwd"); + + 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] = StatementKey(kw, args); + } + else if(st.keyword=="__str") + { + int id = st.args[0].get(); + if(id<=0) + throw bad_definition("__str"); + + strings[id] = st.args[1].get(); + } + else if(st.keyword=="__flt") + float_precision = st.args[0].get(); +} + +IntType::Store BinaryParser::parse_int() { - long long result = 0; + IntType::Store result = 0; unsigned bits = 0; while(in) @@ -119,37 +124,63 @@ long long BinaryParser::parse_int() break; } - const long long mask = 1LL<<(bits-1); + const IntType::Store mask = 1LL<<(bits-1); result = (result^mask)-mask; return result; } -float BinaryParser::parse_float() +FloatType::Store BinaryParser::parse_float() { - union + UInt64 encoded = 0; + for(unsigned i=0; i::is_iec559) + return bf.compose_iec559(); + else { - float f; - char d[sizeof(float)]; - }; - -#if BYTE_ORDER == LITTLE_ENDIAN - for(unsigned i = sizeof(float); i--;) - d[i] = in.get(); -#else - for(unsigned i = 0; i::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; + } } -bool BinaryParser::parse_bool() +BoolType::Store BinaryParser::parse_bool() { return in.get(); } -string BinaryParser::parse_string() +StringType::Store BinaryParser::parse_string() { int len = parse_int(); if(len>=0) @@ -164,7 +195,7 @@ string BinaryParser::parse_string() return get_item(strings, -len); } -Symbol BinaryParser::parse_symbol() +SymbolType::Store BinaryParser::parse_symbol() { return get_item(strings, parse_int()); }