vis-config
lua scripts to configure vis editor
git clone https://9o.is/git/vis-config.git
parser.lua
(1873B)
1 --- Stateful parser for the data send by a language server.
2 -- Note the chunks received may not end with the end of a message.
3 -- In the worst case a data chunk contains two partial messages one
4 -- at the beginning and one at the end.
5 -- @module parser
6 -- @author Florian Fischer
7 -- @license GPL-3
8 -- @copyright Florian Fischer 2021-2024
9 local parser = {}
10
11 local Parser = {}
12
13 function parser.new()
14 local self = {exp_len = nil, data = '', msgs = {}}
15
16 setmetatable(self, {__index = Parser})
17 return self
18 end
19
20 function Parser:add(data)
21 self.data = self.data .. data
22
23 -- we have not seen a complete header in data yet
24 if not self.exp_len then
25 -- search for the end of a header
26 -- LSP message format: 'header\r\n\r\nbody'
27 local header_end, content_start = self.data:find('\r\n\r\n')
28
29 -- header is not complete yet -> save data and wait for more
30 if not header_end then
31 return
32 end
33
34 -- got a complete header
35 local header = self.data:sub(1, header_end)
36
37 -- extract content length from the header
38 self.exp_len = tonumber(header:match('%d+'))
39 if not self.exp_len then
40 return 'invalid header in data: ' .. self.data
41 end
42
43 -- consume header from data
44 self.data = self.data:sub(content_start + 1)
45 end
46
47 local data_avail = string.len(self.data)
48 -- we have no complete message yet -> await more data
49 if self.exp_len > data_avail then
50 return
51 end
52
53 local complete_msg = self.data:sub(1, self.exp_len)
54 table.insert(self.msgs, complete_msg)
55
56 -- consume complete_msg from data
57 self.data = self.data:sub(self.exp_len + 1)
58
59 local leftover = data_avail - self.exp_len
60
61 -- reset exp_len to search for a new header
62 self.exp_len = nil
63
64 if leftover > 0 then
65 return self:add('')
66 end
67 end
68
69 function Parser:get_msgs()
70 local msgs = self.msgs
71 self.msgs = {}
72 return msgs
73 end
74
75 return parser