Example #1
0
void git_index_clear(git_index *index)
{
	unsigned int i;

	assert(index);

	for (i = 0; i < index->entries.length; ++i) {
		git_index_entry *e;
		e = git_vector_get(&index->entries, i);
		free((char *)e->path);
		free(e);
	}

	for (i = 0; i < index->unmerged.length; ++i) {
		git_index_entry_unmerged *e;
		e = git_vector_get(&index->unmerged, i);
		free((char *)e->path);
		free(e);
	}

	git_vector_clear(&index->entries);
	git_vector_clear(&index->unmerged);
	index->last_modified = 0;

	free_tree(index->tree);
	index->tree = NULL;
}
Example #2
0
/* insert_sorted with duplicates */
void test_core_vector__4(void)
{
	git_vector x;
	intptr_t i;
	git_vector_init(&x, 1, &compare_them);

	for (i = 0; i < 10; i += 2) {
		git_vector_insert_sorted(&x, (void*)(i + 1), NULL);
	}

	for (i = 9; i > 0; i -= 2) {
		git_vector_insert_sorted(&x, (void*)(i + 1), NULL);
	}

	for (i = 0; i < 10; i += 2) {
		git_vector_insert_sorted(&x, (void*)(i + 1), NULL);
	}

	for (i = 9; i > 0; i -= 2) {
		git_vector_insert_sorted(&x, (void*)(i + 1), NULL);
	}

	cl_assert(x.length == 20);
	for (i = 0; i < 20; ++i) {
		cl_assert(git_vector_get(&x, i) == (void*)(i / 2 + 1));
	}

	git_vector_free(&x);
}
Example #3
0
static int packfile_load__cb(void *_data, char *path)
{
	struct pack_backend *backend = (struct pack_backend *)_data;
	struct git_pack_file *pack;
	int error;
	size_t i;

	if (git__suffixcmp(path, ".idx") != 0)
		return GIT_SUCCESS; /* not an index */

	for (i = 0; i < backend->packs.length; ++i) {
		struct git_pack_file *p = git_vector_get(&backend->packs, i);
		if (memcmp(p->pack_name, path, strlen(path) - strlen(".idx")) == 0)
			return GIT_SUCCESS;
	}

	error = git_packfile_check(&pack, path);
	if (error < GIT_SUCCESS)
		return git__rethrow(error, "Failed to load packfile");

	if (git_vector_insert(&backend->packs, pack) < GIT_SUCCESS) {
		free(pack);
		return GIT_ENOMEM;
	}

	return GIT_SUCCESS;
}
Example #4
0
int git_odb_read_header(git_rawobj *out, git_odb *db, const git_oid *id)
{
	unsigned int i;
	int error = GIT_ENOTFOUND;

	assert(out && db && id);

	for (i = 0; i < db->backends.length && error < 0; ++i) {
		backend_internal *internal = git_vector_get(&db->backends, i);
		git_odb_backend *b = internal->backend;

		if (b->read_header != NULL)
			error = b->read_header(out, b, id);
	}

	/*
	 * no backend could read only the header.
	 * try reading the whole object and freeing the contents
	 */
	if (error < 0) {
		error = git_odb_read(out, db, id);
		git_rawobj_close(out);
	}

	return error;
}
Example #5
0
int git_commit__writeback(git_commit *commit, git_odb_source *src)
{
	unsigned int i;

	if (commit->tree == NULL)
		return GIT_EMISSINGOBJDATA;

	git__write_oid(src, "tree", git_tree_id(commit->tree));

	for (i = 0; i < commit->parents.length; ++i) {
		git_commit *parent;

		parent = git_vector_get(&commit->parents, i);
		git__write_oid(src, "parent", git_commit_id(parent));
	}

	if (commit->author == NULL)
		return GIT_EMISSINGOBJDATA;

	git_signature__write(src, "author", commit->author);

	if (commit->committer == NULL)
		return GIT_EMISSINGOBJDATA;

	git_signature__write(src, "committer", commit->committer);

	if (commit->message != NULL)
		git__source_printf(src, "\n%s", commit->message);

	/* Mark the commit as having all attributes */
	commit->full_parse = 1;

	return GIT_SUCCESS;
}
Example #6
0
static int pack_entry_find(struct git_pack_entry *e, struct pack_backend *backend, const git_oid *oid)
{
	int error;
	size_t i;

	if ((error = packfile_refresh_all(backend)) < GIT_SUCCESS)
		return git__rethrow(error, "Failed to find pack entry");

	if (backend->last_found &&
		git_pack_entry_find(e, backend->last_found, oid, GIT_OID_HEXSZ) == GIT_SUCCESS)
		return GIT_SUCCESS;

	for (i = 0; i < backend->packs.length; ++i) {
		struct git_pack_file *p;

		p = git_vector_get(&backend->packs, i);
		if (p == backend->last_found)
			continue;

		if (git_pack_entry_find(e, p, oid, GIT_OID_HEXSZ) == GIT_SUCCESS) {
			backend->last_found = p;
			return GIT_SUCCESS;
		}
	}

	return git__throw(GIT_ENOTFOUND, "Failed to find pack entry");
}
Example #7
0
/*
 * Close the least recently used window. You should check to see if
 * the file descriptors need closing from time to time.
 */
