1 | /****************************************************************************** |
---|
2 | * $Id: bencode.h 5643 2008-04-18 16:23:59Z charles $ |
---|
3 | * |
---|
4 | * Copyright (c) 2005-2008 Transmission authors and contributors |
---|
5 | * |
---|
6 | * Permission is hereby granted, free of charge, to any person obtaining a |
---|
7 | * copy of this software and associated documentation files (the "Software"), |
---|
8 | * to deal in the Software without restriction, including without limitation |
---|
9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
---|
10 | * and/or sell copies of the Software, and to permit persons to whom the |
---|
11 | * Software is furnished to do so, subject to the following conditions: |
---|
12 | * |
---|
13 | * The above copyright notice and this permission notice shall be included in |
---|
14 | * all copies or substantial portions of the Software. |
---|
15 | * |
---|
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
---|
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
---|
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
---|
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
---|
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
---|
21 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
---|
22 | * DEALINGS IN THE SOFTWARE. |
---|
23 | *****************************************************************************/ |
---|
24 | |
---|
25 | #ifndef TR_BENCODE_H |
---|
26 | #define TR_BENCODE_H 1 |
---|
27 | |
---|
28 | #include <inttypes.h> /* for int64_t */ |
---|
29 | #include <string.h> /* for memset */ |
---|
30 | |
---|
31 | typedef struct tr_benc |
---|
32 | { |
---|
33 | #define TYPE_INT 1 |
---|
34 | #define TYPE_STR 2 |
---|
35 | #define TYPE_LIST 4 |
---|
36 | #define TYPE_DICT 8 |
---|
37 | char type; |
---|
38 | union |
---|
39 | { |
---|
40 | int64_t i; |
---|
41 | struct |
---|
42 | { |
---|
43 | int i; |
---|
44 | int nofree; |
---|
45 | char * s; |
---|
46 | } s; |
---|
47 | struct |
---|
48 | { |
---|
49 | int alloc; |
---|
50 | int count; |
---|
51 | struct tr_benc * vals; |
---|
52 | } l; |
---|
53 | } val; |
---|
54 | } tr_benc; |
---|
55 | |
---|
56 | /* backwards compatability */ |
---|
57 | typedef tr_benc benc_val_t; |
---|
58 | |
---|
59 | int tr_bencParse( const void * buf, |
---|
60 | const void * bufend, |
---|
61 | tr_benc * setme_benc, |
---|
62 | const uint8_t ** setme_end ); |
---|
63 | |
---|
64 | int tr_bencLoad( const void * buf, |
---|
65 | int buflen, |
---|
66 | tr_benc * setme_benc, |
---|
67 | char ** setme_end ); |
---|
68 | |
---|
69 | void tr_bencPrint( const tr_benc * ); |
---|
70 | void tr_bencFree( tr_benc * ); |
---|
71 | int tr_bencDictFindInt( tr_benc * dict, const char * key, int64_t * setme ); |
---|
72 | int tr_bencDictFindStr( tr_benc * dict, const char * key, const char ** setme ); |
---|
73 | int tr_bencDictFindList( tr_benc * dict, const char * key, tr_benc ** setme ); |
---|
74 | int tr_bencDictFindDict( tr_benc * dict, const char * key, tr_benc ** setme ); |
---|
75 | tr_benc * tr_bencDictFind( tr_benc * dict, const char * key ); |
---|
76 | tr_benc * tr_bencDictFindType( tr_benc * dict, const char * key, int type ); |
---|
77 | tr_benc * tr_bencDictFindFirst( tr_benc * dict, ... ); |
---|
78 | |
---|
79 | /* marks a string as 'do not free' and returns it */ |
---|
80 | char * tr_bencStealStr( tr_benc * val ); |
---|
81 | |
---|
82 | /* convenience functions for building tr_benc structures */ |
---|
83 | |
---|
84 | static inline void tr_bencInit( tr_benc * val, int type ) |
---|
85 | { |
---|
86 | memset( val, 0, sizeof( *val ) ); |
---|
87 | val->type = type; |
---|
88 | } |
---|
89 | |
---|
90 | #define tr_bencInitStr( a, b, c, d ) \ |
---|
91 | _tr_bencInitStr( (a), ( char * )(b), (c), (d) ) |
---|
92 | void _tr_bencInitStr( tr_benc * val, char * str, int len, int nofree ); |
---|
93 | int tr_bencInitStrDup( tr_benc * val, const char * str ); |
---|
94 | void tr_bencInitRaw( tr_benc * val, const void * src, size_t byteCount ); |
---|
95 | int tr_bencInitStrDupLen( tr_benc * val, const char * str, int len ); |
---|
96 | void tr_bencInitInt( tr_benc * val, int64_t num ); |
---|
97 | int tr_bencInitDict( tr_benc * val, int reserveCount ); |
---|
98 | int tr_bencInitList( tr_benc * val, int reserveCount ); |
---|
99 | int tr_bencListReserve( tr_benc * list, int count ); |
---|
100 | /* note that for one key-value pair, count should be 1, not 2 */ |
---|
101 | int tr_bencDictReserve( tr_benc * dict, int count ); |
---|
102 | tr_benc * tr_bencListAdd( tr_benc * list ); |
---|
103 | tr_benc * tr_bencListAddInt( tr_benc * list, int64_t val ); |
---|
104 | tr_benc * tr_bencListAddStr( tr_benc * list, const char * val ); |
---|
105 | tr_benc * tr_bencListAddList( tr_benc * list, int reserveCount ); |
---|
106 | tr_benc * tr_bencListAddDict( tr_benc * list, int reserveCount ); |
---|
107 | /* note: key must not be freed or modified while val is in use */ |
---|
108 | tr_benc * tr_bencDictAdd( tr_benc * dict, const char * key ); |
---|
109 | tr_benc * tr_bencDictAddInt( tr_benc * dict, const char * key, int64_t val ); |
---|
110 | tr_benc * tr_bencDictAddStr( tr_benc * dict, const char * key, const char * val ); |
---|
111 | tr_benc * tr_bencDictAddList( tr_benc * dict, const char * key, int reserveCount ); |
---|
112 | tr_benc * tr_bencDictAddDict( tr_benc * dict, const char * key, int reserveCount ); |
---|
113 | tr_benc * tr_bencDictAddRaw( tr_benc * dict, const char * key, const void *, size_t len ); |
---|
114 | |
---|
115 | char* tr_bencSave( const tr_benc * val, int * len ); |
---|
116 | char* tr_bencSaveAsSerializedPHP( const tr_benc * top, int * len ); |
---|
117 | int tr_bencSaveFile( const char * filename, const tr_benc * ); |
---|
118 | int tr_bencLoadFile( const char * filename, tr_benc * ); |
---|
119 | |
---|
120 | int tr_bencGetInt( const tr_benc * val, int64_t * setme ); |
---|
121 | |
---|
122 | int tr_bencIsType( const tr_benc *, int type ); |
---|
123 | #define tr_bencIsInt(b) (tr_bencIsType(b,TYPE_INT)) |
---|
124 | #define tr_bencIsDict(b) (tr_bencIsType(b,TYPE_DICT)) |
---|
125 | #define tr_bencIsList(b) (tr_bencIsType(b,TYPE_LIST)) |
---|
126 | #define tr_bencIsString(b) (tr_bencIsType(b,TYPE_STR)) |
---|
127 | |
---|
128 | /** |
---|
129 | *** Treat these as private -- they're only made public here |
---|
130 | *** so that the unit tests can find them |
---|
131 | **/ |
---|
132 | |
---|
133 | int tr_bencParseInt( const uint8_t * buf, |
---|
134 | const uint8_t * bufend, |
---|
135 | const uint8_t ** setme_end, |
---|
136 | int64_t * setme_val ); |
---|
137 | |
---|
138 | int tr_bencParseStr( const uint8_t * buf, |
---|
139 | const uint8_t * bufend, |
---|
140 | const uint8_t ** setme_end, |
---|
141 | uint8_t ** setme_str, |
---|
142 | size_t * setme_strlen ); |
---|
143 | |
---|
144 | /** |
---|
145 | *** |
---|
146 | **/ |
---|
147 | |
---|
148 | tr_benc * tr_bencListGetNthChild( tr_benc * list, int n ); |
---|
149 | |
---|
150 | |
---|
151 | #endif |
---|