Changed the interface parameters
[people/mcb30/basetools.git] / Source / C / PyEfiCompressor / EfiCompressor.c
1 #include <Python.h>\r
2 #include <Decompress.h>\r
3 \r
4 /*\r
5  UefiDecompress(data_buffer, size, original_size)\r
6 */\r
7 STATIC\r
8 PyObject*\r
9 UefiDecompress(\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
72 ERROR:\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
84 STATIC\r
85 PyObject*\r
86 FrameworkDecompress(\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
149 ERROR:\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
161 STATIC\r
162 PyObject*\r
163 UefiCompress(\r
164   PyObject    *Self,\r
165   PyObject    *Args\r
166   )\r
167 {\r
168   return NULL;\r
169 }\r
170 \r
171 \r
172 STATIC\r
173 PyObject*\r
174 FrameworkCompress(\r
175   PyObject    *Self,\r
176   PyObject    *Args\r
177   )\r
178 {\r
179   return NULL;\r
180 }\r
181 \r
182 STATIC INT8 DecompressDocs[] = "Decompress(): Decompress data using UEFI standard algorithm\n";\r
183 STATIC INT8 CompressDocs[] = "Compress(): Compress data using UEFI standard algorithm\n";\r
184 \r
185 STATIC 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
193 PyMODINIT_FUNC\r
194 initEfiCompressor(VOID) {\r
195   Py_InitModule3("EfiCompressor", EfiCompressor_Funcs, "EFI Compression Algorithm Extension Module");\r
196 }\r
197 \r
198 \r