makes all tracker requests 'stopped' when aborting
[libtorrent.git] / include / libtorrent / buffer.hpp
blob425a6a634dcaee905d8d46ab03e2743b29c2b11f
1 /*
2 Copyright (c) 2007, Arvid Norberg
3 All rights reserved.
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
9 * Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in
13 the documentation and/or other materials provided with the distribution.
14 * Neither the name of Rasterbar Software nor the names of its
15 contributors may be used to endorse or promote products derived
16 from this software without specific prior written permission.
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 POSSIBILITY OF SUCH DAMAGE.
32 #ifndef LIBTORRENT_BUFFER_HPP
33 #define LIBTORRENT_BUFFER_HPP
35 #include <memory>
36 #include <cstring>
37 #include "libtorrent/invariant_check.hpp"
38 #include "libtorrent/assert.hpp"
40 namespace libtorrent {
42 class buffer
44 public:
45 struct interval
47 interval()
48 : begin(0)
49 , end(0)
52 interval(char* begin, char* end)
53 : begin(begin)
54 , end(end)
57 char operator[](int index) const
59 TORRENT_ASSERT(begin + index < end);
60 return begin[index];
63 int left() const { TORRENT_ASSERT(end >= begin); return end - begin; }
65 char* begin;
66 char* end;
69 struct const_interval
71 const_interval(char const* begin, char const* end)
72 : begin(begin)
73 , end(end)
76 char operator[](int index) const
78 TORRENT_ASSERT(begin + index < end);
79 return begin[index];
82 bool operator==(const const_interval& p_interval)
84 return (begin == p_interval.begin
85 && end == p_interval.end);
88 int left() const { TORRENT_ASSERT(end >= begin); return end - begin; }
90 char const* begin;
91 char const* end;
94 buffer(std::size_t n = 0)
95 : m_begin(0)
96 , m_end(0)
97 , m_last(0)
99 if (n) resize(n);
102 buffer(buffer const& b)
103 : m_begin(0)
104 , m_end(0)
105 , m_last(0)
107 if (b.size() == 0) return;
108 resize(b.size());
109 std::memcpy(m_begin, b.begin(), b.size());
112 buffer& operator=(buffer const& b)
114 resize(b.size());
115 std::memcpy(m_begin, b.begin(), b.size());
116 return *this;
119 ~buffer()
121 ::operator delete (m_begin);
124 buffer::interval data() { return interval(m_begin, m_end); }
125 buffer::const_interval data() const { return const_interval(m_begin, m_end); }
127 void resize(std::size_t n)
129 reserve(n);
130 m_end = m_begin + n;
133 void insert(char* point, char const* first, char const* last)
135 std::size_t p = point - m_begin;
136 if (point == m_end)
138 resize(size() + last - first);
139 std::memcpy(m_begin + p, first, last - first);
140 return;
143 resize(size() + last - first);
144 std::memmove(m_begin + p + (last - first), m_begin + p, last - first);
145 std::memcpy(m_begin + p, first, last - first);
148 void erase(char* begin, char* end)
150 TORRENT_ASSERT(end <= m_end);
151 TORRENT_ASSERT(begin >= m_begin);
152 TORRENT_ASSERT(begin <= end);
153 if (end == m_end)
155 resize(begin - m_begin);
156 return;
158 std::memmove(begin, end, m_end - end);
159 m_end = begin + (m_end - end);
162 void clear() { m_end = m_begin; }
163 std::size_t size() const { return m_end - m_begin; }
164 std::size_t capacity() const { return m_last - m_begin; }
165 void reserve(std::size_t n)
167 if (n <= capacity()) return;
168 TORRENT_ASSERT(n > 0);
170 char* buf = (char*)::operator new(n);
171 std::size_t s = size();
172 std::memcpy(buf, m_begin, s);
173 ::operator delete (m_begin);
174 m_begin = buf;
175 m_end = buf + s;
176 m_last = m_begin + n;
179 bool empty() const { return m_begin == m_end; }
180 char& operator[](std::size_t i) { TORRENT_ASSERT(i < size()); return m_begin[i]; }
181 char const& operator[](std::size_t i) const { TORRENT_ASSERT(i < size()); return m_begin[i]; }
183 char* begin() { return m_begin; }
184 char const* begin() const { return m_begin; }
185 char* end() { return m_end; }
186 char const* end() const { return m_end; }
188 void swap(buffer& b)
190 using std::swap;
191 swap(m_begin, b.m_begin);
192 swap(m_end, b.m_end);
193 swap(m_last, b.m_last);
195 private:
196 char* m_begin; // first
197 char* m_end; // one passed end of size
198 char* m_last; // one passed end of allocation
204 #endif // LIBTORRENT_BUFFER_HPP