I wrote this program in C and also in erlang
To practice I tried to rewrite in D. A friend also wrote it in D but wrote it differently
The steps are simple. Pseudocode:
While not end of file:
X = Read ulong from file and covert to little endian
Y = Read X bytes from file into ubyte array
subtract 1 from each byte in Y
save Y as an ogg file
My D attempt:
import std.file, std.stdio, std.bitmanip, std.conv, core.stdc.stdio : fread;
void main(){
auto file = File("./sounds.pk", "r+");
auto fp = file.getFP();
ulong x;
int i,cnt;
while(fread(&x, 8, 1, fp)){
writeln("start");
x=swapEndian(x);
writeln(x," ",cnt++,"\n");
ubyte[] arr= new ubyte[x];
fread(&arr, x, 1, fp);
for(i=0;i<x;i++) arr[i]-=1;
std.file.write("/home/fold/wak_oggs/"~to!string(cnt)~".ogg",arr);
}
}
It seems I can't just use fread on arr. sizeof is 16 and it gives segmentation fault when I get to the subtracting part. I can't auto alloc a static array, or at least I don't know how. I also can't seem to use malloc because it gives me errors when I try to cast the void* when I loop through the bytes. How would you write this, or, what could I do better?
Hold your pen/pencil properly. Place your index finger on the top of the pen, about one inch away from the writing point. Place your thumb on the side of the pen. Support the bottom of the pen against the side of your middle finger. Let your ring and pinky fingers hang comfortably and naturally.
again why do you expect to be able to read in the entire chunk into a single array (which size in bytes fits in a 64 bit long (possibly more that several petabytes) I made that comment in the other question as well
use a loop to copy the contents
writeln("start");
x=swapEndian(x);
writeln(x," ",cnt++,"\n");
ubyte[1024*8] arr=void; //the buffer
//initialized with void to avoid auto init (or declare above the for)
ubyte b; //temp buff
File out = File("/home/fold/wak_oggs/"~to!string(cnt)~".ogg", "wb");
b=fp.rawRead(arr[0..x%$]);//make it so the buffer can be fully filled each loop
foreach(ref e;b)e-=1;//the subtract 1 each byte loop
out.rawWrite(b);
x-=b.length;
while(x>0 && (b=fp.rawRead(arr[])).length>0){//loop until x becomes 0
foreach(ref e;b)e-=1;
out.rawWrite(b);
x-=b.length;
}
I'm using rawRead
and rawWrite
to read and write
arr
is not a pointer, and does not convert to a pointer like it does in C and C++.
If you want a pointer to the start of the array, use arr.ptr
.
To allocate a static array, you use:
ubyte[N] arr;
However, N
must be a compile time constant (just like in C and C++), so it may not be much use here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With