From 0d4688825367d45a5da9b9f8bc4aa41aadfa0c88 Mon Sep 17 00:00:00 2001 From: Florian Fischer Date: Wed, 7 Aug 2024 19:06:09 +0200 Subject: refactor parser to more idiomatic OOP --- parser.lua | 67 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 34 insertions(+), 33 deletions(-) (limited to 'parser.lua') diff --git a/parser.lua b/parser.lua index 99b16db..c0b9e85 100644 --- a/parser.lua +++ b/parser.lua @@ -1,4 +1,4 @@ --- Copyright (c) 2021 Florian Fischer. All rights reserved. +-- Copyright (c) 2021-2024 Florian Fischer. All rights reserved. -- -- This file is part of vis-lspc. -- @@ -18,14 +18,26 @@ -- Note the chunks received may not end with the end of a message. -- In the worst case a data chunk contains two partial messages on at the beginning -- and one at the end -local function add(p, data) - p.data = p.data .. data +--- @module parser +local parser = {} + +local Parser = {} + +function parser.new() + local self = {exp_len = nil, data = '', msgs = {}} + + setmetatable(self, {__index = Parser}) + return self +end + +function Parser:add(data) + self.data = self.data .. data -- we have not seen a complete header in data yet - if not p.exp_len then + if not self.exp_len then -- search for the end of a header -- LSP message format: 'header\r\n\r\nbody' - local header_end, content_start = p.data:find('\r\n\r\n') + local header_end, content_start = self.data:find('\r\n\r\n') -- header is not complete yet -> save data and wait for more if not header_end then @@ -33,55 +45,44 @@ local function add(p, data) end -- got a complete header - local header = p.data:sub(1, header_end) + local header = self.data:sub(1, header_end) -- extract content length from the header - p.exp_len = tonumber(header:match('%d+')) - if not p.exp_len then - return 'invalid header in data: ' .. p.data + self.exp_len = tonumber(header:match('%d+')) + if not self.exp_len then + return 'invalid header in data: ' .. self.data end -- consume header from data - p.data = p.data:sub(content_start + 1) + self.data = self.data:sub(content_start + 1) end - local data_avail = string.len(p.data) + local data_avail = string.len(self.data) -- we have no complete message yet -> await more data - if p.exp_len > data_avail then + if self.exp_len > data_avail then return end - local complete_msg = p.data:sub(1, p.exp_len) - table.insert(p.msgs, complete_msg) + local complete_msg = self.data:sub(1, self.exp_len) + table.insert(self.msgs, complete_msg) -- consume complete_msg from data - p.data = p.data:sub(p.exp_len + 1) + self.data = self.data:sub(self.exp_len + 1) - local leftover = data_avail - p.exp_len + local leftover = data_avail - self.exp_len -- reset exp_len to search for a new header - p.exp_len = nil + self.exp_len = nil if leftover > 0 then - return p:add('') + return self:add('') end end -local function get_msgs(p) - local msgs = p.msgs - p.msgs = {} +function Parser:get_msgs() + local msgs = self.msgs + self.msgs = {} return msgs end -local function Parser() - local parser = { - add = add, - get_msgs = get_msgs, - exp_len = nil, - data = '', - msgs = {}, - } - return parser -end - -return {Parser = Parser} +return parser -- cgit v1.2.3