makes all tracker requests 'stopped' when aborting
[libtorrent.git] / include / libtorrent / lazy_entry.hpp
blobffb5b67ee25b3aea5faccd92dde4476929fb6f54
1 /*
3 Copyright (c) 2003, Arvid Norberg
4 All rights reserved.
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
10 * Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in
14 the documentation and/or other materials provided with the distribution.
15 * Neither the name of the author nor the names of its
16 contributors may be used to endorse or promote products derived
17 from this software without specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 POSSIBILITY OF SUCH DAMAGE.
33 #ifndef TORRENT_LAZY_ENTRY_HPP_INCLUDED
34 #define TORRENT_LAZY_ENTRY_HPP_INCLUDED
36 #include <utility>
37 #include <vector>
38 #include "libtorrent/assert.hpp"
39 #include "libtorrent/size_type.hpp"
40 #include <iosfwd>
42 namespace libtorrent
44 struct lazy_entry;
46 char const* parse_int(char const* start, char const* end, char delimiter, boost::int64_t& val);
47 // return 0 = success
48 int lazy_bdecode(char const* start, char const* end, lazy_entry& ret, int depth_limit = 1000);
50 struct lazy_entry
52 enum entry_type_t
54 none_t, dict_t, list_t, string_t, int_t
57 lazy_entry() : m_type(none_t), m_begin(0), m_end(0)
58 { m_data.start = 0; }
60 entry_type_t type() const { return m_type; }
62 // start points to the first decimal digit
63 // length is the number of digits
64 void construct_int(char const* start, int length)
66 TORRENT_ASSERT(m_type == none_t);
67 m_type = int_t;
68 m_data.start = start;
69 m_size = length;
70 m_begin = start - 1; // include 'i'
71 m_end = start + length + 1; // include 'e'
74 size_type int_value() const;
76 // string functions
77 // ================
79 void construct_string(char const* start, int length);
81 // the string is not null-terminated!
82 char const* string_ptr() const
84 TORRENT_ASSERT(m_type == string_t);
85 return m_data.start;
88 // this will return a null terminated string
89 // it will write to the source buffer!
90 char const* string_cstr() const
92 TORRENT_ASSERT(m_type == string_t);
93 const_cast<char*>(m_data.start)[m_size] = 0;
94 return m_data.start;
97 std::string string_value() const
99 TORRENT_ASSERT(m_type == string_t);
100 return std::string(m_data.start, m_size);
103 int string_length() const
104 { return m_size; }
106 // dictionary functions
107 // ====================
109 void construct_dict(char const* begin)
111 TORRENT_ASSERT(m_type == none_t);
112 m_type = dict_t;
113 m_size = 0;
114 m_capacity = 0;
115 m_begin = begin;
118 lazy_entry* dict_append(char const* name);
119 lazy_entry* dict_find(char const* name);
120 lazy_entry const* dict_find(char const* name) const
121 { return const_cast<lazy_entry*>(this)->dict_find(name); }
123 std::string dict_find_string_value(char const* name) const;
124 size_type dict_find_int_value(char const* name, size_type default_val = 0) const;
125 lazy_entry const* dict_find_dict(char const* name) const;
126 lazy_entry const* dict_find_list(char const* name) const;
127 lazy_entry const* dict_find_string(char const* name) const;
129 std::pair<std::string, lazy_entry const*> dict_at(int i) const
131 TORRENT_ASSERT(m_type == dict_t);
132 TORRENT_ASSERT(i < m_size);
133 std::pair<char const*, lazy_entry> const& e = m_data.dict[i];
134 return std::make_pair(std::string(e.first, e.second.m_begin - e.first), &e.second);
137 int dict_size() const
139 TORRENT_ASSERT(m_type == dict_t);
140 return m_size;
143 // list functions
144 // ==============
146 void construct_list(char const* begin)
148 TORRENT_ASSERT(m_type == none_t);
149 m_type = list_t;
150 m_size = 0;
151 m_capacity = 0;
152 m_begin = begin;
155 lazy_entry* list_append();
156 lazy_entry* list_at(int i)
158 TORRENT_ASSERT(m_type == list_t);
159 TORRENT_ASSERT(i < m_size);
160 return &m_data.list[i];
162 lazy_entry const* list_at(int i) const
163 { return const_cast<lazy_entry*>(this)->list_at(i); }
165 std::string list_string_value_at(int i) const;
166 size_type list_int_value_at(int i, size_type default_val = 0) const;
168 int list_size() const
170 TORRENT_ASSERT(m_type == list_t);
171 return m_size;
174 // end points one byte passed last byte
175 void set_end(char const* end)
177 TORRENT_ASSERT(end > m_begin);
178 m_end = end;
181 void clear();
183 // releases ownership of any memory allocated
184 void release()
186 m_data.start = 0;
187 m_size = 0;
188 m_capacity = 0;
189 m_type = none_t;
192 ~lazy_entry()
193 { clear(); }
195 // returns pointers into the source buffer where
196 // this entry has its bencoded data
197 std::pair<char const*, int> data_section() const;
199 void swap(lazy_entry& e)
201 using std::swap;
202 swap(m_type, e.m_type);
203 swap(m_data.start, e.m_data.start);
204 swap(m_size, e.m_size);
205 swap(m_capacity, e.m_capacity);
206 swap(m_begin, e.m_begin);
207 swap(m_end, e.m_end);
210 private:
212 entry_type_t m_type;
213 union data_t
215 std::pair<char const*, lazy_entry>* dict;
216 lazy_entry* list;
217 char const* start;
218 } m_data;
219 int m_size; // if list or dictionary, the number of items
220 int m_capacity; // if list or dictionary, allocated number of items
221 // used for dictionaries and lists to record the range
222 // in the original buffer they are based on
223 char const* m_begin;
224 char const* m_end;
227 std::ostream& operator<<(std::ostream& os, lazy_entry const& e);
232 #endif