Poda Posted September 2, 2010 Share Posted September 2, 2010 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. Quote Link to comment https://forums.phpfreaks.com/topic/212329-reading-binary-data/ Share on other sites More sharing options...
RussellReal Posted September 2, 2010 Share Posted September 2, 2010 show us an example file? Quote Link to comment https://forums.phpfreaks.com/topic/212329-reading-binary-data/#findComment-1106315 Share on other sites More sharing options...
Poda Posted September 2, 2010 Author Share Posted September 2, 2010 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] Quote Link to comment https://forums.phpfreaks.com/topic/212329-reading-binary-data/#findComment-1106317 Share on other sites More sharing options...
RussellReal Posted September 2, 2010 Share Posted September 2, 2010 lol I'm trying to unpack it, but I'm having no luck maybe someone here whose done more work with unpack can get it to work you can probably use substr to manually get the bytes you need Quote Link to comment https://forums.phpfreaks.com/topic/212329-reading-binary-data/#findComment-1106324 Share on other sites More sharing options...
Alex Posted September 2, 2010 Share Posted September 2, 2010 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); } Quote Link to comment https://forums.phpfreaks.com/topic/212329-reading-binary-data/#findComment-1106329 Share on other sites More sharing options...
Poda Posted September 2, 2010 Author Share Posted September 2, 2010 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. Quote Link to comment https://forums.phpfreaks.com/topic/212329-reading-binary-data/#findComment-1106336 Share on other sites More sharing options...
Poda Posted September 2, 2010 Author Share Posted September 2, 2010 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? Quote Link to comment https://forums.phpfreaks.com/topic/212329-reading-binary-data/#findComment-1106341 Share on other sites More sharing options...
Poda Posted September 2, 2010 Author Share Posted September 2, 2010 Your substr thing works, dude. Thanks. Quote Link to comment https://forums.phpfreaks.com/topic/212329-reading-binary-data/#findComment-1106342 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.