_chunkifier.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #include <Python/Python.h>
  2. #include <Python/structmember.h>
  3. typedef struct {
  4. PyObject_HEAD
  5. long int m;
  6. long int i;
  7. long int chunk_size;
  8. unsigned long int sum;
  9. PyObject *data;
  10. PyObject *fd;
  11. PyObject *chunks;
  12. } ChunkifyIter;
  13. PyObject* ChunkifyIter_iter(PyObject *self)
  14. {
  15. Py_INCREF(self);
  16. return self;
  17. }
  18. PyObject* ChunkifyIter_iternext(PyObject *self)
  19. {
  20. ChunkifyIter *p = (ChunkifyIter *)self;
  21. if (p->i < p->m) {
  22. PyObject *tmp = Py_BuildValue("l", p->i);
  23. (p->i)++;
  24. return tmp;
  25. } else {
  26. /* Raising of standard StopIteration exception with empty value. */
  27. PyErr_SetNone(PyExc_StopIteration);
  28. return NULL;
  29. }
  30. }
  31. static PyTypeObject ChunkifyIterType = {
  32. PyObject_HEAD_INIT(NULL)
  33. 0, /*ob_size*/
  34. "_chunkifier._ChunkifyIter", /*tp_name*/
  35. sizeof(ChunkifyIter), /*tp_basicsize*/
  36. 0, /*tp_itemsize*/
  37. 0, /*tp_dealloc*/
  38. 0, /*tp_print*/
  39. 0, /*tp_getattr*/
  40. 0, /*tp_setattr*/
  41. 0, /*tp_compare*/
  42. 0, /*tp_repr*/
  43. 0, /*tp_as_number*/
  44. 0, /*tp_as_sequence*/
  45. 0, /*tp_as_mapping*/
  46. 0, /*tp_hash */
  47. 0, /*tp_call*/
  48. 0, /*tp_str*/
  49. 0, /*tp_getattro*/
  50. 0, /*tp_setattro*/
  51. 0, /*tp_as_buffer*/
  52. Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,
  53. /* tp_flags: Py_TPFLAGS_HAVE_ITER tells python to
  54. use tp_iter and tp_iternext fields. */
  55. "", /* tp_doc */
  56. 0, /* tp_traverse */
  57. 0, /* tp_clear */
  58. 0, /* tp_richcompare */
  59. 0, /* tp_weaklistoffset */
  60. ChunkifyIter_iter, /* tp_iter: __iter__() method */
  61. ChunkifyIter_iternext /* tp_iternext: next() method */
  62. };
  63. static PyObject *
  64. chunkify(PyObject *self, PyObject *args)
  65. {
  66. PyObject *fd;
  67. PyObject *chunks;
  68. long int chunk_size;
  69. ChunkifyIter *p;
  70. if (!PyArg_ParseTuple(args, "OlO", &fd, &chunk_size, &chunks)) return NULL;
  71. /* I don't need python callable __init__() method for this iterator,
  72. so I'll simply allocate it as PyObject and initialize it by hand. */
  73. p = PyObject_New(ChunkifyIter, &ChunkifyIterType);
  74. if (!p) return NULL;
  75. /* I'm not sure if it's strictly necessary. */
  76. if (!PyObject_Init((PyObject *)p, &ChunkifyIterType)) {
  77. Py_DECREF(p);
  78. return NULL;
  79. }
  80. p->m = 10;
  81. p->i = 0;
  82. p->fd = fd;
  83. p->chunk_size = chunk_size;
  84. p->chunks = chunks;
  85. return (PyObject *)p;
  86. }
  87. static PyMethodDef ChunkifierMethods[] = {
  88. {"chunkify", chunkify, METH_VARARGS, ""},
  89. {NULL, NULL, 0, NULL} /* Sentinel */
  90. };
  91. PyMODINIT_FUNC
  92. init_chunkifier(void)
  93. {
  94. PyObject* m;
  95. ChunkifyIterType.tp_new = PyType_GenericNew;
  96. if (PyType_Ready(&ChunkifyIterType) < 0) return;
  97. m = Py_InitModule("_chunkifier", ChunkifierMethods);
  98. Py_INCREF(&ChunkifyIterType);
  99. PyModule_AddObject(m, "_ChunkifyIter", (PyObject *)&ChunkifyIterType);
  100. }