diff --git a/apps/shared/storage_cartesian_function.cpp b/apps/shared/storage_cartesian_function.cpp index e5177a123..55db2760a 100644 --- a/apps/shared/storage_cartesian_function.cpp +++ b/apps/shared/storage_cartesian_function.cpp @@ -11,33 +11,36 @@ namespace Shared { void StorageCartesianFunction::DefaultName(char buffer[], size_t bufferSize) { /* a default name is "f[number].func", for instance "f12.func", that does not * exist yet in the storage */ - size_t constantNameSize = 1 + 1 + strlen(GlobalContext::funcExtension) + 1; // 'f', '.', extension, null-terminating char - assert(bufferSize > constantNameSize); + size_t extensionLength = 1 + strlen(GlobalContext::funcExtension); // '.', extension, no null-terminating char + size_t constantNameLength = 1 + extensionLength; // 'f', '.', extension, no null-terminating char + assert(bufferSize > constantNameLength+1); // Write the f buffer[0] = 'f'; // Find the next available number int currentNumber = 0; - int dotCharIndex = -1; - while (currentNumber < bufferSize - constantNameSize) { - dotCharIndex = 1 + Poincare::Integer(currentNumber).serialize(&buffer[1], bufferSize - constantNameSize + 1); + int currentNumberLength = -1; + size_t availableBufferSize = bufferSize - constantNameLength; + while (currentNumberLength < availableBufferSize) { + currentNumberLength = Poincare::Integer(currentNumber).serialize(&buffer[1], availableBufferSize); if (GlobalContext::RecordBaseNameIsFree(buffer)) { // Name found break; } currentNumber++; } + assert(currentNumberLength > 1 && currentNumberLength < availableBufferSize); // Write the extension - assert(dotCharIndex > 1); + int dotCharIndex = 1 + currentNumberLength; buffer[dotCharIndex] = Ion::Storage::k_dotChar; strlcpy(&buffer[dotCharIndex+1], GlobalContext::funcExtension, bufferSize - (dotCharIndex+1)); } -StorageCartesianFunction StorageCartesianFunction::NewModel(Ion::Storage::Record::ErrorStatus & error) { - char nameBuffer[100]; - DefaultName(nameBuffer, 100); +StorageCartesianFunction StorageCartesianFunction::NewModel(Ion::Storage::Record::ErrorStatus * error) { + char nameBuffer[SymbolAbstract::k_maxNameSize]; + DefaultName(nameBuffer, SymbolAbstract::k_maxNameSize); CartesianFunctionRecordData data; *error = Ion::Storage::sharedStorage()->createRecordWithFullName(nameBuffer, &data, sizeof(data)); - if (*error != Ion::Storage::Record::ErrorStatus::None()) { + if (*error != Ion::Storage::Record::ErrorStatus::None) { return StorageCartesianFunction(); } return StorageCartesianFunction(Ion::Storage::sharedStorage()->recordNamed(nameBuffer)); @@ -52,8 +55,7 @@ void StorageCartesianFunction::setDisplayDerivative(bool display) { } double StorageCartesianFunction::approximateDerivative(double x, Poincare::Context * context) const { - const char xUnknown[] = {Symbol::SpecialSymbols::UnknownX, 0}; - Poincare::Derivative derivative(reducedExpression(context), Symbol(xUnknown, 1), Poincare::Float(x)); // derivative takes ownership of Poincare::Float(x) and the clone of expression + Poincare::Derivative derivative(expression(context).clone(), Symbol(Symbol::SpecialSymbols::UnknownX), Poincare::Float(x)); // derivative takes ownership of Poincare::Float(x) and the clone of expression /* TODO: when we approximate derivative, we might want to simplify the * derivative here. However, we might want to do it once for all x (to avoid * lagging in the derivative table. */ @@ -61,7 +63,7 @@ double StorageCartesianFunction::approximateDerivative(double x, Poincare::Conte } double StorageCartesianFunction::sumBetweenBounds(double start, double end, Poincare::Context * context) const { - Poincare::Integral integral(reducedExpression(context), Poincare::Float(start), Poincare::Float(end)); // Integral takes ownership of args + Poincare::Integral integral(expression(context).clone(), Poincare::Float(start), Poincare::Float(end)); // Integral takes ownership of args /* TODO: when we approximate integral, we might want to simplify the integral * here. However, we might want to do it once for all x (to avoid lagging in * the derivative table. */ @@ -69,41 +71,28 @@ double StorageCartesianFunction::sumBetweenBounds(double start, double end, Poin } Expression::Coordinate2D StorageCartesianFunction::nextMinimumFrom(double start, double step, double max, Context * context) const { - return reducedExpression(context).nextMinimum(symbol(), start, step, max, *context, Preferences::sharedPreferences()->angleUnit()); + const char unknownX[2] = {Poincare::Symbol::UnknownX, 0}; + return expression(context).nextMinimum(unknownX, start, step, max, *context, Preferences::sharedPreferences()->angleUnit()); } Expression::Coordinate2D StorageCartesianFunction::nextMaximumFrom(double start, double step, double max, Context * context) const { - return reducedExpression(context).nextMaximum(symbol(), start, step, max, *context, Preferences::sharedPreferences()->angleUnit()); + const char unknownX[2] = {Poincare::Symbol::UnknownX, 0}; + return expression(context).nextMaximum(unknownX, start, step, max, *context, Preferences::sharedPreferences()->angleUnit()); } double StorageCartesianFunction::nextRootFrom(double start, double step, double max, Context * context) const { - return reducedExpression(context).nextRoot(symbol(), start, step, max, *context, Preferences::sharedPreferences()->angleUnit()); + const char unknownX[2] = {Poincare::Symbol::UnknownX, 0}; + return expression(context).nextRoot(unknownX, start, step, max, *context, Preferences::sharedPreferences()->angleUnit()); } Expression::Coordinate2D StorageCartesianFunction::nextIntersectionFrom(double start, double step, double max, Poincare::Context * context, const Shared::StorageFunction * function) const { - Expression reducedExp = reducedExpression(context); - return reducedExp.nextIntersection(symbol(), start, step, max, *context, Preferences::sharedPreferences()->angleUnit(), reducedExp); -} - -void StorageCartesianFunction::setContent(const char * c) { - Expression expressionToStore = StorageExpressionModel::expressionToStoreFromString(c); - Ion::Storage::Record::ErrorStatus error = GlobalContext::SetExpressionForFunctionRecord(expressionToStore, record()); - StorageExpressionModel::didSetContentData(); -} - -void * StorageCartesianFunction::expressionAddress() const { - return recordData()->expressionAddress(); -} - -size_t StorageCartesianFunction::expressionSize() const { - assert(!record().isNull()); - Ion::Storage::Record::Data d = record().value(); - return d.size-sizeof(CartesianFunctionRecordData); + const char unknownX[2] = {Poincare::Symbol::UnknownX, 0}; + return expression(context).nextIntersection(unknownX, start, step, max, *context, Preferences::sharedPreferences()->angleUnit(), function->expression(context)); } StorageCartesianFunction::CartesianFunctionRecordData * StorageCartesianFunction::recordData() const { - assert(!record().isNull()); - Ion::Storage::Record::Data d = record().value(); + assert(!isNull()); + Ion::Storage::Record::Data d = value(); return reinterpret_cast(const_cast(d.buffer)); } diff --git a/apps/shared/storage_cartesian_function.h b/apps/shared/storage_cartesian_function.h index ee995d8bd..a62d54e0f 100644 --- a/apps/shared/storage_cartesian_function.h +++ b/apps/shared/storage_cartesian_function.h @@ -9,17 +9,13 @@ namespace Shared { class StorageCartesianFunction : public StorageFunction { public: - static const char * Extension() { return GlobalContext::funcExtension; } static void DefaultName(char buffer[], size_t bufferSize); - static StorageCartesianFunction NewModel(Ion::Storage::Record::ErrorStatus & error); - StorageCartesianFunction(const char * text = nullptr) : - StorageFunction(text) - {} - StorageCartesianFunction(Ion::Storage::Record record) : + static StorageCartesianFunction NewModel(Ion::Storage::Record::ErrorStatus * error); + StorageCartesianFunction(Ion::Storage::Record record = Record()) : StorageFunction(record) {} - bool operator==(const StorageCartesianFunction & other) const { return record() == other.record(); } - bool operator!=(const StorageCartesianFunction & other) const { return !(*this == other); } + //bool operator==(const StorageCartesianFunction & other) const { return *(static_cast(this)) == static_cast(other)); } + //bool operator!=(const StorageCartesianFunction & other) const { return !(*(static_cast(this)) == static_cast(other)); } bool displayDerivative() const; void setDisplayDerivative(bool display); double approximateDerivative(double x, Poincare::Context * context) const; @@ -28,14 +24,7 @@ public: Poincare::Expression::Coordinate2D nextMaximumFrom(double start, double step, double max, Poincare::Context * context) const; double nextRootFrom(double start, double step, double max, Poincare::Context * context) const; Poincare::Expression::Coordinate2D nextIntersectionFrom(double start, double step, double max, Poincare::Context * context, const StorageFunction * function) const; - const char * symbol() const override { - static const char x[2] = {Poincare::Symbol::UnknownX, 0}; //TODO remove static - return x; - } - // StorageExpressionModel - void * expressionAddress() const override; - size_t expressionSize() const override; -//TODO protected: +protected: class CartesianFunctionRecordData : public FunctionRecordData { public: CartesianFunctionRecordData() : @@ -46,10 +35,10 @@ public: void setDisplayDerivative(bool display) { m_displayDerivative = display; } private: bool m_displayDerivative; - char m_expression[0]; + //char m_expression[0]; }; private: - size_t metaDataSize() override { return sizeof(CartesianFunctionRecordData); } + size_t metaDataSize() const override { return sizeof(CartesianFunctionRecordData); } CartesianFunctionRecordData * recordData() const; }; diff --git a/apps/shared/storage_expression_model.cpp b/apps/shared/storage_expression_model.cpp index 62fa0d6f5..360a329f9 100644 --- a/apps/shared/storage_expression_model.cpp +++ b/apps/shared/storage_expression_model.cpp @@ -16,7 +16,6 @@ StorageExpressionModel::StorageExpressionModel(Storage::Record record) : m_expression(), m_layout() { - assert(!isNull()); } /*void StorageExpressionModel::text(char * buffer, size_t bufferSize) const { @@ -75,6 +74,7 @@ Ion::Storage::Record::ErrorStatus StorageExpressionModel::setContent(const char } Ion::Storage::Record::ErrorStatus StorageExpressionModel::setExpressionContent(Expression & expressionToStore) { + assert(!isNull()); // Prepare the new data to store Ion::Storage::Record::Data newData = value(); size_t expressionToStoreSize = expressionToStore.isUninitialized() ? 0 : expressionToStore.size(); @@ -100,6 +100,7 @@ Ion::Storage::Record::ErrorStatus StorageExpressionModel::setExpressionContent(E } void * StorageExpressionModel::expressionAddress() const { + assert(!isNull()); return (char *)value().buffer+metaDataSize(); } diff --git a/apps/shared/storage_function.cpp b/apps/shared/storage_function.cpp index bd9c9240f..d88630ac4 100644 --- a/apps/shared/storage_function.cpp +++ b/apps/shared/storage_function.cpp @@ -30,7 +30,8 @@ void StorageFunction::setColor(KDColor color) { template T StorageFunction::templatedApproximateAtAbscissa(T x, Poincare::Context * context) const { - return expression(context).approximateWithValueForSymbol(symbol(), x, *context, Preferences::sharedPreferences()->angleUnit()); + const char unknownX[2] = {Poincare::Symbol::UnknownX, 0}; + return expression(context).approximateWithValueForSymbol(unknownX, x, *context, Preferences::sharedPreferences()->angleUnit()); } StorageFunction::FunctionRecordData * StorageFunction::recordData() const { diff --git a/apps/shared/storage_function.h b/apps/shared/storage_function.h index 404671e0e..d1c6d1910 100644 --- a/apps/shared/storage_function.h +++ b/apps/shared/storage_function.h @@ -44,7 +44,6 @@ protected: private: template T templatedApproximateAtAbscissa(T x, Poincare::Context * context) const; FunctionRecordData * recordData() const; - virtual const char * symbol() const = 0; }; }