/********************
 * get_field_names
 ********************/
static int
get_field_names(context_t *ctx, term_t pl_fields)
{
#define MAX_LENGTH 64                           /* max length of a field name */

    term_t  pl_list, pl_head;
    int     i, n, left, size;
    size_t  dummy;
    char   *p, *field;
    

    if ((n = list_length(pl_fields)) < 0)
        return EINVAL;

    size = n * sizeof(ctx->fields[0]) + n * MAX_LENGTH;
    if ((ctx->fields = malloc(size)) == NULL)
        return ENOMEM;
    memset(ctx->fields, 0, size);
    ctx->nfield = n;

    p    = ((char *)ctx->fields) + n * sizeof(ctx->fields[0]);
    left = size - n * sizeof(ctx->fields[0]);

    pl_list = PL_copy_term_ref(pl_fields);      /* XXX is this really needed? */
    pl_head = PL_new_term_ref();
    for (i = 0; i < n && PL_get_list(pl_list, pl_head, pl_list); i++) {
        switch (PL_term_type(pl_head)) {
        case PL_ATOM:
            if (!PL_get_atom_chars(pl_head, &field))
                goto fail;
            break;
        case PL_STRING:
            if (!PL_get_string_chars(pl_head, &field, &dummy))
                goto fail;
            break;
        default:
            goto fail;
        }
        ctx->fields[i] = p;
        size = snprintf(p, left, "%s", field);
        if (size + 1 > left)
            goto fail;
        p    += size + 1;
        left -= size + 1;
    }
    
    return 0;
    
 fail:
    if (ctx->fields != NULL) {
        free(ctx->fields);
        ctx->fields = NULL;
    }
    return EINVAL;
}
示例#2
0
static foreign_t
pl_sha_hash_ctx(term_t old_ctx, term_t from, term_t new_ctx, term_t hash)
{ char *data;
  size_t datalen;
  struct context *cp;
  size_t clen;
  unsigned char hval[SHA2_MAX_DIGEST_SIZE];

  if ( !PL_get_nchars(from, &datalen, &data,
		      CVT_ATOM|CVT_STRING|CVT_LIST|CVT_EXCEPTION) )
    return FALSE;

  if ( !PL_get_string_chars(old_ctx, (char **)&cp, &clen) )
    return FALSE;

  if ( clen != sizeof (*cp)
       || cp->magic != CONTEXT_MAGIC ) {
    return pl_error(NULL, 0, "Invalid OldContext passed",
		    ERR_DOMAIN, old_ctx, "algorithm");
  }

  if ( cp->opts.algorithm == ALGORITHM_SHA1 )
  { sha1_ctx *c1p = &(cp->context.sha1);
    sha1_hash((unsigned char*)data, (unsigned long)datalen, c1p);
    if ( !PL_unify_string_nchars(new_ctx, sizeof(*cp), (char*)cp) )
      return FALSE;
    sha1_end((unsigned char *)hval, c1p);
  } else
  { sha2_ctx *c1p = &(cp->context.sha2);
    sha2_hash((unsigned char*)data, (unsigned long)datalen, c1p);
    if ( !PL_unify_string_nchars(new_ctx, sizeof(*cp), (char*)cp) )
      return FALSE;
    sha2_end((unsigned char *)hval, c1p);
  }

  /* . */
  return PL_unify_list_ncodes(hash, cp->opts.digest_size, (char*)hval);
}