From 05bcd6e31aa2cb08ce64c331daeb40cabc921d94 Mon Sep 17 00:00:00 2001 From: lestcape Date: Sat, 15 May 2021 02:03:50 -0500 Subject: [PATCH 1/6] Fix the return value of the isVeryLong function. --- src/Sav/Writer.php | 2 +- src/Utils.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Sav/Writer.php b/src/Sav/Writer.php index 6668698..585d6c2 100644 --- a/src/Sav/Writer.php +++ b/src/Sav/Writer.php @@ -176,7 +176,7 @@ public function write($data) $this->info[Record\Info\LongVariableNames::SUBTYPE][$shortName] = $var->name; - if (Record\Variable::isVeryLong($var->width) !== 0) { + if (Record\Variable::isVeryLong($var->width) !== false) { $this->info[Record\Info\VeryLongString::SUBTYPE][$shortName] = $var->width; } diff --git a/src/Utils.php b/src/Utils.php index b816708..52d98aa 100644 --- a/src/Utils.php +++ b/src/Utils.php @@ -163,7 +163,7 @@ public static function widthToBytes($width) if (0 === $width) { $bytes = 8; - } elseif (Variable::isVeryLong($width) === 0) { + } elseif (Variable::isVeryLong($width) === false) { $bytes = $width; } else { $chunks = $width / Variable::EFFECTIVE_VLS_CHUNK; @@ -202,7 +202,7 @@ public static function widthToOcts($width) */ public static function widthToSegments($width) { - return Variable::isVeryLong($width) !== 0 ? ceil($width / Variable::EFFECTIVE_VLS_CHUNK) : 1; + return Variable::isVeryLong($width) !== false ? ceil($width / Variable::EFFECTIVE_VLS_CHUNK) : 1; } /** @@ -233,7 +233,7 @@ public static function segmentAllocWidth($width, $segment = 0) $segmentCount = self::widthToSegments($width); // assert($segment < $segmentCount); - if (Variable::isVeryLong($width) === 0) { + if (Variable::isVeryLong($width) === false) { return $width; } From 2f5115f691e08ca6588d7e353207c0657ffaa5da Mon Sep 17 00:00:00 2001 From: lestcape Date: Sat, 15 May 2021 02:18:20 -0500 Subject: [PATCH 2/6] Do not compare a width with an array. --- src/Sav/Writer.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Sav/Writer.php b/src/Sav/Writer.php index 585d6c2..04799b6 100644 --- a/src/Sav/Writer.php +++ b/src/Sav/Writer.php @@ -118,13 +118,13 @@ public function write($data) $variable->print = [ 0, $var->format, - $var->width !== [] ? min($var->width, 255) : 8, + $var->width > 0 ? min($var->width, 255) : 8, $var->decimals, ]; $variable->write = [ 0, $var->format, - $var->width !== [] ? min($var->width, 255) : 8, + $var->width > 0 ? min($var->width, 255) : 8, $var->decimals, ]; From 4ba65729fc2e4bfc7122de74cbadd7becc1b87b2 Mon Sep 17 00:00:00 2001 From: lestcape Date: Sat, 15 May 2021 02:23:09 -0500 Subject: [PATCH 3/6] Ensure that we are using an initialize value for the width. --- src/Sav/Record/Data.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Sav/Record/Data.php b/src/Sav/Record/Data.php index ec2f28c..05284ce 100644 --- a/src/Sav/Record/Data.php +++ b/src/Sav/Record/Data.php @@ -376,7 +376,7 @@ protected function readCaseData(Buffer $buffer, $compressed, $bias, $variables, for ($index = 0; $index < $varCount; $index++) { $var = $variables[$index]; $isNumeric = 0 === $var->width && \SPSS\Sav\Variable::isNumberFormat($var->write[1]); - $width = isset($var->write[2]) ? $var->write[2] : $var->width; + $width = (isset($var->write[2]) && ($var->write[2] !== 0)) ? $var->write[2] : $var->width; // var_dump($var); // exit; @@ -463,7 +463,7 @@ protected function writeCaseData(Buffer $buffer, $row, $compressed, $bias, $vari // $isNumeric = $var->width == 0; $isNumeric = 0 === $var->width && \SPSS\Sav\Variable::isNumberFormat($var->write[1]); - $width = isset($var->write[2]) ? $var->write[2] : $var->width; + $width = (isset($var->write[2]) && ($var->write[2] !== 0)) ? $var->write[2] : $var->width; if ($isNumeric) { if (!$compressed) { From 6503258d9aac99ee167cee5eddb8ed2b77b180f7 Mon Sep 17 00:00:00 2001 From: lestcape Date: Sat, 15 May 2021 02:27:02 -0500 Subject: [PATCH 4/6] Fix the code commnet as for some reason the values are store in a reverse order. --- src/Sav/Record/Variable.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Sav/Record/Variable.php b/src/Sav/Record/Variable.php index bad284d..bab4cc6 100644 --- a/src/Sav/Record/Variable.php +++ b/src/Sav/Record/Variable.php @@ -50,7 +50,7 @@ class Variable extends Record /** * Print format for this variable. - * [decimals, width, format, 0]. + * [0, format, width, decimals]. * * @var array */ @@ -58,7 +58,7 @@ class Variable extends Record /** * Write format for this variable. - * [decimals, width, format, 0]. + * [0, format, width, decimals]. * * @var array */ From e63fd5dde471e1bd9e6d5b360d78bd6ab6fd8d1d Mon Sep 17 00:00:00 2001 From: lestcape Date: Tue, 18 May 2021 15:17:28 -0500 Subject: [PATCH 5/6] The sav ValueLabels are conceived to be once per several variables (indexes), but the library handle it one per variable, what duplicate it. So, what we have is just a list of the current variables where only the last one (the current) that create the valuelabel, is related with it. So, find if we need to convert the string to double there, because the indexes are pointing to the place where the variable will be stored, not to the variable itself. --- src/Sav/Record/ValueLabel.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/Sav/Record/ValueLabel.php b/src/Sav/Record/ValueLabel.php index f58d6c3..d2dad5d 100644 --- a/src/Sav/Record/ValueLabel.php +++ b/src/Sav/Record/ValueLabel.php @@ -89,12 +89,8 @@ public function read(Buffer $buffer) public function write(Buffer $buffer) { - $convertToDouble = false; - $varIndex = reset($this->indexes); - if (false !== $varIndex && isset($this->variables[$varIndex - 1])) { - $varWidth = $this->variables[$varIndex - 1]->width; - $convertToDouble = $varWidth > 0; - } + $var = (count($this->variables) > 0) ? $this->variables[count($this->variables) - 1] : null; + $convertToDouble = (isset($var) && ($var->width > 0)); // Value label record. $buffer->writeInt(self::TYPE); From d9d09609055b8ed0c6a3ac5daab0db83b6fd4eae Mon Sep 17 00:00:00 2001 From: lestcape Date: Tue, 18 May 2021 15:28:00 -0500 Subject: [PATCH 6/6] The LongStringValueLabels is waiting for to have the exact size of it indicate, we can not let it to have a variable size unless the size is the unicode length that is what pack * is doing internally. --- src/Sav/Record/Info/LongStringValueLabels.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Sav/Record/Info/LongStringValueLabels.php b/src/Sav/Record/Info/LongStringValueLabels.php index f3dd83f..e804588 100644 --- a/src/Sav/Record/Info/LongStringValueLabels.php +++ b/src/Sav/Record/Info/LongStringValueLabels.php @@ -46,14 +46,14 @@ public function write(Buffer $buffer) } $width = (int) $data['width']; $localBuffer->writeInt(mb_strlen($varName)); - $localBuffer->writeString($varName); + $localBuffer->writeString($varName, mb_strlen($varName)); $localBuffer->writeInt($width); $localBuffer->writeInt(Utils::is_countable($data['values']) ? \count($data['values']) : 0); foreach ($data['values'] as $value => $label) { $localBuffer->writeInt($width); $localBuffer->writeString($value, $width); $localBuffer->writeInt(mb_strlen($label)); - $localBuffer->writeString($label); + $localBuffer->writeString($label, mb_strlen($label)); } }