|
@@ -1,4 +1,4 @@
|
|
-' Copyright (c) 2019-2020 Bruce A Henderson
|
|
|
|
|
|
+' Copyright (c) 2019-2025 Bruce A Henderson
|
|
'
|
|
'
|
|
' This software is provided 'as-is', without any express or implied
|
|
' This software is provided 'as-is', without any express or implied
|
|
' warranty. In no event will the authors be held liable for any damages
|
|
' warranty. In no event will the authors be held liable for any damages
|
|
@@ -26,11 +26,13 @@ bbdoc: JSON Object de/serializer.
|
|
End Rem
|
|
End Rem
|
|
Module Text.JConv
|
|
Module Text.JConv
|
|
|
|
|
|
-ModuleInfo "Version: 1.06"
|
|
|
|
|
|
+ModuleInfo "Version: 1.07"
|
|
ModuleInfo "Author: Bruce A Henderson"
|
|
ModuleInfo "Author: Bruce A Henderson"
|
|
ModuleInfo "License: zlib/png"
|
|
ModuleInfo "License: zlib/png"
|
|
-ModuleInfo "Copyright: 2019-2020 Bruce A Henderson"
|
|
|
|
|
|
+ModuleInfo "Copyright: 2019-2025 Bruce A Henderson"
|
|
|
|
|
|
|
|
+ModuleInfo "History: 1.07"
|
|
|
|
+ModuleInfo "History: Added support for LongInt and ULongInt types."
|
|
ModuleInfo "History: 1.06"
|
|
ModuleInfo "History: 1.06"
|
|
ModuleInfo "History: Added support for transient, noSerialize and noDeserialize field metadata."
|
|
ModuleInfo "History: Added support for transient, noSerialize and noDeserialize field metadata."
|
|
ModuleInfo "History: 1.05"
|
|
ModuleInfo "History: 1.05"
|
|
@@ -103,6 +105,8 @@ Type TJConvBuilder
|
|
RegisterSerializer("TULong", New TULongSerializer)
|
|
RegisterSerializer("TULong", New TULongSerializer)
|
|
RegisterSerializer("TFloat", New TFloatSerializer)
|
|
RegisterSerializer("TFloat", New TFloatSerializer)
|
|
RegisterSerializer("TDouble", New TDoubleSerializer)
|
|
RegisterSerializer("TDouble", New TDoubleSerializer)
|
|
|
|
+ RegisterSerializer("TLongInt", New TLongIntSerializer)
|
|
|
|
+ RegisterSerializer("TULongInt", New TULongIntSerializer)
|
|
Return Self
|
|
Return Self
|
|
End Method
|
|
End Method
|
|
|
|
|
|
@@ -196,7 +200,15 @@ Type TJConv
|
|
|
|
|
|
Method FromJson:Object(txt:String, typeId:TTypeId, obj:Object)
|
|
Method FromJson:Object(txt:String, typeId:TTypeId, obj:Object)
|
|
Local error:TJSONError
|
|
Local error:TJSONError
|
|
- Local json:TJSON = TJSON.Load(txt, 0, error)
|
|
|
|
|
|
+ Local flags:Int = 0
|
|
|
|
+ If typeId = StringTypeId Then
|
|
|
|
+ flags :| JSON_DECODE_ANY
|
|
|
|
+ End If
|
|
|
|
+ Local json:TJSON = TJSON.Load(txt, flags, error)
|
|
|
|
+
|
|
|
|
+ If error Then
|
|
|
|
+ Throw TJconvJsonException.Create(error)
|
|
|
|
+ End If
|
|
|
|
|
|
Return FromJson(json, typeId, obj)
|
|
Return FromJson(json, typeId, obj)
|
|
End Method
|
|
End Method
|
|
@@ -214,6 +226,10 @@ Type TJConv
|
|
Local error:TJSONError
|
|
Local error:TJSONError
|
|
Local json:TJSON = TJSON.Load(stream, 0, error)
|
|
Local json:TJSON = TJSON.Load(stream, 0, error)
|
|
|
|
|
|
|
|
+ If error Then
|
|
|
|
+ Throw TJconvJsonException.Create(error)
|
|
|
|
+ End If
|
|
|
|
+
|
|
Return FromJson(json, typeId, obj)
|
|
Return FromJson(json, typeId, obj)
|
|
End Method
|
|
End Method
|
|
|
|
|
|
@@ -233,6 +249,11 @@ Type TJConv
|
|
End Rem
|
|
End Rem
|
|
Method ToJson:String(obj:Object)
|
|
Method ToJson:String(obj:Object)
|
|
If Not obj Then
|
|
If Not obj Then
|
|
|
|
+
|
|
|
|
+ If ObjectIsString(obj) Then
|
|
|
|
+ Return "~q~q"
|
|
|
|
+ End If
|
|
|
|
+
|
|
If IsEmptyArray(obj) Then
|
|
If IsEmptyArray(obj) Then
|
|
Return "[]"
|
|
Return "[]"
|
|
End If
|
|
End If
|
|
@@ -241,6 +262,12 @@ Type TJConv
|
|
End If
|
|
End If
|
|
|
|
|
|
Local typeId:TTypeId = TTypeId.ForObject(obj)
|
|
Local typeId:TTypeId = TTypeId.ForObject(obj)
|
|
|
|
+
|
|
|
|
+ If typeId = StringTypeId Then
|
|
|
|
+ Local json:TJSONString = New TJSONString.Create(String(obj))
|
|
|
|
+
|
|
|
|
+ Return json.SaveString(flags | JSON_ENCODE_ANY, 0, precision)
|
|
|
|
+ End If
|
|
|
|
|
|
If typeId.ExtendsType(ArrayTypeId) Then
|
|
If typeId.ExtendsType(ArrayTypeId) Then
|
|
Local json:TJSONArray = New TJSONArray.Create()
|
|
Local json:TJSONArray = New TJSONArray.Create()
|
|
@@ -378,7 +405,13 @@ Type TJConv
|
|
|
|
|
|
Case DoubleTypeId
|
|
Case DoubleTypeId
|
|
j = serializer.Serialize(f.GetDouble(obj), fieldType.Name())
|
|
j = serializer.Serialize(f.GetDouble(obj), fieldType.Name())
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ Case LongIntTypeId
|
|
|
|
+ j = serializer.Serialize(f.GetLongInt(obj), fieldType.Name())
|
|
|
|
+
|
|
|
|
+ Case ULongIntTypeId
|
|
|
|
+ j = serializer.Serialize(f.GetULongInt(obj), fieldType.Name())
|
|
|
|
+
|
|
Case StringTypeId
|
|
Case StringTypeId
|
|
Local s:String = f.GetString(obj)
|
|
Local s:String = f.GetString(obj)
|
|
If s Then
|
|
If s Then
|
|
@@ -425,6 +458,11 @@ Type TJConv
|
|
End Method
|
|
End Method
|
|
|
|
|
|
Method ProcessArrayToJson(json:TJSONArray, typeId:TTypeId, array:Object)
|
|
Method ProcessArrayToJson(json:TJSONArray, typeId:TTypeId, array:Object)
|
|
|
|
+
|
|
|
|
+ If IsEmptyArray(array) Then
|
|
|
|
+ Return
|
|
|
|
+ End If
|
|
|
|
+
|
|
Local dims:Int
|
|
Local dims:Int
|
|
Try
|
|
Try
|
|
dims = typeId.ArrayDimensions(array)
|
|
dims = typeId.ArrayDimensions(array)
|
|
@@ -585,6 +623,14 @@ Type TJConvSerializer
|
|
Return New TJSONReal.Create(source)
|
|
Return New TJSONReal.Create(source)
|
|
End Method
|
|
End Method
|
|
|
|
|
|
|
|
+ Method Serialize:TJSON(source:LongInt, sourceType:String)
|
|
|
|
+ Return New TJSONInteger.Create(source)
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Serialize:TJSON(source:ULongInt, sourceType:String)
|
|
|
|
+ Return New TJSONInteger.Create(source)
|
|
|
|
+ End Method
|
|
|
|
+
|
|
Method Serialize:TJSON(source:String, sourceType:String)
|
|
Method Serialize:TJSON(source:String, sourceType:String)
|
|
Return New TJSONString.Create(source)
|
|
Return New TJSONString.Create(source)
|
|
End Method
|
|
End Method
|
|
@@ -597,6 +643,17 @@ Type TJConvSerializer
|
|
|
|
|
|
Method Deserialize:Object(json:TJSON, typeId:TTypeId, obj:Object)
|
|
Method Deserialize:Object(json:TJSON, typeId:TTypeId, obj:Object)
|
|
If TJSONObject(json) Then
|
|
If TJSONObject(json) Then
|
|
|
|
+
|
|
|
|
+ ' we don't deserialize objects to String type
|
|
|
|
+ If typeId = StringTypeId Then
|
|
|
|
+ Throw TJconvDeserializeException.Create("Deserializing String but found Object type.")
|
|
|
|
+ End If
|
|
|
|
+
|
|
|
|
+ ' we don't deserialize objects to Array type
|
|
|
|
+ IF typeId.ExtendsType(ArrayTypeId) Then
|
|
|
|
+ Throw TJconvDeserializeException.Create("Deserializing Array but found Object type.")
|
|
|
|
+ End If
|
|
|
|
+
|
|
If Not obj Then
|
|
If Not obj Then
|
|
obj = typeId.NewObject()
|
|
obj = typeId.NewObject()
|
|
End If
|
|
End If
|
|
@@ -692,14 +749,20 @@ Type TJConvSerializer
|
|
Continue
|
|
Continue
|
|
End Select
|
|
End Select
|
|
|
|
|
|
- If fieldType.ExtendsType(ArrayTypeId) Or fieldType.ExtendsType(ObjectTypeId) Then
|
|
|
|
|
|
+ If fieldType.ExtendsType(ArrayTypeId)
|
|
|
|
+
|
|
|
|
+ Throw TJconvDeserializeException.Create("Deserializing String but found Array type '" + fieldType.Name() + "' : " + j.key)
|
|
|
|
|
|
|
|
+ End If
|
|
|
|
+
|
|
|
|
+ If fieldType.ExtendsType(ObjectTypeId) Then
|
|
|
|
+
|
|
Local fobj:Object = jconv.FromJson(j, fieldType, Null)
|
|
Local fobj:Object = jconv.FromJson(j, fieldType, Null)
|
|
|
|
|
|
If fobj Then
|
|
If fobj Then
|
|
f.Set(obj, fobj)
|
|
f.Set(obj, fobj)
|
|
End If
|
|
End If
|
|
-
|
|
|
|
|
|
+
|
|
End If
|
|
End If
|
|
|
|
|
|
Continue
|
|
Continue
|
|
@@ -729,6 +792,10 @@ Type TJConvSerializer
|
|
End If
|
|
End If
|
|
Next
|
|
Next
|
|
Else If TJSONArray(json) Then
|
|
Else If TJSONArray(json) Then
|
|
|
|
+
|
|
|
|
+ If typeId = StringTypeId Then
|
|
|
|
+ Throw TJconvDeserializeException.Create("Deserializing String but found Array type.")
|
|
|
|
+ End If
|
|
|
|
|
|
obj = Deserialize(TJSONArray(json), typeId, obj)
|
|
obj = Deserialize(TJSONArray(json), typeId, obj)
|
|
|
|
|
|
@@ -746,7 +813,7 @@ Type TJConvSerializer
|
|
Local size:Int = jsonArray.Size()
|
|
Local size:Int = jsonArray.Size()
|
|
|
|
|
|
If Not size Then
|
|
If Not size Then
|
|
- Return typeId.NewArray()
|
|
|
|
|
|
+ Return typeId.NullValue()
|
|
End If
|
|
End If
|
|
|
|
|
|
Local elementType:TTypeId = typeId.ElementType()
|
|
Local elementType:TTypeId = typeId.ElementType()
|
|
@@ -929,6 +996,27 @@ Type TDouble
|
|
|
|
|
|
End Type
|
|
End Type
|
|
|
|
|
|
|
|
+Type TLongInt
|
|
|
|
+
|
|
|
|
+ Field value:LongInt
|
|
|
|
+
|
|
|
|
+ Method New(value:LongInt)
|
|
|
|
+ Self.value = value
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TULongInt
|
|
|
|
+
|
|
|
|
+ Field value:ULongInt
|
|
|
|
+
|
|
|
|
+ Method New(value:ULongInt)
|
|
|
|
+ Self.value = value
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+
|
|
Type TBoolSerializer Extends TJConvSerializer
|
|
Type TBoolSerializer Extends TJConvSerializer
|
|
|
|
|
|
Method Serialize:TJSON(source:Object, sourceType:String) Override
|
|
Method Serialize:TJSON(source:Object, sourceType:String) Override
|
|
@@ -1139,3 +1227,75 @@ Type TDoubleSerializer Extends TJConvSerializer
|
|
End Method
|
|
End Method
|
|
|
|
|
|
End Type
|
|
End Type
|
|
|
|
+
|
|
|
|
+Type TLongIntSerializer Extends TJConvSerializer
|
|
|
|
+
|
|
|
|
+ Method Serialize:TJSON(source:Object, sourceType:String) Override
|
|
|
|
+ Local value:TLongInt = TLongInt(source)
|
|
|
|
+ If value Then
|
|
|
|
+ Return New TJSONInteger.Create(value.value)
|
|
|
|
+ End If
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Deserialize:Object(json:TJSON, typeId:TTypeId, obj:Object) Override
|
|
|
|
+ If TJSONInteger(json) Then
|
|
|
|
+ If Not obj Then
|
|
|
|
+ obj = New TLongInt(LongInt(TJSONInteger(json).Value()))
|
|
|
|
+ End If
|
|
|
|
+ End If
|
|
|
|
+
|
|
|
|
+ Return obj
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TULongIntSerializer Extends TJConvSerializer
|
|
|
|
+
|
|
|
|
+ Method Serialize:TJSON(source:Object, sourceType:String) Override
|
|
|
|
+ Local value:TULongInt = TULongInt(source)
|
|
|
|
+ If value Then
|
|
|
|
+ Return New TJSONInteger.Create(value.value)
|
|
|
|
+ End If
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Deserialize:Object(json:TJSON, typeId:TTypeId, obj:Object) Override
|
|
|
|
+ If TJSONInteger(json) Then
|
|
|
|
+ If Not obj Then
|
|
|
|
+ obj = New TULongInt(ULongInt(TJSONInteger(json).Value()))
|
|
|
|
+ End If
|
|
|
|
+ End If
|
|
|
|
+
|
|
|
|
+ Return obj
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TJconvJsonException Extends TBlitzException
|
|
|
|
+ Field error:TJSONError
|
|
|
|
+
|
|
|
|
+ Function Create:TJconvJsonException(error:TJSONError)
|
|
|
|
+ Local ex:TJconvJsonException = New TJconvJsonException
|
|
|
|
+ ex.error = error
|
|
|
|
+ Return ex
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+ Method ToString:String()
|
|
|
|
+ If error Then
|
|
|
|
+ Return error.text
|
|
|
|
+ End If
|
|
|
|
+ End Method
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TJconvDeserializeException Extends TBlitzException
|
|
|
|
+ Field error:String
|
|
|
|
+
|
|
|
|
+ Function Create:TJconvDeserializeException(error:String)
|
|
|
|
+ Local ex:TJconvDeserializeException = New TJconvDeserializeException
|
|
|
|
+ ex.error = error
|
|
|
|
+ Return ex
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+ Method ToString:String()
|
|
|
|
+ Return error
|
|
|
|
+ End Method
|
|
|
|
+End Type
|