3 This file is part of libmspdatafile
4 Copyright © 2006 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
8 #include "binarywriter.h"
16 BinaryWriter::BinaryWriter(ostream &o):
21 dict[DictEntry("__st", "iss")]=1;
22 dict[DictEntry("__enum", "is")]=1;
25 void BinaryWriter::write(const Statement &st)
31 void BinaryWriter::write_(const Statement &st)
33 Dictionary::iterator i=dict.find(create_entry(st));
35 throw InvalidParameterValue("Unknown statement");
38 for(ValueArray::const_iterator j=st.args.begin(); j!=st.args.end(); ++j)
41 case INTEGER: write_int (j->get<long long>()); break;
42 case STRING: write_string(j->get<const string &>()); break;
43 case BOOLEAN: write_int (j->get<bool>()); break;
44 case FLOAT: write_float (j->get<float>()); break;
45 case ENUM: write_enum (j->get_raw()); break;
48 write_int(st.sub.size());
49 for(list<Statement>::const_iterator j=st.sub.begin(); j!=st.sub.end(); ++j)
53 DictEntry BinaryWriter::create_entry(const Statement &st)
55 static const char types[]="ifsbe";
58 for(ValueArray::const_iterator i=st.args.begin(); i!=st.args.end(); ++i)
61 throw InvalidParameterValue("Invalid argument type");
62 args+=types[i->get_type()];
65 return DictEntry(st.keyword, args);
68 void BinaryWriter::collect_keywords(const Statement &st)
70 DictEntry de=create_entry(st);
76 kst.args.push_back(next_st_id);
77 kst.args.push_back(de.keyword);
78 kst.args.push_back(de.args);
81 dict.insert(Dictionary::value_type(de, next_st_id++)).first;
84 for(ValueArray::const_iterator i=st.args.begin(); i!=st.args.end(); ++i)
85 if(i->get_type()==ENUM && !enums.count(i->get_raw()))
89 est.args.push_back(next_enum_id);
90 est.args.push_back(i->get_raw());
93 enums[i->get_raw()]=next_enum_id++;
96 for(list<Statement>::const_iterator i=st.sub.begin(); i!=st.sub.end(); ++i)
100 void BinaryWriter::write_int(long long n)
103 for(; n>>(i*7); ++i);
105 out.put(n>>(i*7) & 0x7F | (i?0x80:0));
108 void BinaryWriter::write_string(const string &s)
111 out.write(s.data(), s.size());
114 void BinaryWriter::write_float(float f)
119 char d[sizeof(float)];
123 #if BYTE_ORDER == LITTLE_ENDIAN
124 for(unsigned i=sizeof(float); i--;)
127 for(unsigned i=0; i<sizeof(float); ++i)
132 void BinaryWriter::write_enum(const string &e)
134 EnumMap::const_iterator i=enums.find(e);
136 throw InvalidParameterValue("Unknown enum");
137 write_int(i->second);
140 } // namespace DataFile