Skip to content

Commit 80ac179

Browse files
committed
Initial commit
1 parent 102b9cb commit 80ac179

File tree

7 files changed

+569
-2
lines changed

7 files changed

+569
-2
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ CPackSourceConfig.cmake
88
_deps/
99
lib*.*
1010
ffmpeg-build
11+
__pycache__
12+

src/cpython/__init__.py

Whitespace-only changes.

src/cpython/exceptions/__init__.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
M3U8TagError
1818
)
1919

20+
from .codes import KaiErrorCode
21+
2022
from .utils import code2exception
2123

2224
__all__ = [
@@ -36,5 +38,6 @@
3638
"M3U8PlaylistError",
3739
"PrintfError",
3840
"M3U8TagError",
39-
"code2exception"
41+
"code2exception",
42+
"KaiErrorCode"
4043
]

src/cpython/exceptions/utils.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ def code2exception(code):
99

1010
for (key, value) in ERROR_CODE_MAPPING.items():
1111
if code not in value:
12-
break
12+
continue
1313

1414
exception = key
1515

src/cpython/kai.py

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
from _kai import (
2+
m3u8stream_init,
3+
m3u8stream_load,
4+
m3u8stream_load_url,
5+
m3u8stream_load_file
6+
)
7+
8+
from exceptions import code2exception, KaiErrorCode
9+
10+
class M3U8Stream:
11+
12+
def __init__(self):
13+
self.instance = m3u8stream_init()
14+
15+
def ensure_non_error(self):
16+
code = KaiErrorCode(self.code)
17+
18+
if code != KaiErrorCode.M3U8ERR_SUCCESS:
19+
exception = code2exception(code = self.code)
20+
raise exception
21+
22+
return None
23+
24+
def load(self, something, base_url = None):
25+
self.code = m3u8stream_load(
26+
self.instance,
27+
something,
28+
base_url
29+
)
30+
31+
self.ensure_non_error()
32+
33+
return self
34+
35+
def load_url(self, url, base_url = None):
36+
self.code = m3u8stream_load_url(
37+
self.instance,
38+
url,
39+
base_url
40+
)
41+
42+
self.ensure_non_error()
43+
44+
return self
45+
46+
def load_file(self, filename, base_url = None):
47+
self.code = m3u8stream_load_file(
48+
self.instance,
49+
filename,
50+
base_url
51+
)
52+
53+
self.ensure_non_error()
54+
55+
return self
56+
57+
stream = M3U8Stream()
58+
stream.load_url("https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_adv_example_hevc/master.m3u8")

src/cpython/src/kai.c

