Пример #1
0
int be_encode(be_node *node, char *str, int len)
{
	size_t i;
	int loc = 0;

	switch (node->type) {
		case BE_STR:
			bd_snprintf(str, len, "%lli:", be_str_len(node));
			loc += strlen(&(str[loc]));

			memcpy(&(str[loc]), node->val.s, be_str_len(node));
			loc += be_str_len(node);
			break;

		case BE_INT:
			bd_snprintf(str, len, "i%llie", node->val.i);
			loc += strlen(&(str[loc]));
			break;

		case BE_LIST:

			snprintf(str, len, "l");
			loc += 1;

			for (i = 0; node->val.l[i]; ++i)
			{
				loc += be_encode(node->val.l[i], &(str[loc]), len-loc);
			}

			snprintf(&(str[loc]), len - loc, "e");
			loc += 1;

			break;

		case BE_DICT:
			snprintf(str, len, "d");
			loc += 1;

			for (i = 0; node->val.d[i].val; ++i) {
				
				/* assumption that key must be ascii! */
				snprintf(&(str[loc]), len-loc, "%i:%s", 
						(int) strlen(node->val.d[i].key),
						node->val.d[i].key);
				loc += strlen(&(str[loc]));
				loc += be_encode(node->val.d[i].val, &(str[loc]), len-loc);
			}

			snprintf(&(str[loc]), len - loc, "e");
			loc += 1;

			break;
	}
	return loc;
}
Пример #2
0
unsigned char *be_encode(bencode_t *bencode, size_t *size)
{
    unsigned char *buf;
    unsigned int length;    // size of buf without '\0'

    switch(bencode->type) {
        case BE_INTEGER:
            //printf("int\t%d\n", *(bencode->n));

            length = (unsigned int)log10((double)*bencode->n) + 1;
            //printf("length=%d\n", length);
            buf = (unsigned char *)malloc(sizeof(char) * (length + 3));    // 3: 'i', 'e', '\0'

            sprintf(buf, "i%de", *bencode->n);
            length += 2;    // 2: 'e', 'i'
            buf[length] = '\0';
            break;

        case BE_STRING:
            //printf("str\n");
            {
                int digits;

                length = bencode->str->length;
                digits = (int)log10((double)length) + 1;
                buf = (unsigned char *)malloc(sizeof(char) * (length + digits + 2));    // 2: ':', '\0'

                sprintf(buf, "%d:", length);
                memcpy(buf + digits + 1, bencode->str->data, length);    // 1: ':'a

                length += digits + 1;    // 1: ':'
                buf[length] = '\0';
            }
            break;

        case BE_LIST:
            //printf("list\n");
            {
                list_t *list;
                unsigned char *buf1;
                size_t buf_size  = 512;    // current size of allocated memory for buf
                size_t buf1_size = 0;

                length = 0;

                list = bencode->list;
                buf = (unsigned char *)malloc(sizeof(char) * buf_size);

                *buf = 'l';
                length++;

                while(list) {
                    buf1 = be_encode(list->bencode, &buf1_size);

                    while(length + buf1_size + 1 > buf_size) {    // 1: '\0'
                        buf_size *= 2;
                        buf = (unsigned char*)realloc(buf, sizeof(char) * buf_size);
                    }

                    memcpy(buf + length, buf1, buf1_size);
                    length += buf1_size;

                    free(buf1);

                    list = list->next;
                }

                length += 1;    // 1: 'e'
                buf = (unsigned char *)realloc(buf, sizeof(char) * (length + 1));    // 1:'\0'
                buf[length - 1] = 'e';
                buf[length] = '\0';

                //printf("list\tend:%d\t\t[%s]\n", length, buf);
            }
            break;

        case BE_DICT:
            //printf("dict\n");
            {
                list_t *dict;
                unsigned char *buf1;
                unsigned char *buf2;
                size_t buf_size  = 512;    // current size of allocated memory for buf
                size_t buf1_size = 0;
                size_t buf2_size = 0;

                length = 0;

                dict = bencode->dict;
                buf = (unsigned char *)malloc(sizeof(char) * buf_size);

                *buf = 'd';
                length++;

                while(dict) {
                    buf1 = be_encode(dict->bencode + 0, &buf1_size);
                    //printf("dict\tbuf1\t%s\n", buf1);
                    buf2 = be_encode(dict->bencode + 1, &buf2_size);
                    //printf("dict\tbuf2\t%s\n", buf2);

                    while(length + buf1_size + buf2_size + 1 > buf_size) {    // 1: '\0'
                        buf_size *= 2;
                        buf = (unsigned char*)realloc(buf, sizeof(char) * buf_size);
                    }

                    memcpy(buf + length, buf1, buf1_size);
                    length += buf1_size;
                    memcpy(buf + length, buf2, buf2_size);
                    length += buf2_size;

                    free(buf1);
                    free(buf2);

                    dict = dict->next;
                }

                length += 1;    // 1: 'e'
                buf = (unsigned char *)realloc(buf, sizeof(char) * (length + 1));    // 1: '\0'
                buf[length - 1] = 'e';
                buf[length] = '\0';

                //printf("dict\tend:%d\t\t{%s}\n", length, buf);
            }
            break;

        default:
            //printf("\n\n\n\ndefault\t%d\n\n\n\n", bencode->type);
            return NULL;
    }

    if(size != NULL) {
        *size = length;
    }
    return buf;
}