1 /**
2  * Copyright (c) 2006-2016 LOVE Development Team
3  *
4  * This software is provided 'as-is', without any express or implied
5  * warranty.  In no event will the authors be held liable for any damages
6  * arising from the use of this software.
7  *
8  * Permission is granted to anyone to use this software for any purpose,
9  * including commercial applications, and to alter it and redistribute it
10  * freely, subject to the following restrictions:
11  *
12  * 1. The origin of this software must not be misrepresented; you must not
13  *    claim that you wrote the original software. If you use this software
14  *    in a product, an acknowledgment in the product documentation would be
15  *    appreciated but is not required.
16  * 2. Altered source versions must be plainly marked as such, and must not be
17  *    misrepresented as being the original software.
18  * 3. This notice may not be removed or altered from any source distribution.
19  **/
20 
21 #ifndef LOVE_VARIANT_H
22 #define LOVE_VARIANT_H
23 
24 #include "common/runtime.h"
25 #include "common/Object.h"
26 #include "common/int.h"
27 
28 #include <cstring>
29 #include <vector>
30 
31 namespace love
32 {
33 
34 class Variant
35 {
36 public:
37 
38 	enum Type
39 	{
40 		UNKNOWN = 0,
41 		BOOLEAN,
42 		NUMBER,
43 		STRING,
44 		SMALLSTRING,
45 		LUSERDATA,
46 		FUSERDATA,
47 		NIL,
48 		TABLE
49 	};
50 
51 	Variant();
52 	Variant(bool boolean);
53 	Variant(double number);
54 	Variant(const char *string, size_t len);
55 	Variant(void *userdata);
56 	Variant(love::Type udatatype, void *userdata);
57 	Variant(std::vector<std::pair<Variant, Variant>> *table);
58 	Variant(const Variant &v);
59 	Variant(Variant &&v);
60 	~Variant();
61 
62 	Variant &operator = (const Variant &v);
63 
getType()64 	Type getType() const { return type; }
65 
66 	static Variant fromLua(lua_State *L, int n, bool allowTables = true);
67 	void toLua(lua_State *L) const;
68 
69 private:
70 
71 	class SharedString : public love::Object
72 	{
73 	public:
74 
SharedString(const char * string,size_t len)75 		SharedString(const char *string, size_t len)
76 			: len(len)
77 		{
78 			str = new char[len+1];
79 			memcpy(str, string, len);
80 		}
~SharedString()81 		virtual ~SharedString() { delete[] str; }
82 
83 		char *str;
84 		size_t len;
85 	};
86 
87 	class SharedTable : public love::Object
88 	{
89 	public:
90 
SharedTable(std::vector<std::pair<Variant,Variant>> * table)91 		SharedTable(std::vector<std::pair<Variant, Variant>> *table)
92 			: table(table)
93 		{
94 		}
95 
~SharedTable()96 		virtual ~SharedTable() { delete table; }
97 
98 		std::vector<std::pair<Variant, Variant>> *table;
99 	};
100 
101 	static const int MAX_SMALL_STRING_LENGTH = 15;
102 
103 	Type type;
104 	love::Type udatatype;
105 
106 	union Data
107 	{
108 		bool boolean;
109 		double number;
110 		SharedString *string;
111 		void *userdata;
112 		SharedTable *table;
113 		struct
114 		{
115 			char str[MAX_SMALL_STRING_LENGTH];
116 			uint8 len;
117 		} smallstring;
118 	} data;
119 
120 }; // Variant
121 } // love
122 
123 #endif // LOVE_VARIANT_H
124