aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2020-10-14 13:43:31 +0200
committerDavid Robillard <d@drobilla.net>2020-10-27 13:13:59 +0100
commitf73129cbe9b72319c41f71d3182a6c5e7b2cb95b (patch)
tree1caaf70233235bfe167cbabd0799c7adf55441a3
parent5a71277b900164392dea0bc3800db1c67b9df8e1 (diff)
downloadserd-f73129cbe9b72319c41f71d3182a6c5e7b2cb95b.tar.gz
serd-f73129cbe9b72319c41f71d3182a6c5e7b2cb95b.tar.bz2
serd-f73129cbe9b72319c41f71d3182a6c5e7b2cb95b.zip
fixup! WIP: Add Python bindings
-rw-r--r--bindings/python/serd.pyx75
1 files changed, 46 insertions, 29 deletions
diff --git a/bindings/python/serd.pyx b/bindings/python/serd.pyx
index 70e28258..4514e409 100644
--- a/bindings/python/serd.pyx
+++ b/bindings/python/serd.pyx
@@ -8,6 +8,7 @@
import enum
import logging
+import errno
import cython
@@ -726,7 +727,7 @@ class Namespace:
"""
def __init__(self, prefix: str):
- self.prefix = _uri_from_param(prefix)
+ self.prefix = str(_uri_from_param(prefix))
def __add__(self, suffix: str):
return uri(self.prefix + suffix)
@@ -920,7 +921,7 @@ cdef class World:
env: Env = None,
) -> None:
"""Write a model to a file."""
- byte_sink = ByteSink(filename=path)
+ byte_sink = FileSink(filename=path)
writer = Writer(self, syntax, writer_flags, env, byte_sink)
st = model.all().serialise(writer.sink(), serialisation_flags)
writer.finish()
@@ -936,18 +937,14 @@ cdef class World:
env: Env = None,
) -> str:
"""Write a model to a string and return it."""
- buffer = Buffer()
- byte_sink = ByteSink(buffer=buffer)
+ byte_sink = StringSink()
writer = Writer(self, syntax, writer_flags, env, byte_sink)
st = model.all().serialise(writer.sink(), serialisation_flags)
writer.finish()
- byte_sink.flush()
_ensure_success(st)
- result = _fromcstr(serd_buffer_sink_finish(&buffer._buffer))
- serd_free(buffer._buffer.buf)
- return result
+ return byte_sink.output()
cdef class Node:
@@ -1089,7 +1086,10 @@ cdef class Node:
Passing the returned string to Node.from_syntax() will produce a node
equivalent to this one.
"""
- return _fromcstr(serd_node_to_syntax(self._ptr, syntax))
+ cstr = serd_node_to_syntax(self._ptr, syntax)
+ result = _fromcstr(cstr)
+ serd_free(cstr)
+ return result
# Node constructors
@@ -1403,30 +1403,10 @@ cdef class StringSource(__ByteSource):
_unwrap_node(name))
-cdef class Buffer:
- """A mutable buffer in memory."""
- cdef SerdBuffer _buffer
-
- def __init__(self):
- self._buffer.buf = NULL
- self._buffer.len = 0;
-
-
cdef class ByteSink:
"""A sink for bytes that receives text output."""
cdef SerdByteSink* _ptr
- def __init__(self, filename: str = None,
- buffer: Buffer = None,
- block_size: int = 4096):
- if filename is not None:
- self._ptr = serd_byte_sink_new_filename(_tocstr(filename),
- block_size)
- elif buffer is not None:
- self._ptr = serd_byte_sink_new_buffer(&buffer._buffer)
- else:
- raise TypeError("Bad arguments for ByteSink()")
-
def __dealloc__(self):
serd_byte_sink_free(self._ptr)
self._ptr = NULL
@@ -1440,6 +1420,43 @@ cdef class ByteSink:
serd_byte_sink_close(self._ptr)
+cdef class FileSink(ByteSink):
+ """A sink for bytes that writes text output to a file."""
+
+ def __init__(self,
+ filename: str,
+ block_size: int = 4096):
+ super().__init__()
+
+ self._ptr = serd_byte_sink_new_filename(_tocstr(filename),
+ block_size)
+
+ if self._ptr is NULL:
+ raise OSError(errno, strerror(errno), filename)
+
+
+cdef class StringSink(ByteSink):
+ """A sink for bytes that writes text output to a string."""
+ cdef SerdBuffer _buffer
+
+ def __dealloc__(self):
+ serd_free(self._buffer.buf)
+ self._buffer.buf = NULL
+ self._buffer.len = 0;
+ # super().__dealloc__(self)
+
+ def __init__(self):
+ super().__init__()
+
+ self._buffer.buf = NULL
+ self._buffer.len = 0;
+ self._ptr = serd_byte_sink_new_buffer(&self._buffer)
+
+ def output(self) -> str:
+ self.flush()
+ return _fromcstr(serd_buffer_sink_finish(&self._buffer))
+
+
cdef class Writer:
"""Streaming serialiser that writes a text stream as statements are pushed.
"""