@@ -140,18 +140,6 @@ End Type
140140#End If
141141' === End VBA-UTC
142142
143- #If Mac Then
144- #ElseIf VBA7 Then
145-
146- Private Declare PtrSafe Sub json_CopyMemory Lib "kernel32 " Alias "RtlMoveMemory " _
147- (json_MemoryDestination As Any , json_MemorySource As Any , ByVal json_ByteLength As Long )
148-
149- #Else
150-
151- Private Declare Sub json_CopyMemory Lib "kernel32 " Alias "RtlMoveMemory " _
152- (json_MemoryDestination As Any , json_MemorySource As Any , ByVal json_ByteLength As Long )
153-
154- #End If
155143
156144Private Type json_Options
157145 ' VBA only stores 15 significant digits, so any numbers larger than that are truncated
@@ -210,9 +198,7 @@ End Function
210198' @return {String}
211199''
212200Public Function ConvertToJson (ByVal JsonValue As Variant , Optional ByVal Whitespace As Variant , Optional ByVal json_CurrentIndentation As Long = 0 ) As String
213- Dim json_buffer As String
214- Dim json_BufferPosition As Long
215- Dim json_BufferLength As Long
201+ Dim cSA As New clsStringAppend
216202 Dim json_Index As Long
217203 Dim json_LBound As Long
218204 Dim json_UBound As Long
@@ -271,7 +257,7 @@ Public Function ConvertToJson(ByVal JsonValue As Variant, Optional ByVal Whitesp
271257 End If
272258
273259 ' Array
274- json_BufferAppend json_buffer, "[" , json_BufferPosition, json_BufferLength
260+ cSA.Append "["
275261
276262 On Error Resume Next
277263
@@ -286,21 +272,21 @@ Public Function ConvertToJson(ByVal JsonValue As Variant, Optional ByVal Whitesp
286272 json_IsFirstItem = False
287273 Else
288274 ' Append comma to previous line
289- json_BufferAppend json_buffer, "," , json_BufferPosition, json_BufferLength
275+ cSA.Append ","
290276 End If
291277
292278 If json_LBound2D >= 0 And json_UBound2D >= 0 Then
293279 ' 2D Array
294280 If json_PrettyPrint Then
295- json_BufferAppend json_buffer, vbNewLine, json_BufferPosition, json_BufferLength
281+ cSA.Append vbNewLine
296282 End If
297- json_BufferAppend json_buffer, json_Indentation & "[" , json_BufferPosition, json_BufferLength
283+ cSA.Append json_Indentation & "["
298284
299285 For json_Index2D = json_LBound2D To json_UBound2D
300286 If json_IsFirstItem2D Then
301287 json_IsFirstItem2D = False
302288 Else
303- json_BufferAppend json_buffer, "," , json_BufferPosition, json_BufferLength
289+ cSA.Append ","
304290 End If
305291
306292 json_Converted = ConvertToJson(JsonValue(json_Index, json_Index2D), Whitespace, json_CurrentIndentation + 2 )
@@ -317,14 +303,14 @@ Public Function ConvertToJson(ByVal JsonValue As Variant, Optional ByVal Whitesp
317303 json_Converted = vbNewLine & json_InnerIndentation & json_Converted
318304 End If
319305
320- json_BufferAppend json_buffer, json_Converted, json_BufferPosition, json_BufferLength
306+ cSA.Append json_Converted
321307 Next json_Index2D
322308
323309 If json_PrettyPrint Then
324- json_BufferAppend json_buffer, vbNewLine, json_BufferPosition, json_BufferLength
310+ cSA.Append vbNewLine
325311 End If
326312
327- json_BufferAppend json_buffer, json_Indentation & "]" , json_BufferPosition, json_BufferLength
313+ cSA.Append json_Indentation & "]"
328314 json_IsFirstItem2D = True
329315 Else
330316 ' 1D Array
@@ -342,15 +328,15 @@ Public Function ConvertToJson(ByVal JsonValue As Variant, Optional ByVal Whitesp
342328 json_Converted = vbNewLine & json_Indentation & json_Converted
343329 End If
344330
345- json_BufferAppend json_buffer, json_Converted, json_BufferPosition, json_BufferLength
331+ cSA.Append json_Converted
346332 End If
347333 Next json_Index
348334 End If
349335
350336 On Error GoTo 0
351337
352338 If json_PrettyPrint Then
353- json_BufferAppend json_buffer, vbNewLine, json_BufferPosition, json_BufferLength
339+ cSA.Append vbNewLine
354340
355341 If VBA.VarType(Whitespace) = VBA.vbString Then
356342 json_Indentation = VBA.String $(json_CurrentIndentation, Whitespace)
@@ -359,9 +345,9 @@ Public Function ConvertToJson(ByVal JsonValue As Variant, Optional ByVal Whitesp
359345 End If
360346 End If
361347
362- json_BufferAppend json_buffer, json_Indentation & "]" , json_BufferPosition, json_BufferLength
348+ cSA.Append json_Indentation & "]"
363349
364- ConvertToJson = json_BufferToString(json_buffer, json_BufferPosition, json_BufferLength)
350+ ConvertToJson = cSA.Report
365351
366352 ' Dictionary or Collection
367353 Case VBA.vbObject
@@ -375,7 +361,7 @@ Public Function ConvertToJson(ByVal JsonValue As Variant, Optional ByVal Whitesp
375361
376362 ' Dictionary
377363 If VBA.TypeName(JsonValue) = "Dictionary" Then
378- json_BufferAppend json_buffer, "{" , json_BufferPosition, json_BufferLength
364+ cSA.Append "{"
379365 For Each json_Key In JsonValue.Keys
380366 ' For Objects, undefined (Empty/Nothing) is not added to object
381367 json_Converted = ConvertToJson(JsonValue(json_Key), Whitespace, json_CurrentIndentation + 1 )
@@ -389,7 +375,7 @@ Public Function ConvertToJson(ByVal JsonValue As Variant, Optional ByVal Whitesp
389375 If json_IsFirstItem Then
390376 json_IsFirstItem = False
391377 Else
392- json_BufferAppend json_buffer, "," , json_BufferPosition, json_BufferLength
378+ cSA.Append ","
393379 End If
394380
395381 If json_PrettyPrint Then
@@ -398,12 +384,12 @@ Public Function ConvertToJson(ByVal JsonValue As Variant, Optional ByVal Whitesp
398384 json_Converted = """" & json_Key & """:" & json_Converted
399385 End If
400386
401- json_BufferAppend json_buffer, json_Converted, json_BufferPosition, json_BufferLength
387+ cSA.Append json_Converted
402388 End If
403389 Next json_Key
404390
405391 If json_PrettyPrint Then
406- json_BufferAppend json_buffer, vbNewLine, json_BufferPosition, json_BufferLength
392+ cSA.Append vbNewLine
407393
408394 If VBA.VarType(Whitespace) = VBA.vbString Then
409395 json_Indentation = VBA.String $(json_CurrentIndentation, Whitespace)
@@ -412,16 +398,16 @@ Public Function ConvertToJson(ByVal JsonValue As Variant, Optional ByVal Whitesp
412398 End If
413399 End If
414400
415- json_BufferAppend json_buffer, json_Indentation & "}" , json_BufferPosition, json_BufferLength
401+ cSA.Append json_Indentation & "}"
416402
417403 ' Collection
418404 ElseIf VBA.TypeName(JsonValue) = "Collection" Then
419- json_BufferAppend json_buffer, "[" , json_BufferPosition, json_BufferLength
405+ cSA.Append "["
420406 For Each json_Value In JsonValue
421407 If json_IsFirstItem Then
422408 json_IsFirstItem = False
423409 Else
424- json_BufferAppend json_buffer, "," , json_BufferPosition, json_BufferLength
410+ cSA.Append ","
425411 End If
426412
427413 json_Converted = ConvertToJson(json_Value, Whitespace, json_CurrentIndentation + 1 )
@@ -438,11 +424,11 @@ Public Function ConvertToJson(ByVal JsonValue As Variant, Optional ByVal Whitesp
438424 json_Converted = vbNewLine & json_Indentation & json_Converted
439425 End If
440426
441- json_BufferAppend json_buffer, json_Converted, json_BufferPosition, json_BufferLength
427+ cSA.Append json_Converted
442428 Next json_Value
443429
444430 If json_PrettyPrint Then
445- json_BufferAppend json_buffer, vbNewLine, json_BufferPosition, json_BufferLength
431+ cSA.Append vbNewLine
446432
447433 If VBA.VarType(Whitespace) = VBA.vbString Then
448434 json_Indentation = VBA.String $(json_CurrentIndentation, Whitespace)
@@ -451,10 +437,10 @@ Public Function ConvertToJson(ByVal JsonValue As Variant, Optional ByVal Whitesp
451437 End If
452438 End If
453439
454- json_BufferAppend json_buffer, json_Indentation & "]" , json_BufferPosition, json_BufferLength
440+ cSA.Append json_Indentation & "]"
455441 End If
456442
457- ConvertToJson = json_BufferToString(json_buffer, json_BufferPosition, json_BufferLength)
443+ ConvertToJson = cSA.Report
458444 Case VBA.vbInteger, VBA.vbLong, VBA.vbSingle, VBA.vbDouble, VBA.vbCurrency, VBA.vbDecimal
459445 ' Number (use decimals for numbers)
460446 ConvertToJson = VBA.Replace(JsonValue, "," , "." )
@@ -558,9 +544,7 @@ Private Function json_ParseString(json_String As String, ByRef json_Index As Lon
558544 Dim json_Quote As String
559545 Dim json_Char As String
560546 Dim json_Code As String
561- Dim json_buffer As String
562- Dim json_BufferPosition As Long
563- Dim json_BufferLength As Long
547+ Dim cSA As New clsStringAppend
564548
565549 json_SkipSpaces json_String, json_Index
566550
@@ -579,36 +563,36 @@ Private Function json_ParseString(json_String As String, ByRef json_Index As Lon
579563
580564 Select Case json_Char
581565 Case """" , "\" , "/" , "'"
582- json_BufferAppend json_buffer, json_Char, json_BufferPosition, json_BufferLength
566+ cSA.Append json_Char
583567 json_Index = json_Index + 1
584568 Case "b"
585- json_BufferAppend json_buffer, vbBack, json_BufferPosition, json_BufferLength
569+ cSA.Append vbBack
586570 json_Index = json_Index + 1
587571 Case "f"
588- json_BufferAppend json_buffer, vbFormFeed, json_BufferPosition, json_BufferLength
572+ cSA.Append vbFormFeed
589573 json_Index = json_Index + 1
590574 Case "n"
591- json_BufferAppend json_buffer, vbCrLf, json_BufferPosition, json_BufferLength
575+ cSA.Append vbCrLf
592576 json_Index = json_Index + 1
593577 Case "r"
594- json_BufferAppend json_buffer, vbCr, json_BufferPosition, json_BufferLength
578+ cSA.Append vbCr
595579 json_Index = json_Index + 1
596580 Case "t"
597- json_BufferAppend json_buffer, vbTab, json_BufferPosition, json_BufferLength
581+ cSA.Append vbTab
598582 json_Index = json_Index + 1
599583 Case "u"
600584 ' Unicode character escape (e.g. \u00a9 = Copyright)
601585 json_Index = json_Index + 1
602586 json_Code = VBA.Mid$(json_String, json_Index, 4 )
603- json_BufferAppend json_buffer, VBA.ChrW(VBA.Val("&h" + json_Code)), json_BufferPosition, json_BufferLength
587+ cSA.Append VBA.ChrW(VBA.Val("&h" + json_Code))
604588 json_Index = json_Index + 4
605589 End Select
606590 Case json_Quote
607- json_ParseString = json_BufferToString(json_buffer, json_BufferPosition, json_BufferLength)
591+ json_ParseString = cSA.Report
608592 json_Index = json_Index + 1
609593 Exit Function
610594 Case Else
611- json_BufferAppend json_buffer, json_Char, json_BufferPosition, json_BufferLength
595+ cSA.Append json_Char
612596 json_Index = json_Index + 1
613597 End Select
614598 Loop
@@ -694,9 +678,7 @@ Private Function json_Encode(ByVal json_Text As Variant) As String
694678 Dim json_Index As Long
695679 Dim json_Char As String
696680 Dim json_AscCode As Long
697- Dim json_buffer As String
698- Dim json_BufferPosition As Long
699- Dim json_BufferLength As Long
681+ Dim cSA As New clsStringAppend
700682
701683 For json_Index = 1 To VBA.Len(json_Text)
702684 json_Char = VBA.Mid$(json_Text, json_Index, 1 )
@@ -743,10 +725,10 @@ Private Function json_Encode(ByVal json_Text As Variant) As String
743725 json_Char = "\u" & VBA.Right$("0000" & VBA.Hex$(json_AscCode), 4 )
744726 End Select
745727
746- json_BufferAppend json_buffer, json_Char, json_BufferPosition, json_BufferLength
728+ cSA.Append json_Char
747729 Next json_Index
748730
749- json_Encode = json_BufferToString(json_buffer, json_BufferPosition, json_BufferLength)
731+ json_Encode = cSA.Report
750732End Function
751733
752734Private Function json_Peek (json_String As String , ByVal json_Index As Long , Optional json_NumberOfCharacters As Long = 1 ) As String
@@ -819,93 +801,7 @@ Private Function json_ParseErrorMessage(json_String As String, ByRef json_Index
819801 ErrorMessage
820802End Function
821803
822- Private Sub json_BufferAppend (ByRef json_buffer As String , _
823- ByRef json_Append As Variant , _
824- ByRef json_BufferPosition As Long , _
825- ByRef json_BufferLength As Long )
826- #If Mac Then
827- json_buffer = json_buffer & json_Append
828- #Else
829- ' VBA can be slow to append strings due to allocating a new string for each append
830- ' Instead of using the traditional append, allocate a large empty string and then copy string at append position
831- '
832- ' Example:
833- ' Buffer: "abc "
834- ' Append: "def"
835- ' Buffer Position: 3
836- ' Buffer Length: 5
837- '
838- ' Buffer position + Append length > Buffer length -> Append chunk of blank space to buffer
839- ' Buffer: "abc "
840- ' Buffer Length: 10
841- '
842- ' Copy memory for "def" into buffer at position 3 (0-based)
843- ' Buffer: "abcdef "
844- '
845- ' Approach based on cStringBuilder from vbAccelerator
846- ' http://www.vbaccelerator.com/home/VB/Code/Techniques/RunTime_Debug_Tracing/VB6_Tracer_Utility_zip_cStringBuilder_cls.asp
847-
848- Dim json_AppendLength As Long
849- Dim json_LengthPlusPosition As Long
850-
851- json_AppendLength = VBA.LenB(json_Append)
852- json_LengthPlusPosition = json_AppendLength + json_BufferPosition
853-
854- If json_LengthPlusPosition > json_BufferLength Then
855- ' Appending would overflow buffer, add chunks until buffer is long enough
856- Dim json_TemporaryLength As Long
857-
858- json_TemporaryLength = json_BufferLength
859- Do While json_TemporaryLength < json_LengthPlusPosition
860- ' Initially, initialize string with 255 characters,
861- ' then add large chunks (8192) after that
862- '
863- ' Size: # Characters x 2 bytes / character
864- If json_TemporaryLength = 0 Then
865- json_TemporaryLength = json_TemporaryLength + 510
866- Else
867- json_TemporaryLength = json_TemporaryLength + 16384
868- End If
869- Loop
870-
871- json_buffer = json_buffer & VBA.Space$((json_TemporaryLength - json_BufferLength) \ 2 )
872- json_BufferLength = json_TemporaryLength
873- End If
874-
875- ' Copy memory from append to buffer at buffer position
876- json_CopyMemory ByVal json_UnsignedAdd(StrPtr(json_buffer), _
877- json_BufferPosition), _
878- ByVal StrPtr(json_Append), _
879- json_AppendLength
880-
881- json_BufferPosition = json_BufferPosition + json_AppendLength
882- #End If
883- End Sub
884-
885- Private Function json_BufferToString (ByRef json_buffer As String , ByVal json_BufferPosition As Long , ByVal json_BufferLength As Long ) As String
886- #If Mac Then
887- json_BufferToString = json_buffer
888- #Else
889- If json_BufferPosition > 0 Then
890- json_BufferToString = VBA.Left$(json_buffer, json_BufferPosition \ 2 )
891- End If
892- #End If
893- End Function
894-
895- #If VBA7 Then
896- Private Function json_UnsignedAdd (json_Start As LongPtr , json_Increment As Long ) As LongPtr
897- #Else
898- Private Function json_UnsignedAdd (json_Start As Long , json_Increment As Long ) As Long
899- #End If
900804
901- If json_Start And &H80000000 Then
902- json_UnsignedAdd = json_Start + json_Increment
903- ElseIf (json_Start Or &H80000000 ) < -json_Increment Then
904- json_UnsignedAdd = json_Start + json_Increment
905- Else
906- json_UnsignedAdd = (json_Start + &H80000000 ) + (json_Increment + &H80000000 )
907- End If
908- End Function
909805
910806''
911807' VBA-UTC v1.0.5
@@ -1169,3 +1065,9 @@ Private Function utc_SystemTimeToDate(utc_Value As utc_SYSTEMTIME) As Date
11691065End Function
11701066
11711067#End If
1068+
1069+
1070+
1071+
1072+
1073+
0 commit comments