Skip to content

Commit 0c8ee36

Browse files
committed
Changed ToDictionary with ToSerializable as per #6
1 parent 49b17b3 commit 0c8ee36

2 files changed

Lines changed: 29 additions & 11 deletions

File tree

Documentation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ Input data can be any of the following:
192192
- Primitive (```String```, Number, ```Boolean```, ```Null```)
193193
- Array (any number of dimensions) or ```Collection```
194194
- ```Dictionary```
195-
- Any class that has a ```ToDictionary() As Dictionary``` method (```Property Get``` or ```Function```). Please see [discussion](https://github.com/cristianbuse/VBA-FastJSON/discussions/2). The method is called via late-binding (```IDispatch::Invoke```)
195+
- Any class that has a ```ToSerializable() As Variant``` method (```Property Get``` or ```Function```). Please see [discussion](https://github.com/cristianbuse/VBA-FastJSON/discussions/2) and [issue](https://github.com/cristianbuse/VBA-FastJSON/issues/6). The method is called via late-binding (```IDispatch::Invoke```)
196196
- ```vbError``` or ```vbDate``` are simply converted to ```vbString```
197197

198198
Please not input ```String```(s) must be ```UTF16LE``` regardless if nested or not.

src/LibJSON.bas

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ Private Type SerializeContextInfo
262262
arrKeys() As Variant
263263
arrItems() As Variant
264264
isDict As Boolean
265+
isSerializable As Boolean
265266
incIndex As Long
266267
currIndex As Long
267268
ub As Long
@@ -1239,7 +1240,7 @@ End Function
12391240
' - Invalid data types (direct or nested) are replaced with Null:
12401241
' - Empty
12411242
' - User Defined Type
1242-
' - Nothing or an interface not implementing 'ToDictionary'
1243+
' - Nothing or an interface not implementing 'ToSerializable'
12431244
' - Uninitialized Array
12441245
' - Special Single/Double values: +Inf, -Inf, SNaN, QNaN
12451246
' - Circular references (by default - see below)
@@ -1248,7 +1249,7 @@ End Function
12481249
' - primitive (String, Number, Boolean, Null)
12491250
' - Array or Collection
12501251
' - Dictionary
1251-
' - Any class that implements a 'ToDictionary() As Dictionary' method
1252+
' - Any class that implements a 'ToSerializable() As Variant' method
12521253
' * indentSpaces:
12531254
' - Default is 0 - no indentation
12541255
' - For positive values, indenting will be added up to 'maxIndent' (16)
@@ -1331,6 +1332,7 @@ Public Function Serialize(ByRef jsonData As Variant _
13311332
Dim i As Long
13321333
Dim j As Long
13331334
Dim obj As Object
1335+
Dim v As Variant
13341336
'
13351337
If indentSpaces > 0 Then
13361338
beautify = True
@@ -1395,7 +1397,7 @@ Public Function Serialize(ByRef jsonData As Variant _
13951397
'
13961398
Do
13971399
Dim vt As VbVarType: vt = vars.vt(0)
1398-
If vt = vbObject Or vt = vbDataObject Then
1400+
Do While vt = vbObject Or vt = vbDataObject
13991401
If vars.arr(0) Is Nothing Then GoTo InsertNull
14001402
'
14011403
Dim iUnk As IUnknown: Set iUnk = vars.arr(0)
@@ -1416,7 +1418,8 @@ Public Function Serialize(ByRef jsonData As Variant _
14161418
Dim coll As Collection
14171419
Dim dict As Dictionary
14181420
Dim isDict As Boolean
1419-
Dim isScripting As Boolean: isScripting = False
1421+
Dim isSerializable As Boolean: isSerializable = False
1422+
Dim isScripting As Boolean: isScripting = False
14201423
'
14211424
isDict = (TypeOf vars.arr(0) Is Dictionary)
14221425
If isDict Then
@@ -1430,14 +1433,14 @@ Public Function Serialize(ByRef jsonData As Variant _
14301433
'
14311434
If isScripting Then
14321435
Set obj = vars.arr(0)
1433-
Else 'Try 'ToDictionary' via late-binding
1436+
isDict = True
1437+
Else 'Try 'ToSerializable' via late-binding
14341438
On Error Resume Next
1435-
Set dict = Nothing
1436-
Set dict = vars.arr(0).ToDictionary()
1439+
Assign v, vars.arr(0).ToSerializable
1440+
isSerializable = (Err.Number = 0)
14371441
On Error GoTo 0
1438-
If dict Is Nothing Then GoTo InsertNull
1442+
If Not isSerializable Then GoTo InsertNull
14391443
End If
1440-
isDict = True
14411444
End If
14421445
'
14431446
depth = depth + 1
@@ -1540,6 +1543,12 @@ Public Function Serialize(ByRef jsonData As Variant _
15401543
vars.sa.pvData = .firstKeyPtr
15411544
End If
15421545
End If
1546+
ElseIf isSerializable Then
1547+
.ub = -1
1548+
.epClose = epFalse
1549+
.iUnkPtr = iPtr
1550+
vars.sa.pvData = VarPtr(v)
1551+
vt = vars.vt(0)
15431552
Else
15441553
.ub = coll.Count - 1
15451554
If .ub < 0 Then
@@ -1566,6 +1575,12 @@ Public Function Serialize(ByRef jsonData As Variant _
15661575
End If
15671576
.incIndex = 1
15681577
End With
1578+
If Not isSerializable Then
1579+
vt = vbObject
1580+
Exit Do
1581+
End If
1582+
Loop
1583+
If vt = vbObject Then 'Do nothing - already handled
15691584
ElseIf vt >= vbArray Then
15701585
ptrs.sa.pvData = vars.sa.pvData + pOffset
15711586
If ptrs.arr(0) = NullPtr Then GoTo InsertNull 'Uninitialized
@@ -1787,7 +1802,6 @@ InsertNull: ep = epNull
17871802
If .currIndex = 0 Then
17881803
If beautify And (.incIndex > 0) Then
17891804
currentIndent = currentIndent + indentSpaces
1790-
17911805
If currentIndent > spCount Then
17921806
spCount = currentIndent * 2
17931807
spaces = Space$(spCount)
@@ -1833,6 +1847,10 @@ Clean:
18331847
vars.sa.rgsabound0.cElements = 0: vars.sa.pvData = NullPtr
18341848
End Function
18351849

1850+
Private Sub Assign(ByRef varLeft As Variant, ByRef varRight As Variant)
1851+
If IsObject(varRight) Then Set varLeft = varRight Else varLeft = varRight
1852+
End Sub
1853+
18361854
Private Sub InitEncoded(ByRef encoded() As EncodedString)
18371855
encoded(epTrue).s = "true"
18381856
encoded(epFalse).s = "false"

0 commit comments

Comments
 (0)