Voting

: max(four, nine)?
(Example: nine)

The Note You're Voting On

jjfoerch at earthlink dot net
20 years ago
I had a situation where I had to unpack a file filled with little-endian order double-floats in a way that would work on either little-endian or big-endian machines. PHP doesn't have a formatting code that will change the byte order of doubles, so I wrote this workaround.

<?php
/*The following code is a workaround for php's unpack function
which does not have the capability of unpacking double precision
floats that were packed in the opposite byte order of the current
machine.
*/
function big_endian_unpack ($format, $data) {
$ar = unpack ($format, $data);
$vals = array_values ($ar);
$f = explode ('/', $format);
$i = 0;
foreach (
$f as $f_k => $f_v) {
$repeater = intval (substr ($f_v, 1));
if (
$repeater == 0) $repeater = 1;
if (
$f_v{1} == '*')
{
$repeater = count ($ar) - $i;
}
if (
$f_v{0} != 'd') { $i += $repeater; continue; }
$j = $i + $repeater;
for (
$a = $i; $a < $j; ++$a)
{
$p = pack ('d',$vals[$i]);
$p = strrev ($p);
list (
$vals[$i]) = array_values (unpack ('d1d', $p));
++
$i;
}
}
$a = 0;
foreach (
$ar as $ar_k => $ar_v) {
$ar[$ar_k] = $vals[$a];
++
$a;
}
return
$ar;
}

list (
$endiantest) = array_values (unpack ('L1L', pack ('V',1)));
if (
$endiantest != 1) define ('BIG_ENDIAN_MACHINE',1);
if (
defined ('BIG_ENDIAN_MACHINE')) $unpack_workaround = 'big_endian_unpack';
else
$unpack_workaround = 'unpack';
?>

This workaround is used like this:

<?php

function foo() {
global
$unpack_workaround;
$bar = $unpack_workaround('N7N/V2V/d8d',$my_data);
//...
}

?>

On a little endian machine, $unpack_workaround will simply point to the function unpack. On a big endian machine, it will call the workaround function.

Note, this solution only works for doubles. In my project I had no need to check for single precision floats.

<< Back to user notes page

To Top