~ubuntu-branches/ubuntu/maverick/libtorrent-rasterbar/maverick

« back to all changes in this revision

Viewing changes to src/entry.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Cristian Greco
  • Date: 2008-07-02 10:46:21 UTC
  • Revision ID: james.westby@ubuntu.com-20080702104621-jzx3pfke9lkcxfxn
Tags: upstream-0.13.1
ImportĀ upstreamĀ versionĀ 0.13.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 
 
3
Copyright (c) 2003, Arvid Norberg
 
4
All rights reserved.
 
5
 
 
6
Redistribution and use in source and binary forms, with or without
 
7
modification, are permitted provided that the following conditions
 
8
are met:
 
9
 
 
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.
 
18
 
 
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.
 
30
 
 
31
*/
 
32
 
 
33
#include "libtorrent/pch.hpp"
 
34
 
 
35
#include <algorithm>
 
36
#include <iostream>
 
37
#include <iomanip>
 
38
#include "libtorrent/entry.hpp"
 
39
#include "libtorrent/config.hpp"
 
40
 
 
41
#if defined(_MSC_VER)
 
42
namespace std
 
43
{
 
44
        using ::isprint;
 
45
}
 
46
#define for if (false) {} else for
 
47
#endif
 
48
 
 
49
namespace
 
50
{
 
51
        template <class T>
 
52
        void call_destructor(T* o)
 
53
        {
 
54
                TORRENT_ASSERT(o);
 
55
                o->~T();
 
56
        }
 
57
}
 
58
 
 
59
namespace libtorrent
 
60
{
 
61
        namespace detail
 
62
        {
 
63
                TORRENT_EXPORT char const* integer_to_str(char* buf, int size, entry::integer_type val)
 
64
                {
 
65
                        int sign = 0;
 
66
                        if (val < 0)
 
67
                        {
 
68
                                sign = 1;
 
69
                                val = -val;
 
70
                        }
 
71
                        buf[--size] = '\0';
 
72
                        if (val == 0) buf[--size] = '0';
 
73
                        for (; size > sign && val != 0;)
 
74
                        {
 
75
                                buf[--size] = '0' + char(val % 10);
 
76
                                val /= 10;
 
77
                        }
 
78
                        if (sign) buf[--size] = '-';
 
79
                        return buf + size;
 
80
                }
 
81
        }
 
82
 
 
83
        entry& entry::operator[](char const* key)
 
84
        {
 
85
                dictionary_type::iterator i = dict().find(key);
 
86
                if (i != dict().end()) return i->second;
 
87
                dictionary_type::iterator ret = dict().insert(
 
88
                        dict().begin()
 
89
                        , std::make_pair(key, entry()));
 
90
                return ret->second;
 
91
        }
 
92
 
 
93
        entry& entry::operator[](std::string const& key)
 
94
        {
 
95
                dictionary_type::iterator i = dict().find(key);
 
96
                if (i != dict().end()) return i->second;
 
97
                dictionary_type::iterator ret = dict().insert(
 
98
                        dict().begin()
 
99
                        , std::make_pair(std::string(key), entry()));
 
100
                return ret->second;
 
101
        }
 
102
 
 
103
        entry* entry::find_key(char const* key)
 
104
        {
 
105
                dictionary_type::iterator i = dict().find(key);
 
106
                if (i == dict().end()) return 0;
 
107
                return &i->second;
 
108
        }
 
109
 
 
110
        entry const* entry::find_key(char const* key) const
 
111
        {
 
112
                dictionary_type::const_iterator i = dict().find(key);
 
113
                if (i == dict().end()) return 0;
 
114
                return &i->second;
 
115
        }
 
116
        
 
117
        entry* entry::find_key(std::string const& key)
 
118
        {
 
119
                dictionary_type::iterator i = dict().find(key);
 
120
                if (i == dict().end()) return 0;
 
121
                return &i->second;
 
122
        }
 
123
 
 
124
        entry const* entry::find_key(std::string const& key) const
 
125
        {
 
126
                dictionary_type::const_iterator i = dict().find(key);
 
127
                if (i == dict().end()) return 0;
 
128
                return &i->second;
 
129
        }
 
130
        
 
131
#ifndef BOOST_NO_EXCEPTIONS
 
132
        const entry& entry::operator[](char const* key) const
 
133
        {
 
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());
 
137
                return i->second;
 
138
        }
 
139
 
 
140
        const entry& entry::operator[](std::string const& key) const
 
141
        {
 
142
                return (*this)[key.c_str()];
 
143
        }
 
144
#endif
 
145
 
 
146
        entry::entry(dictionary_type const& v)
 
147
                : m_type(undefined_t)
 
148
        {
 
149
                new(data) dictionary_type(v);
 
150
                m_type = dictionary_t;
 
151
        }
 
152
 
 
153
        entry::entry(string_type const& v)
 
154
                : m_type(undefined_t)
 
155
        {
 
156
                new(data) string_type(v);
 
157
                m_type = string_t;
 
158
        }
 
159
 
 
160
        entry::entry(list_type const& v)
 
161
                : m_type(undefined_t)
 
162
        {
 
163
                new(data) list_type(v);
 
164
                m_type = list_t;
 
165
        }
 
166
 
 
167
        entry::entry(integer_type const& v)
 
168
                : m_type(undefined_t)
 
169
        {
 
170
                new(data) integer_type(v);
 
171
                m_type = int_t;
 
172
        }
 
173
 
 
174
        void entry::operator=(dictionary_type const& v)
 
175
        {
 
176
                destruct();
 
177
                new(data) dictionary_type(v);
 
178
                m_type = dictionary_t;
 
179
        }
 
