1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2024-11-08 00:37:15 +01:00

Basic hooking into json parsing.

Also allow customization of the fallback meta-method.
This commit is contained in:
Sandu Liviu Catalin 2022-10-02 21:24:12 +03:00
parent a788e059a5
commit ec7f1183d8
2 changed files with 94 additions and 3 deletions

View File

@ -2,6 +2,7 @@
#include "Library/JSON.hpp" #include "Library/JSON.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#include <sajson.h>
#include <sqratConst.h> #include <sqratConst.h>
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -180,6 +181,23 @@ CtxJSON & CtxJSON::CloseArray()
return *this; return *this;
} }
// ------------------------------------------------------------------------------------------------
CtxJSON & CtxJSON::ReopenArray()
{
// If the last character is a comma then remove it
if (mOutput.back() == ',')
{
mOutput.pop_back();
}
// If the last character is the array-end character then replace it with a comma
if (mOutput.back() == ']')
{
mOutput.back() = ',';
}
// Allow chaining
return *this;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
CtxJSON & CtxJSON::OpenObject() CtxJSON & CtxJSON::OpenObject()
{ {
@ -212,6 +230,23 @@ CtxJSON & CtxJSON::CloseObject()
return *this; return *this;
} }
// ------------------------------------------------------------------------------------------------
CtxJSON & CtxJSON::ReopenObject()
{
// If the last character is a comma then remove it
if (mOutput.back() == ',')
{
mOutput.pop_back();
}
// If the last character is the object-end character then replace it with a comma
if (mOutput.back() == '}')
{
mOutput.back() = ',';
}
// Allow chaining
return *this;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
CtxJSON & CtxJSON::MakeKey() CtxJSON & CtxJSON::MakeKey()
{ {
@ -225,6 +260,11 @@ CtxJSON & CtxJSON::MakeKey()
{ {
mOutput.push_back(':'); mOutput.push_back(':');
} }
// Allow the hook to react
if (mKeyHook)
{
mKeyHook(*this);
}
// Allow chaining // Allow chaining
return *this; return *this;
} }
@ -467,7 +507,7 @@ SQRESULT CtxJSON::SerializeTable(HSQUIRRELVM vm, SQInteger idx) // NOLINT(misc-n
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
SQRESULT CtxJSON::SerializeInstance(HSQUIRRELVM vm, SQInteger idx) SQRESULT CtxJSON::SerializeInstance(HSQUIRRELVM vm, SQInteger idx)
{ {
sq_pushstring(vm, _SC("_tojson"), 7); sq_pushstring(vm, mMetaMethod.c_str(), static_cast< SQInteger >(mMetaMethod.size()));
// Attempt to retrieve the meta-method from the instance // Attempt to retrieve the meta-method from the instance
if(SQRESULT r = sq_get(vm, idx); SQ_FAILED(r)) if(SQRESULT r = sq_get(vm, idx); SQ_FAILED(r))
{ {
@ -629,6 +669,8 @@ void CtxJSON::PushString(const SQChar * str)
mOutput.append(str); mOutput.append(str);
mOutput.push_back('"'); mOutput.push_back('"');
mOutput.push_back(','); mOutput.push_back(',');
// Allow the hook to know
mString.assign(str);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -638,6 +680,8 @@ void CtxJSON::PushString(const SQChar * str, size_t length)
mOutput.append(str, length); mOutput.append(str, length);
mOutput.push_back('"'); mOutput.push_back('"');
mOutput.push_back(','); mOutput.push_back(',');
// Allow the hook to know
mString.assign(str, length);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -678,6 +722,7 @@ void Register_JSON(HSQUIRRELVM vm)
// Constructors // Constructors
.Ctor() .Ctor()
.Ctor< bool >() .Ctor< bool >()
.Ctor< bool, StackStrF & >()
// Meta-methods // Meta-methods
.SquirrelFunc(_SC("_typename"), &SqCtxJSON::Fn) .SquirrelFunc(_SC("_typename"), &SqCtxJSON::Fn)
// Properties // Properties

View File

@ -5,12 +5,13 @@
#include "Library/IO/Buffer.hpp" #include "Library/IO/Buffer.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#include <sajson.h> #include <functional>
// ------------------------------------------------------------------------------------------------
#include <fmt/args.h> #include <fmt/args.h>
#include <fmt/format.h> #include <fmt/format.h>
#include <fmt/xchar.h> #include <fmt/xchar.h>
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
namespace SqMod { namespace SqMod {
@ -35,6 +36,21 @@ struct CtxJSON
*/ */
uint32_t mDepth{0}; uint32_t mDepth{0};
/* --------------------------------------------------------------------------------------------
* The meta-method name to use on objects.
*/
String mMetaMethod{"_tojson"};
/* --------------------------------------------------------------------------------------------
* Last pushed string value. Can be used to heck for key name in the hook.
*/
String mString{};
/* --------------------------------------------------------------------------------------------
* Internal utility used to monitor the existence of certain keys to allow overloading.
*/
std::function< void(CtxJSON&) > mKeyHook{};
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Default constructor. * Default constructor.
*/ */
@ -49,6 +65,26 @@ struct CtxJSON
mObjectOverArray = ooa; mObjectOverArray = ooa;
} }
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
CtxJSON(bool ooa, StackStrF & mmname) noexcept
: CtxJSON()
{
mObjectOverArray = ooa;
// Allow custom metamethod names
mMetaMethod.assign(mmname.mPtr, static_cast< size_t >(mmname.mLen));
}
/* --------------------------------------------------------------------------------------------
* Internal constructor.
*/
explicit CtxJSON(std::function< void(CtxJSON&) > && kh) noexcept
: CtxJSON()
{
mKeyHook = std::move(kh);
}
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Copy constructor. * Copy constructor.
*/ */
@ -135,6 +171,11 @@ struct CtxJSON
*/ */
CtxJSON & CloseArray(); CtxJSON & CloseArray();
/* --------------------------------------------------------------------------------------------
* Resume writing an array.
*/
CtxJSON & ReopenArray();
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Begin writing an object. * Begin writing an object.
*/ */
@ -145,6 +186,11 @@ struct CtxJSON
*/ */
CtxJSON & CloseObject(); CtxJSON & CloseObject();
/* --------------------------------------------------------------------------------------------
* Resume writing an object.
*/
CtxJSON & ReopenObject();
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Begin writing a key value. * Begin writing a key value.
*/ */