1# Buffers allocated on the heap
2
3from bgenOutput import *
4from bgenType import OutputOnlyMixIn
5from bgenBuffer import FixedInputOutputBufferType
6
7
8class HeapInputOutputBufferType(FixedInputOutputBufferType):
9
10    """Input-output buffer allocated on the heap -- passed as (inbuffer, outbuffer, size).
11
12    Instantiate without parameters.
13    Call from Python with input buffer.
14    """
15
16    def __init__(self, datatype = 'char', sizetype = 'int', sizeformat = None):
17        FixedInputOutputBufferType.__init__(self, "0", datatype, sizetype, sizeformat)
18
19    def getOutputBufferDeclarations(self, name, constmode=False, outmode=False):
20        if constmode:
21            raise RuntimeError, "Cannot use const output buffer"
22        if outmode:
23            out = "*"
24        else:
25            out = ""
26        return ["%s%s *%s__out__" % (self.datatype, out, name)]
27
28    def getargsCheck(self, name):
29        Output("if ((%s__out__ = malloc(%s__in_len__)) == NULL)", name, name)
30        OutLbrace()
31        Output('PyErr_NoMemory();')
32        Output("goto %s__error__;", name)
33        self.label_needed = 1
34        OutRbrace()
35        Output("%s__len__ = %s__in_len__;", name, name)
36
37    def passOutput(self, name):
38        return "%s__in__, %s__out__, (%s)%s__len__" % \
39            (name, name, self.sizetype, name)
40
41    def mkvalueArgs(self, name):
42        return "%s__out__, (int)%s__len__" % (name, name)
43
44    def cleanup(self, name):
45        Output("free(%s__out__);", name)
46        FixedInputOutputBufferType.cleanup(self, name)
47
48
49class VarHeapInputOutputBufferType(HeapInputOutputBufferType):
50
51    """same as base class, but passed as (inbuffer, outbuffer, &size)"""
52
53    def passOutput(self, name):
54        return "%s__in__, %s__out__, &%s__len__" % (name, name, name)
55
56
57class HeapCombinedInputOutputBufferType(HeapInputOutputBufferType):
58
59    """same as base class, but passed as (inoutbuffer, size)"""
60
61    def passOutput(self, name):
62        return "(%s *)memcpy(%s__out__, %s__in__, %s__len__)" % \
63            (self.datatype, name,   name,     name)
64
65
66class VarHeapCombinedInputOutputBufferType(HeapInputOutputBufferType):
67
68    """same as base class, but passed as (inoutbuffer, &size)"""
69
70    def passOutput(self, name):
71        return "(%s *)memcpy(%s__out__, %s__in__, &%s__len__)" % \
72            (self.datatype, name,   name,      name)
73
74
75class HeapOutputBufferType(OutputOnlyMixIn, HeapInputOutputBufferType):
76
77    """Output buffer allocated on the heap -- passed as (buffer, size).
78
79    Instantiate without parameters.
80    Call from Python with buffer size.
81    """
82
83    def getInputBufferDeclarations(self, name, constmode=False):
84        return []
85
86    def getargsFormat(self):
87        return "i"
88
89    def getargsArgs(self, name):
90        return "&%s__in_len__" % name
91
92    def passOutput(self, name):
93        return "%s__out__, %s__len__" % (name, name)
94
95
96class VarHeapOutputBufferType(HeapOutputBufferType):
97
98    """Output buffer allocated on the heap -- passed as (buffer, &size).
99
100    Instantiate without parameters.
101    Call from Python with buffer size.
102    """
103
104    def passOutput(self, name):
105        return "%s__out__, &%s__len__" % (name, name)
106
107
108class VarVarHeapOutputBufferType(VarHeapOutputBufferType):
109
110    """Output buffer allocated on the heap -- passed as (buffer, size, &size).
111
112    Instantiate without parameters.
113    Call from Python with buffer size.
114    """
115
116    def passOutput(self, name):
117        return "%s__out__, %s__len__, &%s__len__" % (name, name, name)
118
119class MallocHeapOutputBufferType(HeapOutputBufferType):
120    """Output buffer allocated by the called function -- passed as (&buffer, &size).
121
122    Instantiate without parameters.
123    Call from Python without parameters.
124    """
125
126    def getargsCheck(self, name):
127        Output("%s__out__ = NULL;", name)
128
129    def getAuxDeclarations(self, name):
130        return []
131
132    def passOutput(self, name):
133        return "&%s__out__, &%s__len__" % (name, name)
134
135    def getargsFormat(self):
136        return ""
137
138    def getargsArgs(self, name):
139        return None
140
141    def mkvalueFormat(self):
142        return "z#"
143
144    def cleanup(self, name):
145        Output("if( %s__out__ ) free(%s__out__);", name, name)
146