diff options
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/util/areastore.cpp | 1 | ||||
-rw-r--r-- | src/util/auth.h | 2 | ||||
-rw-r--r-- | src/util/cpp11_container.h | 43 | ||||
-rw-r--r-- | src/util/enriched_string.cpp | 166 | ||||
-rw-r--r-- | src/util/enriched_string.h | 91 | ||||
-rw-r--r-- | src/util/numeric.cpp | 17 | ||||
-rw-r--r-- | src/util/numeric.h | 37 | ||||
-rw-r--r-- | src/util/srp.cpp | 2 | ||||
-rw-r--r-- | src/util/string.cpp | 19 | ||||
-rw-r--r-- | src/util/string.h | 86 |
11 files changed, 403 insertions, 62 deletions
diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index 0e7cbad07..f571ab22c 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -3,6 +3,7 @@ set(UTIL_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/auth.cpp ${CMAKE_CURRENT_SOURCE_DIR}/base64.cpp ${CMAKE_CURRENT_SOURCE_DIR}/directiontables.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/enriched_string.cpp ${CMAKE_CURRENT_SOURCE_DIR}/numeric.cpp ${CMAKE_CURRENT_SOURCE_DIR}/pointedthing.cpp ${CMAKE_CURRENT_SOURCE_DIR}/serialize.cpp diff --git a/src/util/areastore.cpp b/src/util/areastore.cpp index 58f08a8c2..cef67da2c 100644 --- a/src/util/areastore.cpp +++ b/src/util/areastore.cpp @@ -95,6 +95,7 @@ void AreaStore::deserialize(std::istream &is) is.read(data, data_len); a.data = std::string(data, data_len); insertArea(&a); + delete [] data; } } diff --git a/src/util/auth.h b/src/util/auth.h index 1fd6ab453..7cdc7d74d 100644 --- a/src/util/auth.h +++ b/src/util/auth.h @@ -45,6 +45,6 @@ std::string encode_srp_verifier(const std::string &verifier, /// Reads the DB-formatted SRP verifier and gets the verifier /// and salt components. bool decode_srp_verifier_and_salt(const std::string &encoded, - std::string *salt, std::string *bytes_v); + std::string *verifier, std::string *salt); #endif diff --git a/src/util/cpp11_container.h b/src/util/cpp11_container.h new file mode 100644 index 000000000..88317c9c4 --- /dev/null +++ b/src/util/cpp11_container.h @@ -0,0 +1,43 @@ +/* +Minetest +Copyright (C) 2016 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef MT_CPP11CONTAINER_HEADER +#define MT_CPP11CONTAINER_HEADER + +#if __cplusplus >= 201103L +#define USE_UNORDERED_CONTAINERS +#endif + +#if _MSC_VER >= 1600 +#define USE_UNORDERED_CONTAINERS +#endif + +#ifdef USE_UNORDERED_CONTAINERS + #include <unordered_map> + #include <unordered_set> + #define UNORDERED_MAP std::unordered_map + #define UNORDERED_SET std::unordered_set +#else + #include <map> + #include <set> + #define UNORDERED_MAP std::map + #define UNORDERED_SET std::set +#endif + +#endif diff --git a/src/util/enriched_string.cpp b/src/util/enriched_string.cpp new file mode 100644 index 000000000..a7fc3a828 --- /dev/null +++ b/src/util/enriched_string.cpp @@ -0,0 +1,166 @@ +/* +Copyright (C) 2013 xyz, Ilya Zhuravlev <whatever@xyz.is> +Copyright (C) 2016 Nore, Nathanaƫl Courant <nore@mesecons.net> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "enriched_string.h" +#include "util/string.h" +#include "log.h" +using namespace irr::video; + +EnrichedString::EnrichedString() +{ + clear(); +} + +EnrichedString::EnrichedString(const std::wstring &string, + const std::vector<SColor> &colors): + m_string(string), + m_colors(colors), + m_has_background(false) +{} + +EnrichedString::EnrichedString(const std::wstring &s, const SColor &color) +{ + clear(); + addAtEnd(s, color); +} + +EnrichedString::EnrichedString(const wchar_t *str, const SColor &color) +{ + clear(); + addAtEnd(std::wstring(str), color); +} + +void EnrichedString::operator=(const wchar_t *str) +{ + clear(); + addAtEnd(std::wstring(str), SColor(255, 255, 255, 255)); +} + +void EnrichedString::addAtEnd(const std::wstring &s, const SColor &initial_color) +{ + SColor color(initial_color); + size_t i = 0; + while (i < s.length()) { + if (s[i] != L'\x1b') { + m_string += s[i]; + m_colors.push_back(color); + ++i; + continue; + } + ++i; + size_t start_index = i; + size_t length; + if (i == s.length()) { + break; + } + if (s[i] == L'(') { + ++i; + ++start_index; + while (i < s.length() && s[i] != L')') { + if (s[i] == L'\\') { + ++i; + } + ++i; + } + length = i - start_index; + ++i; + } else { + ++i; + length = 1; + } + std::wstring escape_sequence(s, start_index, length); + std::vector<std::wstring> parts = split(escape_sequence, L'@'); + if (parts[0] == L"c") { + if (parts.size() < 2) { + continue; + } + parseColorString(wide_to_utf8(parts[1]), color, true); + } else if (parts[0] == L"b") { + if (parts.size() < 2) { + continue; + } + parseColorString(wide_to_utf8(parts[1]), m_background, true); + m_has_background = true; + } + continue; + } +} + +void EnrichedString::addChar(const EnrichedString &source, size_t i) +{ + m_string += source.m_string[i]; + m_colors.push_back(source.m_colors[i]); +} + +void EnrichedString::addCharNoColor(wchar_t c) +{ + m_string += c; + if (m_colors.empty()) { + m_colors.push_back(SColor(255, 255, 255, 255)); + } else { + m_colors.push_back(m_colors[m_colors.size() - 1]); + } +} + +EnrichedString EnrichedString::operator+(const EnrichedString &other) const +{ + std::vector<SColor> result; + result.insert(result.end(), m_colors.begin(), m_colors.end()); + result.insert(result.end(), other.m_colors.begin(), other.m_colors.end()); + return EnrichedString(m_string + other.m_string, result); +} + +void EnrichedString::operator+=(const EnrichedString &other) +{ + m_string += other.m_string; + m_colors.insert(m_colors.end(), other.m_colors.begin(), other.m_colors.end()); +} + +EnrichedString EnrichedString::substr(size_t pos, size_t len) const +{ + if (pos == m_string.length()) { + return EnrichedString(); + } + if (len == std::string::npos || pos + len > m_string.length()) { + return EnrichedString( + m_string.substr(pos, std::string::npos), + std::vector<SColor>(m_colors.begin() + pos, m_colors.end()) + ); + } else { + return EnrichedString( + m_string.substr(pos, len), + std::vector<SColor>(m_colors.begin() + pos, m_colors.begin() + pos + len) + ); + } +} + +const wchar_t *EnrichedString::c_str() const +{ + return m_string.c_str(); +} + +const std::vector<SColor> &EnrichedString::getColors() const +{ + return m_colors; +} + +const std::wstring &EnrichedString::getString() const +{ + return m_string; +} diff --git a/src/util/enriched_string.h b/src/util/enriched_string.h new file mode 100644 index 000000000..1aca8948a --- /dev/null +++ b/src/util/enriched_string.h @@ -0,0 +1,91 @@ +/* +Copyright (C) 2013 xyz, Ilya Zhuravlev <whatever@xyz.is> +Copyright (C) 2016 Nore, Nathanaƫl Courant <nore@mesecons.net> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef ENRICHEDSTRING_HEADER +#define ENRICHEDSTRING_HEADER + +#include <string> +#include <vector> +#include <SColor.h> + +class EnrichedString { +public: + EnrichedString(); + EnrichedString(const std::wstring &s, + const irr::video::SColor &color = irr::video::SColor(255, 255, 255, 255)); + EnrichedString(const wchar_t *str, + const irr::video::SColor &color = irr::video::SColor(255, 255, 255, 255)); + EnrichedString(const std::wstring &string, + const std::vector<irr::video::SColor> &colors); + void operator=(const wchar_t *str); + void addAtEnd(const std::wstring &s, const irr::video::SColor &color); + + // Adds the character source[i] at the end. + // An EnrichedString should always be able to be copied + // to the end of an existing EnrichedString that way. + void addChar(const EnrichedString &source, size_t i); + + // Adds a single character at the end, without specifying its + // color. The color used will be the one from the last character. + void addCharNoColor(wchar_t c); + + EnrichedString substr(size_t pos = 0, size_t len = std::string::npos) const; + EnrichedString operator+(const EnrichedString &other) const; + void operator+=(const EnrichedString &other); + const wchar_t *c_str() const; + const std::vector<irr::video::SColor> &getColors() const; + const std::wstring &getString() const; + inline bool operator==(const EnrichedString &other) const + { + return (m_string == other.m_string && m_colors == other.m_colors); + } + inline bool operator!=(const EnrichedString &other) const + { + return !(*this == other); + } + inline void clear() + { + m_string.clear(); + m_colors.clear(); + m_has_background = false; + } + inline bool empty() const + { + return m_string.empty(); + } + inline size_t size() const + { + return m_string.size(); + } + inline bool hasBackground() const + { + return m_has_background; + } + inline irr::video::SColor getBackground() const + { + return m_background; + } +private: + std::wstring m_string; + std::vector<irr::video::SColor> m_colors; + bool m_has_background; + irr::video::SColor m_background; +}; + +#endif diff --git a/src/util/numeric.cpp b/src/util/numeric.cpp index 42ebd9022..a9e7ae584 100644 --- a/src/util/numeric.cpp +++ b/src/util/numeric.cpp @@ -27,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include <string.h> #include <iostream> -std::map<u16, std::vector<v3s16> > FacePositionCache::m_cache; +UNORDERED_MAP<u16, std::vector<v3s16> > FacePositionCache::m_cache; Mutex FacePositionCache::m_cache_mutex; // Calculate the borders of a "d-radius" cube // TODO: Make it work without mutex and data races, probably thread-local @@ -188,14 +188,19 @@ u64 murmur_hash_64_ua(const void *key, int len, unsigned int seed) } /* - blockpos: position of block in block coordinates + blockpos_b: position of block in block coordinates camera_pos: position of camera in nodes camera_dir: an unit vector pointing to camera direction range: viewing range + distance_ptr: return location for distance from the camera */ bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, f32 camera_fov, f32 range, f32 *distance_ptr) { + // Maximum radius of a block. The magic number is + // sqrt(3.0) / 2.0 in literal form. + const f32 block_max_radius = 0.866025403784 * MAP_BLOCKSIZE * BS; + v3s16 blockpos_nodes = blockpos_b * MAP_BLOCKSIZE; // Block center position @@ -209,7 +214,7 @@ bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, v3f blockpos_relative = blockpos - camera_pos; // Total distance - f32 d = blockpos_relative.getLength(); + f32 d = MYMAX(0, blockpos_relative.getLength() - block_max_radius); if(distance_ptr) *distance_ptr = d; @@ -218,13 +223,9 @@ bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, if(d > range) return false; - // Maximum radius of a block. The magic number is - // sqrt(3.0) / 2.0 in literal form. - f32 block_max_radius = 0.866025403784 * MAP_BLOCKSIZE * BS; - // If block is (nearly) touching the camera, don't // bother validating further (that is, render it anyway) - if(d < block_max_radius) + if(d == 0) return true; // Adjust camera position, for purposes of computing the angle, diff --git a/src/util/numeric.h b/src/util/numeric.h index 615327864..4cdc254c3 100644 --- a/src/util/numeric.h +++ b/src/util/numeric.h @@ -26,8 +26,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "../irr_v3d.h" #include "../irr_aabb3d.h" #include "../threading/mutex.h" +#include "cpp11_container.h" #include <list> -#include <map> #include <vector> @@ -41,26 +41,10 @@ public: static std::vector<v3s16> getFacePositions(u16 d); private: static void generateFacePosition(u16 d); - static std::map<u16, std::vector<v3s16> > m_cache; + static UNORDERED_MAP<u16, std::vector<v3s16> > m_cache; static Mutex m_cache_mutex; }; -class IndentationRaiser -{ -public: - IndentationRaiser(u16 *indentation) - { - m_indentation = indentation; - (*m_indentation)++; - } - ~IndentationRaiser() - { - (*m_indentation)--; - } -private: - u16 *m_indentation; -}; - inline s16 getContainerPos(s16 p, s16 d) { return (p>=0 ? p : p-d+1) / d; @@ -149,23 +133,6 @@ inline bool isInArea(v3s16 p, v3s16 d) #define rangelim(d, min, max) ((d) < (min) ? (min) : ((d)>(max)?(max):(d))) #define myfloor(x) ((x) > 0.0 ? (int)(x) : (int)(x) - 1) -inline v3s16 arealim(v3s16 p, s16 d) -{ - if(p.X < 0) - p.X = 0; - if(p.Y < 0) - p.Y = 0; - if(p.Z < 0) - p.Z = 0; - if(p.X > d-1) - p.X = d-1; - if(p.Y > d-1) - p.Y = d-1; - if(p.Z > d-1) - p.Z = d-1; - return p; -} - // The naive swap performs better than the xor version #define SWAP(t, x, y) do { \ t temp = x; \ diff --git a/src/util/srp.cpp b/src/util/srp.cpp index 0d3c938a3..77c1816e8 100644 --- a/src/util/srp.cpp +++ b/src/util/srp.cpp @@ -542,7 +542,7 @@ static SRP_Result fill_buff() if (!fp) return SRP_ERR; - if (fread(g_rand_buff, sizeof(g_rand_buff), 1, fp) != 1) return SRP_ERR; + if (fread(g_rand_buff, sizeof(g_rand_buff), 1, fp) != 1) { fclose(fp); return SRP_ERR; } if (fclose(fp)) return SRP_ERR; #endif return SRP_OK; diff --git a/src/util/string.cpp b/src/util/string.cpp index 2c4143c76..94064ef93 100644 --- a/src/util/string.cpp +++ b/src/util/string.cpp @@ -314,7 +314,7 @@ std::string wide_to_narrow(const std::wstring &wcs) #endif -std::string urlencode(std::string str) +std::string urlencode(const std::string &str) { // Encodes non-unreserved URI characters by a percent sign // followed by two hex digits. See RFC 3986, section 2.3. @@ -322,17 +322,18 @@ std::string urlencode(std::string str) std::ostringstream oss(std::ios::binary); for (u32 i = 0; i < str.size(); i++) { unsigned char c = str[i]; - if (isalnum(c) || c == '-' || c == '.' || c == '_' || c == '~') + if (isalnum(c) || c == '-' || c == '.' || c == '_' || c == '~') { oss << c; - else + } else { oss << "%" << url_hex_chars[(c & 0xf0) >> 4] << url_hex_chars[c & 0x0f]; + } } return oss.str(); } -std::string urldecode(std::string str) +std::string urldecode(const std::string &str) { // Inverse of urlencode std::ostringstream oss(std::ios::binary); @@ -343,18 +344,20 @@ std::string urldecode(std::string str) hex_digit_decode(str[i+2], lowvalue)) { oss << (char) ((highvalue << 4) | lowvalue); i += 2; - } - else + } else { oss << str[i]; + } } return oss.str(); } u32 readFlagString(std::string str, const FlagDesc *flagdesc, u32 *flagmask) { - u32 result = 0, mask = 0; + u32 result = 0; + u32 mask = 0; char *s = &str[0]; - char *flagstr, *strpos = NULL; + char *flagstr; + char *strpos = NULL; while ((flagstr = strtok_r(s, ",", &strpos))) { s = NULL; diff --git a/src/util/string.h b/src/util/string.h index 40ef3e4d3..572c37150 100644 --- a/src/util/string.h +++ b/src/util/string.h @@ -21,12 +21,14 @@ with this program; if not, write to the Free Software Foundation, Inc., #define UTIL_STRING_HEADER #include "irrlichttypes_bloated.h" +#include "cpp11_container.h" #include <stdlib.h> #include <string> #include <cstring> #include <vector> #include <map> #include <sstream> +#include <iomanip> #include <cctype> #define STRINGIFY(x) #x @@ -53,7 +55,7 @@ with this program; if not, write to the Free Software Foundation, Inc., (((unsigned char)(x) < 0xe0) ? 2 : \ (((unsigned char)(x) < 0xf0) ? 3 : 4)) -typedef std::map<std::string, std::string> StringMap; +typedef UNORDERED_MAP<std::string, std::string> StringMap; struct FlagDesc { const char *name; @@ -77,8 +79,8 @@ wchar_t *narrow_to_wide_c(const char *str); std::wstring narrow_to_wide(const std::string &mbs); std::string wide_to_narrow(const std::wstring &wcs); -std::string urlencode(std::string str); -std::string urldecode(std::string str); +std::string urlencode(const std::string &str); +std::string urldecode(const std::string &str); u32 readFlagString(std::string str, const FlagDesc *flagdesc, u32 *flagmask); std::string writeFlagString(u32 flags, const FlagDesc *flagdesc, u32 flagmask); size_t mystrlcpy(char *dst, const char *src, size_t size); @@ -350,23 +352,57 @@ inline T from_string(const std::string &str) /// Returns a 64-bit signed value represented by the string \p str (decimal). inline s64 stoi64(const std::string &str) { return from_string<s64>(str); } -// TODO: Replace with C++11 std::to_string. +#if __cplusplus < 201103L +namespace std { /// Returns a string representing the value \p val. template <typename T> -inline std::string to_string(T val) +inline string to_string(T val) { - std::ostringstream oss; + ostringstream oss; oss << val; return oss.str(); } +#define DEFINE_STD_TOSTRING_FLOATINGPOINT(T) \ + template <> \ + inline string to_string<T>(T val) \ + { \ + ostringstream oss; \ + oss << std::fixed \ + << std::setprecision(6) \ + << val; \ + return oss.str(); \ + } +DEFINE_STD_TOSTRING_FLOATINGPOINT(float) +DEFINE_STD_TOSTRING_FLOATINGPOINT(double) +DEFINE_STD_TOSTRING_FLOATINGPOINT(long double) + +#undef DEFINE_STD_TOSTRING_FLOATINGPOINT + +/// Returns a wide string representing the value \p val +template <typename T> +inline wstring to_wstring(T val) +{ + return utf8_to_wide(to_string(val)); +} +} +#endif /// Returns a string representing the decimal value of the 32-bit value \p i. -inline std::string itos(s32 i) { return to_string(i); } +inline std::string itos(s32 i) { return std::to_string(i); } /// Returns a string representing the decimal value of the 64-bit value \p i. -inline std::string i64tos(s64 i) { return to_string(i); } +inline std::string i64tos(s64 i) { return std::to_string(i); } + +// std::to_string uses the '%.6f' conversion, which is inconsistent with +// std::ostream::operator<<() and impractical too. ftos() uses the +// more generic and std::ostream::operator<<()-compatible '%G' format. /// Returns a string representing the decimal value of the float value \p f. -inline std::string ftos(float f) { return to_string(f); } +inline std::string ftos(float f) +{ + std::ostringstream oss; + oss << f; + return oss.str(); +} /** @@ -519,6 +555,38 @@ std::basic_string<T> unescape_enriched(const std::basic_string<T> &s) return output; } +template <typename T> +std::vector<std::basic_string<T> > split(const std::basic_string<T> &s, T delim) +{ + std::vector<std::basic_string<T> > tokens; + + std::basic_string<T> current; + bool last_was_escape = false; + for (size_t i = 0; i < s.length(); i++) { + T si = s[i]; + if (last_was_escape) { + current += '\\'; + current += si; + last_was_escape = false; + } else { + if (si == delim) { + tokens.push_back(current); + current = std::basic_string<T>(); + last_was_escape = false; + } else if (si == '\\') { + last_was_escape = true; + } else { + current += si; + last_was_escape = false; + } + } + } + //push last element + tokens.push_back(current); + + return tokens; +} + /** * Checks that all characters in \p to_check are a decimal digits. * |