Subversion Repositories DevTools

Rev

Rev 4253 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3892 dpurdie 1
'June 2013 - Version 1.1 by Gerrit van Kuipers
2
Class aspJSON
3
	Public data
4
	Private p_JSONstring
5
	Private p_datatype
6
	private aj_in_string, aj_in_escape, aj_i_tmp, aj_char_tmp, aj_s_tmp, aj_line_tmp, aj_line, aj_lines, aj_currentlevel, aj_currentkey, aj_currentvalue, aj_newlabel
7
 
8
	Private Sub Class_Initialize()
9
		Set data = Collection()
10
		p_datatype = "{}"
11
	End Sub
12
 
13
	Private Sub Class_Terminate()
14
		Set data = Nothing
15
	End Sub
16
 
17
	Public Function loadJSON(strInput)
18
		if len(trim(strInput)) = 0 then Err.Raise 1, "loadJSON Error", "No data to load."
19
		p_JSONstring = CleanUpJSONstring(Trim(strInput))
20
		aj_lines = Split(p_JSONstring, Chr(13) & Chr(10))
21
 
22
		Dim level(99)
23
		aj_currentlevel = 1
24
		Set level(aj_currentlevel) = data
25
		For Each aj_line In aj_lines
26
			aj_currentkey = ""
27
			aj_currentvalue = ""
28
			If Instr(aj_line, ":") > 0 Then
29
				aj_in_string = False
30
				aj_in_escape = False
31
				For aj_i_tmp = 1 To Len(aj_line)
32
					If aj_in_escape Then
33
						aj_in_escape = False
34
					Else
35
						Select Case Mid(aj_line, aj_i_tmp, 1)
36
							Case """"
37
								aj_in_string = Not aj_in_string
38
							Case ":"
39
								If Not aj_in_escape Then
40
									aj_currentkey = Left(aj_line, aj_i_tmp - 1)
41
									aj_currentvalue = Mid(aj_line, aj_i_tmp + 1)
42
									Exit For
43
								End If
44
							Case "\"
45
								aj_in_escape = True
46
						End Select
47
					End If
48
				Next
49
				aj_currentkey = aj_Strip(aj_JSONDecode(aj_currentkey), """")
50
				If Not level(aj_currentlevel).exists(aj_currentkey) Then level(aj_currentlevel).Add aj_currentkey, ""
51
			End If
52
			If right(aj_line,1) = "{" Or right(aj_line,1) = "[" Then
53
				If Len(aj_currentkey) = 0 Then aj_currentkey = level(aj_currentlevel).Count
54
				Set level(aj_currentlevel).Item(aj_currentkey) = Collection()
55
				Set level(aj_currentlevel + 1) = level(aj_currentlevel).Item(aj_currentkey)
56
				aj_currentlevel = aj_currentlevel + 1
57
				aj_currentkey = ""
58
			ElseIf right(aj_line,1) = "}" Or right(aj_line,1) = "]" or right(aj_line,2) = "}," Or right(aj_line,2) = "]," Then
59
				aj_currentlevel = aj_currentlevel - 1
60
			ElseIf Len(Trim(aj_line)) > 0 Then
61
				if Len(aj_currentvalue) = 0 Then aj_currentvalue = getJSONValue(aj_line)
62
				aj_currentvalue = getJSONValue(aj_currentvalue)
63
 
64
				If Len(aj_currentkey) = 0 Then aj_currentkey = level(aj_currentlevel).Count
65
				level(aj_currentlevel).Item(aj_currentkey) = aj_currentvalue
66
			End If
67
		Next
68
	End Function
69
 
70
	Public Function Collection()
4253 dpurdie 71
		set Collection = CreateObject("Scripting.Dictionary")
3892 dpurdie 72
	End Function
73
 
74
	Public Function AddToCollection(dictobj)
75
		if TypeName(dictobj) <> "Dictionary" then Err.Raise 1, "AddToCollection Error", "Not a collection."
