+static void
+sparse_size_coder (struct tar_stat_info const *st, char const *keyword,
+ struct xheader *xhdr, void *data)
+{
+ size_coder (st, keyword, xhdr, data);
+}
+
+static void
+sparse_size_decoder (struct tar_stat_info *st, char const *arg)
+{
+ uintmax_t u;
+ if (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK)
+ st->archive_file_size = u;
+}
+
+static void
+sparse_numblocks_coder (struct tar_stat_info const *st, char const *keyword,
+ struct xheader *xhdr, void *data)
+{
+ code_num (st->sparse_map_avail, keyword, xhdr);
+}
+
+static void
+sparse_numblocks_decoder (struct tar_stat_info *st, char const *arg)
+{
+ uintmax_t u;
+ if (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK)
+ {
+ st->sparse_map_size = u;
+ st->sparse_map = calloc(st->sparse_map_size, sizeof(st->sparse_map[0]));
+ st->sparse_map_avail = 0;
+ }
+}
+
+static void
+sparse_offset_coder (struct tar_stat_info const *st, char const *keyword,
+ struct xheader *xhdr, void *data)
+{
+ size_t i = *(size_t*)data;
+ code_num (st->sparse_map[i].offset, keyword, xhdr);
+}
+
+static void
+sparse_offset_decoder (struct tar_stat_info *st, char const *arg)
+{
+ uintmax_t u;
+ if (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK)
+ st->sparse_map[st->sparse_map_avail].offset = u;
+}
+
+static void
+sparse_numbytes_coder (struct tar_stat_info const *st, char const *keyword,
+ struct xheader *xhdr, void *data)
+{
+ size_t i = *(size_t*)data;
+ code_num (st->sparse_map[i].numbytes, keyword, xhdr);
+}
+
+static void
+sparse_numbytes_decoder (struct tar_stat_info *st, char const *arg)
+{
+ uintmax_t u;
+ if (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK)
+ {
+ if (st->sparse_map_avail == st->sparse_map_size)
+ {
+ size_t newsize = st->sparse_map_size *= 2;
+ st->sparse_map = xrealloc (st->sparse_map,
+ st->sparse_map_size
+ * sizeof st->sparse_map[0]);
+ }
+ st->sparse_map[st->sparse_map_avail++].numbytes = u;
+ }
+}
+
+struct xhdr_tab const xhdr_tab[] = {