]> git.tdb.fi Git - libs/datafile.git/blobdiff - source/loader.cpp
More efficient way of loading binary files
[libs/datafile.git] / source / loader.cpp
index c2de4011232c93da747bfdead7df18af72c6087d..e1a0d4abd7bcd80adfa4040c2a9bdf43ffb43ee7 100644 (file)
@@ -71,6 +71,7 @@ public:
 
 Loader::Loader():
        cur_st(0),
+       direct(false),
        check_sub_loads(false)
 { }
 
@@ -84,9 +85,15 @@ void Loader::load(Parser &p)
 {
        while(p)
        {
-               Statement st = p.parse();
-               if(st.valid)
-                       load_statement(st);
+               if(p.peek(0))
+                       load_direct(p, 0);
+               else
+               {
+                       // Parse in raw mode so we can peek immediately after a mode change
+                       Statement st = p.parse(true);
+                       if(st.valid && !st.control)
+                               load_statement(st);
+               }
        }
        finish();
 }
@@ -98,6 +105,29 @@ void Loader::load(const Statement &st)
        finish();
 }
 
+void Loader::load_direct(Parser &p, unsigned l)
+{
+       SetForScope<Parser *> set_parser(cur_parser, &p);
+       SetForScope<unsigned> set_level(cur_level, l);
+
+       while(p)
+       {
+               const StatementKey *key = p.peek(l);
+               if(!key)
+                       break;
+
+               LoaderAction *act = find_action(*key);
+               if(act)
+               {
+                       SetFlag set_direct(direct);
+                       if(!p.parse_and_load(l, *this, *act))
+                               throw logic_error("direct load failed");
+               }
+               else
+                       load_statement(p.parse());
+       }
+}
+
 void Loader::load_statement(const Statement &st)
 {
        SetForScope<const Statement *> set_cst(cur_st, &st);
@@ -134,11 +164,18 @@ void Loader::load_statement(const Statement &st)
 
 void Loader::load_sub_with(Loader &ldr)
 {
-       if(!cur_st)
+       if(direct)
+       {
+               ldr.load_direct(*cur_parser, cur_level+1);
+               ldr.finish();
+       }
+       else if(cur_st)
+       {
+               ldr.load(*cur_st);
+               sub_loaded = true;
+       }
+       else
                throw logic_error("no current statement");
-
-       ldr.load(*cur_st);
-       sub_loaded = true;
 }
 
 void Loader::add(const string &kwd, LoaderAction *act)