# Buffers allocated on the heap

from bgenOutput import *
from bgenType import OutputOnlyMixIn
from bgenBuffer import FixedInputOutputBufferType


class HeapInputOutputBufferType(FixedInputOutputBufferType):

    """Input-output buffer allocated on the heap -- passed as (inbuffer, outbuffer, size).

    Instantiate without parameters.
    Call from Python with input buffer.
    """

    def __init__(self, datatype = 'char', sizetype = 'int', sizeformat = None):
        FixedInputOutputBufferType.__init__(self, "0", datatype, sizetype, sizeformat)

    def getOutputBufferDeclarations(self, name, constmode=False, outmode=False):
        if constmode:
            raise RuntimeError, "Cannot use const output buffer"
        if outmode:
            out = "*"
        else:
            out = ""
        return ["%s%s *%s__out__" % (self.datatype, out, name)]

    def getargsCheck(self, name):
        Output("if ((%s__out__ = malloc(%s__in_len__)) == NULL)", name, name)
        OutLbrace()
        Output('PyErr_NoMemory();')
        Output("goto %s__error__;", name)
        self.label_needed = 1
        OutRbrace()
        Output("%s__len__ = %s__in_len__;", name, name)

    def passOutput(self, name):
        return "%s__in__, %s__out__, (%s)%s__len__" % \
            (name, name, self.sizetype, name)

    def mkvalueArgs(self, name):
        return "%s__out__, (int)%s__len__" % (name, name)

    def cleanup(self, name):
        Output("free(%s__out__);", name)
        FixedInputOutputBufferType.cleanup(self, name)


class VarHeapInputOutputBufferType(HeapInputOutputBufferType):

    """same as base class, but passed as (inbuffer, outbuffer, &size)"""

    def passOutput(self, name):
        return "%s__in__, %s__out__, &%s__len__" % (name, name, name)


class HeapCombinedInputOutputBufferType(HeapInputOutputBufferType):

    """same as base class, but passed as (inoutbuffer, size)"""

    def passOutput(self, name):
        return "(%s *)memcpy(%s__out__, %s__in__, %s__len__)" % \
            (self.datatype, name,   name,     name)


class VarHeapCombinedInputOutputBufferType(HeapInputOutputBufferType):

    """same as base class, but passed as (inoutbuffer, &size)"""

    def passOutput(self, name):
        return "(%s *)memcpy(%s__out__, %s__in__, &%s__len__)" % \
            (self.datatype, name,   name,      name)


class HeapOutputBufferType(OutputOnlyMixIn, HeapInputOutputBufferType):

    """Output buffer allocated on the heap -- passed as (buffer, size).

    Instantiate without parameters.
    Call from Python with buffer size.
    """

    def getInputBufferDeclarations(self, name, constmode=False):
        return []

    def getargsFormat(self):
        return "i"

    def getargsArgs(self, name):
        return "&%s__in_len__" % name

    def passOutput(self, name):
        return "%s__out__, %s__len__" % (name, name)


class VarHeapOutputBufferType(HeapOutputBufferType):

    """Output buffer allocated on the heap -- passed as (buffer, &size).

    Instantiate without parameters.
    Call from Python with buffer size.
    """

    def passOutput(self, name):
        return "%s__out__, &%s__len__" % (name, name)


class VarVarHeapOutputBufferType(VarHeapOutputBufferType):

    """Output buffer allocated on the heap -- passed as (buffer, size, &size).

    Instantiate without parameters.
    Call from Python with buffer size.
    """

    def passOutput(self, name):
        return "%s__out__, %s__len__, &%s__len__" % (name, name, name)

class MallocHeapOutputBufferType(HeapOutputBufferType):
    """Output buffer allocated by the called function -- passed as (&buffer, &size).

    Instantiate without parameters.
    Call from Python without parameters.
    """

    def getargsCheck(self, name):
        Output("%s__out__ = NULL;", name)

    def getAuxDeclarations(self, name):
        return []

    def passOutput(self, name):
        return "&%s__out__, &%s__len__" % (name, name)

    def getargsFormat(self):
        return ""

    def getargsArgs(self, name):
        return None

    def mkvalueFormat(self):
        return "z#"

    def cleanup(self, name):
        Output("if( %s__out__ ) free(%s__out__);", name, name)
