14
14
from zope.interface import implements
17
from twisted.python import log, reflect, components, failure
17
from twisted.python import log, reflect, failure
18
18
from twisted.persisted import styles
82
82
reflect.qual(self.__class__))
85
"""Called when data is avaliable for reading.
87
Subclasses must override this method. The result will be interpreted
88
in the same way as a result of doWrite().
85
90
raise NotImplementedError("%s does not implement doRead" %
86
91
reflect.qual(self.__class__))
89
"""Called when data is available for writing.
94
"""Called when data can be written.
91
96
A result that is true (which will be a negative number) implies the
92
97
connection was lost. A false result implies the connection is still
159
164
def write(self, data):
160
165
"""Reliably write some data.
162
The data is buffered until his file descriptor is ready for writing.
167
The data is buffered until the underlying file descriptor is ready
168
for writing. If there is more than C{self.bufferSize} data in the
169
buffer and this descriptor has a registered streaming producer, its
170
C{pauseProducing()} method will be called.
164
172
if isinstance(data, unicode): # no, really, I mean it
165
173
raise TypeError("Data must not be unicode")
169
177
self._tempDataBuffer.append(data)
170
178
self._tempDataLen += len(data)
171
if self.producer is not None:
179
# If we are responsible for pausing our producer,
180
if self.producer is not None and self.streamingProducer:
181
# and our buffer is full,
172
182
if len(self.dataBuffer) + self._tempDataLen > self.bufferSize:
173
184
self.producerPaused = 1
174
185
self.producer.pauseProducing()
175
186
self.startWriting()
177
188
def writeSequence(self, iovec):
189
"""Reliably write a sequence of data.
191
Currently, this is a convenience method roughly equivalent to::
196
It may have a more efficient implementation at a later time or in a
199
As with the C{write()} method, if a buffer size limit is reached and a
200
streaming producer is registered, it will be paused until the buffered
201
data is written to the underlying file descriptor.
178
203
if not self.connected or not iovec or self._writeDisconnected:
180
205
self._tempDataBuffer.extend(iovec)
182
207
self._tempDataLen += len(i)
183
if self.producer is not None:
208
# If we are responsible for pausing our producer,
209
if self.producer is not None and self.streamingProducer:
210
# and our buffer is full,
184
211
if len(self.dataBuffer) + self._tempDataLen > self.bufferSize:
185
213
self.producerPaused = 1
186
214
self.producer.pauseProducing()
187
215
self.startWriting()
258
286
This sets this selectable to be a consumer for a producer. When this
259
287
selectable runs out of data on a write() call, it will ask the producer
260
to resumeProducing(). A producer should implement the IProducer
288
to resumeProducing(). When the FileDescriptor's internal data buffer is
289
filled, it will ask the producer to pauseProducing(). If the connection
290
is lost, FileDescriptor calls producer's stopProducing() method.
263
FileDescriptor provides some infrastructure for producer methods.
292
If streaming is true, the producer should provide the IPushProducer
293
interface. Otherwise, it is assumed that producer provides the
294
IPullProducer interface. In this case, the producer won't be asked
295
to pauseProducing(), but it has to be careful to write() data only
296
when its resumeProducing() method is called.
265
298
if self.producer is not None:
266
299
raise RuntimeError("Cannot register producer %s, because producer %s was never unregistered." % (producer, self.producer))