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