int NaClDescConnCapCtor(struct NaClDescConnCap          *self,
                        struct NaClSocketAddress const  *nsap) {
  struct NaClDesc *basep = (struct NaClDesc *) self;
  int rv;

  basep->base.vtbl = (struct NaClRefCountVtbl const *) NULL;
  if (!NaClDescCtor(basep)) {
    return 0;
  }
  rv = NaClDescConnCapSubclassCtor(self, nsap);
  if (!rv) {
    /* NaClDescConnCap construction failed, still a NaClDesc object */
    (*NACL_VTBL(NaClRefCount, basep)->Dtor)((struct NaClRefCount *) basep);
    /* not-an-object; caller frees */
  }
  return rv;
}
int NaClDescConnCapInternalize(struct NaClDesc               **out_desc,
                               struct NaClDescXferState      *xfer,
                               struct NaClDescQuotaInterface *quota_interface) {
  int                       rv;
  struct NaClSocketAddress  nsa;
  struct NaClDescConnCap    *ndccp;

  UNREFERENCED_PARAMETER(quota_interface);
  rv = -NACL_ABI_EIO;  /* catch-all */

  ndccp = malloc(sizeof *ndccp);
  if (NULL == ndccp) {
    rv = -NACL_ABI_ENOMEM;
    goto cleanup;
  }
  if (!NaClDescInternalizeCtor((struct NaClDesc *) ndccp, xfer)) {
    free(ndccp);
    ndccp = NULL;
    rv = -NACL_ABI_ENOMEM;
    goto cleanup;
  }
  if (xfer->next_byte + NACL_PATH_MAX > xfer->byte_buffer_end) {
    rv = -NACL_ABI_EIO;
    goto cleanup;
  }
  memcpy(nsa.path, xfer->next_byte, NACL_PATH_MAX);
  if (!NaClDescConnCapSubclassCtor(ndccp, &nsa)) {
    rv = -NACL_ABI_EIO;
    goto cleanup;
  }
  *out_desc = (struct NaClDesc *) ndccp;
  rv = 0;
  xfer->next_byte += NACL_PATH_MAX;
cleanup:
  if (rv < 0) {
    NaClDescSafeUnref((struct NaClDesc *) ndccp);
  }
  return rv;
}