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