1 /******************************************************************************\
2 * LuaFunction.cpp                                                              *
3 * A C++ equivalent of a Lua function.                                          *
4 *                                                                              *
5 *                                                                              *
6 * Copyright (C) 2005-2013 by Leandro Motta Barros.                             *
7 *                                                                              *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy *
9 * of this software and associated documentation files (the "Software"), to     *
10 * deal in the Software without restriction, including without limitation the   *
11 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or  *
12 * sell copies of the Software, and to permit persons to whom the Software is   *
13 * furnished to do so, subject to the following conditions:                     *
14 *                                                                              *
15 * The above copyright notice and this permission notice shall be included in   *
16 * all copies or substantial portions of the Software.                          *
17 *                                                                              *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR   *
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,     *
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE *
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER       *
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      *
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS *
24 * IN THE SOFTWARE.                                                             *
25 \******************************************************************************/
26 
27 #include <Diluculum/LuaFunction.hpp>
28 #include <cstring>
29 
30 
31 namespace Diluculum
32 {
33    // - LuaFunction::LuaFunction -----------------------------------------------
LuaFunction(const std::string & luaChunk)34    LuaFunction::LuaFunction (const std::string& luaChunk)
35       : functionType_(LUA_LUA_FUNCTION), size_(luaChunk.size()), readerFlag_(false)
36    {
37       data_.typeLuaFunction = new char[size_];
38       memcpy(data_.typeLuaFunction, luaChunk.c_str(), size_);
39    }
40 
LuaFunction(const void * data,size_t size)41    LuaFunction::LuaFunction (const void* data, size_t size)
42       : functionType_(LUA_LUA_FUNCTION), size_(size), readerFlag_(false)
43    {
44       data_.typeLuaFunction = new char[size_];
45       memcpy(data_.typeLuaFunction, data, size);
46    }
47 
LuaFunction(lua_CFunction func)48    LuaFunction::LuaFunction (lua_CFunction func)
49       : functionType_(LUA_C_FUNCTION), size_(sizeof(lua_CFunction)), readerFlag_(false)
50    {
51       data_.typeCFunction = func;
52    }
53 
LuaFunction(const LuaFunction & other)54    LuaFunction::LuaFunction (const LuaFunction& other)
55       : functionType_(other.functionType_),
56         size_(other.getSize()), readerFlag_(false)
57    {
58       switch (functionType_)
59       {
60          case LUA_LUA_FUNCTION:
61             data_.typeLuaFunction = new char[getSize()];
62             memcpy (getData(), other.getData(), getSize());
63             break;
64 
65          default:
66             // no constructor needed.
67             memcpy (&data_, &other.data_, sizeof(PossibleTypes));
68             break;
69       }
70    }
71 
72 
73 
74    // - LuaFunction::getCFunction ----------------------------------------------
getCFunction() const75    lua_CFunction LuaFunction::getCFunction() const
76    {
77       assert(functionType_ == LUA_C_FUNCTION
78              && "Called LuaFunction::getCFunction() for a non-C function.");
79 
80       return data_.typeCFunction;
81    }
82 
83 
84 
85    // - LuaFunction::setData ---------------------------------------------------
setData(void * data,size_t size)86    void LuaFunction::setData (void* data, size_t size)
87    {
88       assert(functionType_ == LUA_LUA_FUNCTION
89              && "Called LuaFunction::setData() for a non-Lua function.");
90 
91       size_ = size;
92       delete[] data_.typeLuaFunction;
93       data_.typeLuaFunction = new char[size];
94       memcpy(data_.typeLuaFunction, data, size);
95    }
96 
97 
98 
99    // - LuaFunction::operator= -------------------------------------------------
operator =(const LuaFunction & rhs)100    const LuaFunction& LuaFunction::operator= (const LuaFunction& rhs)
101    {
102       destroyObjectAtData();
103 
104       size_ = rhs.getSize();
105       functionType_ = rhs.functionType_;
106 
107       switch (functionType_)
108       {
109          case LUA_LUA_FUNCTION:
110             data_.typeLuaFunction = new char[getSize()];
111             memcpy (getData(), rhs.getData(), getSize());
112             break;
113 
114          default:
115             // no constructor needed.
116             memcpy (&data_, &rhs.data_, sizeof(PossibleTypes));
117             break;
118       }
119 
120       return *this;
121    }
122 
123 
124 
125    // - LuaFunction::operator> -------------------------------------------------
operator >(const LuaFunction & rhs) const126    bool LuaFunction::operator> (const LuaFunction& rhs) const
127    {
128       if (functionType_ > rhs.functionType_)
129          return true;
130       if (functionType_ < rhs.functionType_)
131          return false;
132       else // functionType_ == rhs.functionType_
133       {
134          if (functionType_ == LUA_C_FUNCTION)
135             return memcmp (&data_.typeCFunction, &rhs.data_.typeCFunction, sizeof(lua_CFunction)) > 0;
136          else if (functionType_ == LUA_LUA_FUNCTION)
137             if (getSize() > rhs.getSize())
138                return true;
139             else if (getSize() < rhs.getSize())
140                return false;
141             else // getSize() == rhs.getSize()
142                return memcmp (getData(), rhs.getData(), getSize()) > 0;
143          else
144          {
145             assert (false && "Unsupported type found at a call "
146                     "to 'LuaFunction::operator>()'");
147             return false; // make the compiler happy.
148          }
149       }
150    }
151 
152 
153 
154    // - LuaFunction::operator< -------------------------------------------------
operator <(const LuaFunction & rhs) const155    bool LuaFunction::operator< (const LuaFunction& rhs) const
156    {
157       if (functionType_ < rhs.functionType_)
158          return true;
159       else if (functionType_ > rhs.functionType_)
160          return false;
161       else // functionType_ == rhs.functionType_
162       {
163          if (functionType_ == LUA_C_FUNCTION)
164             return memcmp (&data_.typeCFunction, &rhs.data_.typeCFunction, sizeof(lua_CFunction)) < 0;
165          else if (functionType_ == LUA_LUA_FUNCTION)
166          {
167             if (getSize() < rhs.getSize())
168                return true;
169             else if (getSize() > rhs.getSize())
170                return false;
171             else // getSize() == rhs.getSize()
172                return memcmp (getData(), rhs.getData(), getSize()) < 0;
173          }
174          else
175          {
176             assert (false && "Unsupported type found at a call "
177                     "to 'LuaFunction::operator<()'");
178             return false; // make the compiler happy.
179          }
180       }
181    }
182 
183 
184 
185    // - LuaFunction::operator== ------------------------------------------------
operator ==(const LuaFunction & rhs) const186    bool LuaFunction::operator== (const LuaFunction& rhs) const
187    {
188       if (functionType_ != rhs.functionType_)
189          return false;
190       else switch (functionType_)
191       {
192          case LUA_C_FUNCTION:
193             return getCFunction() == rhs.getCFunction();
194 
195          case LUA_LUA_FUNCTION:
196             return getSize() == rhs.getSize()
197                && memcmp (getData(), rhs.getData(), getSize()) == 0;
198 
199          default:
200          {
201             assert(
202                false
203                && "Invalid type found in a call to 'LuaFunction::operator==()'.");
204             return false; // make compilers happy
205          }
206       }
207    }
208 
209 
210 
211    // - LuaFunction::operator!= ------------------------------------------------
operator !=(const LuaFunction & rhs) const212    bool LuaFunction::operator!= (const LuaFunction& rhs) const
213    {
214       if (functionType_ != rhs.functionType_)
215          return true;
216       else switch (functionType_)
217       {
218          case LUA_C_FUNCTION:
219             return getCFunction() != rhs.getCFunction();
220 
221          case LUA_LUA_FUNCTION:
222             return getSize() != rhs.getSize()
223                || memcmp (getData(), rhs.getData(), getSize()) != 0;
224 
225          default:
226          {
227             assert(
228                false
229                && "Invalid type found in a call to 'LuaFunction::operator!=()'.");
230             return false; // make compilers happy
231          }
232       }
233    }
234 
235 
236 
237    // - LuaFunction::destroyObjectAtData ---------------------------------------
destroyObjectAtData()238    void LuaFunction::destroyObjectAtData()
239    {
240       switch (functionType_)
241       {
242          case LUA_LUA_FUNCTION:
243             delete[] data_.typeLuaFunction;
244             break;
245 
246          default:
247             // no destructor needed.
248             break;
249       }
250    }
251 
252 } // namespace Diluculum
253