Exemple #1
0
static read_method_decl(pack_non_delta)
{
	size_t total_read = 0;

	switch (st->z_state) {
	case z_unused:
		memset(&st->z, 0, sizeof(st->z));
		git_inflate_init(&st->z);
		st->z_state = z_used;
		break;
	case z_done:
		return 0;
	case z_error:
		return -1;
	case z_used:
		break;
	}

	while (total_read < sz) {
		int status;
		struct pack_window *window = NULL;
		unsigned char *mapped;

		mapped = use_pack(st->u.in_pack.pack, &window,
				  st->u.in_pack.pos, &st->z.avail_in);

		st->z.next_out = (unsigned char *)buf + total_read;
		st->z.avail_out = sz - total_read;
		st->z.next_in = mapped;
		status = git_inflate(&st->z, Z_FINISH);

		st->u.in_pack.pos += st->z.next_in - mapped;
		total_read = st->z.next_out - (unsigned char *)buf;
		unuse_pack(&window);

		if (status == Z_STREAM_END) {
			git_inflate_end(&st->z);
			st->z_state = z_done;
			break;
		}
		if (status != Z_OK && status != Z_BUF_ERROR) {
			git_inflate_end(&st->z);
			st->z_state = z_error;
			return -1;
		}
	}
	return total_read;
}
void fast_import_sha1write(struct sha1file *f, const void *buf,
			   unsigned int count)
{
	if (!pack_win) {
		pack_win = xcalloc(1, sizeof(*pack_data->windows));
		pack_win->offset = 0;
		pack_win->len = 20;
		pack_win->base = xmalloc(packed_git_window_size);
		pack_win->next = NULL;
	}
	/* pack_data is not set the first time sha1write is called */
	if (pack_data && !pack_data->windows) {
		pack_data->windows = pack_win;
		pack_data->pack_size = pack_win->len;
	}

	sha1write(f, buf, count);
	pack_win->last_used = -1; /* always last used */
	pack_win->inuse_cnt = -1;
	if (pack_data)
		pack_data->pack_size += count;

	if (packed_git_window_size - pack_win->len >= count) {
		memcpy(pack_win->base + pack_win->len - 20, buf, count);
		pack_win->len += count;
	} else {
		/* We're closing the window, so we don't actually need
		 * to copy the beginning of the data, only what will
		 * remain in the new window. */
		pack_win->offset += (((off_t) pack_win->len - 20 + count)
			/ packed_git_window_size) * packed_git_window_size;
		pack_win->len = count % packed_git_window_size -
			(packed_git_window_size - pack_win->len);
		memcpy(pack_win->base, buf + count - pack_win->len + 20,
		       pack_win->len - 20);
		/* Ensure a pack window on the data before that, otherwise,
		 * use_pack() may try to create a window that overlaps with
		 * this one, and that won't work because it won't be complete. */
		sha1flush(f);
		if (prev_win)
			unuse_pack(&prev_win);
		use_pack(pack_data, &prev_win,
			 pack_win->offset - packed_git_window_size, NULL);
	}
}