Jump to content

Reading binary data


Poda

Recommended Posts

Hi, guys.  I'm trying to wrap my head around trying to read a header in a binary file in php.  So, far, I have been able to get the data into a string using file_get_contents.  Now, I think I need to use unpack, but it's a bit confusing to me still.  For example, my file starts by having a 1 byte version number, 4 bytes to represent a number of walls, then "number of walls" * 40 bytes for the actual walls.  But, the problem is, the wall itself is a structure composed of various elements to make up that 40 bytes, from which I'll need to pick out a specific area of interest.  I can do this easily in C, but in php. I can't think how to grab the info.  Any ideas?  Maybe just how to read 1 byte, 4 bytes, then "number of walls" * 40 bytes will get me in the right direction.

Link to comment
https://forums.phpfreaks.com/topic/212329-reading-binary-data/
Share on other sites

Hi.  My example isn't 100% accurate to the file.  But, basically, they are .map files.  Here is how they start:

4 bytes-version

4 bytes-position x

4 bytes-position y

4 bytes-position z

2 bytes-angle

2 bytes-current sector

2 bytes-number of sectors

40 bytes * number of sectors-the sectors themselves.

 

I attached an example map file.  Really, it's just the 40 bytes * number of sectors that I can't seem to wrap my head around.  I can see how to read the other stuff with the unpack function.

 

[attachment deleted by admin]

Link to comment
https://forums.phpfreaks.com/topic/212329-reading-binary-data/#findComment-1106317
Share on other sites

Are the bytes signed or unsigned?

 

Edit: Assuming that they're signed, something like this should work:

 

$file = file_get_contents('somefile.map');
$version = current(unpack('i', substr($file, 0, 4)));
$position_x = current(unpack('i', substr($file, 4, 4)));
// ...
$number_of_sectors = current(unpack('s', substr($file, 22, 2)));

for($i = 0;$i < $number_of_sectors;++$i) {
    // read 40 bytes
    // $bytes = substr($file, $i * 40 + 24, 40);
}

Link to comment
https://forums.phpfreaks.com/topic/212329-reading-binary-data/#findComment-1106329
Share on other sites

Ok, here is what I got so far.  I tested with my C++ program and it checks out ok

 

except the number of walls is wrong.  Here is my code

 

<?php

#read the file

$file = "1hk.map";
$fp = fopen ($file, 'rb') or die ("File <i>$file</i> cannot be opened.");

$data = fread ($fp, 500000) or die ("Could not read data from file <i>$file</i>");

#everything up to the number of sectors.

$header_format = 'Lversion/Lposx/Lposy/Lposz/Sang/Scurrentsector/Snumsectors';
$header = unpack ($header_format, $data);

#now, read the number of walls after the sectors by skipping

$sectors = $header['numsectors'] * 40;

$header_format = 'Lversion/Lposx/Lposy/Lposz/Sang/Scurrentsector/Snumsectors/x$sectors/Snumwalls';

# Unpack the header data
$header = unpack ($header_format, $data);

# Display the data stored in $data
print_r ($header);



?>

 

Basically, it doesn't seem to like my skipping of the number of sector bytes.  But, if I give it the literal number of $sectors, it works ok.

Link to comment
https://forums.phpfreaks.com/topic/212329-reading-binary-data/#findComment-1106336
Share on other sites

In other words, in my part where I put

 

$header_format = 'Lversion/Lposx/Lposy/Lposz/Sang/Scurrentsector/Snumsectors/x$sectors/Snumwalls';

 

If I change $sectors to what its literal value is at that point of 14440, it works ok.  I don't get it.  Can you not use variables inside this expression?

Link to comment
https://forums.phpfreaks.com/topic/212329-reading-binary-data/#findComment-1106341
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.