diff --git a/ejson/Number.cpp b/ejson/Number.cpp index aef53ca..d8ac22f 100644 --- a/ejson/Number.cpp +++ b/ejson/Number.cpp @@ -42,6 +42,22 @@ void ejson::Number::set(double _value) { static_cast(m_data.get())->set(_value); } +void ejson::Number::set(uint64_t _value) { + if (m_data == nullptr) { + EJSON_ERROR("Can not set (nullptr) ..."); + return; + } + static_cast(m_data.get())->set(_value); +} + +void ejson::Number::set(int64_t _value) { + if (m_data == nullptr) { + EJSON_ERROR("Can not set (nullptr) ..."); + return; + } + static_cast(m_data.get())->set(_value); +} + double ejson::Number::get(double _errorValue) const { if (m_data == nullptr) { EJSON_ERROR("Can not get (nullptr) ..."); @@ -49,3 +65,19 @@ double ejson::Number::get(double _errorValue) const { } return static_cast(m_data.get())->get(); } + +uint64_t ejson::Number::getU64(uint64_t _errorValue) const { + if (m_data == nullptr) { + EJSON_ERROR("Can not get (nullptr) ..."); + return _errorValue; + } + return static_cast(m_data.get())->getU64(); +} + +int64_t ejson::Number::getI64(int64_t _errorValue) const { + if (m_data == nullptr) { + EJSON_ERROR("Can not get (nullptr) ..."); + return _errorValue; + } + return static_cast(m_data.get())->getI64(); +} diff --git a/ejson/Number.h b/ejson/Number.h index 2deef21..fce551b 100644 --- a/ejson/Number.h +++ b/ejson/Number.h @@ -42,12 +42,34 @@ namespace ejson { * @param[in] _value New value of the node. */ void set(double _value); + /** + * @brief set the value of the node. + * @param[in] _value New value of the node (integer mode). + */ + void set(uint64_t _value); + /** + * @brief set the value of the node. + * @param[in] _value New value of the node (integer mode). + */ + void set(int64_t _value); /** * @brief Get the current element Value. * @param[in] _errorValue Value return if no value Exist * @return The double number registered */ double get(double _errorValue=0.0) const; + /** + * @brief Get the current element Value. + * @param[in] _errorValue Value return if no value Exist + * @return The unsigned integer number registered + */ + uint64_t getU64(uint64_t _errorValue=0) const; + /** + * @brief Get the current element Value. + * @param[in] _errorValue Value return if no value Exist + * @return The integer number registered + */ + int64_t getI64(int64_t _errorValue=0) const; }; } diff --git a/ejson/internal/Number.cpp b/ejson/internal/Number.cpp index daafcb1..76e6657 100644 --- a/ejson/internal/Number.cpp +++ b/ejson/internal/Number.cpp @@ -12,26 +12,62 @@ ememory::SharedPtr ejson::internal::Number::create(double _value) { return ememory::SharedPtr(new ejson::internal::Number(_value)); } +ememory::SharedPtr ejson::internal::Number::create(uint64_t _value) { + return ememory::SharedPtr(new ejson::internal::Number(_value)); +} +ememory::SharedPtr ejson::internal::Number::create(int64_t _value) { + return ememory::SharedPtr(new ejson::internal::Number(_value)); +} ejson::internal::Number::Number(double _value) : + m_typeNumber(ejson::internal::Number::type::tDouble), m_value(_value) { m_type = ejson::valueType::number; } +ejson::internal::Number::Number(uint64_t _value) : + m_typeNumber(ejson::internal::Number::type::tUint), + m_valueU64(_value) { + m_type = ejson::valueType::number; +} + +ejson::internal::Number::Number(int64_t _value) : + m_typeNumber(ejson::internal::Number::type::tInt), + m_valueI64(_value) { + m_type = ejson::valueType::number; +} + bool ejson::internal::Number::iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::internal::Document& _doc) { EJSON_PARSE_ELEMENT("start parse : 'Number' "); std::string tmpVal; + bool isDouble = false; for (size_t iii=_pos; iii<_data.size(); iii++) { _filePos.check(_data[iii]); #ifdef ENABLE_DISPLAY_PARSED_ELEMENT drawElementParsed(_data[iii], _filePos); #endif - if(true == checkNumber(_data[iii])) { + if(checkNumber(_data[iii]) == true) { + if ( _data[iii] == '.' + || _data[iii] == 'e' + || _data[iii] == '^') { + isDouble = true; + } tmpVal+=_data[iii]; } else { _pos = iii-1; - m_value = etk::string_to_double(tmpVal); - EJSON_PARSE_ELEMENT("end parse : 'Number' " << tmpVal << " >> " << m_value); + if (isDouble == true) { + m_typeNumber = ejson::internal::Number::type::tDouble; + m_value = etk::string_to_double(tmpVal); + EJSON_PARSE_ELEMENT("end parse : 'Number' " << tmpVal << " >> double=" << m_value); + } else if (tmpVal[0] == '-') { + m_typeNumber = ejson::internal::Number::type::tInt; + m_valueI64 = etk::string_to_double(tmpVal); + EJSON_PARSE_ELEMENT("end parse : 'Number' " << tmpVal << " >> int64_t=" << m_valueI64); + } else { + m_typeNumber = ejson::internal::Number::type::tUint; + m_valueU64 = etk::string_to_double(tmpVal); + EJSON_PARSE_ELEMENT("end parse : 'Number' " << tmpVal << " >> uint64_t=" << m_valueU64); + } return true; } } @@ -41,24 +77,41 @@ bool ejson::internal::Number::iParse(const std::string& _data, size_t& _pos, ejs } bool ejson::internal::Number::iGenerate(std::string& _data, size_t _indent) const { - // special thing to remove .000000 at the end of perfect number ... - int64_t tmpVal = m_value; - if (double(tmpVal) == m_value) { - _data += etk::to_string(tmpVal); - } else { - _data += etk::to_string(m_value); + if (m_typeNumber == ejson::internal::Number::type::tDouble) { + // special thing to remove .000000 at the end of perfect number ... + int64_t tmpVal = m_value; + if (double(tmpVal) == m_value) { + _data += etk::to_string(tmpVal); + } else { + _data += etk::to_string(m_value); + } + return true; } + if (m_typeNumber == ejson::internal::Number::type::tInt) { + _data += etk::to_string(m_valueI64); + return true; + } + _data += etk::to_string(m_valueU64); return true; } void ejson::internal::Number::iMachineGenerate(std::string& _data) const { - // special thing to remove .000000 at the end of perfect number ... - int64_t tmpVal = m_value; - if ((double)tmpVal == m_value) { - _data += etk::to_string(tmpVal); - } else { - _data += etk::to_string(m_value); + if (m_typeNumber == ejson::internal::Number::type::tDouble) { + // special thing to remove .000000 at the end of perfect number ... + int64_t tmpVal = m_value; + if (double(tmpVal) == m_value) { + _data += etk::to_string(tmpVal); + } else { + _data += etk::to_string(m_value); + } + return; } + if (m_typeNumber == ejson::internal::Number::type::tInt) { + _data += etk::to_string(m_valueI64); + return; + } + _data += etk::to_string(m_valueU64); + return; } @@ -73,13 +126,36 @@ bool ejson::internal::Number::transfertIn(ememory::SharedPtr other = std::static_pointer_cast(_obj); // remove destination elements - other->m_value = m_value; - m_value = 0; + other->m_typeNumber = m_typeNumber; + m_typeNumber = ejson::internal::Number::type::tUint; + m_valueU64 = 0; + switch (m_typeNumber) { + case ejson::internal::Number::type::tDouble: + other->m_value = m_value; + break; + case ejson::internal::Number::type::tInt: + other->m_valueI64 = m_valueI64; + break; + case ejson::internal::Number::type::tUint: + other->m_valueU64 = m_valueU64; + break; + } return true; } ememory::SharedPtr ejson::internal::Number::clone() const { - ememory::SharedPtr output = ejson::internal::Number::create(m_value); + ememory::SharedPtr output; + switch (m_typeNumber) { + case ejson::internal::Number::type::tDouble: + output = ejson::internal::Number::create(m_value); + break; + case ejson::internal::Number::type::tInt: + output = ejson::internal::Number::create(m_valueI64); + break; + case ejson::internal::Number::type::tUint: + output = ejson::internal::Number::create(m_valueU64); + break; + } if (output == nullptr) { EJSON_ERROR("Allocation error ..."); return ememory::SharedPtr(); @@ -88,9 +164,52 @@ ememory::SharedPtr ejson::internal::Number::clone() cons } void ejson::internal::Number::set(double _value) { + m_typeNumber = ejson::internal::Number::type::tDouble; m_value = _value; } -double ejson::internal::Number::get() const { - return m_value; +void ejson::internal::Number::set(uint64_t _value) { + m_typeNumber = ejson::internal::Number::type::tUint; + m_valueU64 = _value; +} + +void ejson::internal::Number::set(int64_t _value) { + m_typeNumber = ejson::internal::Number::type::tInt; + m_valueI64 = _value; +} + +double ejson::internal::Number::get() const { + switch (m_typeNumber) { + case ejson::internal::Number::type::tDouble: + return m_value; + case ejson::internal::Number::type::tInt: + return double(m_valueI64); + case ejson::internal::Number::type::tUint: + return double(m_valueU64); + } + return 0.0; +} + +uint64_t ejson::internal::Number::getU64() const { + switch (m_typeNumber) { + case ejson::internal::Number::type::tDouble: + return uint64_t(m_value); + case ejson::internal::Number::type::tInt: + return uint64_t(m_valueI64); + case ejson::internal::Number::type::tUint: + return m_valueU64; + } + return 0; +} + +int64_t ejson::internal::Number::getI64() const { + switch (m_typeNumber) { + case ejson::internal::Number::type::tDouble: + return int64_t(m_value); + case ejson::internal::Number::type::tInt: + return m_valueI64; + case ejson::internal::Number::type::tUint: + return int64_t(m_valueU64); + } + return 0; } diff --git a/ejson/internal/Number.h b/ejson/internal/Number.h index 1d48954..fc800c9 100644 --- a/ejson/internal/Number.h +++ b/ejson/internal/Number.h @@ -19,27 +19,61 @@ namespace ejson { * @brief basic element of a xml structure * @param[in] _value Value to set on the ejson::Value */ - Number(double _value=0.0); + Number(uint64_t _value=0); + Number(int64_t _value); + Number(double _value); public: /** * @brief Create factory on the ejson::internal::Number * @param[in] _value Value to set on the ejson::Value * @return A SharedPtr on the Number value */ - static ememory::SharedPtr create(double _value=0.0); + static ememory::SharedPtr create(uint64_t _value=0); + static ememory::SharedPtr create(int64_t _value); + static ememory::SharedPtr create(double _value); protected: - double m_value; //!< value of the node + enum class type { + tDouble, + tInt, + tUint, + }; + type m_typeNumber; + union { + double m_value; //!< value of the node + uint64_t m_valueU64; //!< value of the node + int64_t m_valueI64; //!< value of the node + }; public: /** * @brief set the value of the node. * @param[in] _value New value of the node. */ void set(double _value); + /** + * @brief set the value of the node. + * @param[in] _value New value of the node. + */ + void set(int64_t _value); + /** + * @brief set the value of the node. + * @param[in] _value New value of the node. + */ + void set(uint64_t _value); /** * @brief Get the current element Value. * @return The double number registered */ double get() const; + /** + * @brief Get the current element Value. + * @return The unsigned integer number registered + */ + uint64_t getU64() const; + /** + * @brief Get the current element Value. + * @return The unsigned integer number registered + */ + int64_t getI64() const; public: bool iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::internal::Document& _doc) override; bool iGenerate(std::string& _data, size_t _indent) const override;