[poincare] Fix serializations

They should return the number of written chars
This commit is contained in:
Léa Saviot
2019-08-06 16:14:04 +02:00
committed by Émilie Feral
parent c2e1210ca2
commit 49a508ea62
18 changed files with 64 additions and 66 deletions

View File

@@ -82,6 +82,7 @@ public:
virtual void didAddChildAtIndex(int newNumberOfChildren) {}
// Serialization
// Return the number of chars written, without the null-terminating char.
virtual int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { assert(false); return 0; }
/* When serializing, we turn a tree into a string. In order not to lose
* structure information, we sometimes need to add system parentheses (that

View File

@@ -14,6 +14,8 @@
namespace Poincare {
static inline int minInt(int x, int y) { return x < y ? x : y; }
ConstantNode::ConstantNode(const char * newName, int length) : SymbolAbstractNode() {
strlcpy(const_cast<char*>(name()), newName, length+1);
}
@@ -66,7 +68,7 @@ int ConstantNode::serialize(char * buffer, int bufferSize, Preferences::PrintFlo
if (bufferSize == 0) {
return -1;
}
return strlcpy(buffer, m_name, bufferSize);
return minInt(strlcpy(buffer, m_name, bufferSize), bufferSize - 1);
}
template<typename T>

View File

@@ -109,11 +109,11 @@ int DecimalNode::convertToText(char * buffer, int bufferSize, Preferences::Print
return -1;
}
buffer[bufferSize-1] = 0;
int currentChar = 0;
if (currentChar >= bufferSize-1) { return bufferSize-1; }
if (bufferSize == 1) {
return 0;
}
if (unsignedMantissa().isZero()) {
currentChar += SerializationHelper::CodePoint(buffer + currentChar, bufferSize - currentChar, '0'); // This already writes the null terminating char
return currentChar;
return SerializationHelper::CodePoint(buffer, bufferSize, '0'); // This already writes the null terminating char
}
int exponent = m_exponent;
char tempBuffer[PrintFloat::k_numberOfStoredSignificantDigits+1];
@@ -135,6 +135,7 @@ int DecimalNode::convertToText(char * buffer, int bufferSize, Preferences::Print
* to 2000. To avoid printing 2.000, we removeZeroAtTheEnd here. */
removeZeroAtTheEnd(&m);
}
int currentChar = 0;
if (m_negative) {
currentChar += SerializationHelper::CodePoint(buffer + currentChar, bufferSize - currentChar, '-');
if (currentChar >= bufferSize-1) { return bufferSize-1; }

View File

@@ -77,8 +77,7 @@ int FactorialNode::serialize(char * buffer, int bufferSize, Preferences::PrintFl
if ((numberOfChar < 0) || (numberOfChar >= bufferSize-1)) {
return numberOfChar;
}
numberOfChar += SerializationHelper::CodePoint(&buffer[numberOfChar], bufferSize-numberOfChar, '!');
buffer[numberOfChar] = 0;
numberOfChar += SerializationHelper::CodePoint(buffer+numberOfChar, bufferSize-numberOfChar, '!');
return numberOfChar;
}

View File

@@ -123,8 +123,7 @@ int FractionLayoutNode::serialize(char * buffer, int bufferSize, Preferences::Pr
return -1;
}
buffer[bufferSize-1] = 0;
int numberOfChar = 0;
if (numberOfChar >= bufferSize-1) { return bufferSize-1;}
if (bufferSize == 1) { return 0;}
/* Add System parenthesis to detect omitted multiplication:
* 2
@@ -133,8 +132,8 @@ int FractionLayoutNode::serialize(char * buffer, int bufferSize, Preferences::Pr
*/
// Add system parenthesis
numberOfChar+= SerializationHelper::CodePoint(buffer + numberOfChar, bufferSize - numberOfChar, UCodePointLeftSystemParenthesis);
if (numberOfChar >= bufferSize-1) { return bufferSize-1;}
int numberOfChar = SerializationHelper::CodePoint(buffer, bufferSize, UCodePointLeftSystemParenthesis);
if (numberOfChar >= bufferSize-1) { return bufferSize-1; }
// Write the content of the fraction
numberOfChar += SerializationHelper::Infix(this, buffer+numberOfChar, bufferSize-numberOfChar, floatDisplayMode, numberOfSignificantDigits, "/");
@@ -142,9 +141,6 @@ int FractionLayoutNode::serialize(char * buffer, int bufferSize, Preferences::Pr
// Add system parenthesis
numberOfChar+= SerializationHelper::CodePoint(buffer + numberOfChar, bufferSize - numberOfChar, UCodePointRightSystemParenthesis);
if (numberOfChar >= bufferSize-1) { return bufferSize-1;}
buffer[numberOfChar] = 0;
return numberOfChar;
}

View File

@@ -174,32 +174,32 @@ int Integer::serialize(char * buffer, int bufferSize) const {
abs.setNegative(false);
IntegerDivision d = udiv(abs, base);
int size = 0;
int length = 0;
if (isZero()) {
size += SerializationHelper::CodePoint(buffer + size, bufferSize - size, '0');
length += SerializationHelper::CodePoint(buffer + length, bufferSize - length, '0');
} else if (isNegative()) {
size += SerializationHelper::CodePoint(buffer + size, bufferSize - size, '-');
length += SerializationHelper::CodePoint(buffer + length, bufferSize - length, '-');
}
while (!(d.remainder.isZero() &&
d.quotient.isZero())) {
char c = char_from_digit(d.remainder.isZero() ? 0 : d.remainder.digit(0));
if (size >= bufferSize-1) {
if (length >= bufferSize-1) {
return PrintFloat::convertFloatToText<float>(NAN, buffer, bufferSize, PrintFloat::k_numberOfStoredSignificantDigits, Preferences::PrintFloatMode::Decimal);
}
size += SerializationHelper::CodePoint(buffer + size, bufferSize - size, c);
length += SerializationHelper::CodePoint(buffer + length, bufferSize - length, c);
d = udiv(d.quotient, base);
}
assert(size <= bufferSize - 1);
buffer[size] = 0;
assert(length <= bufferSize - 1);
buffer[length] = 0;
// Flip the string
for (int i = m_negative, j=size-1 ; i < j ; i++, j--) {
for (int i = m_negative, j=length-1 ; i < j ; i++, j--) {
char c = buffer[i];
buffer[i] = buffer[j];
buffer[j] = c;
}
return size;
return length;
}
// Layout

View File

@@ -202,7 +202,6 @@ int IntegralLayoutNode::serialize(char * buffer, int bufferSize, Preferences::Pr
// Write the closing system parenthesis
numberOfChar += SerializationHelper::CodePoint(buffer + numberOfChar, bufferSize - numberOfChar, UCodePointRightSystemParenthesis);
buffer[numberOfChar] = 0;
return numberOfChar;
}

View File

@@ -17,6 +17,8 @@
namespace Poincare {
static inline int minInt(int x, int y) { return x < y ? x : y; }
void MatrixNode::didAddChildAtIndex(int newNumberOfChildren) {
setNumberOfRows(1);
setNumberOfColumns(newNumberOfChildren);
@@ -41,11 +43,10 @@ int MatrixNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloat
return -1;
}
buffer[bufferSize-1] = 0;
int currentChar = 0;
if (currentChar >= bufferSize-1) {
if (bufferSize == 1) {
return 0;
}
currentChar += SerializationHelper::CodePoint(buffer + currentChar, bufferSize - currentChar, '[');
int currentChar = SerializationHelper::CodePoint(buffer, bufferSize, '[');
if (currentChar >= bufferSize-1) {
return currentChar;
}
@@ -78,11 +79,7 @@ int MatrixNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloat
}
}
currentChar += SerializationHelper::CodePoint(buffer + currentChar, bufferSize - currentChar, ']');
if (currentChar >= bufferSize-1) {
return currentChar;
}
buffer[currentChar] = 0;
return currentChar;
return minInt(currentChar, bufferSize-1);
}
template<typename T>

View File

@@ -7,6 +7,8 @@
namespace Poincare {
static inline int minInt(int x, int y) { return x < y ? x : y; }
// MatrixLayoutNode
void MatrixLayoutNode::addGreySquares() {
@@ -98,10 +100,9 @@ int MatrixLayoutNode::serialize(char * buffer, int bufferSize, Preferences::Prin
}
buffer[bufferSize-1] = 0;
if (bufferSize == 1) {
return 1;
return 0;
}
int numberOfChar = 0;
numberOfChar += SerializationHelper::CodePoint(buffer + numberOfChar, bufferSize - numberOfChar, '[');
int numberOfChar = SerializationHelper::CodePoint(buffer, bufferSize, '[');
if (numberOfChar >= bufferSize-1) { return bufferSize-1;}
int maxRowIndex = hasGreySquares() ? m_numberOfRows - 1 : m_numberOfRows;
@@ -117,9 +118,7 @@ int MatrixLayoutNode::serialize(char * buffer, int bufferSize, Preferences::Prin
if (numberOfChar >= bufferSize-1) { return bufferSize-1; }
}
numberOfChar += SerializationHelper::CodePoint(buffer + numberOfChar, bufferSize - numberOfChar, ']');
if (numberOfChar >= bufferSize-1) { return bufferSize-1; }
buffer[numberOfChar] = 0;
return numberOfChar;
return minInt(numberOfChar, bufferSize-1);
}
// Protected

View File

@@ -56,14 +56,12 @@ int OppositeNode::serialize(char * buffer, int bufferSize, Preferences::PrintFlo
return -1;
}
buffer[bufferSize-1] = 0;
int numberOfChar = 0;
if (bufferSize == 1) { return 0; }
numberOfChar += SerializationHelper::CodePoint(buffer + numberOfChar, bufferSize - numberOfChar, '-');
int numberOfChar = SerializationHelper::CodePoint(buffer, bufferSize, '-');
if (numberOfChar >= bufferSize - 1) {
return bufferSize - 1;
}
numberOfChar += childAtIndex(0)->serialize(buffer+numberOfChar, bufferSize-numberOfChar, floatDisplayMode, numberOfSignificantDigits);
buffer[numberOfChar] = 0;
return numberOfChar;
}

View File

@@ -59,6 +59,13 @@ void PrintFloat::Long::DivisionByTen(const Long & longToDivide, Long * quotient,
}
int PrintFloat::Long::serialize(char * buffer, int bufferSize) const {
if (bufferSize == 0) {
return -1;
}
buffer[bufferSize-1] = 0;
if (bufferSize == 1) {
return 0;
}
int numberOfChars = m_negative ? 1 : 0; // 1 for the minus sign char
if (m_digits[0] != 0) {
numberOfChars += PrintInt::Left(m_digits[0], buffer + numberOfChars, bufferSize - numberOfChars - 1);

View File

@@ -72,10 +72,10 @@ int RationalNode::serialize(char * buffer, int bufferSize, Preferences::PrintFlo
}
buffer[bufferSize-1] = 0;
int numberOfChar = signedNumerator().serialize(buffer, bufferSize);
if (isInteger()) {
if (numberOfChar >= bufferSize-1) {
return numberOfChar;
}
if (numberOfChar >= bufferSize-1) {
if (isInteger()) {
return numberOfChar;
}
numberOfChar += SerializationHelper::CodePoint(buffer + numberOfChar, bufferSize - numberOfChar, '/');

View File

@@ -238,7 +238,6 @@ int SequenceLayoutNode::writeDerivedClassInBuffer(const char * operatorName, cha
// Write the closing system parenthesis
numberOfChar += SerializationHelper::CodePoint(buffer + numberOfChar, bufferSize - numberOfChar, UCodePointRightSystemParenthesis);
buffer[numberOfChar] = 0;
return numberOfChar;
}

View File

@@ -76,7 +76,7 @@ int SerializationHelper::SerializeChild(
return bufferSize-1;
}
}
buffer[numberOfChar] = 0;
assert(buffer[numberOfChar] == 0);
return numberOfChar;
}
@@ -114,7 +114,8 @@ int InfixPrefix(
// Add the opening (system or user) parenthesis
numberOfChar += UTF8Decoder::CodePointToChars(needsSystemParentheses ? UCodePointLeftSystemParenthesis : CodePoint('('), buffer+numberOfChar, bufferSize - numberOfChar);
if (numberOfChar >= bufferSize-1) {
return bufferSize-1;
assert(buffer[bufferSize - 1] == 0);
return bufferSize - 1;
}
}
@@ -134,7 +135,7 @@ int InfixPrefix(
strlcpy(buffer+numberOfChar, operatorName, bufferSize-numberOfChar);
if (numberOfChar >= bufferSize-1) {
assert(buffer[bufferSize - 1] == 0);
return bufferSize-1;
return bufferSize - 1;
}
}
// Write the child, with or without parentheses if needed
@@ -143,26 +144,26 @@ int InfixPrefix(
numberOfChar += UTF8Decoder::CodePointToChars(UCodePointLeftSystemParenthesis, buffer+numberOfChar, bufferSize - numberOfChar);
if (numberOfChar >= bufferSize-1) {
assert(buffer[bufferSize - 1] == 0);
return bufferSize-1;
return bufferSize - 1;
}
}
numberOfChar += node->childAtIndex(i)->serialize(buffer+numberOfChar, bufferSize-numberOfChar, floatDisplayMode, numberOfDigits);
if (numberOfChar >= bufferSize-1) {
assert(buffer[bufferSize - 1] == 0);
return bufferSize-1;
return bufferSize - 1;
}
if (needsSystemParentheses && (childrenCount > 1)) {
numberOfChar += UTF8Decoder::CodePointToChars(UCodePointRightSystemParenthesis, buffer+numberOfChar, bufferSize - numberOfChar);
if (numberOfChar >= bufferSize-1) {
assert(buffer[bufferSize - 1] == 0);
return bufferSize-1;
return bufferSize - 1;
}
}
} else {
numberOfChar += SerializationHelper::SerializeChild(node->childAtIndex(i), node, buffer + numberOfChar, bufferSize - numberOfChar, floatDisplayMode, numberOfDigits);
if (numberOfChar >= bufferSize-1) {
assert(buffer[bufferSize - 1] == 0);
return bufferSize-1;
return bufferSize - 1;
}
}
}
@@ -172,11 +173,12 @@ int InfixPrefix(
// Add the closing system parenthesis
numberOfChar += UTF8Decoder::CodePointToChars(needsSystemParentheses ? UCodePointRightSystemParenthesis : CodePoint(')'), buffer+numberOfChar, bufferSize - numberOfChar);
if (numberOfChar >= bufferSize-1) {
return bufferSize-1;
assert(buffer[bufferSize - 1] == 0);
return bufferSize - 1;
}
}
buffer[numberOfChar] = 0;
assert(buffer[numberOfChar] == 0);
return numberOfChar;
}
@@ -217,7 +219,7 @@ int SerializationHelper::CodePoint(char * buffer, int bufferSize, class CodePoin
if (size <= bufferSize - 1) {
buffer[size] = 0;
} else {
assert(size -1 == bufferSize - 1);
assert(size - 1 == bufferSize - 1);
buffer[--size] = 0;
}
return size;

View File

@@ -16,6 +16,8 @@
namespace Poincare {
static inline int minInt(int x, int y) { return x < y ? x : y; }
constexpr char Symbol::k_ans[];
SymbolNode::SymbolNode(const char * newName, int length) : SymbolAbstractNode() {
@@ -108,7 +110,7 @@ int SymbolNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloat
if (bufferSize == 0) {
return -1;
}
return strlcpy(buffer, m_name, bufferSize);
return minInt(bufferSize - 1, strlcpy(buffer, m_name, bufferSize));
}
Expression SymbolNode::shallowReduce(ReductionContext reductionContext) {

View File

@@ -28,8 +28,7 @@ int UndefinedNode::serialize(char * buffer, int bufferSize, Preferences::PrintFl
if (bufferSize == 0) {
return -1;
}
strlcpy(buffer, Undefined::Name(), bufferSize);
return minInt(Undefined::NameSize(), bufferSize) - 1;
return minInt(strlcpy(buffer, Undefined::Name(), bufferSize), bufferSize - 1);
}
template<typename T> Evaluation<T> UndefinedNode::templatedApproximate() const {

View File

@@ -18,8 +18,7 @@ int UnrealNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloat
if (bufferSize == 0) {
return -1;
}
strlcpy(buffer, Unreal::Name(), bufferSize);
return minInt(Unreal::NameSize(), bufferSize) - 1;
return minInt(strlcpy(buffer, Unreal::Name(), bufferSize), bufferSize - 1);
}
}

View File

@@ -8,6 +8,8 @@
namespace Poincare {
static inline int minInt(int x, int y) { return x < y ? x : y; }
void VerticalOffsetLayoutNode::moveCursorLeft(LayoutCursor * cursor, bool * shouldRecomputeLayout) {
if (cursor->layoutNode() == indiceLayout()
&& cursor->position() == LayoutCursor::Position::Left)
@@ -168,10 +170,9 @@ int VerticalOffsetLayoutNode::serialize(char * buffer, int bufferSize, Preferenc
if (numberOfChar >= bufferSize-1) { return bufferSize-1; }
numberOfChar += SerializationHelper::CodePoint(buffer+numberOfChar, bufferSize-numberOfChar, '}');
if (numberOfChar >= bufferSize-1) { return bufferSize-1; }
return numberOfChar;
return minInt(numberOfChar, bufferSize-1);
}
assert(m_position == Position::Superscript);
// If the layout is a superscript, write: '^' 'System(' indice 'System)'
int numberOfChar = SerializationHelper::CodePoint(buffer, bufferSize, '^');
@@ -181,10 +182,7 @@ int VerticalOffsetLayoutNode::serialize(char * buffer, int bufferSize, Preferenc
numberOfChar += const_cast<VerticalOffsetLayoutNode *>(this)->indiceLayout()->serialize(buffer+numberOfChar, bufferSize-numberOfChar, floatDisplayMode, numberOfSignificantDigits);
if (numberOfChar >= bufferSize-1) { return bufferSize-1; }
numberOfChar += SerializationHelper::CodePoint(buffer+numberOfChar, bufferSize-numberOfChar, UCodePointRightSystemParenthesis);
if (numberOfChar >= bufferSize-1) { return bufferSize-1; }
buffer[numberOfChar] = 0;
return numberOfChar;
return minInt(numberOfChar, bufferSize-1);
}
KDSize VerticalOffsetLayoutNode::computeSize() {