bit reading instead of byte reading ...

maccatalan

Registered
Hi.

I'm trying to read a file bit per bit with Cocoa but it seems that byte per byte access is the minimum available way to proceed (NSFileHandle -> readDataOfLength).

Do you know any way to read a file bit per bit ?
Thank you,
Pierre.

NB: for me a byte is a string of 8 bits ... in french we say "octet" and "bit", it's more obvious. ;)
 
Why don't you just read byte and then do your scanning in the byte you read.

P.S. why do you need to read bit by bit?
 
-> Why don't you just read byte and then do your scanning in the byte you read.

Because I don't know how to do. The smallest type I know is char : one byte long. But once I'm there ... how to step into ?
It sounds like you know how to do it, so if you could just tell me how to "scan" a byte ... ;)

-> P.S. why do you need to read bit by bit?

Because I'm trying to create some kind of filesystem emulation. And as I defiened my FS theorically I have a non byte regular structure, some information being two bits long, some other 39 bits long ... This doesn't fit with the byte - 8 bits by 8 bits - configuration, I would have liked to read my file (my pseudo hard-disk in this case) bit by bit. ;)

NB: The best would be reading bit by bit instead of scaning byte by byte as you can understand it ...

Thank you for helping me,
Pierre.
 
I'm not sure if there is a better way to do this, but you could:

Use the bit shift operator on the byte (call it inByte) to shift the bits so that the bit we want is in the least significant place:

For example, if we want the second bit:

inByte = 13; (00001101)
shifted = inByte >> 2; (= 3 (00000011))

The >> operator shifts all the bits rightwards the amount you specify (2 here.)

we can then do this to find out if that bit was set or not:

if (shifted & 1)
printf("bit is set");
else
printf("bit is not set");

this is in C. I think in java you might have to say

if ((shifted & 1) > 0) .... etc

Why do I use 1? 1 is equivalent to
00000001 in binary. The bitwise operator "&" will return a byte with the bits that match up so

00000011
&
00000001
=
00000001

if the bit is on we get one otherwise we get zero. You could do this with a little function:

function getBitValue(unsigned char inByte, int bitPosition) {

if ((inByte >> bitPosition) & 1) return true;

return false;

}

or forget the shift all together and do:

function getBitValue(unsigned char inByte, unsigned char bitValue) {

if (inByte & bitValue) return true;
return false;

}

so the bitValue is 4 if you want the 3rd bit or 128 for the 8th bit.

Do a search on bitwise operators for more information.
 
thanks, merci
for a such clear answer/post.

it will be very usefull to me. ;)

have fun
(and welcome to this forum, I noticed that this post was your first one)
 
Another thing you could do is define a struct full of bit fields, and read your data as that struct, like so:

Code:
struct pseudo_fs
{
    unsigned int two_bits:2,
                 fifteen_bits:15,
                 fifteen_more_bits:15,
                 and_then_three_remaining_bits:3;
};
//here we cast a pointer to some bytes into a pointer to this struct
struct pseudo_fs * pseudopointer = [someDataIJustRead bytes];
//just access the bitfields like so
unsigned int fifteenbitvalue = pseudopointer->fifteen_bits;
This may cause problems when moving your data files from big-endian to little-endian systems and vice versa though.

Yet another method involves defining macros for extracting bit fields. This is used a bit in writing disassemblers and the like.

Code:
//say bits 7 through 19 of a 32 bit int are interesting to us...
#define INTERESTING_BITS(x) ((x & 0x01FFF000) >> 12)

This generally requires that you know how to express a bit mask in hexadecimal. Just take the bits 4 at a time, and each 4 bits is a single hex digit.
 
Thank you for your answers.

but tell me, as far as I understand it (or at least, as far as it seems to be) it is impossible to scan data bit by bit, we must first consider a whole byte and then analyse it ... this will be very usefull, but what is the data length is not proportional to 8 ?

thank you,
Pierre
 
Generally, modern computers have enough memory that you don't need to go pack several data fields into a byte. If you need 29 bits of data, just use a 32 bit int. The extra three bits aren't much of a loss. A long long can hold up to 64 bits. If you need more than 64 bits, you generally will use some polynomial code.

You can't really scan data bit by bit since the CPU itself operates on bytes. Extracting bitfields using masks and shifts is pretty much your only option. In fact, the PowerPC has specialized instructions for extracting bitfields, and gcc will gladly optimize using them.
 
Originally posted by anarchie
In fact, the PowerPC has specialized instructions for extracting bitfields, and gcc will gladly optimize using them.

Just a little note about that : I'm still compiling KDE ('still' because I'm doing it since this morning ; and thank you Fink) and I was glad to note some "7400" specific options and optimizations for gcc ;) :D

... understanding your last post (with the byte processing by CPU) I will then resign to work with masks and modulos. ;) Thank you all. :D
 
Originally posted by maccatalan
Thank you for your answers.

but tell me, as far as I understand it (or at least, as far as it seems to be) it is impossible to scan data bit by bit, we must first consider a whole byte and then analyse it ... this will be very usefull, but what is the data length is not proportional to 8 ?

thank you,
Pierre

As far as I know, no modern CPU provides instructions that will let you move bit-by-bit through memory. Bitfields and masks are as close as you get.
 
Back
Top