WIP: #25-fix-64bit-values #26

Draft
Little Fluffy Clouds wants to merge 15 commits from lfclouds/baza:#25-fix-64bit-values into stable
2 changed files with 40 additions and 10 deletions
Showing only changes of commit 13b27b3fac - Show all commits

View File

@ -227,6 +227,7 @@ class database
* Pack the record values
*
* @param record $record The record
* @const integer ARCH PHP architecture
*
* @return string Packed values
*/
@ -246,10 +247,20 @@ class database
// Packing the value and writing into the buffer of packed values
$packed .= pack($column->type->value . $column->length, $value);
} else if (ARCH === 64 &&
($column->type === type::integer ||
$column->type === type::integer_unsigned)
) {
}
/**
* PHP builtin pack() ignores 64-bit integer values
* found on 64-bit PHP distributions
* @see https://www.php.net/manual/en/function.pack.php#109382
*
* In case of integer type on 64-bit PHP distributions
* we got to splice 64-bit integer into two separate longs
* next to each other in binary representation
*/
else if (ARCH === 64 &&
($column->type === type::integer ||
$column->type === type::integer_unsigned))
{
// Initialize variables for left and right masks of the 64-bit variable
$left = 0xffffffff00000000;
$right = 0x00000000ffffffff;
@ -259,7 +270,7 @@ class database
// Bitwise and the value with the right mask to get the second half
$r = $record->values()[$column->name] & $right;
// Pack into 64bit binary value
// Pack into 64bit binary value with two longs
$packed .= pack('NN', $l, $r);
} else {
// Other types
@ -279,6 +290,7 @@ class database
* Unpack binary values and implement them as a `record` instance
*
* @param array $binaries Binary values in the same order as the columns
* @const integer ARCH PHP architecture
*
* @return record The unpacked record from binary values
*/
@ -307,12 +319,22 @@ class database
// Writing into the buffer of read values
$unpacked[] = $encoded;
} else if (ARCH === 64 &&
($column->type === type::integer ||
$column->type === type::integer_unsigned)
) {
// Unpacking the integer
}
/**
* PHP builtin pack() ignores 64-bit integer values
* found on 64-bit PHP distributions
* @see https://www.php.net/manual/en/function.pack.php#109382
*
* In case of integer type on 64-bit PHP distributions
* we got to reconstruct previosly spliced integer value
*/
else if (ARCH === 64 &&
($column->type === type::integer ||
$column->type === type::integer_unsigned))
{
// Unpacking the integer values into array of two longs
$value = unpack('N2', $binary ?? "\0");
// Reconstructing original integer value
$unpacked[] = $value[1] << 32 | $value[2];
} else {
// Other types

View File

@ -62,6 +62,14 @@ enum type: string
{
// Exit (success)
/**
* PHP builtin pack() ignores 64-bit integer values
* found on 64-bit PHP distributions
* @see https://www.php.net/manual/en/function.pack.php#109382
*
* Architecture-specific size should always be returned
*/
// If type is (unsigned) integer, return size of integer
return (strtoupper($this->value) === 'I')
? PHP_INT_SIZE