www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Decompressing bzip2

reply stunaep <admin pea2nuts.com> writes:
I am trying to use the bzip2 bindings that are available on 
code.dlang.org/packages, but I am having a really hard time using 
it due to the pointers. It needs to be an array once it's 
decompressed.

Here is what I have:
import std.stdio;
import bzlib;

void main(string[] args)
{

    File f = File("./test.bz2");
    ubyte[] data = new ubyte[f.size];
   f.rawRead(data);
    writeln(data);

    ubyte* output;
    uint avail_out;
    bz_stream* stream = new bz_stream();
    stream.avail_out = avail_out;
    stream.next_out = output;

    int init_error = BZ2_bzDecompressInit(stream, 0, 0);
    int bzipresult = BZ2_bzDecompress(stream);

    stream.avail_in = cast(uint) data.length;
    stream.next_in = cast(ubyte*) data;

    bzipresult = BZ2_bzDecompress(stream);
    int read = stream.total_out_lo32;
    BZ2_bzDecompressEnd(stream);
    delete stream;
    writeln(output);
}
It's not working at all so any help would be very much appreciated.
Apr 02 2016
parent reply Thomas Brix Larsen <brix brix-verden.dk> writes:
On Sunday, 3 April 2016 at 02:03:29 UTC, stunaep wrote:
 I am trying to use the bzip2 bindings that are available on 
 code.dlang.org/packages, but I am having a really hard time 
 using it due to the pointers. It needs to be an array once it's 
 decompressed.

 Here is what I have:
import std.stdio;
import bzlib;

void main(string[] args)
{

    File f = File("./test.bz2");
    ubyte[] data = new ubyte[f.size];
   f.rawRead(data);
    writeln(data);

    ubyte* output;
    uint avail_out;
    bz_stream* stream = new bz_stream();
    stream.avail_out = avail_out;
    stream.next_out = output;

    int init_error = BZ2_bzDecompressInit(stream, 0, 0);
    int bzipresult = BZ2_bzDecompress(stream);

    stream.avail_in = cast(uint) data.length;
    stream.next_in = cast(ubyte*) data;

    bzipresult = BZ2_bzDecompress(stream);
    int read = stream.total_out_lo32;
    BZ2_bzDecompressEnd(stream);
    delete stream;
    writeln(output);
}
It's not working at all so any help would be very much appreciated.
You need to allocate the output array: import std.stdio; import bzlib; void main(string[] args) { File f = File("./test.bz2"); auto data = new ubyte[](f.size); f.rawRead(data); writeln(data); auto output = new ubyte[](4096); scope stream = new bz_stream(); stream.avail_out = cast(uint)output.length; stream.next_out = output.ptr; int init_error = BZ2_bzDecompressInit(stream, 0, 0); int bzipresult = BZ2_bzDecompress(stream); stream.avail_in = cast(uint)data.length; stream.next_in = data.ptr; bzipresult = BZ2_bzDecompress(stream); int read = stream.total_out_lo32; BZ2_bzDecompressEnd(stream); writeln(output); }
Apr 04 2016
parent reply stunaep <admin pea2nuts.com> writes:
On Monday, 4 April 2016 at 08:26:07 UTC, Thomas Brix Larsen wrote:
 On Sunday, 3 April 2016 at 02:03:29 UTC, stunaep wrote:
 I am trying to use the bzip2 bindings that are available on 
 code.dlang.org/packages, but I am having a really hard time 
 using it due to the pointers. It needs to be an array once 
 it's decompressed.

 Here is what I have:
import std.stdio;
import bzlib;

