]> git.tdb.fi Git - libs/datafile.git/blob - source/value.h
Add binary data format
[libs/datafile.git] / source / value.h
1 /* $Id$
2
3 This file is part of libmspdatafile
4 Copyright © 2006  Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7 #ifndef MSP_DATAFILE_VALUE_H_
8 #define MSP_DATAFILE_VALUE_H_
9
10 #include <vector>
11 #include <msp/strings/lexicalcast.h>
12 #include "error.h"
13
14 namespace Msp {
15 namespace DataFile {
16
17 enum Type
18 {
19         INTEGER,
20         FLOAT,
21         STRING,
22         BOOLEAN,
23         ENUM
24 };
25
26 template<typename T> struct TypeResolver       { static const Type type=ENUM; };
27 template<> struct TypeResolver<short>          { static const Type type=INTEGER; };
28 template<> struct TypeResolver<unsigned short> { static const Type type=INTEGER; };
29 template<> struct TypeResolver<int>            { static const Type type=INTEGER; };
30 template<> struct TypeResolver<unsigned>       { static const Type type=INTEGER; };
31 template<> struct TypeResolver<long>           { static const Type type=INTEGER; };
32 template<> struct TypeResolver<unsigned long>  { static const Type type=INTEGER; };
33 template<> struct TypeResolver<long long>      { static const Type type=INTEGER; };
34 template<> struct TypeResolver<unsigned long long> { static const Type type=INTEGER; };
35 template<> struct TypeResolver<float>          { static const Type type=FLOAT; };
36 template<> struct TypeResolver<double>         { static const Type type=FLOAT; };
37 template<> struct TypeResolver<bool>           { static const Type type=BOOLEAN; };
38 template<> struct TypeResolver<std::string>    { static const Type type=STRING; };
39 template<typename T> struct TypeResolver<const T>   { static const Type type=TypeResolver<T>::type; };
40 template<typename T> struct TypeResolver<T &>       { static const Type type=TypeResolver<T>::type; };
41 template<typename T> struct TypeResolver<const T &> { static const Type type=TypeResolver<T>::type; };
42
43 class Value
44 {
45 public:
46         Value(Type t, const std::string &d): type(t), data(d) { }
47
48         template<typename T>
49         Value(T d): type(TypeResolver<T>::type), data(lexical_cast(d)) { }
50
51         template<typename T>
52         T get() const;
53
54         Type get_type() const { return type; }
55         const std::string &get_raw() const { return data; }
56 private:
57         Type type;
58         std::string data;
59 };
60
61 typedef std::vector<Value> ValueArray;
62
63 template<Type T> inline bool check_type(Type t)  { return t==T; }
64 template<> inline bool check_type<FLOAT>(Type t) { return t==INTEGER || t==FLOAT; }
65
66 template<typename T>
67 inline T Value::get() const
68 {
69         if(!check_type<TypeResolver<T>::type>(type))
70                 throw TypeError("Type mismatch");
71
72         std::istringstream ss(data);
73         T result;
74         ss>>result;
75         if(ss.fail())
76                 //XXX
77                 throw Exception("Invalid value");
78
79         return result;
80 }
81
82 template<>
83 inline std::string Value::get<std::string>() const
84 {
85         if(type!=STRING)
86                 throw TypeError("Type mismatch");
87         return data;
88 }
89
90 template<>
91 inline const std::string &Value::get<const std::string&>() const
92 {
93         if(type!=STRING)
94                 throw TypeError("Type mismatch");
95         return data;
96 }
97
98 } // namespace DataFile
99 } // namespace Msp
100
101 #endif