void TestBencodeDictGetNextTwice(
    CuTest * tc
)
{
    bencode_t ben;

    bencode_t ben2;

    char *str = strdup("d4:test3:egg3:foo3:hame");

    const char *ren;

    int len;

    bencode_init(&ben, str, strlen(str));

    bencode_dict_get_next(&ben, &ben2, &ren, &len);
    CuAssertTrue(tc, !strncmp(ren, "test", len));
    bencode_string_value(&ben2, &ren, &len);
    CuAssertTrue(tc, !strncmp("egg", ren, len));

    bencode_dict_get_next(&ben, &ben2, &ren, &len);
    CuAssertTrue(tc, !strncmp(ren, "foo", len));
    bencode_string_value(&ben2, &ren, &len);
    CuAssertTrue(tc, !strncmp("ham", ren, len));
//    printf("%s\n", str);
//    CuAssertTrue(tc, !strcmp("l4:test3:fooe", str));
    free(str);
}
void TestBencodeDictGetNextInnerList(
    CuTest * tc
)
{
    bencode_t ben;

    bencode_t ben2;

    bencode_t ben3;

    char *str = strdup("d3:keyl4:test3:fooee");

    const char *ren;

    int len;

    bencode_init(&ben, str, strlen(str));

    bencode_dict_get_next(&ben, &ben2, &ren, &len);
    CuAssertTrue(tc, !strncmp(ren, "key", len));

    bencode_list_get_next(&ben2, &ben3);
    bencode_string_value(&ben3, &ren, &len);
    CuAssertTrue(tc, !strncmp("test", ren, len));

    bencode_list_get_next(&ben2, &ben3);
    bencode_string_value(&ben3, &ren, &len);
    CuAssertTrue(tc, !strncmp("foo", ren, len));

    CuAssertTrue(tc, !bencode_dict_has_next(&ben));
//    printf("%s\n", str);
//    CuAssertTrue(tc, !strcmp("l4:test3:fooe", str));
    free(str);
}
void TestBencodeListGetNextTwice(
    CuTest * tc
)
{
    bencode_t ben;

    bencode_t ben2;

    char *str = strdup("l4:test3:fooe");

    const char *ren;

    int len;

    bencode_init(&ben, str, strlen(str));

    CuAssertTrue(tc, 1 == bencode_list_get_next(&ben, &ben2));
    bencode_string_value(&ben2, &ren, &len);
    CuAssertTrue(tc, !strncmp("test", ren, len));

    CuAssertTrue(tc, 1 == bencode_list_get_next(&ben, &ben2));
    bencode_string_value(&ben2, &ren, &len);
    CuAssertTrue(tc, !strncmp("foo", ren, len));

//    printf("%s\n", str);
//    CuAssertTrue(tc, !strcmp("l4:test3:fooe", str));
    free(str);
}
void TestBencodeStringHandlesNonAscii0(
    CuTest * tc
)
{
    bencode_t ben;

    char *str = strdup("6:xxxxxx");

    const char *ren;

    int len;

    /*  127.0.0.1:80 */
    str[2] = 127;
    str[3] = 0;
    str[4] = 0;
    str[5] = 1;
    str[6] = 0;
    str[7] = 80;

    bencode_init(&ben, str, 8);

    bencode_string_value(&ben, &ren, &len);
    CuAssertTrue(tc, ren[0] == 127);
    CuAssertTrue(tc, ren[1] == 0);
    CuAssertTrue(tc, ren[2] == 0);
    CuAssertTrue(tc, ren[3] == 1);
    CuAssertTrue(tc, ren[4] == 0);
    CuAssertTrue(tc, ren[5] == 80);
    bencode_done(&ben);
    free(str);
}
void TestBencodeWontDoShortExpectedLength2(
    CuTest * tc
)
{
    bencode_t ben;

    char *str = strdup("4:test");

    const char *ren;

    int len;

    bencode_init(&ben, str, 1);
    CuAssertTrue(tc, 0 == bencode_string_value(&ben, &ren, &len));
    free(str);
}
/**
 * The string value function errors when the string is of insufficient length
 * */
void TestBencodeStringInvalid(
    CuTest * tc
)
{
    bencode_t ben;

    char *str = strdup("5:test");

    const char *ren;

    int len;

    bencode_init(&ben, str, strlen(str));
    bencode_string_value(&ben, &ren, &len);
    CuAssertTrue(tc, !ren);
    free(str);
}
void TestBencodeStringValue2(
    CuTest * tc
)
{
    bencode_t ben;

    char *str = strdup("12:flyinganimal");

    const char *ren;

    int len;

    bencode_init(&ben, str, strlen(str));
    bencode_string_value(&ben, &ren, &len);
    CuAssertTrue(tc, !strncmp("flyinganimal", ren, len));
    free(str);
}
void TestBencodeStringValue(
    CuTest * tc
)
{
    bencode_t ben;

    char *str = strdup("4:test");

    const char *ren;

    int len;

    //*ptr = 0;
    bencode_init(&ben, str, strlen(str));
    bencode_string_value(&ben, &ren, &len);
    CuAssertTrue(tc, !strncmp("test", ren, len));
    bencode_done(&ben);
    free(str);
}
void TestBencodeListGetNext(
    CuTest * tc
)
{
    bencode_t ben, ben2;

    char *str = strdup("l3:foo3:bare");

    const char *ren;

    int len;

    bencode_init(&ben, str, strlen(str));

    CuAssertTrue(tc, 1 == bencode_list_get_next(&ben, &ben2));
    bencode_string_value(&ben2, &ren, &len);
    CuAssertTrue(tc, !strncmp("foo", ren, len));
    free(str);
}
void TestBencodeListInListWithValue(
    CuTest * tc
)
{
    bencode_t ben, ben2, ben3;
    const char *ren;
    char *str = strdup("ll3:fooee");
    int len;

    bencode_init(&ben, str, strlen(str));

    CuAssertTrue(tc, 1 == bencode_is_list(&ben));
    CuAssertTrue(tc, 1 == bencode_list_get_next(&ben, &ben2));
    CuAssertTrue(tc, 1 == bencode_is_list(&ben2));
    CuAssertTrue(tc, 1 == bencode_list_get_next(&ben2, &ben3));
    CuAssertTrue(tc, 1 == bencode_is_string(&ben3));
    bencode_string_value(&ben3, &ren, &len);
    CuAssertTrue(tc, !strncmp("foo", ren, len));
    CuAssertTrue(tc, 0 == bencode_list_get_next(&ben, &ben2));
    free(str);
}
void TestBencodeDictGetNext(
    CuTest * tc
)
{
    bencode_t ben, ben2;

    char *str = strdup("d3:foo3:bare");

    const char *ren;

    int len, ret;

    bencode_init(&ben, str, strlen(str));

    ret = bencode_dict_get_next(&ben, &ben2, &ren, &len);
    CuAssertTrue(tc, 1 == ret);
    CuAssertTrue(tc, !strncmp("foo", ren, len));
    bencode_string_value(&ben2, &ren, &len);
    CuAssertPtrNotNull(tc, ren);
    CuAssertTrue(tc, !strncmp("bar", ren, len));
    free(str);
}