Last active
August 29, 2015 14:08
-
-
Save gamingrobot/e6e80d1d50f9f5ce42e2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Attribution: https://bitbucket.org/motdplayer/sm-adplugin/src | |
Parsing fixed by gamingrobot | |
*/ | |
#if defined _easyjson_included | |
#endinput | |
#endif | |
#define _easyjson_included | |
enum JSONType | |
{ | |
Type_String, | |
Type_Integer, | |
Type_Float, | |
Type_Object, | |
Type_Boolean, | |
Type_Array | |
} | |
stock Handle:CreateJSON() | |
{ | |
new Handle:m_hJSON = CreateTrie(); | |
new Handle:m_hJSONKeys = CreateArray(512); | |
SetTrieValue(m_hJSON, "json_key_array", m_hJSONKeys); | |
return m_hJSON; | |
} | |
stock Handle:DecodeJSON(const String:json[], &len=0) | |
{ | |
decl m_iPos, m_iIgnore; | |
new m_iLength = strlen(json); | |
m_iPos = JSONIgnore(json); | |
if(m_iPos == -1 || json[m_iPos] != '{') | |
return INVALID_HANDLE; | |
++m_iPos; | |
m_iIgnore = JSONIgnore(json[m_iPos]); | |
if(m_iIgnore == -1) | |
return INVALID_HANDLE; | |
m_iPos += m_iIgnore; | |
decl m_iStringStart; | |
decl m_iStringEnd; | |
new bool:m_bEnd = false; | |
new Handle:m_hJSON = CreateJSON(); | |
while(m_iPos<m_iLength && json[m_iPos] != '}' && !m_bEnd) | |
{ | |
if(GetJSONString(json[m_iPos], m_iStringStart, m_iStringEnd)) | |
{ | |
new String:m_szKey[m_iStringEnd-m_iStringStart+1]; | |
strcopy(m_szKey, m_iStringEnd-m_iStringStart+1, json[m_iPos+m_iStringStart]); | |
m_iPos += m_iStringEnd+1; | |
m_iPos += JSONIgnore(json[m_iPos]); | |
if(json[m_iPos] == '{') | |
{ | |
new m_iLen = -1; | |
new Handle:m_hObject = DecodeJSON(json[m_iPos], m_iLen); | |
if(m_hObject != INVALID_HANDLE) | |
{ | |
JSONSetObject(m_hJSON, m_szKey, m_hObject); | |
m_iPos += m_iLen; | |
m_iPos += JSONIgnore(json[m_iPos]); | |
} | |
else | |
{ | |
DestroyJSON(m_hJSON); | |
return INVALID_HANDLE; | |
} | |
} else if(json[m_iPos] == '[') | |
{ | |
new m_iLen = -1; | |
new Handle:m_hObject = DecodeArray(json[m_iPos], m_iLen); | |
if(m_hObject != INVALID_HANDLE) | |
{ | |
JSONSetArray(m_hJSON, m_szKey, m_hObject); | |
m_iPos += m_iLen; | |
m_iPos += JSONIgnore(json[m_iPos]); | |
} | |
else | |
{ | |
DestroyJSON(m_hJSON); | |
return INVALID_HANDLE; | |
} | |
} else if(GetJSONString(json[m_iPos], m_iStringStart, m_iStringEnd)) | |
{ | |
new String:m_szValue[m_iStringEnd-m_iStringStart+1]; | |
strcopy(m_szValue, m_iStringEnd-m_iStringStart+1, json[m_iPos+m_iStringStart]); | |
if(json[m_iPos+m_iStringEnd+1]=='}'){ | |
m_bEnd = true; | |
} | |
m_iPos += m_iStringEnd+1; | |
m_iPos += JSONIgnore(json[m_iPos]); | |
new m_iDot = 0; | |
if(m_iStringStart != 0) | |
JSONSetString(m_hJSON, m_szKey, m_szValue); | |
else if(strcmp(m_szValue, "true")==0) | |
JSONSetBoolean(m_hJSON, m_szKey, true); | |
else if(strcmp(m_szValue, "false")==0) | |
JSONSetBoolean(m_hJSON, m_szKey, false); | |
else if(JSONIsNumeric(m_szValue)) | |
JSONSetInteger(m_hJSON, m_szKey, StringToInt(m_szValue)); | |
else if((m_iDot = FindCharInString(m_szValue, '.'))!=-1) | |
{ | |
m_szValue[m_iDot] = 0; | |
if(JSONIsNumeric(m_szValue) && JSONIsNumeric(m_szValue[m_iDot+1])) | |
{ | |
m_szValue[m_iDot] = '.'; | |
JSONSetFloat(m_hJSON, m_szKey, StringToFloat(m_szValue)); | |
} | |
} | |
} | |
} | |
} | |
if(json[m_iPos] == '}') | |
m_iPos += 1; | |
if(len != 0) | |
len = m_iPos; | |
return m_hJSON; | |
} | |
stock Handle:DecodeArray(const String:json[], &len=0) | |
{ | |
decl m_iPos, m_iIgnore; | |
new m_iLength = strlen(json); | |
m_iPos = JSONIgnore(json); | |
if(m_iPos == -1 || json[m_iPos] != '[') | |
return INVALID_HANDLE; | |
++m_iPos; | |
m_iIgnore = JSONIgnore(json[m_iPos]); | |
if(m_iIgnore == -1) | |
return INVALID_HANDLE; | |
m_iPos += m_iIgnore; | |
decl m_iStringStart; | |
decl m_iStringEnd; | |
new bool:m_bEnd = false; | |
new Handle:m_hArray = CreateArray(1); | |
while(m_iPos<m_iLength && json[m_iPos] != ']' && !m_bEnd) | |
{ | |
m_iPos += JSONIgnore(json[m_iPos]); | |
if(json[m_iPos] == '{') | |
{ | |
new m_iLen = -1; | |
new Handle:m_hObject = DecodeJSON(json[m_iPos], m_iLen); | |
if(m_hObject != INVALID_HANDLE) | |
{ | |
PushArrayCell(m_hArray, JSONCreateObject(m_hObject)); | |
m_iPos += m_iLen; | |
m_iPos += JSONIgnore(json[m_iPos]); | |
} | |
else | |
{ | |
DestroyJSONArray(m_hArray); | |
return INVALID_HANDLE; | |
} | |
} else if(json[m_iPos] == '[') | |
{ | |
new m_iLen = -1; | |
new Handle:m_hObject = DecodeArray(json[m_iPos], m_iLen); | |
if(m_hArray != INVALID_HANDLE) | |
{ | |
PushArrayCell(m_hArray, JSONCreateArray(m_hObject)); | |
m_iPos += m_iLen; | |
m_iPos += JSONIgnore(json[m_iPos]); | |
} | |
else | |
{ | |
DestroyJSONArray(m_hArray); | |
return INVALID_HANDLE; | |
} | |
} else if(GetJSONString(json[m_iPos], m_iStringStart, m_iStringEnd)) | |
{ | |
new String:m_szValue[m_iStringEnd-m_iStringStart+1]; | |
strcopy(m_szValue, m_iStringEnd-m_iStringStart+1, json[m_iPos+m_iStringStart]); | |
if(json[m_iPos+m_iStringEnd+1]==']'){ | |
m_bEnd = true; | |
} | |
m_iPos += m_iStringEnd+1; | |
m_iPos += JSONIgnore(json[m_iPos]); | |
new m_iDot = 0; | |
if(m_iStringStart != 0) | |
PushArrayCell(m_hArray, JSONCreateString(m_szValue)); | |
else if(strcmp(m_szValue, "true")==0) | |
PushArrayCell(m_hArray, JSONCreateBoolean(true)); | |
else if(strcmp(m_szValue, "false")==0) | |
PushArrayCell(m_hArray, JSONCreateBoolean(false)); | |
else if(JSONIsNumeric(m_szValue)) | |
PushArrayCell(m_hArray, JSONCreateInteger(StringToInt(m_szValue))); | |
else if((m_iDot = FindCharInString(m_szValue, '.'))!=-1) | |
{ | |
m_szValue[m_iDot] = 0; | |
if(JSONIsNumeric(m_szValue) && JSONIsNumeric(m_szValue[m_iDot+1])) | |
{ | |
m_szValue[m_iDot] = '.'; | |
PushArrayCell(m_hArray, JSONCreateFloat(StringToFloat(m_szValue))); | |
} | |
} | |
} | |
} | |
if(json[m_iPos] == ']') | |
m_iPos += 1; | |
if(len != 0) | |
len = m_iPos; | |
return m_hArray; | |
} | |
stock EncodeJSON(&Handle:json, String:output[], maxlen, bool:beautify=true, &len=0, tabs=1) | |
{ | |
new Handle:m_hKeyArray = INVALID_HANDLE; | |
if(!GetTrieValue(json, "json_key_array", m_hKeyArray)) | |
return; | |
new m_iKeys = GetArraySize(m_hKeyArray); | |
decl String:m_szKey[512]; | |
decl Handle:m_hObject; | |
if(2 >= maxlen) | |
return; | |
new String:m_szTabs[tabs+1]; | |
if(beautify) | |
for(new i=0;i<tabs;++i) | |
m_szTabs[i] = '\t'; | |
new m_iPos = 1; | |
output[0] = '{'; | |
if(beautify) | |
{ | |
output[1] = '\n'; | |
++m_iPos; | |
} | |
for(new i=0;i<m_iKeys;++i) | |
{ | |
GetArrayString(m_hKeyArray, i, m_szKey, sizeof(m_szKey)); | |
if(!GetTrieValue(json, m_szKey, m_hObject)) | |
continue; | |
decl JSONType:m_eType; | |
GetTrieValue(m_hObject, "type", m_eType); | |
switch(m_eType) | |
{ | |
case Type_String: | |
{ | |
decl m_iLength; | |
GetTrieValue(m_hObject, "size", m_iLength); | |
decl String:m_szValue[m_iLength*2+1]; | |
GetTrieString(m_hObject, "value", m_szValue, m_iLength+1); | |
ReplaceString(m_szValue, m_iLength*2+1, "\"", "\\\""); | |
m_iPos += Format(output[m_iPos], maxlen-m_iPos, "%s\"%s\": \"%s\"", m_szTabs, m_szKey, m_szValue); | |
} | |
case Type_Boolean: | |
{ | |
decl bool:m_bValue; | |
GetTrieValue(m_hObject, "value", m_bValue); | |
if(m_bValue) | |
m_iPos += Format(output[m_iPos], maxlen-m_iPos, "%s\"%s\": true", m_szTabs, m_szKey); | |
else | |
m_iPos += Format(output[m_iPos], maxlen-m_iPos, "%s\"%s\": false", m_szTabs, m_szKey); | |
} | |
case Type_Integer: | |
{ | |
decl m_iValue; | |
GetTrieValue(m_hObject, "value", m_iValue); | |
m_iPos += Format(output[m_iPos], maxlen-m_iPos, "%s\"%s\": %d", m_szTabs, m_szKey, m_iValue); | |
} | |
case Type_Float: | |
{ | |
decl Float:m_fValue; | |
GetTrieValue(m_hObject, "value", m_fValue); | |
m_iPos += Format(output[m_iPos], maxlen-m_iPos, "%s\"%s\": %f", m_szTabs, m_szKey, m_fValue); | |
} | |
case Type_Object: | |
{ | |
decl Handle:m_hValue; | |
GetTrieValue(m_hObject, "value", m_hValue); | |
m_iPos += Format(output[m_iPos], maxlen-m_iPos, "%s\"%s\": ", m_szTabs, m_szKey); | |
new m_iLen = -1; | |
EncodeJSON(m_hValue, output[m_iPos], maxlen-m_iPos, beautify, m_iLen, tabs+1); | |
m_iPos += m_iLen; | |
} | |
case Type_Array: | |
{ | |
decl Handle:m_hValue; | |
GetTrieValue(m_hObject, "value", m_hValue); | |
m_iPos += Format(output[m_iPos], maxlen-m_iPos, "%s\"%s\": ", m_szTabs, m_szKey); | |
new m_iLen = -1; | |
EncodeArray(m_hValue, output[m_iPos], maxlen-m_iPos, beautify, m_iLen, tabs+1); | |
m_iPos += m_iLen+1; | |
} | |
default: | |
{ | |
continue; | |
} | |
} | |
if(m_iPos >= maxlen) | |
return; | |
if(m_iKeys != i+1) | |
{ | |
output[m_iPos] = ','; | |
++m_iPos; | |
} | |
if(m_iPos >= maxlen) | |
return; | |
if(beautify) | |
{ | |
output[m_iPos] = '\n'; | |
++m_iPos; | |
} | |
} | |
if(m_iPos < maxlen) | |
{ | |
m_szTabs[tabs-1] = 0; | |
m_iPos += Format(output[m_iPos], maxlen-m_iPos, "%s}", m_szTabs); | |
} | |
if(len != 0) | |
len=m_iPos; | |
} | |
stock EncodeArray(&Handle:json, String:output[], maxlen, bool:beautify=true, &len=0, tabs=1) | |
{ | |
decl Handle:m_hObject; | |
if(2 >= maxlen) | |
return; | |
new String:m_szTabs[tabs+1]; | |
if(beautify) | |
for(new i=0;i<tabs;++i) | |
m_szTabs[i] = '\t'; | |
new m_iPos = 1; | |
output[0] = '['; | |
if(beautify) | |
{ | |
output[1] = '\n'; | |
++m_iPos; | |
} | |
new m_iKeys = GetArraySize(json); | |
for(new i=0;i<m_iKeys;++i) | |
{ | |
m_hObject = GetArrayCell(json, i); | |
decl JSONType:m_eType; | |
GetTrieValue(m_hObject, "type", m_eType); | |
switch(m_eType) | |
{ | |
case Type_String: | |
{ | |
decl m_iLength; | |
GetTrieValue(m_hObject, "size", m_iLength); | |
decl String:m_szValue[m_iLength*2+1]; | |
GetTrieString(m_hObject, "value", m_szValue, m_iLength+1); | |
ReplaceString(m_szValue, m_iLength*2+1, "\"", "\\\""); | |
m_iPos += Format(output[m_iPos], maxlen-m_iPos, "%s\"%s\"", m_szTabs, m_szValue); | |
} | |
case Type_Boolean: | |
{ | |
decl bool:m_bValue; | |
GetTrieValue(m_hObject, "value", m_bValue); | |
if(m_bValue) | |
m_iPos += Format(output[m_iPos], maxlen-m_iPos, "%strue", m_szTabs); | |
else | |
m_iPos += Format(output[m_iPos], maxlen-m_iPos, "%sfalse", m_szTabs); | |
} | |
case Type_Integer: | |
{ | |
decl m_iValue; | |
GetTrieValue(m_hObject, "value", m_iValue); | |
m_iPos += Format(output[m_iPos], maxlen-m_iPos, "%s%d", m_szTabs, m_iValue); | |
} | |
case Type_Float: | |
{ | |
decl Float:m_fValue; | |
GetTrieValue(m_hObject, "value", m_fValue); | |
m_iPos += Format(output[m_iPos], maxlen-m_iPos, "%s%f", m_szTabs, m_fValue); | |
} | |
case Type_Object: | |
{ | |
decl Handle:m_hValue; | |
GetTrieValue(m_hObject, "value", m_hValue); | |
m_iPos += Format(output[m_iPos], maxlen-m_iPos, "%s", m_szTabs); | |
new m_iLen = -1; | |
EncodeJSON(m_hValue, output[m_iPos], maxlen-m_iPos, beautify, m_iLen, tabs+1); | |
m_iPos += m_iLen; | |
} | |
case Type_Array: | |
{ | |
decl Handle:m_hValue; | |
GetTrieValue(m_hObject, "value", m_hValue); | |
m_iPos += Format(output[m_iPos], maxlen-m_iPos, "%s", m_szTabs); | |
new m_iLen = -1; | |
EncodeArray(m_hValue, output[m_iPos], maxlen-m_iPos, beautify, m_iLen, tabs+1); | |
m_iPos += m_iLen; | |
} | |
} | |
if(m_iPos >= maxlen) | |
return; | |
if(m_iKeys != i+1) | |
{ | |
output[m_iPos] = ','; | |
++m_iPos; | |
} | |
if(m_iPos >= maxlen) | |
return; | |
if(beautify) | |
{ | |
output[m_iPos] = '\n'; | |
++m_iPos; | |
} | |
} | |
if(m_iPos < maxlen) | |
{ | |
m_szTabs[tabs-1] = 0; | |
m_iPos += Format(output[m_iPos], maxlen-m_iPos, "%s]", m_szTabs); | |
} | |
if(len != 0) | |
len=m_iPos-1; | |
} | |
stock JSONSetString(&Handle:json, const String:key[], const String:value[]) | |
{ | |
new Handle:m_hKeyArray = INVALID_HANDLE; | |
if(!GetTrieValue(json, "json_key_array", m_hKeyArray)) | |
return; | |
PushArrayString(m_hKeyArray, key); | |
new Handle:m_hObject = JSONCreateString(value); | |
SetTrieValue(json, key, m_hObject); | |
} | |
stock JSONSetBoolean(&Handle:json, const String:key[], bool:value) | |
{ | |
new Handle:m_hKeyArray = INVALID_HANDLE; | |
if(!GetTrieValue(json, "json_key_array", m_hKeyArray)) | |
return; | |
PushArrayString(m_hKeyArray, key); | |
new Handle:m_hObject = JSONCreateBoolean(value); | |
SetTrieValue(json, key, m_hObject); | |
} | |
stock JSONSetInteger(&Handle:json, const String:key[], value) | |
{ | |
new Handle:m_hKeyArray = INVALID_HANDLE; | |
if(!GetTrieValue(json, "json_key_array", m_hKeyArray)) | |
return; | |
PushArrayString(m_hKeyArray, key); | |
new Handle:m_hObject = JSONCreateInteger(value); | |
SetTrieValue(json, key, m_hObject); | |
} | |
stock JSONSetFloat(&Handle:json, const String:key[], Float:value) | |
{ | |
new Handle:m_hKeyArray = INVALID_HANDLE; | |
if(!GetTrieValue(json, "json_key_array", m_hKeyArray)) | |
return; | |
PushArrayString(m_hKeyArray, key); | |
new Handle:m_hObject = JSONCreateFloat(value); | |
SetTrieValue(json, key, m_hObject); | |
} | |
stock JSONSetObject(&Handle:json, const String:key[], Handle:value) | |
{ | |
new Handle:m_hKeyArray = INVALID_HANDLE; | |
if(!GetTrieValue(json, "json_key_array", m_hKeyArray)) | |
return; | |
PushArrayString(m_hKeyArray, key); | |
new Handle:m_hObject = JSONCreateObject(value); | |
SetTrieValue(json, key, m_hObject); | |
} | |
stock JSONSetArray(&Handle:json, const String:key[], Handle:value) | |
{ | |
new Handle:m_hKeyArray = INVALID_HANDLE; | |
if(!GetTrieValue(json, "json_key_array", m_hKeyArray)) | |
return; | |
PushArrayString(m_hKeyArray, key); | |
new Handle:m_hObject = JSONCreateArray(value); | |
SetTrieValue(json, key, m_hObject); | |
} | |
stock Handle:JSONCreateString(const String:value[]) | |
{ | |
new Handle:m_hObject = CreateTrie(); | |
SetTrieString(m_hObject, "value", value); | |
SetTrieValue(m_hObject, "type", Type_String); | |
SetTrieValue(m_hObject, "size", strlen(value)); | |
return m_hObject; | |
} | |
stock Handle:JSONCreateBoolean(bool:value) | |
{ | |
new Handle:m_hObject = CreateTrie(); | |
SetTrieValue(m_hObject, "value", value); | |
SetTrieValue(m_hObject, "type", Type_Boolean); | |
SetTrieValue(m_hObject, "size", sizeof(value)); | |
return m_hObject; | |
} | |
stock Handle:JSONCreateInteger(value) | |
{ | |
new Handle:m_hObject = CreateTrie(); | |
SetTrieValue(m_hObject, "value", value); | |
SetTrieValue(m_hObject, "type", Type_Integer); | |
SetTrieValue(m_hObject, "size", sizeof(value)); | |
return m_hObject; | |
} | |
stock Handle:JSONCreateFloat(Float:value) | |
{ | |
new Handle:m_hObject = CreateTrie(); | |
SetTrieValue(m_hObject, "value", value); | |
SetTrieValue(m_hObject, "type", Type_Float); | |
SetTrieValue(m_hObject, "size", sizeof(value)); | |
return m_hObject; | |
} | |
stock Handle:JSONCreateObject(Handle:value) | |
{ | |
new Handle:m_hObject = CreateTrie(); | |
SetTrieValue(m_hObject, "value", value); | |
SetTrieValue(m_hObject, "type", Type_Object); | |
SetTrieValue(m_hObject, "size", sizeof(value)); | |
return m_hObject; | |
} | |
stock Handle:JSONCreateArray(Handle:value) | |
{ | |
new Handle:m_hObject = CreateTrie(); | |
SetTrieValue(m_hObject, "value", value); | |
SetTrieValue(m_hObject, "type", Type_Array); | |
SetTrieValue(m_hObject, "size", sizeof(value)); | |
return m_hObject; | |
} | |
stock bool:JSONGetString(&Handle:json, const String:key[], String:out[], maxlen) | |
{ | |
decl Handle:m_hObject; | |
if(!GetTrieValue(json, key, m_hObject)) | |
return false; | |
decl JSONType:m_eType; | |
GetTrieValue(m_hObject, "type", m_eType); | |
if(m_eType != Type_String) | |
return false; | |
GetTrieString(m_hObject, "value", out, maxlen); | |
return true; | |
} | |
stock bool:JSONGetObject(&Handle:json, const String:key[], &Handle:out) | |
{ | |
decl Handle:m_hObject; | |
if(!GetTrieValue(json, key, m_hObject)) | |
return false; | |
decl JSONType:m_eType; | |
GetTrieValue(m_hObject, "type", m_eType); | |
if(m_eType != Type_Object) | |
return false; | |
GetTrieValue(m_hObject, "value", out); | |
return true; | |
} | |
stock bool:JSONGetArray(&Handle:json, const String:key[], &Handle:out) | |
{ | |
decl Handle:m_hObject; | |
if(!GetTrieValue(json, key, m_hObject)) | |
return false; | |
decl JSONType:m_eType; | |
GetTrieValue(m_hObject, "type", m_eType); | |
if(m_eType != Type_Array) | |
return false; | |
GetTrieValue(m_hObject, "value", out); | |
return true; | |
} | |
stock bool:JSONGetBoolean(&Handle:json, const String:key[], &bool:value) | |
{ | |
decl Handle:m_hObject; | |
if(!GetTrieValue(json, key, m_hObject)) | |
return false; | |
decl JSONType:m_eType; | |
GetTrieValue(m_hObject, "type", m_eType); | |
if(m_eType != Type_Boolean) | |
return false; | |
GetTrieValue(m_hObject, "value", value); | |
return true; | |
} | |
stock bool:JSONGetInteger(&Handle:json, const String:key[], &value) | |
{ | |
decl Handle:m_hObject; | |
if(!GetTrieValue(json, key, m_hObject)) | |
return false; | |
decl JSONType:m_eType; | |
GetTrieValue(m_hObject, "type", m_eType); | |
if(m_eType != Type_Integer) | |
return false; | |
GetTrieValue(m_hObject, "value", value); | |
return true; | |
} | |
stock bool:JSONGetFloat(&Handle:json, const String:key[], &Float:value) | |
{ | |
decl Handle:m_hObject; | |
if(!GetTrieValue(json, key, m_hObject)) | |
return false; | |
decl JSONType:m_eType; | |
GetTrieValue(m_hObject, "type", m_eType); | |
// For compatibility reasons only, but you should follow strict types | |
if(m_eType != Type_Float && m_eType != Type_Integer) | |
return false; | |
if(m_eType == Type_Integer) | |
{ | |
decl m_iValue; | |
GetTrieValue(m_hObject, "value", m_iValue); | |
value = float(m_iValue); | |
} | |
else | |
GetTrieValue(m_hObject, "value", value); | |
return true; | |
} | |
stock bool:JSONGetArrayString(&Handle:array, idx, String:out[], maxlen) | |
{ | |
new Handle:m_hObject = GetArrayCell(array, idx); | |
decl JSONType:m_eType; | |
GetTrieValue(m_hObject, "type", m_eType); | |
if(m_eType != Type_String) | |
return false; | |
GetTrieString(m_hObject, "value", out, maxlen); | |
return true; | |
} | |
stock bool:JSONGetArrayObject(&Handle:array, idx, &Handle:out) | |
{ | |
new Handle:m_hObject = GetArrayCell(array, idx); | |
decl JSONType:m_eType; | |
GetTrieValue(m_hObject, "type", m_eType); | |
if(m_eType != Type_Object) | |
return false; | |
GetTrieValue(m_hObject, "value", out); | |
return true; | |
} | |
stock bool:JSONGetArrayArray(&Handle:array, idx, &Handle:out) | |
{ | |
new Handle:m_hObject = GetArrayCell(array, idx); | |
decl JSONType:m_eType; | |
GetTrieValue(m_hObject, "type", m_eType); | |
if(m_eType != Type_Array) | |
return false; | |
GetTrieValue(m_hObject, "value", out); | |
return true; | |
} | |
stock bool:JSONGetArrayBoolean(&Handle:array, idx, &bool:value) | |
{ | |
new Handle:m_hObject = GetArrayCell(array, idx); | |
decl JSONType:m_eType; | |
GetTrieValue(m_hObject, "type", m_eType); | |
if(m_eType != Type_Boolean) | |
return false; | |
GetTrieValue(m_hObject, "value", value); | |
return true; | |
} | |
stock bool:JSONGetArrayInteger(&Handle:array, idx, &value) | |
{ | |
new Handle:m_hObject = GetArrayCell(array, idx); | |
decl JSONType:m_eType; | |
GetTrieValue(m_hObject, "type", m_eType); | |
if(m_eType != Type_Integer) | |
return false; | |
GetTrieValue(m_hObject, "value", value); | |
return true; | |
} | |
stock bool:JSONGetArrayFloat(&Handle:array, idx, &Float:value) | |
{ | |
new Handle:m_hObject = GetArrayCell(array, idx); | |
decl JSONType:m_eType; | |
GetTrieValue(m_hObject, "type", m_eType); | |
// For compatibility reasons only, but you should follow strict types | |
if(m_eType != Type_Float && m_eType != Type_Integer) | |
return false; | |
if(m_eType == Type_Integer) | |
{ | |
decl m_iValue; | |
GetTrieValue(m_hObject, "value", m_iValue); | |
value = float(m_iValue); | |
} | |
else | |
GetTrieValue(m_hObject, "value", value); | |
return true; | |
} | |
stock JSONIgnore(const String:json[]) | |
{ | |
new m_iLength = strlen(json); | |
for(new i=0;i<m_iLength;++i) | |
if(json[i] != ' ' && json[i] != '\t' && json[i] != ':' && json[i] != '\n' && json[i] != '\r' && json[i] != ',') | |
return i; | |
return -1; | |
} | |
stock JSONIsNumeric(const String:string[]) | |
{ | |
new m_iLength = strlen(string); | |
new i = 0; | |
if(string[0] == '-') | |
i = 1; | |
for(;i<m_iLength;++i) | |
if(!(48<=string[i]<=57)) | |
return false; | |
return true; | |
} | |
stock bool:GetJSONString(const String:json[], &start, &end) | |
{ | |
decl m_iCharPos; | |
new m_iPos = JSONIgnore(json); | |
if(json[m_iPos] == '"') | |
++m_iPos; | |
start = m_iPos; | |
if(json[m_iPos-1] == '"') | |
{ | |
while((m_iCharPos = FindCharInString(json[m_iPos], '"')) != -1) | |
{ | |
m_iPos += m_iCharPos; | |
if(json[m_iPos-1] == '\\') | |
continue; | |
end = m_iPos; | |
return true; | |
} | |
} | |
new m_iLength = strlen(json); | |
for(;m_iPos<m_iLength;++m_iPos) | |
{ | |
if(m_iPos != 0 && !(48<=json[m_iPos]<=57) && !(97<=json[m_iPos]<=122) && json[m_iPos] != '-' && json[m_iPos] != '.') | |
{ | |
end = m_iPos; | |
return true; | |
} | |
} | |
return false; | |
} | |
stock DestroyJSON(&Handle:json) | |
{ | |
new Handle:m_hKeyArray = INVALID_HANDLE; | |
if(!GetTrieValue(json, "json_key_array", m_hKeyArray)) | |
{ | |
CloseHandle(json); | |
return; | |
} | |
new m_iKeys = GetArraySize(m_hKeyArray); | |
decl String:m_szKey[512]; | |
decl Handle:m_hObject; | |
for(new i=0;i<m_iKeys;++i) | |
{ | |
GetArrayString(m_hKeyArray, i, m_szKey, sizeof(m_szKey)); | |
if(!GetTrieValue(json, m_szKey, m_hObject)) | |
continue; | |
decl JSONType:m_eType; | |
GetTrieValue(m_hObject, "type", m_eType); | |
if(m_eType == Type_Object) | |
{ | |
new Handle:m_hValue; | |
GetTrieValue(m_hObject, "value", m_hValue); | |
DestroyJSON(m_hValue); | |
} else if(m_eType == Type_Array) | |
{ | |
new Handle:m_hValue; | |
GetTrieValue(m_hObject, "value", m_hValue); | |
DestroyJSONArray(m_hValue); | |
} | |
else | |
CloseHandle(m_hObject); | |
} | |
CloseHandle(m_hKeyArray); | |
CloseHandle(json); | |
} | |
stock DestroyJSONArray(&Handle:array) | |
{ | |
new m_iLength = GetArraySize(array); | |
for(new i=0;i<m_iLength;++i) | |
{ | |
new Handle:m_hItem; | |
m_hItem = GetArrayCell(array, i); | |
decl JSONType:m_eType; | |
GetTrieValue(m_hItem, "type", m_eType); | |
if(m_eType == Type_Object) | |
{ | |
new Handle:m_hValue; | |
GetTrieValue(m_hItem, "value", m_hValue); | |
DestroyJSON(m_hValue); | |
} else if(m_eType == Type_Array) | |
{ | |
new Handle:m_hValue; | |
GetTrieValue(m_hItem, "value", m_hValue); | |
DestroyJSONArray(m_hValue); | |
} | |
else | |
CloseHandle(m_hItem); | |
} | |
CloseHandle(array); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment