2013-12-21 10:54:17 +01:00
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
< html xmlns = "http://www.w3.org/1999/xhtml" xml:lang = "en" lang = "en" >
< head >
< meta http-equiv = "Content-Type" content = "text/html; charset=utf-8" / >
2013-12-29 05:29:57 +01:00
< meta name = "generator" content = "Docutils 0.11: http://docutils.sourceforge.net/" / >
2013-12-21 10:54:17 +01:00
< title > Bencoding< / title >
< meta name = "author" content = "Arvid Norberg, arvid@rasterbar.com" / >
< link rel = "stylesheet" type = "text/css" href = "../../css/base.css" / >
< link rel = "stylesheet" type = "text/css" href = "../../css/rst.css" / >
< script type = "text/javascript" >
/* < ![CDATA[ */
(function() {
var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
s.type = 'text/javascript';
s.async = true;
s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';
t.parentNode.insertBefore(s, t);
})();
/* ]]> */
< / script >
< link rel = "stylesheet" href = "style.css" type = "text/css" / >
< style type = "text/css" >
/* Hides from IE-mac \*/
* html pre { height: 1%; }
/* End hide from IE-mac */
< / style >
< / head >
< body >
< div class = "document" id = "bencoding" >
< div id = "container" >
< div id = "headerNav" >
< ul >
< li class = "first" > < a href = "/" > Home< / a > < / li >
< li > < a href = "../../products.html" > Products< / a > < / li >
< li > < a href = "../../contact.html" > Contact< / a > < / li >
< / ul >
< / div >
< div id = "header" >
< div id = "orange" > < / div >
< div id = "logo" > < / div >
< / div >
< div id = "main" >
< h1 class = "title" > Bencoding< / h1 >
< table class = "docinfo" frame = "void" rules = "none" >
< col class = "docinfo-name" / >
< col class = "docinfo-content" / >
< tbody valign = "top" >
< tr > < th class = "docinfo-name" > Author:< / th >
< td > Arvid Norberg, < a class = "last reference external" href = "mailto:arvid@rasterbar.com" > arvid@ rasterbar.com< / a > < / td > < / tr >
< tr > < th class = "docinfo-name" > Version:< / th >
< td > 1.0.0< / td > < / tr >
< / tbody >
< / table >
< div class = "contents topic" id = "table-of-contents" >
< p class = "topic-title first" > Table of contents< / p >
< ul class = "simple" >
< li > < a class = "reference internal" href = "#invalid-encoding" id = "id55" > invalid_encoding< / a > < / li >
< li > < a class = "reference internal" href = "#type-error" id = "id56" > type_error< / a > < / li >
< li > < a class = "reference internal" href = "#entry" id = "id57" > entry< / a > < / li >
< li > < a class = "reference internal" href = "#pascal-string" id = "id58" > pascal_string< / a > < / li >
< li > < a class = "reference internal" href = "#lazy-entry" id = "id59" > lazy_entry< / a > < / li >
< / ul >
< / div >
< p > Bencoding is a common representation in bittorrent used for
for dictionary, list, int and string hierarchies. It's used
to encode .torrent files and some messages in the network
protocol. libtorrent also uses it to store settings, resume
data and other state between sessions.< / p >
< p > Strings in bencoded structures are not necessarily representing
text. Strings are raw byte buffers of a certain length. If a
string is meant to be interpreted as text, it is required to
be UTF-8 encoded. See < a class = "reference external" href = "http://bittorrent.org/beps/bep_0003.html" > BEP 3< / a > .< / p >
< p > There are two mechanims to < em > decode< / em > bencoded buffers in libtorrent.< / p >
< p > The most flexible one is < a class = "reference external" href = "reference-Bencoding.html#bdecode()" > bdecode()< / a > , which returns a structure
represented by < a class = "reference external" href = "reference-Bencoding.html#entry" > entry< / a > . When a buffer is decoded with this function,
it can be discarded. The < a class = "reference external" href = "reference-Bencoding.html#entry" > entry< / a > does not contain any references back
to it. This means that < a class = "reference external" href = "reference-Bencoding.html#bdecode()" > bdecode()< / a > actually copies all the data out
of the buffer and into its own hierarchy. This makes this
function potentially expensive, if you're parsing large amounts
of data.< / p >
< p > Another consideration is that < a class = "reference external" href = "reference-Bencoding.html#bdecode()" > bdecode()< / a > is a recursive parser.
For this reason, in order to avoid DoS attacks by triggering
a stack overflow, there is a recursion limit. This limit is
a sanity check to make sure it doesn't run the risk of
busting the stack.< / p >
< p > The second mechanism is < a class = "reference external" href = "reference-Bencoding.html#lazy_bdecode()" > lazy_bdecode()< / a > , which returns a
bencoded structure represented by < a class = "reference external" href = "reference-Bencoding.html#lazy_entry" > lazy_entry< / a > . This function
builds a tree that points back into the original buffer.
The returned < a class = "reference external" href = "reference-Bencoding.html#lazy_entry" > lazy_entry< / a > will not be valid once the buffer
it was parsed out of is discarded.< / p >
< p > Not only is this function more efficient because of less
memory allocation and data copy, the parser is also not
recursive, which means it probably performs a little bit
better and can have a higher recursion limit on the structures
it's parsing.< / p >
< a name = "invalid_encoding" > < / a > < div class = "section" id = "invalid-encoding" >
< h1 > invalid_encoding< / h1 >
< p > Declared in " < a class = "reference external" href = "../include/libtorrent/bencode.hpp" > libtorrent/bencode.hpp< / a > " < / p >
< p > thrown by < a class = "reference external" href = "reference-Bencoding.html#bdecode()" > bdecode()< / a > if the provided bencoded buffer does not contain
valid encoding.< / p >
< pre class = "literal-block" >
struct invalid_encoding: std::exception
{
virtual const char* < strong > what< / strong > () const throw();
};
< / pre >
< a name = "type_error" > < / a > < / div >
< div class = "section" id = "type-error" >
< h1 > type_error< / h1 >
< p > Declared in " < a class = "reference external" href = "../include/libtorrent/entry.hpp" > libtorrent/entry.hpp< / a > " < / p >
< p > thrown by any accessor function of < a class = "reference external" href = "reference-Bencoding.html#entry" > entry< / a > if the accessor
function requires a type different than the actual type
of the < a class = "reference external" href = "reference-Bencoding.html#entry" > entry< / a > object.< / p >
< pre class = "literal-block" >
struct type_error: std::runtime_error
{
< strong > type_error< / strong > (const char* error);
};
< / pre >
< a name = "entry" > < / a > < / div >
< div class = "section" id = "entry" >
< h1 > entry< / h1 >
< p > Declared in " < a class = "reference external" href = "../include/libtorrent/entry.hpp" > libtorrent/entry.hpp< / a > " < / p >
< p > The < tt class = "docutils literal" > entry< / tt > class represents one node in a bencoded hierarchy. It works as a
variant type, it can be either a list, a dictionary (< tt class = "docutils literal" > < span class = "pre" > std::map< / span > < / tt > ), an integer
or a string.< / p >
< pre class = "literal-block" >
class entry
{
data_type < strong > type< / strong > () const;
< strong > entry< / strong > (list_type const& );
< strong > entry< / strong > (integer_type const& );
< strong > entry< / strong > (dictionary_type const& );
< strong > entry< / strong > (string_type const& );
< strong > entry< / strong > (data_type t);
void < strong > operator=< / strong > (string_type const& );
void < strong > operator=< / strong > (entry const& );
void < strong > operator=< / strong > (integer_type const& );
void < strong > operator=< / strong > (lazy_entry const& );
void < strong > operator=< / strong > (dictionary_type const& );
void < strong > operator=< / strong > (list_type const& );
const integer_type& < strong > integer< / strong > () const;
const string_type& < strong > string< / strong > () const;
const dictionary_type& < strong > dict< / strong > () const;
string_type& < strong > string< / strong > ();
list_type& < strong > list< / strong > ();
dictionary_type& < strong > dict< / strong > ();
integer_type& < strong > integer< / strong > ();
const list_type& < strong > list< / strong > () const;
void < strong > swap< / strong > (entry& e);
entry& < strong > operator[]< / strong > (std::string const& key);
const entry& < strong > operator[]< / strong > (std::string const& key) const;
entry& < strong > operator[]< / strong > (char const* key);
const entry& < strong > operator[]< / strong > (char const* key) const;
entry const* < strong > find_key< / strong > (char const* key) const;
entry* < strong > find_key< / strong > (char const* key);
entry* < strong > find_key< / strong > (std::string const& key);
entry const* < strong > find_key< / strong > (std::string const& key) const;
std::string < strong > to_string< / strong > () const;
enum data_type
{
int_t,
string_t,
list_t,
dictionary_t,
undefined_t,
};
mutable boost::uint8_t m_type_queried:1;
};
< / pre >
< a name = "type()" > < / a > < div class = "section" id = "type" >
< h2 > type()< / h2 >
< pre class = "literal-block" >
data_type < strong > type< / strong > () const;
< / pre >
< p > returns the concrete type of the < a class = "reference external" href = "reference-Bencoding.html#entry" > entry< / a > < / p >
< a name = "entry()" > < / a > < / div >
< div class = "section" id = "id16" >
< h2 > entry()< / h2 >
< pre class = "literal-block" >
< strong > entry< / strong > (list_type const& );
< strong > entry< / strong > (integer_type const& );
< strong > entry< / strong > (dictionary_type const& );
< strong > entry< / strong > (string_type const& );
< / pre >
< p > constructors directly from a specific type.
The content of the argument is copied into the
newly constructed < a class = "reference external" href = "reference-Bencoding.html#entry" > entry< / a > < / p >
< a name = "entry()" > < / a > < / div >
< div class = "section" id = "id18" >
< h2 > entry()< / h2 >
< pre class = "literal-block" >
< strong > entry< / strong > (data_type t);
< / pre >
< p > construct an empty < a class = "reference external" href = "reference-Bencoding.html#entry" > entry< / a > of the specified type.
see < a class = "reference external" href = "reference-Bencoding.html#data_type" > data_type< / a > enum.< / p >
< a name = "operator=()" > < / a > < / div >
< div class = "section" id = "operator" >
< h2 > operator=()< / h2 >
< pre class = "literal-block" >
void < strong > operator=< / strong > (string_type const& );
void < strong > operator=< / strong > (entry const& );
void < strong > operator=< / strong > (integer_type const& );
void < strong > operator=< / strong > (lazy_entry const& );
void < strong > operator=< / strong > (dictionary_type const& );
void < strong > operator=< / strong > (list_type const& );
< / pre >
< p > copies the structure of the right hand side into this
entry.< / p >
< a name = "string()" > < / a >
< a name = "dict()" > < / a >
< a name = "integer()" > < / a >
< a name = "list()" > < / a > < / div >
< div class = "section" id = "string-dict-integer-list" >
< h2 > string() dict() integer() list()< / h2 >
< pre class = "literal-block" >
const integer_type& < strong > integer< / strong > () const;
const string_type& < strong > string< / strong > () const;
const dictionary_type& < strong > dict< / strong > () const;
string_type& < strong > string< / strong > ();
list_type& < strong > list< / strong > ();
dictionary_type& < strong > dict< / strong > ();
integer_type& < strong > integer< / strong > ();
const list_type& < strong > list< / strong > () const;
< / pre >
< p > The < tt class = "docutils literal" > integer()< / tt > , < tt class = "docutils literal" > string()< / tt > , < tt class = "docutils literal" > list()< / tt > and < tt class = "docutils literal" > dict()< / tt > functions
are accessors that return the respective type. If the < tt class = "docutils literal" > entry< / tt > object isn't of the
type you request, the accessor will throw < a class = "reference external" href = "reference-Error_Codes.html#libtorrent_exception" > libtorrent_exception< / a > (which derives from
< tt class = "docutils literal" > < span class = "pre" > std::runtime_error< / span > < / tt > ). You can ask an < tt class = "docutils literal" > entry< / tt > for its type through the
< tt class = "docutils literal" > type()< / tt > function.< / p >
< p > If you want to create an < tt class = "docutils literal" > entry< / tt > you give it the type you want it to have in its
constructor, and then use one of the non-const accessors to get a reference which you then
can assign the value you want it to have.< / p >
< p > The typical code to get info from a torrent file will then look like this:< / p >
< pre class = "literal-block" >
entry torrent_file;
// ...
// throws if this is not a dictionary
entry::dictionary_type const& dict = torrent_file.dict();
entry::dictionary_type::const_iterator i;
i = dict.find(" announce" );
if (i != dict.end())
{
std::string tracker_url = i-> second.string();
std::cout < < tracker_url < < " \n" ;
}
< / pre >
< p > The following code is equivalent, but a little bit shorter:< / p >
< pre class = "literal-block" >
entry torrent_file;
// ...
// throws if this is not a dictionary
if (entry* i = torrent_file.find_key(" announce" ))
{
std::string tracker_url = i-> string();
std::cout < < tracker_url < < " \n" ;
}
< / pre >
< p > To make it easier to extract information from a torrent file, the class < a class = "reference external" href = "reference-Core.html#torrent_info" > torrent_info< / a >
exists.< / p >
< a name = "swap()" > < / a > < / div >
< div class = "section" id = "swap" >
< h2 > swap()< / h2 >
< pre class = "literal-block" >
void < strong > swap< / strong > (entry& e);
< / pre >
< p > swaps the content of < em > this< / em > with < tt class = "docutils literal" > e< / tt > .< / p >
< a name = "operator[]()" > < / a > < / div >
< div class = "section" id = "id23" >
< h2 > operator[]()< / h2 >
< pre class = "literal-block" >
entry& < strong > operator[]< / strong > (std::string const& key);
const entry& < strong > operator[]< / strong > (std::string const& key) const;
entry& < strong > operator[]< / strong > (char const* key);
const entry& < strong > operator[]< / strong > (char const* key) const;
< / pre >
< p > All of these functions requires the < a class = "reference external" href = "reference-Bencoding.html#entry" > entry< / a > to be a dictionary, if it isn't they
will throw < tt class = "docutils literal" > < span class = "pre" > libtorrent::type_error< / span > < / tt > .< / p >
< p > The non-const versions of the < tt class = "docutils literal" > operator[]< / tt > will return a reference to either
the existing element at the given key or, if there is no element with the
given key, a reference to a newly inserted element at that key.< / p >
< p > The const version of < tt class = "docutils literal" > operator[]< / tt > will only return a reference to an
existing element at the given key. If the key is not found, it will throw
< tt class = "docutils literal" > < span class = "pre" > libtorrent::type_error< / span > < / tt > .< / p >
< a name = "find_key()" > < / a > < / div >
< div class = "section" id = "find-key" >
< h2 > find_key()< / h2 >
< pre class = "literal-block" >
entry const* < strong > find_key< / strong > (char const* key) const;
entry* < strong > find_key< / strong > (char const* key);
entry* < strong > find_key< / strong > (std::string const& key);
entry const* < strong > find_key< / strong > (std::string const& key) const;
< / pre >
< p > These functions requires the < a class = "reference external" href = "reference-Bencoding.html#entry" > entry< / a > to be a dictionary, if it isn't they
will throw < tt class = "docutils literal" > < span class = "pre" > libtorrent::type_error< / span > < / tt > .< / p >
< p > They will look for an element at the given key in the dictionary, if the
element cannot be found, they will return 0. If an element with the given
key is found, the return a pointer to it.< / p >
< a name = "data_type" > < / a > < / div >
< div class = "section" id = "enum-data-type" >
< h2 > enum data_type< / h2 >
< p > Declared in " < a class = "reference external" href = "../include/libtorrent/entry.hpp" > libtorrent/entry.hpp< / a > " < / p >
< table border = "1" class = "docutils" >
< colgroup >
< col width = "41%" / >
< col width = "21%" / >
< col width = "38%" / >
< / colgroup >
< thead valign = "bottom" >
< tr > < th class = "head" > name< / th >
< th class = "head" > value< / th >
< th class = "head" > description< / th >
< / tr >
< / thead >
< tbody valign = "top" >
< tr > < td > int_t< / td >
< td > 0< / td >
< td > < / td >
< / tr >
< tr > < td > string_t< / td >
< td > 1< / td >
< td > < / td >
< / tr >
< tr > < td > list_t< / td >
< td > 2< / td >
< td > < / td >
< / tr >
< tr > < td > dictionary_t< / td >
< td > 3< / td >
< td > < / td >
< / tr >
< tr > < td > undefined_t< / td >
< td > 4< / td >
< td > < / td >
< / tr >
< / tbody >
< / table >
< a name = "m_type_queried" > < / a > < dl class = "docutils" >
< dt > m_type_queried< / dt >
< dd > in debug mode this is set to false by bdecode
to indicate that the program has not yet queried
the type of this < a class = "reference external" href = "reference-Bencoding.html#entry" > entry< / a > , and sould not assume
that it has a certain type. This is asserted in
the accessor functions. This does not apply if
exceptions are used.< / dd >
< / dl >
< a name = "pascal_string" > < / a > < / div >
< / div >
< div class = "section" id = "pascal-string" >
< h1 > pascal_string< / h1 >
< p > Declared in " < a class = "reference external" href = "../include/libtorrent/lazy_entry.hpp" > libtorrent/lazy_entry.hpp< / a > " < / p >
< p > this is a string that is not NULL-terminated. Instead it
comes with a length, specified in bytes. This is particularly
useful when parsing bencoded structures, because strings are
not NULL-terminated internally, and requiring NULL termination
would require copying the string.< / p >
< p > see < a class = "reference external" href = "reference-Bencoding.html#string_pstr()" > lazy_entry::string_pstr()< / a > .< / p >
< pre class = "literal-block" >
struct pascal_string
{
< strong > pascal_string< / strong > (char const* p, int l);
bool < strong > operator< < / strong > (pascal_string const& rhs) const;
int len;
char const* ptr;
};
< / pre >
< a name = "pascal_string()" > < / a > < div class = "section" id = "id30" >
< h2 > pascal_string()< / h2 >
< pre class = "literal-block" >
< strong > pascal_string< / strong > (char const* p, int l);
< / pre >
< p > construct a string pointing to the characters at < tt class = "docutils literal" > p< / tt >
of length < tt class = "docutils literal" > l< / tt > characters. No NULL termination is required.< / p >
< a name = "operator<()" > < / a > < / div >
< div class = "section" id = "id31" >
< h2 > operator< ()< / h2 >
< pre class = "literal-block" >
bool < strong > operator< < / strong > (pascal_string const& rhs) const;
< / pre >
< p > lexicographical comparison of strings. Order is consisten
with memcmp.< / p >
< a name = "len" > < / a > < dl class = "docutils" >
< dt > len< / dt >
< dd > the number of characters in the string.< / dd >
< / dl >
< a name = "ptr" > < / a > < dl class = "docutils" >
< dt > ptr< / dt >
< dd > the pointer to the first character in the string. This is
not NULL terminated, but instead consult the < tt class = "docutils literal" > len< / tt > field
to know how many characters follow.< / dd >
< / dl >
< a name = "lazy_entry" > < / a > < / div >
< / div >
< div class = "section" id = "lazy-entry" >
< h1 > lazy_entry< / h1 >
< p > Declared in " < a class = "reference external" href = "../include/libtorrent/lazy_entry.hpp" > libtorrent/lazy_entry.hpp< / a > " < / p >
< p > this object represent a node in a bencoded structure. It is a variant
type whose concrete type is one of:< / p >
< ol class = "arabic simple" >
< li > dictionary (maps strings -> < a class = "reference external" href = "reference-Bencoding.html#lazy_entry" > lazy_entry< / a > )< / li >
< li > list (sequence of < a class = "reference external" href = "reference-Bencoding.html#lazy_entry" > lazy_entry< / a > , i.e. heterogenous)< / li >
< li > integer< / li >
< li > string< / li >
< / ol >
< p > There is also a < tt class = "docutils literal" > none< / tt > type, which is used for uninitialized
lazy_entries.< / p >
< pre class = "literal-block" >
struct lazy_entry
{
entry_type_t < strong > type< / strong > () const;
void < strong > construct_int< / strong > (char const* start, int length);
boost::int64_t < strong > int_value< / strong > () const;
char const* < strong > string_ptr< / strong > () const;
char const* < strong > string_cstr< / strong > () const;
pascal_string < strong > string_pstr< / strong > () const;
std::string < strong > string_value< / strong > () const;
int < strong > string_length< / strong > () const;
lazy_entry const* < strong > dict_find_string< / strong > (char const* name) const;
lazy_entry* < strong > dict_find< / strong > (char const* name);
lazy_entry const* < strong > dict_find< / strong > (char const* name) const;
pascal_string < strong > dict_find_pstr< / strong > (char const* name) const;
std::string < strong > dict_find_string_value< / strong > (char const* name) const;
boost::int64_t < strong > dict_find_int_value< / strong > (char const* name, boost::int64_t default_val = 0) const;
lazy_entry const* < strong > dict_find_int< / strong > (char const* name) const;
lazy_entry const* < strong > dict_find_list< / strong > (char const* name) const;
lazy_entry const* < strong > dict_find_dict< / strong > (char const* name) const;
std::pair< std::string, lazy_entry const*> < strong > dict_at< / strong > (int i) const;
int < strong > dict_size< / strong > () const;
lazy_entry* < strong > list_at< / strong > (int i);
lazy_entry const* < strong > list_at< / strong > (int i) const;
std::string < strong > list_string_value_at< / strong > (int i) const;
pascal_string < strong > list_pstr_at< / strong > (int i) const;
boost::int64_t < strong > list_int_value_at< / strong > (int i, boost::int64_t default_val = 0) const;
int < strong > list_size< / strong > () const;
std::pair< char const*, int> < strong > data_section< / strong > () const;
void < strong > swap< / strong > (lazy_entry& e);
enum entry_type_t
{
none_t,
dict_t,
list_t,
string_t,
int_t,
};
};
< / pre >
< a name = "type()" > < / a > < div class = "section" id = "id35" >
< h2 > type()< / h2 >
< pre class = "literal-block" >
entry_type_t < strong > type< / strong > () const;
< / pre >
< p > tells you which specific type this lazy < a class = "reference external" href = "reference-Bencoding.html#entry" > entry< / a > has.
See < a class = "reference external" href = "reference-Bencoding.html#entry_type_t" > entry_type_t< / a > . The type determines which subset of
member functions are valid to use.< / p >
< a name = "construct_int()" > < / a > < / div >
< div class = "section" id = "construct-int" >
< h2 > construct_int()< / h2 >
< pre class = "literal-block" >
void < strong > construct_int< / strong > (char const* start, int length);
< / pre >
< p > start points to the first decimal digit
length is the number of digits< / p >
< a name = "int_value()" > < / a > < / div >
< div class = "section" id = "int-value" >
< h2 > int_value()< / h2 >
< pre class = "literal-block" >
boost::int64_t < strong > int_value< / strong > () const;
< / pre >
< p > requires the type to be an integer. return the integer value< / p >
< a name = "string_ptr()" > < / a > < / div >
< div class = "section" id = "string-ptr" >
< h2 > string_ptr()< / h2 >
< pre class = "literal-block" >
char const* < strong > string_ptr< / strong > () const;
< / pre >
< p > the string is not null-terminated!
use < a class = "reference external" href = "reference-Bencoding.html#string_length()" > string_length()< / a > to determine how many bytes
are part of the string.< / p >
< a name = "string_cstr()" > < / a > < / div >
< div class = "section" id = "string-cstr" >
< h2 > string_cstr()< / h2 >
< pre class = "literal-block" >
char const* < strong > string_cstr< / strong > () const;
< / pre >
< p > this will return a null terminated string
it will write to the source buffer!< / p >
< a name = "string_pstr()" > < / a > < / div >
< div class = "section" id = "string-pstr" >
< h2 > string_pstr()< / h2 >
< pre class = "literal-block" >
pascal_string < strong > string_pstr< / strong > () const;
< / pre >
< p > if this is a string, returns a < a class = "reference external" href = "reference-Bencoding.html#pascal_string" > pascal_string< / a >
representing the string value.< / p >
< a name = "string_value()" > < / a > < / div >
< div class = "section" id = "string-value" >
< h2 > string_value()< / h2 >
< pre class = "literal-block" >
std::string < strong > string_value< / strong > () const;
< / pre >
< p > if this is a string, returns the string as a std::string.
(which requires a copy)< / p >
< a name = "string_length()" > < / a > < / div >
< div class = "section" id = "string-length" >
< h2 > string_length()< / h2 >
< pre class = "literal-block" >
int < strong > string_length< / strong > () const;
< / pre >
< p > if the < a class = "reference external" href = "reference-Bencoding.html#lazy_entry" > lazy_entry< / a > is a string, returns the
length of the string, in bytes.< / p >
< a name = "dict_find()" > < / a >
< a name = "dict_find_string()" > < / a > < / div >
< div class = "section" id = "dict-find-dict-find-string" >
< h2 > dict_find() dict_find_string()< / h2 >
< pre class = "literal-block" >
lazy_entry const* < strong > dict_find_string< / strong > (char const* name) const;
lazy_entry* < strong > dict_find< / strong > (char const* name);
lazy_entry const* < strong > dict_find< / strong > (char const* name) const;
< / pre >
< p > if this is a dictionary, look for a key < tt class = "docutils literal" > name< / tt > , and return
a pointer to its value, or NULL if there is none.< / p >
< a name = "dict_find_pstr()" > < / a >
< a name = "dict_find_string_value()" > < / a > < / div >
< div class = "section" id = "dict-find-pstr-dict-find-string-value" >
< h2 > dict_find_pstr() dict_find_string_value()< / h2 >
< pre class = "literal-block" >
pascal_string < strong > dict_find_pstr< / strong > (char const* name) const;
std::string < strong > dict_find_string_value< / strong > (char const* name) const;
< / pre >
< p > if this is a dictionary, look for a key < tt class = "docutils literal" > name< / tt > whose value
is a string. If such key exist, return a pointer to
its value, otherwise NULL.< / p >
< a name = "dict_find_int_value()" > < / a >
< a name = "dict_find_int()" > < / a > < / div >
< div class = "section" id = "dict-find-int-value-dict-find-int" >
< h2 > dict_find_int_value() dict_find_int()< / h2 >
< pre class = "literal-block" >
boost::int64_t < strong > dict_find_int_value< / strong > (char const* name, boost::int64_t default_val = 0) const;
lazy_entry const* < strong > dict_find_int< / strong > (char const* name) const;
< / pre >
< p > if this is a dictionary, look for a key < tt class = "docutils literal" > name< / tt > whose value
is an int. If such key exist, return a pointer to its value,
otherwise NULL.< / p >
< a name = "dict_find_list()" > < / a >
< a name = "dict_find_dict()" > < / a > < / div >
< div class = "section" id = "dict-find-list-dict-find-dict" >
< h2 > dict_find_list() dict_find_dict()< / h2 >
< pre class = "literal-block" >
lazy_entry const* < strong > dict_find_list< / strong > (char const* name) const;
lazy_entry const* < strong > dict_find_dict< / strong > (char const* name) const;
< / pre >
< p > these functions require that < tt class = "docutils literal" > this< / tt > is a dictionary.
(this-> type() == dict_t). They look for an element with the
specified name in the dictionary. < tt class = "docutils literal" > dict_find_dict< / tt > only
finds dictionaries and < tt class = "docutils literal" > dict_find_list< / tt > only finds lists.
if no key with the corresponding value of the right type is
found, NULL is returned.< / p >
< a name = "dict_at()" > < / a > < / div >
< div class = "section" id = "dict-at" >
< h2 > dict_at()< / h2 >
< pre class = "literal-block" >
std::pair< std::string, lazy_entry const*> < strong > dict_at< / strong > (int i) const;
< / pre >
< p > if this is a dictionary, return the key value pair at
position < tt class = "docutils literal" > i< / tt > from the dictionary.< / p >
< a name = "dict_size()" > < / a > < / div >
< div class = "section" id = "dict-size" >
< h2 > dict_size()< / h2 >
< pre class = "literal-block" >
int < strong > dict_size< / strong > () const;
< / pre >
< p > requires that < tt class = "docutils literal" > this< / tt > is a dictionary. return the
number of items in it< / p >
< a name = "list_at()" > < / a > < / div >
< div class = "section" id = "list-at" >
< h2 > list_at()< / h2 >
< pre class = "literal-block" >
lazy_entry* < strong > list_at< / strong > (int i);
lazy_entry const* < strong > list_at< / strong > (int i) const;
< / pre >
< p > requires that < tt class = "docutils literal" > this< / tt > is a list. return
the item at index < tt class = "docutils literal" > i< / tt > .< / p >
< a name = "list_string_value_at()" > < / a >
< a name = "list_pstr_at()" > < / a > < / div >
< div class = "section" id = "list-string-value-at-list-pstr-at" >
< h2 > list_string_value_at() list_pstr_at()< / h2 >
< pre class = "literal-block" >
std::string < strong > list_string_value_at< / strong > (int i) const;
pascal_string < strong > list_pstr_at< / strong > (int i) const;
< / pre >
< p > these functions require < tt class = "docutils literal" > this< / tt > to have the type list.
(this-> type() == list_t). < tt class = "docutils literal" > list_string_value_at< / tt > returns
the string at index < tt class = "docutils literal" > i< / tt > . < tt class = "docutils literal" > list_pstr_at< / tt >
returns a < a class = "reference external" href = "reference-Bencoding.html#pascal_string" > pascal_string< / a > of the string value at index < tt class = "docutils literal" > i< / tt > .
if the element at < tt class = "docutils literal" > i< / tt > is not a string, an empty string
is returned.< / p >
< a name = "list_int_value_at()" > < / a > < / div >
< div class = "section" id = "list-int-value-at" >
< h2 > list_int_value_at()< / h2 >
< pre class = "literal-block" >
boost::int64_t < strong > list_int_value_at< / strong > (int i, boost::int64_t default_val = 0) const;
< / pre >
< p > this function require < tt class = "docutils literal" > this< / tt > to have the type list.
(this-> type() == list_t). returns the integer value at
index < tt class = "docutils literal" > i< / tt > . If the element at < tt class = "docutils literal" > i< / tt > is not an integer
< tt class = "docutils literal" > default_val< / tt > is returned, which defaults to 0.< / p >
< a name = "list_size()" > < / a > < / div >
< div class = "section" id = "list-size" >
< h2 > list_size()< / h2 >
< pre class = "literal-block" >
int < strong > list_size< / strong > () const;
< / pre >
< p > if this is a list, return the number of items in it.< / p >
< a name = "data_section()" > < / a > < / div >
< div class = "section" id = "data-section" >
< h2 > data_section()< / h2 >
< pre class = "literal-block" >
std::pair< char const*, int> < strong > data_section< / strong > () const;
< / pre >
< p > returns pointers into the source buffer where
this < a class = "reference external" href = "reference-Bencoding.html#entry" > entry< / a > has its bencoded data< / p >
< a name = "swap()" > < / a > < / div >
< div class = "section" id = "id43" >
< h2 > swap()< / h2 >
< pre class = "literal-block" >
void < strong > swap< / strong > (lazy_entry& e);
< / pre >
< p > swap values of < tt class = "docutils literal" > this< / tt > and < tt class = "docutils literal" > e< / tt > .< / p >
< a name = "entry_type_t" > < / a > < / div >
< div class = "section" id = "enum-entry-type-t" >
< h2 > enum entry_type_t< / h2 >
< p > Declared in " < a class = "reference external" href = "../include/libtorrent/lazy_entry.hpp" > libtorrent/lazy_entry.hpp< / a > " < / p >
< table border = "1" class = "docutils" >
< colgroup >
< col width = "33%" / >
< col width = "23%" / >
< col width = "43%" / >
< / colgroup >
< thead valign = "bottom" >
< tr > < th class = "head" > name< / th >
< th class = "head" > value< / th >
< th class = "head" > description< / th >
< / tr >
< / thead >
< tbody valign = "top" >
< tr > < td > none_t< / td >
< td > 0< / td >
< td > < / td >
< / tr >
< tr > < td > dict_t< / td >
< td > 1< / td >
< td > < / td >
< / tr >
< tr > < td > list_t< / td >
< td > 2< / td >
< td > < / td >
< / tr >
< tr > < td > string_t< / td >
< td > 3< / td >
< td > < / td >
< / tr >
< tr > < td > int_t< / td >
< td > 4< / td >
< td > < / td >
< / tr >
< / tbody >
< / table >
< a name = "bdecode()" > < / a >
< a name = "bencode()" > < / a > < / div >
< div class = "section" id = "bdecode-bencode" >
< h2 > bdecode() bencode()< / h2 >
< p > Declared in " < a class = "reference external" href = "../include/libtorrent/bencode.hpp" > libtorrent/bencode.hpp< / a > " < / p >
< pre class = "literal-block" >
template< class InIt> entry < strong > bdecode< / strong > (InIt start, InIt end);
template< class OutIt> int < strong > bencode< / strong > (OutIt out, const entry& e);
template< class InIt> entry < strong > bdecode< / strong > (InIt start, InIt end, int& len);
< / pre >
< p > These functions will encode data to < a class = "reference external" href = "http://wiki.theory.org/index.php/BitTorrentSpecification" > bencoded< / a > or decode < a class = "reference external" href = "http://wiki.theory.org/index.php/BitTorrentSpecification" > bencoded< / a > data.< / p >
< p > If possible, < a class = "reference external" href = "reference-Bencoding.html#lazy_bdecode()" > lazy_bdecode()< / a > should be preferred over < tt class = "docutils literal" > bdecode()< / tt > .< / p >
< p > The < a class = "reference internal" href = "#entry" > entry< / a > class is the internal representation of the bencoded data
and it can be used to retrieve information, an < a class = "reference internal" href = "#entry" > entry< / a > can also be build by
the program and given to < tt class = "docutils literal" > bencode()< / tt > to encode it into the < tt class = "docutils literal" > OutIt< / tt >
iterator.< / p >
< p > The < tt class = "docutils literal" > OutIt< / tt > and < tt class = "docutils literal" > InIt< / tt > are iterators
(< a class = "reference external" href = "http://www.sgi.com/tech/stl/InputIterator.html" > InputIterator< / a > and < a class = "reference external" href = "http://www.sgi.com/tech/stl/OutputIterator.html" > OutputIterator< / a > respectively). They
are templates and are usually instantiated as < a class = "reference external" href = "http://www.sgi.com/tech/stl/ostream_iterator.html" > ostream_iterator< / a > ,
< a class = "reference external" href = "http://www.sgi.com/tech/stl/back_insert_iterator.html" > back_insert_iterator< / a > or < a class = "reference external" href = "http://www.sgi.com/tech/stl/istream_iterator.html" > istream_iterator< / a > . These
functions will assume that the iterator refers to a character
(< tt class = "docutils literal" > char< / tt > ). So, if you want to encode < a class = "reference external" href = "reference-Bencoding.html#entry" > entry< / a > < tt class = "docutils literal" > e< / tt > into a buffer
in memory, you can do it like this:< / p >
< pre class = "literal-block" >
std::vector< char> buffer;
bencode(std::back_inserter(buf), e);
< / pre >
< p > If you want to decode a torrent file from a buffer in memory, you can do it like this:< / p >
< pre class = "literal-block" >
std::vector< char> buffer;
// ...
entry e = bdecode(buf.begin(), buf.end());
< / pre >
< p > Or, if you have a raw char buffer:< / p >
< pre class = "literal-block" >
const char* buf;
// ...
entry e = bdecode(buf, buf + data_size);
< / pre >
< p > Now we just need to know how to retrieve information from the < a class = "reference external" href = "reference-Bencoding.html#entry" > entry< / a > .< / p >
< p > If < tt class = "docutils literal" > bdecode()< / tt > encounters invalid encoded data in the range given to it
it will throw < a class = "reference external" href = "reference-Error_Codes.html#libtorrent_exception" > libtorrent_exception< / a > .< / p >
< a name = "operator<<()" > < / a > < / div >
< div class = "section" id = "id50" >
< h2 > operator< < ()< / h2 >
< p > Declared in " < a class = "reference external" href = "../include/libtorrent/entry.hpp" > libtorrent/entry.hpp< / a > " < / p >
< pre class = "literal-block" >
inline std::ostream& < strong > operator< < < / strong > (std::ostream& os, const entry& e);
< / pre >
< a name = "lazy_bdecode()" > < / a > < / div >
< div class = "section" id = "lazy-bdecode" >
< h2 > lazy_bdecode()< / h2 >
< p > Declared in " < a class = "reference external" href = "../include/libtorrent/lazy_entry.hpp" > libtorrent/lazy_entry.hpp< / a > " < / p >
< pre class = "literal-block" >
int < strong > lazy_bdecode< / strong > (char const* start, char const* end
, lazy_entry& ret, error_code& ec, int* error_pos = 0
, int depth_limit = 1000, int item_limit = 1000000);
< / pre >
< p > This function decodes < a class = "reference external" href = "http://wiki.theory.org/index.php/BitTorrentSpecification" > bencoded< / a > data.< / p >
< p > Whenever possible, < tt class = "docutils literal" > lazy_bdecode()< / tt > should be preferred over < tt class = "docutils literal" > bdecode()< / tt > .
It is more efficient and more secure. It supports having constraints on the
amount of memory is consumed by the parser.< / p >
< p > < em > lazy< / em > refers to the fact that it doesn't copy any actual data out of the
bencoded buffer. It builds a tree of < tt class = "docutils literal" > lazy_entry< / tt > which has pointers into
the bencoded buffer. This makes it very fast and efficient. On top of that,
it is not recursive, which saves a lot of stack space when parsing deeply
nested trees. However, in order to protect against potential attacks, the
< tt class = "docutils literal" > depth_limit< / tt > and < tt class = "docutils literal" > item_limit< / tt > control how many levels deep the tree is
allowed to get. With recursive parser, a few thousand levels would be enough
to exhaust the threads stack and terminate the process. The < tt class = "docutils literal" > item_limit< / tt >
protects against very large structures, not necessarily deep. Each bencoded
item in the structure causes the parser to allocate some amount of memory,
this memory is constant regardless of how much data actually is stored in
the item. One potential attack is to create a bencoded list of hundreds of
thousands empty strings, which would cause the parser to allocate a significant
amount of memory, perhaps more than is available on the machine, and effectively
provide a denial of service. The default item limit is set as a reasonable
upper limit for desktop computers. Very few torrents have more items in them.
The limit corresponds to about 25 MB, which might be a bit much for embedded
systems.< / p >
< p > < tt class = "docutils literal" > start< / tt > and < tt class = "docutils literal" > end< / tt > defines the bencoded buffer to be decoded. < tt class = "docutils literal" > ret< / tt > is
the < tt class = "docutils literal" > lazy_entry< / tt > which is filled in with the whole decoded tree. < tt class = "docutils literal" > ec< / tt >
is a reference to an < tt class = "docutils literal" > error_code< / tt > which is set to describe the error encountered
in case the function fails. < tt class = "docutils literal" > error_pos< / tt > is an optional pointer to an int,
which will be set to the byte offset into the buffer where an error occurred,
in case the function fails.< / p >
< a name = "get_bdecode_category()" > < / a > < / div >
< div class = "section" id = "get-bdecode-category" >
< h2 > get_bdecode_category()< / h2 >
< p > Declared in " < a class = "reference external" href = "../include/libtorrent/lazy_entry.hpp" > libtorrent/lazy_entry.hpp< / a > " < / p >
< pre class = "literal-block" >
boost::system::error_category& < strong > get_bdecode_category< / strong > ();
< / pre >
< p > get the < tt class = "docutils literal" > error_category< / tt > for bdecode errors< / p >
< a name = "error_code_enum" > < / a > < / div >
< div class = "section" id = "enum-error-code-enum" >
< h2 > enum error_code_enum< / h2 >
< p > Declared in " < a class = "reference external" href = "../include/libtorrent/lazy_entry.hpp" > libtorrent/lazy_entry.hpp< / a > " < / p >
< table border = "1" class = "docutils" >
< colgroup >
< col width = "20%" / >
< col width = "8%" / >
< col width = "72%" / >
< / colgroup >
< thead valign = "bottom" >
< tr > < th class = "head" > name< / th >
< th class = "head" > value< / th >
< th class = "head" > description< / th >
< / tr >
< / thead >
< tbody valign = "top" >
< tr > < td > no_error< / td >
< td > 0< / td >
< td > Not an error< / td >
< / tr >
< tr > < td > expected_string< / td >
< td > 1< / td >
< td > expected string in bencoded string< / td >
< / tr >
< tr > < td > expected_colon< / td >
< td > 2< / td >
< td > expected colon in bencoded string< / td >
< / tr >
< tr > < td > unexpected_eof< / td >
< td > 3< / td >
< td > unexpected end of file in bencoded string< / td >
< / tr >
< tr > < td > expected_value< / td >
< td > 4< / td >
< td > expected value (list, dict, int or string) in bencoded string< / td >
< / tr >
< tr > < td > depth_exceeded< / td >
< td > 5< / td >
< td > bencoded recursion depth limit exceeded< / td >
< / tr >
< tr > < td > limit_exceeded< / td >
< td > 6< / td >
< td > bencoded item count limit exceeded< / td >
< / tr >
< tr > < td > error_code_max< / td >
< td > 7< / td >
< td > the number of error codes< / td >
< / tr >
< / tbody >
< / table >
< / div >
< / div >
< / div >
< div id = "footer" >
< span > Copyright © 2005-2013 Rasterbar Software.< / span >
< / div >
< / div >
< script src = "http://www.google-analytics.com/urchin.js" type = "text/javascript" >
< / script >
< script type = "text/javascript" >
_uacct = "UA-1599045-1";
urchinTracker();
< / script >
< / div >
< / body >
< / html >