39569e4f5c4f76bec0a51102ca13b391718f7cfd
[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   PyObject    *Keywords\r
13   ) \r
14 {\r
15   PyTypeObject  *SrcData;\r
16   UINT32        SrcDataSize;\r
17   UINT32        DstDataSize;\r
18   UINT          Status;\r
19   UINT8         *SrcBuf;\r
20   UINT8         *DstBuf;\r
21   UINT8         *TmpBuf;\r
22   Py_ssize_t    SegNum;\r
23   Py_ssize_t    Index;\r
24 \r
25   Status = PyArg_ParseTupleAndKeywords(\r
26             Args,\r
27             Keywords,\r
28             "0ii",\r
29             &SrcData,\r
30             &SrcDataSize,\r
31             &DstDataSize\r
32             );\r
33   if (Status == 0) {\r
34     return NULL;\r
35   }\r
36 \r
37   if (SrcData->tp_as_buffer == NULL\r
38       || SrcData->tp_as_buffer->bf_getreadbuffer == NULL\r
39       || SrcData->tp_as_buffer->bf_getsegcount == NULL) {\r
40     return NULL;\r
41   }\r
42 \r
43   // Because some Python objects which support "buffer" protocol have more than one\r
44   // memory segment, we have to copy them into a contiguous memory.\r
45   SrcBuf = malloc(SrcDataSize);\r
46   DstBuf = malloc(DstDataSize);\r
47   if (SrcBuf == NULL || DstBuf == NULL) {\r
48     goto ERROR;\r
49   }\r
50 \r
51   SegNum = SrcData->tp_as_buffer->bf_getsegcount(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->tp_as_buffer->bf_getreadbuffer(SrcData, Index, &BufSeg);\r
58     if (Len < 0) {\r
59       goto ERROR;\r
60     }\r
61     memcpy(TmpBuf, BufSeg, Len);\r
62     TmpBuf += Len;\r
63   }\r
64 \r
65   Status = Extract((VOID *)SrcBuf, SrcDataSize, (VOID *)DstBuf, DstDataSize, 1);\r
66   if (Status != EFI_SUCCESS) {\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   PyObject    *Keywords\r
90   )\r
91 {\r
92   PyTypeObject  *SrcData;\r
93   UINT32        SrcDataSize;\r
94   UINT32        DstDataSize;\r
95   UINT          Status;\r
96   UINT8         *SrcBuf;\r
97   UINT8         *DstBuf;\r
98   UINT8         *TmpBuf;\r
99   Py_ssize_t    SegNum;\r
100   Py_ssize_t    Index;\r
101 \r
102   Status = PyArg_ParseTupleAndKeywords(\r
103             Args,\r
104             Keywords,\r
105             "0ii",\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->tp_as_buffer == NULL\r
115       || SrcData->tp_as_buffer->bf_getreadbuffer == NULL\r
116       || SrcData->tp_as_buffer->bf_getsegcount == NULL) {\r
117     return NULL;\r
118   }\r
119 \r
120   // Because some Python objects which support "buffer" protocol have more than one\r
121   // memory segment, we have to copy them into a contiguous memory.\r
122   SrcBuf = malloc(SrcDataSize);\r
123   DstBuf = malloc(DstDataSize);\r
124   if (SrcBuf == NULL || DstBuf == NULL) {\r
125     goto ERROR;\r
126   }\r
127 \r
128   SegNum = SrcData->tp_as_buffer->bf_getsegcount(SrcData, NULL);\r
129   TmpBuf = SrcBuf\r
130   for (Index = 0; Index < SegNum; ++Index) {\r
131     VOID *BufSeg;\r
132     Py_ssize_t Len;\r
133 \r
134     Len = SrcData->tp_as_buffer->bf_getreadbuffer(SrcData, Index, &BufSeg);\r
135     if (Len < 0) {\r
136       goto ERROR;\r
137     }\r
138     memcpy(TmpBuf, BufSeg, Len);\r
139     TmpBuf += Len;\r
140   }\r
141 \r
142   Status = Extract((VOID *)SrcBuf, SrcDataSize, (VOID *)DstBuf, DstDataSize, 2);\r
143   if (Status != EFI_SUCCESS) {\r
144     goto ERROR;\r
145   }\r
146 \r
147   return PyBuffer_FromMemory(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 STATIC\r
161 PyObject*\r
162 UefiCompress(\r
163   PyObject    *Self,\r
164   PyObject    *Args,\r
165   PyObject    *Keywords\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   PyObject    *Keywords\r
178   )\r
179 {\r
180   return NULL;\r
181 }\r
182 \r
183 STATIC CHAR DecompressDocs[] = "Decompress(): Decompress data using UEFI standard algorithm\n";\r
184 STATIC CHAR CompressDocs[] = "Compress(): Compress data using UEFI standard algorithm\n";\r
185 \r
186 STATIC PyMethodDef EfiCompressor_Funcs[] = {\r
187   {"UefiDecompress", (PyCFunction)UefiDecompress, METH_KEYWORDS, DecompressDocs},\r
188   {"UefiCompress", (PyCFunction)UefiCompress, METH_KEYWORDS, DecompressDocs},\r
189   {"FrameworkDecompress", (PyCFunction)FrameworkDecompress, METH_KEYWORDS, DecompressDocs},\r
190   {"FrameworkCompress", (PyCFunction)FrameworkCompress, METH_KEYWORDS, DecompressDocs},\r
191   {NULL, NULL, 0, NULL}\r
192 };\r
193 \r
194 PyMODINIT_FUNC\r
195 InitEfiCompressor(VOID) {\r
196   Py_InitModule3("EfiCompressor", EfiCompressor_Funcs, "EFI Compression Algorithm Extension Module");\r
197 }\r
198 \r
199 \r