sgVar 从 lua 读取数据

前一篇 《 sgVar – a json parser/generator and var lib for c++ 》 介绍了 sgVar 以及从 json 中解析数据,这篇讲下从 lua 中获取数据的方法。

下面的函数就是从 lua 的一个 table 中取得所有的值存入到 variant 中。代码也演示了如何在 C++ 中遍历 lua 的一个 table 并且获取其中的数据。

由于 sgVar 和 lua 的 table 并不完全对等,所以我的策略上,先判断 tabel 的长度是不是大于 0,若是的话,就认为是数组,否则认为是 map 。
另外,在使用中还遇到其他的情况,比如我要把 sgVar 序列化到 as3 中,有时候即使一个 table 内容是空的(t = {}),但是在 as3 中需要被当作 Array 来处理,那么也应该把该 table 作为数组。所以我加了个规则,若 t[0] == true ,则判断该 table 为数组。

void LuaTable2SGVar( lua_State* L, int tableIndex, sgVar &variant )
{
	if(!lua_istable(L, tableIndex))
		return ;

	bool isArray = false;
	size_t tableLen = lua_objlen(L, tableIndex);
	if(tableLen > 0)
	{
		isArray = true;
	}
	else
	{
		// if t[0] == true
		// treat the table as array
		lua_pushinteger(L, 0);
		lua_gettable(L, tableIndex);
		if(lua_isboolean(L, -1) && (lua_toboolean(L, -1) != 0) )
		{
			isArray = true;
		}
		lua_pop(L, 1);
	}

	if(isArray)
	{
		// array
		variant.MakeArray(tableLen);

		for(int i=1; i<=tableLen; ++i)
		{
			lua_pushinteger(L, i);
			lua_gettable(L, tableIndex);

			sgVar val;
			switch(lua_type(L, -1))
			{
			case LUA_TBOOLEAN:
				{
					val = lua_toboolean(L, -1) != 0;
					break;
				}

			case LUA_TNUMBER:
				{
					val = lua_tonumber(L, -1);
					break;
				}

			case LUA_TSTRING:
				{
					val = lua_tostring(L, -1);
					break;
				}

			case LUA_TNIL:
				{
					break;
				}

			case LUA_TTABLE:
				{
					// now the table is on the top of the stack
					// so the positive index is lua_gettop
					LuaTable2SGVar(L, lua_gettop(L), val);
					break;
				}
			}
			variant[i-1] = val;
			lua_pop(L, 1);
		}
	}
	else
	{
		// map
		variant.MakeMap();

		lua_pushnil(L);  // first key
		while(lua_next(L, tableIndex) != 0) {
			// uses 'key' (at index -2) and 'value' (at index -1) 
			sgVar val;
			if(lua_isstring(L, -2) != 0)
			{
				const char *key = lua_tostring(L, -2);

				switch(lua_type(L, -1))
				{
				case LUA_TBOOLEAN:
					{
						val = lua_toboolean(L, -1) != 0;
						break;
					}

				case LUA_TNUMBER:
					{
						val = lua_tonumber(L, -1);
						break;
					}

				case LUA_TSTRING:
					{
						val = lua_tostring(L, -1);
						break;
					}

				case LUA_TNIL:
					{
						break;
					}

				case LUA_TTABLE:
					{
						// now the table is on the top of the stack
						// so the positive index is lua_gettop
						LuaTable2SGVar(L, lua_gettop(L), val);
						break;
					}
				}
				variant[key] = val;
			}
			// removes 'value'; keeps 'key' for next iteration 
			lua_pop(L, 1);
		}

		//lua_pop(L, 1);	// the last lua_next will pop the key left in the stack but not push new key-value into it
	}
}


发表评论?

0 条评论。

发表评论