1/*
2 * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
23#ifndef DATABUFFER_H
24#define DATABUFFER_H
25
26template<class T>
27class DataBuffer
28{
29public:
30 DataBuffer(uint res = 64) :
31 m_size(0),
32 m_capacity(res),
33 m_buffer(new T[m_capacity]) { }
34 ~DataBuffer() {
35 if(m_buffer)
36 delete[] m_buffer;
37 }
38
39 DataBuffer(const DataBuffer<T>& d)
40 {
41 m_size = d.m_size;
42 m_capacity = std::max<uint>(64, d.m_size * 2);
43 m_buffer = new T[m_capacity];
44 memcpy(m_buffer, d.m_buffer, sizeof(T) * m_size);
45 }
46 DataBuffer& operator=(const DataBuffer<T>& d) = delete;
47
48 inline void reset() { m_size = 0; }
49 inline void clear() {
50 m_size = 0;
51 m_capacity = 0;
52 delete[] m_buffer;
53 m_buffer = nullptr;
54 }
55
56 inline bool empty() const { return m_size == 0; }
57 inline uint size() const { return m_size; }
58 inline T *data() const { return m_buffer; }
59
60 inline const T& at(uint i) const { return m_buffer[i]; }
61 inline const T& last() const { return m_buffer[m_size-1]; }
62 inline const T& first() const { return m_buffer[0]; }
63 inline const T& operator[](uint i) const { return m_buffer[i]; }
64 inline T& operator[](uint i) { return m_buffer[i]; }
65
66 inline void reserve(uint n) {
67 if(n > m_capacity) {
68 T *buffer = new T[n];
69 memcpy(buffer, m_buffer, m_size * sizeof(T));
70 if(m_buffer)
71 delete[] m_buffer;
72 m_buffer = buffer;
73 m_capacity = n;
74 }
75 }
76
77 inline void resize(uint n, T def = T()) {
78 if(n == m_size)
79 return;
80 reserve(n);
81 for(uint i=m_size;i<n;++i)
82 m_buffer[i] = def;
83 m_size = n;
84 }
85
86 inline void grow(uint n, bool precise = false) {
87 if(n <= m_size)
88 return;
89 if(n > m_capacity) {
90 uint newcapacity = m_capacity;
91 if (precise) {
92 newcapacity = n;
93 } else {
94 do { newcapacity *= 4; } while (newcapacity < n);
95 }
96 reserve(newcapacity);
97 }
98 m_size = n;
99 }
100
101 inline void add(const T& v) {
102 grow(m_size + 1);
103 m_buffer[m_size-1] = v;
104 }
105
106 inline DataBuffer &operator<<(const T &t) { add(t); return *this; }
107
108private:
109 uint m_size;
110 uint m_capacity;
111 T *m_buffer;
112};
113
114#endif
115