From d334bd1a726a33859ecb5328e9b306b31cf5fdf5 Mon Sep 17 00:00:00 2001 From: Ketmar Dark Date: Wed, 20 Apr 2016 19:46:29 +0300 Subject: [PATCH] more conbuf API --- conbuf.d | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 3 deletions(-) diff --git a/conbuf.d b/conbuf.d index e620468..78f7942 100644 --- a/conbuf.d +++ b/conbuf.d @@ -8,8 +8,10 @@ shared static this () { conbufLock = new Mutex(); } // ////////////////////////////////////////////////////////////////////////// // -enum ConBufSize = 256*1024; -//enum ConBufSize = 64; +version(test_cbuf) + enum ConBufSize = 64; +else + enum ConBufSize = 256*1024; // each line in buffer ends with '\n'; we don't keep offsets or lengthes, as // it's fairly easy to search in buffer, and drawing console is not a common @@ -38,6 +40,62 @@ public void cbufPut (const(char)[] chrs...) nothrow @trusted @nogc { // ////////////////////////////////////////////////////////////////////////// // +// warning! don't modify conbuf while the range is active! +public auto conbufLinesRev () nothrow @trusted @nogc { + static struct Line { + nothrow @trusted @nogc: + private: + int h, t; // head and tail, to check validity + int sp = -1, ep; + + public: + @property auto front () const { pragma(inline, true); return (sp >= 0 ? cbuf.ptr[sp] : '\x00'); } + @property bool empty () const { pragma(inline, true); return (sp < 0 || h != cbufhead || t != cbuftail); } + @property auto save () { pragma(inline, true); return Line(h, t, sp, ep); } + void popFront () { pragma(inline, true); if (sp < 0 || (sp = (sp+1)%ConBufSize) == ep) sp = -1; } + } + + static struct Range { + nothrow @trusted @nogc: + private: + int h, t; // head and tail, to check validity + int pos; // position of prev line + Line line; + + void toLineStart () { + line.ep = pos; + while (pos != cbufhead) { + int p = (pos+ConBufSize-1)%ConBufSize; + if (cbuf.ptr[p] == '\n') break; + pos = p; + } + line.sp = pos; + line.h = h; + line.t = t; + } + + public: + @property auto front () pure { pragma(inline, true); return line; } + @property bool empty () const { pragma(inline, true); return (pos < 0 || pos == h || h != cbufhead || t != cbuftail); } + @property auto save () { pragma(inline, true); return Range(h, t, pos, line); } + void popFront () { + if (pos < 0 || pos == h || h != cbufhead || t != cbuftail) { line = Line.init; h = t = pos = -1; return; } + pos = (pos+ConBufSize-1)%ConBufSize; + toLineStart(); + } + } + + Range res; + res.h = cbufhead; + res.pos = res.t = cbuftail; + if (cbuf.ptr[res.pos] != '\n') res.pos = (res.pos+1)%ConBufSize; + res.toLineStart(); + //{ import std.stdio; writeln("pos=", res.pos, "; head=", res.h, "; tail=", res.t, "; llen=", res.line.length, "; [", res.line, "]"); } + return res; +} + + +// ////////////////////////////////////////////////////////////////////////// // public void conbufDump () { import std.stdio; int pp = cbufhead; @@ -51,12 +109,12 @@ public void conbufDump () { } pp = (pp+1)%ConBufSize; } + //foreach (auto s; conbufLinesRev) stdout.writeln(s, "|"); } // ////////////////////////////////////////////////////////////////////////// // version(test_cbuf) unittest { - conbufDump(); cbufPut("boo\n"); conbufDump(); cbufPut("this is another line\n"); conbufDump(); -- 2.11.4.GIT