Mercurial > projects > managesieve
annotate parser.go @ 12:66b46b3d73be default tip
Handle capabilities sent by the server after negotiating a SASL security layer
author | Guido Berhoerster <guido+managesieve@berhoerster.name> |
---|---|
date | Tue, 09 Feb 2021 23:01:02 +0100 |
parents | 6369453d47a3 |
children |
rev | line source |
---|---|
0
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
1 // Copyright (C) 2020 Guido Berhoerster <guido+managesieve@berhoerster.name> |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
2 // |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
3 // Permission is hereby granted, free of charge, to any person obtaining |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
4 // a copy of this software and associated documentation files (the |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
5 // "Software"), to deal in the Software without restriction, including |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
6 // without limitation the rights to use, copy, modify, merge, publish, |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
7 // distribute, sublicense, and/or sell copies of the Software, and to |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
8 // permit persons to whom the Software is furnished to do so, subject to |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
9 // the following conditions: |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
10 // |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
11 // The above copyright notice and this permission notice shall be included |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
12 // in all copies or substantial portions of the Software. |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
13 // |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
17 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
18 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
19 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
20 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
21 |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
22 package managesieve |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
23 |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
24 import ( |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
25 "strings" |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
26 ) |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
27 |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
28 type response int |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
29 |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
30 const ( |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
31 responseInvalid response = iota |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
32 responseOk |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
33 responseNo |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
34 responseBye |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
35 ) |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
36 |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
37 func lookupResponse(s string) response { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
38 switch s { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
39 case "OK": |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
40 return responseOk |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
41 case "NO": |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
42 return responseNo |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
43 case "BYE": |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
44 return responseBye |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
45 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
46 return responseInvalid |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
47 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
48 |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
49 type reply struct { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
50 lines [][]*token |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
51 resp response |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
52 code string |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
53 codeArgs []string |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
54 msg string |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
55 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
56 |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
57 func parseCapabilities(r *reply) (map[string]string, error) { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
58 capa := make(map[string]string) |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
59 for _, tokens := range r.lines { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
60 var k, v string |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
61 if tokens[0].typ != tokenQuotedString && |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
62 tokens[0].typ != tokenLiteralString { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
63 return nil, ParserError("failed to parse capability name: expected string") |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
64 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
65 k = strings.ToUpper(tokens[0].literal) |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
66 |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
67 if len(tokens) > 1 { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
68 if tokens[1].typ != tokenQuotedString && |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
69 tokens[1].typ != tokenLiteralString { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
70 return nil, ParserError("failed to parse capability value: expected string") |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
71 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
72 v = tokens[1].literal |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
73 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
74 capa[k] = v |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
75 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
76 return capa, nil |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
77 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
78 |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
79 type parser struct { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
80 s *scanner |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
81 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
82 |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
83 func (p *parser) isResponseLine(tokens []*token) bool { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
84 return tokens[0].typ == tokenAtom && |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
85 lookupResponse(tokens[0].literal) != responseInvalid |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
86 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
87 |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
88 func (p *parser) parseResponseLine(tokens []*token) (*reply, error) { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
89 var i int |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
90 next := func() (*token, bool) { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
91 if i >= len(tokens) { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
92 return nil, false |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
93 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
94 tok := tokens[i] |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
95 i++ |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
96 return tok, true |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
97 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
98 |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
99 // response |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
100 tok, cont := next() |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
101 r := &reply{resp: lookupResponse(tok.literal)} |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
102 |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
103 // code starts with left parenthesis |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
104 tok, cont = next() |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
105 if !cont { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
106 // only response without code and/or message |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
107 return r, nil |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
108 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
109 if tok.typ == tokenLeftParenthesis { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
110 // code atom |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
111 tok, cont = next() |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
112 if !cont || tok.typ != tokenAtom { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
113 return nil, ParserError("failed to parse response code: expected atom") |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
114 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
115 r.code = tok.literal |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
116 |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
117 // followed by zero or more string arguments |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
118 for { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
119 tok, cont = next() |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
120 if !cont { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
121 return nil, ParserError("failed to parse response code: unexpected end of line") |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
122 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
123 if tok.typ != tokenQuotedString && |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
124 tok.typ != tokenLiteralString { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
125 break |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
126 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
127 r.codeArgs = append(r.codeArgs, tok.literal) |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
128 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
129 |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
130 // terminated by a right parenthesis |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
131 if tok.typ != tokenRightParenthesis { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
132 return nil, ParserError("failed to parse response code: expected right parenthesis") |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
133 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
134 |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
135 tok, cont = next() |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
136 if !cont { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
137 // response with code but no message |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
138 return r, nil |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
139 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
140 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
141 |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
142 // message string |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
143 if tok.typ != tokenQuotedString && |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
144 tok.typ != tokenLiteralString { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
145 return nil, ParserError("failed to parse response message: expected string") |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
146 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
147 r.msg = strings.TrimSpace(tok.literal) |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
148 |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
149 // end of line |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
150 if _, cont = next(); cont { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
151 return nil, ParserError("failed to parse response line: unexpected trailing data") |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
152 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
153 |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
154 return r, nil |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
155 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
156 |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
157 func (p *parser) readLine() ([]*token, error) { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
158 tokens := make([]*token, 0) |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
159 for { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
160 tok, err := p.s.scan() |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
161 if err != nil { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
162 return nil, err |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
163 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
164 if tok.typ == tokenCRLF { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
165 break |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
166 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
167 tokens = append(tokens, tok) |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
168 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
169 |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
170 return tokens, nil |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
171 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
172 |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
173 func (p *parser) readReply() (*reply, error) { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
174 var r *reply |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
175 var lines [][]*token = make([][]*token, 0, 1) |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
176 for { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
177 tokens, err := p.readLine() |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
178 if err != nil { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
179 return nil, err |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
180 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
181 if len(tokens) == 0 { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
182 return nil, ParserError("unexpected empty line") |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
183 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
184 // check for response tokens |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
185 if p.isResponseLine(tokens) { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
186 r, err = p.parseResponseLine(tokens) |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
187 if err != nil { |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
188 return nil, err |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
189 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
190 r.lines = lines |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
191 break |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
192 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
193 lines = append(lines, tokens) |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
194 } |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
195 |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
196 return r, nil |
6369453d47a3
Initial revision
Guido Berhoerster <guido+managesieve@berhoerster.name>
parents:
diff
changeset
|
197 } |