comparison Core/Lua/LuaFunctionCall.cpp @ 1448:3f7722179467

refactoring: GetJson in Lua
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 02 Jul 2015 09:10:25 +0200
parents 6e7e5ed91c2d
children 905842836ad4
comparison
equal deleted inserted replaced
1447:5ba7471780ae 1448:3f7722179467
124 124
125 return lua_toboolean(context_.lua_, 1) != 0; 125 return lua_toboolean(context_.lua_, 1) != 0;
126 } 126 }
127 127
128 128
129 static void PopJson(Json::Value& result, 129 void LuaFunctionCall::ExecuteToJson(Json::Value& result)
130 lua_State* lua,
131 int top)
132 { 130 {
133 if (lua_istable(lua, top)) 131 ExecuteInternal(1);
132 context_.GetJson(result, lua_gettop(context_.lua_));
133 }
134
135
136 void LuaFunctionCall::ExecuteToString(std::string& result)
137 {
138 ExecuteInternal(1);
139
140 int top = lua_gettop(context_.lua_);
141 if (lua_isstring(context_.lua_, top))
134 { 142 {
135 Json::Value tmp = Json::objectValue; 143 result = lua_tostring(context_.lua_, top);
136 bool isArray = true;
137 size_t size = 0;
138
139 // http://stackoverflow.com/a/6142700/881731
140
141 // Push another reference to the table on top of the stack (so we know
142 // where it is, and this function can work for negative, positive and
143 // pseudo indices
144 lua_pushvalue(lua, top);
145 // stack now contains: -1 => table
146 lua_pushnil(lua);
147 // stack now contains: -1 => nil; -2 => table
148 while (lua_next(lua, -2))
149 {
150 // stack now contains: -1 => value; -2 => key; -3 => table
151 // copy the key so that lua_tostring does not modify the original
152 lua_pushvalue(lua, -2);
153 // stack now contains: -1 => key; -2 => value; -3 => key; -4 => table
154 std::string key(lua_tostring(lua, -1));
155 Json::Value v;
156 PopJson(v, lua, -2);
157
158 tmp[key] = v;
159
160 size += 1;
161 try
162 {
163 if (boost::lexical_cast<size_t>(key) != size)
164 {
165 isArray = false;
166 }
167 }
168 catch (boost::bad_lexical_cast&)
169 {
170 isArray = false;
171 }
172
173 // pop value + copy of key, leaving original key
174 lua_pop(lua, 2);
175 // stack now contains: -1 => key; -2 => table
176 }
177 // stack now contains: -1 => table (when lua_next returns 0 it pops the key
178 // but does not push anything.)
179 // Pop table
180 lua_pop(lua, 1);
181
182 // Stack is now the same as it was on entry to this function
183
184 if (isArray)
185 {
186 result = Json::arrayValue;
187 for (size_t i = 0; i < size; i++)
188 {
189 result.append(tmp[boost::lexical_cast<std::string>(i + 1)]);
190 }
191 }
192 else
193 {
194 result = tmp;
195 }
196 }
197 else if (lua_isnumber(lua, top))
198 {
199 result = static_cast<float>(lua_tonumber(lua, top));
200 }
201 else if (lua_isstring(lua, top))
202 {
203 result = std::string(lua_tostring(lua, top));
204 }
205 else if (lua_isboolean(lua, top))
206 {
207 result = static_cast<bool>(lua_toboolean(lua, top));
208 } 144 }
209 else 145 else
210 { 146 {
211 LOG(WARNING) << "Unsupported Lua type when returning Json"; 147 throw LuaException("The function does not return a string");
212 result = Json::nullValue;
213 } 148 }
214 } 149 }
215
216
217 void LuaFunctionCall::ExecuteToJson(Json::Value& result)
218 {
219 ExecuteInternal(1);
220 PopJson(result, context_.lua_, lua_gettop(context_.lua_));
221 }
222 } 150 }