summaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/util')
-rw-r--r--src/util/CMakeLists.txt1
-rw-r--r--src/util/areastore.cpp1
-rw-r--r--src/util/auth.h2
-rw-r--r--src/util/cpp11_container.h43
-rw-r--r--src/util/enriched_string.cpp166
-rw-r--r--src/util/enriched_string.h91
-rw-r--r--src/util/numeric.cpp17
-rw-r--r--src/util/numeric.h37
-rw-r--r--src/util/srp.cpp2
-rw-r--r--src/util/string.cpp19
-rw-r--r--src/util/string.h86
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.
*