Skip to content

Commit 34110ca

Browse files
committed
Implement cstring type
1 parent 405544e commit 34110ca

File tree

2 files changed

+47
-5
lines changed

2 files changed

+47
-5
lines changed

src/cstring.c

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,43 @@
11
#include <Python.h>
22

33
struct cstring {
4-
PyObject_HEAD
4+
PyObject_VAR_HEAD
5+
char value[];
6+
};
7+
8+
#define CSTRING_VALUE(self) (((struct cstring *)self)->value)
9+
10+
static PyObject *cstring_new(PyTypeObject *type, PyObject *args, PyObject **kwargs) {
11+
char *value = NULL;
12+
13+
if(!PyArg_ParseTuple(args, "s", &value))
14+
return NULL;
15+
16+
int size = strlen(value) + 1;
17+
18+
struct cstring *new = type->tp_alloc(type, size);
19+
memcpy(new->value, value, size);
20+
return (PyObject *)new;
21+
}
22+
23+
static void cstring_dealloc(PyObject *self) {
24+
Py_TYPE(self)->tp_free(self);
25+
}
26+
27+
static PyObject *cstring_str(PyObject *self) {
28+
return PyUnicode_FromString(CSTRING_VALUE(self));
29+
}
30+
31+
static PyTypeObject cstring_type = {
32+
PyVarObject_HEAD_INIT(NULL, 0)
33+
.tp_name = "cstring",
34+
.tp_doc = "",
35+
.tp_basicsize = sizeof(struct cstring),
36+
.tp_itemsize = sizeof(char),
37+
.tp_flags = Py_TPFLAGS_DEFAULT,
38+
.tp_new = cstring_new,
39+
.tp_dealloc = cstring_dealloc,
40+
.tp_str = cstring_str,
541
};
642

743
static struct PyModuleDef module = {
@@ -13,5 +49,10 @@ static struct PyModuleDef module = {
1349
};
1450

1551
PyMODINIT_FUNC PyInit_cstring(void) {
16-
return PyModule_Create(&module);
52+
if(PyType_Ready(&cstring_type) < 0)
53+
return NULL;
54+
Py_INCREF(&cstring_type);
55+
PyObject *m = PyModule_Create(&module);
56+
PyModule_AddObject(m, "cstring", (PyObject *)&cstring_type);
57+
return m;
1758
}

test/test_cstring.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import cstring
1+
from cstring import cstring
22

33

4-
def test_cstring():
5-
pass
4+
def test_str():
5+
result = cstring('hello, world')
6+
assert str(result) == 'hello, world'
67

0 commit comments

Comments
 (0)