class blockreader_base:
    """
    Base class for other blockreaders. Each blockreader should
    have a constructor allowing to specify the file or data flow
    to read, and a blocksize. The blocksize might be automatically
    calculated according to other parameters, but it has to be
    known when the flow starts.

    This class allow automatic computation of the number of blocks
    according to blocksize and filesize. It also features a getnextblock
    method using a nextblock counter, for easy implementation of flow send.
    getnextblock will return None if the last block has been reached.

    Every subclass should define a getblock(blocknumber) method,
    returning the given block as a string. getblock methods can call
    checkblock, which ensures that the block number is valid.
    Requesting an invalid blocknumber (negative, or too large)
    should throw an exception (IndexError is appropriate).

    The rationale for using block numbers instead of byte offsets is
    that we can thus bypass the 4 Gb limit due to 32 bits offsets.
    """
    def __init__(self,filesize,blocksize):
        self.blocksize   = blocksize
        self.filesize    = filesize
        self.wholeblocks = self.filesize / self.blocksize
        self.lastblock   = self.filesize % self.blocksize
        self.blockcount  = self.wholeblocks
        if self.filesize % self.blocksize : self.blockcount += 1
        self.nextblock   = 0
    def getnextblock(self):
        if self.nextblock==self.blockcount: return None
        block = self.getblock(self.nextblock)
        self.nextblock += 1
        return block
    def checkblock(self,blocknumber):
        if blocknumber<0 or blocknumber>=self.blockcount:
            raise IndexError("block %d not in 0..%d"%\
                             (blocknumber,self.blockcount))
    def getblock(self,blocknumber): pass
        
