Files
SmartEnterprise_v1/Terminalino/TerminalinoCommons/JsonModule.vb
2017-12-18 15:32:16 +01:00

222 lines
7.0 KiB
VB.net

Imports System.Text.RegularExpressions
Public Class JSONObject
#Region "Shared Variables"
Private Shared ReadOnly reProp As New Regex("(?<=(^|\,)\s*)([^\:]+)\s*\:\s*([^\,]+)", RegexOptions.Compiled)
Private Shared ReadOnly reReplaced As New Regex("^\$\[\d+\]$", RegexOptions.Compiled)
#End Region
#Region "Shared Functions"
Private Shared Function TokenizeJSON(ByVal json As String, ByVal l As List(Of String)) As String
Dim r As String = String.Empty
Dim nestable As String = "()[]{}"
Dim stringable As String = """'"
Dim nested As New Stack(Of Char)
Dim stringing As Char? = Nothing
Dim start As Integer = -1
l.Clear()
For i As Integer = 0 To json.Length - 1
Dim c As Char = json(i)
If stringing IsNot Nothing Then
If stringing = c Then
stringing = Nothing
If nested.Count = 0 Then
r &= "$[" & l.Count.ToString() & "]"
l.Add(json.Substring(start, i - start + 1))
End If
End If
ElseIf stringable.IndexOf(c) > -1 Then
stringing = c
If nested.Count = 0 Then start = i
ElseIf nestable.IndexOf(c) Mod 2 = 0 Then
If nested.Count = 0 Then start = i
nested.Push(c)
ElseIf nested.Count > 0 Then
If nestable.IndexOf(nested.Peek()) + 1 = nestable.IndexOf(c) Then
nested.Pop()
If nested.Count = 0 Then
r &= "$[" & l.Count.ToString() & "]"
l.Add(json.Substring(start, i - start + 1))
End If
End If
Else
r &= If(c = "\" OrElse c = "$", "\" & c, c)
End If
Next
Return r
End Function
Private Shared Function ParseJSONObject(ByVal json As String) As Dictionary(Of String, String)
Dim r As New Dictionary(Of String, String)
Dim l As New List(Of String)
'Trim any leading or trailing object delimiters found in JSON objects.
json = json.TrimStart(" "c).TrimEnd(" "c)
json = json.Substring(1).Substring(0, json.Length - 2)
'Tokenize the JSON object.
json = TokenizeJSON(json, l)
'Parse the JSON object.
For Each m As Match In reProp.Matches(json)
Dim name As String = m.Groups(2).Value.TrimStart()
Dim value As String = m.Groups(3).Value
If reReplaced.IsMatch(name) Then name = l(Integer.Parse(name.Substring(2, name.Length - 3)))
If reReplaced.IsMatch(value) Then value = l(Integer.Parse(value.Substring(2, value.Length - 3)))
name = name.Trim("'"c, """"c)
r.Add(name, value)
Next
'Return the result.
Return r
End Function
Private Shared Function ParseJSONArray(ByVal json As String) As String()
Dim l As New List(Of String)
Dim r As New List(Of String)
'Trim any leading or trailing array delimiters found in JSON objects, but only one on each side.
json = json.Trim()
json = json.Substring(1, json.Length - 2)
'Tokenize the JSON array.
json = TokenizeJSON(json, l)
'Parse and return the JSON array.
For Each x As String In json.Split(",")
x = x.Trim()
If reReplaced.IsMatch(x) Then
r.Add(l(Integer.Parse(x.Substring(2, x.Length - 3))))
Else
r.Add(x)
End If
Next
Return r.ToArray()
End Function
#End Region
#Region "Variables"
Private ReadOnly _properties As Dictionary(Of String, String)
Private ReadOnly list As New List(Of JSONObject)
#End Region
#Region "Constructor"
Public Sub New(ByVal json As String)
If json.Substring(0, 1) = "{" Then
_properties = JSONObject.ParseJSONObject(json)
ElseIf json.Substring(0, 1) = "[" Then
For Each x As String In JSONObject.ParseJSONArray(json)
Dim obj As JSONObject = New JSONObject(x)
list.Add(obj)
Next
End If
End Sub
#End Region
#Region "Methods"
Public Sub Destroy()
_properties.Clear()
list.Clear()
GC.Collect()
End Sub
Public Function GetJsonArray() As List(Of JSONObject)
Return list
End Function
Public Function GetArray(ByVal name As String) As List(Of JSONObject)
If _properties.ContainsKey(name) Then
list.Clear()
Dim prop As String = _properties(name)
For Each x As String In JSONObject.ParseJSONArray(prop)
Dim obj As JSONObject = New JSONObject(x)
list.Add(obj)
Next
End If
Return list
End Function
Public Function GetProperty(ByVal name As String) As JSONValue
If _properties.ContainsKey(name) Then Return Evaluate(_properties(name))
Return New JSONValue(JSONType.undefined, Nothing)
End Function
Private Function Evaluate(ByVal json As String) As JSONValue
Dim intValue As Integer
Dim floatValue As Double
json = json.TrimStart("("c).TrimEnd(")"c)
If json <> String.Empty Then
If json(0) = "{"c Then
Return New JSONValue(JSONType.object, New JSONObject(json))
ElseIf json(0) = "["c Then
For Each x As String In JSONObject.ParseJSONArray(json)
list.Add(New JSONObject(x))
Next
ElseIf json(0) = "'"c OrElse json(0) = """"c Then
Return New JSONValue(JSONType.string, json.Substring(1, json.Length - 2))
ElseIf Integer.Parse(json) Then
intValue = Integer.Parse(json)
Return New JSONValue(JSONType.int, intValue)
ElseIf Double.Parse(json) Then
floatValue = Double.Parse(json)
Return New JSONValue(JSONType.double, floatValue)
ElseIf json = "true" Then
Return New JSONValue(JSONType.bool, True)
ElseIf json = "false" Then
Return New JSONValue(JSONType.bool, False)
ElseIf json = "null" Then
Return New JSONValue(JSONType.null, Nothing)
End If
End If
Return New JSONValue(JSONType.undefined, Nothing)
End Function
#End Region
End Class
Public Class JSONValue
Private _type As JSONType
Private _value As Object
Public Sub New(ByVal type As JSONType, ByVal value As Object)
_type = type
_value = value
End Sub
Public ReadOnly Property Type() As JSONType
Get
Return _type
End Get
End Property
Public ReadOnly Property Value() As Object
Get
Return _value
End Get
End Property
Public Sub Destroy()
_value = String.Empty
End Sub
End Class
Public Enum JSONType
bool
int
[double]
[string]
[object]
array
null
undefined
End Enum