# -*- Mode: Python; tab-width: 4 -*-
RCS_ID = '$Id: asynchat_sendfile.py,v 1.3 2001/05/01 11:45:27 andreas Exp $'
import sendfile
import asynchat
async_chat = asynchat.async_chat
# we can't call sendfile() until ac_out_buffer is empty.
class async_chat_with_sendfile (async_chat):
# if we are in the middle of sending a file, this will be overriden
_sendfile = None
def push_sendfile (self, fd, offset, bytes, callback=None):
# we set out_buffer_size to zero in order to keep async_chat
# from calling refill_buffer until the whole file has been sent.
self._saved_obs = self.ac_out_buffer_size
self.ac_out_buffer_size = 0
self._sendfile = (fd, offset, bytes, callback)
def initiate_send (self):
if self._sendfile is None:
async_chat.initiate_send (self)
else:
if len(self.ac_out_buffer):
async_chat.initiate_send (self)
else:
fd, offset, bytes, callback = self._sendfile
me = self.socket.fileno()
try:
sent = sendfile.sendfile (fd, me, offset, bytes)
offset = offset + sent
bytes = bytes - sent
if bytes:
self._sendfile = (fd, offset, bytes, callback)
else:
self._sendfile = None
self.ac_out_buffer_size = self._saved_obs
if callback is not None:
# success
callback (1, fd)
except:
self._sendfile = None
self.ac_out_buffer_size = self._saved_obs
# failure
if callback is not None:
callback (0, fd)
# here's how you might use this:
# fd = os.open (filename, os.O_RDONLY, 0644)
# size = os.lseek (fd, 0, 2)
# os.lseek (fd, 0, 0)
# self.push ('%08x' % size)
# self.push_sendfile (fd, 0, size)
|