PageRenderTime 62ms CodeModel.GetById 36ms RepoModel.GetById 0ms app.codeStats 0ms

/Wrapping/PythonCore/PyVTKExtras.cxx

http://github.com/Kitware/VTK
C++ | 154 lines | 105 code | 15 blank | 34 comment | 26 complexity | a81bfb433715ebd7a7a41121c438dd71 MD5 | raw file
Possible License(s): JSON, BSD-3-Clause, LGPL-2.0, LGPL-3.0, GPL-2.0, Apache-2.0
  1. /*=========================================================================
  2. Program: Visualization Toolkit
  3. Module: PyVTKExtras.cxx
  4. Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  5. All rights reserved.
  6. See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
  7. This software is distributed WITHOUT ANY WARRANTY; without even
  8. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  9. PURPOSE. See the above copyright notice for more information.
  10. =========================================================================*/
  11. #include "PyVTKExtras.h"
  12. #include "PyVTKReference.h"
  13. #include "vtkPythonCompatibility.h"
  14. // Silence warning like
  15. // "dereferencing type-punned pointer will break strict-aliasing rules"
  16. // it happens because this kind of expression: (long *)&ptr
  17. #if defined(__GNUC__)
  18. #pragma GCC diagnostic ignored "-Wstrict-aliasing"
  19. #endif
  20. //------------------------------------------------------------------------------
  21. // Helper function for the buffer_shared() check: get the pointer and
  22. // size (in bytes) of the buffer of the provided object. A return
  23. // value of zero indicates that an exception was raised.
  24. static void* buffer_pointer_and_size(PyObject* o, Py_ssize_t* size)
  25. {
  26. void* ptr = nullptr;
  27. #if PY_VERSION_HEX >= 0x02060000
  28. // New buffer protocol
  29. Py_buffer view = VTK_PYBUFFER_INITIALIZER;
  30. if (PyObject_CheckBuffer(o))
  31. {
  32. // Check for a simple buffer
  33. if (PyObject_GetBuffer(o, &view, PyBUF_SIMPLE) == -1)
  34. {
  35. // Check for a C or Fortran contiguous buffer
  36. PyErr_Clear();
  37. if (PyObject_GetBuffer(o, &view, PyBUF_STRIDES) == -1)
  38. {
  39. return nullptr;
  40. }
  41. }
  42. ptr = view.buf;
  43. *size = view.len;
  44. PyBuffer_Release(&view);
  45. if (ptr)
  46. {
  47. return ptr;
  48. }
  49. }
  50. #endif
  51. #ifndef VTK_PY3K
  52. // Old buffer protocol
  53. PyBufferProcs* b = Py_TYPE(o)->tp_as_buffer;
  54. if (b && b->bf_getreadbuffer && b->bf_getsegcount)
  55. {
  56. if (b->bf_getsegcount(o, nullptr) == 1)
  57. {
  58. *size = b->bf_getreadbuffer(o, 0, &ptr);
  59. if (ptr)
  60. {
  61. return ptr;
  62. }
  63. }
  64. else
  65. {
  66. PyErr_SetString(PyExc_TypeError, "buffer must be single-segment");
  67. return nullptr;
  68. }
  69. }
  70. #endif
  71. PyErr_SetString(PyExc_TypeError, "object does not have a readable buffer");
  72. return nullptr;
  73. }
  74. //------------------------------------------------------------------------------
  75. static PyObject* PyVTKExtras_buffer_shared(PyObject*, PyObject* args)
  76. {
  77. PyObject* ob[2] = { nullptr, nullptr };
  78. if (PyArg_UnpackTuple(args, "buffer_shared", 2, 2, &ob[0], &ob[1]))
  79. {
  80. void* ptr[2] = { nullptr, nullptr };
  81. Py_ssize_t size[2] = { 0, 0 };
  82. for (int i = 0; i < 2; i++)
  83. {
  84. ptr[i] = buffer_pointer_and_size(ob[i], &size[i]);
  85. if (!ptr[i])
  86. {
  87. break;
  88. }
  89. }
  90. // check if the pointers and memory size are equal
  91. if (ptr[0] && ptr[1])
  92. {
  93. if (ptr[0] == ptr[1] && size[0] == size[1])
  94. {
  95. Py_RETURN_TRUE;
  96. }
  97. else
  98. {
  99. Py_RETURN_FALSE;
  100. }
  101. }
  102. }
  103. return nullptr;
  104. }
  105. //------------------------------------------------------------------------------
  106. static PyMethodDef PyVTKExtras_Methods[] = {
  107. { "buffer_shared", PyVTKExtras_buffer_shared, METH_VARARGS,
  108. "Check if two objects share the same buffer, meaning that they"
  109. " point to the same block of memory. An TypeError exception will"
  110. " be raised if either of the objects does not provide a buffer." },
  111. { nullptr, nullptr, 0, nullptr }
  112. };
  113. //------------------------------------------------------------------------------
  114. // Exported method called by vtkCommonCorePythonInit
  115. void PyVTKAddFile_PyVTKExtras(PyObject* dict)
  116. {
  117. // It is necessary to call PyType_Ready() on all subclasses
  118. PyType_Ready(&PyVTKNumberReference_Type);
  119. PyType_Ready(&PyVTKStringReference_Type);
  120. PyType_Ready(&PyVTKTupleReference_Type);
  121. // Add the "mutable" object (used for C++ pass-by-reference)
  122. PyObject* o = (PyObject*)&PyVTKReference_Type;
  123. PyDict_SetItemString(dict, "reference", o); // new name (as of VTK 8.1)
  124. PyDict_SetItemString(dict, "mutable", o); // old name
  125. for (PyMethodDef* meth = PyVTKExtras_Methods; meth->ml_name != nullptr; meth++)
  126. {
  127. // Third argument would be the module object, but all we have is
  128. // the module's dict, and it's safe to set it to nullptr.
  129. o = PyCFunction_NewEx(meth, nullptr, nullptr);
  130. if (o && PyDict_SetItemString(dict, meth->ml_name, o) != 0)
  131. {
  132. Py_DECREF(o);
  133. }
  134. }
  135. }