~eloaders/i-nex/I-Nex

« back to all changes in this revision

Viewing changes to src/i-nex/.src/JSON.module

  • Committer: eloaders
  • Date: 2014-07-15 16:31:30 UTC
  • Revision ID: git-v1:64e92b39f32ea7a292985dee67d4c6de1333f9fa
Move src to I-Nex

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
' Gambas module file
2
 
 
3
 
' Copyright(C) 2011-2014, Michał Głowienka aka eloaders <eloaders@linux.pl>
4
 
'
5
 
' This program is free software; you can redistribute it and/or modify
6
 
' it under the terms of the GNU General Public License as published by
7
 
' the Free Software Foundation; either version 3 of the License, or
8
 
' (at your option) any later version.
9
 
'
10
 
' This program is distributed in the hope that it will be useful,
11
 
' but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
' GNU General Public License for more details.
14
 
'
15
 
' You should have received a copy of the GNU General Public License
16
 
' along with this program. If not, see <http://www.gnu.org/licenses/>.
17
 
 
18
 
Property Read {Null} As Variant
19
 
 
20
 
Private $vNull As Variant
21
 
Private $sStr As String
22
 
Private $iPos As Integer
23
 
Private $bUseNull As Boolean
24
 
 
25
 
Private Sub GetChar() As String
26
 
  
27
 
  Dim sCar As String
28
 
  
29
 
  If $iPos > Len($sStr) Then Return
30
 
  sCar = Mid$($sStr, $iPos, 1)
31
 
  Inc $iPos
32
 
  Return sCar
33
 
  
34
 
End
35
 
 
36
 
 
37
 
Private Sub ReadChar() As String
38
 
  
39
 
  Dim sCar As String
40
 
 
41
 
  Do
42
 
    sCar = GetChar()
43
 
    If Not sCar Then Return
44
 
    If sCar > " " Then Return sCar
45
 
  Loop
46
 
  
47
 
End
48
 
 
49
 
 
50
 
Private Sub ReadToken() As String
51
 
  
52
 
  Dim sToken As String
53
 
  Dim sCar As String
54
 
 
55
 
  sCar = ReadChar()
56
 
  If Not IsLetter(sCar) Then Return sCar
57
 
  
58
 
  sToken = sCar
59
 
  Do
60
 
    sCar = GetChar()
61
 
    If Not sCar Then Break
62
 
    If Not IsLetter(sCar) Then 
63
 
      Dec $iPos
64
 
      Break
65
 
    Endif
66
 
    sToken &= sCar
67
 
  Loop
68
 
  
69
 
  Return sToken
70
 
  
71
 
End
72
 
 
73
 
Private Sub ReadString() As String
74
 
  
75
 
  Dim sCar As String
76
 
  Dim sString As String
77
 
  Dim iPos As Integer
78
 
  
79
 
  Do
80
 
    sCar = GetChar()
81
 
    If Not sCar Then Error.Raise("Non terminated string")
82
 
    If sCar = Chr$(34) Then Return sString
83
 
    If sCar = "\\" Then
84
 
      sCar = GetChar()
85
 
      If Not sCar Then Error.Raise("Non terminated string")
86
 
      iPos = InStr("bfrtn", sCar)
87
 
      If iPos Then
88
 
        sCar = Mid$("\b\f\r\t\n", iPos, 1)
89
 
      Else If sCar = "u" Then
90
 
        Try sCar = String.Chr$(Val("&H" & Mid$($sStr, $iPos, 4)))
91
 
        If Not Error Then $iPos += 4
92
 
      Else
93
 
        ' Keep character
94
 
      Endif
95
 
    Endif
96
 
    sString &= sCar
97
 
  Loop
98
 
  
99
 
End
100
 
 
101
 
Private Sub ReadObject() As Collection
102
 
  
103
 
  Dim sCar As String
104
 
  Dim cObject As Collection
105
 
  Dim sKey As String
106
 
  
107
 
  If $bUseNull Then
108
 
    cObject = New JSONCollection
109
 
  Else
110
 
    cObject = New Collection
111
 
  Endif
112
 
  
113
 
  Do
114
 
    sCar = ReadChar()
115
 
    If sCar = "}" Then Return cObject
116
 
    If sCar <> Chr$(34) Then Error.Raise("String expected")
117
 
    sKey = ReadString()
118
 
    sCar = ReadChar()
119
 
    If sCar <> ":" Then Error.Raise("Colon expected")
120
 
    cObject[sKey] = ReadValue()
121
 
    sCar = ReadChar()
122
 
    If sCar = "}" Then Return cObject
123
 
    If sCar <> "," Then Error.Raise("Comma expected")
124
 
  Loop
125
 
  
126
 
End
127
 
 
128
 
Private Sub ReadArray() As Variant[]
129
 
  
130
 
  Dim sCar As String
131
 
  Dim aArray As New Variant[]
132
 
  
133
 
  Do
134
 
    sCar = ReadChar()
135
 
    If sCar = "]" Then Return aArray
136
 
    Dec $iPos
137
 
    aArray.Add(ReadValue())
138
 
    sCar = ReadChar()
139
 
    If sCar = "]" Then Return aArray
140
 
    If sCar <> "," Then Error.Raise("Comma expected")
141
 
  Loop
142
 
  
143
 
End
144
 
 
145
 
