1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 | Tools/bgen/bgen/bgenBuffer.py
"""Buffers are character arrays that may contain null bytes. There are a number of variants depending on: - how the buffer is allocated (for output buffers), and - whether and how the size is passed into and/or out of the called function. """ from bgenType import Type, InputOnlyMixIn, OutputOnlyMixIn, InputOnlyType, OutputOnlyType from bgenOutput import * # Map common types to their format characters type2format = { 'long': 'l', 'int': 'i', 'short': 'h', 'char': 'b', 'unsigned long': 'l', 'unsigned int': 'i', 'unsigned short': 'h', 'unsigned char': 'b', } # ----- PART 1: Fixed character buffers ----- class FixedInputOutputBufferType(InputOnlyType): """Fixed buffer -- passed as (inbuffer, outbuffer).""" def __init__(self, size, datatype = 'char', sizetype = 'int', sizeformat = None): self.typeName = "Buffer" self.size = str(size) self.datatype = datatype self.sizetype = sizetype self.sizeformat = sizeformat or type2format[sizetype] self.label_needed = 0 def getArgDeclarations(self, name, reference=False, constmode=False, outmode=False): if reference: raise RuntimeError, "Cannot pass buffer types by reference" return (self.getBufferDeclarations(name, constmode, outmode) + self.getSizeDeclarations(name, outmode)) def getBufferDeclarations(self, name, constmode=False, outmode=False): return self.getInputBufferDeclarations(name, constmode) + \ self.getOutputBufferDeclarations(name, constmode, outmode) def getInputBufferDeclarations(self, name, constmode=False): if constmode: const = "const " else: const = "" return ["%s%s *%s__in__" % (const, self.datatype, name)] 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__[%s]" % (self.datatype, out, name, self.size)] def getSizeDeclarations(self, name, outmode=False): if outmode: out = "*" else: out = "" return ["%s%s %s__len__" %(self.sizetype, out, name)] def getAuxDeclarations(self, name): return ["int %s__in_len__" %(name)] def getargsFormat(self): return "s#" def getargsArgs(self, name): return "&%s__in__, &%s__in_len__" % (name, name) def getargsCheck(self, name): Output("if (%s__in_len__ != %s)", name, self.size) OutLbrace() Output('PyErr_SetString(PyExc_TypeError, "buffer length should be %s");', self.size) Output("goto %s__error__;", name) self.label_needed = 1 OutRbrace() self.transferSize(name) def transferSize(self, name): Output("%s__len__ = %s__in_len__;", name, name) def passOutput(self, name): return "%s__in__, %s__out__" % (name, name) def mkvalueFormat(self): return "s#" def mkvalueArgs(self, name): return "%s__out__, (int)%s" % (name, self.size) def cleanup(self, name): if self.label_needed: DedentLevel() Output(" %s__error__: ;", name) IndentLevel() class FixedCombinedInputOutputBufferType(FixedInputOutputBufferType): """Like fixed buffer -- but same parameter is input and output.""" def passOutput(self, name): return "(%s *)memcpy(%s__out__, %s__in__, %s)" % \ (self.datatype, name, name, self.size) class InputOnlyBufferMixIn(InputOnlyMixIn): def getOutputBufferDeclarations(self, name, constmode=False, outmode=False): return [] class OutputOnlyBufferMixIn(OutputOnlyMixIn): def getInputBufferDeclarations(self, name, constmode=False): return [] class OptionalInputBufferMixIn: """Add to input buffers if the buffer may be omitted: pass None in Python and the C code will get a NULL pointer and zero size""" def getargsFormat(self): return "z#" class FixedInputBufferType(InputOnlyBufferMixIn, FixedInputOutputBufferType): """Fixed size input buffer -- passed without size information. Instantiate with the size as parameter. """ def passInput(self, name): return "%s__in__" % name class OptionalFixedInputBufferType(OptionalInputBufferMixIn, FixedInputBufferType): pass class FixedOutputBufferType(OutputOnlyBufferMixIn, FixedInputOutputBufferType): """Fixed size output buffer -- passed without size information. Instantiate with the size as parameter. """ def passOutput(self, name): return "%s__out__" % name class VarInputBufferType(FixedInputBufferType): """Variable size input buffer -- passed as (buffer, size). Instantiate without size parameter. """ def __init__(self, datatype = 'char', sizetype = 'int', sizeformat = None): FixedInputBufferType.__init__(self, "0", datatype, sizetype, sizeformat) def getargsCheck(self, name): Output("%s__len__ = %s__in_len__;", name, name) def passInput(self, name): return "%s__in__, %s__len__" % (name, name) class ReverseInputBufferMixin: """ Mixin for input buffers that are passed as (size, buffer) """ def passInput(self, name): return "%s__len__, %s__in__" % (name, name) class OptionalVarInputBufferType(OptionalInputBufferMixIn, VarInputBufferType): pass # ----- PART 2: Structure buffers ----- class StructInputOutputBufferType(FixedInputOutputBufferType): """Structure buffer -- passed as a structure pointer. Instantiate with the struct type as parameter. """ def __init__(self, type): FixedInputOutputBufferType.__init__(self, "sizeof(%s)" % type) self.typeName = self.type = type def getInputBufferDeclarations(self, name, constmode=False): if constmode: const = "const " else: const = "" return ["%s%s *%s__in__" % (const, self.type, name)] def getSizeDeclarations(self, name, outmode=False): return [] def getAuxDeclarations(self, name): return ["int %s__in_len__" % (name)] 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.type, out, name)] def getargsArgs(self, name): return "(char **)&%s__in__, &%s__in_len__" % (name, name) def transferSize(self, name): pass def passInput(self, name): return "%s__in__" % name def passOutput(self, name): return "%s__in__, &%s__out__" % (name, name) def mkvalueArgs(self, name): return "(char *)&%s__out__, (int)%s" % (name, self.size) class StructCombinedInputOutputBufferType(StructInputOutputBufferType): """Like structure buffer -- but same parameter is input and output.""" def passOutput(self, name): return "(%s *)memcpy((char *)%s__out__, (char *)%s__in__, %s)" % \ (self.type, name, name, self.size) class StructInputBufferType(InputOnlyBufferMixIn, StructInputOutputBufferType): """Fixed size input buffer -- passed as a pointer to a structure. Instantiate with the struct type as parameter. """ class StructByValueBufferType(StructInputBufferType): """Fixed size input buffer -- passed as a structure BY VALUE. Instantiate with the struct type as parameter. """ def passInput(self, name): return "*%s__in__" % name class StructOutputBufferType(OutputOnlyBufferMixIn, StructInputOutputBufferType): """Fixed size output buffer -- passed as a pointer to a structure. Instantiate with the struct type as parameter. """ def getSizeDeclarations(self, name, outmode=False): return [] def getAuxDeclarations(self, name): return [] def passOutput(self, name): return "&%s__out__" % name class ArrayOutputBufferType(OutputOnlyBufferMixIn, StructInputOutputBufferType): """Fixed size output buffer -- declared as a typedef, passed as an array. Instantiate with the struct type as parameter. """ def getSizeDeclarations(self, name, outmode=False): return [] def getAuxDeclarations(self, name): return [] def passOutput(self, name): return "%s__out__" % name |