diff options
Diffstat (limited to 'src/utility.h')
-rw-r--r-- | src/utility.h | 299 |
1 files changed, 258 insertions, 41 deletions
diff --git a/src/utility.h b/src/utility.h index 2b878b82b..534aea483 100644 --- a/src/utility.h +++ b/src/utility.h @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include <fstream> #include <string> #include <sstream> +#include <vector> #include <jthread.h> #include <jmutex.h> #include <jmutexautolock.h> @@ -34,11 +35,25 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "exceptions.h" #include "porting.h" +extern const v3s16 g_6dirs[6]; + extern const v3s16 g_26dirs[26]; // 26th is (0,0,0) extern const v3s16 g_27dirs[27]; +inline void writeU64(u8 *data, u64 i) +{ + data[0] = ((i>>56)&0xff); + data[1] = ((i>>48)&0xff); + data[2] = ((i>>40)&0xff); + data[3] = ((i>>32)&0xff); + data[4] = ((i>>24)&0xff); + data[5] = ((i>>16)&0xff); + data[6] = ((i>> 8)&0xff); + data[7] = ((i>> 0)&0xff); +} + inline void writeU32(u8 *data, u32 i) { data[0] = ((i>>24)&0xff); @@ -58,6 +73,14 @@ inline void writeU8(u8 *data, u8 i) data[0] = ((i>> 0)&0xff); } +inline u64 readU64(u8 *data) +{ + return ((u64)data[0]<<56) | ((u64)data[1]<<48) + | ((u64)data[2]<<40) | ((u64)data[3]<<32) + | ((u64)data[4]<<24) | ((u64)data[5]<<16) + | ((u64)data[6]<<8) | ((u64)data[7]<<0); +} + inline u32 readU32(u8 *data) { return (data[0]<<24) | (data[1]<<16) | (data[2]<<8) | (data[3]<<0); @@ -73,8 +96,6 @@ inline u8 readU8(u8 *data) return (data[0]<<0); } -// Signed variants of the above - inline void writeS32(u8 *data, s32 i){ writeU32(data, (u32)i); } @@ -82,6 +103,13 @@ inline s32 readS32(u8 *data){ return (s32)readU32(data); } +inline void writeF1000(u8 *data, f32 i){ + writeS32(data, i*1000); +} +inline f32 readF1000(u8 *data){ + return (f32)readS32(data)/1000.; +} + inline void writeS16(u8 *data, s16 i){ writeU16(data, (u16)i); } @@ -95,7 +123,6 @@ inline void writeV3S32(u8 *data, v3s32 p) writeS32(&data[4], p.Y); writeS32(&data[8], p.Z); } - inline v3s32 readV3S32(u8 *data) { v3s32 p; @@ -105,6 +132,21 @@ inline v3s32 readV3S32(u8 *data) return p; } +inline void writeV3F1000(u8 *data, v3f p) +{ + writeF1000(&data[0], p.X); + writeF1000(&data[4], p.Y); + writeF1000(&data[8], p.Z); +} +inline v3f readV3F1000(u8 *data) +{ + v3f p; + p.X = (float)readF1000(&data[0]); + p.Y = (float)readF1000(&data[4]); + p.Z = (float)readF1000(&data[8]); + return p; +} + inline void writeV2S16(u8 *data, v2s16 p) { writeS16(&data[0], p.X); @@ -150,6 +192,78 @@ inline v3s16 readV3S16(u8 *data) } /* + The above stuff directly interfaced to iostream +*/ + +inline void writeU8(std::ostream &os, u8 p) +{ + char buf[1]; + writeU8((u8*)buf, p); + os.write(buf, 1); +} +inline u8 readU8(std::istream &is) +{ + char buf[1]; + is.read(buf, 1); + return readU8((u8*)buf); +} + +inline void writeU16(std::ostream &os, u16 p) +{ + char buf[2]; + writeU16((u8*)buf, p); + os.write(buf, 2); +} +inline u16 readU16(std::istream &is) +{ + char buf[2]; + is.read(buf, 2); + return readU16((u8*)buf); +} + +inline void writeU32(std::ostream &os, u16 p) +{ + char buf[4]; + writeU16((u8*)buf, p); + os.write(buf, 4); +} +inline u16 readU32(std::istream &is) +{ + char buf[4]; + is.read(buf, 4); + return readU32((u8*)buf); +} + +inline void writeF1000(std::ostream &os, f32 p) +{ + char buf[2]; + writeF1000((u8*)buf, p); + os.write(buf, 2); +} +inline f32 readF1000(std::istream &is) +{ + char buf[2]; + is.read(buf, 2); + // TODO: verify if this gets rid of the valgrind warning + //if(is.gcount() != 2) + // return 0; + return readF1000((u8*)buf); +} + +inline void writeV3F1000(std::ostream &os, v3f p) +{ + char buf[12]; + writeV3F1000((u8*)buf, p); + os.write(buf, 12); +} +inline v3f readV3F1000(std::istream &is) +{ + char buf[12]; + is.read(buf, 12); + return readV3F1000((u8*)buf); +} + +/* None of these are used at the moment */ @@ -273,10 +387,20 @@ template <typename T> class SharedBuffer { public: + SharedBuffer() + { + m_size = 0; + data = NULL; + refcount = new unsigned int; + (*refcount) = 1; + } SharedBuffer(unsigned int size) { m_size = size; - data = new T[size]; + if(m_size != 0) + data = new T[m_size]; + else + data = NULL; refcount = new unsigned int; (*refcount) = 1; } @@ -306,8 +430,13 @@ public: SharedBuffer(T *t, unsigned int size) { m_size = size; - data = new T[size]; - memcpy(data, t, size); + if(m_size != 0) + { + data = new T[m_size]; + memcpy(data, t, m_size); + } + else + data = NULL; refcount = new unsigned int; (*refcount) = 1; } @@ -316,9 +445,14 @@ public: */ SharedBuffer(const Buffer<T> &buffer) { - m_size = buffer.m_size; - data = new T[buffer.getSize()]; - memcpy(data, *buffer, buffer.getSize()); + m_size = buffer.getSize(); + if(m_size != 0) + { + data = new T[m_size]; + memcpy(data, *buffer, buffer.getSize()); + } + else + data = NULL; refcount = new unsigned int; (*refcount) = 1; } @@ -328,6 +462,7 @@ public: } T & operator[](unsigned int i) const { + //assert(i < m_size) return data[i]; } T * operator*() const @@ -345,7 +480,8 @@ private: (*refcount)--; if(*refcount == 0) { - delete[] data; + if(data) + delete[] data; delete refcount; } } @@ -399,8 +535,6 @@ private: TimeTaker */ -class IrrlichtWrapper; - class TimeTaker { public: @@ -636,6 +770,19 @@ inline std::string wide_to_narrow(const std::wstring& wcs) return *mbs; } +// Split a string using the given delimiter. Returns a vector containing +// the component parts. +inline std::vector<std::wstring> str_split(const std::wstring &str, wchar_t delimiter) +{ + std::vector<std::wstring> parts; + std::wstringstream sstr(str); + std::wstring part; + while(std::getline(sstr, part, delimiter)) + parts.push_back(part); + return parts; +} + + /* See test.cpp for example cases. wraps degrees to the range of -360...360 @@ -691,11 +838,20 @@ inline s32 stoi(const std::string &s, s32 min, s32 max) return i; } + +// MSVC2010 includes it's own versions of these +#if !defined(_MSC_VER) || _MSC_VER < 1600 + inline s32 stoi(std::string s) { return atoi(s.c_str()); } +inline s32 stoi(std::wstring s) +{ + return atoi(wide_to_narrow(s).c_str()); +} + inline float stof(std::string s) { float f; @@ -704,6 +860,8 @@ inline float stof(std::string s) return f; } +#endif + inline std::string itos(s32 i) { std::ostringstream o; @@ -1234,6 +1392,14 @@ public: return value; } + void setBool(std::string name, bool value) + { + if(value) + set(name, "true"); + else + set(name, "false"); + } + void setS32(std::string name, s32 value) { set(name, itos(value)); @@ -1369,6 +1535,7 @@ public: } u32 size() { + JMutexAutoLock lock(m_mutex); return m_list.size(); } void push_back(T t) @@ -1444,6 +1611,10 @@ protected: core::list<T> m_list; }; +/* + A single worker thread - multiple client threads queue framework. +*/ + template<typename Caller, typename Data> class CallerInfo { @@ -1493,11 +1664,6 @@ public: core::list<CallerInfo<Caller, CallerData> > callers; }; -/* - Quickhands for typical request-result queues. - Used for distributing work between threads. -*/ - template<typename Key, typename T, typename Caller, typename CallerData> class RequestQueue { @@ -1638,12 +1804,12 @@ private: core::list<Value> m_list; }; -#if 0 +#if 1 template<typename Key, typename Value> -class MutexedCache +class MutexedMap { public: - MutexedCache() + MutexedMap() { m_mutex.Init(); assert(m_mutex.IsInitialized()); @@ -1665,8 +1831,10 @@ public: if(n == NULL) return false; - - *result = n->getValue(); + + if(result != NULL) + *result = n->getValue(); + return true; } @@ -1806,9 +1974,11 @@ inline v3f intToFloat(v3s16 p, f32 d) */ // Creates a string with the length as the first two bytes -inline std::string serializeString(const std::string plain) +inline std::string serializeString(const std::string &plain) { - assert(plain.size() <= 65535); + //assert(plain.size() <= 65535); + if(plain.size() > 65535) + throw SerializationError("String too long for serializeString"); char buf[2]; writeU16((u8*)&buf[0], plain.size()); std::string s; @@ -1817,13 +1987,21 @@ inline std::string serializeString(const std::string plain) return s; } -// Reads a string with the length as the first two bytes -inline std::string deSerializeString(const std::string encoded) +// Creates a string with the length as the first two bytes from wide string +inline std::string serializeWideString(const std::wstring &plain) { - u16 s_size = readU16((u8*)&encoded.c_str()[0]); + //assert(plain.size() <= 65535); + if(plain.size() > 65535) + throw SerializationError("String too long for serializeString"); + char buf[2]; + writeU16((u8*)buf, plain.size()); std::string s; - s.reserve(s_size); - s.append(&encoded.c_str()[2], s_size); + s.append(buf, 2); + for(u32 i=0; i<plain.size(); i++) + { + writeU16((u8*)buf, plain[i]); + s.append(buf, 2); + } return s; } @@ -1845,8 +2023,29 @@ inline std::string deSerializeString(std::istream &is) return s; } +// Reads a wide string with the length as the first two bytes +inline std::wstring deSerializeWideString(std::istream &is) +{ + char buf[2]; + is.read(buf, 2); + if(is.gcount() != 2) + throw SerializationError("deSerializeString: size not read"); + u16 s_size = readU16((u8*)buf); + if(s_size == 0) + return L""; + std::wstring s; + s.reserve(s_size); + for(u32 i=0; i<s_size; i++) + { + is.read(&buf[0], 2); + wchar_t c16 = readU16((u8*)buf); + s.append(&c16, 1); + } + return s; +} + // Creates a string with the length as the first four bytes -inline std::string serializeLongString(const std::string plain) +inline std::string serializeLongString(const std::string &plain) { char buf[4]; writeU32((u8*)&buf[0], plain.size()); @@ -1857,16 +2056,6 @@ inline std::string serializeLongString(const std::string plain) } // Reads a string with the length as the first four bytes -inline std::string deSerializeLongString(const std::string encoded) -{ - u32 s_size = readU32((u8*)&encoded.c_str()[0]); - std::string s; - s.reserve(s_size); - s.append(&encoded.c_str()[2], s_size); - return s; -} - -// Reads a string with the length as the first four bytes inline std::string deSerializeLongString(std::istream &is) { char buf[4]; @@ -1894,7 +2083,8 @@ inline u32 time_to_daynight_ratio(u32 time_of_day) s32 d = daylength; s32 t = (((time_of_day)%24000)/(24000/d)); if(t < nightlength/2 || t >= d - nightlength/2) - return 300; + //return 300; + return 350; else if(t >= d/2 - daytimelength/2 && t < d/2 + daytimelength/2) return 1000; else @@ -1914,6 +2104,33 @@ inline core::aabbox3d<f32> getNodeBox(v3s16 p, float d) ); } +class IntervalLimiter +{ +public: + IntervalLimiter(): + m_accumulator(0) + { + } + /* + dtime: time from last call to this method + wanted_interval: interval wanted + return value: + true: action should be skipped + false: action should be done + */ + bool step(float dtime, float wanted_interval) + { + m_accumulator += dtime; + if(m_accumulator < wanted_interval) + return false; + m_accumulator -= wanted_interval; + return true; + } +protected: + float m_accumulator; +}; + +std::string translatePassword(std::string playername, std::wstring password); #endif |