static int git_mwindow_close_lru(git_mwindow_file *mwf)
{
	unsigned int i;
	git_mwindow *lru_w = NULL, *lru_l = NULL;

	/* FIMXE: Does this give us any advantage? */
	if(mwf->windows)
		git_mwindow_scan_lru(mwf, &lru_w, &lru_l);

	for (i = 0; i < ctl.windowfiles.length; ++i) {
		git_mwindow_scan_lru(git_vector_get(&ctl.windowfiles, i), &lru_w, &lru_l);
	}

	if (lru_w) {
		git_mwindow_close(&lru_w);
		ctl.mapped -= lru_w->window_map.len;
		git_futils_mmap_free(&lru_w->window_map);

		if (lru_l)
			lru_l->next = lru_w->next;
		else
			mwf->windows = lru_w->next;

		free(lru_w);
		ctl.open_windows--;

		return GIT_SUCCESS;
	}

	return git__throw(GIT_ERROR, "Failed to close memory window. Couln't find LRU");
}
Example #8
0
/*
 * Free all the windows in a sequence, typically because we're done
 * with the file
 */
void git_mwindow_free_all(git_mwindow_file *mwf)
{
	unsigned int i;
	/*
	 * Remove these windows from the global list
	 */
	for (i = 0; i < ctl.windowfiles.length; ++i){
		if (git_vector_get(&ctl.windowfiles, i) == mwf) {
			git_vector_remove(&ctl.windowfiles, i);
			break;
		}
	}

	if (ctl.windowfiles.length == 0) {
		git_vector_free(&ctl.windowfiles);
		ctl.windowfiles.contents = NULL;
	}

	while (mwf->windows) {
		git_mwindow *w = mwf->windows;
		assert(w->inuse_cnt == 0);

		ctl.mapped -= w->window_map.len;
		ctl.open_windows--;

		git_futils_mmap_free(&w->window_map);

		mwf->windows = w->next;
		free(w);
	}
}
Example #9
0
static int packfile_load__cb(void *data, git_buf *path)
{
	struct pack_backend *backend = (pack_backend*) data;
	struct git_pack_file *pack;
	const char *path_str = git_buf_cstr(path);
	size_t i, cmp_len = git_buf_len(path);
	int error;

	if (cmp_len <= strlen(".idx") || git__suffixcmp(path_str, ".idx") != 0)
		return 0; /* not an index */

	cmp_len -= strlen(".idx");

	for (i = 0; i < backend->packs.length; ++i) {
		struct git_pack_file *p = (git_pack_file*) git_vector_get(&backend->packs, i);

		if (memcmp(p->pack_name, path_str, cmp_len) == 0)
			return 0;
	}

	error = git_mwindow_get_pack(&pack, path->ptr);

	/* ignore missing .pack file as git does */
	if (error == GIT_ENOTFOUND) {
		giterr_clear();
		return 0;
	}

	if (!error)
		error = git_vector_insert(&backend->packs, pack);

	return error;

}
Example #10
0
/*
 * Since this is a network connection, we need to parse and store the
 * pkt-lines at this stage and keep them there.
 */