180
 
 
181
        void entry::operator=(string_type const& v)
 
182
        {
 
183
                destruct();
 
184
                new(data) string_type(v);
 
185
                m_type = string_t;
 
186
        }
 
187
 
 
188
        void entry::operator=(list_type const& v)
 
189
        {
 
190
                destruct();
 
191
                new(data) list_type(v);
 
192
                m_type = list_t;
 
193
        }
 
194
 
 
195
        void entry::operator=(integer_type const& v)
 
196
        {
 
197
                destruct();
 
198
                new(data) integer_type(v);
 
199
                m_type = int_t;
 
200
        }
 
201
 
 
202
        bool entry::operator==(entry const& e) const
 
203
        {
 
204
                if (m_type != e.m_type) return false;
 
205
 
 
206
                switch(m_type)
 
207
                {
 
208
                case int_t:
 
209
                        return integer() == e.integer();
 
210
                case string_t:
 
211
                        return string() == e.string();
 
212
                case list_t:
 
213
                        return list() == e.list();
 
214
                case dictionary_t:
 
215
                        return dict() == e.dict();
 
216
                default:
 
217
                        TORRENT_ASSERT(m_type == undefined_t);
 
218
                        return true;
 
219
                }
 
220
        }
 
221
 
 
222
        void entry::construct(data_type t)
 
223
        {
 
224
                switch(t)
 
225
                {
 
226
                case int_t:
 
227
                        new(data) integer_type;
 
228
                        break;
 
229
                case string_t:
 
230
                        new(data) string_type;
 
231
                        break;
 
232
                case list_t:
 
233
                        new(data) list_type;
 
234
                        break;
 
235
                case dictionary_t:
 
236
                        new (data) dictionary_type;
 
237
                        break;
 
238
                default:
 
239
                        TORRENT_ASSERT(m_type == undefined_t);
 
240
                        m_type = undefined_t;
 
241
                        return;
 
242
                }
 
243
                m_type = t;
 
244
        }
 
245
 
 
246
        void entry::copy(entry const& e)
 
247
        {
 
248
                switch(e.m_type)
 
249
                {
 
250
                case int_t:
 
251
                        new(data) integer_type(e.integer());
 
252
                        break;
 
253
                case string_t:
 
254
                        new(data) string_type(e.string());
 
255
                        break;
 
256
                case list_t:
 
257
                        new(data) list_type(e.list());
 
258
                        break;
 
259
                case dictionary_t:
 
260
                        new (data) dictionary_type(e.dict());
 
261
                        break;
 
262
                default:
 
263
                        m_type = undefined_t;
 
264
                        return;
 
265
                }
 
266
                m_type = e.m_type;
 
267
        }
 
268
 
 
269
        void entry::destruct()
 
270
        {
 
271
                switch(m_type)
 
272
                {
 
273
                case int_t:
 
274
                        call_destructor(reinterpret_cast<integer_type*>(data));
 
275
                        break;
 
276
                case string_t:
 
277
                        call_destructor(reinterpret_cast<string_type*>(data));
 
278
                        break;
 
279
                case list_t:
 
280
                        call_destructor(reinterpret_cast<list_type*>(data));
 
281
                        break;
 
282
                case dictionary_t:
 
283
                        call_destructor(reinterpret_cast<dictionary_type*>(data));
 
284
                        break;
 
285
                default:
 
286
                        TORRENT_ASSERT(m_type == undefined_t);
 
287
                        break;
 
288
                }
 
289
                m_type = undefined_t;
 
290
        }
 
291
 
 
292
        void entry::swap(entry& e)
 
293
        {
 
294
                // not implemented
 
295
                TORRENT_ASSERT(false);
 
296
        }
 
297
 
 
298
        void entry::print(std::ostream& os, int indent) const
 
299
        {
 
300
                TORRENT_ASSERT(indent >= 0);
 
301
                for (int i = 0; i < indent; ++i) os << " ";
 
302
                switch (m_type)
 
303
                {
 
304
                case int_t:
 
305
                        os << integer() << "\n";
 
306
                        break;
 
307
                case string_t:
 
308
                        {
 
309
                                bool binary_string = false;
 
310
                                for (std::string::const_iterator i = string().begin(); i != string().end(); ++i)
 
311
                                {
 
312
                                        if (!std::isprint(static_cast<unsigned char>(*i)))
 
313
                                        {
 
314
                                                binary_string = true;
 
315
                                                break;
 
316
                                        }
 
317
                                }
 
318
                                if (binary_string)
 
319
                                {
 
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);
 
327
                                        os << "\n";
 
328
                                }
 
329
                                else
 
330
                                {
 
331
                                        os << string() << "\n";
 
332
                                }
 
333
                        } break;
 
334
                case list_t:
 
335
                        {
 
336
                                os << "list\n";
 
337
                                for (list_type::const_iterator i = list().begin(); i != list().end(); ++i)
 
338
                                {
 
339
                                        i->print(os, indent+1);
 
340
                                }
 
341
                        } break;
 
342
                case dictionary_t:
 
343
                        {
 
344
                                os << "dictionary\n";
 
345
                                for (dictionary_type::const_iterator i = dict().begin(); i != dict().end(); ++i)
 
346
                                {
 
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)
 
351
                                                os << "\n";
 
352
                                        else os << " ";
 
353
                                        i->second.print(os, indent+2);
 
354
                                }
 
355
                        } break;
 
356
                default:
 
357
                        os << "<uninitialized>\n";
 
358
                }
 
359
        }
 
360
}
 
361