Jump to page: 1 2
Thread overview
Reading and converting binary file 2 bits at a time
Aug 27, 2015
Andrew Brown
Aug 27, 2015
Rikki Cattermole
Aug 27, 2015
rumbu
Aug 27, 2015
Andrew Brown
Aug 27, 2015
Olivier Pisano
Aug 27, 2015
Gary Willoughby
Aug 27, 2015
Mike James
Aug 27, 2015
Gary Willoughby
Aug 29, 2015
Marc Schütz
Aug 29, 2015
Mike James
Aug 29, 2015
Gary Willoughby
Aug 30, 2015
anonymous
Aug 30, 2015
Gary Willoughby
Aug 31, 2015
Andrew Brown
Aug 31, 2015
Adam D. Ruppe
August 27, 2015
Hi,

I need to read a binary file, and then process it two bits at a time. But I'm a little stuck on the first step. So far I have:

import std.file;
import std.stdio;

void main(){
  auto f = std.file.read("binaryfile");
  auto g = cast(bool[])	f;
  writeln(g);
}

but all the values of g then are just true, could you tell me what I'm doing wrong? I've also looked at the bitmanip module, I couldn't get it to help, but is that the direction I should be looking?

Thanks very much

Andrew
August 27, 2015
On 27/08/15 9:00 PM, Andrew Brown wrote:
> Hi,
>
> I need to read a binary file, and then process it two bits at a time.
> But I'm a little stuck on the first step. So far I have:
>
> import std.file;
> import std.stdio;
>
> void main(){
>    auto f = std.file.read("binaryfile");
>    auto g = cast(bool[])    f;
>    writeln(g);
> }
>
> but all the values of g then are just true, could you tell me what I'm
> doing wrong? I've also looked at the bitmanip module, I couldn't get it
> to help, but is that the direction I should be looking?
>
> Thanks very much
>
> Andrew

You do not use the std.file to prefix call read.
The bool type is one byte in size. A value of 0 is false, anything else is true. But commonly defined as 1.

So if you want to read only one bit you will need to use e.g. bit shifts and bitwise and operator.

I believe bitsSet may help you.
http://dlang.org/phobos/std_bitmanip.html#.bitsSet
August 27, 2015
On Thursday, 27 August 2015 at 09:00:02 UTC, Andrew Brown wrote:
> Hi,
>
> I need to read a binary file, and then process it two bits at a time. But I'm a little stuck on the first step. So far I have:
>
> import std.file;
> import std.stdio;
>
> void main(){
>   auto f = std.file.read("binaryfile");
>   auto g = cast(bool[])	f;
>   writeln(g);
> }
>
> but all the values of g then are just true, could you tell me what I'm doing wrong? I've also looked at the bitmanip module, I couldn't get it to help, but is that the direction I should be looking?
>
> Thanks very much
>
> Andrew

auto bytes = cast(ubyte[])read("binaryfile");
foreach(b; bytes)
{
    writeln((b & 0xC0) >> 6);  //bits 7, 6
    writeln((b & 0x30) >> 4);  //bits 5, 4
    writeln((b & 0x0C) >> 2);  //bits 3, 2
    writeln((b & 0x03));       //bits 1, 0
}



August 27, 2015
On Thursday, 27 August 2015 at 09:26:55 UTC, rumbu wrote:
> On Thursday, 27 August 2015 at 09:00:02 UTC, Andrew Brown wrote:
>> Hi,
>>
>> I need to read a binary file, and then process it two bits at a time. But I'm a little stuck on the first step. So far I have:
>>
>> import std.file;
>> import std.stdio;
>>
>> void main(){
>>   auto f = std.file.read("binaryfile");
>>   auto g = cast(bool[])	f;
>>   writeln(g);
>> }
>>
>> but all the values of g then are just true, could you tell me what I'm doing wrong? I've also looked at the bitmanip module, I couldn't get it to help, but is that the direction I should be looking?
>>
>> Thanks very much
>>
>> Andrew
>
> auto bytes = cast(ubyte[])read("binaryfile");
> foreach(b; bytes)
> {
>     writeln((b & 0xC0) >> 6);  //bits 7, 6
>     writeln((b & 0x30) >> 4);  //bits 5, 4
>     writeln((b & 0x0C) >> 2);  //bits 3, 2
>     writeln((b & 0x03));       //bits 1, 0
> }

That's lovely, thank you. One quick question, the length of the file is not a multiple of the length of ubyte,  but the cast still seems to work. Do you know how it converts a truncated final section?

Thanks again

Andrew
August 27, 2015
On Thursday, 27 August 2015 at 09:38:52 UTC, Andrew Brown wrote:

>
> That's lovely, thank you. One quick question, the length of the file is not a multiple of the length of ubyte,  but the cast still seems to work. Do you know how it converts a truncated final section?
>
> Thanks again
>
> Andrew

