]> git.tdb.fi Git - libs/datafile.git/blobdiff - source/binaryparser.cpp
Add facility for classes to specify what type they should be loaded as
[libs/datafile.git] / source / binaryparser.cpp
index e8487223cf24d1290e07ed302774b3fb7ee00d28..53131289a851b04270e377e8abb5b61b49832b5c 100644 (file)
@@ -1,4 +1,5 @@
 #include <sys/param.h>
+#include <msp/core/maputils.h>
 #include <msp/strings/format.h>
 #include "binaryparser.h"
 #include "input.h"
@@ -8,6 +9,17 @@ using namespace std;
 namespace Msp {
 namespace DataFile {
 
+class bad_definition: public runtime_error
+{
+public:
+       bad_definition(const std::string &w):
+               runtime_error(w)
+       { }
+
+       virtual ~bad_definition() throw() { }
+};
+
+
 BinaryParser::BinaryParser(Input &i, const string &s):
        ParserMode(i, s),
        first(true)
@@ -24,7 +36,7 @@ Statement BinaryParser::parse()
                if(st.keyword=="__kwd")
                {
                        if(st.args.size()!=3)
-                               throw_at(TypeError("Keyword definition must have three arguments"), src);
+                               throw bad_definition("__kwd");
 
                        const unsigned id = st.args[0].get<unsigned>();
                        const string &kw = st.args[1].get<const string &>();
@@ -34,7 +46,7 @@ Statement BinaryParser::parse()
                else if(st.keyword=="__str")
                {
                        if(st.args.size()!=2)
-                               throw_at(TypeError("String definition must have two arguments"), src);
+                               throw bad_definition("__str");
 
                        const unsigned id = st.args[0].get<unsigned>();
                        strings[id] = st.args[1].get<const string &>();
@@ -54,10 +66,7 @@ Statement BinaryParser::parse_statement()
        if(!in)
                return Statement();
 
-       Dictionary::const_iterator i = dict.find(id);
-       if(i==dict.end())
-               throw_at(KeyError("Unknown statement ID", lexical_cast(id)), src);
-       const DictEntry &de = i->second;
+       const DictEntry &de = get_item(dict, id);
 
        Statement result;
        result.keyword = de.keyword;
@@ -80,7 +89,7 @@ Statement BinaryParser::parse_statement()
                        result.args.push_back(parse_bool());
                        break;
                case SymbolType::signature:
-                       result.args.push_back(Symbol(parse_enum()));
+                       result.args.push_back(parse_symbol());
                        break;
                }
        }
@@ -94,9 +103,9 @@ Statement BinaryParser::parse_statement()
        return result;
 }
 
-long long BinaryParser::parse_int()
+IntType::Store BinaryParser::parse_int()
 {
-       long long result = 0;
+       IntType::Store result = 0;
        unsigned bits = 0;
 
        while(in)
@@ -110,13 +119,13 @@ 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
        {
@@ -135,12 +144,12 @@ float BinaryParser::parse_float()
        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)
@@ -152,20 +161,12 @@ string BinaryParser::parse_string()
                return result;
        }
        else
-               return lookup_string(-len);
-}
-
-string BinaryParser::parse_enum()
-{
-       return lookup_string(parse_int());
+               return get_item(strings, -len);
 }
 
-const string &BinaryParser::lookup_string(unsigned id) const
+SymbolType::Store BinaryParser::parse_symbol()
 {
-       StringMap::const_iterator i = strings.find(id);
-       if(i==strings.end())
-               throw_at(KeyError("Unknown string", lexical_cast(id)), src);
-       return i->second;
+       return get_item(strings, parse_int());
 }
 
 } // namespace DataFile