+const StatementKey *BinaryParser::peek(unsigned level)
+{
+ if(level>sub_remaining.size())
+ throw nesting_error("bad level");
+ while(level<sub_remaining.size())
+ {
+ // Discard any substatements that haven't been parsed yet
+ for(unsigned i=sub_remaining.back(); i-->0; )
+ parse();
+ sub_remaining.pop_back();
+ cur_info = 0;
+ }
+
+ if(!sub_remaining.empty() && sub_remaining.back()==0)
+ {
+ // No more substatements on this level
+ cur_info = 0;
+ return 0;
+ }
+
+ if(cur_info)
+ return &cur_info->key;
+
+ int id = parse_int();
+ if(!in)
+ return 0;
+
+ cur_info = &get_item(dict, id);
+ return &cur_info->key;
+}
+
+bool BinaryParser::parse_and_load(unsigned level, Loader &ldr, const LoaderAction &act)
+{
+ if(!cur_info && !peek(level))
+ return false;
+
+ ArgumentStore args(*cur_info);
+ for(unsigned i=0; i<cur_info->key.signature.size(); ++i)
+ switch(cur_info->key.signature[i])
+ {
+ case IntType::signature:
+ args.set(i, parse_int());
+ break;
+ case FloatType::signature:
+ args.set(i, parse_float());
+ break;
+ case BoolType::signature:
+ args.set(i, parse_bool());
+ break;
+ case StringType::signature:
+ args.set(i, parse_string());
+ break;
+ case SymbolType::signature:
+ args.set(i, parse_symbol());
+ break;
+ }
+
+ if(!sub_remaining.empty())
+ --sub_remaining.back();
+ sub_remaining.push_back(parse_int());
+ cur_info = 0;
+
+ act.execute(ldr, args);
+
+ return true;
+}
+