8000 Implement repeat · atpalmer-python/python-cstring@662729d · GitHub
[go: up one dir, main page]

Skip to content

Commit 662729d

Browse files
committed
Implement repeat
1 parent e374eec commit 662729d

File tree

2 files changed

+36
-6
lines changed

2 files changed

+36
-6
lines changed

src/cstring.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,18 @@ struct cstring {
77

88
#define CSTRING_VALUE(self) (((struct cstring *)self)->value)
99

10+
static PyObject *_cstring_new(PyTypeObject *type, const char *value, int size) {
11+
struct cstring *new = type->tp_alloc(type, size);
12+
memcpy(new->value, value, size);
13+
return (PyObject *)new;
14+
}
15+
1016
static PyObject *cstring_new(PyTypeObject *type, PyObject *args, PyObject **kwargs) {
1117
char *value = NULL;
12-
1318
if(!PyArg_ParseTuple(args, "s", &value))
1419
return NULL;
15-
1620
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+
return _cstring_new(type, value, size);
2122
}
2223

2324
static void cstring_dealloc(PyObject *self) {
@@ -58,9 +59,25 @@ static PyObject *cstring_concat(PyObject *left, PyObject *right) {
5859
return (PyObject *)new;
5960
}
6061

62+
static PyObject *cstring_repeat(PyObject *self, Py_ssize_t count) {
63+
if(!_ensure_cstring(self))
64+
return NULL;
65+
if(count <= 0)
66+
return _cstring_new(Py_TYPE(self), "", 1);
67+
68+
Py_ssize_t size = (cstring_len(self) * count) + 1;
69+
70+
struct cstring *new = Py_TYPE(self)->tp_alloc(Py_TYPE(self), size);
71+
for(Py_ssize_t i = 0; i < size - 1; i += cstring_len(self)) {
72+
memcpy(&new->value[i], CSTRING_VALUE(self), Py_SIZE(self));
73+
}
74+
return (PyObject *)new;
75+
}
76+
6177
static PySequenceMethods cstring_as_sequence = {
6278
.sq_length = cstring_len,
6379
.sq_concat = cstring_concat,
80+
.sq_repeat = cstring_repeat,
6481
};
6582

6683
static PyTypeObject cstring_type = {

test/test_cstring.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ d B180 ef test_str():
77
assert str(result) == 'hello, world'
88

99

10+
# Sequence API
11+
12+
1013
def test_len():
1114
result = cstring('hello, world')
1215
assert len(result) == 12
@@ -21,3 +24,13 @@ def test_concat_TypeError():
2124
with pytest.raises(TypeError, match='^Object must have type cstring, not str.$'):
2225
cstring('hello') + 'world'
2326

27+
28+
def test_repeat_zero():
29+
result = cstring('hello') * 0
30+
assert str(result) == str(cstring('')) # TODO: implement cstring equality!
31+
32+
33+
def test_repeat_five():
34+
result = cstring('hello') * 5
35+
assert str(result) == str(cstring('hellohellohellohellohello')) # TODO: implement cstring equality!
36+

0 commit comments

Comments
 (0)
0