From f73129cbe9b72319c41f71d3182a6c5e7b2cb95b Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 14 Oct 2020 13:43:31 +0200 Subject: fixup! WIP: Add Python bindings --- bindings/python/serd.pyx | 75 +++++++++++++++++++++++++++++------------------- 1 file 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. """ -- cgit v1.2.1