static int git_connect(git_transport *transport, int direction)
{
	transport_git *t = (transport_git *) transport;

	if (direction == GIT_DIR_PUSH) {
		giterr_set(GITERR_NET, "Pushing over git:// is not supported");
		return -1;
	}

	t->parent.direction = direction;

	/* Connect and ask for the refs */
	if (do_connect(t, transport->url) < 0)
		return -1;

	gitno_buffer_setup(transport, &transport->buffer, t->buff, sizeof(t->buff));

	t->parent.connected = 1;
	if (git_protocol_store_refs(transport, 1) < 0)
		return -1;

	if (git_protocol_detect_caps(git_vector_get(&transport->refs, 0), &transport->caps) < 0)
		return -1;

	return 0;
}
Example #11
0
static int pack_entry_find_inner(
	struct git_pack_entry *e,
	struct pack_backend *backend,
	const git_oid *oid,
	struct git_pack_file *last_found)
{
	size_t i;

	if (last_found &&
		git_pack_entry_find(e, last_found, oid, GIT_OID_HEXSZ) == 0)
		return 0;

	for (i = 0; i < backend->packs.length; ++i) {
		struct git_pack_file *p;

		p = (git_pack_file*) git_vector_get(&backend->packs, i);
		if (p == last_found)
			continue;

		if (git_pack_entry_find(e, p, oid, GIT_OID_HEXSZ) == 0) {
			backend->last_found = p;
			return 0;
		}
	}

