Skip to content

Instantly share code, notes, and snippets.

@theoremoon
Created May 6, 2018 14:30
Show Gist options
  • Select an option

  • Save theoremoon/c498707efd72a3b18cedcde92cb47054 to your computer and use it in GitHub Desktop.

Select an option

Save theoremoon/c498707efd72a3b18cedcde92cb47054 to your computer and use it in GitHub Desktop.
import std.typecons;
mixin template BinParser()
{
class Nope {}
class A(string[] names, V...) {
auto read(string name, T)() {
return new A!(names ~ name, V, tuple!(T, Nope, Nope, Nope)(T.init, null, null, null));
}
auto should(string name, T, T should_be)() {
return new A!(names ~ name, V, tuple!(T, T, Nope, Nope)(T.init, should_be, null, null));
}
auto parser(string name, T...)()
{
return new A!(names ~ name, V, tuple!(Nope, Nope, Tuple!(T), Nope)(null, null, Tuple!(T).init, null));
}
auto parse(T)(File f, ref T t) {
auto p = f.tell();
static foreach (i, v; V) {
static if (! is(v.Types[1] == Nope)) {
// should
import std.algorithm;
parseType!(v.Types[0], names[i])(f, t);
if (mixin("t."~names[i]) != v[1]) {
f.seek(p);
return false;
}
} else static if (! is(v.Types[2] == Nope)) {
// parser
auto p2 = f.tell;
bool succeeded = false;
static foreach (i; 0..v.Types[2].Types.length) {
auto parser2 = mixin("new "~v.Types[2].Types[i].stringof);
// ↑ここがだめ。ここがだめなんですよ
}
if (! succeeded) {
return false;
}
} else static if (! is(v.Types[3] == Nope)) {
} else static if (! is(v.Types[0] == Nope)){
parseType!(v.Types[0], names[i])(f, t);
}
}
return true;
}
bool parseType(U, string name, T)(File f, ref T t)
{
import std.bitmanip:bitread=read,bitwrite=write;
import std.traits;
import std.range;
static if (isArray!(U) && ElementType!(U).sizeof == ubyte.sizeof) {
f.rawRead(mixin("t."~name));
return true;
} else {
static if (isArray!(U)) {
// array types
alias E = ElementType!(U);
ubyte[] buf = new ubyte[](U.length * E.sizeof);
} else {
ubyte[] buf = new ubyte[](U.sizeof);
}
f.rawRead(buf);
mixin("t."~name) = buf.bitread!U();
return true;
}
}
}
}
auto read(string name, T)()
{
mixin BinParser;
return new A!([name], tuple!(T, Nope, Nope, Nope)(T.init, null, null, null));
}
auto should(string name, T, T should_be)()
{
mixin BinParser;
return new A!([name], tuple!(T, T, Nope, Nope)(T.init, should_be, null, null));
}
struct Wave {
byte[4] riff;
uint size;
ubyte[4] wave;
Fmt fmt;
}
struct Fmt {
byte[4] tag;
uint size;
}
import std.stdio;
void main()
{
Wave wave;
auto fmtp = should!("tag", typeof(Fmt.tag), cast(typeof(Fmt.tag))"fmt ")
.read!("size", uint);
auto p = should!("riff", typeof(Wave.riff), cast(byte[4])"RIFF")
.read!("size", uint)
.should!("wave", ubyte[4], cast(ubyte[4])"WAVE")
.parser!("fmt", typeof(fmtp), typeof(fmtp))
;
auto r = p.parse!(Wave)(File("./Argument.wav", "r"), wave);
writeln(r);
writeln(wave.riff);
writeln(wave.size);
writeln(wave.wave);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment