1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
|
/*
* Copyright (c) 2003, 2004 Michael Pyne <[email protected]>
*
* This software is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; see the file COPYING.
* If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _BDICT_H
#define _BDICT_H
#include <qdict.h>
#include <qcstring.h> // QByteArray
#include "bytetape.h"
#include "bbase.h"
// Some useful typedefs
typedef QDict<BBase> BBaseHash;
typedef QDictIterator<BBase> BBaseHashIterator;
// Forward declarations
class BInt;
class BList;
class BString;
/**
* Class to handle the BitTorrent b-encoded dictionary. It is keyed
* using const char *strings, and stores pointers to a class descended
* from BBase, such as BInt, BString, BList, or even more BDicts.
*
* @author Michael Pyne <[email protected]>
* @see BBase, BInt, BString, BList
*/
class BDict : public BBase
{
public:
/**
* Construct a dictionary based on the b-encoded data contained in
* @p dict. You need to pass a value for @p start if the b-encoded
* dictionary doesn't start at the beginning of @p dict.
*
* @param dict the buffer containing the b-encoded dictionary
* @param start the position of the data within the buffer
*/
BDict (QByteArray &dict, int start = 0);
/**
* Construct a dictionary from a ByteTape. The data and current
* position of @p tape will be shared with all objects using it.
* @p tape should already be positioned to the b-encoded dictionary.
* After construction, @p tape will point to the byte after the
* dictionary if successful. If not successful, @p tape will have
* an undefined position.
*
* @param tape the ByteTape to read from
* @see ByteTape
*/
BDict (ByteTape &tape);
/**
* Destroys the object and frees all memory allocated to it.
*/
virtual ~BDict();
/**
* Returns the type of this class.
*
* @return bDict. This value is only returned by this class.
*/
virtual classID type_id() const { return bDict; }
/**
* Returns the number of keyed values contained within this
* dictionary.
*
* @return the number of items in this dictionary
*/
virtual int count() const { return m_map.count(); }
/**
* This function should be called to determine whether the
* dictionary was successfully created, since no exceptions
* are thrown.
*
* @return true if this is a valid (possibly empty!) dictionary,
* false otherwise
*/
virtual bool isValid() const { return m_valid; }
/**
* This function determines whether or not a value with a
* certain key exists in the dictionary. The key is case-sensitive.
*
* @param key the key to search for a value for
* @return true, if there is a value for the @p key in the
* dictionary, false otherwise
*/
virtual bool contains (const char *key) { return m_map.find(key) != 0; }
/**
* Returns a pointer to the BBase descendant keyed by @p key. You
* can use the type_id() method to determine the type of the
* object returned.
*
* @param key the key to search the dictionary for
* @return a pointer to the matching object, or 0 if no object
* matches the key
* @see BBase
*/
virtual BBase *find (const char *key) { return m_map.find(key); }
/**
* Convienience function to find and return a BInt keyed by @p key.
*
* @param key the key to find a value for
* @return 0 if the key doesn't match a value, or if the value isn't
* a BInt. Otherwise, a pointer to the matching BInt is
* returned.
* @see BInt
*/
BInt* findInt (const char *key);
/**
* Convienience function to find and return a BList keyed by @p key.
*
* @param key the key to find a value for
* @return 0 if the key doesn't match a value, or if the value isn't
* a BList. Otherwise, a pointer to the matching BList is
* returned.
* @see BList
*/
BList* findList (const char *key);
/**
* Convienience function to find and return a BDict keyed by @p key.
*
* @param key the key to find a value for
* @return 0 if the key doesn't match a value, or if the value isn't
* a BDict. Otherwise, a pointer to the matching BDict is
* returned.
* @see BDict
*/
BDict* findDict (const char *key);
/**
* Convienience function to find and return a BString keyed by @p key.
*
* @param key the key to find a value for
* @return 0 if the key doesn't match a value, or if the value isn't
* a BString. Otherwise, a pointer to the matching BString is
* returned.
* @see BString
*/
BString* findStr (const char *key);
/**
* Outputs the b-encoded representation of the object to the given
* QIODevice.
* @param device the QIODevice to write to
* @return true on a successful write, false otherwise
*/
virtual bool writeToDevice (QIODevice &device);
/**
* Returns a QDictIterator<BBase> that you can use to iterate through
* the items in the dictionary.
*
* @return QDictIterator<BBase>, which can be used to iterate through
* the items in the dictionary.
*/
BBaseHashIterator iterator() const
{
return BBaseHashIterator(m_map);
}
private:
/**
* This function handles the actual initialization of the object upon
* construction, and set the m_valid flag if successful.
*
* @param tape the ByteTape to read from
*/
void init (ByteTape &tape);
BBaseHash m_map; /// The QDict that actually store the data
bool m_valid; /// Store initialization status
};
#endif /* _BDICT_H */
// vim: set et sw=4 ts=4:
|