Utilities around AppenderNoGCFixed to build error messages easily without GC.
This commit is contained in:
parent
5f27ab26c7
commit
963d197093
|
@ -63,6 +63,63 @@ body
|
||||||
assert(!atStart, "Nothing to parse in parse()");
|
assert(!atStart, "Nothing to parse in parse()");
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Buils a message to a buffer similarly to writef/writefln, but without
|
||||||
|
/// using GC.
|
||||||
|
///
|
||||||
|
/// C snprintf would be better, but it isn't pure.
|
||||||
|
/// formattedWrite isn't completely @nogc yet (although it isn't GC-heavy).
|
||||||
|
///
|
||||||
|
/// The user has to ensure buffer is long enough - an assert checks that we don't run
|
||||||
|
/// out of space. Currently this can only write strings and dchars.
|
||||||
|
char[] printNoGC(S...)(char[] buffer, S args) @safe pure nothrow @nogc
|
||||||
|
{
|
||||||
|
auto appender = appenderNoGC(buffer);
|
||||||
|
|
||||||
|
foreach(arg; args)
|
||||||
|
{
|
||||||
|
alias A = typeof(arg);
|
||||||
|
static if(is(A == char[]) || is(A == string)) { appender.put(arg); }
|
||||||
|
else static if(is(A == dchar)) { appender.putDChar(arg); }
|
||||||
|
else static assert(false, "printNoGC does not support " ~ A.stringof);
|
||||||
|
}
|
||||||
|
|
||||||
|
return appender.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Write a dchar to a character buffer without decoding or using the GC.
|
||||||
|
///
|
||||||
|
/// Params:
|
||||||
|
///
|
||||||
|
/// c = The dchar to write. Will be written as ASCII if it is in ASCII or "<unknown"
|
||||||
|
/// if it's not.
|
||||||
|
/// buf = The buffer to write to. Must be large enough to store "<unknown>"
|
||||||
|
///
|
||||||
|
/// Returns: Slice of buf containing the written dchar.
|
||||||
|
char[] writeDCharTo(dchar c, char[] buf) @safe pure nothrow @nogc
|
||||||
|
{
|
||||||
|
const unknown = "'unknown'";
|
||||||
|
assert(buf.length > unknown.length, "Too small buffer for writeDCharTo");
|
||||||
|
if(c < 128)
|
||||||
|
{
|
||||||
|
buf[0] = buf[2] = '\'';
|
||||||
|
buf[1] = cast(char)c;
|
||||||
|
return buf[0 .. 3];
|
||||||
|
}
|
||||||
|
buf[0 .. unknown.length] = unknown[] ;
|
||||||
|
return buf[0 .. unknown.length];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A UFCS utility function to write a dchar to an AppenderNoGCFixed using writeDCharTo.
|
||||||
|
void putDChar(ref AppenderNoGCFixed!(char[], char) appender, dchar c)
|
||||||
|
@safe pure nothrow @nogc
|
||||||
|
{
|
||||||
|
char[16] dcharBuf;
|
||||||
|
appender.put(c.writeDCharTo(dcharBuf));
|
||||||
|
}
|
||||||
|
|
||||||
/// Convenience function that returns an $(D AppenderNoGCFixed!A) using with $(D array)
|
/// Convenience function that returns an $(D AppenderNoGCFixed!A) using with $(D array)
|
||||||
/// for storage.
|
/// for storage.
|
||||||
AppenderNoGCFixed!(E[]) appenderNoGC(A : E[], E)(A array)
|
AppenderNoGCFixed!(E[]) appenderNoGC(A : E[], E)(A array)
|
||||||
|
@ -187,3 +244,13 @@ struct AppenderNoGCFixed(A : T[], T)
|
||||||
@disable void clear();
|
@disable void clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
char[256] buffer;
|
||||||
|
auto appender = appenderNoGC(buffer[]);
|
||||||
|
appender.put("found unsupported escape character: ");
|
||||||
|
appender.putDChar('a');
|
||||||
|
appender.putDChar('á');
|
||||||
|
assert(appender.data == "found unsupported escape character: 'a''unknown'");
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue