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