+194
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
#define PY_SSIZE_T_CLEAN
2+
#include <Python.h>
3+
/*
4+
struct OrderedSetItem {
5+
int type;
6+
void* value;
7+
};
8+
9+
struct OrderedSet {
10+
size_t offset;
11+
size_t size;
12+
struct OrderedSetItem* items;
13+
};
14+
15+
static const size_t MIN_SET_SIZE = 128;
16+
17+
int orderedset_exists(
18+
const struct OrderedSet* const ordered_set,
19+
const int type,
20+
const void* const value
21+
) {
22+
23+
size_t index = 0;
24+
int exists = 0;
25+
26+
for (index = 0; index < ordered_set->offset; index++) {
27+
const struct OrderedSetItem* const item = &ordered_set->items[index];
28+
exists = strcmp(value, item->value) == 0;
29+
30+
if (exists) {
31+
break;
32+
}
33+
}
34+
35+
return exists;
36+
37+
}
38+
39+
static PyObject* orderedset_init(PyObject* self, PyObject* args)
40+
{
41+
/*
42+
const char *command;
43+
int sts;
44+
45+
if (!PyArg_ParseTuple(args, "s", &command))
46+
return NULL;
47+
*/
48+
49+
uintptr_t pointer = 0;
50+
51+
struct OrderedSet* ordered_set = malloc(sizeof(struct OrderedSet));
52+
53+
if (ordered_set == NULL) {
54+
return PyErr_NoMemory();
55+
}
56+
57+
ordered_set->offset = 0;
58+
ordered_set->size = sizeof(struct OrderedSetItem) * MIN_SET_SIZE;
59+
ordered_set->items = malloc(ordered_set->size);
60+
61+
if (ordered_set->items == NULL) {
62+
return PyErr_NoMemory();
63+
}
64+
65+
pointer = (uintptr_t) ordered_set;
66+
67+
return PyLong_FromLongLong(pointer);
68+
69+
}
70+
71+
static PyObject* orderedset_add(PyObject* self, PyObject* args)
72+
{
73+
74+
unsigned long long pointer = 0;
75+
const char* value = NULL;
76+
77+
char* vitem = NULL;
78+
79+
struct OrderedSet* ordered_set = NULL;
80+
struct OrderedSetItem item = {0};
81+
82+
if (!PyArg_ParseTuple(args, "Ks", &pointer, &value)) {
83+
return NULL;
84+
}
85+
86+
ordered_set = (struct OrderedSet*) pointer;
87+
88+
if (orderedset_exists(ordered_set, 0, value)) {
89+
return PyBool_FromLong(0);
90+
}
91+
92+
vitem = malloc(strlen(value) + 1);
93+
94+
if (vitem == NULL) {
95+
return PyErr_NoMemory();
96+
}
97+
98+
strcpy(vitem, value);
99+
100+
item.value = vitem;
101+
102+
ordered_set->items[ordered_set->offset++] = item;
103+
104+
if (ordered_set->offset * sizeof(*ordered_set->items) == ordered_set->size) {
105+
size_t size = ordered_set->size * 2;
106+
struct OrderedSetItem* items = realloc(ordered_set->items, size);
107+
108+
if (items == NULL) {
109+
return PyErr_NoMemory();
110+
}
111+
112+
ordered_set->size = size;
113+
ordered_set->items = items;
114+
}
115+
116+
return PyBool_FromLong(1);
117+
118+
}
119+
120+
121+
static PyObject* orderedset_size(PyObject* self, PyObject* args)
122+
{
123+
124+
unsigned long long pointer = 0;
125+
struct OrderedSet* ordered_set = NULL;
126+
127+
if (!PyArg_ParseTuple(args, "K", &pointer)) {
128+
return NULL;
129+
}
130+
131+
ordered_set = (struct OrderedSet*) pointer;
132+
133+
return PyLong_FromLongLong(ordered_set->offset);
134+
135+
}
136+
137+
static PyObject* orderedset_getitem(PyObject* self, PyObject* args)
138+
{
139+
140+
unsigned long long pointer = 0;
141+
unsigned long long position = 0;
142+
143+
struct OrderedSet* ordered_set = NULL;
144+
struct OrderedSetItem* item = NULL;
145+
146+
if (!PyArg_ParseTuple(args, "KK", &pointer, &position)) {
147+
return NULL;
148+
}
149+
150+
ordered_set = (struct OrderedSet*) pointer;
151+
152+
if (position > ordered_set->offset) {
153+
return NULL;
154+
}
155+
156+
item = &ordered_set->items[position];
157+
158+
return PyUnicode_FromString(item->value);
159+
160+
}
161+
*/
162+
163+
static PyMethodDef methods[] = {
164+
{
165+
"orderedset_init",
166+
orderedset_init,
167+
METH_VARARGS,
168+
"Execute a shell command."
169+
}
170+
/*
171+
,
172+
{"orderedset_add", orderedset_add, METH_VARARGS,
173+
"Execute a shell command."},
174+
{"orderedset_size", orderedset_size, METH_VARARGS,
175+
"Execute a shell command."},
176+
{"orderedset_getitem", orderedset_getitem, METH_VARARGS,
177+
"Execute a shell command."},
178+
*/
179+
{NULL, NULL, 0, NULL} /* Sentinel */
180+
};
181+
182+
static struct PyModuleDef module = {
183+
PyModuleDef_HEAD_INIT,
184+
"_kai",
185+
NULL,
186+
-1,
187+
methods
188+
};
189+
190+
PyMODINIT_FUNC PyInit__kai(void) {
191+
192+
return PyModule_Create(&module);
193+
194+
}

0 commit comments

Comments
 (0)