]> git.lizzy.rs Git - minetest.git/blob - src/util/pointer.h
6614ca2c247f93d558146481a3c95c25a8635911
[minetest.git] / src / util / pointer.h
1 /*
2 Minetest
3 Copyright (C) 2010-2013 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 Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser 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 UTIL_POINTER_HEADER
21 #define UTIL_POINTER_HEADER
22
23 #include "../irrlichttypes.h"
24 #include "../debug.h" // For assert()
25 #include <cstring>
26
27 template <typename T>
28 class Buffer
29 {
30 public:
31         Buffer()
32         {
33                 m_size = 0;
34                 data = NULL;
35         }
36         Buffer(unsigned int size)
37         {
38                 m_size = size;
39                 if(size != 0)
40                         data = new T[size];
41                 else
42                         data = NULL;
43         }
44         Buffer(const Buffer &buffer)
45         {
46                 m_size = buffer.m_size;
47                 if(m_size != 0)
48                 {
49                         data = new T[buffer.m_size];
50                         memcpy(data, buffer.data, buffer.m_size);
51                 }
52                 else
53                         data = NULL;
54         }
55         Buffer(const T *t, unsigned int size)
56         {
57                 m_size = size;
58                 if(size != 0)
59                 {
60                         data = new T[size];
61                         memcpy(data, t, size);
62                 }
63                 else
64                         data = NULL;
65         }
66         ~Buffer()
67         {
68                 drop();
69         }
70         Buffer& operator=(const Buffer &buffer)
71         {
72                 if(this == &buffer)
73                         return *this;
74                 drop();
75                 m_size = buffer.m_size;
76                 if(m_size != 0)
77                 {
78                         data = new T[buffer.m_size];
79                         memcpy(data, buffer.data, buffer.m_size);
80                 }
81                 else
82                         data = NULL;
83                 return *this;
84         }
85         T & operator[](unsigned int i) const
86         {
87                 return data[i];
88         }
89         T * operator*() const
90         {
91                 return data;
92         }
93         unsigned int getSize() const
94         {
95                 return m_size;
96         }
97 private:
98         void drop()
99         {
100                 if(data)
101                         delete[] data;
102         }
103         T *data;
104         unsigned int m_size;
105 };
106
107 /************************************************
108  *           !!!  W A R N I N G  !!!            *
109  *           !!!  A C H T U N G  !!!            *
110  *                                              *
111  * This smart pointer class is NOT thread safe. *
112  * ONLY use in a single-threaded context!       *
113  *                                              *
114  ************************************************/
115 template <typename T>
116 class SharedBuffer
117 {
118 public:
119         SharedBuffer()
120         {
121                 m_size = 0;
122                 data = NULL;
123                 refcount = new unsigned int;
124                 (*refcount) = 1;
125         }
126         SharedBuffer(unsigned int size)
127         {
128                 m_size = size;
129                 if(m_size != 0)
130                         data = new T[m_size];
131                 else
132                         data = NULL;
133                 refcount = new unsigned int;
134                 memset(data,0,sizeof(T)*m_size);
135                 (*refcount) = 1;
136         }
137         SharedBuffer(const SharedBuffer &buffer)
138         {
139                 //std::cout<<"SharedBuffer(const SharedBuffer &buffer)"<<std::endl;
140                 m_size = buffer.m_size;
141                 data = buffer.data;
142                 refcount = buffer.refcount;
143                 (*refcount)++;
144         }
145         SharedBuffer & operator=(const SharedBuffer & buffer)
146         {
147                 //std::cout<<"SharedBuffer & operator=(const SharedBuffer & buffer)"<<std::endl;
148                 if(this == &buffer)
149                         return *this;
150                 drop();
151                 m_size = buffer.m_size;
152                 data = buffer.data;
153                 refcount = buffer.refcount;
154                 (*refcount)++;
155                 return *this;
156         }
157         /*
158                 Copies whole buffer
159         */
160         SharedBuffer(const T *t, unsigned int size)
161         {
162                 m_size = size;
163                 if(m_size != 0)
164                 {
165                         data = new T[m_size];
166                         memcpy(data, t, m_size);
167                 }
168                 else
169                         data = NULL;
170                 refcount = new unsigned int;
171                 (*refcount) = 1;
172         }
173         /*
174                 Copies whole buffer
175         */
176         SharedBuffer(const Buffer<T> &buffer)
177         {
178                 m_size = buffer.getSize();
179                 if(m_size != 0)
180                 {
181                         data = new T[m_size];
182                         memcpy(data, *buffer, buffer.getSize());
183                 }
184                 else
185                         data = NULL;
186                 refcount = new unsigned int;
187                 (*refcount) = 1;
188         }
189         ~SharedBuffer()
190         {
191                 drop();
192         }
193         T & operator[](unsigned int i) const
194         {
195                 assert(i < m_size);
196                 return data[i];
197         }
198         T * operator*() const
199         {
200                 return data;
201         }
202         unsigned int getSize() const
203         {
204                 return m_size;
205         }
206         operator Buffer<T>() const
207         {
208                 return Buffer<T>(data, m_size);
209         }
210 private:
211         void drop()
212         {
213                 assert((*refcount) > 0);
214                 (*refcount)--;
215                 if(*refcount == 0)
216                 {
217                         if(data)
218                                 delete[] data;
219                         delete refcount;
220                 }
221         }
222         T *data;
223         unsigned int m_size;
224         unsigned int *refcount;
225 };
226
227 inline SharedBuffer<u8> SharedBufferFromString(const char *string)
228 {
229         SharedBuffer<u8> b((u8*)string, strlen(string)+1);
230         return b;
231 }
232
233 #endif
234