static char* test_encode_and_decode_base64()
{
    load_histograms();

    uint8_t* buffer = NULL;
    uint8_t* decoded = NULL;
    char* encoded = NULL;
    size_t len = 0;
    int rc = 0;

    rc = hdr_encode_compressed(cor_histogram, &buffer, &len);
    mu_assert("Did not encode", validate_return_code(rc));

    size_t encoded_len = hdr_base64_encoded_len(len);
    size_t decoded_len = hdr_base64_decoded_len(encoded_len);
    encoded = calloc(encoded_len + 1, sizeof(char));
    decoded = calloc(decoded_len, sizeof(uint8_t));

    hdr_base64_encode(buffer, len, encoded, encoded_len);
    hdr_base64_decode(encoded, encoded_len, decoded, decoded_len);

    mu_assert("Should be same", memcmp(buffer, decoded, len) == 0);

    return 0;
}
int hdr_log_decode(struct hdr_histogram** histogram, char* base64_histogram, size_t base64_len)
{
    int r;
    uint8_t* compressed_histogram = NULL;
    int result = 0;

    size_t compressed_len = hdr_base64_decoded_len(base64_len);
    compressed_histogram = malloc(sizeof(uint8_t)*compressed_len);
    memset(compressed_histogram, 0, compressed_len);

    r = hdr_base64_decode(
            base64_histogram, base64_len, compressed_histogram, compressed_len);

    if (r != 0)
    {
        FAIL_AND_CLEANUP(cleanup, result, r);
    }

    r = hdr_decode_compressed(compressed_histogram, compressed_len, histogram);
    if (r != 0)
    {
        FAIL_AND_CLEANUP(cleanup, result, r);
    }

cleanup:
    free(compressed_histogram);

    return result;
}
int hdr_log_read(
    struct hdr_log_reader* reader, FILE* file, struct hdr_histogram** histogram,
    struct timespec* timestamp, struct timespec* interval)
{
    const char* format = "%d.%d,%d.%d,%d.%d,%s";
    char* base64_histogram = NULL;
    uint8_t* compressed_histogram = NULL;
    char* line = NULL;
    size_t line_len = 0;
    int result = 0;

    int begin_s = 0;
    int begin_ms = 0;
    int end_s = 0;
    int end_ms = 0;
    int interval_max_s = 0;
    int interval_max_ms = 0;

    (void)reader;

    ssize_t read = getline(&line, &line_len, file);
    if (-1 == read)
    {
        if (0 == errno)
        {
            FAIL_AND_CLEANUP(cleanup, result, EOF);
        }
        else
        {
            FAIL_AND_CLEANUP(cleanup, result, EIO);
        }
    }

    null_trailing_whitespace(line, read);
    if (strlen(line) == 0)
    {
        FAIL_AND_CLEANUP(cleanup, result, EOF);
    }

    int r;
    r = realloc_buffer((void**)&base64_histogram, sizeof(char), read);
    if (r != 0)
    {
        FAIL_AND_CLEANUP(cleanup, result, ENOMEM);
    }

    r = realloc_buffer((void**)&compressed_histogram, sizeof(uint8_t), read);
    if (r != 0)
    {
        FAIL_AND_CLEANUP(cleanup, result, ENOMEM);
    }

    int num_tokens = sscanf(
                         line, format, &begin_s, &begin_ms, &end_s, &end_ms,
                         &interval_max_s, &interval_max_ms, base64_histogram);

    if (num_tokens != 7)
    {
        FAIL_AND_CLEANUP(cleanup, result, EINVAL);
    }

    size_t base64_len = strlen(base64_histogram);
    size_t compressed_len = hdr_base64_decoded_len(base64_len);

    r = hdr_base64_decode(
            base64_histogram, base64_len, compressed_histogram, compressed_len);

    if (r != 0)
    {
        FAIL_AND_CLEANUP(cleanup, result, r);
    }

    r = hdr_decode_compressed(compressed_histogram, compressed_len, histogram);
    if (r != 0)
    {
        FAIL_AND_CLEANUP(cleanup, result, r);
    }

    update_timespec(timestamp, begin_s, begin_ms);
    update_timespec(interval, end_s, end_ms);

cleanup:
    free(line);
    free(base64_histogram);
    free(compressed_histogram);

    return result;
}