source: trunk/libtransmission/bencode.h @ 12918

Last change on this file since 12918 was 12391, checked in by jordan, 10 years ago

(trunk libT) tweak the ABI of tr_bencToBuf() to match the way it's being used

  • Property svn:keywords set to Date Rev Author Id
File size: 8.2 KB
Line 
1/*
2 * This file Copyright (C) Mnemosyne LLC
3 *
4 * This file is licensed by the GPL version 2. Works owned by the
5 * Transmission project are granted a special exemption to clause 2(b)
6 * so that the bulk of its code can remain under the MIT license.
7 * This exemption does not extend to derived works not owned by
8 * the Transmission project.
9 *
10 * $Id: bencode.h 12391 2011-04-27 21:22:08Z jordan $
11 */
12
13#ifndef TR_BENCODE_H
14#define TR_BENCODE_H 1
15
16#ifdef __cplusplus
17extern "C" {
18#endif
19
20#include <inttypes.h> /* for int64_t */
21
22struct evbuffer;
23
24/**
25 * @addtogroup tr_benc Variant
26 *
27 * An object that acts like a union for
28 * integers, strings, lists, dictionaries, booleans, and floating-point numbers.
29 * The structure is named tr_benc due to the historical reason that it was
30 * originally tightly coupled with bencoded data. It currently supports
31 * being parsed from, and serialized to, both bencoded notation and json notation.
32 *
33 * @{
34 */
35
36/* these are PRIVATE IMPLEMENTATION details that should not be touched.
37 * I'll probably change them just to break your code! HA HA HA!
38 * it's included in the header for inlining and composition */
39enum
40{
41    TR_TYPE_INT  = 1,
42    TR_TYPE_STR  = 2,
43    TR_TYPE_LIST = 4,
44    TR_TYPE_DICT = 8,
45    TR_TYPE_BOOL = 16,
46    TR_TYPE_REAL = 32
47};
48
49/* These are PRIVATE IMPLEMENTATION details that should not be touched.
50 * I'll probably change them just to break your code! HA HA HA!
51 * it's included in the header for inlining and composition */
52typedef struct tr_benc
53{
54    union
55    {
56        uint8_t b; /* bool type */
57
58        double d;  /* double type */
59
60        int64_t i; /* int type */
61
62        struct /* string type */
63        {
64            size_t len; /* the string length */
65            union {
66                char buf[16]; /* local buffer for short strings */
67                char * ptr; /* alloc'ed pointer for long strings */
68            } str;
69        } s;
70
71        struct /* list & dict types */
72        {
73            struct tr_benc * vals; /* nodes */
74            size_t alloc; /* nodes allocated */
75            size_t count; /* nodes used */
76        } l;
77    } val;
78
79    char type;
80} tr_benc;
81
82/***
83****
84***/
85
86int       tr_bencParse( const void     * buf,
87                        const void     * bufend,
88                        tr_benc        * setme_benc,
89                        const uint8_t ** setme_end );
90
91int       tr_bencLoad( const void   * buf,
92                       size_t         buflen,
93                       tr_benc      * setme_benc,
94                       char        ** setme_end );
95
96void      tr_bencFree( tr_benc * );
97
98void      tr_bencInitStr( tr_benc *, const void * str, int str_len );
99
100void      tr_bencInitRaw( tr_benc *, const void * raw, size_t raw_len );
101
102void      tr_bencInitInt( tr_benc *, int64_t num );
103
104int       tr_bencInitDict( tr_benc *, size_t reserveCount );
105
106int       tr_bencInitList( tr_benc *, size_t reserveCount );
107
108void      tr_bencInitBool( tr_benc *, int value );
109
110void      tr_bencInitReal( tr_benc *, double value );
111
112/***
113****  Serialization / Deserialization
114***/
115
116typedef enum
117{
118    TR_FMT_BENC,
119    TR_FMT_JSON,
120    TR_FMT_JSON_LEAN /* saves bandwidth by omitting all whitespace. */
121}
122tr_fmt_mode;
123
124int tr_bencToFile( const tr_benc *, tr_fmt_mode, const char * filename );
125
126char* tr_bencToStr( const tr_benc *, tr_fmt_mode, int * len );
127
128struct evbuffer * tr_bencToBuf( const tr_benc *, tr_fmt_mode );
129
130/* TR_FMT_JSON_LEAN and TR_FMT_JSON are equivalent in this function. */
131int tr_bencLoadFile( tr_benc * setme, tr_fmt_mode, const char * filename );
132
133/***
134****
135***/
136
137int tr_bencListReserve( tr_benc *, size_t reserveCount );
138
139tr_benc * tr_bencListAdd( tr_benc * );
140
141tr_benc * tr_bencListAddBool( tr_benc *, bool val );
142
143tr_benc * tr_bencListAddInt( tr_benc *, int64_t val );
144
145tr_benc * tr_bencListAddReal( tr_benc *, double val );
146
147tr_benc * tr_bencListAddStr( tr_benc *, const char * val );
148
149tr_benc * tr_bencListAddRaw( tr_benc *, const uint8_t * val, size_t len );
150
151tr_benc * tr_bencListAddList( tr_benc *, size_t reserveCount );
152
153tr_benc * tr_bencListAddDict( tr_benc *, size_t reserveCount );
154
155size_t    tr_bencListSize( const tr_benc * list );
156
157tr_benc * tr_bencListChild( tr_benc * list, size_t n );
158
159int       tr_bencListRemove( tr_benc *, size_t n );
160
161/***
162****
163***/
164
165int       tr_bencDictReserve( tr_benc *, size_t reserveCount );
166
167int       tr_bencDictRemove( tr_benc *, const char * key );
168
169tr_benc * tr_bencDictAdd( tr_benc *, const char * key );
170
171tr_benc * tr_bencDictAddReal( tr_benc *, const char * key, double );
172
173tr_benc * tr_bencDictAddInt( tr_benc *, const char * key, int64_t );
174
175tr_benc * tr_bencDictAddBool( tr_benc *, const char * key, bool );
176
177tr_benc * tr_bencDictAddStr( tr_benc *, const char * key, const char * );
178
179tr_benc * tr_bencDictAddList( tr_benc *, const char * key, size_t reserve );
180
181tr_benc * tr_bencDictAddDict( tr_benc *, const char * key, size_t reserve );
182
183tr_benc * tr_bencDictAddRaw( tr_benc *, const char * key,
184                             const void * raw, size_t rawlen );
185
186bool      tr_bencDictChild( tr_benc *, size_t i, const char ** key, tr_benc ** val );
187
188tr_benc*  tr_bencDictFind( tr_benc *, const char * key );
189
190bool      tr_bencDictFindList( tr_benc *, const char * key, tr_benc ** setme );
191
192bool      tr_bencDictFindDict( tr_benc *, const char * key, tr_benc ** setme );
193
194bool      tr_bencDictFindInt( tr_benc *, const char * key, int64_t * setme );
195
196bool      tr_bencDictFindReal( tr_benc *, const char * key, double * setme );
197
198bool      tr_bencDictFindBool( tr_benc *, const char * key, bool * setme );
199
200bool      tr_bencDictFindStr( tr_benc *, const char * key, const char ** setme );
201
202bool      tr_bencDictFindRaw( tr_benc *, const char * key,
203                              const uint8_t ** setme_raw, size_t * setme_len );
204
205/***
206****
207***/
208
209/** @brief Get an int64_t from a variant object
210    @return true if successful, or false if the variant could not be represented as an int64_t  */
211bool      tr_bencGetInt( const tr_benc * val, int64_t * setme );
212
213/** @brief Get an string from a variant object
214    @return true if successful, or false if the variant could not be represented as a string  */
215bool      tr_bencGetStr( const tr_benc * val, const char ** setme );
216
217/** @brief Get a raw byte array from a variant object
218    @return true if successful, or false if the variant could not be represented as a raw byte array */
219bool      tr_bencGetRaw( const tr_benc * val, const uint8_t  ** setme_raw, size_t * setme_len );
220
221/** @brief Get a boolean from a variant object
222    @return true if successful, or false if the variant could not be represented as a boolean  */
223bool      tr_bencGetBool( const tr_benc * val, bool * setme );
224
225/** @brief Get a floating-point number from a variant object
226    @return true if successful, or false if the variant could not be represented as a floating-point number  */
227bool      tr_bencGetReal( const tr_benc * val, double * setme );
228
229static inline bool tr_bencIsType  ( const tr_benc * b, int type ) { return ( b != NULL ) && ( b->type == type ); }
230
231static inline bool tr_bencIsInt   ( const tr_benc * b ) { return tr_bencIsType( b, TR_TYPE_INT ); }
232static inline bool tr_bencIsDict  ( const tr_benc * b ) { return tr_bencIsType( b, TR_TYPE_DICT ); }
233static inline bool tr_bencIsList  ( const tr_benc * b ) { return tr_bencIsType( b, TR_TYPE_LIST ); }
234static inline bool tr_bencIsString( const tr_benc * b ) { return tr_bencIsType( b, TR_TYPE_STR ); }
235static inline bool tr_bencIsBool  ( const tr_benc * b ) { return tr_bencIsType( b, TR_TYPE_BOOL ); }
236static inline bool tr_bencIsReal  ( const tr_benc * b ) { return tr_bencIsType( b, TR_TYPE_REAL ); }
237
238/** @brief Private function that's exposed here only for unit tests */
239int tr_bencParseInt( const uint8_t *  buf,
240                     const uint8_t *  bufend,
241                     const uint8_t ** setme_end,
242                     int64_t *        setme_val );
243
244/** @brief Private function that's exposed here only for unit tests */
245int tr_bencParseStr( const uint8_t *  buf,
246                     const uint8_t *  bufend,
247                     const uint8_t ** setme_end,
248                     const uint8_t ** setme_str,
249                     size_t *         setme_strlen );
250
251/**
252***
253**/
254
255/* this is only quasi-supported. don't rely on it too heavily outside of libT */
256void  tr_bencMergeDicts( tr_benc * target, const tr_benc * source );
257
258/* @} */
259
260#ifdef __cplusplus
261}
262#endif
263
264#endif
Note: See TracBrowser for help on using the repository browser.