/** \brief The benc_get_dict function deserializes a btDict from the stream 'bts'. \param bts a parameter of type struct btStream * \param a a parameter of type btDict * \return int 0 - success, 1 - error */ int benc_get_dict( struct btStream *bts, btDict *a) { int res; int c; char buf[1]; res = bts_read( bts, buf, 1); if (res) return res; if (*buf != 'd') return 1; c = bts_peek( bts); while (c != 'e') { btString *k; btObject *o; k = btString_create( NULL); res = benc_get_string( bts, k); if (res) return res; res = benc_get_object( bts, &o); if (res) return res; if (btDict_add( a, k, o)) { return 1; } c = bts_peek( bts); } res = bts_read( bts, buf, 1); if (res) return res; if (*buf != 'e') return 1; return 0; }
/** \brief The benc_get_string function deserializes a btSring from the stream 'bts' using the BEncoding scheme. \param bts a parameter of type struct btStream* \param s a parameter of type btString * \return int 0 - success, 1 - some error */ int benc_get_string( struct btStream* bts, btString *s) { int res; char ibuf[10]; char *sbuf; int slen; res = bts_scanbreak( bts, "0123456789", ":", ibuf, sizeof(ibuf)); if (res) return res; slen= atoi(ibuf); bt_assert(slen<MAXSTRING); sbuf = btmalloc(slen+1); bt_assert(sbuf); if (slen > 0) { res = bts_read( bts, sbuf, slen); } else if (slen < 0) { errno = BTERR_NEGATIVE_STRING_LENGTH; res = -1; } else { *sbuf = 0; res = 0; } if (res) { btfree(sbuf); return res; } sbuf[slen]=0; btString_setbuf(s, sbuf, slen); return 0; }
/** \brief The benc_get_list function deserializes a list including all list values from the stream 'bts'. \param bts a parameter of type struct btStream * \param a a parameter of type btList * \return int 0 - success, 1 - error */ int benc_get_list( struct btStream *bts, btList *a) { int res; int c; char buf[1]; res = bts_read( bts, buf, 1); if (res) return res; if (*buf != 'l') return 1; c = bts_peek( bts); while (c != 'e') { btObject *o; res = benc_get_object( bts, &o); if (res) return 1; btList_add( a, o); c = bts_peek( bts); } res = bts_read( bts, buf, 1); if (res) return res; if (*buf != 'e') return 1; return 0; }
/* * bts_scanbreak * Read from an input stream and copy characters into 'buf' until hitting * a break character. If there are any characters that are not listed * in 'cset' then an error value is returned. Scanbreak is used to read * bEncoded integers. * * bts - I/O stream, must be an input stream * cset - List of allowed characters * bset - List of break characters * buf - Return value of data read from the stream * bufsz - Available space in the buffer * * return 1 on error, 0 on success */ int bts_scanbreak( btStream* bts, char *cset, char *bset, char *buf, int bufsz) { char s[1]; int res; int len=0; while (len < bufsz) { res = bts_read(bts, s, 1); if (res) return res; if ( strchr( bset, *s)) break; if ( !strchr( cset, *s)) return 1; buf[len++]=*s; } if (len == bufsz) return 1; buf[len]=0; return 0; }
/** \brief The benc_get_int function \param bts a parameter of type struct btStream * \param i a parameter of type btInteger * \return int 0 - success, 1 - error */ int benc_get_int( struct btStream *bts, btInteger *i) { int res; char c[1]; char ibuf[25]; res = bts_read( bts, c, 1); if (res) return res; if (*c != 'i') return 1; res = bts_scanbreak( bts, "0123456789", "e", ibuf, sizeof(ibuf)); if (res) return res; #if HAVE_STRTOLL i->ival = strtoll( ibuf, NULL, 10); #else i->ival = atoi( ibuf); #endif return 0; }