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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 }