mirror of
https://github.com/alliedmodders/sourcemod.git
synced 2025-12-06 18:08:36 +00:00
Introduction JSON extension
This commit is contained in:
parent
e4fda1bd78
commit
574423abee
@ -678,6 +678,7 @@ else:
|
|||||||
'extensions/tf2/AMBuilder',
|
'extensions/tf2/AMBuilder',
|
||||||
'extensions/topmenus/AMBuilder',
|
'extensions/topmenus/AMBuilder',
|
||||||
'extensions/updater/AMBuilder',
|
'extensions/updater/AMBuilder',
|
||||||
|
'extensions/yyjson/AMBuilder',
|
||||||
]
|
]
|
||||||
|
|
||||||
if builder.backend == 'amb2':
|
if builder.backend == 'amb2':
|
||||||
|
|||||||
28
extensions/yyjson/AMBuilder
Executable file
28
extensions/yyjson/AMBuilder
Executable file
@ -0,0 +1,28 @@
|
|||||||
|
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
|
||||||
|
import os
|
||||||
|
|
||||||
|
for cxx in builder.targets:
|
||||||
|
binary = SM.ExtLibrary(builder, cxx, 'yyjson.ext')
|
||||||
|
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
|
||||||
|
binary.compiler.cxxflags += ['-fno-rtti']
|
||||||
|
binary.compiler.cflags += ['-fPIC']
|
||||||
|
elif binary.compiler.family == 'msvc':
|
||||||
|
binary.compiler.cxxflags += ['/GR-']
|
||||||
|
|
||||||
|
binary.compiler.defines += [
|
||||||
|
'YYJSON_DISABLE_INCR_READER',
|
||||||
|
]
|
||||||
|
|
||||||
|
binary.compiler.cxxincludes += [
|
||||||
|
os.path.join(builder.sourcePath, 'extensions', 'yyjson', 'yyjson'),
|
||||||
|
]
|
||||||
|
|
||||||
|
binary.sources += [
|
||||||
|
'extension.cpp',
|
||||||
|
'YYJSONManager.cpp',
|
||||||
|
'json_natives.cpp',
|
||||||
|
'yyjson/yyjson.c',
|
||||||
|
'../../public/smsdk_ext.cpp',
|
||||||
|
]
|
||||||
|
|
||||||
|
SM.extensions += [builder.Add(binary)]
|
||||||
1339
extensions/yyjson/IYYJSONManager.h
Executable file
1339
extensions/yyjson/IYYJSONManager.h
Executable file
File diff suppressed because it is too large
Load Diff
3651
extensions/yyjson/YYJSONManager.cpp
Executable file
3651
extensions/yyjson/YYJSONManager.cpp
Executable file
File diff suppressed because it is too large
Load Diff
264
extensions/yyjson/YYJSONManager.h
Executable file
264
extensions/yyjson/YYJSONManager.h
Executable file
@ -0,0 +1,264 @@
|
|||||||
|
#ifndef _INCLUDE_SM_YYJSON_YYJSONMANAGER_H_
|
||||||
|
#define _INCLUDE_SM_YYJSON_YYJSONMANAGER_H_
|
||||||
|
|
||||||
|
#include <IYYJSONManager.h>
|
||||||
|
#include <yyjson.h>
|
||||||
|
#include <IHandleSys.h>
|
||||||
|
#include <random>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief JSON value wrapper
|
||||||
|
*
|
||||||
|
* Wraps yyjson mutable/immutable documents and values.
|
||||||
|
* Used as the primary data type for JSON operations.
|
||||||
|
*/
|
||||||
|
class YYJSONValue {
|
||||||
|
public:
|
||||||
|
YYJSONValue() = default;
|
||||||
|
~YYJSONValue() {
|
||||||
|
if (m_pDocument_mut.unique()) {
|
||||||
|
yyjson_mut_doc_free(m_pDocument_mut.get());
|
||||||
|
}
|
||||||
|
if (m_pDocument.unique()) {
|
||||||
|
yyjson_doc_free(m_pDocument.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
YYJSONValue(const YYJSONValue&) = delete;
|
||||||
|
YYJSONValue& operator=(const YYJSONValue&) = delete;
|
||||||
|
|
||||||
|
void ResetObjectIterator() {
|
||||||
|
m_iterInitialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResetArrayIterator() {
|
||||||
|
m_iterInitialized = false;
|
||||||
|
m_arrayIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsMutable() const {
|
||||||
|
return m_pDocument_mut != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsImmutable() const {
|
||||||
|
return m_pDocument != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mutable document
|
||||||
|
std::shared_ptr<yyjson_mut_doc> m_pDocument_mut;
|
||||||
|
yyjson_mut_val* m_pVal_mut{ nullptr };
|
||||||
|
|
||||||
|
// Immutable document
|
||||||
|
std::shared_ptr<yyjson_doc> m_pDocument;
|
||||||
|
yyjson_val* m_pVal{ nullptr };
|
||||||
|
|
||||||
|
// Mutable document iterators
|
||||||
|
yyjson_mut_obj_iter m_iterObj;
|
||||||
|
yyjson_mut_arr_iter m_iterArr;
|
||||||
|
|
||||||
|
// Immutable document iterators
|
||||||
|
yyjson_obj_iter m_iterObjImm;
|
||||||
|
yyjson_arr_iter m_iterArrImm;
|
||||||
|
|
||||||
|
SourceMod::Handle_t m_handle{ BAD_HANDLE };
|
||||||
|
size_t m_arrayIndex{ 0 };
|
||||||
|
size_t m_readSize{ 0 };
|
||||||
|
bool m_iterInitialized{ false };
|
||||||
|
};
|
||||||
|
|
||||||
|
class YYJSONManager : public IYYJSONManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
YYJSONManager();
|
||||||
|
~YYJSONManager();
|
||||||
|
|
||||||
|
public:
|
||||||
|
// ========== Document Operations ==========
|
||||||
|
virtual YYJSONValue* ParseJSON(const char* json_str, bool is_file, bool is_mutable,
|
||||||
|
yyjson_read_flag read_flg, char* error, size_t error_size) override;
|
||||||
|
virtual bool WriteToString(YYJSONValue* handle, char* buffer, size_t buffer_size,
|
||||||
|
yyjson_write_flag write_flg, size_t* out_size) override;
|
||||||
|
virtual bool WriteToFile(YYJSONValue* handle, const char* path, yyjson_write_flag write_flg,
|
||||||
|
char* error, size_t error_size) override;
|
||||||
|
virtual bool Equals(YYJSONValue* handle1, YYJSONValue* handle2) override;
|
||||||
|
virtual YYJSONValue* DeepCopy(YYJSONValue* targetDoc, YYJSONValue* sourceValue) override;
|
||||||
|
virtual const char* GetTypeDesc(YYJSONValue* handle) override;
|
||||||
|
virtual size_t GetSerializedSize(YYJSONValue* handle, yyjson_write_flag write_flg) override;
|
||||||
|
virtual YYJSONValue* ToMutable(YYJSONValue* handle) override;
|
||||||
|
virtual YYJSONValue* ToImmutable(YYJSONValue* handle) override;
|
||||||
|
virtual yyjson_type GetType(YYJSONValue* handle) override;
|
||||||
|
virtual yyjson_subtype GetSubtype(YYJSONValue* handle) override;
|
||||||
|
virtual bool IsArray(YYJSONValue* handle) override;
|
||||||
|
virtual bool IsObject(YYJSONValue* handle) override;
|
||||||
|
virtual bool IsInt(YYJSONValue* handle) override;
|
||||||
|
virtual bool IsUint(YYJSONValue* handle) override;
|
||||||
|
virtual bool IsSint(YYJSONValue* handle) override;
|
||||||
|
virtual bool IsNum(YYJSONValue* handle) override;
|
||||||
|
virtual bool IsBool(YYJSONValue* handle) override;
|
||||||
|
virtual bool IsTrue(YYJSONValue* handle) override;
|
||||||
|
virtual bool IsFalse(YYJSONValue* handle) override;
|
||||||
|
virtual bool IsFloat(YYJSONValue* handle) override;
|
||||||
|
virtual bool IsStr(YYJSONValue* handle) override;
|
||||||
|
virtual bool IsNull(YYJSONValue* handle) override;
|
||||||
|
virtual bool IsCtn(YYJSONValue* handle) override;
|
||||||
|
virtual bool IsMutable(YYJSONValue* handle) override;
|
||||||
|
virtual bool IsImmutable(YYJSONValue* handle) override;
|
||||||
|
virtual size_t GetReadSize(YYJSONValue* handle) override;
|
||||||
|
|
||||||
|
// ========== Object Operations ==========
|
||||||
|
virtual YYJSONValue* ObjectInit() override;
|
||||||
|
virtual YYJSONValue* ObjectInitWithStrings(const char** pairs, size_t count) override;
|
||||||
|
virtual YYJSONValue* ObjectParseString(const char* str, yyjson_read_flag read_flg,
|
||||||
|
char* error, size_t error_size) override;
|
||||||
|
virtual YYJSONValue* ObjectParseFile(const char* path, yyjson_read_flag read_flg,
|
||||||
|
char* error, size_t error_size) override;
|
||||||
|
virtual size_t ObjectGetSize(YYJSONValue* handle) override;
|
||||||
|
virtual bool ObjectGetKey(YYJSONValue* handle, size_t index, const char** out_key) override;
|
||||||
|
virtual YYJSONValue* ObjectGetValueAt(YYJSONValue* handle, size_t index) override;
|
||||||
|
virtual YYJSONValue* ObjectGet(YYJSONValue* handle, const char* key) override;
|
||||||
|
virtual bool ObjectGetBool(YYJSONValue* handle, const char* key, bool* out_value) override;
|
||||||
|
virtual bool ObjectGetFloat(YYJSONValue* handle, const char* key, double* out_value) override;
|
||||||
|
virtual bool ObjectGetInt(YYJSONValue* handle, const char* key, int* out_value) override;
|
||||||
|
virtual bool ObjectGetInt64(YYJSONValue* handle, const char* key, int64_t* out_value) override;
|
||||||
|
virtual bool ObjectGetString(YYJSONValue* handle, const char* key, const char** out_str, size_t* out_len) override;
|
||||||
|
virtual bool ObjectIsNull(YYJSONValue* handle, const char* key, bool* out_is_null) override;
|
||||||
|
virtual bool ObjectHasKey(YYJSONValue* handle, const char* key, bool use_pointer) override;
|
||||||
|
virtual bool ObjectRenameKey(YYJSONValue* handle, const char* old_key, const char* new_key, bool allow_duplicate) override;
|
||||||
|
virtual bool ObjectSet(YYJSONValue* handle, const char* key, YYJSONValue* value) override;
|
||||||
|
virtual bool ObjectSetBool(YYJSONValue* handle, const char* key, bool value) override;
|
||||||
|
virtual bool ObjectSetFloat(YYJSONValue* handle, const char* key, double value) override;
|
||||||
|
virtual bool ObjectSetInt(YYJSONValue* handle, const char* key, int value) override;
|
||||||
|
virtual bool ObjectSetInt64(YYJSONValue* handle, const char* key, int64_t value) override;
|
||||||
|
virtual bool ObjectSetNull(YYJSONValue* handle, const char* key) override;
|
||||||
|
virtual bool ObjectSetString(YYJSONValue* handle, const char* key, const char* value) override;
|
||||||
|
virtual bool ObjectRemove(YYJSONValue* handle, const char* key) override;
|
||||||
|
virtual bool ObjectClear(YYJSONValue* handle) override;
|
||||||
|
virtual bool ObjectSort(YYJSONValue* handle, YYJSON_SORT_ORDER sort_mode) override;
|
||||||
|
|
||||||
|
// ========== Array Operations ==========
|
||||||
|
virtual YYJSONValue* ArrayInit() override;
|
||||||
|
virtual YYJSONValue* ArrayInitWithStrings(const char** strings, size_t count) override;
|
||||||
|
virtual YYJSONValue* ArrayParseString(const char* str, yyjson_read_flag read_flg,
|
||||||
|
char* error, size_t error_size) override;
|
||||||
|
virtual YYJSONValue* ArrayParseFile(const char* path, yyjson_read_flag read_flg,
|
||||||
|
char* error, size_t error_size) override;
|
||||||
|
virtual size_t ArrayGetSize(YYJSONValue* handle) override;
|
||||||
|
virtual YYJSONValue* ArrayGet(YYJSONValue* handle, size_t index) override;
|
||||||
|
virtual YYJSONValue* ArrayGetFirst(YYJSONValue* handle) override;
|
||||||
|
virtual YYJSONValue* ArrayGetLast(YYJSONValue* handle) override;
|
||||||
|
virtual bool ArrayGetBool(YYJSONValue* handle, size_t index, bool* out_value) override;
|
||||||
|
virtual bool ArrayGetFloat(YYJSONValue* handle, size_t index, double* out_value) override;
|
||||||
|
virtual bool ArrayGetInt(YYJSONValue* handle, size_t index, int* out_value) override;
|
||||||
|
virtual bool ArrayGetInt64(YYJSONValue* handle, size_t index, int64_t* out_value) override;
|
||||||
|
virtual bool ArrayGetString(YYJSONValue* handle, size_t index, const char** out_str, size_t* out_len) override;
|
||||||
|
virtual bool ArrayIsNull(YYJSONValue* handle, size_t index) override;
|
||||||
|
virtual bool ArrayReplace(YYJSONValue* handle, size_t index, YYJSONValue* value) override;
|
||||||
|
virtual bool ArrayReplaceBool(YYJSONValue* handle, size_t index, bool value) override;
|
||||||
|
virtual bool ArrayReplaceFloat(YYJSONValue* handle, size_t index, double value) override;
|
||||||
|
virtual bool ArrayReplaceInt(YYJSONValue* handle, size_t index, int value) override;
|
||||||
|
virtual bool ArrayReplaceInt64(YYJSONValue* handle, size_t index, int64_t value) override;
|
||||||
|
virtual bool ArrayReplaceNull(YYJSONValue* handle, size_t index) override;
|
||||||
|
virtual bool ArrayReplaceString(YYJSONValue* handle, size_t index, const char* value) override;
|
||||||
|
virtual bool ArrayAppend(YYJSONValue* handle, YYJSONValue* value) override;
|
||||||
|
virtual bool ArrayAppendBool(YYJSONValue* handle, bool value) override;
|
||||||
|
virtual bool ArrayAppendFloat(YYJSONValue* handle, double value) override;
|
||||||
|
virtual bool ArrayAppendInt(YYJSONValue* handle, int value) override;
|
||||||
|
virtual bool ArrayAppendInt64(YYJSONValue* handle, int64_t value) override;
|
||||||
|
virtual bool ArrayAppendNull(YYJSONValue* handle) override;
|
||||||
|
virtual bool ArrayAppendString(YYJSONValue* handle, const char* value) override;
|
||||||
|
virtual bool ArrayRemove(YYJSONValue* handle, size_t index) override;
|
||||||
|
virtual bool ArrayRemoveFirst(YYJSONValue* handle) override;
|
||||||
|
virtual bool ArrayRemoveLast(YYJSONValue* handle) override;
|
||||||
|
virtual bool ArrayRemoveRange(YYJSONValue* handle, size_t start_index, size_t end_index) override;
|
||||||
|
virtual bool ArrayClear(YYJSONValue* handle) override;
|
||||||
|
virtual int ArrayIndexOfBool(YYJSONValue* handle, bool search_value) override;
|
||||||
|
virtual int ArrayIndexOfString(YYJSONValue* handle, const char* search_value) override;
|
||||||
|
virtual int ArrayIndexOfInt(YYJSONValue* handle, int search_value) override;
|
||||||
|
virtual int ArrayIndexOfInt64(YYJSONValue* handle, int64_t search_value) override;
|
||||||
|
virtual int ArrayIndexOfFloat(YYJSONValue* handle, double search_value) override;
|
||||||
|
virtual bool ArraySort(YYJSONValue* handle, YYJSON_SORT_ORDER sort_mode) override;
|
||||||
|
|
||||||
|
// ========== Value Operations ==========
|
||||||
|
virtual YYJSONValue* Pack(const char* format, IPackParamProvider* param_provider, char* error, size_t error_size) override;
|
||||||
|
virtual YYJSONValue* CreateBool(bool value) override;
|
||||||
|
virtual YYJSONValue* CreateFloat(double value) override;
|
||||||
|
virtual YYJSONValue* CreateInt(int value) override;
|
||||||
|
virtual YYJSONValue* CreateInt64(int64_t value) override;
|
||||||
|
virtual YYJSONValue* CreateNull() override;
|
||||||
|
virtual YYJSONValue* CreateString(const char* value) override;
|
||||||
|
virtual bool GetBool(YYJSONValue* handle, bool* out_value) override;
|
||||||
|
virtual bool GetFloat(YYJSONValue* handle, double* out_value) override;
|
||||||
|
virtual bool GetInt(YYJSONValue* handle, int* out_value) override;
|
||||||
|
virtual bool GetInt64(YYJSONValue* handle, int64_t* out_value) override;
|
||||||
|
virtual bool GetString(YYJSONValue* handle, const char** out_str, size_t* out_len) override;
|
||||||
|
|
||||||
|
// ========== Pointer Operations ==========
|
||||||
|
virtual YYJSONValue* PtrGet(YYJSONValue* handle, const char* path, char* error, size_t error_size) override;
|
||||||
|
virtual bool PtrGetBool(YYJSONValue* handle, const char* path, bool* out_value, char* error, size_t error_size) override;
|
||||||
|
virtual bool PtrGetFloat(YYJSONValue* handle, const char* path, double* out_value, char* error, size_t error_size) override;
|
||||||
|
virtual bool PtrGetInt(YYJSONValue* handle, const char* path, int* out_value, char* error, size_t error_size) override;
|
||||||
|
virtual bool PtrGetInt64(YYJSONValue* handle, const char* path, int64_t* out_value, char* error, size_t error_size) override;
|
||||||
|
virtual bool PtrGetString(YYJSONValue* handle, const char* path, const char** out_str, size_t* out_len, char* error, size_t error_size) override;
|
||||||
|
virtual bool PtrGetIsNull(YYJSONValue* handle, const char* path, bool* out_is_null, char* error, size_t error_size) override;
|
||||||
|
virtual bool PtrGetLength(YYJSONValue* handle, const char* path, size_t* out_len, char* error, size_t error_size) override;
|
||||||
|
virtual bool PtrSet(YYJSONValue* handle, const char* path, YYJSONValue* value, char* error, size_t error_size) override;
|
||||||
|
virtual bool PtrSetBool(YYJSONValue* handle, const char* path, bool value, char* error, size_t error_size) override;
|
||||||
|
virtual bool PtrSetFloat(YYJSONValue* handle, const char* path, double value, char* error, size_t error_size) override;
|
||||||
|
virtual bool PtrSetInt(YYJSONValue* handle, const char* path, int value, char* error, size_t error_size) override;
|
||||||
|
virtual bool PtrSetInt64(YYJSONValue* handle, const char* path, int64_t value, char* error, size_t error_size) override;
|
||||||
|
virtual bool PtrSetString(YYJSONValue* handle, const char* path, const char* value, char* error, size_t error_size) override;
|
||||||
|
virtual bool PtrSetNull(YYJSONValue* handle, const char* path, char* error, size_t error_size) override;
|
||||||
|
virtual bool PtrAdd(YYJSONValue* handle, const char* path, YYJSONValue* value, char* error, size_t error_size) override;
|
||||||
|
virtual bool PtrAddBool(YYJSONValue* handle, const char* path, bool value, char* error, size_t error_size) override;
|
||||||
|
virtual bool PtrAddFloat(YYJSONValue* handle, const char* path, double value, char* error, size_t error_size) override;
|
||||||
|
virtual bool PtrAddInt(YYJSONValue* handle, const char* path, int value, char* error, size_t error_size) override;
|
||||||
|
virtual bool PtrAddInt64(YYJSONValue* handle, const char* path, int64_t value, char* error, size_t error_size) override;
|
||||||
|
virtual bool PtrAddString(YYJSONValue* handle, const char* path, const char* value, char* error, size_t error_size) override;
|
||||||
|
virtual bool PtrAddNull(YYJSONValue* handle, const char* path, char* error, size_t error_size) override;
|
||||||
|
virtual bool PtrRemove(YYJSONValue* handle, const char* path, char* error, size_t error_size) override;
|
||||||
|
virtual YYJSONValue* PtrTryGet(YYJSONValue* handle, const char* path) override;
|
||||||
|
virtual bool PtrTryGetBool(YYJSONValue* handle, const char* path, bool* out_value) override;
|
||||||
|
virtual bool PtrTryGetFloat(YYJSONValue* handle, const char* path, double* out_value) override;
|
||||||
|
virtual bool PtrTryGetInt(YYJSONValue* handle, const char* path, int* out_value) override;
|
||||||
|
virtual bool PtrTryGetInt64(YYJSONValue* handle, const char* path, int64_t* out_value) override;
|
||||||
|
virtual bool PtrTryGetString(YYJSONValue* handle, const char* path, const char** out_str, size_t* out_len) override;
|
||||||
|
|
||||||
|
// ========== Iterator Operations ==========
|
||||||
|
virtual bool ObjectForeachNext(YYJSONValue* handle, const char** out_key,
|
||||||
|
size_t* out_key_len, YYJSONValue** out_value) override;
|
||||||
|
virtual bool ArrayForeachNext(YYJSONValue* handle, size_t* out_index,
|
||||||
|
YYJSONValue** out_value) override;
|
||||||
|
virtual bool ObjectForeachKeyNext(YYJSONValue* handle, const char** out_key,
|
||||||
|
size_t* out_key_len) override;
|
||||||
|
virtual bool ArrayForeachIndexNext(YYJSONValue* handle, size_t* out_index) override;
|
||||||
|
|
||||||
|
// ========== Release Operations ==========
|
||||||
|
virtual void Release(YYJSONValue* value) override;
|
||||||
|
|
||||||
|
// ========== Handle Type Operations ==========
|
||||||
|
virtual HandleType_t GetHandleType() override;
|
||||||
|
|
||||||
|
// ========== Handle Operations ==========
|
||||||
|
virtual YYJSONValue* GetFromHandle(IPluginContext* pContext, Handle_t handle) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::random_device m_randomDevice;
|
||||||
|
std::mt19937 m_randomGenerator;
|
||||||
|
|
||||||
|
// Helper methods
|
||||||
|
static std::unique_ptr<YYJSONValue> CreateWrapper();
|
||||||
|
static std::shared_ptr<yyjson_mut_doc> WrapDocument(yyjson_mut_doc* doc);
|
||||||
|
static std::shared_ptr<yyjson_mut_doc> CopyDocument(yyjson_doc* doc);
|
||||||
|
static std::shared_ptr<yyjson_mut_doc> CreateDocument();
|
||||||
|
static std::shared_ptr<yyjson_doc> WrapImmutableDocument(yyjson_doc* doc);
|
||||||
|
|
||||||
|
// Pack helper methods
|
||||||
|
static const char* SkipSeparators(const char* ptr);
|
||||||
|
static void SetPackError(char* error, size_t error_size, const char* fmt, ...);
|
||||||
|
static yyjson_mut_val* PackImpl(yyjson_mut_doc* doc, const char* format,
|
||||||
|
IPackParamProvider* provider, char* error,
|
||||||
|
size_t error_size, const char** out_end_ptr);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _INCLUDE_SM_YYJSON_YYJSONMANAGER_H_
|
||||||
62
extensions/yyjson/extension.cpp
Executable file
62
extensions/yyjson/extension.cpp
Executable file
@ -0,0 +1,62 @@
|
|||||||
|
#include "extension.h"
|
||||||
|
#include "YYJSONManager.h"
|
||||||
|
|
||||||
|
JsonExtension g_JsonExtension;
|
||||||
|
SMEXT_LINK(&g_JsonExtension);
|
||||||
|
|
||||||
|
HandleType_t g_htJSON;
|
||||||
|
JSONHandler g_JSONHandler;
|
||||||
|
IYYJSONManager* g_pYYJSONManager;
|
||||||
|
|
||||||
|
bool JsonExtension::SDK_OnLoad(char* error, size_t maxlen, bool late)
|
||||||
|
{
|
||||||
|
sharesys->AddNatives(myself, json_natives);
|
||||||
|
sharesys->RegisterLibrary(myself, "yyjson");
|
||||||
|
|
||||||
|
HandleAccess haJSON;
|
||||||
|
handlesys->InitAccessDefaults(nullptr, &haJSON);
|
||||||
|
haJSON.access[HandleAccess_Read] = 0;
|
||||||
|
haJSON.access[HandleAccess_Delete] = 0;
|
||||||
|
|
||||||
|
HandleError err;
|
||||||
|
g_htJSON = handlesys->CreateType("YYJSON", &g_JSONHandler, 0, nullptr, &haJSON, myself->GetIdentity(), &err);
|
||||||
|
|
||||||
|
if (!g_htJSON) {
|
||||||
|
snprintf(error, maxlen, "Failed to create YYJSON handle type (err: %d)", err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the existing instance if it exists
|
||||||
|
if (g_pYYJSONManager) {
|
||||||
|
delete g_pYYJSONManager;
|
||||||
|
g_pYYJSONManager = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_pYYJSONManager = new YYJSONManager();
|
||||||
|
if (!g_pYYJSONManager) {
|
||||||
|
snprintf(error, maxlen, "Failed to create YYJSONManager instance");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sharesys->AddInterface(myself, g_pYYJSONManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JsonExtension::SDK_OnUnload()
|
||||||
|
{
|
||||||
|
handlesys->RemoveType(g_htJSON, myself->GetIdentity());
|
||||||
|
|
||||||
|
if (g_pYYJSONManager) {
|
||||||
|
delete g_pYYJSONManager;
|
||||||
|
g_pYYJSONManager = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JSONHandler::OnHandleDestroy(HandleType_t type, void* object)
|
||||||
|
{
|
||||||
|
delete (YYJSONValue*)object;
|
||||||
|
}
|
||||||
|
|
||||||
|
IYYJSONManager* JsonExtension::GetYYJSONManager()
|
||||||
|
{
|
||||||
|
return g_pYYJSONManager;
|
||||||
|
}
|
||||||
29
extensions/yyjson/extension.h
Executable file
29
extensions/yyjson/extension.h
Executable file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||||
|
#define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||||
|
|
||||||
|
#include "smsdk_ext.h"
|
||||||
|
#include <yyjson.h>
|
||||||
|
#include <random>
|
||||||
|
#include "IYYJSONManager.h"
|
||||||
|
|
||||||
|
class JsonExtension : public SDKExtension
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late);
|
||||||
|
virtual void SDK_OnUnload();
|
||||||
|
IYYJSONManager* GetYYJSONManager();
|
||||||
|
};
|
||||||
|
|
||||||
|
class JSONHandler : public IHandleTypeDispatch
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void OnHandleDestroy(HandleType_t type, void *object);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern JsonExtension g_JsonExtension;
|
||||||
|
extern HandleType_t g_htJSON;
|
||||||
|
extern JSONHandler g_JSONHandler;
|
||||||
|
extern const sp_nativeinfo_t json_natives[];
|
||||||
|
extern IYYJSONManager* g_pYYJSONManager;
|
||||||
|
|
||||||
|
#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||||
2479
extensions/yyjson/json_natives.cpp
Executable file
2479
extensions/yyjson/json_natives.cpp
Executable file
File diff suppressed because it is too large
Load Diff
17
extensions/yyjson/smsdk_config.h
Executable file
17
extensions/yyjson/smsdk_config.h
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
|
||||||
|
#define _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
|
||||||
|
|
||||||
|
#define SMEXT_CONF_NAME "SourceMod YYJSON Extension"
|
||||||
|
#define SMEXT_CONF_DESCRIPTION "Provide JSON Native"
|
||||||
|
#define SMEXT_CONF_VERSION "1.1.4a"
|
||||||
|
#define SMEXT_CONF_AUTHOR "ProjectSky"
|
||||||
|
#define SMEXT_CONF_URL "https://github.com/ProjectSky/sm-ext-yyjson"
|
||||||
|
#define SMEXT_CONF_LOGTAG "yyjson"
|
||||||
|
#define SMEXT_CONF_LICENSE "GPL"
|
||||||
|
#define SMEXT_CONF_DATESTRING __DATE__
|
||||||
|
|
||||||
|
#define SMEXT_LINK(name) SDKExtension *g_pExtensionIface = name;
|
||||||
|
|
||||||
|
#define SMEXT_ENABLE_HANDLESYS
|
||||||
|
|
||||||
|
#endif // _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
|
||||||
104
extensions/yyjson/version.rc
Executable file
104
extensions/yyjson/version.rc
Executable file
@ -0,0 +1,104 @@
|
|||||||
|
// Microsoft Visual C++ generated resource script.
|
||||||
|
//
|
||||||
|
//#include "resource.h"
|
||||||
|
|
||||||
|
#define APSTUDIO_READONLY_SYMBOLS
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Generated from the TEXTINCLUDE 2 resource.
|
||||||
|
//
|
||||||
|
#include "winres.h"
|
||||||
|
|
||||||
|
#include <sourcemod_version.h>
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
#undef APSTUDIO_READONLY_SYMBOLS
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// English (U.S.) resources
|
||||||
|
|
||||||
|
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||||
|
#ifdef _WIN32
|
||||||
|
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||||
|
#pragma code_page(1252)
|
||||||
|
#endif //_WIN32
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Version
|
||||||
|
//
|
||||||
|
|
||||||
|
VS_VERSION_INFO VERSIONINFO
|
||||||
|
FILEVERSION SM_VERSION_FILE
|
||||||
|
PRODUCTVERSION SM_VERSION_FILE
|
||||||
|
FILEFLAGSMASK 0x17L
|
||||||
|
#ifdef _DEBUG
|
||||||
|
FILEFLAGS 0x1L
|
||||||
|
#else
|
||||||
|
FILEFLAGS 0x0L
|
||||||
|
#endif
|
||||||
|
FILEOS 0x4L
|
||||||
|
FILETYPE 0x2L
|
||||||
|
FILESUBTYPE 0x0L
|
||||||
|
BEGIN
|
||||||
|
BLOCK "StringFileInfo"
|
||||||
|
BEGIN
|
||||||
|
BLOCK "000004b0"
|
||||||
|
BEGIN
|
||||||
|
VALUE "Comments", "YYJSON Extension"
|
||||||
|
VALUE "FileDescription", "SourceMod YYJSON Extension"
|
||||||
|
VALUE "FileVersion", SM_VERSION_FILE
|
||||||
|
VALUE "InternalName", "SourceMod YYJSON Extension"
|
||||||
|
VALUE "LegalCopyright", "Copyright (c) 2004-2009, AlliedModders LLC"
|
||||||
|
VALUE "OriginalFilename", BINARY_NAME
|
||||||
|
VALUE "ProductName", "SourceMod YYJSON Extension"
|
||||||
|
VALUE "ProductVersion", SM_VERSION_STRING
|
||||||
|
END
|
||||||
|
END
|
||||||
|
BLOCK "VarFileInfo"
|
||||||
|
BEGIN
|
||||||
|
VALUE "Translation", 0x0, 1200
|
||||||
|
END
|
||||||
|
END
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef APSTUDIO_INVOKED
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// TEXTINCLUDE
|
||||||
|
//
|
||||||
|
|
||||||
|
1 TEXTINCLUDE
|
||||||
|
BEGIN
|
||||||
|
"resource.h\0"
|
||||||
|
END
|
||||||
|
|
||||||
|
2 TEXTINCLUDE
|
||||||
|
BEGIN
|
||||||
|
"#include ""winres.h""\r\n"
|
||||||
|
"\0"
|
||||||
|
END
|
||||||
|
|
||||||
|
3 TEXTINCLUDE
|
||||||
|
BEGIN
|
||||||
|
"\r\n"
|
||||||
|
"\0"
|
||||||
|
END
|
||||||
|
|
||||||
|
#endif // APSTUDIO_INVOKED
|
||||||
|
|
||||||
|
#endif // English (U.S.) resources
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef APSTUDIO_INVOKED
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Generated from the TEXTINCLUDE 3 resource.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // not APSTUDIO_INVOKED
|
||||||
|
|
||||||
21
extensions/yyjson/yyjson/LICENSE
Executable file
21
extensions/yyjson/yyjson/LICENSE
Executable file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020 YaoYuan <ibireme@gmail.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
11195
extensions/yyjson/yyjson/yyjson.c
Executable file
11195
extensions/yyjson/yyjson/yyjson.c
Executable file
File diff suppressed because it is too large
Load Diff
8346
extensions/yyjson/yyjson/yyjson.h
Executable file
8346
extensions/yyjson/yyjson/yyjson.h
Executable file
File diff suppressed because it is too large
Load Diff
1626
plugins/include/yyjson.inc
Executable file
1626
plugins/include/yyjson.inc
Executable file
File diff suppressed because it is too large
Load Diff
566
plugins/testsuite/yyjson_test.sp
Executable file
566
plugins/testsuite/yyjson_test.sp
Executable file
@ -0,0 +1,566 @@
|
|||||||
|
#include <sourcemod>
|
||||||
|
#include <yyjson>
|
||||||
|
|
||||||
|
public Plugin myinfo =
|
||||||
|
{
|
||||||
|
name = "YYJSON Test Suite",
|
||||||
|
author = "ProjectSky",
|
||||||
|
description = "Test suite for YYJSON extension",
|
||||||
|
version = "1.0.2",
|
||||||
|
url = "https://github.com/ProjectSky/sm-ext-yyjson"
|
||||||
|
};
|
||||||
|
|
||||||
|
public void OnPluginStart()
|
||||||
|
{
|
||||||
|
RegServerCmd("sm_yyjson_test", Command_RunTests, "Run YYJSON test suite");
|
||||||
|
}
|
||||||
|
|
||||||
|
Action Command_RunTests(int args)
|
||||||
|
{
|
||||||
|
// Run all test cases
|
||||||
|
TestBasicOperations();
|
||||||
|
TestArrayOperations();
|
||||||
|
TestObjectOperations();
|
||||||
|
TestSortOperations();
|
||||||
|
TestSearchOperations();
|
||||||
|
TestPointerOperations();
|
||||||
|
TestIterationOperations();
|
||||||
|
TestTypeOperations();
|
||||||
|
TestFileOperations();
|
||||||
|
TestImmutabilityOperations();
|
||||||
|
TestPackOperations();
|
||||||
|
TestFromStringsOperations();
|
||||||
|
|
||||||
|
PrintToServer("[YYJSON] All tests completed!");
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestBasicOperations()
|
||||||
|
{
|
||||||
|
PrintToServer("[YYJSON] Testing basic operations...");
|
||||||
|
|
||||||
|
// Test creation and parsing
|
||||||
|
YYJSONObject obj = new YYJSONObject();
|
||||||
|
obj.SetInt("int", 42);
|
||||||
|
obj.SetFloat("float", 3.14);
|
||||||
|
obj.SetBool("bool", true);
|
||||||
|
obj.SetString("string", "hello");
|
||||||
|
obj.SetNull("null");
|
||||||
|
|
||||||
|
// Test serialization
|
||||||
|
char buffer[1024];
|
||||||
|
obj.ToString(buffer, sizeof(buffer));
|
||||||
|
PrintToServer("Serialized: %s", buffer);
|
||||||
|
|
||||||
|
// Test type checking
|
||||||
|
PrintToServer("Type of 'int': %d", obj.Type);
|
||||||
|
PrintToServer("SubType of 'int': %d", obj.SubType);
|
||||||
|
PrintToServer("Is object: %d", obj.IsObject);
|
||||||
|
|
||||||
|
// Test value existence
|
||||||
|
PrintToServer("Has 'int': %d", obj.HasKey("int"));
|
||||||
|
PrintToServer("Has 'nonexistent': %d", obj.HasKey("nonexistent"));
|
||||||
|
|
||||||
|
// Test value retrieval
|
||||||
|
PrintToServer("Int value: %d", obj.GetInt("int"));
|
||||||
|
PrintToServer("Float value: %f", obj.GetFloat("float"));
|
||||||
|
PrintToServer("Bool value: %d", obj.GetBool("bool"));
|
||||||
|
|
||||||
|
char strBuffer[64];
|
||||||
|
obj.GetString("string", strBuffer, sizeof(strBuffer));
|
||||||
|
PrintToServer("String value: %s", strBuffer);
|
||||||
|
|
||||||
|
PrintToServer("Is 'null' null: %d", obj.IsNull("null"));
|
||||||
|
|
||||||
|
// Test parsing
|
||||||
|
YYJSONObject parsed = YYJSON.Parse(buffer);
|
||||||
|
|
||||||
|
// Test equality
|
||||||
|
PrintToServer("Objects are equal: %d", YYJSON.Equals(obj, parsed));
|
||||||
|
|
||||||
|
// Test deep copy
|
||||||
|
YYJSONObject copy = new YYJSONObject();
|
||||||
|
YYJSONObject copyResult = YYJSON.DeepCopy(copy, obj);
|
||||||
|
PrintToServer("Copy equals original: %d", YYJSON.Equals(copyResult, obj));
|
||||||
|
|
||||||
|
// Test size and read size
|
||||||
|
PrintToServer("Object size: %d", obj.Size);
|
||||||
|
PrintToServer("Read size: %d", obj.ReadSize);
|
||||||
|
|
||||||
|
// Test type description
|
||||||
|
char typeDesc[64];
|
||||||
|
YYJSON.GetTypeDesc(obj, typeDesc, sizeof(typeDesc));
|
||||||
|
PrintToServer("Type description: %s", typeDesc);
|
||||||
|
|
||||||
|
delete obj;
|
||||||
|
delete parsed;
|
||||||
|
delete copy;
|
||||||
|
delete copyResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestArrayOperations()
|
||||||
|
{
|
||||||
|
PrintToServer("[YYJSON] Testing array operations...");
|
||||||
|
|
||||||
|
YYJSONArray arr = new YYJSONArray();
|
||||||
|
|
||||||
|
// Test push operations
|
||||||
|
arr.PushInt(1);
|
||||||
|
arr.PushFloat(2.5);
|
||||||
|
arr.PushBool(true);
|
||||||
|
arr.PushString("test");
|
||||||
|
arr.PushNull();
|
||||||
|
|
||||||
|
PrintToServer("Array after push operations:");
|
||||||
|
PrintJson(arr);
|
||||||
|
|
||||||
|
// Test get operations
|
||||||
|
PrintToServer("First element: %d", arr.GetInt(0));
|
||||||
|
PrintToServer("Second element: %f", arr.GetFloat(1));
|
||||||
|
PrintToServer("Third element: %d", arr.GetBool(2));
|
||||||
|
|
||||||
|
char strBuffer[64];
|
||||||
|
arr.GetString(3, strBuffer, sizeof(strBuffer));
|
||||||
|
PrintToServer("Fourth element: %s", strBuffer);
|
||||||
|
|
||||||
|
PrintToServer("Fifth element is null: %d", arr.IsNull(4));
|
||||||
|
|
||||||
|
YYJSON first = arr.First;
|
||||||
|
YYJSON last = arr.Last;
|
||||||
|
|
||||||
|
// Test array properties
|
||||||
|
PrintToServer("Array length: %d", arr.Length);
|
||||||
|
PrintToServer("First value: %x", first);
|
||||||
|
PrintToServer("Last value: %x", last);
|
||||||
|
|
||||||
|
// Test set operations
|
||||||
|
arr.SetInt(0, 100);
|
||||||
|
arr.SetFloat(1, 3.14);
|
||||||
|
arr.SetBool(2, false);
|
||||||
|
arr.SetString(3, "modified");
|
||||||
|
arr.SetNull(4);
|
||||||
|
|
||||||
|
PrintToServer("Array after set operations:");
|
||||||
|
PrintJson(arr);
|
||||||
|
|
||||||
|
// Test remove operations
|
||||||
|
arr.RemoveFirst();
|
||||||
|
PrintToServer("After RemoveFirst:");
|
||||||
|
PrintJson(arr);
|
||||||
|
|
||||||
|
arr.RemoveLast();
|
||||||
|
PrintToServer("After RemoveLast:");
|
||||||
|
PrintJson(arr);
|
||||||
|
|
||||||
|
arr.Remove(1);
|
||||||
|
PrintToServer("After Remove(1):");
|
||||||
|
PrintJson(arr);
|
||||||
|
|
||||||
|
arr.RemoveRange(0, 1);
|
||||||
|
PrintToServer("After RemoveRange(0, 1):");
|
||||||
|
PrintJson(arr);
|
||||||
|
|
||||||
|
arr.Clear();
|
||||||
|
PrintToServer("Array length after Clear: %d", arr.Length);
|
||||||
|
|
||||||
|
delete arr;
|
||||||
|
delete first;
|
||||||
|
delete last;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestObjectOperations()
|
||||||
|
{
|
||||||
|
PrintToServer("[YYJSON] Testing object operations...");
|
||||||
|
|
||||||
|
YYJSONObject obj = new YYJSONObject();
|
||||||
|
|
||||||
|
// Test set operations
|
||||||
|
obj.SetInt("int", 123);
|
||||||
|
obj.SetFloat("float", 3.14);
|
||||||
|
obj.SetBool("bool", true);
|
||||||
|
obj.SetString("string", "test");
|
||||||
|
obj.SetNull("null");
|
||||||
|
|
||||||
|
PrintToServer("Object after set operations:");
|
||||||
|
PrintJson(obj);
|
||||||
|
|
||||||
|
// Test get operations
|
||||||
|
PrintToServer("Int value: %d", obj.GetInt("int"));
|
||||||
|
PrintToServer("Float value: %f", obj.GetFloat("float"));
|
||||||
|
PrintToServer("Bool value: %d", obj.GetBool("bool"));
|
||||||
|
|
||||||
|
char strBuffer[64];
|
||||||
|
obj.GetString("string", strBuffer, sizeof(strBuffer));
|
||||||
|
PrintToServer("String value: %s", strBuffer);
|
||||||
|
|
||||||
|
PrintToServer("Is null value null: %d", obj.IsNull("null"));
|
||||||
|
|
||||||
|
// Test key operations
|
||||||
|
char key[64];
|
||||||
|
for (int i = 0; i < obj.Size; i++)
|
||||||
|
{
|
||||||
|
obj.GetKey(i, key, sizeof(key));
|
||||||
|
PrintToServer("Key at %d: %s", i, key);
|
||||||
|
|
||||||
|
YYJSON value = obj.GetValueAt(i);
|
||||||
|
PrintToServer("Value type at %d: %d", i, value.Type);
|
||||||
|
delete value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test rename key
|
||||||
|
obj.RenameKey("int", "number");
|
||||||
|
PrintToServer("After renaming 'int' to 'number':");
|
||||||
|
PrintJson(obj);
|
||||||
|
|
||||||
|
// Test remove operations
|
||||||
|
obj.Remove("number");
|
||||||
|
PrintToServer("After removing 'number':");
|
||||||
|
PrintJson(obj);
|
||||||
|
|
||||||
|
obj.Clear();
|
||||||
|
PrintToServer("Object size after Clear: %d", obj.Size);
|
||||||
|
|
||||||
|
delete obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestSortOperations()
|
||||||
|
{
|
||||||
|
PrintToServer("[YYJSON] Testing sort operations...");
|
||||||
|
|
||||||
|
// Test array sorting
|
||||||
|
YYJSONArray arr = YYJSON.Parse("[3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]", .is_mutable_doc = true);
|
||||||
|
|
||||||
|
PrintToServer("Original array:");
|
||||||
|
PrintJson(arr);
|
||||||
|
|
||||||
|
arr.Sort();
|
||||||
|
PrintToServer("After ascending sort:");
|
||||||
|
PrintJson(arr);
|
||||||
|
|
||||||
|
arr.Sort(YYJSON_SORT_DESC);
|
||||||
|
PrintToServer("After descending sort:");
|
||||||
|
PrintJson(arr);
|
||||||
|
|
||||||
|
arr.Sort(YYJSON_SORT_RANDOM);
|
||||||
|
PrintToServer("After random sort:");
|
||||||
|
PrintJson(arr);
|
||||||
|
|
||||||
|
// Test mixed type array sorting
|
||||||
|
YYJSONArray mixed = YYJSON.Parse("[true, 42, \"hello\", 1.23, false, \"world\"]", .is_mutable_doc = true);
|
||||||
|
PrintToServer("Original mixed array:");
|
||||||
|
PrintJson(mixed);
|
||||||
|
|
||||||
|
mixed.Sort();
|
||||||
|
PrintToServer("After sorting mixed array:");
|
||||||
|
PrintJson(mixed);
|
||||||
|
|
||||||
|
// Test object sorting
|
||||||
|
YYJSONObject obj = YYJSON.Parse("{\"zebra\": 1, \"alpha\": 2, \"beta\": 3}", .is_mutable_doc = true);
|
||||||
|
PrintToServer("Original object:");
|
||||||
|
PrintJson(obj);
|
||||||
|
|
||||||
|
obj.Sort();
|
||||||
|
PrintToServer("After ascending sort:");
|
||||||
|
PrintJson(obj);
|
||||||
|
|
||||||
|
obj.Sort(YYJSON_SORT_DESC);
|
||||||
|
PrintToServer("After descending sort:");
|
||||||
|
PrintJson(obj);
|
||||||
|
|
||||||
|
obj.Sort(YYJSON_SORT_RANDOM);
|
||||||
|
PrintToServer("After random sort:");
|
||||||
|
PrintJson(obj);
|
||||||
|
|
||||||
|
delete arr;
|
||||||
|
delete mixed;
|
||||||
|
delete obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestSearchOperations()
|
||||||
|
{
|
||||||
|
PrintToServer("[YYJSON] Testing search operations...");
|
||||||
|
|
||||||
|
YYJSONArray arr = YYJSON.Parse("[42, true, \"hello\", 3.14, \"world\", false, 42]");
|
||||||
|
PrintToServer("Test array:");
|
||||||
|
PrintJson(arr);
|
||||||
|
|
||||||
|
// Test all search methods
|
||||||
|
PrintToServer("Search results:");
|
||||||
|
PrintToServer("IndexOfInt(42): %d", arr.IndexOfInt(42));
|
||||||
|
PrintToServer("IndexOfInt(999): %d", arr.IndexOfInt(999));
|
||||||
|
|
||||||
|
PrintToServer("IndexOfBool(true): %d", arr.IndexOfBool(true));
|
||||||
|
PrintToServer("IndexOfBool(false): %d", arr.IndexOfBool(false));
|
||||||
|
|
||||||
|
PrintToServer("IndexOfString(\"hello\"): %d", arr.IndexOfString("hello"));
|
||||||
|
PrintToServer("IndexOfString(\"missing\"): %d", arr.IndexOfString("missing"));
|
||||||
|
|
||||||
|
PrintToServer("IndexOfFloat(3.14): %d", arr.IndexOfFloat(3.14));
|
||||||
|
PrintToServer("IndexOfFloat(2.718): %d", arr.IndexOfFloat(2.718));
|
||||||
|
|
||||||
|
delete arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestPointerOperations()
|
||||||
|
{
|
||||||
|
PrintToServer("[YYJSON] Testing JSON pointer operations...");
|
||||||
|
|
||||||
|
YYJSONObject obj = new YYJSONObject();
|
||||||
|
|
||||||
|
// Test setting nested values
|
||||||
|
obj.PtrSetInt("/a/b/c", 1);
|
||||||
|
obj.PtrSetString("/a/b/name", "test");
|
||||||
|
obj.PtrSetBool("/a/flag", true);
|
||||||
|
obj.PtrSetFloat("/a/b/pi", 3.14);
|
||||||
|
obj.PtrSetNull("/a/b/empty");
|
||||||
|
|
||||||
|
PrintToServer("After setting values:");
|
||||||
|
PrintJson(obj);
|
||||||
|
|
||||||
|
// Test getting values
|
||||||
|
PrintToServer("Pointer get operations:");
|
||||||
|
PrintToServer("/a/b/c: %d", obj.PtrGetInt("/a/b/c"));
|
||||||
|
|
||||||
|
char strBuffer[64];
|
||||||
|
obj.PtrGetString("/a/b/name", strBuffer, sizeof(strBuffer));
|
||||||
|
PrintToServer("/a/b/name: %s", strBuffer);
|
||||||
|
|
||||||
|
PrintToServer("/a/flag: %d", obj.PtrGetBool("/a/flag"));
|
||||||
|
PrintToServer("/a/b/pi: %f", obj.PtrGetFloat("/a/b/pi"));
|
||||||
|
PrintToServer("/a/b/empty is null: %d", obj.PtrGetIsNull("/a/b/empty"));
|
||||||
|
|
||||||
|
// Test adding values
|
||||||
|
obj.PtrAddInt("/a/b/numbers/0", 1);
|
||||||
|
obj.PtrAddInt("/a/b/numbers/1", 2);
|
||||||
|
obj.PtrAddString("/a/b/strings", "append");
|
||||||
|
|
||||||
|
PrintToServer("After adding values:");
|
||||||
|
PrintJson(obj);
|
||||||
|
|
||||||
|
// Test length
|
||||||
|
PrintToServer("Length of /a/b/numbers: %d", obj.PtrGetLength("/a/b/numbers"));
|
||||||
|
|
||||||
|
// Test removing values
|
||||||
|
obj.PtrRemove("/a/b/c");
|
||||||
|
PrintToServer("After removing /a/b/c:");
|
||||||
|
PrintJson(obj);
|
||||||
|
|
||||||
|
delete obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestIterationOperations()
|
||||||
|
{
|
||||||
|
PrintToServer("[YYJSON] Testing iteration operations...");
|
||||||
|
|
||||||
|
// Test object iteration
|
||||||
|
YYJSONObject obj = YYJSON.Parse("{\"a\": 1, \"b\": 2, \"c\": 3}");
|
||||||
|
char key[64];
|
||||||
|
YYJSON value;
|
||||||
|
|
||||||
|
while (obj.ForeachObject(key, sizeof(key), value))
|
||||||
|
{
|
||||||
|
PrintToServer("Key: %s", key);
|
||||||
|
delete value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test array iteration
|
||||||
|
YYJSONArray arr = YYJSON.Parse("[1, 2, 3, 4, 5]");
|
||||||
|
int index;
|
||||||
|
|
||||||
|
while (arr.ForeachArray(index, value))
|
||||||
|
{
|
||||||
|
PrintToServer("Index: %d", index);
|
||||||
|
delete value;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete obj;
|
||||||
|
delete arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestTypeOperations()
|
||||||
|
{
|
||||||
|
PrintToServer("[YYJSON] Testing type operations...");
|
||||||
|
|
||||||
|
// Test value creation
|
||||||
|
YYJSON boolVal = YYJSON.CreateBool(true);
|
||||||
|
YYJSON intVal = YYJSON.CreateInt(42);
|
||||||
|
YYJSON floatVal = YYJSON.CreateFloat(3.14);
|
||||||
|
YYJSON strVal = YYJSON.CreateString("test");
|
||||||
|
YYJSON nullVal = YYJSON.CreateNull();
|
||||||
|
|
||||||
|
// Test value types
|
||||||
|
PrintToServer("Value types:");
|
||||||
|
PrintToServer("Bool type: %d", boolVal.Type);
|
||||||
|
PrintToServer("Int type: %d", intVal.Type);
|
||||||
|
PrintToServer("Float type: %d", floatVal.Type);
|
||||||
|
PrintToServer("String type: %d", strVal.Type);
|
||||||
|
PrintToServer("Null type: %d", nullVal.Type);
|
||||||
|
|
||||||
|
// Test value retrieval
|
||||||
|
PrintToServer("Value contents:");
|
||||||
|
PrintToServer("Bool value: %d", YYJSON.GetBool(boolVal));
|
||||||
|
PrintToServer("Int value: %d", YYJSON.GetInt(intVal));
|
||||||
|
PrintToServer("Float value: %f", YYJSON.GetFloat(floatVal));
|
||||||
|
|
||||||
|
char strBuffer[64];
|
||||||
|
YYJSON.GetString(strVal, strBuffer, sizeof(strBuffer));
|
||||||
|
PrintToServer("String value: %s", strBuffer);
|
||||||
|
|
||||||
|
delete boolVal;
|
||||||
|
delete intVal;
|
||||||
|
delete floatVal;
|
||||||
|
delete strVal;
|
||||||
|
delete nullVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestFileOperations()
|
||||||
|
{
|
||||||
|
PrintToServer("[YYJSON] Testing file operations...");
|
||||||
|
|
||||||
|
// Create test data
|
||||||
|
YYJSONObject obj = new YYJSONObject();
|
||||||
|
obj.SetInt("id", 1);
|
||||||
|
obj.SetString("name", "test");
|
||||||
|
obj.SetBool("active", true);
|
||||||
|
|
||||||
|
// Test file writing
|
||||||
|
PrintToServer("Writing to file...");
|
||||||
|
obj.ToFile("test.json", YYJSON_WRITE_PRETTY_TWO_SPACES);
|
||||||
|
|
||||||
|
// Test file reading
|
||||||
|
PrintToServer("Reading from file...");
|
||||||
|
YYJSONObject loaded = YYJSON.Parse("test.json", true);
|
||||||
|
|
||||||
|
PrintToServer("File content:");
|
||||||
|
PrintJson(loaded);
|
||||||
|
delete loaded;
|
||||||
|
|
||||||
|
delete obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestImmutabilityOperations()
|
||||||
|
{
|
||||||
|
PrintToServer("[YYJSON] Testing immutability operations...");
|
||||||
|
|
||||||
|
// Test immutable document creation
|
||||||
|
YYJSONObject immutable = YYJSON.Parse("{\"key\": 123, \"str\": \"test\"}");
|
||||||
|
PrintToServer("Created immutable document:");
|
||||||
|
PrintJson(immutable);
|
||||||
|
|
||||||
|
// Test property checks
|
||||||
|
PrintToServer("Is mutable: %d", immutable.IsMutable);
|
||||||
|
PrintToServer("Is immutable: %d", immutable.IsImmutable);
|
||||||
|
|
||||||
|
// Test read operations (should succeed)
|
||||||
|
PrintToServer("Read operations on immutable document:");
|
||||||
|
PrintToServer("Int value: %d", immutable.GetInt("key"));
|
||||||
|
char buffer[64];
|
||||||
|
immutable.GetString("str", buffer, sizeof(buffer));
|
||||||
|
PrintToServer("String value: %s", buffer);
|
||||||
|
|
||||||
|
// Test conversion to mutable
|
||||||
|
YYJSONObject mutable = immutable.ToMutable();
|
||||||
|
PrintToServer("\nConverted to mutable document:");
|
||||||
|
PrintToServer("Is mutable: %d", mutable.IsMutable);
|
||||||
|
PrintToServer("Is immutable: %d", mutable.IsImmutable);
|
||||||
|
|
||||||
|
// Now modifications should work
|
||||||
|
mutable.SetInt("key", 456)
|
||||||
|
PrintToServer("Successfully modified mutable document:");
|
||||||
|
PrintJson(mutable);
|
||||||
|
|
||||||
|
// Test conversion back to immutable
|
||||||
|
YYJSONObject backToImmutable = mutable.ToImmutable();
|
||||||
|
PrintToServer("\nConverted back to immutable:");
|
||||||
|
PrintToServer("Is mutable: %d", backToImmutable.IsMutable);
|
||||||
|
PrintToServer("Is immutable: %d", backToImmutable.IsImmutable);
|
||||||
|
delete backToImmutable;
|
||||||
|
delete mutable;
|
||||||
|
delete immutable;
|
||||||
|
|
||||||
|
// Test file operations with immutability
|
||||||
|
PrintToServer("\nTesting file operations with immutability...");
|
||||||
|
|
||||||
|
// Create and write a mutable document
|
||||||
|
YYJSONObject writeObj = new YYJSONObject();
|
||||||
|
writeObj.SetInt("test", 123);
|
||||||
|
writeObj.ToFile("test_immutable.json");
|
||||||
|
delete writeObj;
|
||||||
|
|
||||||
|
// Read as immutable
|
||||||
|
YYJSONObject readImmutable = YYJSON.Parse("test_immutable.json", true);
|
||||||
|
PrintToServer("Read as immutable document:");
|
||||||
|
PrintJson(readImmutable);
|
||||||
|
PrintToServer("Is mutable: %d", readImmutable.IsMutable);
|
||||||
|
PrintToServer("Is immutable: %d", readImmutable.IsImmutable);
|
||||||
|
delete readImmutable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestPackOperations()
|
||||||
|
{
|
||||||
|
PrintToServer("[YYJSON] Testing pack operations...");
|
||||||
|
|
||||||
|
// Test basic pack operation with different types
|
||||||
|
YYJSON packed = YYJSON.Pack("{s:s,s:i,s:f,s:b,s:n}",
|
||||||
|
"name", "test",
|
||||||
|
"age", 25,
|
||||||
|
"height", 1.75,
|
||||||
|
"active", true,
|
||||||
|
"extra"
|
||||||
|
);
|
||||||
|
|
||||||
|
PrintToServer("Packed JSON:");
|
||||||
|
PrintJson(packed);
|
||||||
|
|
||||||
|
// Test nested object packing
|
||||||
|
YYJSON nested = YYJSON.Pack("{s:{s:s,s:[i,i,i]}}",
|
||||||
|
"user",
|
||||||
|
"name", "test",
|
||||||
|
"scores", 85, 90, 95
|
||||||
|
);
|
||||||
|
|
||||||
|
PrintToServer("Nested packed JSON:");
|
||||||
|
PrintJson(nested);
|
||||||
|
|
||||||
|
// Test array packing with mixed types
|
||||||
|
YYJSON array = YYJSON.Pack("[s,i,f,b,n]",
|
||||||
|
"test", 42, 3.14, true
|
||||||
|
);
|
||||||
|
|
||||||
|
PrintToServer("Array packed JSON:");
|
||||||
|
PrintJson(array);
|
||||||
|
|
||||||
|
delete packed;
|
||||||
|
delete nested;
|
||||||
|
delete array;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestFromStringsOperations()
|
||||||
|
{
|
||||||
|
PrintToServer("[YYJSON] Testing FromStrings operations...");
|
||||||
|
|
||||||
|
// Test object creation from key-value string arrays
|
||||||
|
char pairs[][] = {"name", "test", "type", "demo", "version", "1.0.0"};
|
||||||
|
|
||||||
|
YYJSONObject obj = YYJSONObject.FromStrings(pairs, sizeof(pairs));
|
||||||
|
PrintToServer("Object from strings:");
|
||||||
|
PrintJson(obj);
|
||||||
|
|
||||||
|
// Test array creation from string array
|
||||||
|
char items[][] = {"apple", "banana", "orange", "grape"};
|
||||||
|
YYJSONArray arr = YYJSONArray.FromStrings(items, sizeof(items));
|
||||||
|
PrintToServer("Array from strings:");
|
||||||
|
PrintJson(arr);
|
||||||
|
|
||||||
|
delete obj;
|
||||||
|
delete arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to print json contents
|
||||||
|
void PrintJson(YYJSON data)
|
||||||
|
{
|
||||||
|
int len = data.GetSerializedSize(YYJSON_WRITE_PRETTY_TWO_SPACES);
|
||||||
|
char[] buffer = new char[len];
|
||||||
|
data.ToString(buffer, len, YYJSON_WRITE_PRETTY_TWO_SPACES);
|
||||||
|
PrintToServer("%s", buffer);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user