mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[poincare] Fix serializations
They should return the number of written chars
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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, '/');
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user