2 -- Implementation of the CTCP protocol
5 local table = require "table"
9 -- This module implements the various quoting and escaping requirements of the
13 -- internal functions {{{
16 -- Applies low level quoting to a string (escaping characters which are illegal
17 -- to appear in an IRC packet).
18 -- @param str String to quote
19 -- @return Quoted string
20 function _low_quote(str)
21 return str:gsub("[%z\n\r\020]", {["\000"] = "\0200",
24 ["\020"] = "\020\020"})
30 -- Removes low level quoting done by low_quote.
31 -- @param str String with low level quoting applied to it
32 -- @return String with those quoting methods stripped off
33 function _low_dequote(str)
34 return str:gsub("\020(.?)", function(s)
35 if s == "0" then return "\000" end
36 if s == "n" then return "\n" end
37 if s == "r" then return "\r" end
38 if s == "\020" then return "\020" end
46 -- Applies CTCP quoting to a block of text which has been identified as CTCP
47 -- data (by the calling program).
48 -- @param str String to apply CTCP quoting to
49 -- @return String with CTCP quoting applied
50 function _ctcp_quote(str)
51 local ret = str:gsub("[\001\\]", {["\001"] = "\\a",
53 return "\001" .. ret .. "\001"
59 -- Removes CTCP quoting from a block of text which has been identified as CTCP
60 -- data (likely by ctcp_split).
61 -- @param str String with CTCP quoting
62 -- @return String with all CTCP quoting stripped
63 function _ctcp_dequote(str)
64 local ret = str:gsub("^\001", ""):gsub("\001$", "")
65 return ret:gsub("\\(.?)", function(s)
66 if s == "a" then return "\001" end
67 if s == "\\" then return "\\" end
74 -- TODO: again with this string/table thing... it's ugly!
76 -- Splits a low level dequoted string into normal text and CTCP messages.
77 -- @param str Low level dequoted string
78 -- @param dequote If true, the CTCP messages will also be CTCP dequoted
79 -- @return Array, where string values correspond to plain text, and table
80 -- values have t[1] as the CTCP message
81 function _ctcp_split(str, dequote)
85 local s, e = str:find("\001.*\001", iter)
87 local plain_string, ctcp_string
89 plain_string = str:sub(iter, -1)
91 plain_string = str:sub(iter, s - 1)
92 ctcp_string = str:sub(s, e)
95 if plain_string ~= "" then
96 table.insert(ret, plain_string)
98 if not s then break end
99 if ctcp_string ~= "" then
101 table.insert(ret, {_ctcp_dequote(ctcp_string)})
103 table.insert(ret, {ctcp_string})