Private Sub ReadNumber(sNumber As String) As Variant
146
 
  
147
 
  Dim sCar As String
148
 
  Dim vNumber As Variant
149
 
  Dim bFloat As Boolean
150
 
  
151
 
  Do
152
 
    sCar = GetChar()
153
 
    If Not sCar Then Break
154
 
    If InStr(".eE", sCar) Then
155
 
      bFloat = True
156
 
    Else If InStr("-+0123456789", sCar) = 0 Then 
157
 
      Dec $iPos
158
 
      Break
159
 
    Endif
160
 
    sNumber &= sCar
161
 
  Loop
162
 
  
163
 
  If bFloat Then
164
 
    Try vNumber = CFloat(sNumber)
165
 
    If Not Error Then Return vNumber
166
 
  Else
167
 
    Try vNumber = CInt(sNumber)
168
 
    If Not Error Then Return vNumber
169
 
    Try vNumber = CLong(sNumber)
170
 
    If Not Error Then Return vNumber
171
 
  Endif
172
 
  
173
 
  Error.Raise("Incorrect number")
174
 
  
175
 
End
176
 
 
177
 
Private Sub ReadValue() As Variant
178
 
  
179
 
  Dim sCar As String
180
 
  
181
 
  sCar = ReadToken()
182
 
  
183
 
  If sCar = "{" Then
184
 
    Return ReadObject()
185
 
  Else If sCar = "[" Then
186
 
    Return ReadArray()
187
 
  Else If sCar = Chr$(34) Then
188
 
    Return ReadString()
189
 
  Else If sCar = "-" Or If IsDigit(sCar) Then
190
 
    Return ReadNumber(sCar)
191
 
  Else If sCar = "null" Then
192
 
    Return Null
193
 
  Else If sCar = "true" Then
194
 
    Return True
195
 
  Else If sCar = "false" Then
196
 
    Return False
197
 
  Else If Not sCar Then
198
 
    Return
199
 
  Else
200
 
    Error.Raise("Incorrect token: " & Quote(sCar))
201
 
  Endif
202
 
  
203
 
End
204
 
 
205
 
Private Sub WriteValue(vVal As Variant)
206
 
  
207
 
  Dim sStr As String
208
 
  Dim iPos As Integer
209
 
  Dim aArray As Array
210
 
  Dim cCol As Collection
211
 
  
212
 
  Select Case TypeOf(vVal)
213
 
    
214
 
    Case gb.Null
215
 
      $sStr &= "null"
216
 
    
217
 
    Case gb.Boolean
218
 
      If vVal Then
219
 
        $sStr &= "true"
220
 
      Else
221
 
        $sStr &= "false"
222
 
      Endif
223
 
    
224
 
    Case gb.Byte, gb.Short, gb.Integer, gb.Long, gb.Float
225
 
      $sStr &= CStr(vVal)
226
 
    
227
 
    Case gb.Date
228
 
      $sStr &= Chr$(34) & CStr(vVal) & Chr$(34)
229
 
    
230
 
    Case gb.String
231
 
      sStr = Quote(vVal)
232
 
      Do
233
 
        iPos = InStr(sStr, "\\", iPos + 1)
234
 
        If iPos = 0 Then Break
235
 
        If Mid$(sStr, iPos + 1, 1) = "x" Then
236
 
          Mid$(sStr, iPos, 4) = "\\u00" & Mid$(sStr, iPos + 2, 2)
237
 
        Else
238
 
          Inc iPos
239
 
        Endif
240
 
      Loop
241
 
      $sStr &= sStr
242
 
    
243
 
    Case Else
244
 
      If vVal Is Array Then
245
 
        aArray = vVal
246
 
        $sStr &= "["
247
 
        For iPos = 0 To vVal.Max
248
 
          If iPos Then $sStr &= ", "
249
 
          WriteValue(vVal[iPos])
250
 
        Next
251
 
        $sStr &= "]"
252
 
      Else If vVal Is Collection Then
253
 
        cCol = vVal
254
 
        $sStr &= "{"
255
 
        For Each vVal In cCol
256
 
          If iPos Then $sStr &= ", "
257
 
          WriteValue(cCol.Key)
258
 
          $sStr &= ": "
259
 
          WriteValue(vVal)
260
 
          Inc iPos
261
 
        Next
262
 
        $sStr &= "}"
263
 
      Endif
264
 
    
265
 
  End Select
266
 
    
267
 
End
268
 
 
269
 
 
270
 
Public Sub Decode(JSONString As String, Optional UseNull As Boolean) As Variant
271
 
  
272
 
  Dim vVal As Variant
273
 
  $sStr = JSONString
274
 
  $iPos = 1
275
 
  $bUseNull = UseNull
276
 
  If UseNull And If IsNull($vNull) Then $vNull = VarPtr($vNull)
277
 
  vVal = ReadValue()
278
 
  $bUseNull = False
279
 
  $sStr = ""
280
 
  Return vVal
281
 
  
282
 
End
283
 
 
284
 
Public Sub Encode(Value As Variant) As String
285
 
  
286
 
  $sStr = ""
287
 
  WriteValue(Value)
288
 
  Return $sStr
289
 
  
290
 
End
291
 
 
292
 
Private Function Null_Read() As Variant
293
 
 
294
 
  Return $vNull
295
 
 
296
 
End