pluskid / pyppm

PPM (Predict by Partial Matching) compression algorithm implementation for Python

This URL has Read+Write access

pyppm / pyppm.cpp
311094ae » pluskid 2008-11-02 Added Python interface to p... 1 #include <cstdio>
2 #include <cstring>
3 #include <cerrno>
4 #include <Python.h>
5 #include "ppm_model.h"
6 #include "io_adapter.h"
7
8 using namespace std;
9
10 extern "C" {
11
12 typedef struct
13 {
14 PyObject_HEAD
15 PPMModel *model;
16 } Model;
17
18 static void Model_dealloc(PyObject *self);
19 static PyObject * Model_GetAttr(PyObject *self, char *attrname);
20
21 static PyTypeObject Model_Type = {
22 PyObject_HEAD_INIT(&PyType_Type)
23 0,
24 "Model",
25 sizeof(Model),
26 0,
27 (destructor)Model_dealloc,
28 0,
29 (getattrfunc)Model_GetAttr,
30 /* rest are NULLs */
31 };
32
33 #define Model_Check(v) ((v)->ob_type == &Model_Type)
34 #define Model_Ptr(v) (((Model *)(v))->model)
35
36 static PyObject *Model_New(PyObject *self, PyObject *args)
37 {
38 PPMModel *pm;
39 Model *model = NULL;
40 char *path = NULL;
41
42 if (PyArg_ParseTuple(args, "|s", &path)) {
43 if (path != NULL) {
44 FILE *fp = fopen(path, "rb");
45 if (fp == NULL) {
46 PyErr_SetString(PyExc_IOError, strerror(errno));
47 return (PyObject *)model;
48 } else {
49 pm = PPMModel::load(fp);
50 fclose(fp);
51 }
52 } else {
53 pm = new PPMModel();
54 }
ea2cf61c » pluskid 2008-11-02 Fixed the bug of core dump ... 55 model = PyObject_New(Model, &Model_Type);
311094ae » pluskid 2008-11-02 Added Python interface to p... 56 model->model = pm;
57 }
58
59 return (PyObject *)model;
60 }
61
62 static void Model_dealloc(PyObject *self)
63 {
64 Model_Ptr(self)->decref();
ea2cf61c » pluskid 2008-11-02 Fixed the bug of core dump ... 65 PyObject_Del(self);
311094ae » pluskid 2008-11-02 Added Python interface to p... 66 }
67
68 static PyObject *Model_dump(PyObject *self, PyObject *args)
69 {
70 char *path = NULL;
71
72 if (PyArg_ParseTuple(args, "s", &path)) {
73 FILE *fp = fopen(path, "wb");
74 if (fp == NULL) {
75 PyErr_SetString(PyExc_IOError, strerror(errno));
76 } else {
77 PPMModel::dump(Model_Ptr(self), fp);
78 fclose(fp);
79 }
80 }
81
82 return Py_BuildValue("");
83 }
84
85 static PyObject *Model_train(PyObject *self, PyObject *args)
86 {
87 char *path = NULL;
88
89 if (PyArg_ParseTuple(args, "s", &path)) {
90 FILE *fp = fopen(path, "rb");
91 if (fp == NULL) {
92 PyErr_SetString(PyExc_IOError, strerror(errno));
93 } else {
94 NullOutputAdapter nad;
95
96 PPMEncoder<NullOutputAdapter, DefaultContextUpdater> penc(nad, Model_Ptr(self));
97 penc.start_encoding();
98 for (int ch = fgetc(fp); ch != EOF; ch = fgetc(fp)) {
99 penc.encode(ch);
100 }
101 penc.finish_encoding();
102 fclose(fp);
103
104 return Py_BuildValue("i", nad.count());
105 }
106 }
107 return Py_BuildValue("");
108 }
109
110 static PyObject *Model_predict(PyObject *self, PyObject *args)
111 {
112 char *path = NULL;
113
114 if (PyArg_ParseTuple(args, "s", &path)) {
115 FILE *fp = fopen(path, "rb");
116 if (fp == NULL) {
117 PyErr_SetString(PyExc_IOError, strerror(errno));
118 } else {
119 NullOutputAdapter nad;
120
121 PPMModel *pm = Model_Ptr(self);
122 pm->m_buffer.reset();
123 PPMEncoder<NullOutputAdapter, NopeContextUpdater> penc(nad, pm);
124 penc.start_encoding();
125 for (int ch = fgetc(fp); ch != EOF; ch = fgetc(fp))
126 penc.encode(ch);
127 penc.finish_encoding();
128 fclose(fp);
129
130 return Py_BuildValue("i", nad.count());
131 }
132 }
133 return Py_BuildValue("");
134 }
135
136 static PyMethodDef Model_methods[] = {
137 {"dump", Model_dump, METH_VARARGS},
138 {"train", Model_train, METH_VARARGS},
139 {"predict", Model_predict, METH_VARARGS},
140 {NULL, NULL},
141 };
142
143 static PyObject * Model_GetAttr(PyObject *self, char *attrname)
144 {
145 return Py_FindMethod(Model_methods, self, attrname);
146 }
147
148 static PyMethodDef methods[] = {
149 {"Model", Model_New, METH_VARARGS},
150 {NULL, NULL},
151 };
152
153 void initpyppm()
154 {
155 Py_InitModule("pyppm", methods);
156 }
157
158 } // extern "C"