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