frameparams.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /**
  2. * Copyright (c) 2017-present, Gregory Szorc
  3. * All rights reserved.
  4. *
  5. * This software may be modified and distributed under the terms
  6. * of the BSD license. See the LICENSE file for details.
  7. */
  8. #include "python-zstandard.h"
  9. extern PyObject* ZstdError;
  10. PyDoc_STRVAR(FrameParameters__doc__,
  11. "FrameParameters: information about a zstd frame");
  12. FrameParametersObject* get_frame_parameters(PyObject* self, PyObject* args, PyObject* kwargs) {
  13. static char* kwlist[] = {
  14. "data",
  15. NULL
  16. };
  17. Py_buffer source;
  18. ZSTD_frameHeader header;
  19. FrameParametersObject* result = NULL;
  20. size_t zresult;
  21. #if PY_MAJOR_VERSION >= 3
  22. if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*:get_frame_parameters",
  23. #else
  24. if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s*:get_frame_parameters",
  25. #endif
  26. kwlist, &source)) {
  27. return NULL;
  28. }
  29. if (!PyBuffer_IsContiguous(&source, 'C') || source.ndim > 1) {
  30. PyErr_SetString(PyExc_ValueError,
  31. "data buffer should be contiguous and have at most one dimension");
  32. goto finally;
  33. }
  34. zresult = ZSTD_getFrameHeader(&header, source.buf, source.len);
  35. if (ZSTD_isError(zresult)) {
  36. PyErr_Format(ZstdError, "cannot get frame parameters: %s", ZSTD_getErrorName(zresult));
  37. goto finally;
  38. }
  39. if (zresult) {
  40. PyErr_Format(ZstdError, "not enough data for frame parameters; need %zu bytes", zresult);
  41. goto finally;
  42. }
  43. result = PyObject_New(FrameParametersObject, &FrameParametersType);
  44. if (!result) {
  45. goto finally;
  46. }
  47. result->frameContentSize = header.frameContentSize;
  48. result->windowSize = header.windowSize;
  49. result->dictID = header.dictID;
  50. result->checksumFlag = header.checksumFlag ? 1 : 0;
  51. finally:
  52. PyBuffer_Release(&source);
  53. return result;
  54. }
  55. static void FrameParameters_dealloc(PyObject* self) {
  56. PyObject_Del(self);
  57. }
  58. static PyMemberDef FrameParameters_members[] = {
  59. { "content_size", T_ULONGLONG,
  60. offsetof(FrameParametersObject, frameContentSize), READONLY,
  61. "frame content size" },
  62. { "window_size", T_ULONGLONG,
  63. offsetof(FrameParametersObject, windowSize), READONLY,
  64. "window size" },
  65. { "dict_id", T_UINT,
  66. offsetof(FrameParametersObject, dictID), READONLY,
  67. "dictionary ID" },
  68. { "has_checksum", T_BOOL,
  69. offsetof(FrameParametersObject, checksumFlag), READONLY,
  70. "checksum flag" },
  71. { NULL }
  72. };
  73. PyTypeObject FrameParametersType = {
  74. PyVarObject_HEAD_INIT(NULL, 0)
  75. "FrameParameters", /* tp_name */
  76. sizeof(FrameParametersObject), /* tp_basicsize */
  77. 0, /* tp_itemsize */
  78. (destructor)FrameParameters_dealloc, /* tp_dealloc */
  79. 0, /* tp_print */
  80. 0, /* tp_getattr */
  81. 0, /* tp_setattr */
  82. 0, /* tp_compare */
  83. 0, /* tp_repr */
  84. 0, /* tp_as_number */
  85. 0, /* tp_as_sequence */
  86. 0, /* tp_as_mapping */
  87. 0, /* tp_hash */
  88. 0, /* tp_call */
  89. 0, /* tp_str */
  90. 0, /* tp_getattro */
  91. 0, /* tp_setattro */
  92. 0, /* tp_as_buffer */
  93. Py_TPFLAGS_DEFAULT, /* tp_flags */
  94. FrameParameters__doc__, /* tp_doc */
  95. 0, /* tp_traverse */
  96. 0, /* tp_clear */
  97. 0, /* tp_richcompare */
  98. 0, /* tp_weaklistoffset */
  99. 0, /* tp_iter */
  100. 0, /* tp_iternext */
  101. 0, /* tp_methods */
  102. FrameParameters_members, /* tp_members */
  103. 0, /* tp_getset */
  104. 0, /* tp_base */
  105. 0, /* tp_dict */
  106. 0, /* tp_descr_get */
  107. 0, /* tp_descr_set */
  108. 0, /* tp_dictoffset */
  109. 0, /* tp_init */
  110. 0, /* tp_alloc */
  111. 0, /* tp_new */
  112. };
  113. void frameparams_module_init(PyObject* mod) {
  114. Py_TYPE(&FrameParametersType) = &PyType_Type;
  115. if (PyType_Ready(&FrameParametersType) < 0) {
  116. return;
  117. }
  118. Py_INCREF(&FrameParametersType);
  119. PyModule_AddObject(mod, "FrameParameters", (PyObject*)&FrameParametersType);
  120. }