Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better support for SAX style serialize and deserialize in new version? #554

Closed
salutant opened this issue Apr 15, 2017 · 10 comments
Closed

Comments

@salutant
Copy link

it is very useful to do a language binding , Currently we need iterate the object to create a temp cpp json object before serizalize to string .

@nlohmann
Copy link
Owner

Can you be more specific?

@salutant
Copy link
Author

salutant commented Apr 15, 2017

if i want to use this to create a json serializer and deserializer for other language like lua.
in lua to serialize a lua table to string , i need to do iterate lua table to create a temp cpp json object first, then use it's dump() method to string.

rapidjson give a rapidjson::Writer class . with this we can serialize a lua table to string directly in iterating lua table.

https://github.com/xpol/lua-rapidjson this project create a lua json serializer and deserializer use rapidjson maybe can help you .

@nlohmann
Copy link
Owner

The link is dead. I still don't understand your use case.

You want to iterate over a Lua table and create a JSON serialization from it? But you want to do this without creating an internal JSON representation from the Lua table?

@salutant
Copy link
Author

sorry , the link is okay now,
i want to explain my idea clearly, but i think i couldn't, so i write some code

class lua_json_writer
{
public:
	lua_json_writer(lua_State * l, int idx)
		: L(l), index_(idx), writer_(buffer_)
	{}
	~lua_json_writer()
	{}

	const char * encode()
	{
		encode_table(index_);
		return buffer_.GetString();
	}

private:
	void encode_value(int val)
	{
		int t = lua_type(L, val);
		if ( t == LUA_TSTRING ) {
			size_t len = 0;
			const char * str = lua_tolstring(L, val, &len);
			writer_.String(str, len);
		} else if ( t == LUA_TNUMBER ) {
			if ( lua_isinteger(L, val) ) {
				writer_.Int64(lua_tointeger(L, val));
			} else {
				writer_.Double(lua_tonumber(L, val));
			}
		} else if ( t == LUA_TBOOLEAN ) {
			writer_.Bool(!!lua_toboolean(L, val));
		} else if ( t == LUA_TTABLE ) {
			encode_table(val);
		}
	}

	void encode_object(int key, int val)
	{
		const char * key_str = lua_tostring(L, key);
		if ( strcmp(key_str, "__type") == 0 ) {
			return;
		}
		writer_.Key(key_str);
		encode_value(val);
	}

	void encode_array(int key, int val)
	{
		if ( lua_type(L, key) != LUA_TNUMBER ) {
			return;
		}

		encode_value(val);
	}

	void for_each(std::function<void(lua_json_writer&, int, int)> fx)
	{
		for ( lua_pushnil(L); lua_next(L, -2) != 0; lua_pop(L, 1) ) {

			int top = lua_gettop(L);
			fx(*this, top - 1, top);
		}
	}

	void encode_table(int idx)
	{
		int t = 1; //
		lua_getfield(L, idx, "__type");
		if ( !lua_isnil(L, -1) ) {
			t = static_cast<int>(lua_tointeger(L, -1));
		}
		lua_pop(L, 1);

		if ( t == 1 ) {
			writer_.StartObject();
			for_each(&lua_json_writer::encode_object);
			writer_.EndObject();
		} else if ( t == 2 ) {
			writer_.StartArray();
			for_each(&lua_json_writer::encode_array);
			writer_.EndArray();
		} else if ( t == 3 ) {
			writer_.Null();
		}
	}

private:
	lua_State * L;
	int	index_;
	rapidjson::StringBuffer buffer_; //
	rapidjson::Writer<rapidjson::StringBuffer, rapidjson::UTF8<>, rapidjson::ASCII<>> writer_; //
};

this code can serialize a lua table to json string , i want json.hpp can do something like this .

@nlohmann
Copy link
Owner

You can convert arbitrary types from/to json with the techniques described in https://github.com/nlohmann/json#arbitrary-types-conversions. But if I understand you correctly, you do not want to create a json object, but directly a JSON compliant string representation from you Lua array, right?

@salutant
Copy link
Author

yes i don't want to create json object

@nlohmann
Copy link
Owner

But how would this library help you if you do not want to use any of its functions?

@salutant
Copy link
Author

alright , the rapidjson given rapidjson::Reader and rapidjson::Writer could do this .
cos i like this library so i want to do it use this . if couldn't i'll give up .
thanks!

@nlohmann
Copy link
Owner

I do not understand how exactly my library could help you. We provide a C++-style API for JSON values, support to create these values from arbitrary types, and also the possibility to serialize them. But it seems that you need a translation from Lua types to JSON string. This can be implemented manually without the need of any third-party library.

And why exactly don't you want to create an temporary object in the first place? Performance?

@nlohmann
Copy link
Owner

FYI: #971

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants