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