mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[sequence] Implement specific setExpressionContent for Sequence model
This commit is contained in:
@@ -200,6 +200,20 @@ Poincare::Layout Sequence::SequenceHandle::name(Sequence * sequence) {
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void Sequence::SequenceHandle::updateNewDataWithExpression(Ion::Storage::Record * record, Expression & expressionToStore, void * expressionAddress, size_t newExpressionSize, size_t previousExpressionSize) {
|
||||
Ion::Storage::Record::Data newData = record->value();
|
||||
// Translate expressions located downstream
|
||||
size_t sizeBeforeExpression = (char *)expressionAddress -(char *)newData.buffer;
|
||||
size_t remainingSize = newData.size - sizeBeforeExpression - previousExpressionSize;
|
||||
memmove((char *)expressionAddress + newExpressionSize, (char *)expressionAddress + previousExpressionSize, remainingSize);
|
||||
// Copy the expression
|
||||
if (!expressionToStore.isUninitialized()) {
|
||||
memmove(expressionAddress, expressionToStore.addressInPool(), newExpressionSize);
|
||||
}
|
||||
// Update meta data
|
||||
updateMetaData(record, newExpressionSize);
|
||||
}
|
||||
|
||||
/* Definition Handle*/
|
||||
|
||||
void * Sequence::DefinitionHandle::expressionAddress(const Ion::Storage::Record * record) const {
|
||||
@@ -243,6 +257,10 @@ size_t Sequence::FirstInitialConditionHandle::expressionSize(const Ion::Storage:
|
||||
return static_cast<const Sequence *>(record)->recordData()->firstInitialConditionSize();
|
||||
}
|
||||
|
||||
void Sequence::FirstInitialConditionHandle::updateMetaData(const Ion::Storage::Record * record, size_t newSize) {
|
||||
static_cast<const Sequence *>(record)->recordData()->setFirstInitialConditionSize(newSize);
|
||||
}
|
||||
|
||||
void Sequence::FirstInitialConditionHandle::buildName(Sequence * sequence) {
|
||||
assert(sequence->type() == Type::SingleRecurrence || sequence->type() == Type::DoubleRecurrence);
|
||||
char buffer[k_initialRankNumberOfDigits+1];
|
||||
@@ -262,6 +280,10 @@ void * Sequence::SecondInitialConditionHandle::expressionAddress(const Ion::Stor
|
||||
return (char *)data.buffer+offset;
|
||||
}
|
||||
|
||||
void Sequence::SecondInitialConditionHandle::updateMetaData(const Ion::Storage::Record * record, size_t newSize) {
|
||||
static_cast<const Sequence *>(record)->recordData()->setSecondInitialConditionSize(newSize);
|
||||
}
|
||||
|
||||
size_t Sequence::SecondInitialConditionHandle::expressionSize(const Ion::Storage::Record * record) const {
|
||||
return static_cast<const Sequence *>(record)->recordData()->secondInitialConditionSize();
|
||||
}
|
||||
|
||||
@@ -101,6 +101,9 @@ private:
|
||||
protected:
|
||||
virtual void buildName(Sequence * sequence) = 0;
|
||||
Poincare::Layout m_name;
|
||||
private:
|
||||
void updateNewDataWithExpression(Ion::Storage::Record * record, Poincare::Expression & newExpression, void * expressionAddress, size_t newExpressionSize, size_t previousExpressionSize) override;
|
||||
virtual void updateMetaData(const Ion::Storage::Record * record, size_t newSize) {}
|
||||
};
|
||||
|
||||
class DefinitionHandle : public SequenceHandle {
|
||||
@@ -115,6 +118,7 @@ private:
|
||||
public:
|
||||
void * expressionAddress(const Ion::Storage::Record * record) const override;
|
||||
private:
|
||||
void updateMetaData(const Ion::Storage::Record * record, size_t newSize) override;
|
||||
size_t expressionSize(const Ion::Storage::Record * record) const override;
|
||||
void buildName(Sequence * sequence) override;
|
||||
};
|
||||
@@ -123,6 +127,7 @@ private:
|
||||
public:
|
||||
void * expressionAddress(const Ion::Storage::Record * record) const override;
|
||||
private:
|
||||
void updateMetaData(const Ion::Storage::Record * record, size_t newSize) override;
|
||||
size_t expressionSize(const Ion::Storage::Record * record) const override;
|
||||
void buildName(Sequence * sequence) override;
|
||||
};
|
||||
|
||||
@@ -11,6 +11,8 @@ using namespace Poincare;
|
||||
|
||||
namespace Shared {
|
||||
|
||||
static inline int maxInt(int x, int y) { return x > y ? x : y; }
|
||||
|
||||
ExpressionModelHandle::ExpressionModelHandle() :
|
||||
m_expression(),
|
||||
m_layout(),
|
||||
@@ -68,30 +70,45 @@ Ion::Storage::Record::ErrorStatus ExpressionModelHandle::setContent(Ion::Storage
|
||||
return setExpressionContent(record, e);
|
||||
}
|
||||
|
||||
Ion::Storage::Record::ErrorStatus ExpressionModelHandle::setExpressionContent(Ion::Storage::Record * record, Expression & expressionToStore) {
|
||||
Ion::Storage::Record::ErrorStatus ExpressionModelHandle::setExpressionContent(Ion::Storage::Record * record, Expression & newExpression) {
|
||||
assert(record->fullName() != nullptr);
|
||||
// Prepare the new data to store
|
||||
// Prepare the new data to be stored
|
||||
Ion::Storage::Record::Data newData = record->value();
|
||||
size_t expressionToStoreSize = expressionToStore.isUninitialized() ? 0 : expressionToStore.size();
|
||||
newData.size = newData.size - expressionSize(record) + expressionToStoreSize;
|
||||
|
||||
// Set the data
|
||||
size_t previousExpressionSize = expressionSize(record);
|
||||
size_t newExpressionSize = newExpression.isUninitialized() ? 0 : newExpression.size();
|
||||
size_t previousDataSize = newData.size;
|
||||
size_t newDataSize = previousDataSize - previousExpressionSize + newExpressionSize;
|
||||
void * expAddress = expressionAddress(record);
|
||||
// Update size of record to maximal size between previous and new data
|
||||
newData.size = maxInt(previousDataSize, newDataSize);
|
||||
Ion::Storage::Record::ErrorStatus error = record->setValue(newData);
|
||||
if (error != Ion::Storage::Record::ErrorStatus::None) {
|
||||
assert(error == Ion::Storage::Record::ErrorStatus::NotEnoughSpaceAvailable);
|
||||
return error;
|
||||
}
|
||||
// Prepare the new data content
|
||||
/* WARNING: expressionAddress() cannot be used while the metadata is invalid
|
||||
* (as it is sometimes computed from metadata). Thus, the expression address
|
||||
* is given as a parameter to updateNewDataWithExpression. */
|
||||
updateNewDataWithExpression(record, newExpression, expAddress, newExpressionSize, previousExpressionSize);
|
||||
// Set the data with the right size
|
||||
newData.size = newDataSize;
|
||||
error = record->setValue(newData);
|
||||
// Any error would have occured at the first call to setValue
|
||||
assert(error == Ion::Storage::Record::ErrorStatus::None);
|
||||
|
||||
// Copy the expression if needed
|
||||
if (!expressionToStore.isUninitialized()) {
|
||||
memcpy(expressionAddress(record), expressionToStore.addressInPool(), expressionToStore.size());
|
||||
}
|
||||
/* Here we delete only the elements relative to the expression model kept in
|
||||
* this handle. */
|
||||
tidy();
|
||||
return error;
|
||||
}
|
||||
|
||||
void ExpressionModelHandle::updateNewDataWithExpression(Ion::Storage::Record * record, Expression & expressionToStore, void * expressionAddress, size_t expressionToStoreSize, size_t previousExpressionSize) {
|
||||
if (!expressionToStore.isUninitialized()) {
|
||||
memmove(expressionAddress, expressionToStore.addressInPool(), expressionToStoreSize);
|
||||
}
|
||||
}
|
||||
|
||||
void ExpressionModelHandle::tidy() const {
|
||||
m_layout = Layout();
|
||||
m_expression = Expression();
|
||||
|
||||
@@ -34,6 +34,7 @@ protected:
|
||||
mutable Poincare::Expression m_expression;
|
||||
mutable Poincare::Layout m_layout;
|
||||
private:
|
||||
virtual void updateNewDataWithExpression(Ion::Storage::Record * record, Poincare::Expression & expressionToStore, void * expressionAddress, size_t expressionToStoreSize, size_t previousExpressionSize);
|
||||
virtual size_t expressionSize(const Ion::Storage::Record * record) const = 0;
|
||||
mutable int m_circular;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user