void main(string[] args)
{

    File f = File("./test.bz2");
    ubyte[] data = new ubyte[f.size];
   f.rawRead(data);
    writeln(data);

    ubyte* output;
    uint avail_out;
    bz_stream* stream = new bz_stream();
    stream.avail_out = avail_out;
    stream.next_out = output;

    int init_error = BZ2_bzDecompressInit(stream, 0, 0);
    int bzipresult = BZ2_bzDecompress(stream);

    stream.avail_in = cast(uint) data.length;
    stream.next_in = cast(ubyte*) data;

    bzipresult = BZ2_bzDecompress(stream);
    int read = stream.total_out_lo32;
    BZ2_bzDecompressEnd(stream);
    delete stream;
    writeln(output);
}
It's not working at all so any help would be very much appreciated.
You need to allocate the output array: import std.stdio; import bzlib; void main(string[] args) { File f = File("./test.bz2"); auto data = new ubyte[](f.size); f.rawRead(data); writeln(data); auto output = new ubyte[](4096); scope stream = new bz_stream(); stream.avail_out = cast(uint)output.length; stream.next_out = output.ptr; int init_error = BZ2_bzDecompressInit(stream, 0, 0); int bzipresult = BZ2_bzDecompress(stream); stream.avail_in = cast(uint)data.length; stream.next_in = data.ptr; bzipresult = BZ2_bzDecompress(stream); int read = stream.total_out_lo32; BZ2_bzDecompressEnd(stream); writeln(output); }
Can you please explain what the scope keyword does and if there is any benefit to using "new byte[](size)" over "new byte[size]" with a 1D array?
Apr 04 2016
parent reply Mike Parker <aldacron gmail.com> writes:
On Monday, 4 April 2016 at 21:32:10 UTC, stunaep wrote:

 Can you please explain what the scope keyword does and if there
scope was originally intended to be used primarily with classes in order to get deterministic destruction. It ensures the destructor of a class is called when the scope exits, just as with a struct. It's not needed here and shouldn't really be used at all anymore. It has been superseded by std.typecons.scoped [1]. It's not needed here at all, though. bz_stream is a struct, so there's no need to allocate an instance of it: bz_stream stream; Then you can just take its address when passing it to functions: int init_error = BZ2_bzDecompressInit(&stream, 0, 0);
 is any benefit to using
 "new byte[](size)" over "new byte[size]" with a 1D array?
This is the newer and recommended syntax for allocating arrays. The idea is that it helps improve readability because the old syntax, "new byte[size]", brings to mind static array declarations, and that it's consistent with the syntax for allocating other types: new T(arg); [1] https://dlang.org/phobos/std_typecons.html#.scoped
Apr 04 2016
parent reply Charles Hixson via Digitalmars-d-learn writes:
On 04/04/2016 04:38 PM, Mike Parker via Digitalmars-d-learn wrote:
 On Monday, 4 April 2016 at 21:32:10 UTC, stunaep wrote:

 Can you please explain what the scope keyword does and if there
scope was originally intended to be used primarily with classes in order to get deterministic destruction. It ensures the destructor of a class is called when the scope exits, just as with a struct. It's not needed here and shouldn't really be used at all anymore. It has been superseded by std.typecons.scoped [1]. It's not needed here at all, though. bz_stream is a struct, so there's no need to allocate an instance of it:
... Are you asserting that scope is soon to be officially deprecated? I'm finding "shouldn't really be used at all anymore" a bit of a worrying statement, as I much prefer the syntax used by scope. Why shouldn't it "be used at all anymore"?
Apr 05 2016
parent reply Mike Parker <aldacron gmail.com> writes:
On Tuesday, 5 April 2016 at 19:27:20 UTC, Charles Hixson wrote:
 ...
 Are you asserting that scope is soon to be officially 
 deprecated? I'm finding "shouldn't really be used at all 
 anymore" a bit of a worrying statement, as I much prefer the 
 syntax used by scope.  Why shouldn't it "be used at all 
 anymore"?
http://dlang.org/deprecate.html#scope%20for%20allocating%20classes%20on%20the%20stack
Apr 05 2016
parent Charles Hixson via Digitalmars-d-learn writes:
On 04/05/2016 03:33 PM, Mike Parker via Digitalmars-d-learn wrote:
 On Tuesday, 5 April 2016 at 19:27:20 UTC, Charles Hixson wrote:
 ...
 Are you asserting that scope is soon to be officially deprecated? I'm 
 finding "shouldn't really be used at all anymore" a bit of a worrying 
 statement, as I much prefer the syntax used by scope.  Why shouldn't 
 it "be used at all anymore"?
http://dlang.org/deprecate.html#scope%20for%20allocating%20classe %20on%20the%20stack
Thanks. It is the "for other features" that I normally use scope. Mainly, admittedly, for timing the running of the destructor (or analogs thereto, like File.close), but the syntax is not the one being deprecated.
Apr 05 2016