How to add the support of the get_next_object() callback to the 5-c_stats example?

I have been wanting to provide a tag value array variant to this post for a while now as I belive it is more easy to follow than a plain value array. It does the same thing but use the tag too. The memory and performance overhead of using tag_value instead of value is negligible here, while the advantage is slightly improved readability:

// NOTE: See the original post for the other changes needed to the original (here ConfD-6.7.1) arpstat.c file 
...
static int navals;
static int max_nobjs = 100; // Chunk size hardcoded here to simplify

static int get_next_object_tag(struct confd_trans_ctx *tctx,
			     confd_hkeypath_t *keypath, long next)
{
  int i;
  confd_tag_value_t *tv;
  struct confd_tag_next_object *tobj;
  struct arpdata *dp = tctx->t_opaque;
  struct aentry *curr;

  if (next == -1) {  /* first call */
    if (need_arp(dp)) {
      if (run_arp(dp) == CONFD_ERR)
	return CONFD_ERR;
    }
    curr = dp->arp_entries;
  } else {
    curr = (struct aentry *)next;
  }
  if (curr == NULL) {
    confd_data_reply_next_key(tctx, NULL, -1, -1);
    return CONFD_OK;
  }

  tobj = malloc(sizeof(struct confd_tag_next_object) * (max_nobjs + 1));
  tv = (confd_tag_value_t *) malloc(sizeof(confd_tag_value_t) * max_nobjs * navals);
  
  for (i = 0; curr != NULL && i < max_nobjs; curr = curr->next, i++) { /* Collect max_nobjs or as many as there is rows in the table / list entries */
    tobj[i].tv = &tv[i * navals];

    CONFD_SET_TAG_IPV4(&(tobj[i].tv[0]), arpe_ip, curr->ip4);
    CONFD_SET_TAG_STR(&(tobj[i].tv[1]), arpe_ifname, curr->iface);
    if (curr->hwaddr == NULL) {
      CONFD_SET_TAG_NOEXISTS(&(tobj[i].tv[2]), arpe_hwaddr);
    } else {
      CONFD_SET_TAG_STR(&(tobj[i].tv[2]), arpe_hwaddr, curr->hwaddr);
    }
    CONFD_SET_TAG_BOOL(&(tobj[i].tv[3]), arpe_permanent, curr->perm);
    CONFD_SET_TAG_BOOL(&(tobj[i].tv[4]), arpe_published, curr->pub);
    tobj[i].n = navals;
    tobj[i].next = (long)curr->next;
  }
  
  if (curr == NULL) {
    tobj[i++].tv = NULL;
  }
  
  confd_data_reply_next_object_tag_value_arrays(tctx, tobj, i, 0); /* Reply with an array of object arrays. I.e. the whole table / list */
  free(tv);
  free(tobj);
  return CONFD_OK;
}

int main(int argc, char *argv[])
{
...
    data.get_next_object = get_next_object_tag;
...
    if (confd_load_schemas((struct sockaddr*)&addr,
                           sizeof (struct sockaddr_in)) != CONFD_OK)
        confd_fatal("Failed to load schemas from confd\n");

    object = confd_cs_node_cd(NULL, "/arpe:arpentries/arpe");
    navals = confd_max_object_size(object);
...
}