+#include <Python.h>\r
+#include <Decompress.h>\r
+\r
+/*\r
+ UefiDecompress(data_buffer, size, original_size)\r
+*/\r
+STATIC\r
+PyObject*\r
+UefiDecompress(\r
+ PyObject *Self,\r
+ PyObject *Args,\r
+ PyObject *Keywords\r
+ ) \r
+{\r
+ PyTypeObject *SrcData;\r
+ UINT32 SrcDataSize;\r
+ UINT32 DstDataSize;\r
+ UINT Status;\r
+ UINT8 *SrcBuf;\r
+ UINT8 *DstBuf;\r
+ UINT8 *TmpBuf;\r
+ Py_ssize_t SegNum;\r
+ Py_ssize_t Index;\r
+\r
+ Status = PyArg_ParseTupleAndKeywords(\r
+ Args,\r
+ Keywords,\r
+ "0ii",\r
+ &SrcData,\r
+ &SrcDataSize,\r
+ &DstDataSize\r
+ );\r
+ if (Status == 0) {\r
+ return NULL;\r
+ }\r
+\r
+ if (SrcData->tp_as_buffer == NULL\r
+ || SrcData->tp_as_buffer->bf_getreadbuffer == NULL\r
+ || SrcData->tp_as_buffer->bf_getsegcount == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ // Because some Python objects which support "buffer" protocol have more than one\r
+ // memory segment, we have to copy them into a contiguous memory.\r
+ SrcBuf = malloc(SrcDataSize);\r
+ DstBuf = malloc(DstDataSize);\r
+ if (SrcBuf == NULL || DstBuf == NULL) {\r
+ goto ERROR;\r
+ }\r
+\r
+ SegNum = SrcData->tp_as_buffer->bf_getsegcount(SrcData, NULL);\r
+ TmpBuf = SrcBuf\r
+ for (Index = 0; Index < SegNum; ++Index) {\r
+ VOID *BufSeg;\r
+ Py_ssize_t Len;\r
+\r
+ Len = SrcData->tp_as_buffer->bf_getreadbuffer(SrcData, Index, &BufSeg);\r
+ if (Len < 0) {\r
+ goto ERROR;\r
+ }\r
+ memcpy(TmpBuf, BufSeg, Len);\r
+ TmpBuf += Len;\r
+ }\r
+\r
+ Status = Extract((VOID *)SrcBuf, SrcDataSize, (VOID *)DstBuf, DstDataSize, 1);\r
+ if (Status != EFI_SUCCESS) {\r
+ goto ERROR;\r
+ }\r
+\r
+ return PyBuffer_FromMemory(DstBuf, (Py_ssize_t)DstDataSize);\r
+\r
+ERROR:\r
+ if (SrcBuf != NULL) {\r
+ free(SrcBuf);\r
+ }\r
+\r
+ if (DstBuf != NULL) {\r
+ free(DstBuf);\r
+ }\r
+ return NULL;\r
+}\r
+\r
+\r
+STATIC\r
+PyObject*\r
+FrameworkDecompress(\r
+ PyObject *Self,\r
+ PyObject *Args,\r
+ PyObject *Keywords\r
+ )\r
+{\r
+ PyTypeObject *SrcData;\r
+ UINT32 SrcDataSize;\r
+ UINT32 DstDataSize;\r
+ UINT Status;\r
+ UINT8 *SrcBuf;\r
+ UINT8 *DstBuf;\r
+ UINT8 *TmpBuf;\r
+ Py_ssize_t SegNum;\r
+ Py_ssize_t Index;\r
+\r
+ Status = PyArg_ParseTupleAndKeywords(\r
+ Args,\r
+ Keywords,\r
+ "0ii",\r
+ &SrcData,\r
+ &SrcDataSize,\r
+ &DstDataSize\r
+ );\r
+ if (Status == 0) {\r
+ return NULL;\r
+ }\r
+\r
+ if (SrcData->tp_as_buffer == NULL\r
+ || SrcData->tp_as_buffer->bf_getreadbuffer == NULL\r
+ || SrcData->tp_as_buffer->bf_getsegcount == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ // Because some Python objects which support "buffer" protocol have more than one\r
+ // memory segment, we have to copy them into a contiguous memory.\r
+ SrcBuf = malloc(SrcDataSize);\r
+ DstBuf = malloc(DstDataSize);\r
+ if (SrcBuf == NULL || DstBuf == NULL) {\r
+ goto ERROR;\r
+ }\r
+\r
+ SegNum = SrcData->tp_as_buffer->bf_getsegcount(SrcData, NULL);\r
+ TmpBuf = SrcBuf\r
+ for (Index = 0; Index < SegNum; ++Index) {\r
+ VOID *BufSeg;\r
+ Py_ssize_t Len;\r
+\r
+ Len = SrcData->tp_as_buffer->bf_getreadbuffer(SrcData, Index, &BufSeg);\r
+ if (Len < 0) {\r
+ goto ERROR;\r
+ }\r
+ memcpy(TmpBuf, BufSeg, Len);\r
+ TmpBuf += Len;\r
+ }\r
+\r
+ Status = Extract((VOID *)SrcBuf, SrcDataSize, (VOID *)DstBuf, DstDataSize, 2);\r
+ if (Status != EFI_SUCCESS) {\r
+ goto ERROR;\r
+ }\r
+\r
+ return PyBuffer_FromMemory(DstBuf, (Py_ssize_t)DstDataSize);\r
+\r
+ERROR:\r
+ if (SrcBuf != NULL) {\r
+ free(SrcBuf);\r
+ }\r
+\r
+ if (DstBuf != NULL) {\r
+ free(DstBuf);\r
+ }\r
+ return NULL;\r
+}\r
+\r
+STATIC\r
+PyObject*\r
+UefiCompress(\r
+ PyObject *Self,\r
+ PyObject *Args,\r
+ PyObject *Keywords\r
+ ) \r
+{\r
+ return NULL;\r
+}\r
+\r
+\r
+STATIC\r
+PyObject*\r
+FrameworkCompress(\r
+ PyObject *Self,\r
+ PyObject *Args,\r
+ PyObject *Keywords\r
+ )\r
+{\r
+ return NULL;\r
+}\r
+\r
+STATIC CHAR DecompressDocs[] = "Decompress(): Decompress data using UEFI standard algorithm\n";\r
+STATIC CHAR CompressDocs[] = "Compress(): Compress data using UEFI standard algorithm\n";\r
+\r
+STATIC PyMethodDef EfiCompressor_Funcs[] = {\r
+ {"UefiDecompress", (PyCFunction)UefiDecompress, METH_KEYWORDS, DecompressDocs},\r
+ {"UefiCompress", (PyCFunction)UefiCompress, METH_KEYWORDS, DecompressDocs},\r
+ {"FrameworkDecompress", (PyCFunction)FrameworkDecompress, METH_KEYWORDS, DecompressDocs},\r
+ {"FrameworkCompress", (PyCFunction)FrameworkCompress, METH_KEYWORDS, DecompressDocs},\r
+ {NULL, NULL, 0, NULL}\r
+};\r
+\r
+PyMODINIT_FUNC\r
+InitEfiCompressor(VOID) {\r
+ Py_InitModule3("EfiCompressor", EfiCompressor_Funcs, "EFI Compression Algorithm Extension Module");\r
+}\r
+\r
+\r