Some minor refactoring (#1923)

* Some minor refactoring
This commit is contained in:
Mark Baker 2021-03-14 23:53:13 +01:00 committed by GitHub
parent 30c880b5e6
commit c920a77649
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 67 additions and 80 deletions

View File

@ -3345,18 +3345,15 @@ class Calculation
} }
/** /**
* @param string $cellReference
* @param mixed $cellValue * @param mixed $cellValue
*
* @return bool
*/ */
public function getValueFromCache($cellReference, &$cellValue) public function getValueFromCache(string $cellReference, &$cellValue): bool
{ {
$this->debugLog->writeDebugLog("Testing cache value for cell {$cellReference}");
// Is calculation cacheing enabled? // Is calculation cacheing enabled?
// Is the value present in calculation cache? // If so, is the required value present in calculation cache?
$this->debugLog->writeDebugLog('Testing cache value for cell ', $cellReference);
if (($this->calculationCacheEnabled) && (isset($this->calculationCache[$cellReference]))) { if (($this->calculationCacheEnabled) && (isset($this->calculationCache[$cellReference]))) {
$this->debugLog->writeDebugLog('Retrieving value for cell ', $cellReference, ' from cache'); $this->debugLog->writeDebugLog("Retrieving value for cell {$cellReference} from cache");
// Return the cached result // Return the cached result
$cellValue = $this->calculationCache[$cellReference]; $cellValue = $this->calculationCache[$cellReference];
@ -3418,7 +3415,7 @@ class Calculation
if (($cellID !== null) && ($this->getValueFromCache($wsCellReference, $cellValue))) { if (($cellID !== null) && ($this->getValueFromCache($wsCellReference, $cellValue))) {
return $cellValue; return $cellValue;
} }
$this->debugLog->writeDebugLog('Evaluating formula for cell ', $wsCellReference); $this->debugLog->writeDebugLog("Evaluating formula for cell {$wsCellReference}");
if (($wsTitle[0] !== "\x00") && ($this->cyclicReferenceStack->onStack($wsCellReference))) { if (($wsTitle[0] !== "\x00") && ($this->cyclicReferenceStack->onStack($wsCellReference))) {
if ($this->cyclicFormulaCount <= 0) { if ($this->cyclicFormulaCount <= 0) {
@ -3440,7 +3437,7 @@ class Calculation
} }
} }
$this->debugLog->writeDebugLog('Formula for cell ', $wsCellReference, ' is ', $formula); $this->debugLog->writeDebugLog("Formula for cell {$wsCellReference} is {$formula}");
// Parse the formula onto the token stack and calculate the value // Parse the formula onto the token stack and calculate the value
$this->cyclicReferenceStack->push($wsCellReference); $this->cyclicReferenceStack->push($wsCellReference);
@ -4805,6 +4802,53 @@ class Calculation
return true; return true;
} }
/**
* @param null|string $cellID
* @param mixed $operand1
* @param mixed $operand2
* @param string $operation
*
* @return array
*/
private function executeArrayComparison($cellID, $operand1, $operand2, $operation, Stack &$stack, bool $recursingArrays)
{
$result = [];
if (!is_array($operand2)) {
// Operand 1 is an array, Operand 2 is a scalar
foreach ($operand1 as $x => $operandData) {
$this->debugLog->writeDebugLog('Evaluating Comparison ', $this->showValue($operandData), ' ', $operation, ' ', $this->showValue($operand2));
$this->executeBinaryComparisonOperation($cellID, $operandData, $operand2, $operation, $stack);
$r = $stack->pop();
$result[$x] = $r['value'];
}
} elseif (!is_array($operand1)) {
// Operand 1 is a scalar, Operand 2 is an array
foreach ($operand2 as $x => $operandData) {
$this->debugLog->writeDebugLog('Evaluating Comparison ', $this->showValue($operand1), ' ', $operation, ' ', $this->showValue($operandData));
$this->executeBinaryComparisonOperation($cellID, $operand1, $operandData, $operation, $stack);
$r = $stack->pop();
$result[$x] = $r['value'];
}
} else {
// Operand 1 and Operand 2 are both arrays
if (!$recursingArrays) {
self::checkMatrixOperands($operand1, $operand2, 2);
}
foreach ($operand1 as $x => $operandData) {
$this->debugLog->writeDebugLog('Evaluating Comparison ', $this->showValue($operandData), ' ', $operation, ' ', $this->showValue($operand2[$x]));
$this->executeBinaryComparisonOperation($cellID, $operandData, $operand2[$x], $operation, $stack, true);
$r = $stack->pop();
$result[$x] = $r['value'];
}
}
// Log the result details
$this->debugLog->writeDebugLog('Comparison Evaluation Result is ', $this->showTypeDetails($result));
// And push the result onto the stack
$stack->push('Array', $result);
return $result;
}
/** /**
* @param null|string $cellID * @param null|string $cellID
* @param mixed $operand1 * @param mixed $operand1
@ -4818,38 +4862,7 @@ class Calculation
{ {
// If we're dealing with matrix operations, we want a matrix result // If we're dealing with matrix operations, we want a matrix result
if ((is_array($operand1)) || (is_array($operand2))) { if ((is_array($operand1)) || (is_array($operand2))) {
$result = []; return $this->executeArrayComparison($cellID, $operand1, $operand2, $operation, $stack, $recursingArrays);
if ((is_array($operand1)) && (!is_array($operand2))) {
foreach ($operand1 as $x => $operandData) {
$this->debugLog->writeDebugLog('Evaluating Comparison ', $this->showValue($operandData), ' ', $operation, ' ', $this->showValue($operand2));
$this->executeBinaryComparisonOperation($cellID, $operandData, $operand2, $operation, $stack);
$r = $stack->pop();
$result[$x] = $r['value'];
}
} elseif ((!is_array($operand1)) && (is_array($operand2))) {
foreach ($operand2 as $x => $operandData) {
$this->debugLog->writeDebugLog('Evaluating Comparison ', $this->showValue($operand1), ' ', $operation, ' ', $this->showValue($operandData));
$this->executeBinaryComparisonOperation($cellID, $operand1, $operandData, $operation, $stack);
$r = $stack->pop();
$result[$x] = $r['value'];
}
} else {
if (!$recursingArrays) {
self::checkMatrixOperands($operand1, $operand2, 2);
}
foreach ($operand1 as $x => $operandData) {
$this->debugLog->writeDebugLog('Evaluating Comparison ', $this->showValue($operandData), ' ', $operation, ' ', $this->showValue($operand2[$x]));
$this->executeBinaryComparisonOperation($cellID, $operandData, $operand2[$x], $operation, $stack, true);
$r = $stack->pop();
$result[$x] = $r['value'];
}
}
// Log the result details
$this->debugLog->writeDebugLog('Comparison Evaluation Result is ', $this->showTypeDetails($result));
// And push the result onto the stack
$stack->push('Array', $result);
return $result;
} }
// Simple validate the two operands if they are string values // Simple validate the two operands if they are string values
@ -4863,10 +4876,10 @@ class Calculation
// Use case insensitive comparaison if not OpenOffice mode // Use case insensitive comparaison if not OpenOffice mode
if (Functions::getCompatibilityMode() != Functions::COMPATIBILITY_OPENOFFICE) { if (Functions::getCompatibilityMode() != Functions::COMPATIBILITY_OPENOFFICE) {
if (is_string($operand1)) { if (is_string($operand1)) {
$operand1 = strtoupper($operand1); $operand1 = Shared\StringHelper::strToUpper($operand1);
} }
if (is_string($operand2)) { if (is_string($operand2)) {
$operand2 = strtoupper($operand2); $operand2 = Shared\StringHelper::strToUpper($operand2);
} }
} }

View File

@ -83,11 +83,11 @@ class Conditional
$targetValue = Functions::flattenSingleValue($arguments[0]); $targetValue = Functions::flattenSingleValue($arguments[0]);
$argc = count($arguments) - 1; $argc = count($arguments) - 1;
$switchCount = floor($argc / 2); $switchCount = floor($argc / 2);
$switchSatisfied = false;
$hasDefaultClause = $argc % 2 !== 0; $hasDefaultClause = $argc % 2 !== 0;
$defaultClause = $argc % 2 === 0 ? null : $arguments[count($arguments) - 1]; $defaultClause = $argc % 2 === 0 ? null : $arguments[$argc];
if ($switchCount) { $switchSatisfied = false;
if ($switchCount > 0) {
for ($index = 0; $index < $switchCount; ++$index) { for ($index = 0; $index < $switchCount; ++$index) {
if ($targetValue == $arguments[$index * 2 + 1]) { if ($targetValue == $arguments[$index * 2 + 1]) {
$result = $arguments[$index * 2 + 2]; $result = $arguments[$index * 2 + 2];
@ -98,7 +98,7 @@ class Conditional
} }
} }
if (!$switchSatisfied) { if ($switchSatisfied !== true) {
$result = $hasDefaultClause ? $defaultClause : Functions::NA(); $result = $hasDefaultClause ? $defaultClause : Functions::NA();
} }
} }
@ -161,12 +161,14 @@ class Conditional
*/ */
public static function IFS(...$arguments) public static function IFS(...$arguments)
{ {
if (count($arguments) % 2 != 0) { $argumentCount = count($arguments);
if ($argumentCount % 2 != 0) {
return Functions::NA(); return Functions::NA();
} }
// We use instance of Exception as a falseValue in order to prevent string collision with value in cell // We use instance of Exception as a falseValue in order to prevent string collision with value in cell
$falseValueException = new Exception(); $falseValueException = new Exception();
for ($i = 0; $i < count($arguments); $i += 2) { for ($i = 0; $i < $argumentCount; $i += 2) {
$testValue = ($arguments[$i] === null) ? '' : Functions::flattenSingleValue($arguments[$i]); $testValue = ($arguments[$i] === null) ? '' : Functions::flattenSingleValue($arguments[$i]);
$returnIfTrue = ($arguments[$i + 1] === null) ? '' : Functions::flattenSingleValue($arguments[$i + 1]); $returnIfTrue = ($arguments[$i + 1] === null) ? '' : Functions::flattenSingleValue($arguments[$i + 1]);
$result = self::statementIf($testValue, $returnIfTrue, $falseValueException); $result = self::statementIf($testValue, $returnIfTrue, $falseValueException);

View File

@ -339,7 +339,8 @@ abstract class Coordinate
private static function processRangeSetOperators(array $operators, array $cells): array private static function processRangeSetOperators(array $operators, array $cells): array
{ {
for ($offset = 0; $offset < count($operators); ++$offset) { $operatorCount = count($operators);
for ($offset = 0; $offset < $operatorCount; ++$offset) {
$operator = $operators[$offset]; $operator = $operators[$offset];
if ($operator !== ' ') { if ($operator !== ' ') {
continue; continue;
@ -350,6 +351,7 @@ abstract class Coordinate
$operators = array_values($operators); $operators = array_values($operators);
$cells = array_values($cells); $cells = array_values($cells);
--$offset; --$offset;
--$operatorCount;
} }
return $cells; return $cells;

View File

@ -506,49 +506,33 @@ class Properties
switch ($propertyType) { switch ($propertyType) {
case 'empty': // Empty case 'empty': // Empty
return ''; return '';
break;
case 'null': // Null case 'null': // Null
return null; return null;
break;
case 'i1': // 1-Byte Signed Integer case 'i1': // 1-Byte Signed Integer
case 'i2': // 2-Byte Signed Integer case 'i2': // 2-Byte Signed Integer
case 'i4': // 4-Byte Signed Integer case 'i4': // 4-Byte Signed Integer
case 'i8': // 8-Byte Signed Integer case 'i8': // 8-Byte Signed Integer
case 'int': // Integer case 'int': // Integer
return (int) $propertyValue; return (int) $propertyValue;
break;
case 'ui1': // 1-Byte Unsigned Integer case 'ui1': // 1-Byte Unsigned Integer
case 'ui2': // 2-Byte Unsigned Integer case 'ui2': // 2-Byte Unsigned Integer
case 'ui4': // 4-Byte Unsigned Integer case 'ui4': // 4-Byte Unsigned Integer
case 'ui8': // 8-Byte Unsigned Integer case 'ui8': // 8-Byte Unsigned Integer
case 'uint': // Unsigned Integer case 'uint': // Unsigned Integer
return abs((int) $propertyValue); return abs((int) $propertyValue);
break;
case 'r4': // 4-Byte Real Number case 'r4': // 4-Byte Real Number
case 'r8': // 8-Byte Real Number case 'r8': // 8-Byte Real Number
case 'decimal': // Decimal case 'decimal': // Decimal
return (float) $propertyValue; return (float) $propertyValue;
break;
case 'lpstr': // LPSTR case 'lpstr': // LPSTR
case 'lpwstr': // LPWSTR case 'lpwstr': // LPWSTR
case 'bstr': // Basic String case 'bstr': // Basic String
return $propertyValue; return $propertyValue;
break;
case 'date': // Date and Time case 'date': // Date and Time
case 'filetime': // File Time case 'filetime': // File Time
return strtotime($propertyValue); return strtotime($propertyValue);
break;
case 'bool': // Boolean case 'bool': // Boolean
return $propertyValue == 'true'; return $propertyValue == 'true';
break;
case 'cy': // Currency case 'cy': // Currency
case 'error': // Error Status Code case 'error': // Error Status Code
case 'vector': // Vector case 'vector': // Vector
@ -563,8 +547,6 @@ class Properties
case 'clsid': // Class ID case 'clsid': // Class ID
case 'cf': // Clipboard Data case 'cf': // Clipboard Data
return $propertyValue; return $propertyValue;
break;
} }
return $propertyValue; return $propertyValue;
@ -584,31 +566,21 @@ class Properties
case 'ui8': // 8-Byte Unsigned Integer case 'ui8': // 8-Byte Unsigned Integer
case 'uint': // Unsigned Integer case 'uint': // Unsigned Integer
return self::PROPERTY_TYPE_INTEGER; return self::PROPERTY_TYPE_INTEGER;
break;
case 'r4': // 4-Byte Real Number case 'r4': // 4-Byte Real Number
case 'r8': // 8-Byte Real Number case 'r8': // 8-Byte Real Number
case 'decimal': // Decimal case 'decimal': // Decimal
return self::PROPERTY_TYPE_FLOAT; return self::PROPERTY_TYPE_FLOAT;
break;
case 'empty': // Empty case 'empty': // Empty
case 'null': // Null case 'null': // Null
case 'lpstr': // LPSTR case 'lpstr': // LPSTR
case 'lpwstr': // LPWSTR case 'lpwstr': // LPWSTR
case 'bstr': // Basic String case 'bstr': // Basic String
return self::PROPERTY_TYPE_STRING; return self::PROPERTY_TYPE_STRING;
break;
case 'date': // Date and Time case 'date': // Date and Time
case 'filetime': // File Time case 'filetime': // File Time
return self::PROPERTY_TYPE_DATE; return self::PROPERTY_TYPE_DATE;
break;
case 'bool': // Boolean case 'bool': // Boolean
return self::PROPERTY_TYPE_BOOLEAN; return self::PROPERTY_TYPE_BOOLEAN;
break;
case 'cy': // Currency case 'cy': // Currency
case 'error': // Error Status Code case 'error': // Error Status Code
case 'vector': // Vector case 'vector': // Vector
@ -623,8 +595,6 @@ class Properties
case 'clsid': // Class ID case 'clsid': // Class ID
case 'cf': // Clipboard Data case 'cf': // Clipboard Data
return self::PROPERTY_TYPE_UNKNOWN; return self::PROPERTY_TYPE_UNKNOWN;
break;
} }
return self::PROPERTY_TYPE_UNKNOWN; return self::PROPERTY_TYPE_UNKNOWN;