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(IO::Base &o):
21 dict[DictEntry("__st", "iss")]=1;
22 dict[DictEntry("__enum", "is")]=2;
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[de]=next_st_id++;
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)
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)
116 out.write(s.data(), s.size());
119 void BinaryWriter::write_float(float f)
124 char d[sizeof(float)];
128 #if BYTE_ORDER == LITTLE_ENDIAN
129 for(unsigned i=sizeof(float); i--;)
132 for(unsigned i=0; i<sizeof(float); ++i)
137 void BinaryWriter::write_enum(const string &e)
139 EnumMap::const_iterator i=enums.find(e);
141 throw InvalidParameterValue("Unknown enum");
142 write_int(i->second);
145 } // namespace DataFile