]> git.lizzy.rs Git - luairc.git/blob - src/irc/ctcp.lua
split between internal/public functions in ctcp.lua
[luairc.git] / src / irc / ctcp.lua
1 ---
2 -- Implementation of the CTCP protocol
3 -- initialization {{{
4 local base = _G
5 local table = require "table"
6 -- }}}
7
8 ---
9 -- This module implements the various quoting and escaping requirements of the
10 -- CTCP protocol.
11 module "irc.ctcp"
12
13 -- internal functions {{{
14 -- _low_quote {{{
15 --
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",
22                                      ["\n"]   = "\020n",
23                                      ["\r"]   = "\020r",
24                                      ["\020"] = "\020\020"})
25 end
26 -- }}}
27
28 -- _low_dequote {{{
29 --
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
39                                     return ""
40                                 end)
41 end
42 -- }}}
43
44 -- _ctcp_quote {{{
45 --
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",
52                                       ["\\"]   = "\\\\"})
53     return "\001" .. ret .. "\001"
54 end
55 -- }}}
56
57 -- _ctcp_dequote {{{
58 --
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
68                                   return ""
69                               end)
70 end
71 -- }}}
72
73 -- _ctcp_split {{{
74 -- TODO: again with this string/table thing... it's ugly!
75 --
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)
82     local ret = {}
83     local iter = 1
84     while true do
85         local s, e = str:find("\001.*\001", iter)
86
87         local plain_string, ctcp_string
88         if not s then
89             plain_string = str:sub(iter, -1)
90         else
91             plain_string = str:sub(iter, s - 1)
92             ctcp_string = str:sub(s, e)
93         end
94
95         if plain_string ~= "" then
96             table.insert(ret, plain_string)
97         end
98         if not s then break end
99         if ctcp_string ~= "" then
100             if dequote then
101                 table.insert(ret, {_ctcp_dequote(ctcp_string)})
102             else
103                 table.insert(ret, {ctcp_string})
104             end
105         end
106
107         iter = e + 1
108     end
109
110     return ret
111 end
112 -- }}}
113 -- }}}