3 This file is part of libmspdatafile
4 Copyright © 2007-2008, 2010 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
8 #include "binarywriter.h"
16 BinaryWriter::BinaryWriter(IO::Base &o):
21 dict[DictEntry("__kwd", "iss")] = 1;
22 dict[DictEntry("__str", "is")] = 2;
25 void BinaryWriter::write(const Statement &st)
31 void BinaryWriter::write_(const Statement &st)
33 Dictionary::iterator i = dict.find(DictEntry(st.keyword, st.get_signature()));
35 throw InvalidParameterValue("Unknown statement");
38 for(Statement::Arguments::const_iterator j = st.args.begin(); j!=st.args.end(); ++j)
39 switch(j->get_signature())
41 case IntType::signature: write_int (j->get<IntType::Store>()); break;
42 case StringType::signature: write_string(j->get<StringType::Store>()); break;
43 case BoolType::signature: write_int (j->get<BoolType::Store>()); break;
44 case FloatType::signature: write_float (j->get<FloatType::Store>()); break;
45 case SymbolType::signature: write_enum (j->get<SymbolType::Store>()); break;
48 write_int(st.sub.size());
49 for(list<Statement>::const_iterator j = st.sub.begin(); j!=st.sub.end(); ++j)
53 void BinaryWriter::collect_keywords(const Statement &st)
55 DictEntry de(st.keyword, st.get_signature());
60 kst.keyword = "__kwd";
61 kst.args.push_back(next_kwd_id);
62 kst.args.push_back(de.keyword);
63 kst.args.push_back(de.args);
66 dict[de] = next_kwd_id++;
69 for(ValueArray::const_iterator i = st.args.begin(); i!=st.args.end(); ++i)
71 char sig = i->get_signature();
73 if(sig==SymbolType::signature)
74 str = i->get<Symbol>().name;
75 else if(sig==StringType::signature)
77 str = i->get<string>();
84 if(strings.count(str))
88 sst.keyword = "__str";
89 sst.args.push_back(next_str_id);
90 sst.args.push_back(str);
93 strings[str] = next_str_id++;
96 for(list<Statement>::const_iterator i = st.sub.begin(); i!=st.sub.end(); ++i)
100 void BinaryWriter::write_int(long long n)
102 unsigned i = sizeof(long long)-1;
105 for(; (i>0 && (n>>(i*7-1))==0); --i) ;
107 for(; (i>0 && (n>>(i*7-1))==-1); --i) ;
110 out.put((n>>(i*7) & 0x7F) | (i?0x80:0));
113 void BinaryWriter::write_string(const string &s)
115 StringMap::const_iterator i = strings.find(s);
117 write_int(-static_cast<int>(i->second));
121 out.write(s.data(), s.size());
125 void BinaryWriter::write_float(float f)
130 char d[sizeof(float)];
134 #if BYTE_ORDER == LITTLE_ENDIAN
135 for(unsigned i = sizeof(float); i--;)
138 for(unsigned i = 0; i<sizeof(float); ++i)
143 void BinaryWriter::write_enum(const string &e)
145 StringMap::const_iterator i = strings.find(e);
147 throw InvalidParameterValue("Unknown enum");
148 write_int(i->second);
151 } // namespace DataFile