Well, since the length of ubyte is 1, the length of the file is necessarily a multiple of the length of ubyte.
August 27, 2015
On Thursday, 27 August 2015 at 09:38:52 UTC, Andrew Brown wrote:
> On Thursday, 27 August 2015 at 09:26:55 UTC, rumbu wrote:
>> On Thursday, 27 August 2015 at 09:00:02 UTC, Andrew Brown wrote:
>>> Hi,
>>>
>>> I need to read a binary file, and then process it two bits at a time. But I'm a little stuck on the first step. So far I have:
>>>
>>> import std.file;
>>> import std.stdio;
>>>
>>> void main(){
>>>   auto f = std.file.read("binaryfile");
>>>   auto g = cast(bool[])	f;
>>>   writeln(g);
>>> }
>>>
>>> but all the values of g then are just true, could you tell me what I'm doing wrong? I've also looked at the bitmanip module, I couldn't get it to help, but is that the direction I should be looking?
>>>
>>> Thanks very much
>>>
>>> Andrew
>>
>> auto bytes = cast(ubyte[])read("binaryfile");
>> foreach(b; bytes)
>> {
>>     writeln((b & 0xC0) >> 6);  //bits 7, 6
>>     writeln((b & 0x30) >> 4);  //bits 5, 4
>>     writeln((b & 0x0C) >> 2);  //bits 3, 2
>>     writeln((b & 0x03));       //bits 1, 0
>> }
>
> That's lovely, thank you. One quick question, the length of the file is not a multiple of the length of ubyte,  but the cast still seems to work. Do you know how it converts a truncated final section?
>
> Thanks again
>
> Andrew

You can also avoid the bitshifts to make the code a little more readable like this:

import std.stdio;
import std.bitmanip;

struct Crumbs
{
	mixin(bitfields!(
		uint, "one", 2,
		uint, "two", 2,
		uint, "three", 2,
		uint, "four", 2
	));
}

void main(string[] args)
{
	ubyte[] buffer = [123, 12, 126, 244, 35];

	foreach (octet; buffer)
	{
		auto crumbs = Crumbs(octet);
		ubyte* representation = cast(ubyte*)&crumbs;

		writefln("Crumb:       %08b", *representation);
		writefln("Crumb one:   %s", crumbs.one);
		writefln("Crumb two:   %s", crumbs.two);
		writefln("Crumb three: %s", crumbs.three);
		writefln("Crumb four:  %s", crumbs.four);
		writeln("---------------------");
	}
}

Now you can read a crumb at a time.
August 27, 2015
On Thursday, 27 August 2015 at 09:00:02 UTC, Andrew Brown wrote:
> Hi,
>
> I need to read a binary file, and then process it two bits at a time. But I'm a little stuck on the first step. So far I have:
>
> import std.file;
> import std.stdio;
>
> void main(){
>   auto f = std.file.read("binaryfile");
>   auto g = cast(bool[])	f;
>   writeln(g);
> }
>
> but all the values of g then are just true, could you tell me what I'm doing wrong? I've also looked at the bitmanip module, I couldn't get it to help, but is that the direction I should be looking?
>
> Thanks very much
>
> Andrew

How about...

module main;

import std.bitmanip;
import std.stdio;

struct Crumbs {
    @property ref ubyte whole() {
        return m_whole;
    }

    union {
        private ubyte m_whole;
        mixin(bitfields!(
            ubyte, "one",   2,
            ubyte, "two",   2,
            ubyte, "three", 2,
            ubyte, "four",  2
        ));
    }
}

void main(string[] argv)
{
    ubyte[] buffer = [123, 12, 126, 244, 35];
    Crumbs cmb;

    foreach (octet; buffer) {
        cmb.whole = octet;

        writefln("Crumb:       %08b", octet);
        writefln("Crumb one:   %s", cmb.one);
        writefln("Crumb two:   %s", cmb.two);
        writefln("Crumb three: %s", cmb.three);
        writefln("Crumb four:  %s", cmb.four);
    }
}


Regards, Mike.
August 27, 2015
On Thursday, 27 August 2015 at 12:40:07 UTC, Mike James wrote:
> How about...

A lot nicer. :)
August 29, 2015
Just cast to `Crumbs[]` directly:

    import std.bitmanip;
    import std.stdio;
    import std.file;

    struct Crumbs {
        mixin(bitfields!(
            ubyte, "one",   2,
            ubyte, "two",   2,
            ubyte, "three", 2,
            ubyte, "four",  2
        ));
    }

    void main(string[] argv)
    {
        auto raw = read("binaryfile");
        auto buffer = cast(Crumbs[]) raw;

        foreach (cmb; buffer) {
            writefln("Crumb one:   %s", cmb.one);
            writefln("Crumb two:   %s", cmb.two);
            writefln("Crumb three: %s", cmb.three);
            writefln("Crumb four:  %s", cmb.four);
        }
    }
August 29, 2015
On Saturday, 29 August 2015 at 20:15:53 UTC, Marc Schütz wrote:
> Just cast to `Crumbs[]` directly:
>
>     import std.bitmanip;
>     import std.stdio;
>     import std.file;
>
>     struct Crumbs {
>         mixin(bitfields!(
>             ubyte, "one",   2,
>             ubyte, "two",   2,
>             ubyte, "three", 2,
>             ubyte, "four",  2
>         ));
>     }
>
>     void main(string[] argv)
>     {
>         auto raw = read("binaryfile");
>         auto buffer = cast(Crumbs[]) raw;
>
>         foreach (cmb; buffer) {
>             writefln("Crumb one:   %s", cmb.one);
>             writefln("Crumb two:   %s", cmb.two);
>             writefln("Crumb three: %s", cmb.three);
>             writefln("Crumb four:  %s", cmb.four);
>         }
>     }

I like that :-)

« First   ‹ Prev
1 2