source: trunk/libtransmission/variant.h @ 13672

Last change on this file since 13672 was 13672, checked in by jordan, 9 years ago

(trunk, libT) faster JSON parsing for tr_variant. This mostly helps the Qt client, which makes heavy use of the JSON-based RPC calls.

File size: 13.3 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:$
11 */
12
13#ifndef TR_VARIANT_H
14#define TR_VARIANT_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_variant 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_variant 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_VARIANT_TYPE_INT  = 1,
42  TR_VARIANT_TYPE_STR  = 2,
43  TR_VARIANT_TYPE_LIST = 4,
44  TR_VARIANT_TYPE_DICT = 8,
45  TR_VARIANT_TYPE_BOOL = 16,
46  TR_VARIANT_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_variant
53{
54  char type;
55
56  union
57    {
58      bool b;
59
60      double d;
61
62      int64_t i;
63
64      struct
65        {
66          size_t len; /* the string length */
67          union
68            {
69              char buf[16]; /* local buffer for short strings */
70              char * ptr; /* alloc'ed pointer for long strings */
71            }
72          str;
73        }
74      s;
75
76      struct
77        {
78          struct tr_variant * vals; /* nodes */
79          size_t alloc; /* nodes allocated */
80          size_t count; /* nodes used */
81        } l;
82    }
83  val;
84}
85tr_variant;
86
87void  tr_variantFree (tr_variant *);
88
89/***
90****  Serialization / Deserialization
91***/
92
93typedef enum
94{
95    TR_VARIANT_FMT_BENC,
96    TR_VARIANT_FMT_JSON,
97    TR_VARIANT_FMT_JSON_LEAN /* saves bandwidth by omitting all whitespace. */
98}
99tr_variant_fmt;
100
101int tr_variantToFile (const tr_variant * variant,
102                      tr_variant_fmt     fmt,
103                      const char       * filename);
104
105char* tr_variantToStr (const tr_variant * variant,
106                       tr_variant_fmt     fmt,
107                       int              * len);
108
109struct evbuffer * tr_variantToBuf (const tr_variant * variant,
110                                   tr_variant_fmt     fmt);
111
112/* TR_VARIANT_FMT_JSON_LEAN and TR_VARIANT_FMT_JSON are equivalent here. */
113int tr_variantFromFile (tr_variant      * setme,
114                        tr_variant_fmt    fmt,
115                        const char      * filename);
116
117/* TR_VARIANT_FMT_JSON_LEAN and TR_VARIANT_FMT_JSON are equivalent here. */
118int tr_variantFromBuf (tr_variant     * setme,
119                       tr_variant_fmt   fmt,
120                       const void     * buf,
121                       size_t           buflen,
122                       const char     * optional_source,
123                       const char    ** setme_end);
124
125static inline int
126tr_variantFromBenc (tr_variant * setme,
127                    const void * buf,
128                    size_t       buflen)
129{
130  return tr_variantFromBuf (setme, TR_VARIANT_FMT_BENC,
131                            buf, buflen, NULL, NULL);
132}
133static inline int
134tr_variantFromBencFull (tr_variant  * setme,
135                        const void  * buf,
136                        size_t        buflen,
137                        const char  * source,
138                        const char ** setme_end)
139{
140  return tr_variantFromBuf (setme,
141                            TR_VARIANT_FMT_BENC,
142                            buf,
143                            buflen,
144                            source,
145                            setme_end);
146}
147static inline int
148tr_variantFromJsonFull (tr_variant  * setme,
149                        const void  * buf,
150                        size_t        buflen,
151                        const char  * source,
152                        const char ** setme_end)
153{
154  return tr_variantFromBuf (setme,
155                            TR_VARIANT_FMT_JSON,
156                            buf,
157                            buflen,
158                            source,
159                            setme_end);
160}
161static inline int
162tr_variantFromJson (tr_variant  * setme,
163                    const void  * buf,
164                    size_t        buflen)
165{
166  return tr_variantFromBuf (setme,
167                            TR_VARIANT_FMT_JSON,
168                            buf,
169                            buflen,
170                            NULL,
171                            NULL);
172}
173static inline bool
174tr_variantIsType (const tr_variant * b, int type)
175{
176  return (b != NULL) && (b->type == type);
177}
178
179
180/***
181****  Strings
182***/
183
184static inline bool
185tr_variantIsString (const tr_variant * b)
186{
187  return tr_variantIsType (b, TR_VARIANT_TYPE_STR);
188}
189
190bool         tr_variantGetStr          (const tr_variant * variant,
191                                        const char      ** setme_str,
192                                        size_t           * setme_len);
193                                                                 
194void         tr_variantInitStr         (tr_variant       * initme,
195                                        const void       * str,
196                                        int                str_len);
197
198void         tr_variantInitRaw         (tr_variant       * initme,
199                                        const void       * raw,
200                                        size_t             raw_len);
201
202bool         tr_variantGetRaw          (const tr_variant * variant,
203                                        const uint8_t   ** raw_setme,
204                                        size_t           * len_setme);
205/***
206****  Real Numbers
207***/
208
209static inline bool
210tr_variantIsReal (const tr_variant * b)
211{
212  return tr_variantIsType (b, TR_VARIANT_TYPE_REAL);
213}
214
215void         tr_variantInitReal        (tr_variant       * initme,
216                                        double             value);
217
218bool         tr_variantGetReal         (const tr_variant * variant,
219                                        double           * value_setme);
220
221/***
222****  Booleans
223***/
224
225static inline bool
226tr_variantIsBool (const tr_variant * b)
227{
228  return tr_variantIsType (b, TR_VARIANT_TYPE_BOOL);
229}
230
231void         tr_variantInitBool        (tr_variant       * initme,
232                                        bool               value);
233
234bool         tr_variantGetBool         (const tr_variant * variant,
235                                        bool             * setme);
236
237
238/***
239****  Ints
240***/
241
242static inline bool
243tr_variantIsInt (const tr_variant * b)
244{
245  return tr_variantIsType (b, TR_VARIANT_TYPE_INT);
246}
247
248void         tr_variantInitInt         (tr_variant       * variant,
249                                        int64_t            value);
250
251bool         tr_variantGetInt          (const tr_variant * val,
252                                        int64_t          * setme);
253
254/***
255****  Lists
256***/
257
258static inline bool
259tr_variantIsList (const tr_variant * b)
260{
261  return tr_variantIsType (b, TR_VARIANT_TYPE_LIST);
262}
263
264int          tr_variantInitList        (tr_variant       * list,
265                                        size_t             reserve_count);
266
267int          tr_variantListReserve     (tr_variant       * list,
268                                        size_t             reserve_count);
269
270tr_variant * tr_variantListAdd         (tr_variant       * list);
271
272tr_variant * tr_variantListAddBool     (tr_variant       * list,
273                                        bool               addme);
274
275tr_variant * tr_variantListAddInt      (tr_variant       * list,
276                                        int64_t            addme);
277
278tr_variant * tr_variantListAddReal     (tr_variant       * list,
279                                        double             addme);
280
281tr_variant * tr_variantListAddStr      (tr_variant       * list,
282                                        const char       * addme);
283
284tr_variant * tr_variantListAddRaw      (tr_variant       * list,
285                                        const void       * addme_value,
286                                        size_t             addme_len);
287
288tr_variant * tr_variantListAddList     (tr_variant       * list,
289                                        size_t             reserve_count);
290
291tr_variant * tr_variantListAddDict     (tr_variant       * list,
292                                        size_t             reserve_count);
293
294tr_variant * tr_variantListChild       (tr_variant       * list,
295                                        size_t             pos);
296
297int          tr_variantListRemove      (tr_variant       * list,
298                                        size_t             pos);
299
300size_t       tr_variantListSize        (const tr_variant * list);
301
302
303/***
304****  Dictionaries
305***/
306
307static inline bool
308tr_variantIsDict (const tr_variant * b)
309{
310  return tr_variantIsType (b, TR_VARIANT_TYPE_DICT);
311}
312
313int          tr_variantInitDict        (tr_variant       * initme,
314                                        size_t             reserve_count);
315
316int          tr_variantDictReserve     (tr_variant       * dict,
317                                        size_t             reserve_count);
318
319int          tr_variantDictRemove      (tr_variant       * dict,
320                                        const char       * key);
321
322tr_variant * tr_variantDictAdd         (tr_variant       * dict,
323                                        const char       * key,
324                                        int                keylen);
325
326tr_variant * tr_variantDictAddReal     (tr_variant       * dict,
327                                        const char       * key,
328                                        double             value);
329
330tr_variant * tr_variantDictAddInt      (tr_variant       * dict,
331                                        const char       * key,
332                                        int64_t            value);
333
334tr_variant * tr_variantDictAddBool     (tr_variant       * dict,
335                                        const char       * key,
336                                        bool               value);
337
338tr_variant * tr_variantDictAddStr      (tr_variant       * dict,
339                                        const char       * key,
340                                        const char       * value);
341
342tr_variant * tr_variantDictAddList     (tr_variant       * dict,
343                                        const char       * key,
344                                        size_t             reserve_count);
345
346tr_variant * tr_variantDictAddDict     (tr_variant       * dict,
347                                        const char       * key,
348                                        size_t             reserve_count);
349
350tr_variant * tr_variantDictAddRaw      (tr_variant       * dict,
351                                        const char       * key,
352                                        const void       * value,
353                                        size_t             len);
354
355bool         tr_variantDictChild       (tr_variant       * dict,
356                                        size_t             pos,
357                                        const char      ** setme_key,
358                                        tr_variant      ** setme_value);
359
360tr_variant * tr_variantDictFind        (tr_variant       * dict,
361                                        const char       * key);
362
363bool         tr_variantDictFindList    (tr_variant       * dict,
364                                        const char       * key,
365                                        tr_variant      ** setme);
366
367bool         tr_variantDictFindDict    (tr_variant       * dict,
368                                        const char       * key,
369                                        tr_variant      ** setme_value);
370
371bool         tr_variantDictFindInt     (tr_variant       * dict,
372                                        const char       * key,
373                                        int64_t          * setme);
374
375bool         tr_variantDictFindReal    (tr_variant       * dict,
376                                        const char       * key,
377                                        double           * setme);
378
379bool         tr_variantDictFindBool    (tr_variant       * dict,
380                                        const char       * key,
381                                        bool             * setme);
382
383bool         tr_variantDictFindStr     (tr_variant       * dict,
384                                        const char       * key,
385                                        const char      ** setme,
386                                        size_t           * len);
387
388bool         tr_variantDictFindRaw     (tr_variant       * dict,
389                                        const char       * key,
390                                        const uint8_t   ** setme_raw,
391                                        size_t           * setme_len);
392
393/* this is only quasi-supported. don't rely on it too heavily outside of libT */
394void         tr_variantMergeDicts      (tr_variant       * dict_target,
395                                        const tr_variant * dict_source);
396
397/***
398****
399****
400***/
401
402/**
403***
404**/
405
406/* @} */
407
408#ifdef __cplusplus
409}
410#endif
411
412#endif
Note: See TracBrowser for help on using the repository browser.