	return -1;
}
Example #12
0
int git_tree__writeback(git_tree *tree, git_odb_source *src)
{
	size_t i;
	char filemode[8];

	assert(tree && src);

	if (tree->entries.length == 0)
		return GIT_EMISSINGOBJDATA;

	git_vector_sort(&tree->entries);

	for (i = 0; i < tree->entries.length; ++i) {
		git_tree_entry *entry;

		entry = git_vector_get(&tree->entries, i);
	
		sprintf(filemode, "%06o ", entry->attr);

		git__source_write(src, filemode, strlen(filemode));
		git__source_write(src, entry->filename, strlen(entry->filename) + 1);
		git__source_write(src, entry->oid.id, GIT_OID_RAWSZ);
	} 

	return GIT_SUCCESS;
}
Example #13
0
int git_odb_write_pack(struct git_odb_writepack **out, git_odb *db, git_transfer_progress_cb progress_cb, void *progress_payload)
{
	size_t i, writes = 0;
	int error = GIT_ERROR;

	assert(out && db);

	for (i = 0; i < db->backends.length && error < 0; ++i) {
		backend_internal *internal = (backend_internal *) git_vector_get(&db->backends, i);
		git_odb_backend *b = internal->backend;

		/* we don't write in alternates! */
		if (internal->is_alternate)
			continue;

		if (b->writepack != NULL) {
			++writes;
			error = b->writepack(out, b, db, progress_cb, progress_payload);
		}
	}

	if (error == GIT_PASSTHROUGH)
		error = 0;
	if (error < 0 && !writes)
		error = git_odb__error_unsupported_in_backend("write pack");

	return error;
}
Example #14
0
static int detect_caps(transport_git *t)
{
	git_vector *refs = &t->refs;
	git_pkt_ref *pkt;
	git_transport_caps *caps = &t->caps;
	const char *ptr;

	pkt = git_vector_get(refs, 0);
	/* No refs or capabilites, odd but not a problem */
	if (pkt == NULL || pkt->capabilities == NULL)
		return 0;

	ptr = pkt->capabilities;
	while (ptr != NULL && *ptr != '\0') {
		if (*ptr == ' ')
			ptr++;

		if(!git__prefixcmp(ptr, GIT_CAP_OFS_DELTA)) {
			caps->common = caps->ofs_delta = 1;
			ptr += strlen(GIT_CAP_OFS_DELTA);
			continue;
		}

		/* We don't know this capability, so skip it */
		ptr = strchr(ptr, ' ');
	}

	return 0;
}
Example #15
0
int git_odb_exists_prefix(
	git_oid *out, git_odb *db, const git_oid *short_id, size_t len)
{
	int error = GIT_ENOTFOUND, num_found = 0;
	size_t i;
	git_oid key = {{0}}, last_found = {{0}}, found;

	assert(db && short_id);

	if (len < GIT_OID_MINPREFIXLEN)
		return git_odb__error_ambiguous("prefix length too short");
	if (len > GIT_OID_HEXSZ)
		len = GIT_OID_HEXSZ;

	if (len == GIT_OID_HEXSZ) {
		if (git_odb_exists(db, short_id)) {
			if (out)
				git_oid_cpy(out, short_id);
			return 0;
		} else {
			return git_odb__error_notfound("no match for id prefix", short_id);
		}
	}

	/* just copy valid part of short_id */
	memcpy(&key.id, short_id->id, (len + 1) / 2);
	if (len & 1)
		key.id[len / 2] &= 0xF0;

	for (i = 0; i < db->backends.length; ++i) {
		backend_internal *internal = (backend_internal *) git_vector_get(&db->backends, i);
		git_odb_backend *b = internal->backend;

		if (!b->exists_prefix)
			continue;

		error = b->exists_prefix(&found, b, &key, len);
		if (error == GIT_ENOTFOUND || error == GIT_PASSTHROUGH)
			continue;
		if (error)
			return error;

		/* make sure found item doesn't introduce ambiguity */
		if (num_found) {
			if (git_oid__cmp(&last_found, &found))
				return git_odb__error_ambiguous("multiple matches for prefix");
		} else {
			git_oid_cpy(&last_found, &found);
			num_found++;
		}
	}

	if (!num_found)
		return git_odb__error_notfound("no match for id prefix", &key);
	if (out)
		git_oid_cpy(out, &last_found);

	return 0;
}
Example #16
0
void test_checkout_conflict__report_progress(void)
{
	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
	git_vector paths = GIT_VECTOR_INIT;
	char *path;
	size_t i;

	struct checkout_index_entry checkout_index_entries[] = {
		{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "conflicting-1.txt" },
		{ 0100644, CONFLICTING_OURS_OID, 2, "conflicting-1.txt" },
		{ 0100644, CONFLICTING_THEIRS_OID, 3, "conflicting-1.txt" },

		{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "conflicting-2.txt" },
		{ 0100644, CONFLICTING_OURS_OID, 2, "conflicting-2.txt" },
		{ 0100644, CONFLICTING_THEIRS_OID, 3, "conflicting-2.txt" },

		{ 0100644, AUTOMERGEABLE_ANCESTOR_OID, 1, "conflicting-3.txt" },
		{ 0100644, AUTOMERGEABLE_OURS_OID, 2, "conflicting-3.txt" },
		{ 0100644, AUTOMERGEABLE_THEIRS_OID, 3, "conflicting-3.txt" },

		{ 0100644, AUTOMERGEABLE_ANCESTOR_OID, 1, "conflicting-4.txt" },
		{ 0100644, AUTOMERGEABLE_OURS_OID, 2, "conflicting-4.txt" },
		{ 0100644, AUTOMERGEABLE_THEIRS_OID, 3, "conflicting-4.txt" },
	};

	opts.progress_cb = collect_progress;
	opts.progress_payload = &paths;


	create_index(checkout_index_entries, 12);
	git_index_write(g_index);

	cl_git_pass(git_checkout_index(g_repo, g_index, &opts));

	cl_assert_equal_i(4, git_vector_length(&paths));
	cl_assert_equal_s("conflicting-1.txt", git_vector_get(&paths, 0));
	cl_assert_equal_s("conflicting-2.txt", git_vector_get(&paths, 1));
	cl_assert_equal_s("conflicting-3.txt", git_vector_get(&paths, 2));
	cl_assert_equal_s("conflicting-4.txt", git_vector_get(&paths, 3));

	git_vector_foreach(&paths, i, path)
		git__free(path);

	git_vector_free(&paths);
}
Example #17
0
void test_network_remote_rename__symref_head(void)
{
	int error;
	git_reference *ref;
	git_branch_t btype;
	git_branch_iterator *iter;
	git_strarray problems = {0};
	char idstr[GIT_OID_HEXSZ + 1] = {0};
	git_vector refs;

	cl_git_pass(git_reference_symbolic_create(&ref, _repo, "refs/remotes/test/HEAD", "refs/remotes/test/master", 0, NULL, NULL));
	git_reference_free(ref);

	cl_git_pass(git_remote_rename(&problems, _repo, _remote_name, "renamed"));
	cl_assert_equal_i(0, problems.count);
	git_strarray_free(&problems);

	cl_git_pass(git_vector_init(&refs, 2, (git_vector_cmp) git_reference_cmp));
	cl_git_pass(git_branch_iterator_new(&iter, _repo, GIT_BRANCH_REMOTE));

	while ((error = git_branch_next(&ref, &btype, iter)) == 0) {
		cl_git_pass(git_vector_insert(&refs, ref));
	}
	cl_assert_equal_i(GIT_ITEROVER, error);
	git_vector_sort(&refs);

	cl_assert_equal_i(2, refs.length);

	ref = git_vector_get(&refs, 0);
	cl_assert_equal_s("refs/remotes/renamed/HEAD", git_reference_name(ref));
	cl_assert_equal_s("refs/remotes/renamed/master", git_reference_symbolic_target(ref));
	git_reference_free(ref);

	ref = git_vector_get(&refs, 1);
	cl_assert_equal_s("refs/remotes/renamed/master", git_reference_name(ref));
	git_oid_fmt(idstr, git_reference_target(ref));
	cl_assert_equal_s("be3563ae3f795b2b4353bcce3a527ad0a4f7f644", idstr);
	git_reference_free(ref);

	git_vector_free(&refs);

	cl_git_fail_with(GIT_ITEROVER, git_branch_next(&ref, &btype, iter));
	git_branch_iterator_free(iter);
}
Example #18
0
const git_reflog_entry * git_reflog_entry_byindex(const git_reflog *reflog, size_t idx)
{
	assert(reflog);

	if (idx >= reflog->entries.length)
		return NULL;

	return git_vector_get(
		&reflog->entries, reflog_inverse_index(idx, reflog->entries.length));
}
Example #19
0
int git_commit_parent(git_commit **parent, git_commit *commit, unsigned int n)
{
	git_oid *parent_oid;
	assert(commit);

	parent_oid = git_vector_get(&commit->parent_oids, n);
	if (parent_oid == NULL)
		return git__throw(GIT_ENOTFOUND, "Parent %u does not exist", n);

	return git_commit_lookup(parent, commit->object.repo, parent_oid);
}
Example #20
0
static void clear_parents(git_commit *commit)
{
	unsigned int i;

	for (i = 0; i < commit->parent_oids.length; ++i) {
		git_oid *parent = git_vector_get(&commit->parent_oids, i);
		free(parent);
	}

	git_vector_clear(&commit->parent_oids);
}
Example #21
0
git_tree_entry *git_tree_entry_byname(git_tree *tree, const char *filename)
{
	int idx;

	assert(tree && filename);

	idx = git_vector_search(&tree->entries, filename);
	if (idx == GIT_ENOTFOUND)
		return NULL;

	return git_vector_get(&tree->entries, idx);
}
Example #22
0
static void check_backend_sorting(git_odb *odb)
{
	unsigned int i;

	for (i = 0; i < odb->backends.length; ++i) {
		fake_backend *internal =
			*((fake_backend **)git_vector_get(&odb->backends, i));

		cl_assert(internal != NULL);
		cl_assert(internal->position == (int)i);
	}
}
Example #23
0
	git_vector_foreach(contents, i, ps) {
		/* skip if before start_stat or after end_stat */
		cmp_len = min(start_len, ps->path_len);
		if (cmp_len && strncomp(ps->path, start_stat, cmp_len) < 0)
			continue;
		cmp_len = min(end_len, ps->path_len);
		if (cmp_len && strncomp(ps->path, end_stat, cmp_len) > 0)
			continue;

		git_buf_truncate(&full, prefix_len);

		if ((error = git_buf_joinpath(&full, full.ptr, ps->path)) < 0 ||
			(error = git_path_lstat(full.ptr, &ps->st)) < 0) {

			if (error == GIT_ENOTFOUND) {
				/* file was removed between readdir and lstat */
				char *entry_path = git_vector_get(contents, i);
				git_vector_remove(contents, i--);
				git__free(entry_path);
			} else {
				/* Treat the file as unreadable if we get any other error */
				memset(&ps->st, 0, sizeof(ps->st));
				ps->st.st_mode = GIT_FILEMODE_UNREADABLE;
			}

			giterr_clear();
			error = 0;
			continue;
		}

		if (S_ISDIR(ps->st.st_mode)) {
			ps->path[ps->path_len++] = '/';
			ps->path[ps->path_len] = '\0';
		}
		else if (!S_ISREG(ps->st.st_mode) && !S_ISLNK(ps->st.st_mode)) {
			char *entry_path = git_vector_get(contents, i);
			git_vector_remove(contents, i--);
			git__free(entry_path);
		}
	}
