parent
f87d68ff8f
commit
555b5574a2
|
@ -21,6 +21,10 @@ anywhere else in your data structures. A suitable value might be `"\0"`.
|
|||
|
||||
When encoding a Lua object, if a function is found, then it is invoked (with no arguments) and the (single) returned value is encoded in the place of the function.
|
||||
|
||||
!!! note
|
||||
|
||||
All examples below use in-memory JSON or content read from the SPIFFS file system. However, where a streaming implementation really shines is in fetching large JSON structures from the remote resources and extracting values on-the-fly. An elaborate streaming example can be found in the [`/lua_examples`](../../../lua_examples/sjson-streaming.lua) folder.
|
||||
|
||||
## sjson.encoder()
|
||||
|
||||
This creates an encoder object that can convert a Lua object into a JSON encoded string.
|
||||
|
@ -53,7 +57,8 @@ A string of up to `size` bytes, or `nil` if the encoding is complete and all dat
|
|||
#### Example
|
||||
The following example prints out (in 64 byte chunks) a JSON encoded string containing the first 4k of every file in the file system. The total string
|
||||
can be bigger than the total amount of memory on the NodeMCU.
|
||||
```
|
||||
|
||||
```lua
|
||||
function files()
|
||||
result = {}
|
||||
for k,v in pairs(file.list()) do
|
||||
|
@ -230,5 +235,5 @@ for k,v in pairs(t) do print(k,v) end
|
|||
|
||||
##Constants
|
||||
|
||||
There is one constant -- `sjson.NULL` -- which is used in Lua structures to represent the presence of a JSON null.
|
||||
There is one constant, `sjson.NULL`, which is used in Lua structures to represent the presence of a JSON null.
|
||||
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
-- Test sjson and GitHub API
|
||||
|
||||
local s = tls.createConnection()
|
||||
s:on("connection", function(sck, c)
|
||||
sck:send("GET /repos/nodemcu/nodemcu-firmware/git/trees/master HTTP/1.0\r\nUser-agent: nodemcu/0.1\r\nHost: api.github.com\r\nConnection: close\r\nAccept: application/json\r\n\r\n")
|
||||
end)
|
||||
|
||||
function startswith(String, Start)
|
||||
return string.sub(String, 1, string.len(Start)) == Start
|
||||
end
|
||||
|
||||
local seenBlank = false
|
||||
local partial
|
||||
local wantval = { tree = 1, path = 1, url = 1 }
|
||||
-- Make an sjson decoder that only keeps certain fields
|
||||
local decoder = sjson.decoder({
|
||||
metatable =
|
||||
{
|
||||
__newindex = function(t, k, v)
|
||||
if wantval[k] or type(k) == "number" then
|
||||
rawset(t, k, v)
|
||||
end
|
||||
end
|
||||
}
|
||||
})
|
||||
local function handledata(s)
|
||||
decoder:write(s)
|
||||
end
|
||||
|
||||
-- The receive callback is somewhat gnarly as it has to deal with find the end of the header
|
||||
-- and having the newline sequence split across packets
|
||||
s:on("receive", function(sck, c)
|
||||
if partial then
|
||||
c = partial .. c
|
||||
partial = nil
|
||||
end
|
||||
if seenBlank then
|
||||
handledata(c)
|
||||
return
|
||||
end
|
||||
while c do
|
||||
if startswith(c, "\r\n") then
|
||||
seenBlank = true
|
||||
c = c:sub(3)
|
||||
handledata(c)
|
||||
return
|
||||
end
|
||||
local s, e = c:find("\r\n")
|
||||
if s then
|
||||
-- Throw away line
|
||||
c = c:sub(e + 1)
|
||||
else
|
||||
partial = c
|
||||
c = nil
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
local function getresult()
|
||||
local result = decoder:result()
|
||||
-- This gets the resulting decoded object with only the required fields
|
||||
print(result['tree'][4]['path'], "is at",
|
||||
result['tree'][4]['url'])
|
||||
end
|
||||
|
||||
s:on("disconnection", getresult)
|
||||
s:on("reconnection", getresult)
|
||||
|
||||
-- Make it all happen!
|
||||
s:connect(443, "api.github.com")
|
Loading…
Reference in New Issue