From 396f9a0ead6c0675004a381c3c6c115367f715d0 Mon Sep 17 00:00:00 2001 From: ketmar Date: Thu, 25 Nov 2021 04:31:29 +0000 Subject: [PATCH] use "iv.dynstring" FossilOrigin-Name: feebf4743d079b8f949e505c71377949462e6fce88ef82850a4deae20a974925 --- chibackend/mbuilder.d | 8 +- chibackend/package.d | 331 +------------------------------------------------- 2 files changed, 6 insertions(+), 333 deletions(-) diff --git a/chibackend/mbuilder.d b/chibackend/mbuilder.d index 1064a45..723dd5f 100644 --- a/chibackend/mbuilder.d +++ b/chibackend/mbuilder.d @@ -385,10 +385,10 @@ public: scope(failure) delete att; att.name = filename; //att.mime = mime; // let the engine determine it - att.data.reserve!false(cast(uint)fl.size); - assert(att.data.datap.alloted >= cast(uint)fl.size); - fl.rawReadExact(att.data.datap.ptr[0..cast(uint)fl.size]); - att.data.datap.used = cast(uint)fl.size; + //att.data.reserve!false(cast(uint)fl.size); + att.data.length = cast(uint)fl.size; + assert(!att.data.isShared && !att.data.isSlice && att.data.length == cast(uint)fl.size); + fl.rawReadExact(att.data.makeUniquePointer[0..cast(uint)fl.size]); attaches ~= att; } diff --git a/chibackend/package.d b/chibackend/package.d index 5eba443..ea59b8e 100644 --- a/chibackend/package.d +++ b/chibackend/package.d @@ -25,6 +25,8 @@ public import chibackend.mbuilder; private import iv.strex; private import iv.vfs.util; +public import iv.dynstring : DynStr = dynstring; + // ////////////////////////////////////////////////////////////////////////// // // some utilities @@ -121,335 +123,6 @@ public string SysTimeToRFCString() (in auto ref Imp!"std.datetime".SysTime tm) { // ////////////////////////////////////////////////////////////////////////// // -public struct DynStr { -package: - static struct Data { - usize udata = void; - uint rc = void; - usize used = void; - usize alloted = void; - - inout(char)* ptr () inout pure nothrow @trusted @nogc { pragma(inline, true); return cast(char*)udata; } - void ptr (void *v) pure nothrow @trusted @nogc { pragma(inline, true); udata = cast(usize)v; } - } - -package: - usize udata = 0; - -package: - inout(Data)* datap () inout pure nothrow @trusted @nogc { pragma(inline, true); return cast(Data*)udata; } - void datap (Data *v) pure nothrow @trusted @nogc { pragma(inline, true); udata = cast(usize)v; } - - void incRef () nothrow @trusted @nogc { - pragma(inline, true); - if (udata) ++((cast(Data*)udata).rc); - } - - void decRef () nothrow @trusted @nogc { - pragma(inline, true); - if (udata) { - if (--((cast(Data*)udata).rc) == 0) { - import core.stdc.stdlib : free; - if ((cast(Data*)udata).udata) free((cast(Data*)udata).ptr); - } - udata = 0; - } - } - -package: - bool isMyData (const(void)* ptr) pure nothrow @trusted @nogc { - //pragma(inline, true); - if (!ptr || !udata || !datap.udata) return false; - immutable usize cc = cast(usize)ptr; - return (cc >= datap.udata && cc < datap.udata+datap.alloted); - } - -public: - alias getData this; - -public: -nothrow @trusted @nogc: - this (DynStr s) { pragma(inline, true); udata = s.udata; incRef(); } - - this (const(char)[] s) { - if (s.length) { - ensure!false(s.length); - datap.ptr[0..s.length] = s[]; - datap.used = s.length; - } - } - - this (this) { pragma(inline, true); incRef(); } - ~this () { pragma(inline, true); decRef(); } - - void clear () { pragma(inline, true); decRef(); } - - void compact () nothrow @trusted @nogc { - if (!udata) return; - Data* dp = datap; - if (!dp.udata) return; - if ((dp.used|0x1fU)+1U > dp.alloted) { - immutable usize newsz = (dp.used|0x1fU)+1U; - import core.stdc.stdlib : realloc; - void *np = realloc(dp.ptr, newsz); - if (np is null) return; - dp.ptr = np; - dp.alloted = newsz; - } - } - - void ensure(bool overalloc) (usize sz) nothrow @trusted @nogc { - if (sz == 0) return; - static if (overalloc) { - if (sz <= 256) sz = (sz|0x1fU)+1U; - else if (sz <= 1024) sz = (sz|0x3fU)+1U; - else if (sz <= 8192) sz = (sz|0x1ffU)+1U; - else if (sz <= 16384) sz = (sz|0x3ffU)+1U; - else if (sz <= 32768) sz = (sz|0xfffU)+1U; - else sz = (sz|0x1fffU)+1U; - } else { - sz = (sz|0x1fU)+1U; - } - Data* dp = datap; - if (dp is null) { - import core.stdc.stdlib : calloc; - dp = cast(Data*)calloc(1, Data.sizeof); - if (dp is null) { import core.exception : onOutOfMemoryErrorNoGC; onOutOfMemoryErrorNoGC(); } - datap = dp; - dp.rc = 1U; - } - if (sz > dp.alloted) { - import core.stdc.stdlib : realloc; - void *np = realloc(dp.ptr, sz); - if (np is null) { import core.exception : onOutOfMemoryErrorNoGC; onOutOfMemoryErrorNoGC(); } - dp.ptr = np; - dp.alloted = sz; - } - } - - void makeUnique () nothrow @trusted @nogc { - if (!udata || datap.rc == 1) return; - immutable usize oldudata = udata; - immutable usize oldused = datap.used; - udata = 0; - ensure!false(oldused); - immutable usize xudata = udata; - udata = oldudata; - decRef(); - udata = xudata; - } - - void reserve(bool overalloc=true) (usize newsz) { pragma(inline, true); ensure!overalloc(newsz); } - - void append(bool overalloc=true) (const(void)[] buf) { - if (buf.length == 0) return; - if (buf.length >= cast(usize)0x2fff_ffff) { import core.exception : onOutOfMemoryErrorNoGC; onOutOfMemoryErrorNoGC(); } - if (udata && cast(usize)0x3000_0000-datap.used < buf.length) { import core.exception : onOutOfMemoryErrorNoGC; onOutOfMemoryErrorNoGC(); } - DynStr tmpstr; - if (isMyData(buf.ptr)) { - tmpstr.set(buf[]); - tmpstr.makeUnique(); - buf = cast(const(void)[])tmpstr.getData(); - } - Data* data = void; - if (udata) { - data = datap; - if (data.used+buf.length > data.alloted) { - ensure!overalloc(data.used+buf.length); - data = datap; - } - } else { - ensure!overalloc(buf.length); - data = datap; - } - data.ptr[data.used..data.used+buf.length] = cast(const(char)[])buf; - data.used += buf.length; - } - void append (const char ch) { pragma(inline, true); append((&ch)[0..1]); } - - void set (const(void)[] buf) { - pragma(inline, true); - if (buf.length == 0) { - decRef(); - } else if (udata) { - if (isMyData(buf.ptr)) { - DynStr tmpstr; - tmpstr.set(buf); - makeUnique(); - append!false(tmpstr.getData); - } else { - makeUnique(); - datap.used = 0; - append!false(buf); - } - compact(); - } else { - append!false(buf); - } - } - void set (const char ch) { pragma(inline, true); set((&ch)[0..1]); } - - uint length () const pure { pragma(inline, true); return (udata ? cast(uint)datap.used : 0U); } - - const(char)[] getData () const pure { pragma(inline, true); return (udata && datap.used ? datap.ptr[0..datap.used] : null); } - const(ubyte)[] getBytes () const pure { pragma(inline, true); return cast(const(ubyte)[])(udata && datap.used ? datap.ptr[0..datap.used] : null); } - - void opAssign() (const(char)[] s) { pragma(inline, true); set(s); } - void opAssign() (const char ch) { pragma(inline, true); set(ch); } - void opAssign() (DynStr s) { pragma(inline, true); if (s.udata != udata) set(s); } - - void opOpAssign(string op:"~") (const(char)[] s) { pragma(inline, true); append(s); } - void opOpAssign(string op:"~") (const char ch) { pragma(inline, true); append(ch); } - void opOpAssign(string op:"~") (DynStr s) { pragma(inline, true); append(s); } - - const(char)[] opCast(T:const(char)[]) () const pure { pragma(inline, true); return getData(); } - const(ubyte)[] opCast(T:const(ubyte)[]) () const pure { pragma(inline, true); return getBytes(); } - - bool opEqual (const(char)[] other) const pure { pragma(inline, true); return (other[] == getBytes()[]); } - bool opEqual (const ref DynStr other) const pure { pragma(inline, true); return (other.getBytes()[] == getBytes()[]); } - - int opCmp (const(char)[] other) const pure { - if (!udata || datap.used == 0) return (other.length ? -1 : 0); - if (other.length == 0) return 1; - if (datap.ptr == other.ptr && datap.used == other.length) return 0; - import core.stdc.string : memcmp; - immutable int cres = memcmp(datap.ptr, other.ptr, (datap.used < other.length ? datap.used : other.length)); - if (cres != 0) return (cres < 0 ? -1 : +1); - return (datap.used < other.length ? -1 : datap.used > other.length ? +1 : 0); - } - - int opCmp (const ref DynStr other) const { pragma(inline, true); return opCmp(other.getData); } - - void appendQEncoded (const(void)[] ss) { - static bool isSpecial (immutable char ch) pure nothrow @safe @nogc { - return - ch < ' ' || - ch >= 127 || - ch == '\'' || - ch == '`' || - ch == '"' || - ch == '\\' || - ch == '@'; - } - - if (ss.length == 0) return; - const(char)[] s = cast(const(char)[])ss; - - static immutable string hexd = "0123456789abcdef"; - - bool needWork = (s[0] == '=' || s[0] == '?'); - if (!needWork) foreach (char ch; s) if (isSpecial(ch)) { needWork = true; break; } - - if (!needWork) { - append(s); - } else { - append("=?UTF-8?Q?"); // quoted printable - foreach (char ch; s) { - if (ch <= ' ') ch = '_'; - if (!isSpecial(ch) && ch != '=' && ch != '?') { - append(ch); - } else { - append("="); - append(hexd[(cast(ubyte)ch)>>4]); - append(hexd[(cast(ubyte)ch)&0x0f]); - } - } - append("?="); - } - } - - void appendB64Encoded (const(void)[] buf, uint maxlinelen=76) { - static immutable string b64alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - ubyte[3] bts = void; - uint btspos = 0; - uint linelen = 0; - - void putB64Char (immutable char ch) nothrow @trusted @nogc { - if (maxlinelen && linelen >= maxlinelen) { append("\r\n"); linelen = 0; } - append(ch); - ++linelen; - } - - void encodeChunk () nothrow @trusted @nogc { - if (btspos == 0) return; - putB64Char(b64alphabet.ptr[(bts.ptr[0]&0xfc)>>2]); - if (btspos == 1) { - putB64Char(b64alphabet.ptr[(bts.ptr[0]&0x03)<<4]); - /*static if (padding)*/ { putB64Char('='); putB64Char('='); } - } else { - // 2 or more - putB64Char(b64alphabet.ptr[((bts.ptr[0]&0x03)<<4)|((bts.ptr[1]&0xf0)>>4)]); - if (btspos == 2) { - putB64Char(b64alphabet.ptr[(bts.ptr[1]&0x0f)<<2]); - /*static if (padding)*/ putB64Char('='); - } else { - // 3 bytes - putB64Char(b64alphabet.ptr[((bts.ptr[1]&0x0f)<<2)|((bts.ptr[2]&0xc0)>>6)]); - putB64Char(b64alphabet.ptr[bts.ptr[2]&0x3f]); - } - } - btspos = 0; - } - - foreach (immutable ubyte ib; (cast(const(ubyte)[])buf)[]) { - bts.ptr[btspos++] = ib; - if (btspos == 3) encodeChunk(); - } - if (btspos != 0) encodeChunk(); - - if (maxlinelen) append("\r\n"); - } - - void appendNum(T) (const T v) if (__traits(isIntegral, T)) { - import core.stdc.stdio : snprintf; - static if (T.sizeof <= 4) { - char[32] buf = void; - static if (__traits(isUnsigned, T)) { - auto len = snprintf(buf.ptr, buf.length, "%u", cast(uint)v); - } else { - auto len = snprintf(buf.ptr, buf.length, "%d", cast(int)v); - } - append(buf[0..len]); - } else { - char[128] buf = void; - static if (__traits(isUnsigned, T)) { - auto len = snprintf(buf.ptr, buf.length, "%llu", cast(ulong)v); - } else { - auto len = snprintf(buf.ptr, buf.length, "%lld", cast(long)v); - } - append(buf[0..len]); - } - } - - void removeASCIICtrls () { - static bool isCtrl (const char ch) pure nothrow @safe @nogc { - pragma(inline, true); - return (ch < 32 && ch != '\t' && ch != '\n'); - } - - bool needWork = false; - foreach (immutable char ch; getData) if (isCtrl(ch)) { needWork = true; break; } - if (!needWork) return; - - makeUnique(); - char[] buf = cast(char[])datap.ptr[0..datap.used]; - foreach (ref char ch; buf) if (isCtrl(ch)) ch = ' '; - } - - // only for ASCII - void lowerInPlace () { - bool needWork = false; - foreach (immutable char ch; getData) if (ch >= 'A' && ch <= 'Z') { needWork = true; break; } - if (!needWork) return; - - makeUnique(); - char[] buf = cast(char[])datap.ptr[0..datap.used]; - foreach (ref char ch; buf) if (ch >= 'A' && ch <= 'Z') ch += 32; - } -} - - -// ////////////////////////////////////////////////////////////////////////// // // simple exponential running average struct RunningAverageExp { protected: -- 2.11.4.GIT