mirror of
https://github.com/XeonSquared/OC-Copper.git
synced 2024-11-14 22:08:05 +11:00
45 lines
1.4 KiB
Lua
45 lines
1.4 KiB
Lua
-- I, 20kdc, release this into the public domain.
|
|
-- No warranty is provided, implied or otherwise.
|
|
|
|
-- 'Copper' networking implementation - encode/decode
|
|
-- Notably, it's fine that culib relies on the hops byte being the first byte,
|
|
-- because culib is supposed to know the protocol anyway,
|
|
-- and thus can rely on things like that.
|
|
-- YOU, on the other hand, cannot -
|
|
-- relib doesn't know or care about protocol internals, for example,
|
|
-- short of some "convenient" nudging of relib header size and maximum Copper data packet size.
|
|
|
|
local function encodeName(name)
|
|
if name:len() > 256 then error("Bad name (l>256)") end
|
|
if name == "" then error("No name") end
|
|
return string.char(name:len() - 1) .. name
|
|
end
|
|
local function decodeName(message)
|
|
if message:len() < 2 then return end
|
|
local nlen = message:byte(1) + 1
|
|
local fnam = message:sub(2, nlen + 1)
|
|
if fnam:len() < nlen then return end
|
|
return fnam, message:sub(nlen + 2)
|
|
end
|
|
|
|
local function decodeNoHops(data)
|
|
local src, data = decodeName(data)
|
|
if not src then return end
|
|
local dst, data = decodeName(data)
|
|
if not dst then return end
|
|
return src, dst, data
|
|
end
|
|
|
|
return {
|
|
encode = function (hops, src, dst, data)
|
|
return string.char(hops) .. encodeName(src) .. encodeName(dst) .. data
|
|
end,
|
|
decode = function (d)
|
|
if d:len() < 3 then return end
|
|
local src, dst, data = decodeNoHops(d:sub(2))
|
|
if not data then return end
|
|
return d:byte(1), src, dst, data
|
|
end,
|
|
decodeNoHops = decodeNoHops
|
|
}
|