/******************** * 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; }
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); }