Example #24
0
static int write_entries(git_index *index, git_filebuf *file)
{
	unsigned int i;

	for (i = 0; i < index->entries.length; ++i) {
		git_index_entry *entry;
		entry = git_vector_get(&index->entries, i);
		if (write_disk_entry(file, entry) < GIT_SUCCESS)
			return GIT_ENOMEM;
	}

	return GIT_SUCCESS;
}
Example #25
0
int git_patch_parsed_from_diff(git_patch **out, git_diff *d, size_t idx)
{
	git_diff_parsed *diff = (git_diff_parsed *)d;
	git_patch *p;

	if ((p = git_vector_get(&diff->patches, idx)) == NULL)
		return -1;

	GIT_REFCOUNT_INC(p);
	*out = p;

	return 0;
}
Example #26
0
static void git_free(git_transport *transport)
{
	transport_git *t = (transport_git *) transport;
	git_vector *refs = &transport->refs;
	unsigned int i;

	for (i = 0; i < refs->length; ++i) {
		git_pkt *p = git_vector_get(refs, i);
		git_pkt_free(p);
	}
	git_vector_free(refs);

	refs = &transport->common;
	for (i = 0; i < refs->length; ++i) {
		git_pkt *p = git_vector_get(refs, i);
		git_pkt_free(p);
	}
	git_vector_free(refs);

	git__free(t->parent.url);
	git__free(t);
}
Example #27
0
static commit_object *alloc_commit(git_revwalk *walk)
{
	unsigned char *chunk;

	if (walk->chunk_size == COMMITS_PER_CHUNK)
		alloc_chunk(walk);

	chunk = git_vector_get(&walk->memory_alloc, walk->memory_alloc.length - 1);
	chunk += (walk->chunk_size * CHUNK_STEP);
	walk->chunk_size++;

	return (commit_object *)chunk;
}
Example #28
0
int git_config_set_string(git_config *cfg, const char *name, const char *value)
{
	file_internal *internal;
	git_config_file *file;

	if (cfg->files.length == 0)
		return git__throw(GIT_EINVALIDARGS, "Cannot set variable value; no files open in the `git_config` instance");

	internal = git_vector_get(&cfg->files, 0);
	file = internal->file;

	return file->set(file, name, value);
}
Example #29
0
const git_index_entry_unmerged *git_index_get_unmerged_bypath(git_index *index, const char *path)
{
	int pos;
	assert(index && path);

	if (!index->unmerged.length)
		return NULL;

	if ((pos = git_vector_bsearch2(&index->unmerged, unmerged_srch, path)) < GIT_SUCCESS)
		return NULL;

	return git_vector_get(&index->unmerged, pos);
}
Example #30
0
int git_odb_open_wstream(
	git_odb_stream **stream, git_odb *db, size_t size, git_otype type)
{
	size_t i, writes = 0;
	int error = GIT_ERROR;
	git_hash_ctx *ctx = NULL;

	assert(stream && db);

	for (i = 0; i < db->backends.length && error < 0; ++i) {
		backend_internal *internal = (backend_internal *) git_vector_get(&db->backends, i);
		git_odb_backend *b = internal->backend;

		/* we don't write in alternates! */
		if (internal->is_alternate)
			continue;

		if (b->writestream != NULL) {
			++writes;
			error = b->writestream(stream, b, size, type);
		} else if (b->write != NULL) {
			++writes;
			error = init_fake_wstream(stream, b, size, type);
		}
	}

	if (error < 0) {
		if (error == GIT_PASSTHROUGH)
			error = 0;
		else if (!writes)
			error = git_odb__error_unsupported_in_backend("write object");

		goto done;
	}

	ctx = (git_hash_ctx*) git__malloc(sizeof(git_hash_ctx));
	GITERR_CHECK_ALLOC(ctx);

	if ((error = git_hash_ctx_init(ctx)) < 0)
		goto done;

	hash_header(ctx, size, type);
	(*stream)->hash_ctx = ctx;

	(*stream)->declared_size = size;
	(*stream)->received_bytes = 0;

done:
	return error;
}