Some MSVC fixes
[oweals/minetest.git] / src / utility.h
1 /*
2 Minetest-c55
3 Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #ifndef UTILITY_HEADER
21 #define UTILITY_HEADER
22
23 #include <iostream>
24 #include <fstream>
25 #include <string>
26 #include <sstream>
27 #include <vector>
28 #include <jthread.h>
29 #include <jmutex.h>
30 #include <jmutexautolock.h>
31 #include <cstring>
32
33 #include "common_irrlicht.h"
34 #include "debug.h"
35 #include "exceptions.h"
36 #include "porting.h"
37 #include "strfnd.h" // For trim()
38
39 extern const v3s16 g_6dirs[6];
40
41 extern const v3s16 g_26dirs[26];
42
43 // 26th is (0,0,0)
44 extern const v3s16 g_27dirs[27];
45
46 inline void writeU64(u8 *data, u64 i)
47 {
48         data[0] = ((i>>56)&0xff);
49         data[1] = ((i>>48)&0xff);
50         data[2] = ((i>>40)&0xff);
51         data[3] = ((i>>32)&0xff);
52         data[4] = ((i>>24)&0xff);
53         data[5] = ((i>>16)&0xff);
54         data[6] = ((i>> 8)&0xff);
55         data[7] = ((i>> 0)&0xff);
56 }
57
58 inline void writeU32(u8 *data, u32 i)
59 {
60         data[0] = ((i>>24)&0xff);
61         data[1] = ((i>>16)&0xff);
62         data[2] = ((i>> 8)&0xff);
63         data[3] = ((i>> 0)&0xff);
64 }
65
66 inline void writeU16(u8 *data, u16 i)
67 {
68         data[0] = ((i>> 8)&0xff);
69         data[1] = ((i>> 0)&0xff);
70 }
71
72 inline void writeU8(u8 *data, u8 i)
73 {
74         data[0] = ((i>> 0)&0xff);
75 }
76
77 inline u64 readU64(u8 *data)
78 {
79         return ((u64)data[0]<<56) | ((u64)data[1]<<48)
80                 | ((u64)data[2]<<40) | ((u64)data[3]<<32)
81                 | ((u64)data[4]<<24) | ((u64)data[5]<<16)
82                 | ((u64)data[6]<<8) | ((u64)data[7]<<0);
83 }
84
85 inline u32 readU32(u8 *data)
86 {
87         return (data[0]<<24) | (data[1]<<16) | (data[2]<<8) | (data[3]<<0);
88 }
89
90 inline u16 readU16(u8 *data)
91 {
92         return (data[0]<<8) | (data[1]<<0);
93 }
94
95 inline u8 readU8(u8 *data)
96 {
97         return (data[0]<<0);
98 }
99
100 inline void writeS32(u8 *data, s32 i){
101         writeU32(data, (u32)i);
102 }
103 inline s32 readS32(u8 *data){
104         return (s32)readU32(data);
105 }
106
107 inline void writeF1000(u8 *data, f32 i){
108         writeS32(data, i*1000);
109 }
110 inline f32 readF1000(u8 *data){
111         return (f32)readS32(data)/1000.;
112 }
113
114 inline void writeS16(u8 *data, s16 i){
115         writeU16(data, (u16)i);
116 }
117 inline s16 readS16(u8 *data){
118         return (s16)readU16(data);
119 }
120
121 inline void writeV3S32(u8 *data, v3s32 p)
122 {
123         writeS32(&data[0], p.X);
124         writeS32(&data[4], p.Y);
125         writeS32(&data[8], p.Z);
126 }
127 inline v3s32 readV3S32(u8 *data)
128 {
129         v3s32 p;
130         p.X = readS32(&data[0]);
131         p.Y = readS32(&data[4]);
132         p.Z = readS32(&data[8]);
133         return p;
134 }
135
136 inline void writeV3F1000(u8 *data, v3f p)
137 {
138         writeF1000(&data[0], p.X);
139         writeF1000(&data[4], p.Y);
140         writeF1000(&data[8], p.Z);
141 }
142 inline v3f readV3F1000(u8 *data)
143 {
144         v3f p;
145         p.X = (float)readF1000(&data[0]);
146         p.Y = (float)readF1000(&data[4]);
147         p.Z = (float)readF1000(&data[8]);
148         return p;
149 }
150
151 inline void writeV2F1000(u8 *data, v2f p)
152 {
153         writeF1000(&data[0], p.X);
154         writeF1000(&data[4], p.Y);
155 }
156 inline v2f readV2F1000(u8 *data)
157 {
158         v2f p;
159         p.X = (float)readF1000(&data[0]);
160         p.Y = (float)readF1000(&data[4]);
161         return p;
162 }
163
164 inline void writeV2S16(u8 *data, v2s16 p)
165 {
166         writeS16(&data[0], p.X);
167         writeS16(&data[2], p.Y);
168 }
169
170 inline v2s16 readV2S16(u8 *data)
171 {
172         v2s16 p;
173         p.X = readS16(&data[0]);
174         p.Y = readS16(&data[2]);
175         return p;
176 }
177
178 inline void writeV2S32(u8 *data, v2s32 p)
179 {
180         writeS32(&data[0], p.X);
181         writeS32(&data[2], p.Y);
182 }
183
184 inline v2s32 readV2S32(u8 *data)
185 {
186         v2s32 p;
187         p.X = readS32(&data[0]);
188         p.Y = readS32(&data[2]);
189         return p;
190 }
191
192 inline void writeV3S16(u8 *data, v3s16 p)
193 {
194         writeS16(&data[0], p.X);
195         writeS16(&data[2], p.Y);
196         writeS16(&data[4], p.Z);
197 }
198
199 inline v3s16 readV3S16(u8 *data)
200 {
201         v3s16 p;
202         p.X = readS16(&data[0]);
203         p.Y = readS16(&data[2]);
204         p.Z = readS16(&data[4]);
205         return p;
206 }
207
208 /*
209         The above stuff directly interfaced to iostream
210 */
211
212 inline void writeU8(std::ostream &os, u8 p)
213 {
214         char buf[1];
215         writeU8((u8*)buf, p);
216         os.write(buf, 1);
217 }
218 inline u8 readU8(std::istream &is)
219 {
220         char buf[1];
221         is.read(buf, 1);
222         return readU8((u8*)buf);
223 }
224
225 inline void writeU16(std::ostream &os, u16 p)
226 {
227         char buf[2];
228         writeU16((u8*)buf, p);
229         os.write(buf, 2);
230 }
231 inline u16 readU16(std::istream &is)
232 {
233         char buf[2];
234         is.read(buf, 2);
235         return readU16((u8*)buf);
236 }
237
238 inline void writeU32(std::ostream &os, u32 p)
239 {
240         char buf[4];
241         writeU32((u8*)buf, p);
242         os.write(buf, 4);
243 }
244 inline u32 readU32(std::istream &is)
245 {
246         char buf[4];
247         is.read(buf, 4);
248         return readU32((u8*)buf);
249 }
250
251 inline void writeS32(std::ostream &os, u32 p)
252 {
253         char buf[4];
254         writeS32((u8*)buf, p);
255         os.write(buf, 4);
256 }
257 inline u32 readS32(std::istream &is)
258 {
259         char buf[4];
260         is.read(buf, 4);
261         return readS32((u8*)buf);
262 }
263
264 inline void writeF1000(std::ostream &os, f32 p)
265 {
266         char buf[4];
267         writeF1000((u8*)buf, p);
268         os.write(buf, 4);
269 }
270 inline f32 readF1000(std::istream &is)
271 {
272         char buf[4];
273         is.read(buf, 4);
274         return readF1000((u8*)buf);
275 }
276
277 inline void writeV3F1000(std::ostream &os, v3f p)
278 {
279         char buf[12];
280         writeV3F1000((u8*)buf, p);
281         os.write(buf, 12);
282 }
283 inline v3f readV3F1000(std::istream &is)
284 {
285         char buf[12];
286         is.read(buf, 12);
287         return readV3F1000((u8*)buf);
288 }
289
290 inline void writeV2F1000(std::ostream &os, v2f p)
291 {
292         char buf[8];
293         writeV2F1000((u8*)buf, p);
294         os.write(buf, 8);
295 }
296 inline v2f readV2F1000(std::istream &is)
297 {
298         char buf[8];
299         is.read(buf, 8);
300         return readV2F1000((u8*)buf);
301 }
302
303 inline void writeV2S16(std::ostream &os, v2s16 p)
304 {
305         char buf[4];
306         writeV2S16((u8*)buf, p);
307         os.write(buf, 4);
308 }
309 inline v2s16 readV2S16(std::istream &is)
310 {
311         char buf[4];
312         is.read(buf, 4);
313         return readV2S16((u8*)buf);
314 }
315
316 inline void writeV3S16(std::ostream &os, v3s16 p)
317 {
318         char buf[6];
319         writeV3S16((u8*)buf, p);
320         os.write(buf, 6);
321 }
322 inline v3s16 readV3S16(std::istream &is)
323 {
324         char buf[6];
325         is.read(buf, 6);
326         return readV3S16((u8*)buf);
327 }
328
329 /*
330         None of these are used at the moment
331 */
332
333 template <typename T>
334 class SharedPtr
335 {
336 public:
337         SharedPtr(T *t=NULL)
338         {
339                 refcount = new int;
340                 *refcount = 1;
341                 ptr = t;
342         }
343         SharedPtr(SharedPtr<T> &t)
344         {
345                 //*this = t;
346                 drop();
347                 refcount = t.refcount;
348                 (*refcount)++;
349                 ptr = t.ptr;
350         }
351         ~SharedPtr()
352         {
353                 drop();
354         }
355         SharedPtr<T> & operator=(T *t)
356         {
357                 drop();
358                 refcount = new int;
359                 *refcount = 1;
360                 ptr = t;
361                 return *this;
362         }
363         SharedPtr<T> & operator=(SharedPtr<T> &t)
364         {
365                 drop();
366                 refcount = t.refcount;
367                 (*refcount)++;
368                 ptr = t.ptr;
369                 return *this;
370         }
371         T* operator->()
372         {
373                 return ptr;
374         }
375         T & operator*()
376         {
377                 return *ptr;
378         }
379         bool operator!=(T *t)
380         {
381                 return ptr != t;
382         }
383         bool operator==(T *t)
384         {
385                 return ptr == t;
386         }
387         T & operator[](unsigned int i)
388         {
389                 return ptr[i];
390         }
391 private:
392         void drop()
393         {
394                 assert((*refcount) > 0);
395                 (*refcount)--;
396                 if(*refcount == 0)
397                 {
398                         delete refcount;
399                         if(ptr != NULL)
400                                 delete ptr;
401                 }
402         }
403         T *ptr;
404         int *refcount;
405 };
406
407 template <typename T>
408 class Buffer
409 {
410 public:
411         Buffer()
412         {
413                 m_size = 0;
414                 data = NULL;
415         }
416         Buffer(unsigned int size)
417         {
418                 m_size = size;
419                 if(size != 0)
420                         data = new T[size];
421                 else
422                         data = NULL;
423         }
424         Buffer(const Buffer &buffer)
425         {
426                 m_size = buffer.m_size;
427                 if(m_size != 0)
428                 {
429                         data = new T[buffer.m_size];
430                         memcpy(data, buffer.data, buffer.m_size);
431                 }
432                 else
433                         data = NULL;
434         }
435         Buffer(const T *t, unsigned int size)
436         {
437                 m_size = size;
438                 if(size != 0)
439                 {
440                         data = new T[size];
441                         memcpy(data, t, size);
442                 }
443                 else
444                         data = NULL;
445         }
446         ~Buffer()
447         {
448                 drop();
449         }
450         Buffer& operator=(const Buffer &buffer)
451         {
452                 if(this == &buffer)
453                         return *this;
454                 drop();
455                 m_size = buffer.m_size;
456                 if(m_size != 0)
457                 {
458                         data = new T[buffer.m_size];
459                         memcpy(data, buffer.data, buffer.m_size);
460                 }
461                 else
462                         data = NULL;
463                 return *this;
464         }
465         T & operator[](unsigned int i) const
466         {
467                 return data[i];
468         }
469         T * operator*() const
470         {
471                 return data;
472         }
473         unsigned int getSize() const
474         {
475                 return m_size;
476         }
477 private:
478         void drop()
479         {
480                 if(data)
481                         delete[] data;
482         }
483         T *data;
484         unsigned int m_size;
485 };
486
487 template <typename T>
488 class SharedBuffer
489 {
490 public:
491         SharedBuffer()
492         {
493                 m_size = 0;
494                 data = NULL;
495                 refcount = new unsigned int;
496                 (*refcount) = 1;
497         }
498         SharedBuffer(unsigned int size)
499         {
500                 m_size = size;
501                 if(m_size != 0)
502                         data = new T[m_size];
503                 else
504                         data = NULL;
505                 refcount = new unsigned int;
506                 (*refcount) = 1;
507         }
508         SharedBuffer(const SharedBuffer &buffer)
509         {
510                 //std::cout<<"SharedBuffer(const SharedBuffer &buffer)"<<std::endl;
511                 m_size = buffer.m_size;
512                 data = buffer.data;
513                 refcount = buffer.refcount;
514                 (*refcount)++;
515         }
516         SharedBuffer & operator=(const SharedBuffer & buffer)
517         {
518                 //std::cout<<"SharedBuffer & operator=(const SharedBuffer & buffer)"<<std::endl;
519                 if(this == &buffer)
520                         return *this;
521                 drop();
522                 m_size = buffer.m_size;
523                 data = buffer.data;
524                 refcount = buffer.refcount;
525                 (*refcount)++;
526                 return *this;
527         }
528         /*
529                 Copies whole buffer
530         */
531         SharedBuffer(T *t, unsigned int size)
532         {
533                 m_size = size;
534                 if(m_size != 0)
535                 {
536                         data = new T[m_size];
537                         memcpy(data, t, m_size);
538                 }
539                 else
540                         data = NULL;
541                 refcount = new unsigned int;
542                 (*refcount) = 1;
543         }
544         /*
545                 Copies whole buffer
546         */
547         SharedBuffer(const Buffer<T> &buffer)
548         {
549                 m_size = buffer.getSize();
550                 if(m_size != 0)
551                 {
552                         data = new T[m_size];
553                         memcpy(data, *buffer, buffer.getSize());
554                 }
555                 else
556                         data = NULL;
557                 refcount = new unsigned int;
558                 (*refcount) = 1;
559         }
560         ~SharedBuffer()
561         {
562                 drop();
563         }
564         T & operator[](unsigned int i) const
565         {
566                 //assert(i < m_size)
567                 return data[i];
568         }
569         T * operator*() const
570         {
571                 return data;
572         }
573         unsigned int getSize() const
574         {
575                 return m_size;
576         }
577         operator Buffer<T>() const
578         {
579                 return Buffer<T>(data, m_size);
580         }
581 private:
582         void drop()
583         {
584                 assert((*refcount) > 0);
585                 (*refcount)--;
586                 if(*refcount == 0)
587                 {
588                         if(data)
589                                 delete[] data;
590                         delete refcount;
591                 }
592         }
593         T *data;
594         unsigned int m_size;
595         unsigned int *refcount;
596 };
597
598 inline SharedBuffer<u8> SharedBufferFromString(const char *string)
599 {
600         SharedBuffer<u8> b((u8*)string, strlen(string)+1);
601         return b;
602 }
603
604 template<typename T>
605 class MutexedVariable
606 {
607 public:
608         MutexedVariable(T value):
609                 m_value(value)
610         {
611                 m_mutex.Init();
612         }
613
614         T get()
615         {
616                 JMutexAutoLock lock(m_mutex);
617                 return m_value;
618         }
619
620         void set(T value)
621         {
622                 JMutexAutoLock lock(m_mutex);
623                 m_value = value;
624         }
625         
626         // You'll want to grab this in a SharedPtr
627         JMutexAutoLock * getLock()
628         {
629                 return new JMutexAutoLock(m_mutex);
630         }
631         
632         // You pretty surely want to grab the lock when accessing this
633         T m_value;
634
635 private:
636         JMutex m_mutex;
637 };
638
639 /*
640         TimeTaker
641 */
642
643 class TimeTaker
644 {
645 public:
646         TimeTaker(const char *name, u32 *result=NULL);
647
648         ~TimeTaker()
649         {
650                 stop();
651         }
652
653         u32 stop(bool quiet=false);
654
655         u32 getTime();
656
657 private:
658         const char *m_name;
659         u32 m_time1;
660         bool m_running;
661         u32 *m_result;
662 };
663
664 #ifndef SERVER
665 // Sets the color of all vertices in the mesh
666 void setMeshVerticesColor(scene::IMesh* mesh, video::SColor& color);
667 #endif
668
669 // Calculates the borders of a "d-radius" cube
670 inline void getFacePositions(core::list<v3s16> &list, u16 d)
671 {
672         if(d == 0)
673         {
674                 list.push_back(v3s16(0,0,0));
675                 return;
676         }
677         if(d == 1)
678         {
679                 /*
680                         This is an optimized sequence of coordinates.
681                 */
682                 list.push_back(v3s16( 0, 1, 0)); // top
683                 list.push_back(v3s16( 0, 0, 1)); // back
684                 list.push_back(v3s16(-1, 0, 0)); // left
685                 list.push_back(v3s16( 1, 0, 0)); // right
686                 list.push_back(v3s16( 0, 0,-1)); // front
687                 list.push_back(v3s16( 0,-1, 0)); // bottom
688                 // 6
689                 list.push_back(v3s16(-1, 0, 1)); // back left
690                 list.push_back(v3s16( 1, 0, 1)); // back right
691                 list.push_back(v3s16(-1, 0,-1)); // front left
692                 list.push_back(v3s16( 1, 0,-1)); // front right
693                 list.push_back(v3s16(-1,-1, 0)); // bottom left
694                 list.push_back(v3s16( 1,-1, 0)); // bottom right
695                 list.push_back(v3s16( 0,-1, 1)); // bottom back
696                 list.push_back(v3s16( 0,-1,-1)); // bottom front
697                 list.push_back(v3s16(-1, 1, 0)); // top left
698                 list.push_back(v3s16( 1, 1, 0)); // top right
699                 list.push_back(v3s16( 0, 1, 1)); // top back
700                 list.push_back(v3s16( 0, 1,-1)); // top front
701                 // 18
702                 list.push_back(v3s16(-1, 1, 1)); // top back-left
703                 list.push_back(v3s16( 1, 1, 1)); // top back-right
704                 list.push_back(v3s16(-1, 1,-1)); // top front-left
705                 list.push_back(v3s16( 1, 1,-1)); // top front-right
706                 list.push_back(v3s16(-1,-1, 1)); // bottom back-left
707                 list.push_back(v3s16( 1,-1, 1)); // bottom back-right
708                 list.push_back(v3s16(-1,-1,-1)); // bottom front-left
709                 list.push_back(v3s16( 1,-1,-1)); // bottom front-right
710                 // 26
711                 return;
712         }
713
714         // Take blocks in all sides, starting from y=0 and going +-y
715         for(s16 y=0; y<=d-1; y++)
716         {
717                 // Left and right side, including borders
718                 for(s16 z=-d; z<=d; z++)
719                 {
720                         list.push_back(v3s16(d,y,z));
721                         list.push_back(v3s16(-d,y,z));
722                         if(y != 0)
723                         {
724                                 list.push_back(v3s16(d,-y,z));
725                                 list.push_back(v3s16(-d,-y,z));
726                         }
727                 }
728                 // Back and front side, excluding borders
729                 for(s16 x=-d+1; x<=d-1; x++)
730                 {
731                         list.push_back(v3s16(x,y,d));
732                         list.push_back(v3s16(x,y,-d));
733                         if(y != 0)
734                         {
735                                 list.push_back(v3s16(x,-y,d));
736                                 list.push_back(v3s16(x,-y,-d));
737                         }
738                 }
739         }
740
741         // Take the bottom and top face with borders
742         // -d<x<d, y=+-d, -d<z<d
743         for(s16 x=-d; x<=d; x++)
744         for(s16 z=-d; z<=d; z++)
745         {
746                 list.push_back(v3s16(x,-d,z));
747                 list.push_back(v3s16(x,d,z));
748         }
749 }
750
751 class IndentationRaiser
752 {
753 public:
754         IndentationRaiser(u16 *indentation)
755         {
756                 m_indentation = indentation;
757                 (*m_indentation)++;
758         }
759         ~IndentationRaiser()
760         {
761                 (*m_indentation)--;
762         }
763 private:
764         u16 *m_indentation;
765 };
766
767 inline s16 getContainerPos(s16 p, s16 d)
768 {
769         return (p>=0 ? p : p-d+1) / d;
770 }
771
772 inline v2s16 getContainerPos(v2s16 p, s16 d)
773 {
774         return v2s16(
775                 getContainerPos(p.X, d),
776                 getContainerPos(p.Y, d)
777         );
778 }
779
780 inline v3s16 getContainerPos(v3s16 p, s16 d)
781 {
782         return v3s16(
783                 getContainerPos(p.X, d),
784                 getContainerPos(p.Y, d),
785                 getContainerPos(p.Z, d)
786         );
787 }
788
789 inline v2s16 getContainerPos(v2s16 p, v2s16 d)
790 {
791         return v2s16(
792                 getContainerPos(p.X, d.X),
793                 getContainerPos(p.Y, d.Y)
794         );
795 }
796
797 inline v3s16 getContainerPos(v3s16 p, v3s16 d)
798 {
799         return v3s16(
800                 getContainerPos(p.X, d.X),
801                 getContainerPos(p.Y, d.Y),
802                 getContainerPos(p.Z, d.Z)
803         );
804 }
805
806 inline bool isInArea(v3s16 p, s16 d)
807 {
808         return (
809                 p.X >= 0 && p.X < d &&
810                 p.Y >= 0 && p.Y < d &&
811                 p.Z >= 0 && p.Z < d
812         );
813 }
814
815 inline bool isInArea(v2s16 p, s16 d)
816 {
817         return (
818                 p.X >= 0 && p.X < d &&
819                 p.Y >= 0 && p.Y < d
820         );
821 }
822
823 inline bool isInArea(v3s16 p, v3s16 d)
824 {
825         return (
826                 p.X >= 0 && p.X < d.X &&
827                 p.Y >= 0 && p.Y < d.Y &&
828                 p.Z >= 0 && p.Z < d.Z
829         );
830 }
831
832 inline s16 rangelim(s16 i, s16 max)
833 {
834         if(i < 0)
835                 return 0;
836         if(i > max)
837                 return max;
838         return i;
839 }
840
841 #define rangelim(d, min, max) ((d) < (min) ? (min) : ((d)>(max)?(max):(d)))
842
843 inline v3s16 arealim(v3s16 p, s16 d)
844 {
845         if(p.X < 0)
846                 p.X = 0;
847         if(p.Y < 0)
848                 p.Y = 0;
849         if(p.Z < 0)
850                 p.Z = 0;
851         if(p.X > d-1)
852                 p.X = d-1;
853         if(p.Y > d-1)
854                 p.Y = d-1;
855         if(p.Z > d-1)
856                 p.Z = d-1;
857         return p;
858 }
859
860 inline std::wstring narrow_to_wide(const std::string& mbs)
861 {
862         size_t wcl = mbs.size();
863         Buffer<wchar_t> wcs(wcl+1);
864         size_t l = mbstowcs(*wcs, mbs.c_str(), wcl);
865         if(l == (size_t)(-1))
866                 return L"<invalid multibyte string>";
867         wcs[l] = 0;
868         return *wcs;
869 }
870
871 inline std::string wide_to_narrow(const std::wstring& wcs)
872 {
873         size_t mbl = wcs.size()*4;
874         SharedBuffer<char> mbs(mbl+1);
875         size_t l = wcstombs(*mbs, wcs.c_str(), mbl);
876         if(l == (size_t)(-1))
877                 mbs[0] = 0;
878         else
879                 mbs[l] = 0;
880         return *mbs;
881 }
882
883 // Split a string using the given delimiter. Returns a vector containing
884 // the component parts.
885 inline std::vector<std::wstring> str_split(const std::wstring &str, wchar_t delimiter)
886 {
887         std::vector<std::wstring> parts;
888         std::wstringstream sstr(str);
889         std::wstring part;
890         while(std::getline(sstr, part, delimiter))
891                 parts.push_back(part);
892         return parts;
893 }
894
895
896 /*
897         See test.cpp for example cases.
898         wraps degrees to the range of -360...360
899         NOTE: Wrapping to 0...360 is not used because pitch needs negative values.
900 */
901 inline float wrapDegrees(float f)
902 {
903         // Take examples of f=10, f=720.5, f=-0.5, f=-360.5
904         // This results in
905         // 10, 720, -1, -361
906         int i = floor(f);
907         // 0, 2, 0, -1
908         int l = i / 360;
909         // NOTE: This would be used for wrapping to 0...360
910         // 0, 2, -1, -2
911         /*if(i < 0)
912                 l -= 1;*/
913         // 0, 720, 0, -360
914         int k = l * 360;
915         // 10, 0.5, -0.5, -0.5
916         f -= float(k);
917         return f;
918 }
919
920 /* Wrap to 0...360 */
921 inline float wrapDegrees_0_360(float f)
922 {
923         // Take examples of f=10, f=720.5, f=-0.5, f=-360.5
924         // This results in
925         // 10, 720, -1, -361
926         int i = floor(f);
927         // 0, 2, 0, -1
928         int l = i / 360;
929         // Wrap to 0...360
930         // 0, 2, -1, -2
931         if(i < 0)
932                 l -= 1;
933         // 0, 720, 0, -360
934         int k = l * 360;
935         // 10, 0.5, -0.5, -0.5
936         f -= float(k);
937         return f;
938 }
939
940 /* Wrap to -180...180 */
941 inline float wrapDegrees_180(float f)
942 {
943         f += 180;
944         f = wrapDegrees_0_360(f);
945         f -= 180;
946         return f;
947 }
948
949 inline std::string lowercase(const std::string &s)
950 {
951         std::string s2;
952         for(size_t i=0; i<s.size(); i++)
953         {
954                 char c = s[i];
955                 if(c >= 'A' && c <= 'Z')
956                         c -= 'A' - 'a';
957                 s2 += c;
958         }
959         return s2;
960 }
961
962 inline bool is_yes(const std::string &s)
963 {
964         std::string s2 = lowercase(trim(s));
965         if(s2 == "y" || s2 == "yes" || s2 == "true" || s2 == "1")
966                 return true;
967         return false;
968 }
969
970 inline s32 mystoi(const std::string &s, s32 min, s32 max)
971 {
972         s32 i = atoi(s.c_str());
973         if(i < min)
974                 i = min;
975         if(i > max)
976                 i = max;
977         return i;
978 }
979
980
981 // MSVC2010 includes it's own versions of these
982 //#if !defined(_MSC_VER) || _MSC_VER < 1600
983
984 inline s32 mystoi(std::string s)
985 {
986         return atoi(s.c_str());
987 }
988
989 inline s32 mystoi(std::wstring s)
990 {
991         return atoi(wide_to_narrow(s).c_str());
992 }
993
994 inline float mystof(std::string s)
995 {
996         float f;
997         std::istringstream ss(s);
998         ss>>f;
999         return f;
1000 }
1001
1002 //#endif
1003
1004 #define stoi mystoi
1005 #define stof mystof
1006
1007 inline std::string itos(s32 i)
1008 {
1009         std::ostringstream o;
1010         o<<i;
1011         return o.str();
1012 }
1013
1014 inline std::string ftos(float f)
1015 {
1016         std::ostringstream o;
1017         o<<f;
1018         return o.str();
1019 }
1020
1021 inline void str_replace(std::string & str, std::string const & pattern,
1022                 std::string const & replacement)
1023 {
1024         std::string::size_type start = str.find(pattern, 0);
1025         while(start != str.npos)
1026         {
1027                 str.replace(start, pattern.size(), replacement);
1028                 start = str.find(pattern, start+replacement.size());
1029         }
1030 }
1031
1032 inline void str_replace_char(std::string & str, char from, char to)
1033 {
1034         for(unsigned int i=0; i<str.size(); i++)
1035         {
1036                 if(str[i] == from)
1037                         str[i] = to;
1038         }
1039 }
1040
1041 /*
1042         A base class for simple background thread implementation
1043 */
1044
1045 class SimpleThread : public JThread
1046 {
1047         bool run;
1048         JMutex run_mutex;
1049
1050 public:
1051
1052         SimpleThread():
1053                 JThread(),
1054                 run(true)
1055         {
1056                 run_mutex.Init();
1057         }
1058
1059         virtual ~SimpleThread()
1060         {}
1061
1062         virtual void * Thread() = 0;
1063
1064         bool getRun()
1065         {
1066                 JMutexAutoLock lock(run_mutex);
1067                 return run;
1068         }
1069         void setRun(bool a_run)
1070         {
1071                 JMutexAutoLock lock(run_mutex);
1072                 run = a_run;
1073         }
1074
1075         void stop()
1076         {
1077                 setRun(false);
1078                 while(IsRunning())
1079                         sleep_ms(100);
1080         }
1081 };
1082
1083 /*
1084         FIFO queue (well, actually a FILO also)
1085 */
1086 template<typename T>
1087 class Queue
1088 {
1089 public:
1090         void push_back(T t)
1091         {
1092                 m_list.push_back(t);
1093         }
1094         
1095         T pop_front()
1096         {
1097                 if(m_list.size() == 0)
1098                         throw ItemNotFoundException("Queue: queue is empty");
1099
1100                 typename core::list<T>::Iterator begin = m_list.begin();
1101                 T t = *begin;
1102                 m_list.erase(begin);
1103                 return t;
1104         }
1105         T pop_back()
1106         {
1107                 if(m_list.size() == 0)
1108                         throw ItemNotFoundException("Queue: queue is empty");
1109
1110                 typename core::list<T>::Iterator last = m_list.getLast();
1111                 T t = *last;
1112                 m_list.erase(last);
1113                 return t;
1114         }
1115
1116         u32 size()
1117         {
1118                 return m_list.size();
1119         }
1120
1121 protected:
1122         core::list<T> m_list;
1123 };
1124
1125 /*
1126         Thread-safe FIFO queue (well, actually a FILO also)
1127 */
1128
1129 template<typename T>
1130 class MutexedQueue
1131 {
1132 public:
1133         MutexedQueue()
1134         {
1135                 m_mutex.Init();
1136         }
1137         u32 size()
1138         {
1139                 JMutexAutoLock lock(m_mutex);
1140                 return m_list.size();
1141         }
1142         void push_back(T t)
1143         {
1144                 JMutexAutoLock lock(m_mutex);
1145                 m_list.push_back(t);
1146         }
1147         T pop_front(u32 wait_time_max_ms=0)
1148         {
1149                 u32 wait_time_ms = 0;
1150
1151                 for(;;)
1152                 {
1153                         {
1154                                 JMutexAutoLock lock(m_mutex);
1155
1156                                 if(m_list.size() > 0)
1157                                 {
1158                                         typename core::list<T>::Iterator begin = m_list.begin();
1159                                         T t = *begin;
1160                                         m_list.erase(begin);
1161                                         return t;
1162                                 }
1163
1164                                 if(wait_time_ms >= wait_time_max_ms)
1165                                         throw ItemNotFoundException("MutexedQueue: queue is empty");
1166                         }
1167
1168                         // Wait a while before trying again
1169                         sleep_ms(10);
1170                         wait_time_ms += 10;
1171                 }
1172         }
1173         T pop_back(u32 wait_time_max_ms=0)
1174         {
1175                 u32 wait_time_ms = 0;
1176
1177                 for(;;)
1178                 {
1179                         {
1180                                 JMutexAutoLock lock(m_mutex);
1181
1182                                 if(m_list.size() > 0)
1183                                 {
1184                                         typename core::list<T>::Iterator last = m_list.getLast();
1185                                         T t = *last;
1186                                         m_list.erase(last);
1187                                         return t;
1188                                 }
1189
1190                                 if(wait_time_ms >= wait_time_max_ms)
1191                                         throw ItemNotFoundException("MutexedQueue: queue is empty");
1192                         }
1193
1194                         // Wait a while before trying again
1195                         sleep_ms(10);
1196                         wait_time_ms += 10;
1197                 }
1198         }
1199
1200         JMutex & getMutex()
1201         {
1202                 return m_mutex;
1203         }
1204
1205         core::list<T> & getList()
1206         {
1207                 return m_list;
1208         }
1209
1210 protected:
1211         JMutex m_mutex;
1212         core::list<T> m_list;
1213 };
1214
1215 /*
1216         A single worker thread - multiple client threads queue framework.
1217 */
1218
1219 template<typename Caller, typename Data>
1220 class CallerInfo
1221 {
1222 public:
1223         Caller caller;
1224         Data data;
1225 };
1226
1227 template<typename Key, typename T, typename Caller, typename CallerData>
1228 class GetResult
1229 {
1230 public:
1231         Key key;
1232         T item;
1233         core::list<CallerInfo<Caller, CallerData> > callers;
1234 };
1235
1236 template<typename Key, typename T, typename Caller, typename CallerData>
1237 class ResultQueue: public MutexedQueue< GetResult<Key, T, Caller, CallerData> >
1238 {
1239 };
1240
1241 template<typename Key, typename T, typename Caller, typename CallerData>
1242 class GetRequest
1243 {
1244 public:
1245         GetRequest()
1246         {
1247                 dest = NULL;
1248         }
1249         GetRequest(ResultQueue<Key,T, Caller, CallerData> *a_dest)
1250         {
1251                 dest = a_dest;
1252         }
1253         GetRequest(ResultQueue<Key,T, Caller, CallerData> *a_dest,
1254                         Key a_key)
1255         {
1256                 dest = a_dest;
1257                 key = a_key;
1258         }
1259         ~GetRequest()
1260         {
1261         }
1262         
1263         Key key;
1264         ResultQueue<Key, T, Caller, CallerData> *dest;
1265         core::list<CallerInfo<Caller, CallerData> > callers;
1266 };
1267
1268 template<typename Key, typename T, typename Caller, typename CallerData>
1269 class RequestQueue
1270 {
1271 public:
1272         u32 size()
1273         {
1274                 return m_queue.size();
1275         }
1276
1277         void add(Key key, Caller caller, CallerData callerdata,
1278                         ResultQueue<Key, T, Caller, CallerData> *dest)
1279         {
1280                 JMutexAutoLock lock(m_queue.getMutex());
1281                 
1282                 /*
1283                         If the caller is already on the list, only update CallerData
1284                 */
1285                 for(typename core::list< GetRequest<Key, T, Caller, CallerData> >::Iterator
1286                                 i = m_queue.getList().begin();
1287                                 i != m_queue.getList().end(); i++)
1288                 {
1289                         GetRequest<Key, T, Caller, CallerData> &request = *i;
1290
1291                         if(request.key == key)
1292                         {
1293                                 for(typename core::list< CallerInfo<Caller, CallerData> >::Iterator
1294                                                 i = request.callers.begin();
1295                                                 i != request.callers.end(); i++)
1296                                 {
1297                                         CallerInfo<Caller, CallerData> &ca = *i;
1298                                         if(ca.caller == caller)
1299                                         {
1300                                                 ca.data = callerdata;
1301                                                 return;
1302                                         }
1303                                 }
1304                                 CallerInfo<Caller, CallerData> ca;
1305                                 ca.caller = caller;
1306                                 ca.data = callerdata;
1307                                 request.callers.push_back(ca);
1308                                 return;
1309                         }
1310                 }
1311
1312                 /*
1313                         Else add a new request to the queue
1314                 */
1315
1316                 GetRequest<Key, T, Caller, CallerData> request;
1317                 request.key = key;
1318                 CallerInfo<Caller, CallerData> ca;
1319                 ca.caller = caller;
1320                 ca.data = callerdata;
1321                 request.callers.push_back(ca);
1322                 request.dest = dest;
1323                 
1324                 m_queue.getList().push_back(request);
1325         }
1326
1327         GetRequest<Key, T, Caller, CallerData> pop(bool wait_if_empty=false)
1328         {
1329                 return m_queue.pop_front(wait_if_empty);
1330         }
1331
1332 private:
1333         MutexedQueue< GetRequest<Key, T, Caller, CallerData> > m_queue;
1334 };
1335
1336 /*
1337         Pseudo-random (VC++ rand() sucks)
1338 */
1339 int myrand(void);
1340 void mysrand(unsigned seed);
1341 #define MYRAND_MAX 32767
1342
1343 int myrand_range(int min, int max);
1344
1345 /*
1346         Miscellaneous functions
1347 */
1348
1349 bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
1350                 f32 camera_fov, f32 range, f32 *distance_ptr=NULL);
1351
1352 /*
1353         Queue with unique values with fast checking of value existence
1354 */
1355
1356 template<typename Value>
1357 class UniqueQueue
1358 {
1359 public:
1360         
1361         /*
1362                 Does nothing if value is already queued.
1363                 Return value:
1364                         true: value added
1365                         false: value already exists
1366         */
1367         bool push_back(Value value)
1368         {
1369                 // Check if already exists
1370                 if(m_map.find(value) != NULL)
1371                         return false;
1372
1373                 // Add
1374                 m_map.insert(value, 0);
1375                 m_list.push_back(value);
1376                 
1377                 return true;
1378         }
1379
1380         Value pop_front()
1381         {
1382                 typename core::list<Value>::Iterator i = m_list.begin();
1383                 Value value = *i;
1384                 m_map.remove(value);
1385                 m_list.erase(i);
1386                 return value;
1387         }
1388
1389         u32 size()
1390         {
1391                 assert(m_list.size() == m_map.size());
1392                 return m_list.size();
1393         }
1394
1395 private:
1396         core::map<Value, u8> m_map;
1397         core::list<Value> m_list;
1398 };
1399
1400 #if 1
1401 template<typename Key, typename Value>
1402 class MutexedMap
1403 {
1404 public:
1405         MutexedMap()
1406         {
1407                 m_mutex.Init();
1408                 assert(m_mutex.IsInitialized());
1409         }
1410         
1411         void set(const Key &name, const Value &value)
1412         {
1413                 JMutexAutoLock lock(m_mutex);
1414
1415                 m_values[name] = value;
1416         }
1417         
1418         bool get(const Key &name, Value *result)
1419         {
1420                 JMutexAutoLock lock(m_mutex);
1421
1422                 typename core::map<Key, Value>::Node *n;
1423                 n = m_values.find(name);
1424
1425                 if(n == NULL)
1426                         return false;
1427                 
1428                 if(result != NULL)
1429                         *result = n->getValue();
1430                         
1431                 return true;
1432         }
1433
1434 private:
1435         core::map<Key, Value> m_values;
1436         JMutex m_mutex;
1437 };
1438 #endif
1439
1440 /*
1441         Generates ids for comparable values.
1442         Id=0 is reserved for "no value".
1443
1444         Is fast at:
1445         - Returning value by id (very fast)
1446         - Returning id by value
1447         - Generating a new id for a value
1448
1449         Is not able to:
1450         - Remove an id/value pair (is possible to implement but slow)
1451 */
1452 template<typename T>
1453 class MutexedIdGenerator
1454 {
1455 public:
1456         MutexedIdGenerator()
1457         {
1458                 m_mutex.Init();
1459                 assert(m_mutex.IsInitialized());
1460         }
1461         
1462         // Returns true if found
1463         bool getValue(u32 id, T &value)
1464         {
1465                 if(id == 0)
1466                         return false;
1467                 JMutexAutoLock lock(m_mutex);
1468                 if(m_id_to_value.size() < id)
1469                         return false;
1470                 value = m_id_to_value[id-1];
1471                 return true;
1472         }
1473         
1474         // If id exists for value, returns the id.
1475         // Otherwise generates an id for the value.
1476         u32 getId(const T &value)
1477         {
1478                 JMutexAutoLock lock(m_mutex);
1479                 typename core::map<T, u32>::Node *n;
1480                 n = m_value_to_id.find(value);
1481                 if(n != NULL)
1482                         return n->getValue();
1483                 m_id_to_value.push_back(value);
1484                 u32 new_id = m_id_to_value.size();
1485                 m_value_to_id.insert(value, new_id);
1486                 return new_id;
1487         }
1488
1489 private:
1490         JMutex m_mutex;
1491         // Values are stored here at id-1 position (id 1 = [0])
1492         core::array<T> m_id_to_value;
1493         core::map<T, u32> m_value_to_id;
1494 };
1495
1496 /*
1497         Checks if a string contains only supplied characters
1498 */
1499 inline bool string_allowed(const std::string &s, const std::string &allowed_chars)
1500 {
1501         for(u32 i=0; i<s.size(); i++)
1502         {
1503                 bool confirmed = false;
1504                 for(u32 j=0; j<allowed_chars.size(); j++)
1505                 {
1506                         if(s[i] == allowed_chars[j])
1507                         {
1508                                 confirmed = true;
1509                                 break;
1510                         }
1511                 }
1512                 if(confirmed == false)
1513                         return false;
1514         }
1515         return true;
1516 }
1517
1518 /*
1519         Forcefully wraps string into rows using \n
1520         (no word wrap, used for showing paths in gui)
1521 */
1522 inline std::string wrap_rows(const std::string &from, u32 rowlen)
1523 {
1524         std::string to;
1525         for(u32 i=0; i<from.size(); i++)
1526         {
1527                 if(i != 0 && i%rowlen == 0)
1528                         to += '\n';
1529                 to += from[i];
1530         }
1531         return to;
1532 }
1533
1534 /*
1535         Some helper stuff
1536 */
1537 #define MYMIN(a,b) ((a)<(b)?(a):(b))
1538 #define MYMAX(a,b) ((a)>(b)?(a):(b))
1539
1540 /*
1541         Returns integer position of node in given floating point position
1542 */
1543 inline v3s16 floatToInt(v3f p, f32 d)
1544 {
1545         v3s16 p2(
1546                 (p.X + (p.X>0 ? d/2 : -d/2))/d,
1547                 (p.Y + (p.Y>0 ? d/2 : -d/2))/d,
1548                 (p.Z + (p.Z>0 ? d/2 : -d/2))/d);
1549         return p2;
1550 }
1551
1552 /*
1553         Returns floating point position of node in given integer position
1554 */
1555 inline v3f intToFloat(v3s16 p, f32 d)
1556 {
1557         v3f p2(
1558                 (f32)p.X * d,
1559                 (f32)p.Y * d,
1560                 (f32)p.Z * d
1561         );
1562         return p2;
1563 }
1564
1565 /*
1566         More serialization stuff
1567 */
1568
1569 // Creates a string with the length as the first two bytes
1570 inline std::string serializeString(const std::string &plain)
1571 {
1572         //assert(plain.size() <= 65535);
1573         if(plain.size() > 65535)
1574                 throw SerializationError("String too long for serializeString");
1575         char buf[2];
1576         writeU16((u8*)&buf[0], plain.size());
1577         std::string s;
1578         s.append(buf, 2);
1579         s.append(plain);
1580         return s;
1581 }
1582
1583 // Creates a string with the length as the first two bytes from wide string
1584 inline std::string serializeWideString(const std::wstring &plain)
1585 {
1586         //assert(plain.size() <= 65535);
1587         if(plain.size() > 65535)
1588                 throw SerializationError("String too long for serializeString");
1589         char buf[2];
1590         writeU16((u8*)buf, plain.size());
1591         std::string s;
1592         s.append(buf, 2);
1593         for(u32 i=0; i<plain.size(); i++)
1594         {
1595                 writeU16((u8*)buf, plain[i]);
1596                 s.append(buf, 2);
1597         }
1598         return s;
1599 }
1600
1601 // Reads a string with the length as the first two bytes
1602 inline std::string deSerializeString(std::istream &is)
1603 {
1604         char buf[2];
1605         is.read(buf, 2);
1606         if(is.gcount() != 2)
1607                 throw SerializationError("deSerializeString: size not read");
1608         u16 s_size = readU16((u8*)buf);
1609         if(s_size == 0)
1610                 return "";
1611         Buffer<char> buf2(s_size);
1612         is.read(&buf2[0], s_size);
1613         std::string s;
1614         s.reserve(s_size);
1615         s.append(&buf2[0], s_size);
1616         return s;
1617 }
1618
1619 // Reads a wide string with the length as the first two bytes
1620 inline std::wstring deSerializeWideString(std::istream &is)
1621 {
1622         char buf[2];
1623         is.read(buf, 2);
1624         if(is.gcount() != 2)
1625                 throw SerializationError("deSerializeString: size not read");
1626         u16 s_size = readU16((u8*)buf);
1627         if(s_size == 0)
1628                 return L"";
1629         std::wstring s;
1630         s.reserve(s_size);
1631         for(u32 i=0; i<s_size; i++)
1632         {
1633                 is.read(&buf[0], 2);
1634                 wchar_t c16 = readU16((u8*)buf);
1635                 s.append(&c16, 1);
1636         }
1637         return s;
1638 }
1639
1640 // Creates a string with the length as the first four bytes
1641 inline std::string serializeLongString(const std::string &plain)
1642 {
1643         char buf[4];
1644         writeU32((u8*)&buf[0], plain.size());
1645         std::string s;
1646         s.append(buf, 4);
1647         s.append(plain);
1648         return s;
1649 }
1650
1651 // Reads a string with the length as the first four bytes
1652 inline std::string deSerializeLongString(std::istream &is)
1653 {
1654         char buf[4];
1655         is.read(buf, 4);
1656         if(is.gcount() != 4)
1657                 throw SerializationError("deSerializeLongString: size not read");
1658         u32 s_size = readU32((u8*)buf);
1659         if(s_size == 0)
1660                 return "";
1661         Buffer<char> buf2(s_size);
1662         is.read(&buf2[0], s_size);
1663         std::string s;
1664         s.reserve(s_size);
1665         s.append(&buf2[0], s_size);
1666         return s;
1667 }
1668
1669 //
1670
1671 inline u32 time_to_daynight_ratio(u32 time_of_day)
1672 {
1673         const s32 daylength = 16;
1674         const s32 nightlength = 6;
1675         const s32 daytimelength = 8;
1676         s32 d = daylength;
1677         s32 t = (((time_of_day)%24000)/(24000/d));
1678         if(t < nightlength/2 || t >= d - nightlength/2)
1679                 //return 300;
1680                 return 350;
1681         else if(t >= d/2 - daytimelength/2 && t < d/2 + daytimelength/2)
1682                 return 1000;
1683         else
1684                 return 750;
1685 }
1686
1687 // Random helper. Usually d=BS
1688 inline core::aabbox3d<f32> getNodeBox(v3s16 p, float d)
1689 {
1690         return core::aabbox3d<f32>(
1691                 (float)p.X * d - 0.5*d,
1692                 (float)p.Y * d - 0.5*d,
1693                 (float)p.Z * d - 0.5*d,
1694                 (float)p.X * d + 0.5*d,
1695                 (float)p.Y * d + 0.5*d,
1696                 (float)p.Z * d + 0.5*d
1697         );
1698 }
1699         
1700 class IntervalLimiter
1701 {
1702 public:
1703         IntervalLimiter():
1704                 m_accumulator(0)
1705         {
1706         }
1707         /*
1708                 dtime: time from last call to this method
1709                 wanted_interval: interval wanted
1710                 return value:
1711                         true: action should be skipped
1712                         false: action should be done
1713         */
1714         bool step(float dtime, float wanted_interval)
1715         {
1716                 m_accumulator += dtime;
1717                 if(m_accumulator < wanted_interval)
1718                         return false;
1719                 m_accumulator -= wanted_interval;
1720                 return true;
1721         }
1722 protected:
1723         float m_accumulator;
1724 };
1725
1726 std::string translatePassword(std::string playername, std::wstring password);
1727
1728 #endif
1729