1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc.  See LICENSE. */
250aadb33SDmitri Tikhonov#include <assert.h>
350aadb33SDmitri Tikhonov#include <stdio.h>
450aadb33SDmitri Tikhonov#include <stdlib.h>
550aadb33SDmitri Tikhonov#include <string.h>
6461e84d8SAmol Deshpande#ifndef WIN32
750aadb33SDmitri Tikhonov#include <sys/time.h>
8461e84d8SAmol Deshpande#endif
950aadb33SDmitri Tikhonov
1050aadb33SDmitri Tikhonov#include "lsquic.h"
1150aadb33SDmitri Tikhonov#include "lsquic_types.h"
1250aadb33SDmitri Tikhonov#include "lsquic_parse.h"
1350aadb33SDmitri Tikhonov
1450aadb33SDmitri Tikhonov
15f07b3eaeSTyler Young//static const struct parse_funcs *const pf = select_pf_by_ver(LSQVER_043); // will not work on MSVC
16f07b3eaeSTyler Young#define pf ((const struct parse_funcs *const)select_pf_by_ver(LSQVER_043))
1750aadb33SDmitri Tikhonov
1850aadb33SDmitri Tikhonovstruct float_test {
1950aadb33SDmitri Tikhonov    uint64_t    long_time;
2050aadb33SDmitri Tikhonov    uint8_t     float_time[2];
2150aadb33SDmitri Tikhonov};
2250aadb33SDmitri Tikhonov
2350aadb33SDmitri Tikhonovstatic const struct float_test to_float_tests[] = {
2450aadb33SDmitri Tikhonov    /* Small numbers represent themselves. */
2550aadb33SDmitri Tikhonov    { 0, { 0x00, 0x00, }, },
2650aadb33SDmitri Tikhonov    { 1, { 0x00, 0x01, }, },
2750aadb33SDmitri Tikhonov    { 2, { 0x00, 0x02, }, },
2850aadb33SDmitri Tikhonov    { 3, { 0x00, 0x03, }, },
2950aadb33SDmitri Tikhonov    { 4, { 0x00, 0x04, }, },
3050aadb33SDmitri Tikhonov    { 5, { 0x00, 0x05, }, },
3150aadb33SDmitri Tikhonov    { 6, { 0x00, 0x06, }, },
3250aadb33SDmitri Tikhonov    { 7, { 0x00, 0x07, }, },
3350aadb33SDmitri Tikhonov    { 15, { 0x00, 0x0F, }, },
3450aadb33SDmitri Tikhonov    { 31, { 0x00, 0x1F, }, },
3550aadb33SDmitri Tikhonov    { 42, { 0x00, 0x2A, }, },
3650aadb33SDmitri Tikhonov    { 123, { 0x00, 0x7B, }, },
3750aadb33SDmitri Tikhonov    { 1234, { 0x04, 0xD2, }, },
3850aadb33SDmitri Tikhonov    /*  Check transition through 2^11. */
3950aadb33SDmitri Tikhonov    { 2046, { 0x07, 0xFE, }, },
4050aadb33SDmitri Tikhonov    { 2047, { 0x07, 0xFF, }, },
4150aadb33SDmitri Tikhonov    { 2048, { 0x08, 0x00, }, },
4250aadb33SDmitri Tikhonov    { 2049, { 0x08, 0x01, }, },
4350aadb33SDmitri Tikhonov    /*  Running out of mantissa at 2^12. */
4450aadb33SDmitri Tikhonov    { 4094, { 0x0F, 0xFE, }, },
4550aadb33SDmitri Tikhonov    { 4095, { 0x0F, 0xFF, }, },
4650aadb33SDmitri Tikhonov    { 4096, { 0x10, 0x00, }, },
4750aadb33SDmitri Tikhonov    { 4097, { 0x10, 0x00, }, },
4850aadb33SDmitri Tikhonov    { 4098, { 0x10, 0x01, }, },
4950aadb33SDmitri Tikhonov    { 4099, { 0x10, 0x01, }, },
5050aadb33SDmitri Tikhonov    { 4100, { 0x10, 0x02, }, },
5150aadb33SDmitri Tikhonov    { 4101, { 0x10, 0x02, }, },
5250aadb33SDmitri Tikhonov    /*  Check transition through 2^13. */
5350aadb33SDmitri Tikhonov    { 8190, { 0x17, 0xFF, }, },
5450aadb33SDmitri Tikhonov    { 8191, { 0x17, 0xFF, }, },
5550aadb33SDmitri Tikhonov    { 8192, { 0x18, 0x00, }, },
5650aadb33SDmitri Tikhonov    { 8193, { 0x18, 0x00, }, },
5750aadb33SDmitri Tikhonov    { 8194, { 0x18, 0x00, }, },
5850aadb33SDmitri Tikhonov    { 8195, { 0x18, 0x00, }, },
5950aadb33SDmitri Tikhonov    { 8196, { 0x18, 0x01, }, },
6050aadb33SDmitri Tikhonov    { 8197, { 0x18, 0x01, }, },
6150aadb33SDmitri Tikhonov    /*  Half-way through the exponents. */
6250aadb33SDmitri Tikhonov    { 0x7FF8000, { 0x87, 0xFF, }, },
6350aadb33SDmitri Tikhonov    { 0x7FFFFFF, { 0x87, 0xFF, }, },
6450aadb33SDmitri Tikhonov    { 0x8000000, { 0x88, 0x00, }, },
6550aadb33SDmitri Tikhonov    { 0xFFF0000, { 0x8F, 0xFF, }, },
6650aadb33SDmitri Tikhonov    { 0xFFFFFFF, { 0x8F, 0xFF, }, },
6750aadb33SDmitri Tikhonov    { 0x10000000, { 0x90, 0x00, }, },
6850aadb33SDmitri Tikhonov    /*  Transition into the largest exponent. */
6950aadb33SDmitri Tikhonov    { 0x1FFFFFFFFFE, { 0xF7, 0xFF, }, },
7050aadb33SDmitri Tikhonov    { 0x1FFFFFFFFFF, { 0xF7, 0xFF, }, },
7150aadb33SDmitri Tikhonov    { 0x20000000000, { 0xF8, 0x00, }, },
7250aadb33SDmitri Tikhonov    { 0x20000000001, { 0xF8, 0x00, }, },
7350aadb33SDmitri Tikhonov    { 0x2003FFFFFFE, { 0xF8, 0x00, }, },
7450aadb33SDmitri Tikhonov    { 0x2003FFFFFFF, { 0xF8, 0x00, }, },
7550aadb33SDmitri Tikhonov    { 0x20040000000, { 0xF8, 0x01, }, },
7650aadb33SDmitri Tikhonov    { 0x20040000001, { 0xF8, 0x01, }, },
7750aadb33SDmitri Tikhonov    /*  Transition into the max value and clamping. */
7850aadb33SDmitri Tikhonov    { 0x3FF80000000, { 0xFF, 0xFE, }, },
7950aadb33SDmitri Tikhonov    { 0x3FFBFFFFFFF, { 0xFF, 0xFE, }, },
8050aadb33SDmitri Tikhonov    { 0x3FFC0000000, { 0xFF, 0xFF, }, },
8150aadb33SDmitri Tikhonov    { 0x3FFC0000001, { 0xFF, 0xFF, }, },
8250aadb33SDmitri Tikhonov    { 0x3FFFFFFFFFF, { 0xFF, 0xFF, }, },
8350aadb33SDmitri Tikhonov    { 0x40000000000, { 0xFF, 0xFF, }, },
8450aadb33SDmitri Tikhonov    { 0xFFFFFFFFFFFFFFFF, { 0xFF, 0xFF, }, },
8550aadb33SDmitri Tikhonov};
8650aadb33SDmitri Tikhonov
8750aadb33SDmitri Tikhonov
8850aadb33SDmitri Tikhonovstatic void
8950aadb33SDmitri Tikhonovrun_to_float_tests (void)
9050aadb33SDmitri Tikhonov{
9150aadb33SDmitri Tikhonov    const struct float_test *test;
9250aadb33SDmitri Tikhonov    const struct float_test *const test_end =
9350aadb33SDmitri Tikhonov        &to_float_tests[ sizeof(to_float_tests) / sizeof(to_float_tests[0]) ];
9450aadb33SDmitri Tikhonov    for (test = to_float_tests; test < test_end; ++test)
9550aadb33SDmitri Tikhonov    {
9650aadb33SDmitri Tikhonov        char out[2];
9750aadb33SDmitri Tikhonov        pf->pf_write_float_time16(test->long_time, out);
9850aadb33SDmitri Tikhonov        assert(("Convertion to QUIC float format is successful",
9950aadb33SDmitri Tikhonov                                0 == memcmp(out, test->float_time, 2)));
10050aadb33SDmitri Tikhonov    }
10150aadb33SDmitri Tikhonov}
10250aadb33SDmitri Tikhonov
10350aadb33SDmitri Tikhonov
10450aadb33SDmitri Tikhonovstatic const struct float_test from_float_tests[] = {
10550aadb33SDmitri Tikhonov    /*  Small numbers represent themselves. */
10650aadb33SDmitri Tikhonov    { 0, { 0x00, 0x00, }, },
10750aadb33SDmitri Tikhonov    { 1, { 0x00, 0x01, }, },
10850aadb33SDmitri Tikhonov    { 2, { 0x00, 0x02, }, },
10950aadb33SDmitri Tikhonov    { 3, { 0x00, 0x03, }, },
11050aadb33SDmitri Tikhonov    { 4, { 0x00, 0x04, }, },
11150aadb33SDmitri Tikhonov    { 5, { 0x00, 0x05, }, },
11250aadb33SDmitri Tikhonov    { 6, { 0x00, 0x06, }, },
11350aadb33SDmitri Tikhonov    { 7, { 0x00, 0x07, }, },
11450aadb33SDmitri Tikhonov    { 15, { 0x00, 0x0F, }, },
11550aadb33SDmitri Tikhonov    { 31, { 0x00, 0x1F, }, },
11650aadb33SDmitri Tikhonov    { 42, { 0x00, 0x2A, }, },
11750aadb33SDmitri Tikhonov    { 123, { 0x00, 0x7B, }, },
11850aadb33SDmitri Tikhonov    { 1234, { 0x04, 0xD2, }, },
11950aadb33SDmitri Tikhonov    /*  Check transition through 2^11. */
12050aadb33SDmitri Tikhonov    { 2046, { 0x07, 0xFE, }, },
12150aadb33SDmitri Tikhonov    { 2047, { 0x07, 0xFF, }, },
12250aadb33SDmitri Tikhonov    { 2048, { 0x08, 0x00, }, },
12350aadb33SDmitri Tikhonov    { 2049, { 0x08, 0x01, }, },
12450aadb33SDmitri Tikhonov    /*  Running out of mantissa at 2^12. */
12550aadb33SDmitri Tikhonov    { 4094, { 0x0F, 0xFE, }, },
12650aadb33SDmitri Tikhonov    { 4095, { 0x0F, 0xFF, }, },
12750aadb33SDmitri Tikhonov    { 4096, { 0x10, 0x00, }, },
12850aadb33SDmitri Tikhonov    { 4098, { 0x10, 0x01, }, },
12950aadb33SDmitri Tikhonov    { 4100, { 0x10, 0x02, }, },
13050aadb33SDmitri Tikhonov    /*  Check transition through 2^13. */
13150aadb33SDmitri Tikhonov    { 8190, { 0x17, 0xFF, }, },
13250aadb33SDmitri Tikhonov    { 8192, { 0x18, 0x00, }, },
13350aadb33SDmitri Tikhonov    { 8196, { 0x18, 0x01, }, },
13450aadb33SDmitri Tikhonov    /*  Half-way through the exponents. */
13550aadb33SDmitri Tikhonov    { 0x7FF8000, { 0x87, 0xFF, }, },
13650aadb33SDmitri Tikhonov    { 0x8000000, { 0x88, 0x00, }, },
13750aadb33SDmitri Tikhonov    { 0xFFF0000, { 0x8F, 0xFF, }, },
13850aadb33SDmitri Tikhonov    { 0x10000000, { 0x90, 0x00, }, },
13950aadb33SDmitri Tikhonov    /*  Transition into the largest exponent. */
14050aadb33SDmitri Tikhonov    { 0x1FFE0000000, { 0xF7, 0xFF, }, },
14150aadb33SDmitri Tikhonov    { 0x20000000000, { 0xF8, 0x00, }, },
14250aadb33SDmitri Tikhonov    { 0x20040000000, { 0xF8, 0x01, }, },
14350aadb33SDmitri Tikhonov    /*  Transition into the max value. */
14450aadb33SDmitri Tikhonov    { 0x3FF80000000, { 0xFF, 0xFE, }, },
14550aadb33SDmitri Tikhonov    { 0x3FFC0000000, { 0xFF, 0xFF, }, },
14650aadb33SDmitri Tikhonov};
14750aadb33SDmitri Tikhonov
14850aadb33SDmitri Tikhonov
14950aadb33SDmitri Tikhonovstatic void
15050aadb33SDmitri Tikhonovrun_from_float_tests (void)
15150aadb33SDmitri Tikhonov{
15250aadb33SDmitri Tikhonov    const struct float_test *test;
15350aadb33SDmitri Tikhonov    const struct float_test *const test_end =
15450aadb33SDmitri Tikhonov        &from_float_tests[ sizeof(from_float_tests) / sizeof(from_float_tests[0]) ];
15550aadb33SDmitri Tikhonov    for (test = from_float_tests; test < test_end; ++test)
15650aadb33SDmitri Tikhonov    {
15750aadb33SDmitri Tikhonov        uint64_t result = pf->pf_read_float_time16(test->float_time);
15850aadb33SDmitri Tikhonov        assert(("Convertion to QUIC float format is successful",
15950aadb33SDmitri Tikhonov                                                result == test->long_time));
16050aadb33SDmitri Tikhonov    }
16150aadb33SDmitri Tikhonov}
16250aadb33SDmitri Tikhonov
16350aadb33SDmitri Tikhonov
16450aadb33SDmitri Tikhonovint
16550aadb33SDmitri Tikhonovmain (void)
16650aadb33SDmitri Tikhonov{
16750aadb33SDmitri Tikhonov    run_to_float_tests();
16850aadb33SDmitri Tikhonov    run_from_float_tests();
16950aadb33SDmitri Tikhonov    return 0;
17050aadb33SDmitri Tikhonov}
171