X-Git-Url: https://git.distorted.org.uk/~mdw/mLib-python/blobdiff_plain/20bce5e92b01cd928f26b61be78215117039c561..579d01693c86259110fe7a2c2a6f005f1bdbad5b:/lbuf.pyx diff --git a/lbuf.pyx b/lbuf.pyx new file mode 100644 index 0000000..820cba1 --- /dev/null +++ b/lbuf.pyx @@ -0,0 +1,131 @@ +# -*-pyrex-*- +# +# $Id$ +# +# Line buffering +# +# (c) 2005 Straylight/Edgeware +# + +#----- Licensing notice ----------------------------------------------------- +# +# This file is part of the Python interface to mLib. +# +# mLib/Python is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# mLib/Python is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with mLib/Python; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +LBUF_CRLF = _LBUF_CRLF +LBUF_STRICTCRLF = _LBUF_STRICTCRLF + +cdef class LineBuffer: + cdef lbuf b + cdef _line + cdef _eof + def __new__(me, lineproc = None, eofproc = None, *hunoz, **hukairz): + lbuf_init(&me.b, _lbfunc, me) + me._line = _checkcallable(lineproc, 'line proc') + me._eof = _checkcallable(eofproc, 'eof proc') + def __dealloc__(me): + lbuf_destroy(&me.b) + property activep: + def __get__(me): + return _tobool(me.b.f & LBUF_ENABLE) + property delim: + def __get__(me): + if me.b.delim == _LBUF_CRLF or me.b.delim == _LBUF_STRICTCRLF: + return me.b.delim + else: + return chr(me.b.delim) + def __set__(me, d): + if d == _LBUF_CRLF or d == _LBUF_STRICTCRLF: + me.b.delim = d + else: + me.b.delim = ord(d) + property size: + def __get__(me): + return me.b.sz + def __set__(me, sz): + if sz <= 0: + raise TypeError, 'size must be positive' + lbuf_setsize(&me.b, sz) + property lineproc: + def __get__(me): + return me._line + def __set__(me, proc): + me._line = _checkcallable(proc, 'line proc') + def __del__(me): + me._line = None + property eofproc: + def __get__(me): + return me._eof + def __set__(me, proc): + me._eof = _checkcallable(proc, 'eof proc') + def __del__(me): + me._eof = None + def enable(me): + if me.b.f & LBUF_ENABLE: + raise ValueError, 'already enabled' + me.b.f = me.b.f | LBUF_ENABLE + me.enabled() + return me + def disable(me): + if not (me.b.f & LBUF_ENABLE): + raise ValueError, 'already disabled' + me.b.f = me.b.f & ~LBUF_ENABLE + me.disabled() + return me + def close(me): + if not (me.b.f & LBUF_ENABLE): + raise ValueError, 'buffer disabled' + lbuf_close(&me.b) + return me + property free: + def __get__(me): + cdef char *p + return lbuf_free(&me.b, &p) + def flush(me, str): + cdef int len + cdef char *p + cdef char *q + cdef size_t n + PyString_AsStringAndSize(str, &p, &len) + while len > 0: + n = lbuf_free(&me.b, &q) + if n > len: + n = len + memcpy(q, p, n) + p = p + n + len = len - n + if not (me.b.f & LBUF_ENABLE): + break + lbuf_flush(&me.b, q, n) + return PyString_FromStringAndSize(p, len) + def enabled(me): + pass + def disabled(me): + pass + def line(me, line): + return _maybecall(me._line, (line,)) + def eof(me): + return _maybecall(me._eof, ()) + +cdef void _lbfunc(char *s, size_t n, void *arg): + cdef LineBuffer sb + sb = arg + if s is NULL: + sb.eof() + else: + sb.line(PyString_FromStringAndSize(s, n)) + +#----- That's all, folks ----------------------------------------------------