Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(549)

Side by Side Diff: third_party/twisted_8_1/twisted/protocols/dict.py

Issue 12261012: Remove third_party/twisted_8_1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # Copyright (c) 2001-2004 Twisted Matrix Laboratories.
2 # See LICENSE for details.
3
4
5 """
6 Dict client protocol implementation.
7
8 @author: U{Pavel Pergamenshchik<mailto:pp64@cornell.edu>}
9 """
10
11 from twisted.protocols import basic
12 from twisted.internet import defer, protocol
13 from twisted.python import log
14 from StringIO import StringIO
15
16 def parseParam(line):
17 """Chew one dqstring or atom from beginning of line and return (param, reman ingline)"""
18 if line == '':
19 return (None, '')
20 elif line[0] != '"': # atom
21 mode = 1
22 else: # dqstring
23 mode = 2
24 res = ""
25 io = StringIO(line)
26 if mode == 2: # skip the opening quote
27 io.read(1)
28 while 1:
29 a = io.read(1)
30 if a == '"':
31 if mode == 2:
32 io.read(1) # skip the separating space
33 return (res, io.read())
34 elif a == '\\':
35 a = io.read(1)
36 if a == '':
37 return (None, line) # unexpected end of string
38 elif a == '':
39 if mode == 1:
40 return (res, io.read())
41 else:
42 return (None, line) # unexpected end of string
43 elif a == ' ':
44 if mode == 1:
45 return (res, io.read())
46 res += a
47
48 def makeAtom(line):
49 """Munch a string into an 'atom'"""
50 # FIXME: proper quoting
51 return filter(lambda x: not (x in map(chr, range(33)+[34, 39, 92])), line)
52
53 def makeWord(s):
54 mustquote = range(33)+[34, 39, 92]
55 result = []
56 for c in s:
57 if ord(c) in mustquote:
58 result.append("\\")
59 result.append(c)
60 s = "".join(result)
61 return s
62
63 def parseText(line):
64 if len(line) == 1 and line == '.':
65 return None
66 else:
67 if len(line) > 1 and line[0:2] == '..':
68 line = line[1:]
69 return line
70
71 class Definition:
72 """A word definition"""
73 def __init__(self, name, db, dbdesc, text):
74 self.name = name
75 self.db = db
76 self.dbdesc = dbdesc
77 self.text = text # list of strings not terminated by newline
78
79 class DictClient(basic.LineReceiver):
80 """dict (RFC2229) client"""
81
82 data = None # multiline data
83 MAX_LENGTH = 1024
84 state = None
85 mode = None
86 result = None
87 factory = None
88
89 def __init__(self):
90 self.data = None
91 self.result = None
92
93 def connectionMade(self):
94 self.state = "conn"
95 self.mode = "command"
96
97 def sendLine(self, line):
98 """Throw up if the line is longer than 1022 characters"""
99 if len(line) > self.MAX_LENGTH - 2:
100 raise ValueError("DictClient tried to send a too long line")
101 basic.LineReceiver.sendLine(self, line)
102
103 def lineReceived(self, line):
104 try:
105 line = line.decode("UTF-8")
106 except UnicodeError: # garbage received, skip
107 return
108 if self.mode == "text": # we are receiving textual data
109 code = "text"
110 else:
111 if len(line) < 4:
112 log.msg("DictClient got invalid line from server -- %s" % line)
113 self.protocolError("Invalid line from server")
114 self.transport.LoseConnection()
115 return
116 code = int(line[:3])
117 line = line[4:]
118 method = getattr(self, 'dictCode_%s_%s' % (code, self.state), self.dictC ode_default)
119 method(line)
120
121 def dictCode_default(self, line):
122 """Unkown message"""
123 log.msg("DictClient got unexpected message from server -- %s" % line)
124 self.protocolError("Unexpected server message")
125 self.transport.loseConnection()
126
127 def dictCode_221_ready(self, line):
128 """We are about to get kicked off, do nothing"""
129 pass
130
131 def dictCode_220_conn(self, line):
132 """Greeting message"""
133 self.state = "ready"
134 self.dictConnected()
135
136 def dictCode_530_conn(self):
137 self.protocolError("Access denied")
138 self.transport.loseConnection()
139
140 def dictCode_420_conn(self):
141 self.protocolError("Server temporarily unavailable")
142 self.transport.loseConnection()
143
144 def dictCode_421_conn(self):
145 self.protocolError("Server shutting down at operator request")
146 self.transport.loseConnection()
147
148 def sendDefine(self, database, word):
149 """Send a dict DEFINE command"""
150 assert self.state == "ready", "DictClient.sendDefine called when not in ready state"
151 self.result = None # these two are just in case. In "ready" state, resu lt and data
152 self.data = None # should be None
153 self.state = "define"
154 command = "DEFINE %s %s" % (makeAtom(database.encode("UTF-8")), makeWord (word.encode("UTF-8")))
155 self.sendLine(command)
156
157 def sendMatch(self, database, strategy, word):
158 """Send a dict MATCH command"""
159 assert self.state == "ready", "DictClient.sendMatch called when not in r eady state"
160 self.result = None
161 self.data = None
162 self.state = "match"
163 command = "MATCH %s %s %s" % (makeAtom(database), makeAtom(strategy), ma keAtom(word))
164 self.sendLine(command.encode("UTF-8"))
165
166 def dictCode_550_define(self, line):
167 """Invalid database"""
168 self.mode = "ready"
169 self.defineFailed("Invalid database")
170
171 def dictCode_550_match(self, line):
172 """Invalid database"""
173 self.mode = "ready"
174 self.matchFailed("Invalid database")
175
176 def dictCode_551_match(self, line):
177 """Invalid strategy"""
178 self.mode = "ready"
179 self.matchFailed("Invalid strategy")
180
181 def dictCode_552_define(self, line):
182 """No match"""
183 self.mode = "ready"
184 self.defineFailed("No match")
185
186 def dictCode_552_match(self, line):
187 """No match"""
188 self.mode = "ready"
189 self.matchFailed("No match")
190
191 def dictCode_150_define(self, line):
192 """n definitions retrieved"""
193 self.result = []
194
195 def dictCode_151_define(self, line):
196 """Definition text follows"""
197 self.mode = "text"
198 (word, line) = parseParam(line)
199 (db, line) = parseParam(line)
200 (dbdesc, line) = parseParam(line)
201 if not (word and db and dbdesc):
202 self.protocolError("Invalid server response")
203 self.transport.loseConnection()
204 else:
205 self.result.append(Definition(word, db, dbdesc, []))
206 self.data = []
207
208 def dictCode_152_match(self, line):
209 """n matches found, text follows"""
210 self.mode = "text"
211 self.result = []
212 self.data = []
213
214 def dictCode_text_define(self, line):
215 """A line of definition text received"""
216 res = parseText(line)
217 if res == None:
218 self.mode = "command"
219 self.result[-1].text = self.data
220 self.data = None
221 else:
222 self.data.append(line)
223
224 def dictCode_text_match(self, line):
225 """One line of match text received"""
226 def l(s):
227 p1, t = parseParam(s)
228 p2, t = parseParam(t)
229 return (p1, p2)
230 res = parseText(line)
231 if res == None:
232 self.mode = "command"
233 self.result = map(l, self.data)
234 self.data = None
235 else:
236 self.data.append(line)
237
238 def dictCode_250_define(self, line):
239 """ok"""
240 t = self.result
241 self.result = None
242 self.state = "ready"
243 self.defineDone(t)
244
245 def dictCode_250_match(self, line):
246 """ok"""
247 t = self.result
248 self.result = None
249 self.state = "ready"
250 self.matchDone(t)
251
252 def protocolError(self, reason):
253 """override to catch unexpected dict protocol conditions"""
254 pass
255
256 def dictConnected(self):
257 """override to be notified when the server is ready to accept commands"" "
258 pass
259
260 def defineFailed(self, reason):
261 """override to catch reasonable failure responses to DEFINE"""
262 pass
263
264 def defineDone(self, result):
265 """override to catch succesful DEFINE"""
266 pass
267
268 def matchFailed(self, reason):
269 """override to catch resonable failure responses to MATCH"""
270 pass
271
272 def matchDone(self, result):
273 """override to catch succesful MATCH"""
274 pass
275
276
277 class InvalidResponse(Exception):
278 pass
279
280
281 class DictLookup(DictClient):
282 """Utility class for a single dict transaction. To be used with DictLookupFa ctory"""
283
284 def protocolError(self, reason):
285 if not self.factory.done:
286 self.factory.d.errback(InvalidResponse(reason))
287 self.factory.clientDone()
288
289 def dictConnected(self):
290 if self.factory.queryType == "define":
291 apply(self.sendDefine, self.factory.param)
292 elif self.factory.queryType == "match":
293 apply(self.sendMatch, self.factory.param)
294
295 def defineFailed(self, reason):
296 self.factory.d.callback([])
297 self.factory.clientDone()
298 self.transport.loseConnection()
299
300 def defineDone(self, result):
301 self.factory.d.callback(result)
302 self.factory.clientDone()
303 self.transport.loseConnection()
304
305 def matchFailed(self, reason):
306 self.factory.d.callback([])
307 self.factory.clientDone()
308 self.transport.loseConnection()
309
310 def matchDone(self, result):
311 self.factory.d.callback(result)
312 self.factory.clientDone()
313 self.transport.loseConnection()
314
315
316 class DictLookupFactory(protocol.ClientFactory):
317 """Utility factory for a single dict transaction"""
318 protocol = DictLookup
319 done = None
320
321 def __init__(self, queryType, param, d):
322 self.queryType = queryType
323 self.param = param
324 self.d = d
325 self.done = 0
326
327 def clientDone(self):
328 """Called by client when done."""
329 self.done = 1
330 del self.d
331
332 def clientConnectionFailed(self, connector, error):
333 self.d.errback(error)
334
335 def clientConnectionLost(self, connector, error):
336 if not self.done:
337 self.d.errback(error)
338
339 def buildProtocol(self, addr):
340 p = self.protocol()
341 p.factory = self
342 return p
343
344
345 def define(host, port, database, word):
346 """Look up a word using a dict server"""
347 d = defer.Deferred()
348 factory = DictLookupFactory("define", (database, word), d)
349
350 from twisted.internet import reactor
351 reactor.connectTCP(host, port, factory)
352 return d
353
354 def match(host, port, database, strategy, word):
355 """Match a word using a dict server"""
356 d = defer.Deferred()
357 factory = DictLookupFactory("match", (database, strategy, word), d)
358
359 from twisted.internet import reactor
360 reactor.connectTCP(host, port, factory)
361 return d
362
OLDNEW
« no previous file with comments | « third_party/twisted_8_1/twisted/protocols/basic.py ('k') | third_party/twisted_8_1/twisted/protocols/dns.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698