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
#include "libtorrent/pch.hpp"
38
#include "libtorrent/entry.hpp"
39
#include "libtorrent/config.hpp"
46
#define for if (false) {} else for
52
void call_destructor(T* o)
63
TORRENT_EXPORT char const* integer_to_str(char* buf, int size, entry::integer_type val)
72
if (val == 0) buf[--size] = '0';
73
for (; size > sign && val != 0;)
75
buf[--size] = '0' + char(val % 10);
78
if (sign) buf[--size] = '-';
83
entry& entry::operator[](char const* key)
85
dictionary_type::iterator i = dict().find(key);
86
if (i != dict().end()) return i->second;
87
dictionary_type::iterator ret = dict().insert(
89
, std::make_pair(key, entry()));
93
entry& entry::operator[](std::string const& key)
95
dictionary_type::iterator i = dict().find(key);
96
if (i != dict().end()) return i->second;
97
dictionary_type::iterator ret = dict().insert(
99
, std::make_pair(std::string(key), entry()));
103
entry* entry::find_key(char const* key)
105
dictionary_type::iterator i = dict().find(key);
106
if (i == dict().end()) return 0;
110
entry const* entry::find_key(char const* key) const
112
dictionary_type::const_iterator i = dict().find(key);
113
if (i == dict().end()) return 0;
117
entry* entry::find_key(std::string const& key)
119
dictionary_type::iterator i = dict().find(key);
120
if (i == dict().end()) return 0;
124
entry const* entry::find_key(std::string const& key) const
126
dictionary_type::const_iterator i = dict().find(key);
127
if (i == dict().end()) return 0;
131
#ifndef BOOST_NO_EXCEPTIONS
132
const entry& entry::operator[](char const* key) const
134
dictionary_type::const_iterator i = dict().find(key);
135
if (i == dict().end()) throw type_error(
136
(std::string("key not found: ") + key).c_str());
140
const entry& entry::operator[](std::string const& key) const
142
return (*this)[key.c_str()];
146
entry::entry(dictionary_type const& v)
147
: m_type(undefined_t)
149
new(data) dictionary_type(v);
150
m_type = dictionary_t;
153
entry::entry(string_type const& v)
154
: m_type(undefined_t)
156
new(data) string_type(v);
160
entry::entry(list_type const& v)
161
: m_type(undefined_t)
163
new(data) list_type(v);
167
entry::entry(integer_type const& v)
168
: m_type(undefined_t)
170
new(data) integer_type(v);
174
void entry::operator=(dictionary_type const& v)
177
new(data) dictionary_type(v);
178
m_type = dictionary_t;
181
void entry::operator=(string_type const& v)
184
new(data) string_type(v);
188
void entry::operator=(list_type const& v)
191
new(data) list_type(v);
195
void entry::operator=(integer_type const& v)
198
new(data) integer_type(v);
202
bool entry::operator==(entry const& e) const
204
if (m_type != e.m_type) return false;
209
return integer() == e.integer();
211
return string() == e.string();
213
return list() == e.list();
215
return dict() == e.dict();
217
TORRENT_ASSERT(m_type == undefined_t);
222
void entry::construct(data_type t)
227
new(data) integer_type;
230
new(data) string_type;
236
new (data) dictionary_type;
239
TORRENT_ASSERT(m_type == undefined_t);
240
m_type = undefined_t;
246
void entry::copy(entry const& e)
251
new(data) integer_type(e.integer());
254
new(data) string_type(e.string());
257
new(data) list_type(e.list());
260
new (data) dictionary_type(e.dict());
263
m_type = undefined_t;
269
void entry::destruct()
274
call_destructor(reinterpret_cast<integer_type*>(data));
277
call_destructor(reinterpret_cast<string_type*>(data));
280
call_destructor(reinterpret_cast<list_type*>(data));
283
call_destructor(reinterpret_cast<dictionary_type*>(data));
286
TORRENT_ASSERT(m_type == undefined_t);
289
m_type = undefined_t;
292
void entry::swap(entry& e)
295
TORRENT_ASSERT(false);
298
void entry::print(std::ostream& os, int indent) const
300
TORRENT_ASSERT(indent >= 0);
301
for (int i = 0; i < indent; ++i) os << " ";
305
os << integer() << "\n";
309
bool binary_string = false;
310
for (std::string::const_iterator i = string().begin(); i != string().end(); ++i)
312
if (!std::isprint(static_cast<unsigned char>(*i)))
314
binary_string = true;
320
os.unsetf(std::ios_base::dec);
321
os.setf(std::ios_base::hex);
322
for (std::string::const_iterator i = string().begin(); i != string().end(); ++i)
323
os << std::setfill('0') << std::setw(2)
324
<< static_cast<unsigned int>((unsigned char)*i);
325
os.unsetf(std::ios_base::hex);
326
os.setf(std::ios_base::dec);
331
os << string() << "\n";
337
for (list_type::const_iterator i = list().begin(); i != list().end(); ++i)
339
i->print(os, indent+1);
344
os << "dictionary\n";
345
for (dictionary_type::const_iterator i = dict().begin(); i != dict().end(); ++i)
347
for (int j = 0; j < indent+1; ++j) os << " ";
348
os << "[" << i->first << "]";
349
if (i->second.type() != entry::string_t
350
&& i->second.type() != entry::int_t)
353
i->second.print(os, indent+2);
357
os << "<uninitialized>\n";