76
		aj_newlabel = dictobj.Count
77
		dictobj.Add aj_newlabel, Collection()
78
		set AddToCollection = dictobj.item(aj_newlabel)
79
	end function
80
 
81
	Private Function CleanUpJSONstring(aj_originalstring)
82
		aj_originalstring = Replace(aj_originalstring, Chr(13) & Chr(10), "")
83
		p_datatype = Left(aj_originalstring, 1) & Right(aj_originalstring, 1)
84
		aj_originalstring = Mid(aj_originalstring, 2, Len(aj_originalstring) - 2)
85
		aj_in_string = False : aj_in_escape = False : aj_s_tmp = ""
86
		For aj_i_tmp = 1 To Len(aj_originalstring)
87
			aj_char_tmp = Mid(aj_originalstring, aj_i_tmp, 1)
88
			If aj_in_escape Then
89
				aj_in_escape = False
90
				aj_s_tmp = aj_s_tmp & aj_char_tmp
91
			Else
92
				Select Case aj_char_tmp
93
					Case "\" : aj_in_escape = True
94
					Case """" : aj_s_tmp = aj_s_tmp & aj_char_tmp : aj_in_string = Not aj_in_string
95
					Case "{", "["
96
						aj_s_tmp = aj_s_tmp & aj_char_tmp & aj_InlineIf(aj_in_string, "", Chr(13) & Chr(10))
97
					Case "}", "]"
98
						aj_s_tmp = aj_s_tmp & aj_InlineIf(aj_in_string, "", Chr(13) & Chr(10)) & aj_char_tmp
99
					Case "," : aj_s_tmp = aj_s_tmp & aj_char_tmp & aj_InlineIf(aj_in_string, "", Chr(13) & Chr(10))
100
					Case Else : aj_s_tmp = aj_s_tmp & aj_char_tmp
101
				End Select
102
			End If
103
		Next
104
 
105
		CleanUpJSONstring = ""
106
		aj_s_tmp = split(aj_s_tmp, Chr(13) & Chr(10))
107
		For Each aj_line_tmp In aj_s_tmp
108
			aj_line_tmp = replace(replace(aj_line_tmp, chr(10), ""), chr(13), "")
109
			CleanUpJSONstring = CleanUpJSONstring & Trim(aj_line_tmp) & Chr(13) & Chr(10)
110
		Next
111
	End Function
112
 
113
	Private Function getJSONValue(ByVal val)
114
		val = Trim(val)
115
		If Left(val,1) = ":"  Then val = Mid(val, 2)
116
		If Right(val,1) = "," Then val = Left(val, Len(val) - 1)
117
		val = Trim(val)
118
 
119
		Select Case val
120
			Case "true"  : getJSONValue = True
121
			Case "false" : getJSONValue = False
122
			Case "null" : getJSONValue = Null
123
			Case Else
124
				If (Instr(val, """") = 0) Then
125
					If IsNumeric(val) Then
126
						getJSONValue = CDbl(val)
127
					Else
128
						getJSONValue = val
129
					End If
130
				Else
131
					If Left(val,1) = """" Then val = Mid(val, 2)
132
					If Right(val,1) = """" Then val = Left(val, Len(val) - 1)
133
					getJSONValue = aj_JSONDecode(Trim(val))
134
				End If
135
		End Select
136
	End Function
137
 
138
	Private JSONoutput_level
139
	Public Function JSONoutput()
140
		JSONoutput_level = 1
141
		JSONoutput = Left(p_datatype, 1) & Chr(13) & Chr(10) & GetDict(data) & Right(p_datatype, 1)
142
	End Function
143
 
144
	Private Function GetDict(objDict)
145
		dim aj_item, aj_keyvals, aj_label, aj_dicttype
146
		For Each aj_item In objDict
147
			Select Case TypeName(objDict.Item(aj_item))
148
				Case "Dictionary"
