I needed to make the code easier to use with other modules in my code. To do this, I have changed the
jsonDocument in
jsonCreateDocument() to an
integer (reference to an array element held inside the json module).
_jsonDocuments[] holds the data.
You only need to change 2 lines and the rest of the code works. But it makes the module really easy to use with other code
No need to pass a jsonDocument by reference into other functions.
Where you start the code with:
doc As jsonDocument
jsonCreateDocument(doc)
Change it to:
doc as integer
doc = jsonCreateDocument(-1)
You can call this as many times as you need, it will return a new integer each time, and the json module will create a new jsonDocument.
Here is my revised version of your code:
#constant JSONTYPE_UNKNOWN =-1
#constant JSONTYPE_INTEGER = 0
#constant JSONTYPE_FLOAT = 1
#constant JSONTYPE_STRING = 2
#constant JSONTYPE_BOOL = 3
#constant JSONTYPE_NULL = 4
#constant JSONTYPE_OBJECT = 5
#constant JSONTYPE_ARRAY = 6
#constant JSON_ENDL = Chr(13) + Chr(10)
Type jsonValue
str As String
obj As jsonObject
ary As jsonArray
typ As Integer
EndType
Type jsonElement
key as string
id As Integer
EndType
Type jsonArray
id As Integer[]
EndType
Type jsonObject
object As jsonElement[]
EndType
type jsonDocument
file As string
code As String
ident As String
fid As Integer
char As Integer[1]
container As jsonValue[]
endtype
Global __json_g_whitespace As String
Global __json_g_errortext As String[]
global _jsonDocuments as jsonDocument[]
// ----------------------------------------------------------------------------
// DOCUMENTED FUNCTIONS
//
// Document Load/Save/Create
// -----------------------------------------------------------------------------
//
Function jsonCreateDocument(docId as integer)
__json_g_whitespace = Chr(09) + Chr(32) + Chr(10) + Chr(13)
if docId = -1
_jsonDocuments.length = _jsonDocuments.length + 1
docId = _jsonDocuments.length
endif
_jsonDocuments[docId].code = ""
_jsonDocuments[docId].ident = ""
_jsonDocuments[docId].fid = -1
dummy As jsonObject
__json_create_new_object(docId, dummy, "root")
EndFunction docId
Function jsonLoad(docId as integer, file As String)
If GetFileExists(file)
_jsonDocuments[docId].file = file
_jsonDocuments[docId].fid = OpenToRead(file)
__json_read_next_byte(docId)
__json_skip_whitespace(docId)
__json_parse_object(docId, _jsonDocuments[docId].container[0])
CloseFile(_jsonDocuments[docId].fid)
_jsonDocuments[docId].fid = -1
EndIf
_jsonDocuments[docId].file = file
EndFunction
Function jsonSave(docId as integer)
_jsonDocuments[docId].code = ""
__json_build_code(docId, _jsonDocuments[docId].container[0])
f As Integer
f = OpenToWrite(_jsonDocuments[docId].file, 0)
If FileIsOpen(f) = 1
WriteLine(f, _jsonDocuments[docId].code)
CloseFile(f)
EndIf
EndFunction
Function jsonSaveAs(file As String, docId as integer)
_jsonDocuments[docId].file = file
jsonSave(docId)
EndFunction
Function jsonClearDocument(docId as integer)
While _jsonDocuments[docId].container.length >= 0
__json_clear_value(docId, _jsonDocuments[docId].container[0])
_jsonDocuments[docId].container.remove(0)
EndWhile
_jsonDocuments[docId].code = ""
_jsonDocuments[docId].ident = ""
_jsonDocuments[docId].char[0] = 0
_jsonDocuments[docId].char[1] = 0
_jsonDocuments[docId].fid = -1
_jsonDocuments[docId].file = ""
EndFunction
Function jsonValidateDocument(docId as integer)
orig As String
orig = _jsonDocuments[docId].file
jsonSaveAs("validate_" + orig, docId)
jsonClearDocument(docId)
jsonCreateDocument(docId)
jsonLoad(docId, "validate_" + orig)
_jsonDocuments[docId].file = orig
DeleteFile("validate_" + orig)
EndFunction
// Values Set/Create
// -----------------------------------------------------------------------------
//
Function jsonCreateStringValue(value As String)
out As jsonValue
out.typ = JSONTYPE_STRING
out.str = value
EndFunction out
Function jsonCreateFloatValue(value As Float)
out As jsonValue
out.typ = JSONTYPE_FLOAT
out.str = TruncateString(Str(value), "0")
EndFunction out
Function jsonCreateIntegerValue(value As Integer)
out As jsonValue
out.typ = JSONTYPE_INTEGER
out.str = Str(value)
EndFunction out
Function jsonCreateBooleanValue(value As Integer)
out As jsonValue
out.typ = JSONTYPE_BOOL
v As String = "false"
If value > 0 Then v = "true"
out.str = v
EndFunction out
Function jsonCreateNullValue()
out As jsonValue
out.typ = JSONTYPE_NULL
out.str = "null"
EndFunction out
Function jsonCreateObjectValue()
out As jsonValue
out.typ = JSONTYPE_OBJECT
out.str = ""
EndFunction out
Function jsonCreateArrayValue()
out As jsonValue
out.typ = JSONTYPE_ARRAY
out.str = ""
EndFunction out
Function jsonSetValue(docId as integer, id As Integer, value Ref As jsonValue)
If id < 0 Or id > _jsonDocuments[docId].container.length Then ExitFunction
If value.typ = JSONTYPE_UNKNOWN Then ExitFunction
_jsonDocuments[docId].container[id] = value
EndFunction
Function jsonGetValueAsString(docId as integer, valueId As Integer)
if valueId < 0 Or valueID > _jsonDocuments[docId].container.length Then ExitFunction ""
EndFunction _jsonDocuments[docId].container[valueId].str
Function jsonGetValueAsInteger(docId as integer, valueId As Integer, base As Integer)
if valueId < 0 Or valueID > _jsonDocuments[docId].container.length Then ExitFunction 0
if _jsonDocuments[docId].container[valueId].typ <> JSONTYPE_INTEGER Then ExitFunction 0
out As Integer
out = Val(_jsonDocuments[docId].container[valueId].str, base)
EndFunction out
Function jsonGetValueAsFloat(docId as integer, valueId As Integer)
if valueId < 0 Or valueID > _jsonDocuments[docId].container.length Then ExitFunction 0.0
if _jsonDocuments[docId].container[valueId].typ <> JSONTYPE_FLOAT Then ExitFunction 0.0
out As Float
out = ValFloat(_jsonDocuments[docId].container[valueId].str)
EndFunction out
Function jsonGetValueAsBoolean(docId as integer, valueId As Integer)
if valueId < 0 Or valueID > _jsonDocuments[docId].container.length Then ExitFunction 0
if _jsonDocuments[docId].container[valueId].typ <> JSONTYPE_BOOL Then ExitFunction 0
if CompareString(_jsonDocuments[docId].container[valueId].str, "true") Then ExitFunction 1
EndFunction 0
Function jsonGetValueAsNull(docId as integer, valueId As Integer)
if valueId < 0 Or valueID > _jsonDocuments[docId].container.length Then ExitFunction ""
if _jsonDocuments[docId].container[valueId].typ <> JSONTYPE_NULL Then ExitFunction ""
EndFunction "null"
Function jsonGetValueCount(docId as integer, valueId As Integer)
if valueId < 0 Or valueID > _jsonDocuments[docId].container.length Then ExitFunction -1
If _jsonDocuments[docId].container[valueId].typ = JSONTYPE_OBJECT Then ExitFunction _jsonDocuments[docId].container[valueId].obj.object.length
If _jsonDocuments[docId].container[valueId].typ = JSONTYPE_ARRAY Then ExitFunction _jsonDocuments[docId].container[valueId].ary.id.length
EndFunction -1
Function jsonGetValueType(docId as integer, valueId As Integer)
if valueId < 0 Or valueID > _jsonDocuments[docId].container.length Then ExitFunction JSONTYPE_UNKNOWN
EndFunction _jsonDocuments[docId].container[valueID].typ
// Object Get/Set/Remove Values
// -----------------------------------------------------------------------------
//
Function jsonGetObject(docId as integer, path As String)
id As Integer = -1
id = __json_find_object(docId, path, _jsonDocuments[docId].container[0].obj, 0)
If id < 0 Then ExitFunction -1
If _jsonDocuments[docId].container[id].typ <> JSONTYPE_OBJECT Then ExitFunction -1
EndFunction id
Function jsonGetObjectEntry(docId as integer, objId As Integer, key As String)
If objId < 0 Or objID > _jsonDocuments[docId].container.length Then ExitFunction -1
id As Integer = -1
id = __json_find_value_by_key(docId, _jsonDocuments[docId].container[objId].obj, key, 0)
EndFunction id
Function jsonGetObjectEntryAt(docId as integer, objId As Integer, index As Integer)
If objId < 0 Or objID > _jsonDocuments[docId].container.length Then ExitFunction -1
If _jsonDocuments[docId].container[objId].typ <> JSONTYPE_OBJECT Then ExitFunction -1
If index > _jsonDocuments[docId].container[objId].obj.object.length Or index < 0 Then ExitFunction -1
EndFunction _jsonDocuments[docId].container[objId].obj.object[index].id
Function jsonGetObjectNameAt(docId as integer, objId As Integer, index As Integer)
If objId < 0 Or objID > _jsonDocuments[docId].container.length Then ExitFunction ""
If _jsonDocuments[docId].container[objId].typ <> JSONTYPE_OBJECT Then ExitFunction ""
If index > _jsonDocuments[docId].container[objId].obj.object.length Or index < 0 Then ExitFunction ""
EndFunction _jsonDocuments[docId].container[objId].obj.object[index].key
Function jsonSetObjectValue(docId as integer, path As String, key As String, value Ref As jsonValue, create As Integer)
id as Integer
oid As Integer
oid = __json_find_object(docId, path, _jsonDocuments[docId].container[0].obj, create)
If _jsonDocuments[docId].container[oid].typ <> JSONTYPE_OBJECT Then ExitFunction -1
id = __json_find_value_by_key(docId, _jsonDocuments[docId].container[oid].obj, key, create)
If id < 0 Then ExitFunction -1
jsonSetValue(docId, id, value)
EndFunction id
Function jsonRemoveObjectContent(docId as integer, path As String)
objId As Integer
objId = jsonGetObject(docId, path)
jsonRemoveObjectContentById(docId, objId)
EndFunction
Function jsonRemoveObjectContentById(docId as integer, objId As Integer)
If objId < 0 Or objId > _jsonDocuments[docId].container.length Then ExitFunction
If _jsonDocuments[docId].container[objId].typ <> JSONTYPE_OBJECT Then ExitFunction
While _jsonDocuments[docId].container[objId].obj.object.length >= 0
jsonRemoveObjectEntryAt(docId, objId, 0)
EndWhile
EndFunction
Function jsonRemoveObjectEntry(docId as integer, path As String, key As String)
objId As Integer
objId = jsonGetObject(docId, path)
jsonRemoveObjectEntryById(docId, objId, key)
EndFunction
Function jsonRemoveObjectEntryById(docId as integer, objId As Integer, key As String)
If objId < 0 Or objId > _jsonDocuments[docId].container.length Then ExitFunction
If _jsonDocuments[docId].container[objId].typ <> JSONTYPE_OBJECT Then ExitFunction
id As Integer
id = jsonGetObjectEntry(docId, objId, key)
if id < 0 Then ExitFunction
__json_find_value_by_key(docId, _jsonDocuments[docId].container[objId].obj, key, -1)
EndFunction
Function jsonRemoveObjectEntryAt(docId as integer, objId As Integer, index As Integer)
If objId < 0 Or objId > _jsonDocuments[docId].container.length Then ExitFunction
If _jsonDocuments[docId].container[objId].typ <> JSONTYPE_OBJECT Then ExitFunction
id As Integer
id = jsonGetObjectEntryAt(docId, objId, index)
if id < 0 Then ExitFunction
__json_clear_value(docId, _jsonDocuments[docId].container[id])
_jsonDocuments[docId].container[objId].obj.object.remove(index)
EndFunction
Function jsonGetObjectValue(docId as integer, path As String, key As String)
id as Integer
id = jsonGetObjectEntry(docId, jsonGetObject(docId, path), key)
If id < 0 Then ExitFunction -1
If _jsonDocuments[docId].container[id].typ = JSONTYPE_OBJECT Or _jsonDocuments[docId].container[id].typ = JSONTYPE_ARRAY Then ExitFunction -1
EndFunction id
Function jsonSetObjectValueById(docId as integer, objId As Integer, key As String, value As jsonValue, create As Integer)
If objId < 0 Or objId > _jsonDocuments[docId].container.length Then ExitFunction -1
If _jsonDocuments[docId].container[objid].typ <> JSONTYPE_OBJECT Then ExitFunction -1
If value.typ = JSONTYPE_UNKNOWN Then ExitFunction -1
id as Integer
id = __json_find_value_by_key(docId, _jsonDocuments[docId].container[objId].obj, key, create)
if id < 0 Then ExitFunction -1
jsonSetValue(docId, id, value)
EndFunction id
Function jsonGetObjectValueById(docId as integer, objId As Integer, key As String)
out As jsonValue
out.typ = JSONTYPE_UNKNOWN
If objId < 0 Or objId > _jsonDocuments[docId].container.length Then ExitFunction -1
If _jsonDocuments[docId].container[objid].typ <> JSONTYPE_OBJECT Then ExitFunction -1
id as Integer
id = jsonGetObjectEntry(docId, objId, key)
EndFunction id
// Array Get/Set Values
// -----------------------------------------------------------------------------
//
Function jsonGetArray(docId as integer, path As String, name As String)
id As Integer = -1
id = __json_find_object(docId, path, _jsonDocuments[docId].container[0].obj, 0)
If id < 0 Then ExitFunction -1
If _jsonDocuments[docId].container[id].typ <> JSONTYPE_OBJECT Then ExitFunction -1
id = __json_find_value_by_key(docId, _jsonDocuments[docId].container[id].obj, name, 0)
If id < 0 Then ExitFunction -1
If _jsonDocuments[docId].container[id].typ = JSONTYPE_UNKNOWN Then _jsonDocuments[docId].container[id].typ = JSONTYPE_ARRAY
If _jsonDocuments[docId].container[id].typ <> JSONTYPE_ARRAY Then ExitFunction -1
EndFunction id
Function jsonGetArrayEntry(docId as integer, aryId As Integer, index As Integer)
If aryId < 0 Or aryId > _jsonDocuments[docId].container.length Then ExitFunction -1
If _jsonDocuments[docId].container[aryId].typ <> JSONTYPE_ARRAY Then ExitFunction -1
If index < 0 Then ExitFunction -1
id As Integer = -1
id = __json_find_value_by_index(docId, _jsonDocuments[docId].container[aryId].ary, index, 0)
EndFunction id
Function jsonSetArrayValue(docId as integer, path As String, name As String, index As Integer, value As jsonValue, create As Integer)
aid As Integer
aid = __json_find_object(docId, path, _jsonDocuments[docId].container[0].obj, create)
If aid < 0 Or aid > _jsonDocuments[docId].container.length Then ExitFunction -1
If _jsonDocuments[docId].container[aid].typ <> JSONTYPE_OBJECT Then ExitFunction -1
aid = __json_find_value_by_key(docId, _jsonDocuments[docId].container[id].obj, name, create)
If _jsonDocuments[docId].container[aid].typ = JSONTYPE_UNKNOWN Then _jsonDocuments[docId].container[aid].typ = JSONTYPE_ARRAY
If _jsonDocuments[docId].container[aid].typ <> JSONTYPE_ARRAY Then ExitFunction -1
id as Integer
id = __json_find_value_by_index(docId, _jsonDocuments[docId].container[aid].ary, index, create)
if id < 0 Then ExitFunction -1
jsonSetValue(docId, id, value)
EndFunction id
Function jsonSetArrayValueById(docId as integer, aryId As Integer, index As Integer, value As jsonValue, create As Integer)
If aryId < 0 Or aryId > _jsonDocuments[docId].container.length Then ExitFunction -1
id as Integer
id = __json_find_value_by_index(docId, _jsonDocuments[docId].container[aryId].ary, index, create)
if id < 0 Then ExitFunction -1
jsonSetValue(docId, id, value)
EndFunction id
Function jsonRemoveArrayContent(docId as integer, path As String, name As String)
aryId As Integer
aryId = jsonGetObjectEntry(docId, jsonGetObject(docId, path), name)
If aryId < 0 Or aryId > _jsonDocuments[docId].container.length Then ExitFunction
If _jsonDocuments[docId].container[aryId].typ <> JSONTYPE_ARRAY Then ExitFunction
While _jsonDocuments[docId].container[aryId].ary.id.length >= 0
jsonRemoveArrayEntryById(docId, aryId, 0)
EndWhile
EndFunction
Function jsonRemoveArrayEntry(docId as integer, path As String, name As String, index As Integer)
aryId As Integer
aryId = jsonGetArray(docId, path, name)
If aryId < 0 Then ExitFunction
jsonRemoveArrayEntryById(docId, aryId, index)
EndFunction
Function jsonRemoveArrayEntryById(docId as integer, aryId As Integer, index As Integer)
If aryId < 0 Or aryId > _jsonDocuments[docId].container.length Then ExitFunction
If _jsonDocuments[docId].container[aryId].typ <> JSONTYPE_ARRAY Then ExitFunction
If index < 0 Or index > _jsonDocuments[docId].container[aryId].ary.id.length Then ExitFunction
__json_find_value_by_index(docId, _jsonDocuments[docId].container[aryId].ary, index, -1)
EndFunction
// Error handling
// -----------------------------------------------------------------------------
//
Function jsonHasErrors(docId as integer)
EndFunction __json_g_errortext.length
Function jsonGetErrors(docId as integer)
EndFunction __json_g_errortext
Function jsonClearErrors(docId as integer)
__json_g_errortext.length = -1
EndFunction
// ----------------------------------------------------------------------------
// INTERN FUNCTIONS
//
Function __json_clear_value(docId as integer, value Ref As jsonValue)
If value.typ = JSONTYPE_UNKNOWN Then ExitFunction
If value.ary.id.length >= 0
While value.ary.id.length >= 0
__json_clear_value(docId, _jsonDocuments[docId].container[value.ary.id[0]])
value.ary.id.remove(0)
EndWhile
EndIf
If value.obj.object.length >= 0
While value.obj.object.length >= 0
__json_clear_value(docId, _jsonDocuments[docId].container[value.obj.object[0].id])
value.obj.object.remove(0)
EndWhile
EndIf
value.typ = JSONTYPE_UNKNOWN
value.str = ""
EndFunction
Function __json_find_object(docId as integer, path As String, obj0 Ref As jsonObject, create As Integer)
If Len(path) = 0 Then ExitFunction 0
count As Integer
count = obj0.object.length
token As String
token = GetStringToken(path, "~", 0)
path = Right(path, Len(path) - (Len(token)))
id As Integer = -1
i As Integer
For i=0 To count
If CompareString(token, obj0.object[i].key) = 1
If _jsonDocuments[docId].container[obj0.object[i].id].typ = JSONTYPE_OBJECT
id = obj0.object[i].id
If Len(path) > 1
id = __json_find_object(docId, Right(path, Len(path)-1), _jsonDocuments[docId].container[id].obj, create)
EndIf
EndIf
EndIf
Next
If id = -1 And create = 1 And Len(token) > 0
id = __json_create_new_object(docId, obj0, token)
If Len(path) > 1
id = __json_find_object(docId, Right(path, Len(path)-1), _jsonDocuments[docId].container[id].obj, create)
EndIf
EndIf
EndFunction id
Function __json_create_new_object(docId as integer, parentObj Ref As jsonObject, key As String)
value As jsonValue
value.typ = JSONTYPE_OBJECT
_jsonDocuments[docId].container.insert(value)
id As Integer
id = _jsonDocuments[docId].container.length
If CompareString(key, "root") = 1 Then ExitFunction id
element As jsonElement
element.id = id
element.key = key
parentObj.object.insert(element)
EndFunction id
Function __json_create_new_value(docId as integer)
value As jsonValue
value.typ = JSONTYPE_NULL
_jsonDocuments[docId].container.insert(value)
id As Integer
id = _jsonDocuments[docId].container.length
EndFunction id
Function __json_find_value_by_key(docId as integer, obj Ref As jsonObject, key As String, create As Integer)
count As Integer
count = obj.object.length
If count >= 0
i As Integer
For i=0 To count
If CompareString(obj.object[i].key, key)
If create = -1
__json_clear_value(docId, _jsonDocuments[docId].container[obj.object[i].id])
obj.object.remove(i)
ExitFunction -1
EndIf
ExitFunction obj.object[i].id
EndIf
Next
EndIf
id As Integer = -1
If create = 1
v As jsonValue
v.typ = JSONTYPE_UNKNOWN
_jsonDocuments[docId].container.insert(v)
element As jsonElement
element.key = key
element.id = _jsonDocuments[docId].container.length
obj.object.insert(element)
id = element.id
EndIf
EndFunction id
Function __json_find_value_by_index(docId as integer, ary Ref As jsonArray, index As Integer, create As Integer)
count As Integer
count = ary.id.length
If index > count And create = 1
While index > count
ary.id.insert(__json_create_new_value(docId))
Inc count
EndWhile
ElseIf index > count || index < 0
ExitFunction -1
EndIf
If create = -1
__json_clear_value(docId, _jsonDocuments[docId].container[ary.id[index]])
ary.id.remove(index)
ExitFunction -1
EndIf
EndFunction ary.id[index]
Function __json_build_code(docId as integer, parent Ref As jsonValue)
Select parent.typ
Case JSONTYPE_ARRAY:
__json_build_array_code(docId, parent.ary)
EndCase
Case JSONTYPE_BOOL:
_jsonDocuments[docId].code = _jsonDocuments[docId].code + parent.str
EndCase
Case JSONTYPE_FLOAT:
_jsonDocuments[docId].code = _jsonDocuments[docId].code + __crop_float_string(parent.str)
EndCase
Case JSONTYPE_INTEGER:
_jsonDocuments[docId].code = _jsonDocuments[docId].code + parent.str
EndCase
Case JSONTYPE_NULL:
_jsonDocuments[docId].code = _jsonDocuments[docId].code + "null"
EndCase
Case JSONTYPE_OBJECT:
__json_build_object_code(docId, parent.obj)
EndCase
Case JSONTYPE_STRING:
_jsonDocuments[docId].code = _jsonDocuments[docId].code + Chr(34) + parent.str + Chr(34)
EndCase
Case JSONTYPE_UNKNOWN:
EndCase
EndSelect
EndFunction
Function __crop_float_string(value As String)
pos As Integer
pos = FindString(value, ".", 0, -1)
If pos = 0 Then ExitFunction value
Inc pos, 2
pos = FindString(value, "0", 0, pos)
If pos = 0 Then ExitFunction value
value = Left(value, pos-1)
EndFunction value
Function __json_build_object_code(docId as integer, obj Ref as jsonObject)
_jsonDocuments[docId].ident = _jsonDocuments[docId].ident + " "
hasNested As Integer
hasNested = __json_object_has_nested(docId, obj)
nextVal As String
nextVal = " "
If hasNested = 1 Then nextVal = JSON_ENDL + _jsonDocuments[docId].ident
_jsonDocuments[docId].code = _jsonDocuments[docId].code + "{" + nextVal
count As Integer
count = obj.object.length
i As Integer
For i=0 To count
_jsonDocuments[docId].code = _jsonDocuments[docId].code + Chr(34) + obj.object[i].key + Chr(34) + " : "
__json_build_code(docId, _jsonDocuments[docId].container[obj.object[i].id])
if i <> count Then _jsonDocuments[docId].code = _jsonDocuments[docId].code + "," Else nextVal = Left(nextVal, Len(NextVal)-4)
_jsonDocuments[docId].code = _jsonDocuments[docId].code + nextVal
Next
_jsonDocuments[docId].ident = Left(_jsonDocuments[docId].ident, Len(_jsonDocuments[docId].ident) - 4)
_jsonDocuments[docId].code = _jsonDocuments[docId].code + "}"
EndFunction
Function __json_build_array_code(docId as integer, ary Ref as jsonArray)
_jsonDocuments[docId].ident = _jsonDocuments[docId].ident + " "
hasNested As Integer
hasNested = __json_array_has_nested(docId, ary)
nextVal As String
nextVal = " "
If hasNested = 1 Then nextVal = JSON_ENDL + _jsonDocuments[docId].ident
_jsonDocuments[docId].code = _jsonDocuments[docId].code + "[" + nextVal
count As Integer
count = ary.id.length
i As Integer
For i=0 To count
__json_build_code(docId, _jsonDocuments[docId].container[ary.id[i]])
if i <> count Then _jsonDocuments[docId].code = _jsonDocuments[docId].code + "," Else nextVal = Left(nextVal, Len(NextVal)-2)
_jsonDocuments[docId].code = _jsonDocuments[docId].code + nextVal
Next
_jsonDocuments[docId].ident = Left(_jsonDocuments[docId].ident, Len(_jsonDocuments[docId].ident) - 2)
_jsonDocuments[docId].code = _jsonDocuments[docId].code + "]"
EndFunction
Function __json_object_has_nested(docId as integer, obj Ref As jsonObject)
count As Integer = 0
count = obj.object.length
If count > -1
i As Integer
For i=0 To count
id As Integer
id = obj.object[i].id
If _jsonDocuments[docId].container[id].typ = JSONTYPE_ARRAY Or _jsonDocuments[docId].container[id].typ = JSONTYPE_OBJECT Then ExitFunction 1
//~ If _jsonDocuments[docId].container[id].typ = JSONTYPE_STRING And count > 8 Then ExitFunction 1
If count > 8 Then ExitFunction 1
Next
EndIf
EndFunction 0
Function __json_array_has_nested(docId as integer, ary Ref As jsonArray)
out As Integer = 0
count As Integer = 0
count = ary.id.length
If count > -1
i As Integer
For i=0 To count
id As Integer
id = ary.id[i]
if _jsonDocuments[docId].container[id].typ = JSONTYPE_ARRAY Or _jsonDocuments[docId].container[id].typ = JSONTYPE_OBJECT Then out = 1
Next
Endif
EndFunction out
Function __json_parse_object(docId as integer, parent Ref As jsonValue)
__json_skip_whitespace(docId)
If _jsonDocuments[docId].char[0] = 0x7b // {
__json_read_next_byte(docId)
__json_skip_whitespace(docId)
parent.typ = JSONTYPE_OBJECT
While _jsonDocuments[docId].char[0] <> 0x7d // }
element As jsonElement
element.key = __json_parse_key(docId)
element.id = __json_parse_value(docId)
parent.obj.object.insert(element)
__json_skip_whitespace(docId)
if _jsonDocuments[docId].char[0] = 0x2c Then __json_read_next_byte(docId)
EndWhile
__json_read_next_byte(docId)
EndIf
EndFunction
Function __json_parse_array(docId as integer, parent Ref As jsonValue)
__json_skip_whitespace(docId)
If _jsonDocuments[docId].char[0] = 0x5b // [
__json_read_next_byte(docId)
__json_skip_whitespace(docId)
parent.typ = JSONTYPE_ARRAY
While _jsonDocuments[docId].char[0] <> 0x5d // ]
id As Integer
id = __json_parse_value(docId)
parent.ary.id.insert(id)
__json_skip_whitespace(docId)
if _jsonDocuments[docId].char[0] = 0x2c Then __json_read_next_byte(docId)
EndWhile
__json_read_next_byte(docId)
EndIf
EndFunction
Function __json_parse_string(docId as integer, parent Ref As jsonValue)
__json_skip_whitespace(docId)
If _jsonDocuments[docId].char[0] = 0x22 // "
parent.typ = JSONTYPE_STRING
parent.str = __json_parse_common_string(docId)
EndIf
EndFunction
Function __json_parse_boolean(docId as integer, parent Ref As jsonValue)
parent.typ = JSONTYPE_UNKNOWN
parent.str = ""
While __json_is_alpha(_jsonDocuments[docId].char[0]) = 1
parent.str = parent.str + Chr(_jsonDocuments[docId].char[0])
__json_read_next_byte(docId)
EndWhile
If CompareString(parent.str, "true", 1, -1) = 1 Or CompareString(parent.str, "false", 1, -1) = 1
parent.typ = JSONTYPE_BOOL
parent.str = Lower(parent.str)
Else
parent.str = ""
__json_g_errortext.insert("Parse error: Can't recognize 'boolean'.")
EndIf
EndFunction
Function __json_parse_null(docId as integer, parent Ref As jsonValue)
parent.typ = JSONTYPE_UNKNOWN
parent.str = ""
While __json_is_alpha(_jsonDocuments[docId].char[0]) = 1
parent.str = parent.str + Chr(_jsonDocuments[docId].char[0])
__json_read_next_byte(docId)
EndWhile
If CompareString(parent.str, "null", 1, -1) = 1
parent.typ = JSONTYPE_NULL
parent.str = Lower(parent.str)
Else
parent.str = ""
__json_g_errortext.insert("Parse error: Can't recognize 'nil'.")
EndIf
EndFunction
Function __json_parse_number(docId as integer, parent Ref As jsonValue)
parent.typ = JSONTYPE_INTEGER
parent.str = ""
While __json_is_realdigit(_jsonDocuments[docId].char[0]) = 1
parent.str = parent.str + Chr(_jsonDocuments[docId].char[0])
If _jsonDocuments[docId].char[0] = 0x2e Then parent.typ = JSONTYPE_FLOAT
__json_read_next_byte(docId)
EndWhile
EndFunction
Function __json_skip_whitespace(docId as integer)
While __json_is_whitespace(_jsonDocuments[docId].char[0]) = 1
__json_read_next_byte(docId)
EndWhile
EndFunction
Function __json_is_realdigit(char As Integer)
out As Integer = 0
if (char >= 0x30 And char <= 0x39) Or char = 0x2e Or char = 0x45 Or char = 0x65 Or char = 0x2d Or char = 0x2b Then out = 1
EndFunction out
Function __json_is_alpha(char As Integer)
out As Integer = 0
if (char >= 0x41 And char <= 0x5a) Or (char >= 0x61 And char <= 0x7a) Then out = 1
EndFunction out
Function __json_is_whitespace(char As Integer)
out As Integer = 0
if char = 32 Or char = 9 Or char = 10 Or char = 13 Then out = 1
EndFunction out
Function __json_is_string_end(char0 As Integer, char1 As Integer)
out As Integer = 0
if char0 = 0x22 And char1 <> 0x5c Then out = 1
EndFunction out
Function __json_read_next_byte(docId as integer)
_jsonDocuments[docId].char[1] = _jsonDocuments[docId].char[0]
_jsonDocuments[docId].char[0] = ReadByte(_jsonDocuments[docId].fid)
EndFunction
Function __json_parse_key(docId as integer)
key As String
key = __json_parse_common_string(docId)
__json_skip_whitespace(docId)
If _jsonDocuments[docId].char[0] <> Asc(":")
__json_g_errortext.insert("Parse error: Can't recognize 'key'.")
EndIf
__json_read_next_byte(docId)
EndFunction key
Function __json_parse_common_string(docId as integer)
out As String
__json_skip_whitespace(docId)
If _jsonDocuments[docId].char[0] = 0x22
__json_read_next_byte(docId)
//~ While _jsonDocuments[docId].char[0] <> 34 And _jsonDocuments[docId].char[1] <> 92
While __json_is_string_end(_jsonDocuments[docId].char[0], _jsonDocuments[docId].char[1]) = 0
out = out + Chr(_jsonDocuments[docId].char[0])
__json_read_next_byte(docId)
EndWhile
Else
__json_g_errortext.insert("Parse error: Is not a string.")
EndIf
__json_read_next_byte(docId)
EndFunction out
Function __json_parse_value(docId as integer)
out As jsonValue
__json_skip_whitespace(docId)
if _jsonDocuments[docId].char[0] >= 0x61 And _jsonDocuments[docId].char[0] <= 0x7a Then Dec _jsonDocuments[docId].char[0], 0x20
Select _jsonDocuments[docId].char[0]
Case 0x7b: // { (Object)
__json_parse_object(docId, out)
EndCase
Case 0x5b: // [ (Array)
__json_parse_array(docId, out)
EndCase
Case 0x22: // " (String)
__json_parse_string(docId, out)
EndCase
Case Default:
If _jsonDocuments[docId].char[0] = 0x54 Or _jsonDocuments[docId].char[0] = 0x46 // True / False
__json_parse_Boolean(docId, out)
ElseIf _jsonDocuments[docId].char[0] = 0x4e // Null
__json_parse_Null(docId, out)
//~ ElseIf _jsonDocuments[docId].char[0] >= 0x30 And _jsonDocuments[docId].char[0] <= 0x39 // Number
ElseIf __json_is_realdigit(_jsonDocuments[docId].char[0]) = 1 // Number
__json_parse_number(docId, out)
Else
__json_g_errortext.insert("Parse error: Can't recognize 'value'.")
EndIf
EndCase
EndSelect
num As Integer
num = _jsonDocuments[docId].container.length + 1
_jsonDocuments[docId].container.insert(out)
EndFunction num
I cannot test everything, but I think it is stable.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Quidquid latine dictum sit, altum sonatur
TutCity is being rebuilt