diff --git a/etk/Number.cpp b/etk/Number.cpp new file mode 100644 index 0000000..045f62a --- /dev/null +++ b/etk/Number.cpp @@ -0,0 +1,305 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license MPL v2.0 (see license file) + */ + +#include + +etk::Number::Number() : + m_negative(false), + m_unit(0), + m_lessZero(0), + m_numberLessZero(0), + m_exponent(0) { + +} +etk::Number::Number(int8_t _value) : + m_negative(false), + m_unit(_value), + m_lessZero(0), + m_numberLessZero(0), + m_exponent(0) { + +} +etk::Number::Number(int16_t _value) : + m_negative(false), + m_unit(_value), + m_lessZero(0), + m_numberLessZero(0), + m_exponent(0) { + +} +etk::Number::Number(int32_t _value) : + m_negative(false), + m_unit(_value), + m_lessZero(0), + m_numberLessZero(0), + m_exponent(0) { + +} +etk::Number::Number(int64_t _value) : + m_negative(false), + m_unit(_value), + m_lessZero(0), + m_numberLessZero(0), + m_exponent(0) { + +} +etk::Number::Number(uint8_t _value) : + m_negative(false), + m_unit(_value), + m_lessZero(0), + m_numberLessZero(0), + m_exponent(0) { + +} +etk::Number::Number(uint16_t _value) : + m_negative(false), + m_unit(_value), + m_lessZero(0), + m_numberLessZero(0), + m_exponent(0) { + +} +etk::Number::Number(uint32_t _value) : + m_negative(false), + m_unit(_value), + m_lessZero(0), + m_numberLessZero(0), + m_exponent(0) { + +} +etk::Number::Number(uint64_t _value) : + m_negative(false), + m_unit(_value), + m_lessZero(0), + m_numberLessZero(0), + m_exponent(0) { + +} +etk::Number::Number(float _value) : + m_negative(false), + m_unit(0), + m_lessZero(0), + m_numberLessZero(0), + m_exponent(0) { + m_unit(_value); + _value -= int64_t(_value); + _value *= 10.0; + for (size_t iii=0; iii<64; ++iii) { + if (_value == 0.0) { + return; + } + uint64_t val = _value; + _value = (_value - val) * 10.0; + m_lessZero *= 10; + m_lessZero += val; + m_numberLessZero++; + } +} +etk::Number::Number(double _value) : + m_negative(false), + m_unit(0), + m_lessZero(0), + m_numberLessZero(0), + m_exponent(0) { + m_unit(_value); + _value -= int64_t(_value); + _value *= 10.0; + for (size_t iii=0; iii<64; ++iii) { + if (_value == 0.0) { + return; + } + uint64_t val = _value; + _value = (_value - val) * 10.0; + m_lessZero *= 10; + m_lessZero += val; + m_numberLessZero++; + } +} +etk::Number::Number(long double _value) : + m_negative(false), + m_unit(0), + m_lessZero(0), + m_numberLessZero(0), + m_exponent(0) { + m_unit(_value); + _value -= int64_t(_value); + _value *= 10.0; + for (size_t iii=0; iii<64; ++iii) { + if (_value == 0.0) { + return; + } + uint64_t val = _value; + _value = (_value - val) * 10.0; + m_lessZero *= 10; + m_lessZero += val; + m_numberLessZero++; + } +} +etk::Number::Number(bool _value) : + m_negative(false), + m_unit(_value), + m_lessZero(0), + m_numberLessZero(0), + m_exponent(0) { + +} +etk::Number::Number(const etk::UString& _value) : + m_negative(false), + m_unit(0), + m_lessZero(0), + m_numberLessZero(0), + m_exponent(0) { + parse(_value); +} + +void etk::Number::clear() { + m_negative = false; + m_unit = 0; + m_lessZero = 0; + m_exponent = 0; +} + +bool etk::Number::isDigit(char32_t _value, enum etk::Number::type _type) { + if (_type == type::numberBinary) { + if ( _value == '0' + || _value == '1') { + return false; + } + return false; + } else if (_type == type::numberHexadecimal) { + if ( _value >= 'A' + && _value <= 'F') { + return true; + } + if ( _value >= 'a' + && _value <= 'f') { + return true; + } + } + if ( _value >= '0' + && _value <= '9') { + return true; + } + return false; +} + +bool etk::Number::parse(const etk::UString& _value) { + enum type section = type::numberDecimal; + for (size_t iii=0; iii<_value.size(); ++iii) { + if ( iii == 0 + && _value[iii] == '+') { + // noting to do ==> already positive value + continue; + } + if ( iii == 0 + && _value[iii] == '-') { + m_negative = true; + continue; + } + if ( iii == 1 + && _value[0] == '0' + && ( _value[1] == 'x' + || _value[1] == 'X')) { + section = type::numberHexadecimal; + continue; + } + if ( iii == 1 + && _value[0] == '0' + && ( _value[1] == 'b' + || _value[1] == 'B')) { + section = type::numberBinary; + continue; + } + if (_value[iii] == '.') { + if (section == type::numberDecimal) { + section = type::numberLessZero; + continue; + } + TK_ERROR("Can not parse the Number '" << _value << "':" << iii << " '.' can not parse"); + return false; + } + if (_value[iii] == 'e') { + if ( section == type::numberDecimal + || section == type::numberLessZero) { + section = type::numberExponent; + continue; + } + TK_ERROR("Can not parse the Number '" << _value << "':" << iii << " 'e' ==> can not parse ..."); + return false; + } + if (isDigit(_value[iii], section) == true) { + // TODO: Check too big number + if (section == type::numberDecimal) { + m_unit = (m_unit*10) + (_value[iii]-'0'); + } else if (section == type::numberBinary) { + m_unit = (m_unit<<1) + (_value[iii]-'0'); + } else if (section == type::numberHexadecimal) { + if (_value[iii] <= 'F') { + m_unit = (m_unit*16) + (_value[iii]-'A' + 10); + } else if (_value[iii] <= 'f') { + m_unit = (m_unit*16) + (_value[iii]-'a' + 10); + } else { + m_unit = (m_unit*16) + (_value[iii]-'0'); + } + } else if (section == type::numberLessZero) { + m_lessZero = (m_lessZero*10) + (_value[iii]-'0'); + m_numberLessZero++; + } else { + m_exponent = (m_exponent*10) + (_value[iii]-'0'); + } + } else { + return false; + } + } + return false; +} +long double etk::Number::getDouble() { + long double out = 0; + out = m_lessZero; + out *= pow(10,-m_numberLessZero); + out += m_unit; + out *= pow(10,m_exponent); + if (m_negative == true) { + out *= -1.0; + } + return -1; +} +uint64_t etk::Number::getU64() { + uint64_t out = 0; + if (m_exponent != 0) { + // Auto manage exponent + long double tmp = getDouble(); + if (tmp <= 0.0) { + return 0; + } + return uint64_t(tmp); + } + out += m_unit; + if (m_negative == true) { + return 0; + } + return out; +} +int64_t etk::Number::getI64() { + int64_t out = 0; + if (m_exponent != 0) { + // Auto manage exponent + long double tmp = getDouble(); + if (tmp <= 0.0) { + return 0; + } + return int64_t(tmp); + } + out += m_unit; + if (m_negative == true) { + out *= -1.0; + } + return out; +} + + diff --git a/etk/Number.hpp b/etk/Number.hpp new file mode 100644 index 0000000..b618cb1 --- /dev/null +++ b/etk/Number.hpp @@ -0,0 +1,67 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license MPL v2.0 (see license file) + */ +#pragma once + +#include +#include +#include + + +namespace etk { + struct Number { + protected: + bool m_negative; + uint64_t m_unit; + uint64_t m_lessZero; + uint64_t m_numberLessZero; + uint32_t m_exponent; + public: + enum class type { + numberDecimal, + numberBinary, + numberHexadecimal, + numberLessZero, + numberExponent, + }; + Number(); + Number(int8_t _value); + Number(int16_t _value); + Number(int32_t _value); + Number(int64_t _value); + Number(uint8_t _value); + Number(uint16_t _value); + Number(uint32_t _value); + Number(uint64_t _value); + Number(float _value); + Number(double _value); + Number(long double _value); + Number(bool _value); + Number(const etk::UString& _value); + void clear(); + bool isDigit(char32_t _value, enum type _type); + // Format: + // 51651 + // -455465 + // +54654 + // 51651.545 + // -455465.4845 + // +54654.485424 + // 51651e12 + // -455465e12 + // +54654e12 + // 51651.545e12 + // -455465.4845e12 + // +54654.485424e12 + // 0x123456789ABCDEF + // 0b10101110101010 + bool parse(const etk::UString& _value); + long double getDouble(); + uint64_t getU64(); + int64_t getI64(); + }; +} \ No newline at end of file diff --git a/etk/UString.cpp b/etk/UString.cpp index 75a49f2..06573be 100644 --- a/etk/UString.cpp +++ b/etk/UString.cpp @@ -1,6 +1,7 @@ #include +#include etk::UString::UString(): m_data() { @@ -456,182 +457,70 @@ bool etk::UString::startWith(const etk::UString& _val, bool _caseSensitive) cons return true; } -struct Number { - public: - bool m_negative; - uint64_t m_unit; - uint64_t m_lessZero; - uint32_t m_exponent; - Number() : - m_negative(false), - m_unit(0), - m_lessZero(0), - m_exponent(0) { - - } - void clear() { - m_negative = false; - m_unit = 0; - m_lessZero = 0; - m_exponent = 0; - } - bool isDigit(char32_t _value) { - if (_value < '0') { - return false; - } - if (_value > '9') { - return false; - } - return true; - } - // Format: - // 51651 - // -455465 - // +54654 - // 51651.545 - // -455465.4845 - // +54654.485424 - // 51651e12 - // -455465e12 - // +54654e12 - // 51651.545e12 - // -455465.4845e12 - // +54654.485424e12 - // 0x123456789ABCDEF - bool parse(const etk::UString& _value) { - int8_t section = 0; - for (size_t iii=0; iii<_value.size(); ++iii) { - if ( iii == 0 - && _value[iii] == "+") { - // noting to do ==> already positive value - continue; - } - if ( iii == 0 - && _value[iii] == "-") { - m_negative = true; - continue; - } - if (_value[iii] == ".") { - if (section == 0) { - section = 1; - continue; - } - TK_ERROR("Can not parse the Number '" << _value << "':" << iii << " '.' can not parse"); - return false; - } - if (_value[iii] == "e") { - if ( section == 0 - || section == 1) { - section = 2; - continue; - } - TK_ERROR("Can not parse the Number '" << _value << "':" << iii << " 'e' ==> can not parse ..."); - return false; - } - if (isDigit(_value[iii]) == true) { - // TODO: Check too big number - if (section == 0) { - m_unit = m_unit*10 + (_value[iii]-'0'); - } else if (section == 0) { - m_lessZero = m_lessZero*10 + (_value[iii]-'0'); - } else { - m_exponent = m_exponent*10 + (_value[iii]-'0'); - } - } - } - return false; - } -}; - template <> long double etk::UString::to() const { - long double ret = 0; - sscanf(c_str(), "%Lf", &ret); - return ret; + etk::Number value(*this); + return value.getDouble(); } template <> double etk::UString::to() const { - double ret = 0; - sscanf(c_str(), "%lf", &ret); - return ret; + etk::Number value(*this); + return value.getDouble(); } template <> float etk::UString::to() const { - float ret = 0; - sscanf(c_str(), "%f", &ret); - return ret; + etk::Number value(*this); + return value.getDouble(); } template <> int8_t etk::UString::to() const { - int ret = 0; - sscanf(c_str(), "%d", &ret); - return ret; + etk::Number value(*this); + return value.getI64(); } template <> int16_t etk::UString::to() const { - int ret = 0; - sscanf(c_str(), "%d", &ret); - return ret; + etk::Number value(*this); + return value.getI64(); } template <> int32_t etk::UString::to() const { - int ret = 0; - sscanf(c_str(), "%d", &ret); - return ret; + etk::Number value(*this); + return value.getI64(); } template <> int64_t etk::UString::to() const { - int64_t ret = 0; - #if ( defined(__TARGET_OS__Android) \ - || defined(__TARGET_OS__Windows) \ - || defined(__TARGET_OS__MacOs) \ - || defined(__TARGET_OS__IOs)) - sscanf(c_str(), "%lld", &ret); - #else - sscanf(c_str(), "%ld", &ret); - #endif - return ret; + etk::Number value(*this); + return value.getI64(); } template <> uint8_t etk::UString::to() const { - int ret = 0; - sscanf(c_str(), "%d", &ret); - return ret; + etk::Number value(*this); + return value.getU64(); } template <> uint16_t etk::UString::to() const { - int ret = 0; - sscanf(c_str(), "%d", &ret); - return ret; + etk::Number value(*this); + return value.getU64(); } template <> uint32_t etk::UString::to() const { - int ret = 0; - sscanf(c_str(), "%d", &ret); - return ret; + etk::Number value(*this); + return value.getU64(); } template <> uint64_t etk::UString::to() const { - uint64_t ret = 0; - #if ( defined(__TARGET_OS__Android) \ - || defined(__TARGET_OS__Windows) \ - || defined(__TARGET_OS__MacOs) \ - || defined(__TARGET_OS__IOs)) - sscanf(c_str(), "%llu", &ret); - #else - sscanf(c_str(), "%lu", &ret); - #endif - return ret; + etk::Number value(*this); + return value.getU64(); } template <> @@ -740,84 +629,57 @@ namespace etk { } template<> -etk::UString etk::toString(const bool& _val) { - if (_val == true) { - return "true"; - } - return "false"; +etk::UString etk::toUString(const bool& _val) { + return utf8::convertUnicode(etk::toString(_val)); } template<> -etk::UString etk::toString(const int8_t& _val) { - char32_t tmpVal[256]; - sprintf(tmpVal, "%d", _val); - return tmpVal; +etk::UString etk::toUString(const int8_t& _val) { + return utf8::convertUnicode(etk::toString(_val)); } template<> -etk::UString etk::toString(const int16_t& _val) { - char32_t tmpVal[256]; - sprintf(tmpVal, "%d", _val); - return tmpVal; +etk::UString etk::toUString(const int16_t& _val) { + return utf8::convertUnicode(etk::toString(_val)); } template<> -etk::UString etk::toString(const int32_t& _val) { - char32_t tmpVal[256]; - sprintf(tmpVal, "%d", _val); - return tmpVal; +etk::UString etk::toUString(const int32_t& _val) { + return utf8::convertUnicode(etk::toString(_val)); } template<> -etk::UString etk::toString(const int64_t& _val) { - char32_t tmpVal[256]; - sprintf(tmpVal, "%lld", _val); - return tmpVal; +etk::UString etk::toUString(const int64_t& _val) { + return utf8::convertUnicode(etk::toString(_val)); } template<> -etk::UString etk::toString(const uint8_t& _val) { - char32_t tmpVal[256]; - sprintf(tmpVal, "%u", _val); - return tmpVal; +etk::UString etk::toUString(const uint8_t& _val) { + return utf8::convertUnicode(etk::toString(_val)); } template<> -etk::UString etk::toString(const uint16_t& _val) { - char32_t tmpVal[256]; - sprintf(tmpVal, "%u", _val); - return tmpVal; +etk::UString etk::toUString(const uint16_t& _val) { + return utf8::convertUnicode(etk::toString(_val)); } template<> -etk::UString etk::toString(const uint32_t& _val) { - char32_t tmpVal[256]; - sprintf(tmpVal, "%u", _val); - return tmpVal; +etk::UString etk::toUString(const uint32_t& _val) { + return utf8::convertUnicode(etk::toString(_val)); } template<> -etk::UString etk::toString(const uint64_t& _val) { - char32_t tmpVal[256]; - sprintf(tmpVal, "%llu", _val); - return tmpVal; +etk::UString etk::toUString(const uint64_t& _val) { + return utf8::convertUnicode(etk::toString(_val)); } template<> -etk::UString etk::toString(const size_t& _val) { - char32_t tmpVal[256]; - sprintf(tmpVal, "%zu", _val); - return tmpVal; +etk::UString etk::toUString(const size_t& _val) { + return utf8::convertUnicode(etk::toString(_val)); } template<> -etk::UString etk::toString(const float& _val) { - char32_t tmpVal[256]; - sprintf(tmpVal, "%f", _val); - return tmpVal; +etk::UString etk::toUString(const float& _val) { + return utf8::convertUnicode(etk::toString(_val)); } template<> -etk::UString etk::toString(const double& _val) { - char32_t tmpVal[256]; - sprintf(tmpVal, "%f", _val); - return tmpVal; +etk::UString etk::toUString(const double& _val) { + return utf8::convertUnicode(etk::toString(_val)); } template<> -etk::UString etk::toString(const long double& _val) { - char32_t tmpVal[256]; - sprintf(tmpVal, "%Lf", _val); - return tmpVal; +etk::UString etk::toUString(const long double& _val) { + return utf8::convertUnicode(etk::toString(_val)); } size_t etk::UString::find(char32_t _value, size_t _pos) const { @@ -932,10 +794,10 @@ etk::UString etk::UString::getLine(int32_t _pos) const { if (startPos == etk::UString::npos) { startPos = 0; } else if (startPos >= size() ) { - return ""; + return U""; } if (stopPos == etk::UString::npos) { - return ""; + return U""; } else if (stopPos >= size() ) { stopPos = size(); } diff --git a/etk/math/Vector2D.hpp b/etk/math/Vector2D.hpp index 4829387..9f8efe6 100644 --- a/etk/math/Vector2D.hpp +++ b/etk/math/Vector2D.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #pragma once @@ -71,7 +72,7 @@ namespace etk { */ Vector2D(const etk::String& _str); #if __CPP_VERSION__ >= 2011 - Vector2D(const std::u32string& _str); + Vector2D(const etk::UString& _str); #endif /** * @brief Operator= Asign the current object with an other object @@ -552,7 +553,7 @@ namespace etk { * @brief String caster of the object. * @return the Object cated in string (x.x,y.y) */ - operator std::u32string() const; + operator etk::UString() const; #endif }; //! @not_in_doc diff --git a/etk/math/Vector3D.hpp b/etk/math/Vector3D.hpp index d48a901..8a4cb1d 100644 --- a/etk/math/Vector3D.hpp +++ b/etk/math/Vector3D.hpp @@ -6,6 +6,8 @@ #include #include +#include +#include #pragma once diff --git a/etk/os/FSNodeRight.hpp b/etk/os/FSNodeRight.hpp index 6987bd3..76b683d 100644 --- a/etk/os/FSNodeRight.hpp +++ b/etk/os/FSNodeRight.hpp @@ -9,6 +9,7 @@ #pragma once #include +#include namespace etk { /**