# -*- 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)
