]> code.delx.au - offlineimap/blob - src/Network/IMAP/Parser/Prim.hs
Added text and test for it
[offlineimap] / src / Network / IMAP / Parser / Prim.hs
1 {- offlineimap component
2 Copyright (C) 2008 John Goerzen <jgoerzen@complete.org>
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 -}
18
19 module Network.IMAP.Parser.Prim where
20 import Text.ParserCombinators.Parsec
21 import Network.IMAP.Types
22
23 ----------------------------------------------------------------------
24 -- RFC 2234 (ABNF) declarations
25 ----------------------------------------------------------------------
26
27 -- | RFC 2234
28 ctl :: String
29 ctl = '\x7f' : ['\x00'..'\x1f']
30
31 -- | RFC 2234
32 cr, lf :: Char
33 cr = '\x0d'
34 lf = '\x0a'
35
36 -- | RFC 2234
37 crlf :: String
38 crlf = [cr, lf]
39
40 -- | RFC 2234
41 digit2234 :: String
42 digit2234 = ['0'..'9']
43
44 -- | RFC 2234
45 hexdig :: String
46 hexdig = digit2234 ++ ['A'..'F']
47
48 -- | RFC 2234
49 alpha :: String
50 alpha = ['A'..'Z'] ++ ['a'..'z']
51
52 -- | RFC 2234
53 dquote :: Char
54 dquote = '"'
55
56 -- | RFC 2234
57 char2234 :: String
58 char2234 = ['\x01'..'\x7f']
59
60 -- | RFC 2234
61 sp :: Char
62 sp = ' '
63
64 -- | RFC 2234
65
66 ----------------------------------------------------------------------
67 -- RFC 3501 primitives
68 ----------------------------------------------------------------------
69
70 -- | RFC 3501
71 atomSpecials :: String
72 atomSpecials = "(){ " ++ ctl ++ listWildcards ++ quotedSpecials ++ respSpecials
73
74 listWildcards :: String
75 listWildcards = "%*"
76
77 quotedSpecials :: String
78 quotedSpecials = ['\\', dquote]
79
80 respSpecials :: String
81 respSpecials = "]"
82
83 ----------------------------------------------------------------------
84 -- Parsec RFC 3501 primitives
85 ----------------------------------------------------------------------
86
87 -- | Technically, <any CHAR except atom-specials> but we will
88 -- be more permissive.
89 --
90 -- FIXME: not stated in RFC, but perhaps CRLF is also excluded?
91 atomChar = noneOf atomSpecials
92
93 atom = many1 atomChar
94
95 astringChar = atomChar <|> oneOf respSpecials
96
97 astring = many1 astringChar <|> string3501
98
99 string3501 = quoted <|> literal
100
101 literal =
102 do char '{'
103 scount <- many1 digit
104 char '}'
105 string crlf
106 let icount = (read scount)::Int
107 count icount anyChar
108
109 quoted =
110 do char dquote
111 strdata <- many quotedChar
112 char dquote
113 return strdata
114
115 quotedChar =
116 noneOf quotedSpecials <|> (do char '\\'
117 oneOf quotedSpecials
118 )
119
120 -- | Fixme: should exclude 8-bit data per RFC3501
121 textChar = noneOf crlf
122
123 text = many1 textChar