1359575Sdim/* Typemap definitions, to allow SWIG to properly handle 'char**' data types. */
2359575Sdim
3359575Sdim%typemap(in) char ** {
4359575Sdim  /* Check if is a list  */
5359575Sdim  if (PythonList::Check($input)) {
6359575Sdim    PythonList list(PyRefType::Borrowed, $input);
7359575Sdim    int size = list.GetSize();
8359575Sdim    int i = 0;
9359575Sdim    $1 = (char**)malloc((size+1)*sizeof(char*));
10359575Sdim    for (i = 0; i < size; i++) {
11359575Sdim      PythonString py_str = list.GetItemAtIndex(i).AsType<PythonString>();
12359575Sdim      if (!py_str.IsAllocated()) {
13359575Sdim        PyErr_SetString(PyExc_TypeError,"list must contain strings");
14359575Sdim        free($1);
15359575Sdim        return nullptr;
16359575Sdim      }
17359575Sdim
18359575Sdim      $1[i] = const_cast<char*>(py_str.GetString().data());
19359575Sdim    }
20359575Sdim    $1[i] = 0;
21359575Sdim  } else if ($input == Py_None) {
22359575Sdim    $1 =  NULL;
23359575Sdim  } else {
24359575Sdim    PyErr_SetString(PyExc_TypeError,"not a list");
25359575Sdim    return NULL;
26359575Sdim  }
27359575Sdim}
28359575Sdim
29359575Sdim%typemap(typecheck) char ** {
30359575Sdim  /* Check if is a list  */
31359575Sdim  $1 = 1;
32359575Sdim  if (PythonList::Check($input)) {
33359575Sdim    PythonList list(PyRefType::Borrowed, $input);
34359575Sdim    int size = list.GetSize();
35359575Sdim    int i = 0;
36359575Sdim    for (i = 0; i < size; i++) {
37359575Sdim      PythonString s = list.GetItemAtIndex(i).AsType<PythonString>();
38359575Sdim      if (!s.IsAllocated()) { $1 = 0; }
39359575Sdim    }
40359575Sdim  }
41359575Sdim  else
42359575Sdim  {
43359575Sdim    $1 = ( ($input == Py_None) ? 1 : 0);
44359575Sdim  }
45359575Sdim}
46359575Sdim
47359575Sdim%typemap(freearg) char** {
48359575Sdim  free((char *) $1);
49359575Sdim}
50359575Sdim
51359575Sdim%typemap(out) char** {
52359575Sdim  int len;
53359575Sdim  int i;
54359575Sdim  len = 0;
55359575Sdim  while ($1[len]) len++;
56359575Sdim  PythonList list(len);
57359575Sdim  for (i = 0; i < len; i++)
58359575Sdim    list.SetItemAtIndex(i, PythonString($1[i]));
59359575Sdim  $result = list.release();
60359575Sdim}
61359575Sdim
62359575Sdim
63359575Sdim%typemap(in) lldb::tid_t {
64359575Sdim  if (PythonInteger::Check($input))
65359575Sdim  {
66359575Sdim    PythonInteger py_int(PyRefType::Borrowed, $input);
67359575Sdim    $1 = static_cast<lldb::tid_t>(py_int.GetInteger());
68359575Sdim  }
69359575Sdim  else
70359575Sdim  {
71359575Sdim    PyErr_SetString(PyExc_ValueError, "Expecting an integer");
72359575Sdim    return nullptr;
73359575Sdim  }
74359575Sdim}
75359575Sdim
76359575Sdim%typemap(in) lldb::StateType {
77359575Sdim  if (PythonInteger::Check($input))
78359575Sdim  {
79359575Sdim    PythonInteger py_int(PyRefType::Borrowed, $input);
80359575Sdim    int64_t state_type_value = py_int.GetInteger() ;
81359575Sdim
82359575Sdim    if (state_type_value > lldb::StateType::kLastStateType) {
83359575Sdim      PyErr_SetString(PyExc_ValueError, "Not a valid StateType value");
84359575Sdim      return nullptr;
85359575Sdim    }
86359575Sdim    $1 = static_cast<lldb::StateType>(state_type_value);
87359575Sdim  }
88359575Sdim  else
89359575Sdim  {
90359575Sdim    PyErr_SetString(PyExc_ValueError, "Expecting an integer");
91359575Sdim    return nullptr;
92359575Sdim  }
93359575Sdim}
94359575Sdim
95359575Sdim/* Typemap definitions to allow SWIG to properly handle char buffer. */
96359575Sdim
97359575Sdim// typemap for a char buffer
98359575Sdim%typemap(in) (char *dst, size_t dst_len) {
99359575Sdim   if (!PyInt_Check($input)) {
100359575Sdim       PyErr_SetString(PyExc_ValueError, "Expecting an integer");
101359575Sdim       return NULL;
102359575Sdim   }
103359575Sdim   $2 = PyInt_AsLong($input);
104359575Sdim   if ($2 <= 0) {
105359575Sdim       PyErr_SetString(PyExc_ValueError, "Positive integer expected");
106359575Sdim       return NULL;
107359575Sdim   }
108359575Sdim   $1 = (char *) malloc($2);
109359575Sdim}
110359575Sdim// SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated
111359575Sdim// as char data instead of byte data.
112359575Sdim%typemap(in) (void *char_buf, size_t size) = (char *dst, size_t dst_len);
113359575Sdim
114359575Sdim// Return the char buffer.  Discarding any previous return result
115359575Sdim%typemap(argout) (char *dst, size_t dst_len) {
116359575Sdim   Py_XDECREF($result);   /* Blow away any previous result */
117359575Sdim   if (result == 0) {
118359575Sdim      PythonString string("");
119359575Sdim      $result = string.release();
120359575Sdim      Py_INCREF($result);
121359575Sdim   } else {
122359575Sdim      llvm::StringRef ref(static_cast<const char*>($1), result);
123359575Sdim      PythonString string(ref);
124359575Sdim      $result = string.release();
125359575Sdim   }
126359575Sdim   free($1);
127359575Sdim}
128359575Sdim// SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated
129359575Sdim// as char data instead of byte data.
130359575Sdim%typemap(argout) (void *char_buf, size_t size) = (char *dst, size_t dst_len);
131359575Sdim
132359575Sdim
133359575Sdim// typemap for handling an snprintf-like API like SBThread::GetStopDescription.
134359575Sdim%typemap(in) (char *dst_or_null, size_t dst_len) {
135359575Sdim   if (!PyInt_Check($input)) {
136359575Sdim       PyErr_SetString(PyExc_ValueError, "Expecting an integer");
137359575Sdim       return NULL;
138359575Sdim   }
139359575Sdim   $2 = PyInt_AsLong($input);
140359575Sdim   if ($2 <= 0) {
141359575Sdim       PyErr_SetString(PyExc_ValueError, "Positive integer expected");
142359575Sdim       return NULL;
143359575Sdim   }
144359575Sdim   $1 = (char *) malloc($2);
145359575Sdim}
146359575Sdim%typemap(argout) (char *dst_or_null, size_t dst_len) {
147359575Sdim   Py_XDECREF($result);   /* Blow away any previous result */
148359575Sdim   llvm::StringRef ref($1);
149359575Sdim   PythonString string(ref);
150359575Sdim   $result = string.release();
151359575Sdim   free($1);
152359575Sdim}
153359575Sdim
154359575Sdim
155359575Sdim// typemap for an outgoing buffer
156359575Sdim// See also SBEvent::SBEvent(uint32_t event, const char *cstr, uint32_t cstr_len).
157359575Sdim// Ditto for SBProcess::PutSTDIN(const char *src, size_t src_len).
158359575Sdim%typemap(in) (const char *cstr, uint32_t cstr_len),
159359575Sdim             (const char *src, size_t src_len) {
160359575Sdim   if (PythonString::Check($input)) {
161359575Sdim      PythonString str(PyRefType::Borrowed, $input);
162359575Sdim      $1 = (char*)str.GetString().data();
163359575Sdim      $2 = str.GetSize();
164359575Sdim   }
165359575Sdim   else if(PythonByteArray::Check($input)) {
166359575Sdim      PythonByteArray bytearray(PyRefType::Borrowed, $input);
167359575Sdim      $1 = (char*)bytearray.GetBytes().data();
168359575Sdim      $2 = bytearray.GetSize();
169359575Sdim   }
170359575Sdim   else if (PythonBytes::Check($input)) {
171359575Sdim      PythonBytes bytes(PyRefType::Borrowed, $input);
172359575Sdim      $1 = (char*)bytes.GetBytes().data();
173359575Sdim      $2 = bytes.GetSize();
174359575Sdim   }
175359575Sdim   else {
176359575Sdim      PyErr_SetString(PyExc_ValueError, "Expecting a string");
177359575Sdim      return NULL;
178359575Sdim   }
179359575Sdim}
180359575Sdim// For SBProcess::WriteMemory, SBTarget::GetInstructions and SBDebugger::DispatchInput.
181359575Sdim%typemap(in) (const void *buf, size_t size),
182359575Sdim             (const void *data, size_t data_len) {
183359575Sdim   if (PythonString::Check($input)) {
184359575Sdim      PythonString str(PyRefType::Borrowed, $input);
185359575Sdim      $1 = (void*)str.GetString().data();
186359575Sdim      $2 = str.GetSize();
187359575Sdim   }
188359575Sdim   else if(PythonByteArray::Check($input)) {
189359575Sdim      PythonByteArray bytearray(PyRefType::Borrowed, $input);
190359575Sdim      $1 = (void*)bytearray.GetBytes().data();
191359575Sdim      $2 = bytearray.GetSize();
192359575Sdim   }
193359575Sdim   else if (PythonBytes::Check($input)) {
194359575Sdim      PythonBytes bytes(PyRefType::Borrowed, $input);
195359575Sdim      $1 = (void*)bytes.GetBytes().data();
196359575Sdim      $2 = bytes.GetSize();
197359575Sdim   }
198359575Sdim   else {
199359575Sdim      PyErr_SetString(PyExc_ValueError, "Expecting a buffer");
200359575Sdim      return NULL;
201359575Sdim   }
202359575Sdim}
203359575Sdim
204359575Sdim// typemap for an incoming buffer
205359575Sdim// See also SBProcess::ReadMemory.
206359575Sdim%typemap(in) (void *buf, size_t size) {
207359575Sdim   if (PyInt_Check($input)) {
208359575Sdim      $2 = PyInt_AsLong($input);
209359575Sdim   } else if (PyLong_Check($input)) {
210359575Sdim      $2 = PyLong_AsLong($input);
211359575Sdim   } else {
212359575Sdim      PyErr_SetString(PyExc_ValueError, "Expecting an integer or long object");
213359575Sdim      return NULL;
214359575Sdim   }
215359575Sdim   if ($2 <= 0) {
216359575Sdim       PyErr_SetString(PyExc_ValueError, "Positive integer expected");
217359575Sdim       return NULL;
218359575Sdim   }
219359575Sdim   $1 = (void *) malloc($2);
220359575Sdim}
221359575Sdim
222359575Sdim// Return the buffer.  Discarding any previous return result
223359575Sdim// See also SBProcess::ReadMemory.
224359575Sdim%typemap(argout) (void *buf, size_t size) {
225359575Sdim   Py_XDECREF($result);   /* Blow away any previous result */
226359575Sdim   if (result == 0) {
227359575Sdim      $result = Py_None;
228359575Sdim      Py_INCREF($result);
229359575Sdim   } else {
230359575Sdim      PythonBytes bytes(static_cast<const uint8_t*>($1), result);
231359575Sdim      $result = bytes.release();
232359575Sdim   }
233359575Sdim   free($1);
234359575Sdim}
235359575Sdim
236359575Sdim%{
237359575Sdimnamespace {
238359575Sdimtemplate <class T>
239359575SdimT PyLongAsT(PyObject *obj) {
240359575Sdim  static_assert(true, "unsupported type");
241359575Sdim}
242359575Sdim
243359575Sdimtemplate <> uint64_t PyLongAsT<uint64_t>(PyObject *obj) {
244359575Sdim  return static_cast<uint64_t>(PyLong_AsUnsignedLongLong(obj));
245359575Sdim}
246359575Sdim
247359575Sdimtemplate <> uint32_t PyLongAsT<uint32_t>(PyObject *obj) {
248359575Sdim  return static_cast<uint32_t>(PyLong_AsUnsignedLong(obj));
249359575Sdim}
250359575Sdim
251359575Sdimtemplate <> int64_t PyLongAsT<int64_t>(PyObject *obj) {
252359575Sdim  return static_cast<int64_t>(PyLong_AsLongLong(obj));
253359575Sdim}
254359575Sdim
255359575Sdimtemplate <> int32_t PyLongAsT<int32_t>(PyObject *obj) {
256359575Sdim  return static_cast<int32_t>(PyLong_AsLong(obj));
257359575Sdim}
258359575Sdim
259359575Sdimtemplate <class T>
260359575Sdimbool SetNumberFromPyObject(T &number, PyObject *obj) {
261359575Sdim  if (PyInt_Check(obj))
262359575Sdim    number = static_cast<T>(PyInt_AsLong(obj));
263359575Sdim  else if (PyLong_Check(obj))
264359575Sdim    number = PyLongAsT<T>(obj);
265359575Sdim  else return false;
266359575Sdim
267359575Sdim  return true;
268359575Sdim}
269359575Sdim
270359575Sdimtemplate <>
271359575Sdimbool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
272359575Sdim  if (PyFloat_Check(obj)) {
273359575Sdim    number = PyFloat_AsDouble(obj);
274359575Sdim    return true;
275359575Sdim  }
276359575Sdim
277359575Sdim  return false;
278359575Sdim}
279359575Sdim
280359575Sdim} // namespace
281359575Sdim%}
282359575Sdim
283359575Sdim// these typemaps allow Python users to pass list objects
284359575Sdim// and have them turn into C++ arrays (this is useful, for instance
285359575Sdim// when creating SBData objects from lists of numbers)
286359575Sdim%typemap(in) (uint64_t* array, size_t array_len),
287359575Sdim             (uint32_t* array, size_t array_len),
288359575Sdim             (int64_t* array, size_t array_len),
289359575Sdim             (int32_t* array, size_t array_len),
290359575Sdim             (double* array, size_t array_len) {
291359575Sdim  /* Check if is a list  */
292359575Sdim  if (PyList_Check($input)) {
293359575Sdim    int size = PyList_Size($input);
294359575Sdim    int i = 0;
295359575Sdim    $2 = size;
296359575Sdim    $1 = ($1_type) malloc(size * sizeof($*1_type));
297359575Sdim    for (i = 0; i < size; i++) {
298359575Sdim      PyObject *o = PyList_GetItem($input,i);
299359575Sdim      if (!SetNumberFromPyObject($1[i], o)) {
300359575Sdim        PyErr_SetString(PyExc_TypeError,"list must contain numbers");
301359575Sdim        free($1);
302359575Sdim        return NULL;
303359575Sdim      }
304359575Sdim
305359575Sdim      if (PyErr_Occurred()) {
306359575Sdim        free($1);
307359575Sdim        return NULL;
308359575Sdim      }
309359575Sdim    }
310359575Sdim  } else if ($input == Py_None) {
311359575Sdim    $1 =  NULL;
312359575Sdim    $2 = 0;
313359575Sdim  } else {
314359575Sdim    PyErr_SetString(PyExc_TypeError,"not a list");
315359575Sdim    return NULL;
316359575Sdim  }
317359575Sdim}
318359575Sdim
319359575Sdim%typemap(freearg) (uint64_t* array, size_t array_len),
320359575Sdim                  (uint32_t* array, size_t array_len),
321359575Sdim                  (int64_t* array, size_t array_len),
322359575Sdim                  (int32_t* array, size_t array_len),
323359575Sdim                  (double* array, size_t array_len) {
324359575Sdim  free($1);
325359575Sdim}
326359575Sdim
327359575Sdim// these typemaps wrap SBModule::GetVersion() from requiring a memory buffer
328359575Sdim// to the more Pythonic style where a list is returned and no previous allocation
329359575Sdim// is necessary - this will break if more than 50 versions are ever returned
330359575Sdim%typemap(typecheck) (uint32_t *versions, uint32_t num_versions) {
331359575Sdim    $1 = ($input == Py_None ? 1 : 0);
332359575Sdim}
333359575Sdim
334359575Sdim%typemap(in, numinputs=0) (uint32_t *versions) {
335359575Sdim    $1 = (uint32_t*)malloc(sizeof(uint32_t) * 50);
336359575Sdim}
337359575Sdim
338359575Sdim%typemap(in, numinputs=0) (uint32_t num_versions) {
339359575Sdim    $1 = 50;
340359575Sdim}
341359575Sdim
342359575Sdim%typemap(argout) (uint32_t *versions, uint32_t num_versions) {
343359575Sdim    uint32_t count = result;
344359575Sdim    if (count >= $2)
345359575Sdim        count = $2;
346359575Sdim    PyObject* list = PyList_New(count);
347359575Sdim    for (uint32_t j = 0; j < count; j++)
348359575Sdim    {
349359575Sdim        PyObject* item = PyInt_FromLong($1[j]);
350359575Sdim        int ok = PyList_SetItem(list,j,item);
351359575Sdim        if (ok != 0)
352359575Sdim        {
353359575Sdim            $result = Py_None;
354359575Sdim            break;
355359575Sdim        }
356359575Sdim    }
357359575Sdim    $result = list;
358359575Sdim}
359359575Sdim
360359575Sdim%typemap(freearg) (uint32_t *versions) {
361359575Sdim    free($1);
362359575Sdim}
363359575Sdim
364359575Sdim
365359575Sdim// For Log::LogOutputCallback
366359575Sdim%typemap(in) (lldb::LogOutputCallback log_callback, void *baton) {
367359575Sdim  if (!($input == Py_None || PyCallable_Check(reinterpret_cast<PyObject*>($input)))) {
368359575Sdim    PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
369359575Sdim    return NULL;
370359575Sdim  }
371359575Sdim
372359575Sdim  // FIXME (filcab): We can't currently check if our callback is already
373359575Sdim  // LLDBSwigPythonCallPythonLogOutputCallback (to DECREF the previous
374359575Sdim  // baton) nor can we just remove all traces of a callback, if we want to
375359575Sdim  // revert to a file logging mechanism.
376359575Sdim
377359575Sdim  // Don't lose the callback reference
378359575Sdim  Py_INCREF($input);
379359575Sdim  $1 = LLDBSwigPythonCallPythonLogOutputCallback;
380359575Sdim  $2 = $input;
381359575Sdim}
382359575Sdim
383359575Sdim%typemap(typecheck) (lldb::LogOutputCallback log_callback, void *baton) {
384359575Sdim  $1 = $input == Py_None;
385359575Sdim  $1 = $1 || PyCallable_Check(reinterpret_cast<PyObject*>($input));
386359575Sdim}
387359575Sdim
388359575Sdim
389359575Sdim%typemap(in) lldb::FileSP {
390359575Sdim  PythonFile py_file(PyRefType::Borrowed, $input);
391359575Sdim  if (!py_file) {
392359575Sdim    PyErr_SetString(PyExc_TypeError, "not a file");
393359575Sdim    return nullptr;
394359575Sdim  }
395359575Sdim  auto sp = unwrapOrSetPythonException(py_file.ConvertToFile());
396359575Sdim  if (!sp)
397359575Sdim    return nullptr;
398359575Sdim  $1 = sp;
399359575Sdim}
400359575Sdim
401359575Sdim%typemap(in) lldb::FileSP FORCE_IO_METHODS {
402359575Sdim  PythonFile py_file(PyRefType::Borrowed, $input);
403359575Sdim  if (!py_file) {
404359575Sdim    PyErr_SetString(PyExc_TypeError, "not a file");
405359575Sdim    return nullptr;
406359575Sdim  }
407359575Sdim  auto sp = unwrapOrSetPythonException(py_file.ConvertToFileForcingUseOfScriptingIOMethods());
408359575Sdim  if (!sp)
409359575Sdim    return nullptr;
410359575Sdim  $1 = sp;
411359575Sdim}
412359575Sdim
413359575Sdim%typemap(in) lldb::FileSP BORROWED {
414359575Sdim  PythonFile py_file(PyRefType::Borrowed, $input);
415359575Sdim  if (!py_file) {
416359575Sdim    PyErr_SetString(PyExc_TypeError, "not a file");
417359575Sdim    return nullptr;
418359575Sdim  }
419359575Sdim  auto sp = unwrapOrSetPythonException(py_file.ConvertToFile(/*borrowed=*/true));
420359575Sdim  if (!sp)
421359575Sdim    return nullptr;
422359575Sdim  $1 = sp;
423359575Sdim}
424359575Sdim
425359575Sdim%typemap(in) lldb::FileSP BORROWED_FORCE_IO_METHODS {
426359575Sdim  PythonFile py_file(PyRefType::Borrowed, $input);
427359575Sdim  if (!py_file) {
428359575Sdim    PyErr_SetString(PyExc_TypeError, "not a file");
429359575Sdim    return nullptr;
430359575Sdim  }
431359575Sdim  auto sp = unwrapOrSetPythonException(py_file.ConvertToFileForcingUseOfScriptingIOMethods(/*borrowed=*/true));
432359575Sdim  if (!sp)
433359575Sdim    return nullptr;
434359575Sdim  $1 = sp;
435359575Sdim}
436359575Sdim
437359575Sdim%typecheck(SWIG_TYPECHECK_POINTER) lldb::FileSP {
438359575Sdim  if (PythonFile::Check($input)) {
439359575Sdim    $1 = 1;
440359575Sdim  } else {
441359575Sdim    PyErr_Clear();
442359575Sdim    $1 = 0;
443359575Sdim  }
444359575Sdim}
445359575Sdim
446359575Sdim%typemap(out) lldb::FileSP {
447359575Sdim  $result = nullptr;
448359575Sdim  lldb::FileSP &sp = $1;
449359575Sdim  if (sp) {
450359575Sdim    PythonFile pyfile = unwrapOrSetPythonException(PythonFile::FromFile(*sp));
451359575Sdim    if (!pyfile.IsValid())
452359575Sdim      return nullptr;
453359575Sdim    $result = pyfile.release();
454359575Sdim  }
455359575Sdim  if (!$result)
456359575Sdim  {
457359575Sdim      $result = Py_None;
458359575Sdim      Py_INCREF(Py_None);
459359575Sdim  }
460359575Sdim}
461359575Sdim
462359575Sdim%typemap(in) (const char* string, int len) {
463359575Sdim    if ($input == Py_None)
464359575Sdim    {
465359575Sdim        $1 = NULL;
466359575Sdim        $2 = 0;
467359575Sdim    }
468359575Sdim    else if (PythonString::Check($input))
469359575Sdim    {
470359575Sdim        PythonString py_str(PyRefType::Borrowed, $input);
471359575Sdim        llvm::StringRef str = py_str.GetString();
472359575Sdim        $1 = const_cast<char*>(str.data());
473359575Sdim        $2 = str.size();
474359575Sdim        // In Python 2, if $input is a PyUnicode object then this
475359575Sdim        // will trigger a Unicode -> String conversion, in which
476359575Sdim        // case the `PythonString` will now own the PyString.  Thus
477359575Sdim        // if it goes out of scope, the data will be deleted.  The
478359575Sdim        // only way to avoid this is to leak the Python object in
479359575Sdim        // that case.  Note that if there was no conversion, then
480359575Sdim        // releasing the string will not leak anything, since we
481359575Sdim        // created this as a borrowed reference.
482359575Sdim        py_str.release();
483359575Sdim    }
484359575Sdim    else
485359575Sdim    {
486359575Sdim        PyErr_SetString(PyExc_TypeError,"not a string-like object");
487359575Sdim        return NULL;
488359575Sdim    }
489359575Sdim}
490359575Sdim
491359575Sdim// These two pybuffer macros are copied out of swig/Lib/python/pybuffer.i,
492359575Sdim// and fixed so they will not crash if PyObject_GetBuffer fails.
493359575Sdim// https://github.com/swig/swig/issues/1640
494359575Sdim
495359575Sdim%define %pybuffer_mutable_binary(TYPEMAP, SIZE)
496359575Sdim%typemap(in) (TYPEMAP, SIZE) {
497359575Sdim  int res; Py_ssize_t size = 0; void *buf = 0;
498359575Sdim  Py_buffer view;
499359575Sdim  res = PyObject_GetBuffer($input, &view, PyBUF_WRITABLE);
500359575Sdim  if (res < 0) {
501359575Sdim    PyErr_Clear();
502359575Sdim    %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum);
503359575Sdim  }
504359575Sdim  size = view.len;
505359575Sdim  buf = view.buf;
506359575Sdim  PyBuffer_Release(&view);
507359575Sdim  $1 = ($1_ltype) buf;
508359575Sdim  $2 = ($2_ltype) (size/sizeof($*1_type));
509359575Sdim}
510359575Sdim%enddef
511359575Sdim
512359575Sdim%define %pybuffer_binary(TYPEMAP, SIZE)
513359575Sdim%typemap(in) (TYPEMAP, SIZE) {
514359575Sdim  int res; Py_ssize_t size = 0; const void *buf = 0;
515359575Sdim  Py_buffer view;
516359575Sdim  res = PyObject_GetBuffer($input, &view, PyBUF_CONTIG_RO);
517359575Sdim  if (res < 0) {
518359575Sdim    PyErr_Clear();
519359575Sdim    %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum);
520359575Sdim  }
521359575Sdim  size = view.len;
522359575Sdim  buf = view.buf;
523359575Sdim  PyBuffer_Release(&view);
524359575Sdim  $1 = ($1_ltype) buf;
525359575Sdim  $2 = ($2_ltype) (size / sizeof($*1_type));
526359575Sdim}
527359575Sdim%enddef
528359575Sdim
529359575Sdim%pybuffer_binary(const uint8_t *buf, size_t num_bytes);
530359575Sdim%pybuffer_mutable_binary(uint8_t *buf, size_t num_bytes);
531