[DEV] add capability od number to manage integer and not only double

This commit is contained in:
Edouard DUPIN 2016-05-27 22:02:20 +02:00
parent 1f7a39741e
commit a39779657a
4 changed files with 230 additions and 23 deletions

View File

@ -42,6 +42,22 @@ void ejson::Number::set(double _value) {
static_cast<ejson::internal::Number*>(m_data.get())->set(_value); static_cast<ejson::internal::Number*>(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<ejson::internal::Number*>(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<ejson::internal::Number*>(m_data.get())->set(_value);
}
double ejson::Number::get(double _errorValue) const { double ejson::Number::get(double _errorValue) const {
if (m_data == nullptr) { if (m_data == nullptr) {
EJSON_ERROR("Can not get (nullptr) ..."); EJSON_ERROR("Can not get (nullptr) ...");
@ -49,3 +65,19 @@ double ejson::Number::get(double _errorValue) const {
} }
return static_cast<ejson::internal::Number*>(m_data.get())->get(); return static_cast<ejson::internal::Number*>(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<ejson::internal::Number*>(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<ejson::internal::Number*>(m_data.get())->getI64();
}

View File

@ -42,12 +42,34 @@ namespace ejson {
* @param[in] _value New value of the node. * @param[in] _value New value of the node.
*/ */
void set(double _value); 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. * @brief Get the current element Value.
* @param[in] _errorValue Value return if no value Exist * @param[in] _errorValue Value return if no value Exist
* @return The double number registered * @return The double number registered
*/ */
double get(double _errorValue=0.0) const; 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;
}; };
} }

View File

@ -12,26 +12,62 @@
ememory::SharedPtr<ejson::internal::Number> ejson::internal::Number::create(double _value) { ememory::SharedPtr<ejson::internal::Number> ejson::internal::Number::create(double _value) {
return ememory::SharedPtr<ejson::internal::Number>(new ejson::internal::Number(_value)); return ememory::SharedPtr<ejson::internal::Number>(new ejson::internal::Number(_value));
} }
ememory::SharedPtr<ejson::internal::Number> ejson::internal::Number::create(uint64_t _value) {
return ememory::SharedPtr<ejson::internal::Number>(new ejson::internal::Number(_value));
}
ememory::SharedPtr<ejson::internal::Number> ejson::internal::Number::create(int64_t _value) {
return ememory::SharedPtr<ejson::internal::Number>(new ejson::internal::Number(_value));
}
ejson::internal::Number::Number(double _value) : ejson::internal::Number::Number(double _value) :
m_typeNumber(ejson::internal::Number::type::tDouble),
m_value(_value) { m_value(_value) {
m_type = ejson::valueType::number; 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) { 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' "); EJSON_PARSE_ELEMENT("start parse : 'Number' ");
std::string tmpVal; std::string tmpVal;
bool isDouble = false;
for (size_t iii=_pos; iii<_data.size(); iii++) { for (size_t iii=_pos; iii<_data.size(); iii++) {
_filePos.check(_data[iii]); _filePos.check(_data[iii]);
#ifdef ENABLE_DISPLAY_PARSED_ELEMENT #ifdef ENABLE_DISPLAY_PARSED_ELEMENT
drawElementParsed(_data[iii], _filePos); drawElementParsed(_data[iii], _filePos);
#endif #endif
if(true == checkNumber(_data[iii])) { if(checkNumber(_data[iii]) == true) {
if ( _data[iii] == '.'
|| _data[iii] == 'e'
|| _data[iii] == '^') {
isDouble = true;
}
tmpVal+=_data[iii]; tmpVal+=_data[iii];
} else { } else {
_pos = iii-1; _pos = iii-1;
m_value = etk::string_to_double(tmpVal); if (isDouble == true) {
EJSON_PARSE_ELEMENT("end parse : 'Number' " << tmpVal << " >> " << m_value); 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; 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 { bool ejson::internal::Number::iGenerate(std::string& _data, size_t _indent) const {
// special thing to remove .000000 at the end of perfect number ... if (m_typeNumber == ejson::internal::Number::type::tDouble) {
int64_t tmpVal = m_value; // special thing to remove .000000 at the end of perfect number ...
if (double(tmpVal) == m_value) { int64_t tmpVal = m_value;
_data += etk::to_string(tmpVal); if (double(tmpVal) == m_value) {
} else { _data += etk::to_string(tmpVal);
_data += etk::to_string(m_value); } 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; return true;
} }
void ejson::internal::Number::iMachineGenerate(std::string& _data) const { void ejson::internal::Number::iMachineGenerate(std::string& _data) const {
// special thing to remove .000000 at the end of perfect number ... if (m_typeNumber == ejson::internal::Number::type::tDouble) {
int64_t tmpVal = m_value; // special thing to remove .000000 at the end of perfect number ...
if ((double)tmpVal == m_value) { int64_t tmpVal = m_value;
_data += etk::to_string(tmpVal); if (double(tmpVal) == m_value) {
} else { _data += etk::to_string(tmpVal);
_data += etk::to_string(m_value); } 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<ejson::internal::Va
} }
ememory::SharedPtr<ejson::internal::Number> other = std::static_pointer_cast<ejson::internal::Number>(_obj); ememory::SharedPtr<ejson::internal::Number> other = std::static_pointer_cast<ejson::internal::Number>(_obj);
// remove destination elements // remove destination elements
other->m_value = m_value; other->m_typeNumber = m_typeNumber;
m_value = 0; 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; return true;
} }
ememory::SharedPtr<ejson::internal::Value> ejson::internal::Number::clone() const { ememory::SharedPtr<ejson::internal::Value> ejson::internal::Number::clone() const {
ememory::SharedPtr<ejson::internal::Number> output = ejson::internal::Number::create(m_value); ememory::SharedPtr<ejson::internal::Number> 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) { if (output == nullptr) {
EJSON_ERROR("Allocation error ..."); EJSON_ERROR("Allocation error ...");
return ememory::SharedPtr<ejson::internal::Value>(); return ememory::SharedPtr<ejson::internal::Value>();
@ -88,9 +164,52 @@ ememory::SharedPtr<ejson::internal::Value> ejson::internal::Number::clone() cons
} }
void ejson::internal::Number::set(double _value) { void ejson::internal::Number::set(double _value) {
m_typeNumber = ejson::internal::Number::type::tDouble;
m_value = _value; m_value = _value;
} }
double ejson::internal::Number::get() const { void ejson::internal::Number::set(uint64_t _value) {
return m_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;
} }

View File

@ -19,27 +19,61 @@ namespace ejson {
* @brief basic element of a xml structure * @brief basic element of a xml structure
* @param[in] _value Value to set on the ejson::Value * @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: public:
/** /**
* @brief Create factory on the ejson::internal::Number * @brief Create factory on the ejson::internal::Number
* @param[in] _value Value to set on the ejson::Value * @param[in] _value Value to set on the ejson::Value
* @return A SharedPtr on the Number value * @return A SharedPtr on the Number value
*/ */
static ememory::SharedPtr<Number> create(double _value=0.0); static ememory::SharedPtr<Number> create(uint64_t _value=0);
static ememory::SharedPtr<Number> create(int64_t _value);
static ememory::SharedPtr<Number> create(double _value);
protected: 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: public:
/** /**
* @brief set the value of the node. * @brief set the value of the node.
* @param[in] _value New value of the node. * @param[in] _value New value of the node.
*/ */
void set(double _value); 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. * @brief Get the current element Value.
* @return The double number registered * @return The double number registered
*/ */
double get() const; 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: public:
bool iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::internal::Document& _doc) override; 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; bool iGenerate(std::string& _data, size_t _indent) const override;