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