--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hglib.lua Wed Sep 07 16:07:39 2016 +0800
+local sizes = { i4 = 4, u4 = 4, c = 1 }
+local function read_u4(rh)
+ local byte = rh:read(1):byte()
+ value = value + byte * (2 ^ ((sizes.u4 - i) * 8))
+local function read_c(rh)
+ return rh:read(sizes.c)
+local function read_channel(rh)
+ local channel = read_c(rh)
+ local length = read_u4(rh)
+ if channel == 'I' or channel == 'L' then
+ return channel, rh:read(length)
+function Client.connect(rh, wh)
+ setmetatable(client, Client)
+function Client:read_hello()
+ local channel, message = read_channel(self.rh)
+ assert(channel == 'o', 'channel for the hello message must be "o"')
+ while index <= #message do
+ local nexteol = message:find('\n', index + 1, true)
+ if nexteol == nil then nexteol = #message + 1 end
+ local line = message:sub(index, nexteol - 1)
+ local ci = line:find(': ', 1, true)
+ local key, value = line:sub(1, ci - 1), line:sub(ci + 2)
+ if key == 'capabilities' then
+ for cap in value:gmatch('%S+') do
+ self.capabilities[cap] = true
+ elseif key == 'encoding' then
+ elseif key == 'pid' then
+ self.pid = tonumber(value)
+ elseif key == 'pgid' then
+ self.pgid = tonumber(value)
+ read_channel = read_channel,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/hglib_spec.lua Wed Sep 07 16:07:39 2016 +0800
+local hglib = require('hglib')
+describe('hglib client', function()
+ it('can read hello', function()
+ local rh = io.open('spec/data/hello', 'rb')
+ local client = hglib.Client.connect(rh, nil)
+ assert.is_true(client.capabilities.getencoding)
+ assert.is_true(client.capabilities.runcommand)
+ assert.are_equal('UTF-8', client.encoding)
+ assert.are_equal(3615, client.pid)
+ assert.are_equal(3615, client.pgid)