]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/PyEfiCompressor/EfiCompressor.c
BaseTools: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / BaseTools / Source / C / PyEfiCompressor / EfiCompressor.c
CommitLineData
52302d4d 1/** @file\r
97fa0ee9 2Efi Compressor\r
52302d4d 3\r
f7496d71 4Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
2e351cbe 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
52302d4d
LG
6\r
7**/\r
8\r
30fdf114
LG
9#include <Python.h>\r
10#include <Decompress.h>\r
11\r
12/*\r
13 UefiDecompress(data_buffer, size, original_size)\r
14*/\r
15STATIC\r
16PyObject*\r
17UefiDecompress(\r
18 PyObject *Self,\r
19 PyObject *Args\r
20 )\r
21{\r
22 PyObject *SrcData;\r
23 UINT32 SrcDataSize;\r
24 UINT32 DstDataSize;\r
25 UINTN Status;\r
26 UINT8 *SrcBuf;\r
27 UINT8 *DstBuf;\r
28 UINT8 *TmpBuf;\r
29 Py_ssize_t SegNum;\r
30 Py_ssize_t Index;\r
31\r
32 Status = PyArg_ParseTuple(\r
33 Args,\r
34 "Oi",\r
35 &SrcData,\r
36 &SrcDataSize\r
37 );\r
38 if (Status == 0) {\r
39 return NULL;\r
40 }\r
41\r
42 if (SrcData->ob_type->tp_as_buffer == NULL\r
43 || SrcData->ob_type->tp_as_buffer->bf_getreadbuffer == NULL\r
44 || SrcData->ob_type->tp_as_buffer->bf_getsegcount == NULL) {\r
45 PyErr_SetString(PyExc_Exception, "First argument is not a buffer\n");\r
46 return NULL;\r
47 }\r
48\r
49 // Because some Python objects which support "buffer" protocol have more than one\r
50 // memory segment, we have to copy them into a contiguous memory.\r
51 SrcBuf = PyMem_Malloc(SrcDataSize);\r
52 if (SrcBuf == NULL) {\r
53 PyErr_SetString(PyExc_Exception, "Not enough memory\n");\r
54 goto ERROR;\r
55 }\r
56\r
57 SegNum = SrcData->ob_type->tp_as_buffer->bf_getsegcount((PyObject *)SrcData, NULL);\r
58 TmpBuf = SrcBuf;\r
59 for (Index = 0; Index < SegNum; ++Index) {\r
60 VOID *BufSeg;\r
61 Py_ssize_t Len;\r
62\r
63 Len = SrcData->ob_type->tp_as_buffer->bf_getreadbuffer((PyObject *)SrcData, Index, &BufSeg);\r
64 if (Len < 0) {\r
65 PyErr_SetString(PyExc_Exception, "Buffer segment is not available\n");\r
66 goto ERROR;\r
67 }\r
68 memcpy(TmpBuf, BufSeg, Len);\r
69 TmpBuf += Len;\r
70 }\r
71\r
72 Status = Extract((VOID *)SrcBuf, SrcDataSize, (VOID **)&DstBuf, &DstDataSize, 1);\r
73 if (Status != EFI_SUCCESS) {\r
74 PyErr_SetString(PyExc_Exception, "Failed to decompress\n");\r
75 goto ERROR;\r
76 }\r
77\r
78 return PyBuffer_FromMemory(DstBuf, (Py_ssize_t)DstDataSize);\r
79\r
80ERROR:\r
81 if (SrcBuf != NULL) {\r
82 free(SrcBuf);\r
83 }\r
84\r
85 if (DstBuf != NULL) {\r
86 free(DstBuf);\r
87 }\r
88 return NULL;\r
89}\r
90\r
91\r
92STATIC\r
93PyObject*\r
94FrameworkDecompress(\r
95 PyObject *Self,\r
96 PyObject *Args\r
97 )\r
98{\r
99 PyObject *SrcData;\r
100 UINT32 SrcDataSize;\r
101 UINT32 DstDataSize;\r
102 UINTN Status;\r
103 UINT8 *SrcBuf;\r
104 UINT8 *DstBuf;\r
105 UINT8 *TmpBuf;\r
106 Py_ssize_t SegNum;\r
107 Py_ssize_t Index;\r
108\r
109 Status = PyArg_ParseTuple(\r
110 Args,\r
111 "Oi",\r
112 &SrcData,\r
113 &SrcDataSize\r
114 );\r
115 if (Status == 0) {\r
116 return NULL;\r
117 }\r
118\r
119 if (SrcData->ob_type->tp_as_buffer == NULL\r
120 || SrcData->ob_type->tp_as_buffer->bf_getreadbuffer == NULL\r
121 || SrcData->ob_type->tp_as_buffer->bf_getsegcount == NULL) {\r
122 PyErr_SetString(PyExc_Exception, "First argument is not a buffer\n");\r
123 return NULL;\r
124 }\r
125\r
126 // Because some Python objects which support "buffer" protocol have more than one\r
127 // memory segment, we have to copy them into a contiguous memory.\r
128 SrcBuf = PyMem_Malloc(SrcDataSize);\r
129 if (SrcBuf == NULL) {\r
130 PyErr_SetString(PyExc_Exception, "Not enough memory\n");\r
131 goto ERROR;\r
132 }\r
133\r
134 SegNum = SrcData->ob_type->tp_as_buffer->bf_getsegcount((PyObject *)SrcData, NULL);\r
135 TmpBuf = SrcBuf;\r
136 for (Index = 0; Index < SegNum; ++Index) {\r
137 VOID *BufSeg;\r
138 Py_ssize_t Len;\r
139\r
140 Len = SrcData->ob_type->tp_as_buffer->bf_getreadbuffer((PyObject *)SrcData, Index, &BufSeg);\r
141 if (Len < 0) {\r
142 PyErr_SetString(PyExc_Exception, "Buffer segment is not available\n");\r
143 goto ERROR;\r
144 }\r
145 memcpy(TmpBuf, BufSeg, Len);\r
146 TmpBuf += Len;\r
147 }\r
148\r
149 Status = Extract((VOID *)SrcBuf, SrcDataSize, (VOID **)&DstBuf, &DstDataSize, 2);\r
150 if (Status != EFI_SUCCESS) {\r
151 PyErr_SetString(PyExc_Exception, "Failed to decompress\n");\r
152 goto ERROR;\r
153 }\r
154\r
155 return PyString_FromStringAndSize((CONST INT8*)DstBuf, (Py_ssize_t)DstDataSize);\r
156\r
157ERROR:\r
158 if (SrcBuf != NULL) {\r
159 free(SrcBuf);\r
160 }\r
161\r
162 if (DstBuf != NULL) {\r
163 free(DstBuf);\r
164 }\r
165 return NULL;\r
166}\r
167\r
168\r
169STATIC\r
170PyObject*\r
171UefiCompress(\r
172 PyObject *Self,\r
173 PyObject *Args\r
174 )\r
175{\r
176 return NULL;\r
177}\r
178\r
179\r
180STATIC\r
181PyObject*\r
182FrameworkCompress(\r
183 PyObject *Self,\r
184 PyObject *Args\r
185 )\r
186{\r
187 return NULL;\r
188}\r
189\r
190STATIC INT8 DecompressDocs[] = "Decompress(): Decompress data using UEFI standard algorithm\n";\r
191STATIC INT8 CompressDocs[] = "Compress(): Compress data using UEFI standard algorithm\n";\r
192\r
193STATIC PyMethodDef EfiCompressor_Funcs[] = {\r
194 {"UefiDecompress", (PyCFunction)UefiDecompress, METH_VARARGS, DecompressDocs},\r
195 {"UefiCompress", (PyCFunction)UefiCompress, METH_VARARGS, DecompressDocs},\r
196 {"FrameworkDecompress", (PyCFunction)FrameworkDecompress, METH_VARARGS, DecompressDocs},\r
197 {"FrameworkCompress", (PyCFunction)FrameworkCompress, METH_VARARGS, DecompressDocs},\r
198 {NULL, NULL, 0, NULL}\r
199};\r
200\r
201PyMODINIT_FUNC\r
202initEfiCompressor(VOID) {\r
203 Py_InitModule3("EfiCompressor", EfiCompressor_Funcs, "EFI Compression Algorithm Extension Module");\r
204}\r
205\r
206\r