~hendrik-grewe/transmission/private-patch

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
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
/*
 * This file Copyright (C) 2008-2014 Mnemosyne LLC
 *
 * It may be used under the GNU GPL versions 2 or 3
 * or any future license endorsed by Mnemosyne LLC.
 *
 * $Id$
 */

#ifndef TR_VARIANT_H
#define TR_VARIANT_H 1

#ifdef __cplusplus
extern "C" {
#endif

#include <inttypes.h> /* for int64_t */
#include "quark.h"

struct evbuffer;

/**
 * @addtogroup tr_variant Variant
 *
 * An object that acts like a union for
 * integers, strings, lists, dictionaries, booleans, and floating-point numbers.
 * The structure is named tr_variant due to the historical reason that it was
 * originally tightly coupled with bencoded data. It currently supports
 * being parsed from, and serialized to, both bencoded notation and json notation.
 *
 * @{
 */

typedef enum
{
  TR_STRING_TYPE_QUARK,
  TR_STRING_TYPE_HEAP,
  TR_STRING_TYPE_BUF
}
tr_string_type;

/* these are PRIVATE IMPLEMENTATION details that should not be touched.
 * I'll probably change them just to break your code! HA HA HA!
 * it's included in the header for inlining and composition */
struct tr_variant_string
{
  tr_string_type type;
  tr_quark quark;
  size_t len;
  union { char buf[16]; const char * str; } str;
};
  

/* these are PRIVATE IMPLEMENTATION details that should not be touched.
 * I'll probably change them just to break your code! HA HA HA!
 * it's included in the header for inlining and composition */
enum
{
  TR_VARIANT_TYPE_INT  = 1,
  TR_VARIANT_TYPE_STR  = 2,
  TR_VARIANT_TYPE_LIST = 4,
  TR_VARIANT_TYPE_DICT = 8,
  TR_VARIANT_TYPE_BOOL = 16,
  TR_VARIANT_TYPE_REAL = 32
};

/* These are PRIVATE IMPLEMENTATION details that should not be touched.
 * I'll probably change them just to break your code! HA HA HA!
 * it's included in the header for inlining and composition */
typedef struct tr_variant
{
  char type;

  tr_quark key;

  union
    {
      bool b;

      double d;

      int64_t i;

      struct tr_variant_string s;

      struct
        {
          size_t alloc;
          size_t count;
          struct tr_variant * vals;
        } l;
    }
  val;
}
tr_variant;

void  tr_variantFree (tr_variant *);

/***
****  Serialization / Deserialization
***/

typedef enum
{
    TR_VARIANT_FMT_BENC,
    TR_VARIANT_FMT_JSON,
    TR_VARIANT_FMT_JSON_LEAN /* saves bandwidth by omitting all whitespace. */
}
tr_variant_fmt;

int tr_variantToFile (const tr_variant * variant,
                      tr_variant_fmt     fmt,
                      const char       * filename);

char* tr_variantToStr (const tr_variant * variant,
                       tr_variant_fmt     fmt,
                       int              * len);

struct evbuffer * tr_variantToBuf (const tr_variant * variant,
                                   tr_variant_fmt     fmt);

/* TR_VARIANT_FMT_JSON_LEAN and TR_VARIANT_FMT_JSON are equivalent here. */
int tr_variantFromFile (tr_variant      * setme,
                        tr_variant_fmt    fmt,
                        const char      * filename);

/* TR_VARIANT_FMT_JSON_LEAN and TR_VARIANT_FMT_JSON are equivalent here. */
int tr_variantFromBuf (tr_variant     * setme,
                       tr_variant_fmt   fmt,
                       const void     * buf,
                       size_t           buflen,
                       const char     * optional_source,
                       const char    ** setme_end);

static inline int
tr_variantFromBenc (tr_variant * setme,
                    const void * buf,
                    size_t       buflen)
{
  return tr_variantFromBuf (setme, TR_VARIANT_FMT_BENC,
                            buf, buflen, NULL, NULL);
}
static inline int
tr_variantFromBencFull (tr_variant  * setme,
                        const void  * buf,
                        size_t        buflen,
                        const char  * source,
                        const char ** setme_end)
{
  return tr_variantFromBuf (setme,
                            TR_VARIANT_FMT_BENC,
                            buf,
                            buflen,
                            source,
                            setme_end);
}
static inline int
tr_variantFromJsonFull (tr_variant  * setme,
                        const void  * buf,
                        size_t        buflen,
                        const char  * source,
                        const char ** setme_end)
{
  return tr_variantFromBuf (setme,
                            TR_VARIANT_FMT_JSON,
                            buf,
                            buflen,
                            source,
                            setme_end);
}
static inline int
tr_variantFromJson (tr_variant  * setme,
                    const void  * buf,
                    size_t        buflen)
{
  return tr_variantFromBuf (setme,
                            TR_VARIANT_FMT_JSON,
                            buf,
                            buflen,
                            NULL,
                            NULL);
}
static inline bool
tr_variantIsType (const tr_variant * b, int type)
{
  return (b != NULL) && (b->type == type);
}


/***
****  Strings
***/

static inline bool
tr_variantIsString (const tr_variant * b)
{
  return (b != NULL) && (b->type == TR_VARIANT_TYPE_STR);
}

bool         tr_variantGetStr          (const tr_variant * variant,
                                        const char      ** setme_str,
                                        size_t           * setme_len);
                                                                 
void         tr_variantInitStr         (tr_variant       * initme,
                                        const void       * str,
                                        int                str_len);

void         tr_variantInitQuark       (tr_variant       * initme,
                                        const tr_quark     quark);

void         tr_variantInitRaw         (tr_variant       * initme,
                                        const void       * raw,
                                        size_t             raw_len);

bool         tr_variantGetRaw          (const tr_variant * variant,
                                        const uint8_t   ** raw_setme,
                                        size_t           * len_setme);
/***
****  Real Numbers
***/

static inline bool
tr_variantIsReal (const tr_variant * v)
{
  return (v != NULL) && (v->type == TR_VARIANT_TYPE_REAL);
}

void         tr_variantInitReal        (tr_variant       * initme,
                                        double             value);

bool         tr_variantGetReal         (const tr_variant * variant,
                                        double           * value_setme);

/***
****  Booleans
***/

static inline bool
tr_variantIsBool (const tr_variant * v)
{
  return (v != NULL) && (v->type == TR_VARIANT_TYPE_BOOL);
}

void         tr_variantInitBool        (tr_variant       * initme,
                                        bool               value);

bool         tr_variantGetBool         (const tr_variant * variant,
                                        bool             * setme);


/***
****  Ints
***/

static inline bool
tr_variantIsInt (const tr_variant * v)
{
  return (v != NULL) && (v->type == TR_VARIANT_TYPE_INT);
}

void         tr_variantInitInt         (tr_variant       * variant,
                                        int64_t            value);

bool         tr_variantGetInt          (const tr_variant * val,
                                        int64_t          * setme);

/***
****  Lists
***/

static inline bool
tr_variantIsList (const tr_variant * v)
{
  return (v != NULL) && (v->type == TR_VARIANT_TYPE_LIST);
}

void         tr_variantInitList        (tr_variant       * list,
                                        size_t             reserve_count);

void         tr_variantListReserve     (tr_variant       * list,
                                        size_t             reserve_count);

tr_variant * tr_variantListAdd         (tr_variant       * list);

tr_variant * tr_variantListAddBool     (tr_variant       * list,
                                        bool               addme);

tr_variant * tr_variantListAddInt      (tr_variant       * list,
                                        int64_t            addme);

tr_variant * tr_variantListAddReal     (tr_variant       * list,
                                        double             addme);

tr_variant * tr_variantListAddStr      (tr_variant       * list,
                                        const char       * addme);

tr_variant * tr_variantListAddQuark    (tr_variant       * list,
                                        const tr_quark     addme);

tr_variant * tr_variantListAddRaw      (tr_variant       * list,
                                        const void       * addme_value,
                                        size_t             addme_len);

tr_variant * tr_variantListAddList     (tr_variant       * list,
                                        size_t             reserve_count);

tr_variant * tr_variantListAddDict     (tr_variant       * list,
                                        size_t             reserve_count);

tr_variant * tr_variantListChild       (tr_variant       * list,
                                        size_t             pos);

bool         tr_variantListRemove      (tr_variant       * list,
                                        size_t             pos);

size_t       tr_variantListSize        (const tr_variant * list);


/***
****  Dictionaries
***/

static inline bool
tr_variantIsDict (const tr_variant * v)
{
  return (v != NULL) && (v->type == TR_VARIANT_TYPE_DICT);
}

void         tr_variantInitDict        (tr_variant       * initme,
                                        size_t             reserve_count);

void         tr_variantDictReserve     (tr_variant       * dict,
                                        size_t             reserve_count);

bool         tr_variantDictRemove      (tr_variant       * dict,
                                        const tr_quark     key);

tr_variant * tr_variantDictAdd         (tr_variant       * dict,
                                        const tr_quark     key);

tr_variant * tr_variantDictAddReal     (tr_variant       * dict,
                                        const tr_quark     key,
                                        double             value);

tr_variant * tr_variantDictAddInt      (tr_variant       * dict,
                                        const tr_quark     key,
                                        int64_t            value);

tr_variant * tr_variantDictAddBool     (tr_variant       * dict,
                                        const tr_quark     key,
                                        bool               value);

tr_variant * tr_variantDictAddStr      (tr_variant       * dict,
                                        const tr_quark     key,
                                        const char       * value);

tr_variant * tr_variantDictAddQuark    (tr_variant       * dict,
                                        const tr_quark     key,
                                        const tr_quark     val);

tr_variant * tr_variantDictAddList     (tr_variant       * dict,
                                        const tr_quark     key,
                                        size_t             reserve_count);

tr_variant * tr_variantDictAddDict     (tr_variant       * dict,
                                        const tr_quark     key,
                                        size_t             reserve_count);

tr_variant * tr_variantDictAddRaw      (tr_variant       * dict,
                                        const tr_quark     key,
                                        const void       * value,
                                        size_t             len);

bool         tr_variantDictChild       (tr_variant       * dict,
                                        size_t             pos,
                                        tr_quark         * setme_key,
                                        tr_variant      ** setme_value);

tr_variant * tr_variantDictFind        (tr_variant       * dict,
                                        const tr_quark     key);

bool         tr_variantDictFindList    (tr_variant       * dict,
                                        const tr_quark     key,
                                        tr_variant      ** setme);

bool         tr_variantDictFindDict    (tr_variant       * dict,
                                        const tr_quark     key,
                                        tr_variant      ** setme_value);

bool         tr_variantDictFindInt     (tr_variant       * dict,
                                        const tr_quark     key,
                                        int64_t          * setme);

bool         tr_variantDictFindReal    (tr_variant       * dict,
                                        const tr_quark     key,
                                        double           * setme);

bool         tr_variantDictFindBool    (tr_variant       * dict,
                                        const tr_quark     key,
                                        bool             * setme);

bool         tr_variantDictFindStr     (tr_variant       * dict,
                                        const tr_quark     key,
                                        const char      ** setme,
                                        size_t           * len);

bool         tr_variantDictFindRaw     (tr_variant       * dict,
                                        const tr_quark     key,
                                        const uint8_t   ** setme_raw,
                                        size_t           * setme_len);

/* this is only quasi-supported. don't rely on it too heavily outside of libT */
void         tr_variantMergeDicts      (tr_variant       * dict_target,
                                        const tr_variant * dict_source);

/***
****
****
***/

/**
***
**/

/* @} */

#ifdef __cplusplus
}
#endif

#endif