149
					GetDict = GetDict & Space(JSONoutput_level * 4)
150
 
151
					aj_dicttype = "[]"
152
					For Each aj_label In objDict.Item(aj_item).Keys
153
						 If Not IsInt(aj_label) Then aj_dicttype = "{}"
154
					Next
155
 
156
					If IsInt(aj_item) Then
157
						GetDict = GetDict & Left(aj_dicttype,1) & Chr(13) & Chr(10)
158
					Else
159
						GetDict = GetDict & """" & aj_JSONEncode(aj_item) & """" & ": " & Left(aj_dicttype,1) & Chr(13) & Chr(10)
160
					End If
161
					JSONoutput_level = JSONoutput_level + 1
162
 
163
					aj_keyvals = objDict.Keys
164
					GetDict = GetDict & GetSubDict(objDict.Item(aj_item)) & Space(JSONoutput_level * 4) & Right(aj_dicttype,1) & aj_InlineIf(aj_item = aj_keyvals(objDict.Count - 1),"" , ",") & Chr(13) & Chr(10)
165
				Case Else
166
					aj_keyvals =  objDict.Keys
167
					GetDict = GetDict & Space(JSONoutput_level * 4) & aj_InlineIf(IsInt(aj_item), "", """" & aj_JSONEncode(aj_item) & """: ") & WriteValue(objDict.Item(aj_item)) & aj_InlineIf(aj_item = aj_keyvals(objDict.Count - 1),"" , ",") & Chr(13) & Chr(10)
168
			End Select
169
		Next
170
	End Function
171
 
172
	Private Function IsInt(val)
173
		IsInt = (TypeName(val) = "Integer" Or TypeName(val) = "Long")
174
	End Function
175
 
176
	Private Function GetSubDict(objSubDict)
177
		GetSubDict = GetDict(objSubDict)
178
		JSONoutput_level= JSONoutput_level -1
179
	End Function
180
 
181
	Private Function WriteValue(ByVal val)
182
		Select Case TypeName(val)
183
			Case "Double", "Integer", "Long": WriteValue = val
184
			Case "Null"						: WriteValue = "null"
185
			Case "Boolean"					: WriteValue = aj_InlineIf(val, "true", "false")
186
			Case Else						: WriteValue = """" & aj_JSONEncode(val) & """"
187
		End Select
188
	End Function
189
 
190
	Private Function aj_JSONEncode(ByVal val)
191
		val = Replace(val, "\", "\\")
192
		val = Replace(val, """", "\""")
193
		'val = Replace(val, "/", "\/")
194
		val = Replace(val, Chr(8), "\b")
195
		val = Replace(val, Chr(12), "\f")
196
		val = Replace(val, Chr(10), "\n")
197
		val = Replace(val, Chr(13), "\r")
198
		val = Replace(val, Chr(9), "\t")
199
		aj_JSONEncode = Trim(val)
200
	End Function
201
 
202
	Private Function aj_JSONDecode(ByVal val)
203
		val = Replace(val, "\""", """")
204
		val = Replace(val, "\\", "\")
205
		val = Replace(val, "\/", "/")
206
		val = Replace(val, "\b", Chr(8))
207
		val = Replace(val, "\f", Chr(12))
208
		val = Replace(val, "\n", Chr(10))
209
		val = Replace(val, "\r", Chr(13))
210
		val = Replace(val, "\t", Chr(9))
211
		aj_JSONDecode = Trim(val)
212
	End Function
213
 
214
	Private Function aj_InlineIf(condition, returntrue, returnfalse)
215
		If condition Then aj_InlineIf = returntrue Else aj_InlineIf = returnfalse
216
	End Function
217
 
218
	Private Function aj_Strip(ByVal val, stripper)
219
		If Left(val, 1) = stripper Then val = Mid(val, 2)
220
		If Right(val, 1) = stripper Then val = Left(val, Len(val) - 1)
221
		aj_Strip = val
222
	End Function
223
End Class