1/* 2 * Copyright 2018, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the BSD 2-Clause license. Note that NO WARRANTY is provided. 8 * See "LICENSE_BSD2.txt" for details. 9 * 10 * @TAG(DATA61_BSD) 11 */ 12 13/*- macro show_input_parameter(p, namespace_prefix='') -*/ 14 /*- if p.direction == 'in' -*/ 15 /*-- if p.array --*/ 16 size_t /*? namespace_prefix ?*//*? p.name ?*/_sz, 17 /*- if p.type == 'string' -*/ 18 char ** 19 /*- else -*/ 20 const /*? macros.show_type(p.type) ?*/ * 21 /*- endif -*/ 22 /*-- elif p.type == 'string' --*/ 23 const char * 24 /*- else -*/ 25 /*?- macros.show_type(p.type) -?*/ 26 /*- endif -*/ /*? namespace_prefix ?*//*? p.name -?*/ 27 /*- else -*/ 28 /*- if p.array -*/ 29 /*- if p.direction == 'refin' -*/ 30 const 31 /*- endif -*/ 32 size_t * /*? namespace_prefix ?*//*? p.name ?*/_sz, 33 /*- if p.type == 'string' -*/ 34 char *** 35 /*- else -*/ 36 /*?- macros.show_type(p.type) ?*/ ** 37 /*- endif -*/ 38 /*- elif p.type == 'string' -*/ 39 char ** 40 /*- else -*/ 41 /*- if p.direction == 'refin' -*/ 42 const 43 /*- endif -*/ 44 /*?- macros.show_type(p.type) ?*/ * 45 /*- endif -*/ 46 /*? namespace_prefix ?*//*? p.name ?*/ 47 /*- endif -*/ 48/*- endmacro -*/ 49 50/*- macro show_input_parameter_list(parameters, valid_directions, namespace_prefix='') -*/ 51 /*-- for p in parameters --*/ 52 /*?- assert(p.direction in valid_directions) -?*/ 53 /*?- show_input_parameter(p, namespace_prefix) ?*//*- if not loop.last -*/,/*- endif -*/ 54 /*-- endfor --*/ 55/*- endmacro -*/ 56 57/*- macro show_output_parameter(p, namespace_prefix='') -*/ 58 /*- if p.array -*/ 59 size_t * /*? namespace_prefix ?*//*? p.name ?*/_sz, 60 /*?- macros.show_type(p.type) -?*/ ** /*?- namespace_prefix ?*//*? p.name -?*/ 61 /*- else -*/ 62 /*?- macros.show_type(p.type) -?*/ * /*?- namespace_prefix ?*//*? p.name -?*/ 63 /*- endif -*/ 64/*- endmacro -*/ 65 66/*- macro show_output_parameter_list(parameters, namespace_prefix='') -*/ 67 /*-- for p in parameters --*/ 68 /*?- show_output_parameter(p, namespace_prefix) -?*//*-- if not loop.last --*/,/*-- endif --*/ 69 /*-- endfor --*/ 70/*- endmacro -*/ 71 72/*# Generates code for marshalling input parameters to an RPC invocation 73 # name: Name of this method 74 # function: Name of function to create 75 # method_index: Index of this method in the containing interface 76 # methods_len: Total number of methods in this interface 77 # input_parameters: All input parameters to this method 78 #*/ 79/*- macro make_marshal_input_symbols(name, function, method_index, methods_len, input_parameters) -*/ 80 /*# Validate that our arguments are the correct type #*/ 81 /*? assert(isinstance(name, six.string_types)) ?*/ 82 /*? assert(isinstance(function, six.string_types)) ?*/ 83 /*? assert(isinstance(method_index, six.integer_types)) ?*/ 84 /*? assert(isinstance(methods_len, six.integer_types)) ?*/ 85 /*? assert(isinstance(input_parameters, (list, tuple))) ?*/ 86 87 static unsigned /*? function ?*/(void * base, size_t size 88 /*-- if len(input_parameters) > 0 --*/ 89 , 90 /*-- endif -*/ 91 /*?- show_input_parameter_list(input_parameters, ['in', 'refin', 'inout'], namespace_prefix="p_") -?*/ 92 ) { 93 94 unsigned offset = 0; 95 96 /*- if methods_len > 1 -*/ 97 /* Marshal the method index. */ 98 /*? macros.type_to_fit_integer(methods_len) ?*/ method_index = /*? method_index ?*/; 99 offset = MARSHAL_PARAM(&method_index, base, size, offset, "/*? name ?*/", "method_index"); 100 /*- endif -*/ 101 102 /*- for p in input_parameters -*/ 103 /*-- if loop.first -*/ 104 /* Marshal the parameters. */ 105 /*-- endif -*/ 106 /*?- assert(isinstance(p.type, six.string_types)) ?*/ 107 108 /*#- Construct parameter pointers. We do this here to consolidate where we 109 * are taking the address of local variables. In future, we need to avoid 110 * doing this for verification. 111 #*/ 112 /*-- set ptr = "p_%s_ptr" % p.name -*/ 113 /*-- set ptr_sz = "p_%s_ptr_sz" % p.name -*/ 114 /*-- set ptr_str = "p_%s_ptr_str" % p.name -*/ 115 /*-- set ptr_arr = "p_%s_ptr_arr" % p.name -*/ 116 /*-- if p.direction == 'in' -*/ 117 /*-- if p.array -*/ 118 size_t * /*? ptr_sz ?*/ = &p_/*? p.name ?*/_sz; 119 * /*? ptr_sz ?*/ = p_/*? p.name ?*/_sz; 120 /*-- if p.type == 'string' -*/ 121 char ** /*? ptr_arr ?*/ = p_/*? p.name ?*/; 122 /*-- else -*/ 123 const /*? macros.show_type(p.type) ?*/ * /*? ptr_arr ?*/ = p_/*? p.name ?*/; 124 /*-- endif -*/ 125 /*-- elif p.type == 'string' -*/ 126 const char * /*? ptr_str ?*/ = p_/*? p.name ?*/; 127 /*-- else -*/ 128 /*? macros.show_type(p.type) ?*/ * /*? ptr ?*/ = &p_/*? p.name ?*/; 129 /*-- endif -*/ 130 /*-- else -*/ 131 /*-- if p.array -*/ 132 const size_t * /*? ptr_sz ?*/ = p_/*? p.name ?*/_sz; 133 /*-- if p.type == 'string' -*/ 134 char ** /*? ptr_arr ?*/ = * p_/*? p.name ?*/; 135 /*-- else -*/ 136 const /*? macros.show_type(p.type) ?*/ * /*? ptr_arr ?*/ = * p_/*? p.name ?*/; 137 /*-- endif -*/ 138 /*-- elif p.type == 'string' -*/ 139 const char * /*? ptr_str ?*/ = * p_/*? p.name ?*/; 140 /*-- else -*/ 141 const /*? macros.show_type(p.type) ?*/ * /*? ptr ?*/ = p_/*? p.name ?*/; 142 /*-- endif -*/ 143 /*-- endif -*/ 144 145 /*-- if p.array -*/ 146 /*-- if p.type == 'string' -*/ 147 offset = MARSHAL_STRING_ARRAY_PARAM(/*? ptr_arr ?*/, /*? ptr_sz ?*/, base, size, offset, "/*? name ?*/", "/*? p.name ?*/"); 148 /*-- else -*/ 149 offset = MARSHAL_ARRAY_PARAM(/*? ptr_arr ?*/, /*? ptr_sz ?*/, base, size, offset, "/*? name ?*/", "/*? p.name ?*/"); 150 /*-- endif -*/ 151 /*-- elif p.type == 'string' -*/ 152 offset = MARSHAL_STRING_PARAM(/*? ptr_str ?*/, base, size, offset, "/*? name ?*/", "/*? p.name ?*/"); 153 /*-- else -*/ 154 offset = MARSHAL_PARAM(/*? ptr ?*/, base, size, offset, "/*? name ?*/", "/*? p.name ?*/"); 155 /*-- endif -*/ 156 /*- endfor -*/ 157 158 assert(offset <= size && 159 "uncaught buffer overflow while marshalling inputs for /*? name ?*/"); 160 161 return offset; 162 } 163/*- endmacro -*/ 164 165/*# Emits a call to the C symbol that will marshal input parameters 166 # function: Name of function to invoke 167 # buffer: Buffer symbol (or expression) to marshal into 168 # size: Length of the buffer; possibly not generation-time constant 169 # input_parameters: All input parameters to this method 170 #*/ 171/*- macro call_marshal_input(function, buffer, size, input_parameters, namespace_prefix='') -*/ 172 /*#- Validate our arguments are the correct types #*/ 173 /*?- assert(isinstance(function, six.string_types)) ?*/ 174 /*?- assert(isinstance(buffer, six.string_types)) ?*/ 175 /*?- assert(isinstance(size, (six.string_types,six.integer_types))) ?*/ 176 /*?- assert(isinstance(input_parameters, (list, tuple))) ?*/ 177 178 /*?- function ?*/(/*? buffer ?*/, /*? size ?*/ 179 /*-- for p in input_parameters --*/, 180 /*- if p.array -*//*? namespace_prefix ?*//*? p.name ?*/_sz,/*- endif -*/ 181 /*?- namespace_prefix ?*//*? p.name ?*/ 182 /*-- endfor --*/ 183 ) 184/*- endmacro -*/ 185 186 187/*# Generates code for marshalling out parameters to an RPC invocation 188 # name: Name of this method 189 # function: Name of function to create 190 # method_index: Index of this method in the containing interface 191 # output_parameters: All output parameters to this method 192 # return_type: Return type of this interface 193 # allow_trailing_data: Whether to ignore checks for remaining bytes after a message 194 #*/ 195/*# Whether to ignore checks for remaining bytes after a message #*/ 196/*- macro make_unmarshal_output_symbols(name, function, method_index, output_parameters, return_type, allow_trailing_data) -*/ 197 /*# Validate our argument types #*/ 198 /*? assert(isinstance(name, six.string_types)) ?*/ 199 /*? assert(isinstance(function, six.string_types)) ?*/ 200 /*? assert(isinstance(method_index, six.integer_types)) ?*/ 201 /*? assert(isinstance(output_parameters, (list, tuple))) ?*/ 202 /*? assert(return_type is none or isinstance(return_type, six.string_types)) ?*/ 203 /*? assert(isinstance(allow_trailing_data, bool)) ?*/ 204 205 static int /*? function ?*/(void * base, unsigned size 206 /*-- if return_type is not none or len(output_parameters) > 0 --*/ 207 , 208 /*-- endif -*/ 209 /*-- if return_type is not none -*/ 210 /*?- macros.show_type(return_type) ?*/ * return_value 211 /*-- if len(output_parameters) > 0 -*/,/*- endif -*/ 212 /*-- endif -*/ 213 /*?- show_output_parameter_list(output_parameters, namespace_prefix="p_") ?*/ 214 ) { 215 216 unsigned offset = 0; 217 218 /*- if return_type is not none -*/ 219 /* Unmarshal the return value. */ 220 /*-- if return_type == 'string' -*/ 221 offset = UNMARSHAL_STRING_PARAM(return_value, base, size, offset, "/*? name ?*/", "return value", ({return -1;})); 222 /*-- else -*/ 223 offset = UNMARSHAL_PARAM(return_value, base, size, offset, "/*? name ?*/", "return value", ({return -1;})); 224 /*- endif -*/ 225 /*- endif -*/ 226 227 /*-- for index, p in enumerate(output_parameters) -*/ 228 /*-- if loop.first -*/ 229 /* Unmarshal the parameters. */ 230 /*-- endif -*/ 231 /*?- assert(isinstance(p.type, six.string_types)) ?*/ 232 /*-- if p.array -*/ 233 /*-- if p.direction == 'inout' -*/ 234 /*-- if p.type == 'string' -*/ 235 /* At this point p_/*? p.name ?*/_sz should still contain the old size */ 236 for (int i = 0; i < * p_/*? p.name ?*/_sz; i ++) { 237 free((* p_/*? p.name ?*/)[i]); 238 } 239 /*-- endif -*/ 240 free(* p_/*? p.name ?*/); 241 /*-- endif -*/ 242 /*-- elif p.type == 'string' -*/ 243 /*-- if p.direction == 'inout' -*/ 244 free(* p_/*? p.name ?*/); 245 /*-- endif -*/ 246 /*-- endif -*/ 247 248 /*-- if p.array -*/ 249 /*-- if p.type == 'string' -*/ 250 offset = UNMARSHAL_STRING_ARRAY_PARAM(p_/*? p.name ?*/, p_/*? p.name ?*/_sz, base, size, offset, "/*? name ?*/", "/*? p.name ?*/", ({goto cleanup_/*? index ?*/;})); 251 /*-- else -*/ 252 offset = UNMARSHAL_ARRAY_PARAM(p_/*? p.name ?*/, p_/*? p.name ?*/_sz, base, size, offset, "/*? name ?*/", "/*? p.name ?*/", ({goto cleanup_/*? index ?*/;})); 253 /*-- endif -*/ 254 /*-- elif p.type == 'string' -*/ 255 offset = UNMARSHAL_STRING_PARAM(p_/*? p.name ?*/, base, size, offset, "/*? name ?*/", "/*? p.name ?*/", ({goto cleanup_/*? index ?*/;})); 256 /*-- else -*/ 257 offset = UNMARSHAL_PARAM(p_/*? p.name ?*/, base, size, offset, "/*? name ?*/", "/*? p.name ?*/", ({goto cleanup_/*? index ?*/;})); 258 /*-- endif -*/ 259 /*- endfor -*/ 260 261 /*- if not allow_trailing_data -*/ 262 /* Error if there is still payload that hasn't been processed */ 263 ERR_IF_MALFORMED_RPC_EXCESS_PAYLOAD(size, offset, "/*? name ?*/", ({ 264 goto cleanup_/*? len(output_parameters) ?*/; 265 })); 266 /*- endif -*/ 267 268 return 0; 269 270 /*- for index, q in enumerate(output_parameters) | reverse -*/ 271cleanup_/*? index + 1 ?*/: 272 /*- if q.array -*/ 273 /*- if q.type == 'string' -*/ 274 for (int i = 0; i < * p_/*? q.name ?*/_sz; i++) { 275 free((* p_/*? q.name ?*/)[i]); 276 } 277 /*- endif -*/ 278 free(* p_/*? q.name ?*/); 279 /*- elif q.type == 'string' -*/ 280 free(* p_/*? q.name ?*/); 281 /*- endif -*/ 282 /*- endfor -*/ 283cleanup_0: 284 /*-- if return_type == 'string' -*/ 285 free(* return_value); 286 /*-- endif -*/ 287 return -1; 288 } 289/*- endmacro -*/ 290 291 292/*# Emits a call to the C symbol that will unmarshal output parameters 293 # function: Name of function to invoke 294 # buffer: Buffer symbol (or expression) to marshal into 295 # size: Name of a variable storing the byte length of the message 296 # output_parameters: All output parameters to this method 297 # return_type: Return type of this interface 298 # ret_ptr: Pointer for the return value 299 #*/ 300/*- macro call_unmarshal_output(function, buffer, size, output_parameters, return_type, ret_ptr, namespace_prefix='') -*/ 301 /*#- Validate the types of our arguments #*/ 302 /*?- assert(isinstance(function, six.string_types)) ?*/ 303 /*?- assert(isinstance(buffer, six.string_types)) ?*/ 304 /*?- assert(isinstance(size, (six.string_types,six.integer_types))) ?*/ 305 /*?- assert(isinstance(output_parameters, (list, tuple))) ?*/ 306 /*?- assert(return_type is none or isinstance(return_type, six.string_types)) ?*/ 307 308 /*?- function ?*/(/*? buffer ?*/, 309 /*?- size ?*/ 310 /*-- if return_type is not none -*/, 311 /*?- ret_ptr ?*/ 312 /*-- endif -*/ 313 /*-- for p in output_parameters -*/, 314 /*-- if p.array -*/ 315 /*?- namespace_prefix ?*//*? p.name ?*/_sz, 316 /*-- endif -*/ 317 /*?- namespace_prefix ?*//*? p.name ?*/ 318 /*-- endfor --*/ 319 ) 320/*- endmacro -*/ 321 322/*# Generates code for marshalling out parameters to an RPC invocation 323 # name: Name of this method 324 # function: Name of function to create 325 # methods_len: Total number of methods in this interface 326 # input_parameters: All input parameters to this method 327 # allow_trailing_data: Whether to ignore checks for remaining bytes after a message 328 #*/ 329/*- macro make_unmarshal_input_symbols(name, function, methods_len, input_parameters, allow_trailing_data) -*/ 330 /*# Validate the types of our arguments #*/ 331 /*? assert(isinstance(name, six.string_types)) ?*/ 332 /*? assert(isinstance(function, six.string_types)) ?*/ 333 /*? assert(isinstance(methods_len, six.integer_types)) ?*/ 334 /*? assert(isinstance(input_parameters, (list, tuple))) ?*/ 335 336 static int /*? function ?*/(void * base, unsigned size 337 /*-- if len(input_parameters) > 0 --*/ 338 , 339 /*-- endif --*/ 340 /*? show_output_parameter_list(input_parameters, namespace_prefix="p_") -?*/ 341 ) { 342 343 unsigned offset = 0; 344 345 /*- if methods_len > 1 -*/ 346 /* Step over the method index. */ 347 offset += sizeof(/*? macros.type_to_fit_integer(methods_len) ?*/); 348 /*- endif -*/ 349 350 /*- for index, p in enumerate(input_parameters) -*/ 351 /*-- if loop.first -*/ 352 /* Unmarshal input parameters. */ 353 /*-- endif -*/ 354 /*?- assert(isinstance(p.type, six.string_types)) ?*/ 355 /*-- if p.array -*/ 356 /*-- if p.type == 'string' -*/ 357 offset = UNMARSHAL_STRING_ARRAY_PARAM(p_/*? p.name ?*/, p_/*? p.name ?*/_sz, base, size, offset, "/*? name ?*/", "/*? p.name ?*/", ({goto cleanup_/*? index ?*/;})); 358 /*-- else -*/ 359 offset = UNMARSHAL_ARRAY_PARAM(p_/*? p.name ?*/, p_/*? p.name ?*/_sz, base, size, offset, "/*? name ?*/", "/*? p.name ?*/", ({goto cleanup_/*? index ?*/;})); 360 /*-- endif -*/ 361 /*-- elif p.type == 'string' -*/ 362 offset = UNMARSHAL_STRING_PARAM(p_/*? p.name ?*/, base, size, offset, "/*? name ?*/", "/*? p.name ?*/", ({goto cleanup_/*? index ?*/;})); 363 /*-- else -*/ 364 offset = UNMARSHAL_PARAM(p_/*? p.name ?*/, base, size, offset, "/*? name ?*/", "/*? p.name ?*/", ({goto cleanup_/*? index ?*/;})); 365 /*-- endif -*/ 366 /*-- endfor -*/ 367 368 /*- if not allow_trailing_data -*/ 369 ERR_IF_MALFORMED_RPC_EXCESS_PAYLOAD(size, offset, "/*? name ?*/", ({ 370 goto cleanup_/*? len(input_parameters) ?*/; 371 })); 372 /*- endif -*/ 373 374 return 0; 375 /*-- for index, q in enumerate(input_parameters) | reverse -*/ 376cleanup_/*? index + 1 ?*/: 377 /*-- if q.array -*/ 378 /*-- if q.type == 'string' -*/ 379 for (int i = 0; i < * p_/*? q.name ?*/_sz; i ++) { 380 free((* p_/*? q.name ?*/)[i]); 381 } 382 /*-- endif -*/ 383 free(* p_/*? q.name ?*/); 384 /*-- elif q.type == 'string' -*/ 385 free(* p_/*? q.name ?*/); 386 /*-- endif -*/ 387 /*-- endfor -*/ 388cleanup_0: 389 return -1; 390 391 } 392/*- endmacro -*/ 393 394/*# Emits a call to the C symbol that will unmarshal output parameters 395 # function: Name of function to invoke 396 # buffer: Buffer symbol (or expression) to marshal into 397 # size: Name of a variable storing the byte length of the message 398 # input_parameters: All input parameters to this method 399 #*/ 400/*- macro call_unmarshal_input(function, buffer, size, input_parameters, namespace_prefix='') -*/ 401 /*#- Validate our arguments are the expected type #*/ 402 /*?- assert(isinstance(function, six.string_types)) ?*/ 403 /*?- assert(isinstance(buffer, six.string_types)) ?*/ 404 /*?- assert(isinstance(size, (six.string_types,six.integer_types))) ?*/ 405 /*?- assert(isinstance(input_parameters, (list, tuple))) ?*/ 406 407 /*?- function ?*/(/*? buffer ?*/, /*? size ?*/ 408 /*-- for p in input_parameters -*/, 409 /*-- if p.array --*/ 410 /*? namespace_prefix ?*//*? p.name ?*/_sz_ptr, 411 /*-- endif --*/ 412 /*? namespace_prefix ?*//*? p.name ?*/_ptr 413 /*-- endfor --*/ 414 ) 415/*- endmacro -*/ 416 417/*# Generates code for marshalling out parameters to an RPC invocation 418 # name: Name of this method 419 # function: Name of function to create 420 # output_parameters: All output parameters to this method 421 # return_type: Return type of this interface 422 #*/ 423/*- macro make_marshal_output_symbols(name, function, output_parameters, return_type) -*/ 424 /*# Validate our arguments are the correct type #*/ 425 /*? assert(isinstance(name, six.string_types)) ?*/ 426 /*? assert(isinstance(function, six.string_types)) ?*/ 427 /*? assert(isinstance(output_parameters, (list, tuple))) ?*/ 428 /*? assert(return_type is none or isinstance(return_type, six.string_types)) ?*/ 429 430 static unsigned /*? function ?*/(void * base, unsigned size 431 /*-- if return_type is not none -*/, 432 /*-- if return_type == 'string' --*/ 433 char ** return_var 434 /*-- else --*/ 435 const /*? macros.show_type(return_type) ?*/ * return_var 436 /*-- endif -*/ 437 /*-- endif -*/ 438 /*-- if len(output_parameters) > 0 --*/ 439 , 440 /*-- endif -*/ 441 /*?- show_input_parameter_list(output_parameters, ['out', 'inout'], namespace_prefix="p_") ?*/ 442 ) { 443 444 unsigned offset = 0; 445 446 /*- if return_type is not none -*/ 447 /* Marshal the return value. */ 448 /*- if return_type == 'string' -*/ 449 offset = MARSHAL_STRING_PARAM(* return_var, base, size, offset, "/*? name ?*/", "return value"); 450 /*- else -*/ 451 offset = MARSHAL_PARAM(return_var, base, size, offset, "/*? name ?*/", "return value"); 452 /*- endif -*/ 453 /*- endif -*/ 454 455 /*-- for p in output_parameters -*/ 456 /*-- if loop.first -*/ 457 /* Marshal output parameters. */ 458 /*-- endif -*/ 459 /*?- assert(isinstance(p.type, six.string_types)) ?*/ 460 /*-- if p.array -*/ 461 /*-- if p.type == 'string' -*/ 462 offset = MARSHAL_STRING_ARRAY_PARAM((* p_/*? p.name ?*/), p_/*? p.name ?*/_sz, base, size, offset, "/*? name ?*/", "/*? p.name ?*/"); 463 /*-- else -*/ 464 offset = MARSHAL_ARRAY_PARAM((* p_/*? p.name ?*/), p_/*? p.name ?*/_sz, base, size, offset, "/*? name ?*/", "/*? p.name ?*/"); 465 /*-- endif -*/ 466 /*-- elif p.type == 'string' -*/ 467 offset = MARSHAL_STRING_PARAM(* p_/*? p.name ?*/, base, size, offset, "/*? name ?*/", "/*? p.name ?*/"); 468 /*-- else -*/ 469 offset = MARSHAL_PARAM(p_/*? p.name ?*/, base, size, offset, "/*? name ?*/", "/*? p.name ?*/"); 470 /*-- endif -*/ 471 /*- endfor -*/ 472 473 assert(offset <= size && 474 "uncaught buffer overflow while marshalling outputs for /*? name ?*/"); 475 476 return offset; 477 } 478/*- endmacro -*/ 479 480/*# Emits a call to the C symbol that will unmarshal output parameters 481 # function: Name of function to invoke 482 # buffer: Buffer symbol (or expression) to marshal into 483 # size: Length of the buffer; possibly not generation-time constant 484 # output_parameters: All output parameters to this method 485 # return_type: Return type of this interface 486 # ret_ptr: Pointer for the return value 487 #*/ 488/*- macro call_marshal_output(function, buffer, size, output_parameters, return_type, ret_ptr, namespace_prefix='') -*/ 489 /*#- Validate our arguments are the correct type #*/ 490 /*?- assert(isinstance(function, six.string_types)) ?*/ 491 /*?- assert(isinstance(buffer, six.string_types)) ?*/ 492 /*?- assert(isinstance(size, (six.string_types,six.integer_types))) ?*/ 493 /*?- assert(isinstance(output_parameters, (list, tuple))) ?*/ 494 /*?- assert(return_type is none or isinstance(return_type, six.string_types)) ?*/ 495 496 /*?- function ?*/(/*? buffer ?*/, /*? size ?*/ 497 /*-- if return_type is not none -*/, 498 /*?- assert(isinstance(ret_ptr, six.string_types)) ?*/ 499 /*?- ret_ptr ?*/ 500 /*-- endif -*/ 501 /*-- for p in output_parameters -*/, 502 /*-- if p.array -*/ 503 /*?- namespace_prefix ?*//*? p.name ?*/_sz_ptr, 504 /*-- endif -*/ 505 /*?- namespace_prefix ?*//*? p.name ?*/_ptr 506 /*-- endfor --*/ 507 ) 508/*- endmacro -*/ 509