diff --git a/apps/calculation/calculation.h b/apps/calculation/calculation.h index bbf037ddc..e7b81c2bc 100644 --- a/apps/calculation/calculation.h +++ b/apps/calculation/calculation.h @@ -17,9 +17,9 @@ public: ExpressionLayout * evaluationLayout(); void setContent(const char * c, Context * context); bool isEmpty(); + constexpr static int k_maximalExpressionTextLength = 255; private: - constexpr static int k_bodyLength = 255; - char m_text[k_bodyLength]; + char m_text[k_maximalExpressionTextLength]; Expression * m_expression; ExpressionLayout * m_layout; Expression * m_evaluation; diff --git a/apps/calculation/history_controller.cpp b/apps/calculation/history_controller.cpp index 358dc67b4..0c6a54340 100644 --- a/apps/calculation/history_controller.cpp +++ b/apps/calculation/history_controller.cpp @@ -1,6 +1,5 @@ #include "history_controller.h" #include "app.h" -#include "../constant.h" #include namespace Calculation { @@ -47,7 +46,8 @@ bool HistoryController::handleEvent(Ion::Events::Event event) { if (subviewType == HistoryViewCell::SubviewType::PrettyPrint) { editController->setTextBody(calculation->text()); } else { - char * resultText = calculation->evaluation()->text(); + char resultText[Calculation::k_maximalExpressionTextLength]; + calculation->evaluation()->writeTextInBuffer(resultText, Calculation::k_maximalExpressionTextLength); editController->setTextBody(resultText); } m_selectableTableView.deselectTable(); @@ -64,7 +64,8 @@ bool HistoryController::handleEvent(Ion::Events::Event event) { if (subviewType == HistoryViewCell::SubviewType::PrettyPrint) { newCalculation = *calculation; } else { - char * resultText = calculation->evaluation()->text(); + char resultText[Calculation::k_maximalExpressionTextLength]; + calculation->evaluation()->writeTextInBuffer(resultText, Calculation::k_maximalExpressionTextLength); /* TODO: this will work when we will parse float */ //App * calculationApp = (App *)app(); //newCalculation.setContent(resultText, calculationApp->evaluateContext()); diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index fc883a646..0ac65eeee 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -69,11 +69,7 @@ class Expression { * Do not forget to delete the new expression to avoid leaking. */ virtual Expression * evaluate(Context& context) const = 0; virtual float approximate(Context& context) const = 0; - char * text(); - protected: - virtual void setText(); - constexpr static int k_maxLength = 255; - char m_text[k_maxLength]; + virtual int writeTextInBuffer(char * buffer, int bufferSize); private: bool sequentialOperandsIdentity(const Expression * e) const; bool commutativeOperandsIdentity(const Expression * e) const; diff --git a/poincare/include/poincare/float.h b/poincare/include/poincare/float.h index b25988cee..7a2b5d589 100644 --- a/poincare/include/poincare/float.h +++ b/poincare/include/poincare/float.h @@ -20,10 +20,10 @@ public: }; void setNumberOfDigitsInMantissa(int numberOfDigits); /* The parameter 'DisplayMode' refers to the way to display float 'scientific' or - * 'decimal'. The code only handles 'scientific' so far. */ - void convertFloatToText(char * buffer, int bufferSize, int numberOfDigitsInMantissa, DisplayMode mode = DisplayMode::Scientific) const; -protected: - void setText() override; + * 'decimal'. The code only handles 'scientific' so far. If the buffer size is + * small, the function does nothing. */ + int convertFloatToText(char * buffer, int bufferSize, int numberOfDigitsInMantissa, DisplayMode mode = DisplayMode::Scientific) const; + int writeTextInBuffer(char * buffer, int bufferSize) override; private: constexpr static int k_maxBufferLength = 14; /* This function prints the int i in the buffer with a '.' at the position diff --git a/poincare/include/poincare/matrix.h b/poincare/include/poincare/matrix.h index 3bb62ec4e..84da1a2eb 100644 --- a/poincare/include/poincare/matrix.h +++ b/poincare/include/poincare/matrix.h @@ -21,8 +21,9 @@ class Matrix : public Expression { int numberOfOperands, bool cloneOperands = true) const override; int numberOfRows() const; int numberOfColumns() const; - protected: - void setText() override; + /* If the buffer is too small, the function fills the buffer until reaching + * buffer size */ + int writeTextInBuffer(char * buffer, int bufferSize) override; private: MatrixData * m_matrixData; static Integer * defaultExpression(); diff --git a/poincare/src/expression.cpp b/poincare/src/expression.cpp index fb312c8e0..ab2a3757b 100644 --- a/poincare/src/expression.cpp +++ b/poincare/src/expression.cpp @@ -171,10 +171,6 @@ bool Expression::isCommutative() const { return false; } -void Expression::setText() { -} - -char * Expression::text() { - setText(); - return m_text; +int Expression::writeTextInBuffer(char * buffer, int bufferSize) { + return 0; } diff --git a/poincare/src/float.cpp b/poincare/src/float.cpp index 90a869610..95b2d906e 100644 --- a/poincare/src/float.cpp +++ b/poincare/src/float.cpp @@ -49,8 +49,8 @@ bool Float::valueEquals(const Expression * e) const { return m_float == ((Float *)e)->m_float; } -void Float::setText() { - convertFloatToText(m_text, k_maxBufferLength, m_numberOfDigitsInMantissa); +int Float::writeTextInBuffer(char * buffer, int bufferSize) { + return convertFloatToText(buffer, bufferSize, m_numberOfDigitsInMantissa); } void Float::printBase10IntegerWithDecimalMarker(char * buffer, int bufferSize, int i, int decimalMarkerPosition) { @@ -78,12 +78,15 @@ void Float::printBase10IntegerWithDecimalMarker(char * buffer, int bufferSize, } while (endChar >= startChar); } -void Float::convertFloatToText(char * buffer, int bufferSize, +int Float::convertFloatToText(char * buffer, int bufferSize, int numberOfDigitsInMantissa, DisplayMode mode) const { /* We here assert that the buffer is long enough to display with the right * number of digits in the mantissa. If numberOfDigitsInMantissa = 7, the * worst case has the form -1.999999e-38 (7+6+1 char). */ - assert(bufferSize > 6 + numberOfDigitsInMantissa); + if (bufferSize <= 6 + numberOfDigitsInMantissa) { + buffer[0] = 0; + return 0; + } if (isinf(m_float)) { buffer[0] = m_float > 0 ? '+' : '-'; @@ -91,7 +94,7 @@ void Float::convertFloatToText(char * buffer, int bufferSize, buffer[2] = 'n'; buffer[3] = 'f'; buffer[4] = 0; - return; + return 5; } if (isnan(m_float)) { @@ -99,7 +102,7 @@ void Float::convertFloatToText(char * buffer, int bufferSize, buffer[1] = 'a'; buffer[2] = 'N'; buffer[3] = 0; - return; + return 4; } float logBase10 = m_float != 0.0f ? log10f(fabsf(m_float)) : 0; @@ -154,4 +157,5 @@ void Float::convertFloatToText(char * buffer, int bufferSize, buffer[availableCharsForMantissaWithSign] = 'e'; printBase10IntegerWithDecimalMarker(buffer+availableCharsForMantissaWithSign+1, numberOfCharExponent, exponentInBase10, -1); buffer[availableCharsForMantissaWithSign+1+numberOfCharExponent] = 0; + return (availableCharsForMantissaWithSign+1+numberOfCharExponent); } diff --git a/poincare/src/matrix.cpp b/poincare/src/matrix.cpp index d44e66780..976606b25 100644 --- a/poincare/src/matrix.cpp +++ b/poincare/src/matrix.cpp @@ -79,22 +79,48 @@ int Matrix::numberOfColumns() const { return m_matrixData->numberOfColumns(); } -void Matrix::setText() { +int Matrix::writeTextInBuffer(char * buffer, int bufferSize) { + buffer[bufferSize] = 0; int currentChar = 0; - m_text[currentChar++] = '['; - for (int i = 0; i < m_matrixData->numberOfRows(); i++) { - m_text[currentChar++] = '['; - char * operandText = m_matrixData->operands()[i*m_matrixData->numberOfColumns()]->text(); - strlcpy(m_text+currentChar, operandText, strlen(operandText)+1); - for (int j = 1; j < numberOfColumns(); j++) { - currentChar += strlen(operandText); - m_text[currentChar++] = ','; - operandText = m_matrixData->operands()[i*m_matrixData->numberOfColumns()+j]->text(); - strlcpy(m_text+currentChar, operandText, strlen(operandText)+1); - } - currentChar += strlen(operandText); - m_text[currentChar++] = ']'; + if (currentChar >= bufferSize) { + return 0; } - m_text[currentChar++] = ']'; - m_text[currentChar] = 0; + buffer[currentChar++] = '['; + if (currentChar >= bufferSize) { + return currentChar; + } + for (int i = 0; i < m_matrixData->numberOfRows(); i++) { + buffer[currentChar++] = '['; + if (currentChar >= bufferSize) { + return currentChar; + } + currentChar += m_matrixData->operands()[i*m_matrixData->numberOfColumns()]->writeTextInBuffer(buffer+currentChar, bufferSize-currentChar); + if (currentChar >= bufferSize) { + return currentChar; + } + for (int j = 1; j < numberOfColumns(); j++) { + buffer[currentChar++] = ','; + if (currentChar >= bufferSize) { + return currentChar; + } + currentChar += m_matrixData->operands()[i*m_matrixData->numberOfColumns()+j]->writeTextInBuffer(buffer+currentChar, bufferSize-currentChar); + if (currentChar >= bufferSize) { + return currentChar; + } + } + currentChar = strlen(buffer); + if (currentChar >= bufferSize) { + return currentChar; + } + buffer[currentChar++] = ']'; + if (currentChar >= bufferSize) { + return currentChar; + } + } + buffer[currentChar++] = ']'; + if (currentChar >= bufferSize) { + return currentChar; + } + buffer[currentChar] = 0; + return currentChar; }