6

I have a binary file that is really a stack of files, the format is:

lengh_of_subfile,subfile

length_of_subfile is a 64-bit integer. I can read the long no problem but when I try to create a buffer for the subfile I get compile errors saying it cannot be read at compile time. What am I missing? I've written an identical extraction tool in erlang, PHP and C#... D is throwing me for a loop.

void main(string args[]) {
    Stream file = new BufferedFile(args[1], FileMode.In);
    int counter = 0;
    while(file.position < file.size) {
        ulong len;
        file.read(len);
        ubyte[len] ogg;
        file.read(ogg);
        string outname = getcwd() ~ "/" ~ to!string(counter) ~ ".ogg";
        Stream oggout = new BufferedFile(outname, FileMode.OutNew);
        oggout.write(ogg);
        writefln("Creating file " ~ to!string(counter) ~ ".ogg");
        counter++;
    }   
}
Ry-
  • 218,210
  • 55
  • 464
  • 476
b0redom
  • 387
  • 2
  • 11
  • 2
    You need a [dynamic array](http://stackoverflow.com/questions/8363728/d-dynamic-array-initialization-stride-and-the-index-operation). (I have no idea how, though, because I don't program in D) – Ry- Dec 31 '11 at 22:01

3 Answers3

7

Instead of

        ubyte[len] ogg;

write

        ubyte[] ogg = new ubyte[len];
ruakh
  • 175,680
  • 26
  • 273
  • 307
2

slice off what you want to fill

ubyte[1024*8] ogg;
ogg=ogg[0..len]
file.read(ogg);

or use a loop to do the copying (as a 2^64 byte array wont fit in memory)

ubyte[1024*16] ogg;
while(len>0 && (int read=file.read(ogg[0..$>len?len:$]))!=0){
    oggout.write(ogg[0..read]);
    len-=read;//len is the amount still to be read
}

side note writeln("Creating file ",counter, ".ogg"); is more efficient than concat then write (the java way) because it doesn't create useless strings (and creating the format string at runtime is asking for a error sooner or later on the first % you don't account for)

ratchet freak
  • 47,288
  • 5
  • 68
  • 106
1

You could use a array with dynamic length or just use new to create a new ubyte array:

new ubyte[len]
Mat
  • 202,337
  • 40
  • 393
  • 406
dav1d
  • 5,917
  • 1
  • 33
  • 52