3 Copyright (c) 2003, Arvid Norberg
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
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
38 #include "libtorrent/assert.hpp"
39 #include "libtorrent/size_type.hpp"
46 char const* parse_int(char const* start
, char const* end
, char delimiter
, boost::int64_t& val
);
48 int lazy_bdecode(char const* start
, char const* end
, lazy_entry
& ret
, int depth_limit
= 1000);
54 none_t
, dict_t
, list_t
, string_t
, int_t
57 lazy_entry() : m_type(none_t
), m_begin(0), m_end(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
);
70 m_begin
= start
- 1; // include 'i'
71 m_end
= start
+ length
+ 1; // include 'e'
74 size_type
int_value() const;
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
);
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;
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
106 // dictionary functions
107 // ====================
109 void construct_dict(char const* begin
)
111 TORRENT_ASSERT(m_type
== none_t
);
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
);
146 void construct_list(char const* begin
)
148 TORRENT_ASSERT(m_type
== none_t
);
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
);
174 // end points one byte passed last byte
175 void set_end(char const* end
)
177 TORRENT_ASSERT(end
> m_begin
);
183 // releases ownership of any memory allocated
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
)
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
);
215 std::pair
<char const*, lazy_entry
>* dict
;
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
227 std::ostream
& operator<<(std::ostream
& os
, lazy_entry
const& e
);