{
switch(de.args[j])
{
- case 'i':
+ case IntType::signature:
result.args.push_back(parse_int());
break;
- case 'f':
+ case FloatType::signature:
result.args.push_back(parse_float());
break;
- case 's':
+ case StringType::signature:
result.args.push_back(parse_string());
break;
- case 'b':
+ case BoolType::signature:
result.args.push_back(parse_bool());
break;
- case 'e':
- result.args.push_back(Value(ENUM, parse_enum()));
+ case SymbolType::signature:
+ result.args.push_back(Symbol(parse_enum()));
break;
}
}
/* $Id$
This file is part of libmspdatafile
-Copyright © 2006 Mikko Rasa, Mikkosoft Productions
+Copyright © 2007-2008, 2010 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
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());
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))
{
for(ValueArray::const_iterator i = st.args.begin(); i!=st.args.end(); ++i)
{
- const Type t = i->get_type();
- const string &r = i->get_raw();
- if((t==ENUM || (t==STRING && r.size()<32)) && !strings.count(r))
+ char sig = i->get_signature();
+ string str;
+ if(sig==SymbolType::signature)
+ str = i->get<Symbol>().name;
+ else if(sig==StringType::signature)
{
- Statement sst;
- sst.keyword = "__str";
- sst.args.push_back(next_str_id);
- sst.args.push_back(r);
- write_(sst);
-
- strings[r] = next_str_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)
/* $Id$
This file is part of libmspdatafile
-Copyright © 2006 Mikko Rasa, Mikkosoft Productions
+Copyright © 2007-2008, 2010 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
void write(const Statement &st);
private:
void write_(const Statement &st);
- DictEntry create_entry(const Statement &st);
void collect_keywords(const Statement &st);
void write_int(long long n);
void write_string(const std::string &s);
/* $Id$
This file is part of libmspdatafile
-Copyright © 2006-2008 Mikko Rasa, Mikkosoft Productions
+Copyright © 2008, 2010 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
{
std::vector<A0> values;
values.reserve(st.args.size());
- for(ValueArray::const_iterator i=st.args.begin(); i!=st.args.end(); ++i)
+ for(Statement::Arguments::const_iterator i=st.args.begin(); i!=st.args.end(); ++i)
values.push_back(i->get<A0>());
(dynamic_cast<L &>(l).*func)(values);
}
/* $Id: statement.h 19 2007-08-21 14:11:23Z tdb $
This file is part of libmspdatafile
-Copyright © 2006 Mikko Rasa, Mikkosoft Productions
+Copyright © 2007, 2010 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
#include <msp/strings/formatter.h>
#include "statement.h"
+using namespace std;
+
namespace Msp {
namespace DataFile {
-std::string Statement::get_location() const
+Statement::Statement():
+ valid(false),
+ line(0)
+{ }
+
+Statement::Statement(const string &kw):
+ keyword(kw),
+ valid(true),
+ line(0)
+{ }
+
+string Statement::get_location() const
{
- std::string result = source;
+ string result = source;
if(line)
result += format(":%d", line);
return result;
}
+string Statement::get_signature() const
+{
+ string result;
+ for(Arguments::const_iterator i = args.begin(); i!=args.end(); ++i)
+ result += i->get_signature();
+ return result;
+}
+
} // namespace DataFile
} // namespace Msp
/* $Id$
This file is part of libmspdatafile
-Copyright © 2006 Mikko Rasa, Mikkosoft Productions
+Copyright © 2006-2008, 2010 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
+
#ifndef MSP_DATAFILE_STATEMENT_H_
#define MSP_DATAFILE_STATEMENT_H_
class Statement
{
public:
+ typedef std::vector<Value> Arguments;
+
std::string keyword;
- ValueArray args;
+ Arguments args;
bool valid;
std::string source;
unsigned line;
std::list<Statement> sub;
- Statement(): valid(false), line(0) { }
- Statement(const std::string &kw): keyword(kw), valid(true), line(0) { }
+ Statement();
+ Statement(const std::string &);
std::string get_location() const;
+ std::string get_signature() const;
template<typename T>
Statement &append(const T &v)
{
- args.push_back(Value(v));
+ args.push_back(v);
return *this;
}
/* $Id$
This file is part of libmspdatafile
-Copyright © 2007-2008 Mikko Rasa, Mikkosoft Productions
+Copyright © 2007-2008, 2010 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
else if(token.str==";")
break;
else if(token.type==Token::INTEGER)
- result.args.push_back(Value(INTEGER, token.str));
+ result.append(lexical_cast<IntType::Store>(token.str));
else if(token.type==Token::FLOAT)
- result.args.push_back(Value(FLOAT, token.str));
+ result.append(lexical_cast<FloatType::Store>(token.str));
else if(token.type==Token::STRING)
- result.args.push_back(Value(STRING, token.str));
+ result.append(token.str);
else if(token.type==Token::IDENTIFIER)
{
if(token.str=="true")
- result.args.push_back(Value(BOOLEAN, "1"));
+ result.append(true);
else if(token.str=="false")
- result.args.push_back(Value(BOOLEAN, "0"));
+ result.append(false);
else
- result.args.push_back(Value(ENUM, token.str));
- //result.args.push_back(resolve_identifiertoken.str);
+ result.append(Symbol(token.str));
}
else if(token.str=="")
throw_at(ParseError("Unexcepted end of input"), get_location());
/* $Id$
This file is part of libmspdatafile
-Copyright © 2006 Mikko Rasa, Mikkosoft Productions
+Copyright © 2007-2008, 2010 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
for(ValueArray::const_iterator i = st.args.begin(); i!=st.args.end(); ++i)
{
out.put(' ');
- if(i->get_type()==STRING)
- IO::print(out, "\"%s\"", c_escape(i->get_raw(), false));
- else if(i->get_type()==BOOLEAN)
- out.write(i->get<bool>() ? "true" : "false");
- else
- out.write(i->get_raw());
+ if(i->get_signature()==StringType::signature)
+ IO::print(out, "\"%s\"", c_escape(i->get<StringType::Store>(), false));
+ else if(i->get_signature()==BoolType::signature)
+ out.write(i->get<BoolType::Store>() ? "true" : "false");
+ else if(i->get_signature()==IntType::signature)
+ out.write(lexical_cast(i->get<IntType::Store>()));
+ else if(i->get_signature()==FloatType::signature)
+ out.write(format("%15g", (i->get<FloatType::Store>())));
+ else if(i->get_signature()==SymbolType::signature)
+ out.write(i->get<SymbolType::Store>().name);
}
if(!st.sub.empty())
{
--- /dev/null
+/* $Id$
+
+This file is part of libmspdatafile
+Copyright © 2010 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef MSP_DATAFILE_TYPE_H_
+#define MSP_DATAFILE_TYPE_H_
+
+#include <msp/strings/lexicalcast.h>
+
+namespace Msp {
+namespace DataFile {
+
+struct Symbol
+{
+ std::string name;
+
+ Symbol(const std::string &n): name(n) { }
+
+ template<typename T> operator T() const { return lexical_cast<T>(name); }
+};
+
+struct IntType
+{
+ static const char signature = 'i';
+ typedef long long int Store;
+};
+
+struct FloatType
+{
+ static const char signature = 'f';
+ typedef double Store;
+};
+
+struct BoolType
+{
+ static const char signature = 'b';
+ typedef bool Store;
+};
+
+struct StringType
+{
+ static const char signature = 's';
+ typedef std::string Store;
+};
+
+struct SymbolType
+{
+ // For backward compatibility
+ static const char signature = 'e';
+ typedef Symbol Store;
+};
+
+template<typename T>
+struct TypeInfo: SymbolType { };
+
+template<>
+struct TypeInfo<short int>: IntType { };
+
+template<>
+struct TypeInfo<unsigned short int>: IntType { };
+
+template<>
+struct TypeInfo<int>: IntType { };
+
+template<>
+struct TypeInfo<unsigned int>: IntType { };
+
+template<>
+struct TypeInfo<long int>: IntType { };
+
+template<>
+struct TypeInfo<unsigned long int>: IntType { };
+
+template<>
+struct TypeInfo<long long int>: IntType { };
+
+template<>
+struct TypeInfo<unsigned long long int>: IntType { };
+
+template<>
+struct TypeInfo<float>: FloatType { };
+
+template<>
+struct TypeInfo<double>: FloatType { };
+
+template<>
+struct TypeInfo<bool>: BoolType { };
+
+template<>
+struct TypeInfo<std::string>: StringType { };
+
+template<typename T>
+struct TypeInfo<const T>: TypeInfo<T> { };
+
+template<typename T>
+struct TypeInfo<T &>: TypeInfo<T> { };
+
+} // namespace DataFile
+} // namespace Msp
+
+#endif
/* $Id$
This file is part of libmspdatafile
-Copyright © 2006 Mikko Rasa, Mikkosoft Productions
+Copyright © 2006-2008, 2010 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
+
#ifndef MSP_DATAFILE_VALUE_H_
#define MSP_DATAFILE_VALUE_H_
#include <vector>
-#include <msp/strings/lexicalcast.h>
+#include <msp/core/meta.h>
+#include <msp/core/variant.h>
#include "except.h"
+#include "type.h"
namespace Msp {
namespace DataFile {
-enum Type
-{
- INTEGER,
- FLOAT,
- STRING,
- BOOLEAN,
- ENUM
-};
-
-template<typename T> struct TypeResolver { static const Type type=ENUM; };
-template<> struct TypeResolver<short> { static const Type type=INTEGER; };
-template<> struct TypeResolver<unsigned short> { static const Type type=INTEGER; };
-template<> struct TypeResolver<int> { static const Type type=INTEGER; };
-template<> struct TypeResolver<unsigned> { static const Type type=INTEGER; };
-template<> struct TypeResolver<long> { static const Type type=INTEGER; };
-template<> struct TypeResolver<unsigned long> { static const Type type=INTEGER; };
-template<> struct TypeResolver<long long> { static const Type type=INTEGER; };
-template<> struct TypeResolver<unsigned long long> { static const Type type=INTEGER; };
-template<> struct TypeResolver<float> { static const Type type=FLOAT; };
-template<> struct TypeResolver<double> { static const Type type=FLOAT; };
-template<> struct TypeResolver<bool> { static const Type type=BOOLEAN; };
-template<> struct TypeResolver<std::string> { static const Type type=STRING; };
-template<typename T> struct TypeResolver<const T> { static const Type type=TypeResolver<T>::type; };
-template<typename T> struct TypeResolver<T &> { static const Type type=TypeResolver<T>::type; };
-template<typename T> struct TypeResolver<const T &> { static const Type type=TypeResolver<T>::type; };
-
class Value
{
-public:
- Value(Type t, const std::string &d): type(t), data(d) { }
+private:
+ char sig;
+ Variant data;
+public:
template<typename T>
- Value(T d): type(TypeResolver<T>::type), data(lexical_cast(d)) { }
+ Value(T d):
+ sig(TypeInfo<T>::signature),
+ data(static_cast<typename TypeInfo<T>::Store>(d))
+ { }
+
+ Value(Symbol d): sig(TypeInfo<Symbol>::signature), data(d) { }
template<typename T>
- T get() const;
+ typename RemoveReference<T>::Type get() const
+ { return get_<typename TypeInfo<T>::Store>(); }
- Type get_type() const { return type; }
- const std::string &get_raw() const { return data; }
+ char get_signature() const { return sig; }
private:
- Type type;
- std::string data;
+ template<typename T>
+ T get_() const;
};
-typedef std::vector<Value> ValueArray;
-
-template<Type T> inline bool check_type(Type t) { return t==T; }
-template<> inline bool check_type<FLOAT>(Type t) { return t==INTEGER || t==FLOAT; }
+typedef std::vector<Value> ValueArray __attribute__((deprecated));
template<typename T>
-inline T Value::get() const
+inline T Value::get_() const
{
- if(!check_type<TypeResolver<T>::type>(type))
+ if(sig!=TypeInfo<T>::signature)
throw TypeError("Type mismatch");
- return lexical_cast<T>(data);
+ return data.value<typename TypeInfo<T>::Store>();
}
template<>
-inline std::string Value::get<std::string>() const
+inline FloatType::Store Value::get_<FloatType::Store>() const
{
- if(type!=STRING)
+ if(sig==IntType::signature)
+ return data.value<IntType::Store>();
+ else if(sig!=FloatType::signature)
throw TypeError("Type mismatch");
- return data;
-}
-template<>
-inline const std::string &Value::get<const std::string&>() const
-{
- if(type!=STRING)
- throw TypeError("Type mismatch");
- return data;
+ return data.value<FloatType::Store>();
}
} // namespace DataFile
/* $Id$
This file is part of libmspdatafile
-Copyright © 2008 Mikko Rasa, Mikkosoft Productions
+Copyright © 2008, 2010 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
return true;
for(vector<DataFile::Value>::iterator i = st.args.begin(); i!=st.args.end(); ++i)
- if(i->get_type()==DataFile::STRING)
+ if(i->get_signature()==DataFile::StringType::signature)
{
- if(i->get_raw()=="$filename")
+ string value = i->get<string>();
+ if(value=="$filename")
*i = DataFile::Value(FS::basename(fn.str()));
- else if(i->get_raw()=="$content")
+ else if(value=="$content")
{
IO::File in(fn.str());
string data;