Properties.cc
Go to the documentation of this file.
00001 /* 00002 * Copyright 2006-2009 Savarese Software Research Corporation 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * https://www.savarese.com/software/ApacheLicense-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include <ssrc/wispers/lua/Properties.h> 00018 00019 __BEGIN_NS_SSRC_WSPR_LUA 00020 00021 void PropertiesToTable::PushValue::operator()(const primitive_property_vector & v) const 00022 { 00023 lua_createtable(state, v.size(), 0); 00024 int i = 1; 00025 for(primitive_property_vector::const_iterator && it = v.begin(), && end = v.end(); it != end; ++it) 00026 { 00027 lua_pushinteger(state, i++); 00028 boost::apply_visitor(*this, *it); 00029 lua_settable(state, -3); 00030 } 00031 } 00032 00033 void PropertiesToTable::PushValue::operator()(const Properties & properties) 00034 const 00035 { 00036 using NS_SSRC_WSPR_UTILITY::property_type; 00037 const property_type *v = properties.value(); 00038 00039 if(properties.is_leaf()) { 00040 if(v != 0) { 00041 boost::apply_visitor(*this, *v); 00042 } else { 00043 lua_pushnil(state); 00044 } 00045 } else { 00046 lua_newtable(state); 00047 00048 if(v != 0) { 00049 boost::apply_visitor(*this, *v); 00050 lua_setfield(state, -2, "_value"); 00051 } 00052 00053 properties.visit(to_table); 00054 } 00055 } 00056 00057 void PropertiesToTable::PushValue::operator()(const property_vector & v) const 00058 { 00059 lua_createtable(state, v.size(), 0); 00060 int i = 1; 00061 for(property_vector::const_iterator && it = v.begin(), && end = v.end(); it != end; ++it) 00062 { 00063 lua_pushinteger(state, i++); 00064 PropertiesToTable::PushValue::operator()(*it); 00065 lua_settable(state, -3); 00066 } 00067 } 00068 00069 void PropertiesToTable::enter(const std::string key, 00070 const Properties *properties, 00071 const bool) 00072 const 00073 { 00074 using NS_SSRC_WSPR_UTILITY::property_type; 00075 const property_type *v = properties->value(); 00076 00077 if(!properties->is_leaf()) { 00078 lua_newtable(state()); 00079 00080 if(v != 0) { 00081 boost::apply_visitor(push, *v); 00082 lua_setfield(state(), -2, "_value"); 00083 } 00084 } else { 00085 if(v != 0) { 00086 boost::apply_visitor(push, *v); 00087 } else { 00088 lua_pushnil(state()); 00089 } 00090 } 00091 } 00092 00093 void PropertiesToTable::leave(const std::string key, 00094 const Properties *properties, 00095 const bool) 00096 const 00097 { 00098 lua_setfield(state(), -2, key.c_str()); 00099 } 00100 00110 void table_to_properties(lua_State *state, Properties & properties) { 00111 const size_t size = lua_objlen(state, -1); 00112 00113 if(size == 0) { 00114 lua_pushnil(state); 00115 while(lua_next(state, -2)) { 00116 const int ltype = lua_type(state, -1); 00117 const string && key = convert<string>(state, -2); 00118 00119 // TODO: key == "_value" should use set_value(v) instead of set(v, k) 00120 switch(ltype) { 00121 case LUA_TNUMBER: 00122 properties.set(convert<lua_Number>(state, -1), key); 00123 break; 00124 case LUA_TBOOLEAN: 00125 properties.set(convert<bool>(state, -1), key); 00126 break; 00127 case LUA_TSTRING: 00128 properties.set(convert<string>(state, -1), key); 00129 break; 00130 case LUA_TTABLE: { 00131 Properties *node = properties.create_node(key); 00132 table_to_properties(state, *node); 00133 } 00134 break; 00135 default: 00136 break; 00137 }; 00138 00139 lua_pop(state, 1); 00140 } 00141 } else { 00142 lua_pushnil(state); 00143 // Determine type of array elements (primitive or table). 00144 if(lua_next(state, -2)) { 00145 if(lua_istable(state, -1)) { 00146 Properties *node; 00147 property_vector & v = properties.create_property_vector(); 00148 v.reserve(size); 00149 do { 00150 v.push_back(node = new Properties); 00151 table_to_properties(state, *node); 00152 lua_pop(state, 1); 00153 } while(lua_next(state, -2)); 00154 } else { 00155 primitive_property_vector & v = 00156 properties.create_primitive_property_vector(); 00157 v.reserve(size); 00158 do { 00159 const int ltype = lua_type(state, -1); 00160 switch(ltype) { 00161 case LUA_TNUMBER: v.push_back(convert<lua_Number>(state, -1)); break; 00162 case LUA_TBOOLEAN: v.push_back(convert<bool>(state, -1)); break; 00163 case LUA_TSTRING: v.push_back(convert<string>(state, -1)); break; 00164 default: break; 00165 }; 00166 lua_pop(state, 1); 00167 } while(lua_next(state, -2)); 00168 } 00169 } 00170 } 00171 } 00172 00180 void swig_table_to_properties(void *state, Properties & properties) { 00181 table_to_properties(reinterpret_cast<lua_State*>(state), properties); 00182 } 00183 00184 namespace { 00185 inline properties_ptr load_properties(lua_State *state, int err) 00186 SSRC_DECL_THROW(LuaCallError) 00187 { 00188 if(err != 0) { 00189 string msg(lua_tostring(state, -1)); 00190 lua_pop(state, 1); 00191 throw LuaCallError(msg, err); 00192 } 00193 00194 pcall_nopop(0, LUA_MULTRET, state); 00195 00196 if(!lua_istable(state, -1)) { 00197 lua_pop(state, 1); 00198 throw LuaCallError("properties definition does not return table", 00199 LUA_ERRSYNTAX); 00200 } 00201 00202 properties_ptr properties(new Properties); 00203 00204 table_to_properties(state, *properties); 00205 lua_pop(state, 1); 00206 00207 return properties; 00208 } 00209 } 00210 00211 properties_ptr load_properties(lua_State *state, const std::string & filename) 00212 SSRC_DECL_THROW(LuaCallError) 00213 { 00214 int err = luaL_loadfile(state, filename.c_str()); 00215 return load_properties(state, err); 00216 } 00217 00218 properties_ptr load_string_properties(lua_State *state, 00219 const std::string & code_str) 00220 SSRC_DECL_THROW(LuaCallError) 00221 { 00222 int err = luaL_loadstring(state, code_str.c_str()); 00223 return load_properties(state, err); 00224 } 00225 00226 __END_NS_SSRC_WSPR_LUA
Copyright © 2006-2011 Savarese Software Research Corporation. All rights reserved.