libmicrohttpd2

HTTP server C library (MHD 2.x, alpha)
Log | Files | Refs | README | LICENSE

unit_hpack_tables.c (102531B)


      1 /* SPDX-License-Identifier: LGPL-2.1-or-later OR (GPL-2.0-or-later WITH eCos-exception-2.0) */
      2 /*
      3   This file is part of GNU libmicrohttpd.
      4   Copyright (C) 2025 Evgeny Grin (Karlson2k)
      5 
      6   GNU libmicrohttpd is free software; you can redistribute it and/or
      7   modify it under the terms of the GNU Lesser General Public
      8   License as published by the Free Software Foundation; either
      9   version 2.1 of the License, or (at your option) any later version.
     10 
     11   GNU libmicrohttpd is distributed in the hope that it will be useful,
     12   but WITHOUT ANY WARRANTY; without even the implied warranty of
     13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14   Lesser General Public License for more details.
     15 
     16   Alternatively, you can redistribute GNU libmicrohttpd and/or
     17   modify it under the terms of the GNU General Public License as
     18   published by the Free Software Foundation; either version 2 of
     19   the License, or (at your option) any later version, together
     20   with the eCos exception, as follows:
     21 
     22     As a special exception, if other files instantiate templates or
     23     use macros or inline functions from this file, or you compile this
     24     file and link it with other works to produce a work based on this
     25     file, this file does not by itself cause the resulting work to be
     26     covered by the GNU General Public License. However the source code
     27     for this file must still be made available in accordance with
     28     section (3) of the GNU General Public License v2.
     29 
     30     This exception does not invalidate any other reasons why a work
     31     based on this file might be covered by the GNU General Public
     32     License.
     33 
     34   You should have received copies of the GNU Lesser General Public
     35   License and the GNU General Public License along with this library;
     36   if not, see <https://www.gnu.org/licenses/>.
     37 */
     38 
     39 /**
     40  * @file src/test/unit/unit_hpack_tables.c
     41  * @brief  The tests for HPACK tables functions
     42  * @author Karlson2k (Evgeny Grin)
     43  */
     44 
     45 
     46 #include "mhd_sys_options.h"
     47 
     48 #define mhd_HPACK_TESTING_TABLES_ONLY      1
     49 /* Include .c file (!) to access static functions.
     50    Only official interface mhd_* is used to handle the tables. */
     51 #include "h2/hpack/mhd_hpack_codec.c"
     52 
     53 #include "mhdt_has_in_name.h"
     54 #include "mhdt_has_param.h"
     55 #include "mhdt_checks.h"
     56 
     57 #ifndef MHD_ENABLE_SLOW_TESTS
     58 static int mhdtl_enable_deep_tests = 0;
     59 #else
     60 static int mhdtl_enable_deep_tests = ! 0;
     61 #endif
     62 
     63 #define MHDTL_DYN_ENTRY_MIN_SIZE        mhd_HPACK_ENTRY_OVERHEAD
     64 
     65 /*
     66  * Local test helpers
     67  */
     68 
     69 #define MHDTL_HPACK_ENTRY_SIZE(name_len,val_len) \
     70         (name_len + val_len + mhd_HPACK_ENTRY_OVERHEAD)
     71 
     72 
     73 static inline uint_least16_t
     74 mhdtl_rotl16 (uint_least16_t val, unsigned int rot)
     75 {
     76   return
     77     (uint_least16_t)
     78     (((val & 0xFFFFu) << (rot % 16u))
     79      | ((val & 0xFFFFu) >> ((16u - (rot % 16u)) % 16u)));
     80 }
     81 
     82 
     83 static inline uint_least16_t
     84 mhdtl_mix16 (uint_fast16_t a, uint_fast16_t b)
     85 {
     86   /* Mix with Golden Ratio's fractional part */
     87   uint_least16_t res =
     88     (uint_least16_t) (((a & 0xFFFFu) * 0x9E37u)
     89                       ^ mhdtl_rotl16 ((uint_least16_t) b, 5));
     90   /* Re-mix bits better */
     91   res ^= (uint_least16_t) (res >> 7);
     92   res = (uint_least16_t) ((res * 0x9E37u) & 0xFFFFu);
     93   res ^= (uint_least16_t) (res >> 9);
     94 
     95   return res;
     96 }
     97 
     98 
     99 static size_t
    100 mhdtl_dyn_get_size_used (const struct mhd_HpackDTblContext *dyn)
    101 {
    102   const size_t used = mhd_dtbl_get_table_used (dyn);
    103   MHDT_EXPECT_UINT_GE_VAL (mhd_dtbl_get_table_max_size (dyn), \
    104                            used);
    105   return used;
    106 }
    107 
    108 
    109 static size_t
    110 mhdtl_dyn_get_free (const struct mhd_HpackDTblContext *dyn)
    111 {
    112   const size_t used = mhd_dtbl_get_table_used (dyn);
    113   const size_t max_size = mhd_dtbl_get_table_max_size (dyn);
    114   MHDT_EXPECT_UINT_GE_VAL (max_size, used);
    115   return max_size - used;
    116 }
    117 
    118 
    119 #define MHDTL_DTBL_FIND_ENTRY_STR(dyn,name,val) \
    120         mhd_dtbl_find_entry (dyn, strlen (name), name, strlen (val), val)
    121 
    122 #define MHDTL_DTBL_FIND_NAME_STR(dyn,name) \
    123         mhd_dtbl_find_name (dyn, strlen (name), name)
    124 
    125 
    126 /* Return non-zero if succeeded, zero if failed */
    127 static int
    128 mhdtl_dyn_check_get_valid_invalid (const struct mhd_HpackDTblContext *dyn)
    129 {
    130   const dtbl_idx_ft num_entries = (dtbl_idx_t) mhd_dtbl_get_num_entries (dyn);
    131   struct mhd_BufferConst check_name;
    132   struct mhd_BufferConst check_value;
    133 
    134   if (! MHDT_EXPECT_FALSE_D (mhd_dtbl_get_entry (dyn, \
    135                                                  mhd_HPACK_STBL_LAST_IDX + 1u \
    136                                                  + num_entries, \
    137                                                  &check_name, \
    138                                                  &check_value), \
    139                              "getting entry with the index outside valid "
    140                              "range should fail"))
    141     return 0;
    142 
    143   if (0u == num_entries)
    144     return ! 0;
    145 
    146   if (! MHDT_EXPECT_TRUE_D (mhd_dtbl_get_entry (dyn, \
    147                                                 mhd_HPACK_STBL_LAST_IDX + 1u, \
    148                                                 &check_name, \
    149                                                 &check_value), \
    150                             "non-empty table should return successfully " \
    151                             "the first valid entry"))
    152     return 0;
    153   if (! MHDT_EXPECT_TRUE_D (mhd_dtbl_get_entry (dyn, \
    154                                                 mhd_HPACK_STBL_LAST_IDX \
    155                                                 + num_entries, \
    156                                                 &check_name, \
    157                                                 &check_value), \
    158                             "non-empty table should return successfully " \
    159                             "the last valid entry"))
    160     return 0;
    161 
    162   return ! 0;
    163 }
    164 
    165 
    166 /* Return non-zero if succeeded, zero if failed */
    167 static int
    168 mhdtl_dyn_check_entry_n_at_idx (struct mhd_HpackDTblContext *dyn,
    169                                 size_t idx,
    170                                 size_t expect_name_len,
    171                                 const char *expect_name,
    172                                 size_t expect_value_len,
    173                                 const char *expect_value)
    174 {
    175   struct mhd_BufferConst check_name;
    176   struct mhd_BufferConst check_value;
    177 
    178   dtbl_idx_t idx_idx = (dtbl_idx_t) idx;
    179   if (0 == idx)
    180     MHDT_ERR_EXIT ();
    181   if (idx_idx != idx)
    182     MHDT_ERR_EXIT ();
    183 
    184   if (MHDT_EXPECT_TRUE_D (mhd_dtbl_get_entry (dyn,        \
    185                                               idx_idx,     \
    186                                               &check_name,  \
    187                                               &check_value), \
    188                           "the entry with specified index should exist"))
    189   {
    190     MHDT_EXPECT_STRN_EQ_STR_D (check_name.size, \
    191                                check_name.data, \
    192                                expect_name,     \
    193                                "the name of the entry should match " \
    194                                "expected value");
    195     MHDT_EXPECT_STRN_EQ_STR_D (check_value.size, \
    196                                check_value.data, \
    197                                expect_value,     \
    198                                "the name of the entry should match " \
    199                                "expected value");
    200   }
    201   else
    202     return 0;
    203 
    204   /* It should be possible to find the entry. The index could be different
    205      if entries are duplicated. */
    206 
    207   MHDT_EXPECT_UINT_GT_VAL_D (mhd_dtbl_find_entry (dyn, \
    208                                                   expect_name_len, \
    209                                                   expect_name, \
    210                                                   expect_value_len, \
    211                                                   expect_value), \
    212                              mhd_HPACK_STBL_LAST_IDX, \
    213                              "search by known entry name and value " \
    214                              "should succeed");
    215   MHDT_EXPECT_UINT_GT_VAL_D (mhd_dtbl_find_name (dyn, \
    216                                                  expect_name_len, \
    217                                                  expect_name), \
    218                              mhd_HPACK_STBL_LAST_IDX, \
    219                              "search by known entry name " \
    220                              "should succeed");
    221 
    222   return ! 0;
    223 }
    224 
    225 
    226 /* Return non-zero if succeeded, zero if failed */
    227 static int
    228 mhdtl_dyn_check_entry_at_idx (struct mhd_HpackDTblContext *dyn,
    229                               size_t idx,
    230                               const char *expect_name,
    231                               const char *expect_value)
    232 {
    233   return mhdtl_dyn_check_entry_n_at_idx (dyn,
    234                                          idx,
    235                                          strlen (expect_name),
    236                                          expect_name,
    237                                          strlen (expect_value),
    238                                          expect_value);
    239 }
    240 
    241 
    242 /* Return non-zero if succeeded, zero if failed */
    243 static MHD_FN_PAR_IN_SIZE_ (3,2) MHD_FN_PAR_IN_SIZE_ (5,4) int
    244 mhdtl_dyn_add_hdr_n_with_check (struct mhd_HpackDTblContext *dyn,
    245                                 size_t hdr_name_len,
    246                                 const char *hdr_name,
    247                                 size_t hdr_value_len,
    248                                 const char *hdr_value)
    249 {
    250   char prev_name_buf[512];
    251   size_t prev_name_len = 0u;
    252   char prev_val_buf[512];
    253   size_t prev_val_len = 0u;
    254   int have_prev_entry = 0;
    255   char last_name_buf[512];
    256   size_t last_name_len = 0u;
    257   char last_val_buf[512];
    258   size_t last_val_len = 0u;
    259   int have_last_entry = 0;
    260   const size_t hdr_size = MHDTL_HPACK_ENTRY_SIZE (hdr_name_len, hdr_value_len);
    261   const size_t table_max_size = mhd_dtbl_get_table_max_size (dyn);
    262   const size_t table_free_before = mhdtl_dyn_get_free (dyn);
    263   const dtbl_idx_ft num_entries_before = (dtbl_idx_t)
    264                                          mhd_dtbl_get_num_entries (dyn);
    265   struct mhd_BufferConst check_name = {0u, NULL};
    266   struct mhd_BufferConst check_value = {0u, NULL};
    267 
    268   if ((mhd_DTBL_MAX_SIZE < hdr_name_len) ||
    269       (mhd_DTBL_MAX_SIZE < hdr_value_len) ||
    270       (mhd_DTBL_MAX_SIZE < hdr_size))
    271     MHDT_ERR_EXIT ();
    272 
    273   MHDT_EXPECT_UINT_GE_VAL (table_max_size, table_free_before);
    274   MHDT_EXPECT_UINT_GE_VAL_D (mhdtl_dyn_get_size_used (dyn), \
    275                              num_entries_before * MHDTL_DYN_ENTRY_MIN_SIZE, \
    276                              "Each entry should have at least a minimal size");
    277 
    278   if (mhd_dtbl_get_entry (dyn,
    279                           mhd_HPACK_STBL_LAST_IDX + 1u,
    280                           &check_name, &check_value))
    281   { /* Check whether the current newest entry and the new entry will fit
    282        the table together */
    283     if (hdr_size + MHDTL_HPACK_ENTRY_SIZE (check_name.size, check_value.size)
    284         <= mhd_dtbl_get_table_max_size (dyn))
    285     {
    286       if ((sizeof(prev_name_buf) > check_name.size)
    287           && (sizeof(prev_val_buf) > check_value.size))
    288       {
    289         /* Save the first entry to check later that it is not changed after
    290            adding the new entry */
    291         memcpy (prev_name_buf,
    292                 check_name.data,
    293                 check_name.size);
    294         prev_name_buf[check_name.size] = 0; /* Zero-terminate for convenience */
    295         prev_name_len = check_name.size;
    296         memcpy (prev_val_buf,
    297                 check_value.data,
    298                 check_value.size);
    299         prev_val_buf[check_value.size] = 0; /* Zero-terminate for convenience */
    300         prev_val_len = check_value.size;
    301         have_prev_entry = ! 0;
    302       }
    303     }
    304   }
    305   if ((1u < mhd_dtbl_get_num_entries (dyn))
    306       && (hdr_size <= table_free_before))
    307   {
    308     if (MHDT_EXPECT_TRUE (mhd_dtbl_get_entry (dyn,
    309                                               mhd_HPACK_STBL_LAST_IDX
    310                                               + num_entries_before,
    311                                               &check_name, &check_value)))
    312     {
    313       if ((sizeof(last_name_buf) > check_name.size)
    314           && (sizeof(last_val_buf) > check_value.size))
    315       {
    316         /* Save the last entry to check later that it is not changed after
    317            adding the new entry */
    318         memcpy (last_name_buf,
    319                 check_name.data,
    320                 check_name.size);
    321         last_name_buf[check_name.size] = 0; /* Zero-terminate for convenience */
    322         last_name_len = check_name.size;
    323         memcpy (last_val_buf,
    324                 check_value.data,
    325                 check_value.size);
    326         last_val_buf[check_value.size] = 0; /* Zero-terminate for convenience */
    327         last_val_len = check_value.size;
    328         have_last_entry = ! 0;
    329       }
    330     }
    331   }
    332 
    333   mhd_dtbl_new_entry (dyn,
    334                       hdr_name_len,
    335                       hdr_name,
    336                       hdr_value_len,
    337                       hdr_value);
    338 
    339   if (hdr_size <= table_free_before)
    340   {
    341     /* No eviction */
    342     MHDT_EXPECT_UINT_EQ_VAL_D (mhd_dtbl_get_num_entries (dyn), \
    343                                num_entries_before + 1u, \
    344                                "added one entry without eviction");
    345     MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_free (dyn), \
    346                              table_free_before - hdr_size);
    347     if (have_last_entry)
    348       mhdtl_dyn_check_entry_n_at_idx (dyn,
    349                                       mhd_HPACK_STBL_LAST_IDX
    350                                       + num_entries_before + 1u,
    351                                       last_name_len,
    352                                       last_name_buf,
    353                                       last_val_len,
    354                                       last_val_buf);
    355   }
    356   else
    357   {
    358     /* Eviction */
    359     MHDT_EXPECT_UINT_LE_VAL_D (mhd_dtbl_get_num_entries (dyn), \
    360                                num_entries_before,
    361                                "some entries evicted when adding new entry");
    362     if (hdr_size > table_max_size)
    363     {
    364       /* Full eviction */
    365       MHDT_EXPECT_UINT_EQ_VAL_D (mhd_dtbl_get_num_entries (dyn), 0u, \
    366                                  "all entries evicted by adding too large " \
    367                                  "new entry");
    368       MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_free (dyn), table_max_size);
    369       MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), \
    370                                table_max_size);
    371       return ! 0;
    372     }
    373     else if (hdr_size + MHDTL_DYN_ENTRY_MIN_SIZE > table_max_size)
    374       MHDT_EXPECT_UINT_EQ_VAL_D (mhd_dtbl_get_num_entries (dyn), 1u, \
    375                                  "exactly one new entry fits the table");
    376     else
    377       MHDT_EXPECT_UINT_GE_VAL_D (mhd_dtbl_get_num_entries (dyn), 1u,
    378                                  "some entries evicted and one entry added");
    379 
    380   }
    381 
    382   /* The new entry has been added to the table */
    383 
    384   if (1u == mhd_dtbl_get_num_entries (dyn))
    385     MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), hdr_size);
    386   else
    387     MHDT_EXPECT_UINT_GE_VAL (mhdtl_dyn_get_size_used (dyn), \
    388                              hdr_size + MHDTL_DYN_ENTRY_MIN_SIZE);
    389 
    390   if (! MHDT_EXPECT_TRUE_D (mhd_dtbl_get_entry (dyn, \
    391                                                 mhd_HPACK_STBL_LAST_IDX + 1u, \
    392                                                 &check_name, \
    393                                                 &check_value), \
    394                             "new entry should be available as the newest " \
    395                             "entry in the dynamic table"))
    396     return 0;
    397 
    398   if (! MHDT_EXPECT_STRN_EQ_D (check_name.size, \
    399                                check_name.data, \
    400                                hdr_name_len, \
    401                                hdr_name, \
    402                                "The name of the newest entry should " \
    403                                "match the last added entry's name"))
    404     return 0;
    405   if (! MHDT_EXPECT_STRN_EQ_D (check_value.size, \
    406                                check_value.data, \
    407                                hdr_value_len, \
    408                                hdr_value, \
    409                                "The value of the newest entry should " \
    410                                "match the last added entry's value"))
    411     return 0;
    412 
    413   if (! MHDT_EXPECT_UINT_GT_VAL_D (mhd_dtbl_find_entry (dyn, \
    414                                                         hdr_name_len, \
    415                                                         hdr_name, \
    416                                                         hdr_value_len, \
    417                                                         hdr_value), \
    418                                    mhd_HPACK_STBL_LAST_IDX, \
    419                                    "search for the newly added entry should " \
    420                                    "be successful"))
    421     return 0;
    422   if (! MHDT_EXPECT_UINT_GT_VAL_D (mhd_dtbl_find_name (dyn, \
    423                                                        hdr_name_len, \
    424                                                        hdr_name), \
    425                                    mhd_HPACK_STBL_LAST_IDX, \
    426                                    "search for the newly added entry name "
    427                                    "should be successful"))
    428     return 0;
    429 
    430   if (have_prev_entry)
    431   {
    432     if (MHDT_EXPECT_TRUE_D (mhd_dtbl_get_entry (dyn, \
    433                                                 mhd_HPACK_STBL_LAST_IDX + 2u, \
    434                                                 &check_name, &check_value), \
    435                             "previous entry must remain the same"))
    436     {
    437       MHDT_EXPECT_STRN_EQ_D (check_name.size, check_name.data, \
    438                              prev_name_len, prev_name_buf, \
    439                              "previous entry must be unchanged");
    440       MHDT_EXPECT_STRN_EQ_D (check_value.size, check_value.data, \
    441                              prev_val_len, prev_val_buf, \
    442                              "previous entry must be unchanged");
    443     }
    444   }
    445 
    446 
    447   mhdtl_dyn_check_get_valid_invalid (dyn);
    448 
    449   return ! 0;
    450 }
    451 
    452 
    453 /* Return non-zero if succeeded, zero if failed */
    454 static MHD_FN_PAR_CSTR_ (2) MHD_FN_PAR_CSTR_ (3) int
    455 mhdtl_dyn_add_hdr_with_check (struct mhd_HpackDTblContext *dyn,
    456                               const char *hdr_name,
    457                               const char *hdr_value)
    458 {
    459   const size_t hdr_name_len = strlen (hdr_name);
    460   const size_t hdr_value_len = strlen (hdr_value);
    461 
    462   return mhdtl_dyn_add_hdr_n_with_check (dyn,
    463                                          hdr_name_len,
    464                                          hdr_name,
    465                                          hdr_value_len,
    466                                          hdr_value);
    467 }
    468 
    469 
    470 /* Return non-zero if succeeded, zero if failed */
    471 static int
    472 mhdtl_dyn_add_sized_strs_with_check (struct mhd_HpackDTblContext *dyn,
    473                                      size_t hdr_strings_size)
    474 {
    475 #define MHDTL_NAMES_BUF_SIZE 512
    476   static char names[MHDTL_NAMES_BUF_SIZE] = "";
    477   static char values[MHDTL_NAMES_BUF_SIZE] = "";
    478 #undef MHDTL_NAMES_BUF_SIZE
    479   /* Use '- 1u' to have valid addresses for zero-sized names and values */
    480   static const size_t bufs_size = sizeof(names) - 1u;
    481   static size_t names_off = 0u;
    482   static size_t values_off = 0u;
    483   size_t name_size;
    484   size_t value_size;
    485   char *hdr_name;
    486   char *hdr_value;
    487 
    488   if ((bufs_size + bufs_size) < hdr_strings_size)
    489     MHDT_ERR_EXIT_D ("the entry must not be larger than a hardcoded limit");
    490 
    491   if (0 == values[0])
    492   {
    493     size_t i;
    494     for (i = 0; i < sizeof(names); ++i)
    495     {
    496       names[i] = (char) ('a' + (char) (i % ('z' - 'a' + 1)));
    497       values[i] = (char) (' ' + (char) ((bufs_size - i) % ('~' - ' ' + 1)));
    498     }
    499   }
    500 
    501   value_size = hdr_strings_size / 2;
    502   name_size = hdr_strings_size - value_size;
    503 
    504   hdr_name =
    505     names + (names_off++) % (bufs_size - name_size + 1u);
    506   hdr_value =
    507     values + (bufs_size - value_size)
    508     - ((values_off++) % (bufs_size - value_size + 1u));
    509 
    510   return mhdtl_dyn_add_hdr_n_with_check (dyn,
    511                                          name_size,
    512                                          hdr_name,
    513                                          value_size,
    514                                          hdr_value);
    515 }
    516 
    517 
    518 /* Return non-zero if succeeded, zero if failed */
    519 static int
    520 mhdtl_dyn_add_sized_entry_with_check (struct mhd_HpackDTblContext *dyn,
    521                                       size_t entry_size)
    522 {
    523   if (MHDTL_DYN_ENTRY_MIN_SIZE > entry_size)
    524     MHDT_ERR_EXIT_D ("the entry must be at least a minimal entry size");
    525 
    526   return mhdtl_dyn_add_sized_strs_with_check (dyn,
    527                                               entry_size
    528                                               - mhd_HPACK_ENTRY_OVERHEAD);
    529 }
    530 
    531 
    532 static void
    533 mhdtl_stat_check_entry_n_at_idx (size_t idx,
    534                                  size_t expect_name_len,
    535                                  const char *expect_name,
    536                                  size_t expect_value_len,
    537                                  const char *expect_value)
    538 {
    539   struct mhd_BufferConst check_name;
    540   struct mhd_BufferConst check_value;
    541 
    542   dtbl_idx_t idx_idx = (dtbl_idx_t) idx;
    543   if (0 == idx)
    544     MHDT_ERR_EXIT ();
    545   if (idx_idx != idx)
    546     MHDT_ERR_EXIT ();
    547   if (0u == idx)
    548     MHDT_ERR_EXIT ();
    549   if (mhd_HPACK_STBL_LAST_IDX < idx)
    550     MHDT_ERR_EXIT ();
    551   if (0u == expect_name_len)
    552     MHDT_ERR_EXIT ();
    553   if ((':' == expect_name[0]) != (idx < (mhd_HPACK_STBL_NORM_START_POS + 1u)))
    554     MHDT_ERR_EXIT ();
    555 
    556   mhd_stbl_get_entry (idx_idx,
    557                       &check_name,
    558                       &check_value);
    559 
    560   MHDT_EXPECT_STRN_EQ_STR_D (check_name.size, \
    561                              check_name.data, \
    562                              expect_name, \
    563                              "the name of the entry should match " \
    564                              "expected value");
    565   MHDT_EXPECT_STRN_EQ_STR_D (check_value.size, \
    566                              check_value.data, \
    567                              expect_value, \
    568                              "the name of the entry should match " \
    569                              "expected value");
    570 
    571   /* It should be possible to find the entry. The index could be different
    572      if entries are duplicated. */
    573 
    574   if (':' != expect_name[0])
    575   {
    576     MHDT_EXPECT_UINT_NE_VAL_D (mhd_stbl_find_entry_real (expect_name_len, \
    577                                                          expect_name, \
    578                                                          expect_value_len,
    579                                                          expect_value), \
    580                                0u, \
    581                                "search by known entry name and value " \
    582                                "should not fail");
    583     MHDT_EXPECT_UINT_EQ_VAL_D (mhd_stbl_find_entry_real (expect_name_len, \
    584                                                          expect_name, \
    585                                                          expect_value_len,
    586                                                          expect_value), \
    587                                idx, \
    588                                "search by known entry name and value " \
    589                                "should return the " \
    590                                "known entry index");
    591 
    592     MHDT_EXPECT_UINT_NE_VAL_D (mhd_stbl_find_name_real (expect_name_len, \
    593                                                         expect_name), \
    594                                0u, \
    595                                "search by known entry name " \
    596                                "should not fail");
    597     MHDT_EXPECT_UINT_LE_VAL_D (mhd_stbl_find_name_real (expect_name_len, \
    598                                                         expect_name), \
    599                                idx, \
    600                                "search by known entry name " \
    601                                "should return value not greater than the " \
    602                                "known entry index");
    603   }
    604   else
    605   {
    606     MHDT_EXPECT_UINT_EQ_VAL_D (mhd_stbl_find_entry_real (expect_name_len, \
    607                                                          expect_name, \
    608                                                          expect_value_len,
    609                                                          expect_value), \
    610                                0u, \
    611                                "search by pseudo-header entry name " \
    612                                "and value should fail");
    613 
    614     MHDT_EXPECT_UINT_EQ_VAL_D (mhd_stbl_find_name_real (expect_name_len, \
    615                                                         expect_name), \
    616                                0u, \
    617                                "search by pseudo-header entry name " \
    618                                "should fail");
    619   }
    620 }
    621 
    622 
    623 static void
    624 mhdtl_stat_check_entry_at_idx (size_t idx,
    625                                const char *expect_name,
    626                                const char *expect_value)
    627 {
    628   mhdtl_stat_check_entry_n_at_idx (idx,
    629                                    strlen (expect_name),
    630                                    expect_name,
    631                                    strlen (expect_value),
    632                                    expect_value);
    633 }
    634 
    635 
    636 #define MHDTL_STBL_FIND_ENTRY_REAL_STR(name,value) \
    637         mhd_stbl_find_entry_real (strlen (name),(name), \
    638                                   strlen (value),(value))
    639 #define MHDTL_STBL_FIND_NAME_REAL_STR(name) \
    640         mhd_stbl_find_name_real (strlen (name),(name))
    641 
    642 
    643 /* Return non-zero if succeeded, zero if failed */
    644 static int
    645 mhdtl_comb_check_entry_n_at_idx (struct mhd_HpackDTblContext *dyn,
    646                                  size_t idx,
    647                                  size_t expect_name_len,
    648                                  const char *expect_name,
    649                                  size_t expect_value_len,
    650                                  const char *expect_value)
    651 {
    652   struct mhd_BufferConst check_name;
    653   struct mhd_BufferConst check_value;
    654 
    655   dtbl_idx_t idx_idx = (dtbl_idx_t) idx;
    656   dtbl_idx_t found_by_name_and_value;
    657   dtbl_idx_t found_by_name_only;
    658   if (0 == idx)
    659     MHDT_ERR_EXIT ();
    660   if (idx_idx != idx)
    661     MHDT_ERR_EXIT ();
    662   if ((':' == expect_name[0]) != (idx < (mhd_HPACK_STBL_NORM_START_POS + 1u)))
    663     MHDT_ERR_EXIT_D ("pseudo-header entries are allowed only at first " \
    664                      "static table positions");
    665 
    666   if (MHDT_EXPECT_TRUE_D (mhd_htbl_get_entry (dyn,        \
    667                                               idx_idx,     \
    668                                               &check_name,  \
    669                                               &check_value), \
    670                           "the entry with specified index should exist"))
    671   {
    672     MHDT_EXPECT_STRN_EQ_STR_D (check_name.size, \
    673                                check_name.data, \
    674                                expect_name,     \
    675                                "the name of the entry should match " \
    676                                "expected value");
    677     MHDT_EXPECT_STRN_EQ_STR_D (check_value.size, \
    678                                check_value.data, \
    679                                expect_value,     \
    680                                "the name of the entry should match " \
    681                                "expected value");
    682   }
    683   else
    684     return 0;
    685 
    686   /* It should be possible to find the entry. */
    687   found_by_name_and_value =
    688     mhd_htbl_find_entry_real (dyn,
    689                               expect_name_len,
    690                               expect_name,
    691                               expect_value_len,
    692                               expect_value);
    693   found_by_name_only =
    694     mhd_htbl_find_name_real (dyn,
    695                              expect_name_len,
    696                              expect_name);
    697 
    698   if ((0u == expect_name_len) ||
    699       (':' != expect_name[0]))
    700   {
    701     MHDT_EXPECT_UINT_NE_VAL_D (found_by_name_and_value, \
    702                                0u, \
    703                                "search by known entry name and value " \
    704                                "should not fail");
    705     MHDT_EXPECT_UINT_LE_VAL_D (found_by_name_and_value, \
    706                                mhd_HPACK_STBL_LAST_IDX \
    707                                + mhd_dtbl_get_num_entries (dyn), \
    708                                "search by known entry name and value " \
    709                                "should return a valid index number");
    710     if (mhd_HPACK_STBL_LAST_IDX >= idx)
    711       MHDT_EXPECT_UINT_EQ_VAL_D (found_by_name_and_value, \
    712                                  idx, \
    713                                  "search by known entry name and value " \
    714                                  "should return the " \
    715                                  "known entry index");
    716 
    717 
    718     MHDT_EXPECT_UINT_NE_VAL_D (found_by_name_only, \
    719                                0u, \
    720                                "search by known entry name " \
    721                                "should not fail");
    722     MHDT_EXPECT_UINT_LE_VAL_D (found_by_name_only, \
    723                                mhd_HPACK_STBL_LAST_IDX \
    724                                + mhd_dtbl_get_num_entries (dyn), \
    725                                "search by known entry name " \
    726                                "should return a valid index number");
    727     /* The next check is not required by RFC, but guaranteed by implementation
    728        design. */
    729     if (mhd_HPACK_STBL_LAST_IDX >= idx)
    730       MHDT_EXPECT_UINT_LE_VAL_D (found_by_name_and_value, \
    731                                  mhd_HPACK_STBL_LAST_IDX, \
    732                                  "search by known static entry name " \
    733                                  "should return the " \
    734                                  "static table index");
    735   }
    736   else
    737   {
    738     MHDT_EXPECT_UINT_EQ_VAL_D (found_by_name_and_value, \
    739                                0u, \
    740                                "search by pseudo-header entry name " \
    741                                "and value should fail");
    742 
    743     MHDT_EXPECT_UINT_EQ_VAL_D (found_by_name_only, \
    744                                0u, \
    745                                "search by pseudo-header entry name " \
    746                                "should fail");
    747   }
    748 
    749   return ! 0;
    750 }
    751 
    752 
    753 /* Return non-zero if succeeded, zero if failed */
    754 static int
    755 mhdtl_comb_check_entry_at_idx (struct mhd_HpackDTblContext *dyn,
    756                                size_t idx,
    757                                const char *expect_name,
    758                                const char *expect_value)
    759 {
    760   return mhdtl_comb_check_entry_n_at_idx (dyn,
    761                                           idx,
    762                                           strlen (expect_name),
    763                                           expect_name,
    764                                           strlen (expect_value),
    765                                           expect_value);
    766 }
    767 
    768 
    769 #define MHDTL_HTBL_FIND_ENTRY_REAL_STR(dyn,name,value) \
    770         mhd_htbl_find_entry_real (dyn,strlen (name),(name), \
    771                                   strlen (value),(value))
    772 #define MHDTL_HTBL_FIND_NAME_REAL_STR(dyn,name) \
    773         mhd_htbl_find_name_real (dyn,strlen (name),(name))
    774 
    775 
    776 /*
    777  * The dynamic table tests
    778  */
    779 
    780 static int
    781 test_dyn_create_destroy (void)
    782 {
    783   struct mhd_HpackDTblContext*dyn;
    784 
    785   MHDT_EXPECT_PTR_NONNULL_D (dyn = \
    786                                mhd_dtbl_create (mhd_hpack_def_dyn_table_size), \
    787                              "Create HPACK dynamic table");
    788   if (NULL == dyn)
    789     return MHDT_TEST_RESULT ();
    790 
    791   MHDT_EXPECT_UINT_EQ_VAL_D (mhd_dtbl_get_num_entries (dyn), 0u, \
    792                              "an empty table must have no entries");
    793   mhdtl_dyn_check_get_valid_invalid (dyn);
    794 
    795   mhd_dtbl_destroy (dyn);
    796 
    797   return MHDT_TEST_RESULT ();
    798 }
    799 
    800 
    801 static int
    802 test_dyn_create_destroy_larger (void)
    803 {
    804   struct mhd_HpackDTblContext*dyn;
    805 
    806   MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (59u * 1024u), \
    807                              "Create HPACK dynamic table");
    808   if (NULL == dyn)
    809     return MHDT_TEST_RESULT ();
    810 
    811   MHDT_EXPECT_UINT_EQ_VAL_D (mhd_dtbl_get_num_entries (dyn), 0u, \
    812                              "an empty table must have no entries");
    813   mhdtl_dyn_check_get_valid_invalid (dyn);
    814 
    815   mhd_dtbl_destroy (dyn);
    816 
    817   MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (mhd_DTBL_MAX_SIZE), \
    818                              "Create HPACK dynamic table with maximum size");
    819   if (NULL == dyn)
    820     return MHDT_TEST_RESULT ();
    821 
    822   /* Add some entries with checks */
    823   mhdtl_dyn_add_sized_entry_with_check (dyn, 123u);
    824   mhdtl_dyn_add_sized_entry_with_check (dyn, 234u);
    825   mhdtl_dyn_check_get_valid_invalid (dyn);
    826 
    827   mhd_dtbl_destroy (dyn);
    828 
    829   return MHDT_TEST_RESULT ();
    830 }
    831 
    832 
    833 static int
    834 test_dyn_add_three (void)
    835 {
    836   struct mhd_HpackDTblContext*dyn;
    837 
    838   MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (256u), \
    839                              "Create HPACK dynamic table");
    840   if (NULL == dyn)
    841     return MHDT_TEST_RESULT ();
    842 
    843   mhdtl_dyn_add_hdr_with_check (dyn, "header1", "value1");
    844   mhdtl_dyn_add_hdr_with_check (dyn, "header2", "longer value of the header2");
    845   mhdtl_dyn_add_hdr_with_check (dyn, "Header3", "value of the header with the "
    846                                 "uppercase name");
    847 
    848   mhd_dtbl_destroy (dyn);
    849 
    850   return MHDT_TEST_RESULT ();
    851 }
    852 
    853 
    854 static int
    855 test_dyn_add_empty (void)
    856 {
    857   struct mhd_HpackDTblContext*dyn;
    858 
    859   MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (256u), \
    860                              "Create HPACK dynamic table");
    861   if (NULL == dyn)
    862     return MHDT_TEST_RESULT ();
    863 
    864   mhdtl_dyn_add_hdr_with_check (dyn, "", "");
    865   mhdtl_dyn_add_hdr_with_check (dyn, "h", "");
    866   mhdtl_dyn_add_hdr_with_check (dyn, "", "v");
    867 
    868   mhd_dtbl_destroy (dyn);
    869 
    870   return MHDT_TEST_RESULT ();
    871 }
    872 
    873 
    874 static int
    875 test_dyn_add_evict_simple (void)
    876 {
    877   struct mhd_HpackDTblContext*dyn;
    878 
    879   MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (128u), \
    880                              "Create HPACK dynamic table");
    881   if (NULL == dyn)
    882     return MHDT_TEST_RESULT ();
    883 
    884   mhdtl_dyn_add_hdr_with_check (dyn, "header1", "value1");
    885   mhdtl_dyn_add_hdr_with_check (dyn, "header2", "longer value of the header2");
    886   mhdtl_dyn_add_hdr_with_check (dyn, "Header3", "value of the header with the "
    887                                 "uppercase name");
    888   mhdtl_dyn_add_hdr_with_check (dyn, "header4", "smaller header");
    889   mhdtl_dyn_add_hdr_with_check (dyn, "header5", "value5");
    890 
    891   mhd_dtbl_destroy (dyn);
    892 
    893   return MHDT_TEST_RESULT ();
    894 }
    895 
    896 
    897 static int
    898 test_dyn_add_evict_wrap (void)
    899 {
    900   struct mhd_HpackDTblContext*dyn;
    901 
    902   MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (280u), \
    903                              "Create HPACK dynamic table");
    904   if (NULL == dyn)
    905     return MHDT_TEST_RESULT ();
    906 
    907 #define MHDTL_H01N "notably-long-name1"         /* length: 18 */
    908 #define MHDTL_H01V "some notably long data1"    /* length: 23 */
    909 #define MHDTL_H02N "longer-name2"       /* length: 12 */
    910 #define MHDTL_H02V "some longer data2"  /* length: 17 */
    911 #define MHDTL_H03N "abcdefgh3"          /* length: 9 */
    912 #define MHDTL_H03V "random data3"       /* length: 12 */
    913 #define MHDTL_H04N "short-hdr4"         /* length: 10 */
    914 #define MHDTL_H04V "value4"             /* length: 6 */
    915 #define MHDTL_H05N "some-header5"                       /* length: 12 */
    916 #define MHDTL_H05V "even longer value of the header5"   /* length: 32 */
    917 #define MHDTL_H06N "longer-name6"       /* length: 12 */
    918 #define MHDTL_H06V "some longer data6"  /* length: 17 */
    919 #define MHDTL_H07N "some-extremely-long-name7"                  /* length: 25 */
    920 #define MHDTL_H07V "some really long value of the header7"      /* length: 37 */
    921 #define MHDTL_H08N "someheader8"        /* length: 11 */
    922 #define MHDTL_H08V "value8"             /* length: 6 */
    923 #define MHDTL_H09N "the-long-long-long-long-long-long-long-name9"       /* length: 44 */
    924 #define MHDTL_H09V "the header (field) value, with commas and other " \
    925         "extra characters to make it really huge, larger " \
    926         "enough to replace all other headers but one, the " \
    927         "last one."                    /* length: 154 */
    928 #define MHDTL_H10N "the-long-long-long-long-long-long-long-name10"      /* length: 45 */
    929 #define MHDTL_H10V "the header (field) value, with commas and other " \
    930         "extra characters to make it really huge, larger " \
    931         "enough to replace all other headers, leaving space " \
    932         "only for a tiny header"                      /* length: 169 */
    933 #define MHDTL_H11N "a"          /* length: 1 */
    934 #define MHDTL_H11V "B"          /* length: 1 */
    935 #define MHDTL_H12N "c"          /* length: 1 */
    936 #define MHDTL_H12V "D"          /* length: 1 */
    937 #define MHDTL_H13N "e"          /* length: 1 */
    938 #define MHDTL_H13V "F"          /* length: 1 */
    939 #define MHDTL_H14N "g"          /* length: 1 */
    940 #define MHDTL_H14V "H"          /* length: 1 */
    941 #define MHDTL_H15N "i"          /* length: 1 */
    942 #define MHDTL_H15V "J"          /* length: 1 */
    943 #define MHDTL_H16N "k"          /* length: 1 */
    944 #define MHDTL_H16V "L"          /* length: 1 */
    945 #define MHDTL_H17N "m"          /* length: 1 */
    946 #define MHDTL_H17V "N"          /* length: 1 */
    947 #define MHDTL_H18N "name18"     /* length: 6 */
    948 #define MHDTL_H18V "vl18"       /* length: 4 */
    949 #define MHDTL_H19N "o"          /* length: 1 */
    950 #define MHDTL_H19V "P"          /* length: 1 */
    951 #define MHDTL_H20N "m"          /* length: 1 */
    952 #define MHDTL_H20V "N"          /* length: 1 */
    953 
    954   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H01N, MHDTL_H01V); /* 18 + 23 + 32 = 73 */
    955   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H02N, MHDTL_H02V); /* 12 + 17 + 32 = 61 */
    956   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H03N, MHDTL_H03V); /*  9 + 12 + 32 = 53 */
    957   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H04N, MHDTL_H04V); /* 10 +  6 + 32 = 48 */
    958   /* 73 + 61 + 48 + 76 = 258 */
    959 
    960   /* '1', '2', '3', '4' [insert pos] */
    961   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 235u);
    962   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 4u);
    963 
    964   mhdtl_dyn_check_entry_at_idx (dyn,
    965                                 mhd_HPACK_STBL_LAST_IDX + 1u,
    966                                 MHDTL_H04N, MHDTL_H04V);
    967   mhdtl_dyn_check_entry_at_idx (dyn,
    968                                 mhd_HPACK_STBL_LAST_IDX + 2u,
    969                                 MHDTL_H03N, MHDTL_H03V);
    970   mhdtl_dyn_check_entry_at_idx (dyn,
    971                                 mhd_HPACK_STBL_LAST_IDX + 3u,
    972                                 MHDTL_H02N, MHDTL_H02V);
    973   mhdtl_dyn_check_entry_at_idx (dyn,
    974                                 mhd_HPACK_STBL_LAST_IDX + 4u,
    975                                 MHDTL_H01N, MHDTL_H01V);
    976 
    977   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H05N, MHDTL_H05V); /* 12 + 32 + 32 = 76 */
    978   /* '5' [insert pos], '2', '3', '4' */
    979   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 238u);
    980   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 4u);
    981 
    982   mhdtl_dyn_check_entry_at_idx (dyn,
    983                                 mhd_HPACK_STBL_LAST_IDX + 1u,
    984                                 MHDTL_H05N, MHDTL_H05V);
    985   mhdtl_dyn_check_entry_at_idx (dyn,
    986                                 mhd_HPACK_STBL_LAST_IDX + 2u,
    987                                 MHDTL_H04N, MHDTL_H04V);
    988   mhdtl_dyn_check_entry_at_idx (dyn,
    989                                 mhd_HPACK_STBL_LAST_IDX + 3u,
    990                                 MHDTL_H03N, MHDTL_H03V);
    991   mhdtl_dyn_check_entry_at_idx (dyn,
    992                                 mhd_HPACK_STBL_LAST_IDX + 4u,
    993                                 MHDTL_H02N, MHDTL_H02V);
    994 
    995   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H06N, MHDTL_H06V); /* 12 + 17 + 32 = 61 */
    996   /* '5', '6' [insert pos], '3', '4' */
    997   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 238u);
    998   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 4u);
    999 
   1000   mhdtl_dyn_check_entry_at_idx (dyn,
   1001                                 mhd_HPACK_STBL_LAST_IDX + 1u,
   1002                                 MHDTL_H06N, MHDTL_H06V);
   1003   mhdtl_dyn_check_entry_at_idx (dyn,
   1004                                 mhd_HPACK_STBL_LAST_IDX + 2u,
   1005                                 MHDTL_H05N, MHDTL_H05V);
   1006   mhdtl_dyn_check_entry_at_idx (dyn,
   1007                                 mhd_HPACK_STBL_LAST_IDX + 3u,
   1008                                 MHDTL_H04N, MHDTL_H04V);
   1009   mhdtl_dyn_check_entry_at_idx (dyn,
   1010                                 mhd_HPACK_STBL_LAST_IDX + 4u,
   1011                                 MHDTL_H03N, MHDTL_H03V);
   1012 
   1013   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H07N, MHDTL_H07V); /* 25 + 37 + 32 = 94 */
   1014   /* '5', '6', '7' [insert pos], '4' */
   1015   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 279u);
   1016   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 4u);
   1017 
   1018   mhdtl_dyn_check_entry_at_idx (dyn,
   1019                                 mhd_HPACK_STBL_LAST_IDX + 1u,
   1020                                 MHDTL_H07N, MHDTL_H07V);
   1021   mhdtl_dyn_check_entry_at_idx (dyn,
   1022                                 mhd_HPACK_STBL_LAST_IDX + 2u,
   1023                                 MHDTL_H06N, MHDTL_H06V);
   1024   mhdtl_dyn_check_entry_at_idx (dyn,
   1025                                 mhd_HPACK_STBL_LAST_IDX + 3u,
   1026                                 MHDTL_H05N, MHDTL_H05V);
   1027   mhdtl_dyn_check_entry_at_idx (dyn,
   1028                                 mhd_HPACK_STBL_LAST_IDX + 4u,
   1029                                 MHDTL_H04N, MHDTL_H04V);
   1030 
   1031   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H08N, MHDTL_H08V); /* 11 +  6 + 32 = 49 */
   1032   /* '5', '6', '7', '8' [insert pos] */
   1033   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 280u);
   1034   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 4u);
   1035 
   1036   mhdtl_dyn_check_entry_at_idx (dyn,
   1037                                 mhd_HPACK_STBL_LAST_IDX + 1u,
   1038                                 MHDTL_H08N, MHDTL_H08V);
   1039   mhdtl_dyn_check_entry_at_idx (dyn,
   1040                                 mhd_HPACK_STBL_LAST_IDX + 2u,
   1041                                 MHDTL_H07N, MHDTL_H07V);
   1042   mhdtl_dyn_check_entry_at_idx (dyn,
   1043                                 mhd_HPACK_STBL_LAST_IDX + 3u,
   1044                                 MHDTL_H06N, MHDTL_H06V);
   1045   mhdtl_dyn_check_entry_at_idx (dyn,
   1046                                 mhd_HPACK_STBL_LAST_IDX + 4u,
   1047                                 MHDTL_H05N, MHDTL_H05V);
   1048 
   1049   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H09N, MHDTL_H09V); /* 44 + 154 + 32 = 230 */
   1050   /* '9' [insert pos], '8' */
   1051   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 279u);
   1052   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u);
   1053 
   1054   mhdtl_dyn_check_entry_at_idx (dyn,
   1055                                 mhd_HPACK_STBL_LAST_IDX + 1u,
   1056                                 MHDTL_H09N, MHDTL_H09V);
   1057   mhdtl_dyn_check_entry_at_idx (dyn,
   1058                                 mhd_HPACK_STBL_LAST_IDX + 2u,
   1059                                 MHDTL_H08N, MHDTL_H08V);
   1060 
   1061   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H10N, MHDTL_H10V); /* 45 + 169 + 32 = 246 */
   1062   /* '10' [insert pos] */
   1063   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 246u);
   1064   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 1u);
   1065 
   1066   mhdtl_dyn_check_entry_at_idx (dyn,
   1067                                 mhd_HPACK_STBL_LAST_IDX + 1u,
   1068                                 MHDTL_H10N, MHDTL_H10V);
   1069 
   1070   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H11N, MHDTL_H11V); /*  1 +  1 + 32 = 34 */
   1071   /* '10', '11' [insert pos] */
   1072   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 280u);
   1073   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u);
   1074 
   1075   mhdtl_dyn_check_entry_at_idx (dyn,
   1076                                 mhd_HPACK_STBL_LAST_IDX + 1u,
   1077                                 MHDTL_H11N, MHDTL_H11V);
   1078   mhdtl_dyn_check_entry_at_idx (dyn,
   1079                                 mhd_HPACK_STBL_LAST_IDX + 2u,
   1080                                 MHDTL_H10N, MHDTL_H10V);
   1081 
   1082   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H12N, MHDTL_H12V); /*  1 +  1 + 32 = 34 */
   1083   /* '12' [insert pos], '11' */
   1084   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 68u);
   1085   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u);
   1086 
   1087   mhdtl_dyn_check_entry_at_idx (dyn,
   1088                                 mhd_HPACK_STBL_LAST_IDX + 1u,
   1089                                 MHDTL_H12N, MHDTL_H12V);
   1090   mhdtl_dyn_check_entry_at_idx (dyn,
   1091                                 mhd_HPACK_STBL_LAST_IDX + 2u,
   1092                                 MHDTL_H11N, MHDTL_H11V);
   1093 
   1094   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H13N, MHDTL_H13V); /*  1 +  1 + 32 = 34 */
   1095   /* '12', '13' [insert pos], '11' */
   1096   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 102u);
   1097   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u);
   1098 
   1099   mhdtl_dyn_check_entry_at_idx (dyn,
   1100                                 mhd_HPACK_STBL_LAST_IDX + 1u,
   1101                                 MHDTL_H13N, MHDTL_H13V);
   1102   mhdtl_dyn_check_entry_at_idx (dyn,
   1103                                 mhd_HPACK_STBL_LAST_IDX + 2u,
   1104                                 MHDTL_H12N, MHDTL_H12V);
   1105   mhdtl_dyn_check_entry_at_idx (dyn,
   1106                                 mhd_HPACK_STBL_LAST_IDX + 3u,
   1107                                 MHDTL_H11N, MHDTL_H11V);
   1108 
   1109   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H14N, MHDTL_H14V); /*  1 +  1 + 32 = 34 */
   1110   /* '12', '13', '14' [insert pos], '11' */
   1111   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 136u);
   1112   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 4u);
   1113 
   1114   mhdtl_dyn_check_entry_at_idx (dyn,
   1115                                 mhd_HPACK_STBL_LAST_IDX + 1u,
   1116                                 MHDTL_H14N, MHDTL_H14V);
   1117   mhdtl_dyn_check_entry_at_idx (dyn,
   1118                                 mhd_HPACK_STBL_LAST_IDX + 2u,
   1119                                 MHDTL_H13N, MHDTL_H13V);
   1120   mhdtl_dyn_check_entry_at_idx (dyn,
   1121                                 mhd_HPACK_STBL_LAST_IDX + 3u,
   1122                                 MHDTL_H12N, MHDTL_H12V);
   1123   mhdtl_dyn_check_entry_at_idx (dyn,
   1124                                 mhd_HPACK_STBL_LAST_IDX + 4u,
   1125                                 MHDTL_H11N, MHDTL_H11V);
   1126 
   1127   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H15N, MHDTL_H15V); /*  1 +  1 + 32 = 34 */
   1128   /* '12', '13', '14', '15' [insert pos], '11' */
   1129   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 170u);
   1130   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 5u);
   1131 
   1132   mhdtl_dyn_check_entry_at_idx (dyn,
   1133                                 mhd_HPACK_STBL_LAST_IDX + 1u,
   1134                                 MHDTL_H15N, MHDTL_H15V);
   1135   mhdtl_dyn_check_entry_at_idx (dyn,
   1136                                 mhd_HPACK_STBL_LAST_IDX + 2u,
   1137                                 MHDTL_H14N, MHDTL_H14V);
   1138   mhdtl_dyn_check_entry_at_idx (dyn,
   1139                                 mhd_HPACK_STBL_LAST_IDX + 3u,
   1140                                 MHDTL_H13N, MHDTL_H13V);
   1141   mhdtl_dyn_check_entry_at_idx (dyn,
   1142                                 mhd_HPACK_STBL_LAST_IDX + 4u,
   1143                                 MHDTL_H12N, MHDTL_H12V);
   1144   mhdtl_dyn_check_entry_at_idx (dyn,
   1145                                 mhd_HPACK_STBL_LAST_IDX + 5u,
   1146                                 MHDTL_H11N, MHDTL_H11V);
   1147 
   1148   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H16N, MHDTL_H16V); /*  1 +  1 + 32 = 34 */
   1149   /* '12', '13', '14', '15', '16' [insert pos], '11' */
   1150   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 204u);
   1151   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 6u);
   1152 
   1153   mhdtl_dyn_check_entry_at_idx (dyn,
   1154                                 mhd_HPACK_STBL_LAST_IDX + 1u,
   1155                                 MHDTL_H16N, MHDTL_H16V);
   1156   mhdtl_dyn_check_entry_at_idx (dyn,
   1157                                 mhd_HPACK_STBL_LAST_IDX + 2u,
   1158                                 MHDTL_H15N, MHDTL_H15V);
   1159   mhdtl_dyn_check_entry_at_idx (dyn,
   1160                                 mhd_HPACK_STBL_LAST_IDX + 3u,
   1161                                 MHDTL_H14N, MHDTL_H14V);
   1162   mhdtl_dyn_check_entry_at_idx (dyn,
   1163                                 mhd_HPACK_STBL_LAST_IDX + 4u,
   1164                                 MHDTL_H13N, MHDTL_H13V);
   1165   mhdtl_dyn_check_entry_at_idx (dyn,
   1166                                 mhd_HPACK_STBL_LAST_IDX + 5u,
   1167                                 MHDTL_H12N, MHDTL_H12V);
   1168   mhdtl_dyn_check_entry_at_idx (dyn,
   1169                                 mhd_HPACK_STBL_LAST_IDX + 6u,
   1170                                 MHDTL_H11N, MHDTL_H11V);
   1171 
   1172   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H17N, MHDTL_H17V); /*  1 +  1 + 32 = 34 */
   1173   /* '12', '13', '14', '15', '16', '17' [insert pos], '11' */
   1174   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 238u);
   1175   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 7u);
   1176 
   1177   mhdtl_dyn_check_entry_at_idx (dyn,
   1178                                 mhd_HPACK_STBL_LAST_IDX + 1u,
   1179                                 MHDTL_H17N, MHDTL_H17V);
   1180   mhdtl_dyn_check_entry_at_idx (dyn,
   1181                                 mhd_HPACK_STBL_LAST_IDX + 2u,
   1182                                 MHDTL_H16N, MHDTL_H16V);
   1183   mhdtl_dyn_check_entry_at_idx (dyn,
   1184                                 mhd_HPACK_STBL_LAST_IDX + 3u,
   1185                                 MHDTL_H15N, MHDTL_H15V);
   1186   mhdtl_dyn_check_entry_at_idx (dyn,
   1187                                 mhd_HPACK_STBL_LAST_IDX + 4u,
   1188                                 MHDTL_H14N, MHDTL_H14V);
   1189   mhdtl_dyn_check_entry_at_idx (dyn,
   1190                                 mhd_HPACK_STBL_LAST_IDX + 5u,
   1191                                 MHDTL_H13N, MHDTL_H13V);
   1192   mhdtl_dyn_check_entry_at_idx (dyn,
   1193                                 mhd_HPACK_STBL_LAST_IDX + 6u,
   1194                                 MHDTL_H12N, MHDTL_H12V);
   1195   mhdtl_dyn_check_entry_at_idx (dyn,
   1196                                 mhd_HPACK_STBL_LAST_IDX + 7u,
   1197                                 MHDTL_H11N, MHDTL_H11V);
   1198 
   1199   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H18N, MHDTL_H18V); /*  6 +  4 + 32 = 42 */
   1200   /* '12', '13', '14', '15', '16', '17', '18' [insert pos], '11' */
   1201   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 280u);
   1202   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 8u);
   1203 
   1204   mhdtl_dyn_check_entry_at_idx (dyn,
   1205                                 mhd_HPACK_STBL_LAST_IDX + 1u,
   1206                                 MHDTL_H18N, MHDTL_H18V);
   1207   mhdtl_dyn_check_entry_at_idx (dyn,
   1208                                 mhd_HPACK_STBL_LAST_IDX + 2u,
   1209                                 MHDTL_H17N, MHDTL_H17V);
   1210   mhdtl_dyn_check_entry_at_idx (dyn,
   1211                                 mhd_HPACK_STBL_LAST_IDX + 3u,
   1212                                 MHDTL_H16N, MHDTL_H16V);
   1213   mhdtl_dyn_check_entry_at_idx (dyn,
   1214                                 mhd_HPACK_STBL_LAST_IDX + 4u,
   1215                                 MHDTL_H15N, MHDTL_H15V);
   1216   mhdtl_dyn_check_entry_at_idx (dyn,
   1217                                 mhd_HPACK_STBL_LAST_IDX + 5u,
   1218                                 MHDTL_H14N, MHDTL_H14V);
   1219   mhdtl_dyn_check_entry_at_idx (dyn,
   1220                                 mhd_HPACK_STBL_LAST_IDX + 6u,
   1221                                 MHDTL_H13N, MHDTL_H13V);
   1222   mhdtl_dyn_check_entry_at_idx (dyn,
   1223                                 mhd_HPACK_STBL_LAST_IDX + 7u,
   1224                                 MHDTL_H12N, MHDTL_H12V);
   1225   mhdtl_dyn_check_entry_at_idx (dyn,
   1226                                 mhd_HPACK_STBL_LAST_IDX + 8u,
   1227                                 MHDTL_H11N, MHDTL_H11V);
   1228 
   1229   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H19N, MHDTL_H19V); /*  1 +  1 + 32 = 34 */
   1230   /* '12', '13', '14', '15', '16', '17', '18', '19' [insert pos] */
   1231   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 280u);
   1232   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 8u);
   1233 
   1234   mhdtl_dyn_check_entry_at_idx (dyn,
   1235                                 mhd_HPACK_STBL_LAST_IDX + 1u,
   1236                                 MHDTL_H19N, MHDTL_H19V);
   1237   mhdtl_dyn_check_entry_at_idx (dyn,
   1238                                 mhd_HPACK_STBL_LAST_IDX + 2u,
   1239                                 MHDTL_H18N, MHDTL_H18V);
   1240   mhdtl_dyn_check_entry_at_idx (dyn,
   1241                                 mhd_HPACK_STBL_LAST_IDX + 3u,
   1242                                 MHDTL_H17N, MHDTL_H17V);
   1243   mhdtl_dyn_check_entry_at_idx (dyn,
   1244                                 mhd_HPACK_STBL_LAST_IDX + 4u,
   1245                                 MHDTL_H16N, MHDTL_H16V);
   1246   mhdtl_dyn_check_entry_at_idx (dyn,
   1247                                 mhd_HPACK_STBL_LAST_IDX + 5u,
   1248                                 MHDTL_H15N, MHDTL_H15V);
   1249   mhdtl_dyn_check_entry_at_idx (dyn,
   1250                                 mhd_HPACK_STBL_LAST_IDX + 6u,
   1251                                 MHDTL_H14N, MHDTL_H14V);
   1252   mhdtl_dyn_check_entry_at_idx (dyn,
   1253                                 mhd_HPACK_STBL_LAST_IDX + 7u,
   1254                                 MHDTL_H13N, MHDTL_H13V);
   1255   mhdtl_dyn_check_entry_at_idx (dyn,
   1256                                 mhd_HPACK_STBL_LAST_IDX + 8u,
   1257                                 MHDTL_H12N, MHDTL_H12V);
   1258 
   1259   mhdtl_dyn_add_sized_entry_with_check (dyn, 246u);
   1260   /* 'generated' [insert pos], '19' */
   1261   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 280u);
   1262   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u);
   1263 
   1264   mhdtl_dyn_check_entry_at_idx (dyn,
   1265                                 mhd_HPACK_STBL_LAST_IDX + 2u,
   1266                                 MHDTL_H19N, MHDTL_H19V);
   1267 
   1268   mhdtl_dyn_add_sized_entry_with_check (dyn, 247u); /* Should be reset on the next add */
   1269   /* Re-use headers */
   1270   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H12N, MHDTL_H12V); /*  1 +  1 + 32 = 34 */
   1271   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H13N, MHDTL_H13V); /*  1 +  1 + 32 = 34 */
   1272   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H14N, MHDTL_H14V); /*  1 +  1 + 32 = 34 */
   1273   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H15N, MHDTL_H15V); /*  1 +  1 + 32 = 34 */
   1274   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H16N, MHDTL_H16V); /*  1 +  1 + 32 = 34 */
   1275   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H17N, MHDTL_H17V); /*  1 +  1 + 32 = 34 */
   1276   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H18N, MHDTL_H18V); /*  6 +  4 + 32 = 42 */
   1277   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H19N, MHDTL_H19V); /*  1 +  1 + 32 = 34 */
   1278   /* '12', '13', '14', '15', '16', '17', '18', '19' [insert pos] */
   1279   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 280u);
   1280   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 8u);
   1281 
   1282   mhdtl_dyn_check_entry_at_idx (dyn,
   1283                                 mhd_HPACK_STBL_LAST_IDX + 1u,
   1284                                 MHDTL_H19N, MHDTL_H19V);
   1285   mhdtl_dyn_check_entry_at_idx (dyn,
   1286                                 mhd_HPACK_STBL_LAST_IDX + 2u,
   1287                                 MHDTL_H18N, MHDTL_H18V);
   1288   mhdtl_dyn_check_entry_at_idx (dyn,
   1289                                 mhd_HPACK_STBL_LAST_IDX + 3u,
   1290                                 MHDTL_H17N, MHDTL_H17V);
   1291   mhdtl_dyn_check_entry_at_idx (dyn,
   1292                                 mhd_HPACK_STBL_LAST_IDX + 4u,
   1293                                 MHDTL_H16N, MHDTL_H16V);
   1294   mhdtl_dyn_check_entry_at_idx (dyn,
   1295                                 mhd_HPACK_STBL_LAST_IDX + 5u,
   1296                                 MHDTL_H15N, MHDTL_H15V);
   1297   mhdtl_dyn_check_entry_at_idx (dyn,
   1298                                 mhd_HPACK_STBL_LAST_IDX + 6u,
   1299                                 MHDTL_H14N, MHDTL_H14V);
   1300   mhdtl_dyn_check_entry_at_idx (dyn,
   1301                                 mhd_HPACK_STBL_LAST_IDX + 7u,
   1302                                 MHDTL_H13N, MHDTL_H13V);
   1303   mhdtl_dyn_check_entry_at_idx (dyn,
   1304                                 mhd_HPACK_STBL_LAST_IDX + 8u,
   1305                                 MHDTL_H12N, MHDTL_H12V);
   1306 
   1307   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H20N, MHDTL_H20V); /*  1 +  1 + 32 = 34 */
   1308   /* '20' [insert pos], '13', '14', '15', '16', '17', '18', '19' */
   1309   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 280u);
   1310   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 8u);
   1311 
   1312   mhdtl_dyn_check_entry_at_idx (dyn,
   1313                                 mhd_HPACK_STBL_LAST_IDX + 1u,
   1314                                 MHDTL_H20N, MHDTL_H20V);
   1315   mhdtl_dyn_check_entry_at_idx (dyn,
   1316                                 mhd_HPACK_STBL_LAST_IDX + 2u,
   1317                                 MHDTL_H19N, MHDTL_H19V);
   1318   mhdtl_dyn_check_entry_at_idx (dyn,
   1319                                 mhd_HPACK_STBL_LAST_IDX + 3u,
   1320                                 MHDTL_H18N, MHDTL_H18V);
   1321   mhdtl_dyn_check_entry_at_idx (dyn,
   1322                                 mhd_HPACK_STBL_LAST_IDX + 4u,
   1323                                 MHDTL_H17N, MHDTL_H17V);
   1324   mhdtl_dyn_check_entry_at_idx (dyn,
   1325                                 mhd_HPACK_STBL_LAST_IDX + 5u,
   1326                                 MHDTL_H16N, MHDTL_H16V);
   1327   mhdtl_dyn_check_entry_at_idx (dyn,
   1328                                 mhd_HPACK_STBL_LAST_IDX + 6u,
   1329                                 MHDTL_H15N, MHDTL_H15V);
   1330   mhdtl_dyn_check_entry_at_idx (dyn,
   1331                                 mhd_HPACK_STBL_LAST_IDX + 7u,
   1332                                 MHDTL_H14N, MHDTL_H14V);
   1333   mhdtl_dyn_check_entry_at_idx (dyn,
   1334                                 mhd_HPACK_STBL_LAST_IDX + 8u,
   1335                                 MHDTL_H13N, MHDTL_H13V);
   1336 
   1337   mhdtl_dyn_add_sized_entry_with_check (dyn, 212u);
   1338   /* '20', 'generated' [insert pos], '19' */
   1339   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 280u);
   1340   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u);
   1341 
   1342   mhdtl_dyn_check_entry_at_idx (dyn,
   1343                                 mhd_HPACK_STBL_LAST_IDX + 2u,
   1344                                 MHDTL_H20N, MHDTL_H20V);
   1345   mhdtl_dyn_check_entry_at_idx (dyn,
   1346                                 mhd_HPACK_STBL_LAST_IDX + 3u,
   1347                                 MHDTL_H19N, MHDTL_H19V);
   1348 
   1349   mhd_dtbl_destroy (dyn);
   1350 
   1351 #undef MHDTL_H01N
   1352 #undef MHDTL_H01V
   1353 #undef MHDTL_H02N
   1354 #undef MHDTL_H02V
   1355 #undef MHDTL_H03N
   1356 #undef MHDTL_H03V
   1357 #undef MHDTL_H04N
   1358 #undef MHDTL_H04V
   1359 #undef MHDTL_H05N
   1360 #undef MHDTL_H05V
   1361 #undef MHDTL_H06N
   1362 #undef MHDTL_H06V
   1363 #undef MHDTL_H07N
   1364 #undef MHDTL_H07V
   1365 #undef MHDTL_H08N
   1366 #undef MHDTL_H08V
   1367 #undef MHDTL_H09N
   1368 #undef MHDTL_H09V
   1369 #undef MHDTL_H10N
   1370 #undef MHDTL_H10V
   1371 #undef MHDTL_H11N
   1372 #undef MHDTL_H11V
   1373 #undef MHDTL_H12N
   1374 #undef MHDTL_H12V
   1375 #undef MHDTL_H13N
   1376 #undef MHDTL_H13V
   1377 #undef MHDTL_H14N
   1378 #undef MHDTL_H14V
   1379 #undef MHDTL_H15N
   1380 #undef MHDTL_H15V
   1381 #undef MHDTL_H16N
   1382 #undef MHDTL_H16V
   1383 #undef MHDTL_H17N
   1384 #undef MHDTL_H17V
   1385 #undef MHDTL_H18N
   1386 #undef MHDTL_H18V
   1387 #undef MHDTL_H19N
   1388 #undef MHDTL_H19V
   1389 #undef MHDTL_H20N
   1390 #undef MHDTL_H20V
   1391 
   1392   return MHDT_TEST_RESULT ();
   1393 }
   1394 
   1395 
   1396 static int
   1397 test_dyn_add_evict_inter (void)
   1398 {
   1399   struct mhd_HpackDTblContext*dyn;
   1400   struct mhd_BufferConst check_name;
   1401   struct mhd_BufferConst check_value;
   1402 
   1403   MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (705u), \
   1404                              "Create HPACK dynamic table");
   1405   if (NULL == dyn)
   1406     return MHDT_TEST_RESULT ();
   1407 
   1408   mhdtl_dyn_add_sized_entry_with_check (dyn, 50u);
   1409   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 1u);
   1410   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 50u);
   1411   mhdtl_dyn_add_sized_entry_with_check (dyn, 75u);
   1412   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u);
   1413   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 125u);
   1414   mhdtl_dyn_add_sized_entry_with_check (dyn, 100u);
   1415   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u);
   1416   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 225u);
   1417   mhdtl_dyn_add_sized_entry_with_check (dyn, 125u);
   1418   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 4u);
   1419   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 350u);
   1420   mhdtl_dyn_add_sized_entry_with_check (dyn, 150u);
   1421   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 5u);
   1422   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 500u);
   1423   mhdtl_dyn_add_sized_entry_with_check (dyn, 175u);
   1424 
   1425   /* { 50, 75, 100, 125, 150, 175 [insert pos] } */
   1426   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 675u);
   1427   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 6u);
   1428 
   1429   if (MHDT_EXPECT_TRUE (mhd_dtbl_get_entry (dyn, \
   1430                                             mhd_HPACK_STBL_LAST_IDX + 6u, \
   1431                                             &check_name, \
   1432                                             &check_value)))
   1433     MHDT_EXPECT_UINT_EQ_VAL (MHDTL_HPACK_ENTRY_SIZE (check_name.size, \
   1434                                                      check_value.size), \
   1435                              50u);
   1436 
   1437   /* First two entries should be replaced with a single entry, which
   1438      is 2 bytes smaller than two entries.
   1439      (50, 75) -> (123) */
   1440   mhdtl_dyn_add_sized_entry_with_check (dyn, 123u);
   1441   /* { 123 [insert pos], 100, 125, 150, 175 } */
   1442   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 673u);
   1443   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 5u);
   1444 
   1445   if (MHDT_EXPECT_TRUE (mhd_dtbl_get_entry (dyn, \
   1446                                             mhd_HPACK_STBL_LAST_IDX + 5u, \
   1447                                             &check_name, \
   1448                                             &check_value)))
   1449     MHDT_EXPECT_UINT_EQ_VAL (MHDTL_HPACK_ENTRY_SIZE (check_name.size, \
   1450                                                      check_value.size), \
   1451                              100u);
   1452 
   1453   /* Next entry should be replaced with a smaller entry.
   1454      (100) -> (35) */
   1455   mhdtl_dyn_add_sized_entry_with_check (dyn, 35u);
   1456   /* { 123, 35 [insert pos], 125, 150, 175 } */
   1457   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 608u);
   1458   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 5u);
   1459 
   1460   if (MHDT_EXPECT_TRUE (mhd_dtbl_get_entry (dyn, \
   1461                                             mhd_HPACK_STBL_LAST_IDX + 5u, \
   1462                                             &check_name, \
   1463                                             &check_value)))
   1464     MHDT_EXPECT_UINT_EQ_VAL (MHDTL_HPACK_ENTRY_SIZE (check_name.size, \
   1465                                                      check_value.size), \
   1466                              125u);
   1467 
   1468   /* Should be added without eviction.
   1469      -> (97) */
   1470   mhdtl_dyn_add_sized_entry_with_check (dyn, 97u);
   1471   /* { 123, 35, 97 [insert pos], 125, 150, 175 } */
   1472   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 705u);
   1473   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 6u);
   1474 
   1475   if (MHDT_EXPECT_TRUE (mhd_dtbl_get_entry (dyn, \
   1476                                             mhd_HPACK_STBL_LAST_IDX + 6u, \
   1477                                             &check_name, \
   1478                                             &check_value)))
   1479     MHDT_EXPECT_UINT_EQ_VAL (MHDTL_HPACK_ENTRY_SIZE (check_name.size, \
   1480                                                      check_value.size), \
   1481                              125u);
   1482 
   1483   /* Two entries should be replaced with single one.
   1484      (125, 150) -> (275) */
   1485   mhdtl_dyn_add_sized_entry_with_check (dyn, 275u);
   1486   /* { 123, 35, 97, 275 [insert pos], 175 } */
   1487   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 705u);
   1488   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 5u);
   1489 
   1490   if (MHDT_EXPECT_TRUE (mhd_dtbl_get_entry (dyn, \
   1491                                             mhd_HPACK_STBL_LAST_IDX + 5u, \
   1492                                             &check_name, \
   1493                                             &check_value)))
   1494     MHDT_EXPECT_UINT_EQ_VAL (MHDTL_HPACK_ENTRY_SIZE (check_name.size, \
   1495                                                      check_value.size), \
   1496                              175u);
   1497 
   1498   /* Two entries should be replaced with single one.
   1499      (175, 123) -> (251) */
   1500   mhdtl_dyn_add_sized_entry_with_check (dyn, 251u);
   1501   /* { 35, 97, 275, 251 [insert pos] } */
   1502   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 658u);
   1503   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 4u);
   1504 
   1505   if (MHDT_EXPECT_TRUE (mhd_dtbl_get_entry (dyn, \
   1506                                             mhd_HPACK_STBL_LAST_IDX + 4u, \
   1507                                             &check_name, \
   1508                                             &check_value)))
   1509     MHDT_EXPECT_UINT_EQ_VAL (MHDTL_HPACK_ENTRY_SIZE (check_name.size, \
   1510                                                      check_value.size), \
   1511                              35u);
   1512 
   1513   /* Should be added without eviction.
   1514      -> (42) */
   1515   mhdtl_dyn_add_sized_entry_with_check (dyn, 42u);
   1516   /* { 42 [insert pos], 35, 97, 275, 251 } */
   1517   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 700u);
   1518   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 5u);
   1519 
   1520   if (MHDT_EXPECT_TRUE (mhd_dtbl_get_entry (dyn, \
   1521                                             mhd_HPACK_STBL_LAST_IDX + 5u, \
   1522                                             &check_name, \
   1523                                             &check_value)))
   1524     MHDT_EXPECT_UINT_EQ_VAL (MHDTL_HPACK_ENTRY_SIZE (check_name.size, \
   1525                                                      check_value.size), \
   1526                              35u);
   1527 
   1528   /* Two entries should be replaced with single one.
   1529      (35, 97) -> (51) */
   1530   mhdtl_dyn_add_sized_entry_with_check (dyn, 51u);
   1531   /* { 42, 51 [insert pos], 275, 251 } */
   1532   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 619u);
   1533   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 4u);
   1534 
   1535   if (MHDT_EXPECT_TRUE (mhd_dtbl_get_entry (dyn, \
   1536                                             mhd_HPACK_STBL_LAST_IDX + 4u, \
   1537                                             &check_name, \
   1538                                             &check_value)))
   1539     MHDT_EXPECT_UINT_EQ_VAL (MHDTL_HPACK_ENTRY_SIZE (check_name.size, \
   1540                                                      check_value.size), \
   1541                              275u);
   1542 
   1543   /* Three entries should be replaced with single one.
   1544      (275, 251, 42) -> (613) */
   1545   mhdtl_dyn_add_sized_entry_with_check (dyn, 613u);
   1546   /* { 51, 613 [insert pos] } */
   1547   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 664u);
   1548   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u);
   1549 
   1550   /* (51, 613) -> (672) */
   1551   mhdtl_dyn_add_sized_entry_with_check (dyn, 672u);
   1552   /* { 672 [insert pos] } */
   1553   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 672u);
   1554   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 1u);
   1555 
   1556   /* -> (33) */
   1557   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1558   /* { 672, 33 [insert pos] } */
   1559   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 705u);
   1560   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u);
   1561 
   1562   /* (672) -> (33) */
   1563   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1564   /* { 33 [insert pos], 33 } */
   1565   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 66u);
   1566   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u);
   1567 
   1568   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1569   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1570   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1571   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1572   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1573   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1574   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1575   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1576   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1577   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1578   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1579   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1580   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1581   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1582   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1583   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1584   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1585   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1586   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1587   /* { 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
   1588        33, 33, 33 [insert pos], 33 } */
   1589   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 693u);
   1590   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 21u);
   1591 
   1592   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1593   /* { 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
   1594        33, 33, 33, 33 [insert pos] } */
   1595   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 693u);
   1596   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 21u);
   1597 
   1598   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1599   /* { 33 [insert pos], 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
   1600        33, 33, 33, 33, 33, 33, 33 } */
   1601   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 693u);
   1602   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 21u);
   1603 
   1604   mhdtl_dyn_add_sized_entry_with_check (dyn, 639u);
   1605   /* { 33, 639 [insert pos], 33 } */
   1606   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 705u);
   1607   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u);
   1608 
   1609   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1610   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1611   /* { 33 [insert pos], 639, 33 } */
   1612   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 705u);
   1613   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u);
   1614 
   1615   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1616   /* { 33, 33 [insert pos], 33 } */
   1617   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 99u);
   1618   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u);
   1619 
   1620   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1621   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1622   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1623   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1624   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1625   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1626   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1627   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1628   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1629   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1630   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1631   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1632   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1633   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1634   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1635   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1636   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1637   mhdtl_dyn_add_sized_entry_with_check (dyn, 33u);
   1638   /* { 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
   1639        33, 33, 33 [insert pos], 33 } */
   1640   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 693u);
   1641   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 21u);
   1642 
   1643   mhd_dtbl_destroy (dyn);
   1644 
   1645   return MHDT_TEST_RESULT ();
   1646 }
   1647 
   1648 
   1649 static int
   1650 test_dyn_add_series (void)
   1651 {
   1652   const uint_fast16_t num_inter =
   1653     (uint_fast16_t)
   1654     (mhdtl_enable_deep_tests ? (16u * 1024u) : (1024u));
   1655   struct mhd_HpackDTblContext*dyn;
   1656   uint_fast16_t i;
   1657 
   1658   MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (925u), \
   1659                              "Create HPACK dynamic table");
   1660   if (NULL == dyn)
   1661     return MHDT_TEST_RESULT ();
   1662 
   1663   /* Add large strings */
   1664   for (i = 0; i < num_inter; ++i)
   1665   {
   1666     size_t prev_used;
   1667     size_t cur_used;
   1668     size_t strs_size;
   1669 
   1670     cur_used = mhdtl_dyn_get_size_used (dyn);
   1671     do
   1672     {
   1673       strs_size = 50u + mhdtl_mix16 (i,
   1674                                      (uint_least16_t) prev_used) % 256u;
   1675       prev_used = cur_used;
   1676       mhdtl_dyn_add_sized_strs_with_check (dyn,
   1677                                            strs_size);
   1678       cur_used = mhdtl_dyn_get_size_used (dyn);
   1679     } while (prev_used + strs_size + mhd_HPACK_ENTRY_OVERHEAD
   1680              == cur_used);
   1681     mhd_dtbl_evict_to_size (dyn,
   1682                             0u);
   1683   }
   1684 
   1685   /* Add small strings */
   1686   for (i = 0; i < num_inter; ++i)
   1687   {
   1688     size_t prev_used;
   1689     size_t cur_used;
   1690     size_t strs_size;
   1691 
   1692     cur_used = mhdtl_dyn_get_size_used (dyn);
   1693     do
   1694     {
   1695       strs_size = mhdtl_mix16 (i,
   1696                                (uint_least16_t) prev_used) % 16u;
   1697       prev_used = cur_used;
   1698       mhdtl_dyn_add_sized_strs_with_check (dyn,
   1699                                            strs_size);
   1700       cur_used = mhdtl_dyn_get_size_used (dyn);
   1701     } while (prev_used + strs_size + mhd_HPACK_ENTRY_OVERHEAD
   1702              == cur_used);
   1703     mhd_dtbl_evict_to_size (dyn,
   1704                             0u);
   1705   }
   1706 
   1707   /* Add mixed-size strings */
   1708   for (i = 0; i < num_inter; ++i)
   1709   {
   1710     size_t prev_used;
   1711     size_t cur_used;
   1712     size_t strs_size;
   1713 
   1714     cur_used = mhdtl_dyn_get_size_used (dyn);
   1715     do
   1716     {
   1717       strs_size = mhdtl_mix16 (i,
   1718                                (uint_least16_t) prev_used) % 312u;
   1719       prev_used = cur_used;
   1720       mhdtl_dyn_add_sized_strs_with_check (dyn,
   1721                                            strs_size);
   1722       cur_used = mhdtl_dyn_get_size_used (dyn);
   1723     } while (prev_used + strs_size + mhd_HPACK_ENTRY_OVERHEAD
   1724              == cur_used);
   1725     mhd_dtbl_evict_to_size (dyn,
   1726                             0u);
   1727   }
   1728 
   1729   mhd_dtbl_destroy (dyn);
   1730 
   1731   return MHDT_TEST_RESULT ();
   1732 }
   1733 
   1734 
   1735 static int
   1736 test_dyn_add_evict_series (void)
   1737 {
   1738   const uint_fast16_t num_inter =
   1739     (uint_fast16_t)
   1740     (mhdtl_enable_deep_tests ? (1024u) : (64u));
   1741   struct mhd_HpackDTblContext*dyn;
   1742   uint_fast16_t i;
   1743 
   1744   MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (925u), \
   1745                              "Create HPACK dynamic table");
   1746   if (NULL == dyn)
   1747     return MHDT_TEST_RESULT ();
   1748 
   1749   for (i = 0; i < num_inter; ++i)
   1750   {
   1751     uint_fast16_t j;
   1752     /* Add large strings */
   1753     for (j = 0; j < 128u; ++j)
   1754     {
   1755       size_t strs_size = 50u + mhdtl_mix16 (i, j) % 256u;
   1756       mhdtl_dyn_add_sized_strs_with_check (dyn,
   1757                                            strs_size);
   1758       /* Sometimes repeat the same size */
   1759       if (16u == (j % 32u))
   1760       {
   1761         unsigned int num_rep = mhdtl_mix16 (j, i) % 16u;
   1762         while (0 != num_rep--)
   1763           mhdtl_dyn_add_sized_strs_with_check (dyn,
   1764                                                strs_size);
   1765       }
   1766     }
   1767     /* Add small strings */
   1768     for (j = 0; j < 512u; ++j)
   1769     {
   1770       size_t strs_size = mhdtl_mix16 (i, j) % 15u;
   1771       mhdtl_dyn_add_sized_strs_with_check (dyn,
   1772                                            strs_size);
   1773       /* Sometimes repeat the same size */
   1774       if (16u == (j % 32u))
   1775       {
   1776         unsigned int num_rep = mhdtl_mix16 (j, i) % 32u;
   1777         while (0 != num_rep--)
   1778           mhdtl_dyn_add_sized_strs_with_check (dyn,
   1779                                                strs_size);
   1780       }
   1781     }
   1782     /* Add mixed-size strings */
   1783     for (j = 0; j < 256u; ++j)
   1784     {
   1785       size_t strs_size = mhdtl_mix16 (i, j) % 312u;
   1786       mhdtl_dyn_add_sized_strs_with_check (dyn,
   1787                                            strs_size);
   1788       /* Sometimes repeat the same size */
   1789       if (16u == (j % 32u))
   1790       {
   1791         unsigned int num_rep = mhdtl_mix16 (j, i) % 24u;
   1792         while (0 != num_rep--)
   1793           mhdtl_dyn_add_sized_strs_with_check (dyn,
   1794                                                strs_size);
   1795       }
   1796     }
   1797     /* Again add small strings before adding large strings */
   1798     for (j = 0; j < 32u; ++j)
   1799     {
   1800       size_t strs_size = mhdtl_mix16 (i, j) % 15u;
   1801       mhdtl_dyn_add_sized_strs_with_check (dyn,
   1802                                            strs_size);
   1803     }
   1804   }
   1805 
   1806   mhd_dtbl_destroy (dyn);
   1807 
   1808   return MHDT_TEST_RESULT ();
   1809 }
   1810 
   1811 
   1812 static int
   1813 test_dyn_evict_to_size (void)
   1814 {
   1815   struct mhd_HpackDTblContext*dyn;
   1816 
   1817   MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (256u), \
   1818                              "Create HPACK dynamic table");
   1819   if (NULL == dyn)
   1820     return MHDT_TEST_RESULT ();
   1821 
   1822 #define MHDTL_H01N "a"   /* length: 1 */
   1823 #define MHDTL_H01V "b"   /* length: 1 */
   1824 #define MHDTL_H02N "cd"  /* length: 2 */
   1825 #define MHDTL_H02V "ef"  /* length: 2 */
   1826 #define MHDTL_H03N "header3"             /* length: 7 */
   1827 #define MHDTL_H03V "value of header3"    /* length: 16 */
   1828 #define MHDTL_H04N "some-header4"                        /* length: 12 */
   1829 #define MHDTL_H04V "even longer value of the header4"    /* length: 32 */
   1830 
   1831   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H01N, MHDTL_H01V); /* 1 + 1 + 32 = 34 */
   1832   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H02N, MHDTL_H02V); /* 2 + 2 + 32 = 36 */
   1833   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H03N, MHDTL_H03V); /* 7 + 16 + 32 = 55 */
   1834   mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H04N, MHDTL_H04V); /* 12 + 32 + 32 = 76 */
   1835   /* Total size: 34 + 36 + 55 + 76 = 201 */
   1836 
   1837   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 201u);
   1838   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 4u);
   1839 
   1840   mhdtl_dyn_check_entry_at_idx (dyn,
   1841                                 mhd_HPACK_STBL_LAST_IDX + 1u,
   1842                                 MHDTL_H04N, MHDTL_H04V);
   1843   mhdtl_dyn_check_entry_at_idx (dyn,
   1844                                 mhd_HPACK_STBL_LAST_IDX + 2u,
   1845                                 MHDTL_H03N, MHDTL_H03V);
   1846   mhdtl_dyn_check_entry_at_idx (dyn,
   1847                                 mhd_HPACK_STBL_LAST_IDX + 3u,
   1848                                 MHDTL_H02N, MHDTL_H02V);
   1849   mhdtl_dyn_check_entry_at_idx (dyn,
   1850                                 mhd_HPACK_STBL_LAST_IDX + 4u,
   1851                                 MHDTL_H01N, MHDTL_H01V);
   1852 
   1853   mhdtl_dyn_check_get_valid_invalid (dyn);
   1854 
   1855   mhd_dtbl_evict_to_size (dyn, 202u); /* Nothing should be evicted */
   1856   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 201u);
   1857   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 4u);
   1858   mhdtl_dyn_check_get_valid_invalid (dyn);
   1859 
   1860   mhd_dtbl_evict_to_size (dyn, 201u); /* Still nothing should be evicted */
   1861   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 201u);
   1862   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 4u);
   1863   mhdtl_dyn_check_get_valid_invalid (dyn);
   1864 
   1865   mhd_dtbl_evict_to_size (dyn, 200u); /* Oldest entry should be evicted */
   1866   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 201u - 34u);
   1867   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u);
   1868 
   1869   mhdtl_dyn_check_entry_at_idx (dyn,
   1870                                 mhd_HPACK_STBL_LAST_IDX + 1u,
   1871                                 MHDTL_H04N, MHDTL_H04V);
   1872   mhdtl_dyn_check_entry_at_idx (dyn,
   1873                                 mhd_HPACK_STBL_LAST_IDX + 2u,
   1874                                 MHDTL_H03N, MHDTL_H03V);
   1875   mhdtl_dyn_check_entry_at_idx (dyn,
   1876                                 mhd_HPACK_STBL_LAST_IDX + 3u,
   1877                                 MHDTL_H02N, MHDTL_H02V);
   1878 
   1879   mhdtl_dyn_check_get_valid_invalid (dyn);
   1880 
   1881   mhd_dtbl_evict_to_size (dyn, 76u + 1u); /* Only last entry should be left */
   1882   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 76u);
   1883   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 1u);
   1884 
   1885   mhdtl_dyn_check_entry_at_idx (dyn,
   1886                                 mhd_HPACK_STBL_LAST_IDX + 1u,
   1887                                 MHDTL_H04N, MHDTL_H04V);
   1888 
   1889   mhdtl_dyn_check_get_valid_invalid (dyn);
   1890 
   1891   mhd_dtbl_evict_to_size (dyn, 76u - 1u); /* Everything should be evicted */
   1892   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 0u);
   1893   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u);
   1894 
   1895   mhdtl_dyn_check_get_valid_invalid (dyn);
   1896 
   1897 #undef MHDTL_H01N
   1898 #undef MHDTL_H01V
   1899 #undef MHDTL_H02N
   1900 #undef MHDTL_H02V
   1901 #undef MHDTL_H03N
   1902 #undef MHDTL_H03V
   1903 #undef MHDTL_H04N
   1904 #undef MHDTL_H04V
   1905 
   1906   mhd_dtbl_destroy (dyn);
   1907 
   1908   return MHDT_TEST_RESULT ();
   1909 }
   1910 
   1911 
   1912 static int
   1913 test_dyn_resize (void)
   1914 {
   1915   struct mhd_HpackDTblContext*dyn;
   1916 
   1917   /* zero-sized table */
   1918   MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (321u), \
   1919                              "Create HPACK dynamic table");
   1920   if (NULL == dyn)
   1921     return MHDT_TEST_RESULT ();
   1922 
   1923   mhdtl_dyn_add_hdr_with_check (dyn, "a", "b");
   1924   mhdtl_dyn_add_sized_entry_with_check (dyn, 150u);
   1925   mhdtl_dyn_add_hdr_with_check (dyn, "c", "d");
   1926   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u);
   1927   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 218u);
   1928 
   1929   /* Resize table (should be no eviction) */
   1930   MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 230u), "resize of the table");
   1931   MHDT_EXPECT_PTR_NONNULL (dyn);
   1932   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 230u);
   1933   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u);
   1934   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 218u);
   1935   mhdtl_dyn_check_entry_at_idx (dyn,
   1936                                 mhd_HPACK_STBL_LAST_IDX + 3u,
   1937                                 "a",
   1938                                 "b");
   1939   mhdtl_dyn_check_entry_at_idx (dyn,
   1940                                 mhd_HPACK_STBL_LAST_IDX + 1u,
   1941                                 "c",
   1942                                 "d");
   1943 
   1944   /* Resize table (should be still no eviction) */
   1945   MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 218u), "resize of the table");
   1946   MHDT_EXPECT_PTR_NONNULL (dyn);
   1947   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 218u);
   1948   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u);
   1949   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 218u);
   1950   mhdtl_dyn_check_entry_at_idx (dyn,
   1951                                 mhd_HPACK_STBL_LAST_IDX + 3u,
   1952                                 "a",
   1953                                 "b");
   1954   mhdtl_dyn_check_entry_at_idx (dyn,
   1955                                 mhd_HPACK_STBL_LAST_IDX + 1u,
   1956                                 "c",
   1957                                 "d");
   1958 
   1959   /* Resize table (oldest entry should be evicted) */
   1960   MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 217u), "resize of the table");
   1961   MHDT_EXPECT_PTR_NONNULL (dyn);
   1962   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 217u);
   1963   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u);
   1964   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 184u);
   1965   mhdtl_dyn_add_hdr_with_check (dyn, "x", "");
   1966   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u);
   1967   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 217u);
   1968   mhdtl_dyn_check_entry_at_idx (dyn,
   1969                                 mhd_HPACK_STBL_LAST_IDX + 1u,
   1970                                 "x",
   1971                                 "");
   1972 
   1973   /* Resize table (all entries except the newest should be evicted) */
   1974   MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 33u), "resize of the table");
   1975   MHDT_EXPECT_PTR_NONNULL (dyn);
   1976   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 33u);
   1977   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 1u);
   1978   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 33u);
   1979   mhdtl_dyn_check_entry_at_idx (dyn,
   1980                                 mhd_HPACK_STBL_LAST_IDX + 1u,
   1981                                 "x",
   1982                                 "");
   1983 
   1984   /* Resize table (grow, no eviction) */
   1985   MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 501u), "resize of the table");
   1986   MHDT_EXPECT_PTR_NONNULL (dyn);
   1987   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 501u);
   1988   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 1u);
   1989   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 33u);
   1990   mhdtl_dyn_add_sized_entry_with_check (dyn, 468u);
   1991   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u);
   1992   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 501u);
   1993   mhdtl_dyn_check_entry_at_idx (dyn,
   1994                                 mhd_HPACK_STBL_LAST_IDX + 2u,
   1995                                 "x",
   1996                                 "");
   1997 
   1998   mhd_dtbl_destroy (dyn);
   1999 
   2000   return MHDT_TEST_RESULT ();
   2001 }
   2002 
   2003 
   2004 static int
   2005 test_dyn_find (void)
   2006 {
   2007   static const char *hdr1_name = "first-hdr";
   2008   static const char *hdr1_val = "first value";
   2009   static const char *hdr2_name = "second-hdr";
   2010   static const char *hdr2_val = "second value";
   2011   static const char *hdr3_name = "third-hdr";
   2012   static const char *hdr3_val = "third value";
   2013   static const char *hdr4_name = "fourth-hdr";
   2014   static const char *hdr4_val = "fourth value";
   2015   struct mhd_HpackDTblContext*dyn;
   2016 
   2017   MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (256u), \
   2018                              "Create HPACK dynamic table");
   2019   if (NULL == dyn)
   2020     return MHDT_TEST_RESULT ();
   2021 
   2022   mhdtl_dyn_add_hdr_with_check (dyn, hdr1_name, hdr1_val);
   2023   mhdtl_dyn_add_hdr_with_check (dyn, hdr2_name, hdr2_val);
   2024   mhdtl_dyn_add_hdr_with_check (dyn, hdr3_name, hdr3_val);
   2025   mhdtl_dyn_add_hdr_with_check (dyn, hdr4_name, hdr4_val);
   2026 
   2027   mhdtl_dyn_check_entry_at_idx (dyn,
   2028                                 mhd_HPACK_STBL_LAST_IDX + 4u,
   2029                                 hdr1_name, hdr1_val);
   2030   mhdtl_dyn_check_entry_at_idx (dyn,
   2031                                 mhd_HPACK_STBL_LAST_IDX + 3u,
   2032                                 hdr2_name, hdr2_val);
   2033   mhdtl_dyn_check_entry_at_idx (dyn,
   2034                                 mhd_HPACK_STBL_LAST_IDX + 2u,
   2035                                 hdr3_name, hdr3_val);
   2036   mhdtl_dyn_check_entry_at_idx (dyn,
   2037                                 mhd_HPACK_STBL_LAST_IDX + 1u,
   2038                                 hdr4_name, hdr4_val);
   2039 
   2040   mhd_dtbl_destroy (dyn);
   2041 
   2042   return MHDT_TEST_RESULT ();
   2043 }
   2044 
   2045 
   2046 static int
   2047 test_dyn_reset_on_too_large (void)
   2048 {
   2049   static const size_t tbl_size = 133u; /* not a power of two */
   2050   struct mhd_HpackDTblContext*dyn;
   2051 
   2052   MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (tbl_size), \
   2053                              "Create HPACK dynamic table");
   2054   if (NULL == dyn)
   2055     return MHDT_TEST_RESULT ();
   2056 
   2057   /* Add small entries */
   2058   mhdtl_dyn_add_hdr_with_check (dyn, "a", "b");
   2059   mhdtl_dyn_add_hdr_with_check (dyn, "c", "d");
   2060   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u);
   2061 
   2062   mhdtl_dyn_add_sized_entry_with_check (dyn, tbl_size + 1);
   2063   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u);
   2064 
   2065   /* Re-add small entries */
   2066   mhdtl_dyn_add_hdr_with_check (dyn, "a", "b");
   2067   mhdtl_dyn_add_hdr_with_check (dyn, "c", "d");
   2068   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u);
   2069 
   2070   mhdtl_dyn_add_sized_entry_with_check (dyn, tbl_size);
   2071   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 1u);
   2072 
   2073   if (1)
   2074   {
   2075     struct mhd_BufferConst check_name;
   2076     struct mhd_BufferConst check_value;
   2077 
   2078     if (MHDT_EXPECT_TRUE (mhd_dtbl_get_entry (dyn, \
   2079                                               mhd_HPACK_STBL_LAST_IDX + 1u, \
   2080                                               &check_name,
   2081                                               &check_value)))
   2082     {
   2083       MHDT_EXPECT_UINT_GT_VAL (check_name.size, 1u);
   2084       MHDT_EXPECT_UINT_GT_VAL (check_value.size, 1u);
   2085     }
   2086   }
   2087 
   2088   mhd_dtbl_destroy (dyn);
   2089 
   2090   return MHDT_TEST_RESULT ();
   2091 }
   2092 
   2093 
   2094 static int
   2095 test_dyn_zero_sizes (void)
   2096 {
   2097   struct mhd_HpackDTblContext*dyn;
   2098 
   2099   /* zero-sized table */
   2100   MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (0u), \
   2101                              "Create HPACK dynamic table");
   2102   if (NULL == dyn)
   2103     return MHDT_TEST_RESULT ();
   2104 
   2105   mhdtl_dyn_add_hdr_with_check (dyn, "a", "b");
   2106   mhdtl_dyn_add_hdr_with_check (dyn, "c", "d");
   2107   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u);
   2108   /* smallest entry (zero-sized strings) */
   2109   mhdtl_dyn_add_sized_strs_with_check (dyn, 0u);
   2110   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u);
   2111 
   2112   /* Resize table to the same zero size */
   2113   MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 0u), \
   2114                       "resize of the table");
   2115   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 0u);
   2116   /* smallest entry (zero-sized strings) */
   2117   mhdtl_dyn_add_sized_strs_with_check (dyn, 0u);
   2118   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u);
   2119 
   2120   /* Resize table to non-zero size */
   2121   MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 127u), \
   2122                       "resize of the table");
   2123   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 127u);
   2124 
   2125   mhdtl_dyn_add_hdr_with_check (dyn, "a", "b");
   2126   mhdtl_dyn_add_hdr_with_check (dyn, "c", "d");
   2127   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u);
   2128 
   2129   mhd_dtbl_evict_to_size (dyn, 0u);
   2130   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u);
   2131 
   2132   mhdtl_dyn_add_hdr_with_check (dyn, "a", "b");
   2133   mhdtl_dyn_add_hdr_with_check (dyn, "c", "d");
   2134   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u);
   2135 
   2136   mhdtl_dyn_add_sized_entry_with_check (dyn, 45u);
   2137   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u);
   2138   mhdtl_dyn_check_entry_at_idx (dyn,
   2139                                 mhd_HPACK_STBL_LAST_IDX + 3u,
   2140                                 "a",
   2141                                 "b");
   2142   mhdtl_dyn_check_entry_at_idx (dyn,
   2143                                 mhd_HPACK_STBL_LAST_IDX + 2u,
   2144                                 "c",
   2145                                 "d");
   2146 
   2147   /* smallest entries (zero-sized strings) */
   2148   mhdtl_dyn_add_hdr_with_check (dyn, "", "");
   2149   mhdtl_dyn_add_hdr_with_check (dyn, "", "");
   2150   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u);
   2151   mhdtl_dyn_check_entry_at_idx (dyn,
   2152                                 mhd_HPACK_STBL_LAST_IDX + 1u,
   2153                                 "",
   2154                                 "");
   2155   mhdtl_dyn_check_entry_at_idx (dyn,
   2156                                 mhd_HPACK_STBL_LAST_IDX + 2u,
   2157                                 "",
   2158                                 "");
   2159 
   2160   /* Resize table to zero size again */
   2161   MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 0u), \
   2162                       "resize of the table");
   2163   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 0u);
   2164   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u);
   2165   mhd_dtbl_evict_to_size (dyn, 0u);
   2166   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 0u);
   2167   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u);
   2168 
   2169   mhdtl_dyn_add_hdr_with_check (dyn, "a", "b");
   2170   mhdtl_dyn_add_hdr_with_check (dyn, "c", "d");
   2171   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u);
   2172   mhdtl_dyn_add_sized_strs_with_check (dyn, 0u);
   2173   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u);
   2174 
   2175   /* Resize table to the size smaller than minimal entry size */
   2176   MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 31u), \
   2177                       "resize of the table");
   2178   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u);
   2179   mhdtl_dyn_add_hdr_with_check (dyn, "a", "b");
   2180   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u);
   2181   mhdtl_dyn_add_sized_strs_with_check (dyn, 0u);
   2182   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u);
   2183 
   2184   /* Resize table to the minimal size */
   2185   MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 32u), \
   2186                       "resize of the table");
   2187   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 32u);
   2188   mhdtl_dyn_add_sized_strs_with_check (dyn, 0u);
   2189   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 1u);
   2190   /* Resize table back to the size smaller than minimal entry size */
   2191   MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 31u), \
   2192                       "resize of the table");
   2193   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 31u);
   2194   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u);
   2195   mhdtl_dyn_add_sized_strs_with_check (dyn, 0u);
   2196   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u);
   2197   MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 0u), \
   2198                       "resize of the table");
   2199   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 0u);
   2200   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u);
   2201 
   2202   /* Resize table to the usable size */
   2203   MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 128u), \
   2204                       "resize of the table");
   2205   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 128u);
   2206   mhdtl_dyn_add_sized_strs_with_check (dyn, 0u);
   2207   mhdtl_dyn_add_sized_strs_with_check (dyn, 0u);
   2208   mhdtl_dyn_add_sized_strs_with_check (dyn, 0u);
   2209   mhdtl_dyn_add_sized_strs_with_check (dyn, 0u);
   2210   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 4u);
   2211   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 128u);
   2212   mhdtl_dyn_add_hdr_with_check (dyn, "a", "1");
   2213   mhdtl_dyn_add_hdr_with_check (dyn, "b", "2");
   2214   mhdtl_dyn_add_hdr_with_check (dyn, "c", "3");
   2215   mhdtl_dyn_add_hdr_with_check (dyn, "d", "4");
   2216   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u);
   2217   MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 102u);
   2218   mhdtl_dyn_check_entry_at_idx (dyn,
   2219                                 mhd_HPACK_STBL_LAST_IDX + 3u,
   2220                                 "b",
   2221                                 "2");
   2222   /* Resize table to zero size again */
   2223   MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 0u), \
   2224                       "resize of the table");
   2225   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 0u);
   2226   MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u);
   2227 
   2228   mhd_dtbl_destroy (dyn);
   2229 
   2230   return MHDT_TEST_RESULT ();
   2231 }
   2232 
   2233 
   2234 static int
   2235 test_stat_get_find (void)
   2236 {
   2237   mhdtl_stat_check_entry_at_idx (1u,
   2238                                  ":authority",
   2239                                  "");
   2240   mhdtl_stat_check_entry_at_idx (5u,
   2241                                  ":path",
   2242                                  "/index.html");
   2243   mhdtl_stat_check_entry_at_idx (14u,
   2244                                  ":status",
   2245                                  "500");
   2246   mhdtl_stat_check_entry_at_idx (15u,
   2247                                  "accept-charset",
   2248                                  "");
   2249   mhdtl_stat_check_entry_at_idx (16u,
   2250                                  "accept-encoding",
   2251                                  "gzip, deflate");
   2252   mhdtl_stat_check_entry_at_idx (17u,
   2253                                  "accept-language",
   2254                                  "");
   2255   mhdtl_stat_check_entry_at_idx (31u,
   2256                                  "content-type",
   2257                                  "");
   2258   mhdtl_stat_check_entry_at_idx (42u,
   2259                                  "if-range",
   2260                                  "");
   2261   mhdtl_stat_check_entry_at_idx (47u,
   2262                                  "max-forwards",
   2263                                  "");
   2264   mhdtl_stat_check_entry_at_idx (51u,
   2265                                  "referer",
   2266                                  "");
   2267   mhdtl_stat_check_entry_at_idx (58u,
   2268                                  "user-agent",
   2269                                  "");
   2270   mhdtl_stat_check_entry_at_idx (61u,
   2271                                  "www-authenticate",
   2272                                  "");
   2273 
   2274   return MHDT_TEST_RESULT ();
   2275 }
   2276 
   2277 
   2278 static int
   2279 test_stat_find_non_pseudo_entry_absent (void)
   2280 {
   2281   MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_STBL_FIND_ENTRY_REAL_STR ("foo","bar"), \
   2282                              0u, \
   2283                              "search for non-existing header should fail");
   2284   MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_STBL_FIND_ENTRY_REAL_STR ("foo",""), \
   2285                              0u, \
   2286                              "search for non-existing header should fail");
   2287   MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_STBL_FIND_ENTRY_REAL_STR ("","bar"), \
   2288                              0u, \
   2289                              "search for non-existing header should fail");
   2290   MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_STBL_FIND_ENTRY_REAL_STR ("",""), \
   2291                              0u, \
   2292                              "search for non-existing header should fail");
   2293   MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_STBL_FIND_ENTRY_REAL_STR (":foo",""), \
   2294                              0u, \
   2295                              "search for non-existing header should fail");
   2296   MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_STBL_FIND_ENTRY_REAL_STR (":authority",""), \
   2297                              0u, \
   2298                              "search for pseudo-header should fail");
   2299   MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_STBL_FIND_ENTRY_REAL_STR (":status", \
   2300                                                              "200"), \
   2301                              0u, \
   2302                              "search for pseudo-header should fail");
   2303 
   2304   return MHDT_TEST_RESULT_D ("search for non-existing non-pseudo headers");
   2305 }
   2306 
   2307 
   2308 static int
   2309 test_stat_find_non_pseudo_name_absent (void)
   2310 {
   2311   MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_STBL_FIND_NAME_REAL_STR ("foo"), \
   2312                              0u, \
   2313                              "search for non-existing header should fail");
   2314   MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_STBL_FIND_NAME_REAL_STR (""), \
   2315                              0u, \
   2316                              "search for non-existing header should fail");
   2317   MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_STBL_FIND_NAME_REAL_STR (":foo"), \
   2318                              0u, \
   2319                              "search for non-existing header should fail");
   2320   MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_STBL_FIND_NAME_REAL_STR (":authority"), \
   2321                              0u, \
   2322                              "search for pseudo-header should fail");
   2323   MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_STBL_FIND_NAME_REAL_STR (":status"), \
   2324                              0u, \
   2325                              "search for pseudo-header should fail");
   2326 
   2327   return MHDT_TEST_RESULT_D ("search for non-existing non-pseudo names");
   2328 }
   2329 
   2330 
   2331 static int
   2332 test_comb_get_find (void)
   2333 {
   2334   struct mhd_HpackDTblContext *dyn;
   2335 
   2336   /* zero-sized table */
   2337   MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (456u), \
   2338                              "Create HPACK dynamic table");
   2339   if (NULL == dyn)
   2340     return MHDT_TEST_RESULT ();
   2341 
   2342   mhdtl_dyn_add_hdr_with_check (dyn, "abc", "xyz");
   2343   mhdtl_dyn_add_hdr_with_check (dyn, "", "empty-name");
   2344   mhdtl_dyn_add_hdr_with_check (dyn, "empty-value", "");
   2345   mhdtl_dyn_add_hdr_with_check (dyn, "", "");
   2346   mhdtl_dyn_add_hdr_with_check (dyn, "2", "two");
   2347 
   2348   mhdtl_comb_check_entry_at_idx (dyn,
   2349                                  1u,
   2350                                  ":authority",
   2351                                  "");
   2352   mhdtl_comb_check_entry_at_idx (dyn,
   2353                                  5u,
   2354                                  ":path",
   2355                                  "/index.html");
   2356   mhdtl_comb_check_entry_at_idx (dyn,
   2357                                  16u,
   2358                                  "accept-encoding",
   2359                                  "gzip, deflate");
   2360   mhdtl_comb_check_entry_at_idx (dyn,
   2361                                  17u,
   2362                                  "accept-language",
   2363                                  "");
   2364   mhdtl_comb_check_entry_at_idx (dyn,
   2365                                  42u,
   2366                                  "if-range",
   2367                                  "");
   2368   mhdtl_comb_check_entry_at_idx (dyn,
   2369                                  61u,
   2370                                  "www-authenticate",
   2371                                  "");
   2372   mhdtl_comb_check_entry_at_idx (dyn,
   2373                                  62u,
   2374                                  "2",
   2375                                  "two");
   2376   mhdtl_comb_check_entry_at_idx (dyn,
   2377                                  63u,
   2378                                  "",
   2379                                  "");
   2380   mhdtl_comb_check_entry_at_idx (dyn,
   2381                                  64u,
   2382                                  "empty-value",
   2383                                  "");
   2384   mhdtl_comb_check_entry_at_idx (dyn,
   2385                                  65u,
   2386                                  "",
   2387                                  "empty-name");
   2388   mhdtl_comb_check_entry_at_idx (dyn,
   2389                                  66u,
   2390                                  "abc",
   2391                                  "xyz");
   2392 
   2393   mhd_dtbl_destroy (dyn);
   2394 
   2395   return MHDT_TEST_RESULT ();
   2396 }
   2397 
   2398 
   2399 static int
   2400 test_comb_find_entry_absent (void)
   2401 {
   2402   struct mhd_HpackDTblContext *dyn;
   2403 
   2404   /* zero-sized table */
   2405   MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (456u), \
   2406                              "Create HPACK dynamic table");
   2407   if (NULL == dyn)
   2408     return MHDT_TEST_RESULT ();
   2409 
   2410   mhdtl_dyn_add_hdr_with_check (dyn, "", "");
   2411   mhdtl_dyn_add_hdr_with_check (dyn, "hdr1", "value1");
   2412   mhdtl_dyn_add_hdr_with_check (dyn, "", "empty-name");
   2413   mhdtl_dyn_add_hdr_with_check (dyn, "hdr2", "value2");
   2414   mhdtl_dyn_add_hdr_with_check (dyn, "empty-value", "");
   2415 
   2416   MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_HTBL_FIND_ENTRY_REAL_STR (dyn, "foo","bar"), \
   2417                              0u, \
   2418                              "search for non-existing header should fail");
   2419   MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_HTBL_FIND_ENTRY_REAL_STR (dyn, "foo",""), \
   2420                              0u, \
   2421                              "search for non-existing header should fail");
   2422   MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_HTBL_FIND_ENTRY_REAL_STR (dyn, "","bar"), \
   2423                              0u, \
   2424                              "search for non-existing header should fail");
   2425   MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_HTBL_FIND_ENTRY_REAL_STR (dyn, ":foo",""), \
   2426                              0u, \
   2427                              "search for non-existing header should fail");
   2428   MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_HTBL_FIND_ENTRY_REAL_STR (dyn, \
   2429                                                              ":authority",""), \
   2430                              0u, \
   2431                              "search for pseudo-header should fail");
   2432   MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_HTBL_FIND_ENTRY_REAL_STR (dyn, ":status", \
   2433                                                              "200"), \
   2434                              0u, \
   2435                              "search for pseudo-header should fail");
   2436 
   2437   mhdtl_comb_check_entry_at_idx (dyn, mhd_HPACK_STBL_LAST_IDX + 5u,
   2438                                  "",
   2439                                  "");
   2440   mhdtl_comb_check_entry_at_idx (dyn, mhd_HPACK_STBL_LAST_IDX + 1u,
   2441                                  "empty-value",
   2442                                  "");
   2443 
   2444   mhd_dtbl_destroy (dyn);
   2445 
   2446   return MHDT_TEST_RESULT ();
   2447 }
   2448 
   2449 
   2450 static int
   2451 test_comb_find_name_absent (void)
   2452 {
   2453   struct mhd_HpackDTblContext *dyn;
   2454 
   2455   /* zero-sized table */
   2456   MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (456u), \
   2457                              "Create HPACK dynamic table");
   2458   if (NULL == dyn)
   2459     return MHDT_TEST_RESULT ();
   2460 
   2461   mhdtl_dyn_add_hdr_with_check (dyn, "hdr1", "value1");
   2462   mhdtl_dyn_add_hdr_with_check (dyn, "hdr2", "value2");
   2463   mhdtl_dyn_add_hdr_with_check (dyn, "empty-value", "");
   2464   mhdtl_dyn_add_hdr_with_check (dyn, "", "empty-name");
   2465   mhdtl_dyn_add_hdr_with_check (dyn, "", "");
   2466 
   2467   MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_HTBL_FIND_NAME_REAL_STR (dyn, "foo"), \
   2468                              0u, \
   2469                              "search for non-existing header should fail");
   2470   MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_HTBL_FIND_NAME_REAL_STR (dyn, ":foo"), \
   2471                              0u, \
   2472                              "search for non-existing header should fail");
   2473   MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_HTBL_FIND_NAME_REAL_STR (dyn, ":authority"), \
   2474                              0u, \
   2475                              "search for pseudo-header should fail");
   2476   MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_HTBL_FIND_NAME_REAL_STR (dyn, ":status"), \
   2477                              0u, \
   2478                              "search for pseudo-header should fail");
   2479 
   2480   mhdtl_comb_check_entry_at_idx (dyn,
   2481                                  mhd_HPACK_STBL_LAST_IDX + 1u,
   2482                                  "",
   2483                                  "");
   2484   mhdtl_comb_check_entry_at_idx (dyn,
   2485                                  mhd_HPACK_STBL_LAST_IDX + 5u,
   2486                                  "hdr1",
   2487                                  "value1");
   2488 
   2489   mhd_dtbl_destroy (dyn);
   2490 
   2491   return MHDT_TEST_RESULT ();
   2492 }
   2493 
   2494 
   2495 int
   2496 main (int argc,
   2497       char *const *argv)
   2498 {
   2499   if (argc < 1)
   2500     return 99;
   2501 
   2502   if (mhdt_has_param (argc, argv, "-v") ||
   2503       mhdt_has_param (argc, argv, "--verbose"))
   2504     MHDT_set_verbosity (MHDT_VERB_LVL_VERBOSE);
   2505   else if (mhdt_has_param (argc, argv, "-s") ||
   2506            mhdt_has_param (argc, argv, "--silent"))
   2507     MHDT_set_verbosity (MHDT_VERB_LVL_SILENT);
   2508 
   2509   if (! mhdtl_enable_deep_tests)
   2510     mhdtl_enable_deep_tests = mhdt_has_param (argc, argv, "--deep");
   2511 
   2512   if (mhdt_has_in_name (argv[0], "_dynamic"))
   2513   {
   2514     test_dyn_create_destroy ();
   2515     test_dyn_create_destroy_larger ();
   2516     test_dyn_add_three ();
   2517     test_dyn_add_empty ();
   2518     test_dyn_add_evict_simple ();
   2519     test_dyn_add_evict_wrap ();
   2520     test_dyn_add_evict_inter ();
   2521     test_dyn_evict_to_size ();
   2522     test_dyn_resize ();
   2523     test_dyn_find ();
   2524     test_dyn_reset_on_too_large ();
   2525     test_dyn_zero_sizes ();
   2526     test_dyn_add_series ();
   2527     test_dyn_add_evict_series ();
   2528   }
   2529   else if (mhdt_has_in_name (argv[0], "_static"))
   2530   {
   2531     test_stat_get_find ();
   2532     test_stat_find_non_pseudo_entry_absent ();
   2533     test_stat_find_non_pseudo_name_absent ();
   2534   }
   2535   else if (mhdt_has_in_name (argv[0], "_combined"))
   2536   {
   2537     test_comb_get_find ();
   2538     test_comb_find_entry_absent ();
   2539     test_comb_find_name_absent ();
   2540   }
   2541   else
   2542     MHDT_ERR_EXIT_D ("The test subtype marker string was not found in " \
   2543                      "the name of this binary");
   2544 
   2545   return MHDT_FINAL_RESULT (argv[0]);
   2546 }