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("__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(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_kwd_id);
77 kst.args.push_back(de.keyword);
78 kst.args.push_back(de.args);
81 dict[de]=next_kwd_id++;
84 for(ValueArray::const_iterator i=st.args.begin(); i!=st.args.end(); ++i)
86 const Type t=i->get_type();
87 const string &r=i->get_raw();
88 if((t==ENUM || (t==STRING && r.size()<32)) && !strings.count(r))
92 sst.args.push_back(next_str_id);
93 sst.args.push_back(r);
96 strings[r]=next_str_id++;
100 for(list<Statement>::const_iterator i=st.sub.begin(); i!=st.sub.end(); ++i)
101 collect_keywords(*i);
104 void BinaryWriter::write_int(long long n)
106 unsigned i=sizeof(long long)-1;
109 for(; (i>0 && (n>>(i*7-1))==0); --i) ;
111 for(; (i>0 && (n>>(i*7-1))==-1); --i) ;
114 out.put((n>>(i*7) & 0x7F) | (i?0x80:0));
117 void BinaryWriter::write_string(const string &s)
119 StringMap::const_iterator i=strings.find(s);
121 write_int(-static_cast<int>(i->second));
125 out.write(s.data(), s.size());
129 void BinaryWriter::write_float(float f)
134 char d[sizeof(float)];
138 #if BYTE_ORDER == LITTLE_ENDIAN
139 for(unsigned i=sizeof(float); i--;)
142 for(unsigned i=0; i<sizeof(float); ++i)
147 void BinaryWriter::write_enum(const string &e)
149 StringMap::const_iterator i=strings.find(e);
151 throw InvalidParameterValue("Unknown enum");
152 write_int(i->second);
155 } // namespace DataFile