0)) { $int = 0xFFFF8000 | $int; } // Convert the value return (int)self::dword2signedInt($int); } /** * bytes2unsignedInt * * The function converts array of 2 or 4 bytes to unsigned integer. * The return value depends on order of the input bytes (endianning). * * @param array $values * @param bool $bigEndian * @return int|float */ public static function bytes2unsignedInt($values, $bigEndian = 0) { $data = array(); $int = 0; // Set the array to correct form $data = self::checkData($values); // Combine bytes $int = self::combineBytes($data, $bigEndian); // Convert the value return self::dword2unsignedInt($int); } /** * bytes2string * * The function converts an values array to the string. The function detects * the end of the string by 0x00 character as defined by string standards. * * @param array $values * @param bool $bigEndian * @return string */ public static function bytes2string($values, $bigEndian = 0) { // Prepare string variable $str = ""; // Parse the received data word array for ($i = 0; $i < count($values); $i += 2) { if ($bigEndian) { if ($values[$i] != 0) { $str .= chr($values[$i]); } else { break; } if ($values[$i + 1] != 0) { $str .= chr($values[$i + 1]); } else { break; } } else { if ($values[$i + 1] != 0) { $str .= chr($values[$i + 1]); } else { break; } if ($values[$i] != 0) { $str .= chr($values[$i]); } else { break; } } } // return string return $str; } /** * real2float * * This function converts a value in IEC-1131 REAL single precision form to float. * * For more see [{@link http://en.wikipedia.org/wiki/Single_precision Single precision on Wiki}] or * [{@link http://de.php.net/manual/en/function.base-convert.php PHP base_convert function commentary}, Todd Stokes * @ Georgia Tech 21-Nov-2007] or * [{@link http://www.php.net/manual/en/function.pack.php PHP pack/unpack functionality}] * * @param int $value in IEC REAL data type to be converted * @return float float value */ private static function real2float($value) { // get unsigned long $ulong = pack("L", $value); // set float $float = unpack("f", $ulong); return $float[1]; } /** * dword2signedInt * * Switch double word to signed integer * * @param int $value * @return int */ private static function dword2signedInt($value) { if ((0x80000000 & $value) != 0) { return -(0x7FFFFFFF & ~$value) - 1; } else { return (0x7FFFFFFF & $value); } } /** * dword2signedInt * * Switch double word to unsigned integer * * @param int $value * @return int|float */ private static function dword2unsignedInt($value) { if ((0x80000000 & $value) != 0) { return ((float)(0x7FFFFFFF & $value)) + 2147483648; } else { return (int)(0x7FFFFFFF & $value); } } /** * checkData * * Check if the data variable is array, and check if the values are numeric * * @param int[] $data * @return int * @throws Exception */ private static function checkData($data) { // Check the data if (!is_array($data) || count($data) < 2 || count($data) > 4 || count($data) == 3 ) { throw new Exception('The input data should be an array of 2 or 4 bytes.'); } // Fill the rest of array by zeroes if (count($data) == 2) { $data[2] = 0; $data[3] = 0; } // Check the values to be number if (!is_numeric($data[0]) || !is_numeric($data[1]) || !is_numeric($data[2]) || !is_numeric($data[3]) ) { throw new Exception('Data are not numeric or the array keys are not indexed by 0,1,2 and 3'); } return $data; } /** * combineBytes * * Combine bytes together * * @param int $data * @param bool $bigEndian * @return int */ private static function combineBytes($data, $bigEndian) { $value = 0; // Combine bytes if ($bigEndian == 0) { $value = (($data[3] & 0xFF) << 16) | (($data[2] & 0xFF) << 24) | (($data[1] & 0xFF)) | (($data[0] & 0xFF) << 8); } else { $value = (($data[3] & 0xFF) << 24) | (($data[2] & 0xFF) << 16) | (($data[1] & 0xFF) << 8) | (($data[0] & 0xFF)); } return $value; } }