]> git.tdb.fi Git - libs/datafile.git/blobdiff - source/binarywriter.cpp
Drop copyright and license notices from source files
[libs/datafile.git] / source / binarywriter.cpp
index 95526bbae84666b6b02997ec68c724a1a357e6d8..9651609164ce4d5a5679928ba7e4f1b1b2947337 100644 (file)
@@ -1,10 +1,3 @@
-/* $Id$
-
-This file is part of libmspdatafile
-Copyright © 2006  Mikko Rasa, Mikkosoft Productions
-Distributed under the LGPL
-*/
-
 #include "binarywriter.h"
 #include "statement.h"
 
@@ -13,13 +6,13 @@ using namespace std;
 namespace Msp {
 namespace DataFile {
 
-BinaryWriter::BinaryWriter(ostream &o):
+BinaryWriter::BinaryWriter(IO::Base &o):
        WriterMode(o),
-       next_st_id(3),
-       next_enum_id(1)
+       next_kwd_id(3),
+       next_str_id(1)
 {
-       dict[DictEntry("__st", "iss")]=1;
-       dict[DictEntry("__enum", "is")]=1;
+       dict[DictEntry("__kwd", "iss")] = 1;
+       dict[DictEntry("__str", "is")] = 2;
 }
 
 void BinaryWriter::write(const Statement &st)
@@ -30,85 +23,96 @@ void BinaryWriter::write(const Statement &st)
 
 void BinaryWriter::write_(const Statement &st)
 {
-       Dictionary::iterator i=dict.find(create_entry(st));
+       Dictionary::iterator i = dict.find(DictEntry(st.keyword, st.get_signature()));
        if(i==dict.end())
                throw InvalidParameterValue("Unknown statement");
 
        write_int(i->second);
-       for(ValueArray::const_iterator j=st.args.begin(); j!=st.args.end(); ++j)
-               switch(j->get_type())
+       for(Statement::Arguments::const_iterator j = st.args.begin(); j!=st.args.end(); ++j)
+               switch(j->get_signature())
                {
-               case INTEGER: write_int   (j->get<long long>()); break;
-               case STRING:  write_string(j->get<const string &>()); break;
-               case BOOLEAN: write_int   (j->get<bool>()); break;
-               case FLOAT:   write_float (j->get<float>()); break;
-               case ENUM:    write_enum  (j->get_raw()); break;
+               case IntType::signature:    write_int   (j->get<IntType::Store>()); break;
+               case StringType::signature: write_string(j->get<StringType::Store>()); break;
+               case BoolType::signature:   write_int   (j->get<BoolType::Store>()); break;
+               case FloatType::signature:  write_float (j->get<FloatType::Store>()); break;
+               case SymbolType::signature: write_enum  (j->get<SymbolType::Store>()); break;
                }
 
        write_int(st.sub.size());
-       for(list<Statement>::const_iterator j=st.sub.begin(); j!=st.sub.end(); ++j)
+       for(list<Statement>::const_iterator j = st.sub.begin(); j!=st.sub.end(); ++j)
                write(*j);
 }
 
-DictEntry BinaryWriter::create_entry(const Statement &st)
-{
-       static const char types[]="ifsbe";
-
-       string args;
-       for(ValueArray::const_iterator i=st.args.begin(); i!=st.args.end(); ++i)
-       {
-               if(i->get_type()>=5)
-                       throw InvalidParameterValue("Invalid argument type");
-               args+=types[i->get_type()];
-       }
-
-       return DictEntry(st.keyword, args);
-}
-
 void BinaryWriter::collect_keywords(const Statement &st)
 {
-       DictEntry de=create_entry(st);
+       DictEntry de(st.keyword, st.get_signature());
 
        if(!dict.count(de))
        {
                Statement kst;
-               kst.keyword="__st";
-               kst.args.push_back(next_st_id);
+               kst.keyword = "__kwd";
+               kst.args.push_back(next_kwd_id);
                kst.args.push_back(de.keyword);
                kst.args.push_back(de.args);
                write_(kst);
 
-               dict.insert(Dictionary::value_type(de, next_st_id++)).first;
+               dict[de] = next_kwd_id++;
        }
 
-       for(ValueArray::const_iterator i=st.args.begin(); i!=st.args.end(); ++i)
-               if(i->get_type()==ENUM && !enums.count(i->get_raw()))
+       for(ValueArray::const_iterator i = st.args.begin(); i!=st.args.end(); ++i)
+       {
+               char sig = i->get_signature();
+               string str;
+               if(sig==SymbolType::signature)
+                       str = i->get<Symbol>().name;
+               else if(sig==StringType::signature)
                {
-                       Statement est;
-                       est.keyword="__enum";
-                       est.args.push_back(next_enum_id);
-                       est.args.push_back(i->get_raw());
-                       write_(est);
-
-                       enums[i->get_raw()]=next_enum_id++;
+                       str = i->get<string>();
+                       if(str.size()>32)
+                               continue;
                }
+               else
+                       continue;
+
+               if(strings.count(str))
+                       continue;
+
+               Statement sst;
+               sst.keyword = "__str";
+               sst.args.push_back(next_str_id);
+               sst.args.push_back(str);
+               write_(sst);
+
+               strings[str] = next_str_id++;
+       }
 
-       for(list<Statement>::const_iterator i=st.sub.begin(); i!=st.sub.end(); ++i)
+       for(list<Statement>::const_iterator i = st.sub.begin(); i!=st.sub.end(); ++i)
                collect_keywords(*i);
 }
 
 void BinaryWriter::write_int(long long n)
 {
-       unsigned i=1;
-       for(; n>>(i*7); ++i);
-       for(; i--;)
-               out.put(n>>(i*7) & 0x7F | (i?0x80:0));
+       unsigned i = sizeof(long long)-1;
+
+       if(n>=0)
+               for(; (i>0 && (n>>(i*7-1))==0); --i) ;
+       else
+               for(; (i>0 && (n>>(i*7-1))==-1); --i) ;
+
+       for(++i; i--;)
+               out.put((n>>(i*7) & 0x7F) | (i?0x80:0));
 }
 
 void BinaryWriter::write_string(const string &s)
 {
-       write_int(s.size());
-       out.write(s.data(), s.size());
+       StringMap::const_iterator i = strings.find(s);
+       if(i!=strings.end())
+               write_int(-static_cast<int>(i->second));
+       else
+       {
+               write_int(s.size());
+               out.write(s.data(), s.size());
+       }
 }
 
 void BinaryWriter::write_float(float f)
@@ -119,20 +123,20 @@ void BinaryWriter::write_float(float f)
                char d[sizeof(float)];
        };
 
-       v=f;
+       v = f;
 #if BYTE_ORDER == LITTLE_ENDIAN
-       for(unsigned i=sizeof(float); i--;)
+       for(unsigned i = sizeof(float); i--;)
                out.put(d[i]);
 #else
-       for(unsigned i=0; i<sizeof(float); ++i)
+       for(unsigned i = 0; i<sizeof(float); ++i)
                out.put(d[i]);
 #endif
 }
 
 void BinaryWriter::write_enum(const string &e)
 {
-       EnumMap::const_iterator i=enums.find(e);
-       if(i==enums.end())
+       StringMap::const_iterator i = strings.find(e);
+       if(i==strings.end())
                throw InvalidParameterValue("Unknown enum");
        write_int(i->second);
 }