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