예제 #1
0
파일: blob.c 프로젝트: brodie/libgit2
static int write_file_stream(
	git_oid *oid, git_odb *odb, const char *path, git_off_t file_size)
{
	int fd, error;
	char buffer[4096];
	git_odb_stream *stream = NULL;
	ssize_t read_len = -1, written = 0;

	if ((error = git_odb_open_wstream(
			&stream, odb, (size_t)file_size, GIT_OBJ_BLOB)) < 0)
		return error;

	if ((fd = git_futils_open_ro(path)) < 0) {
		git_odb_stream_free(stream);
		return -1;
	}

	while (!error && (read_len = p_read(fd, buffer, sizeof(buffer))) > 0) {
		error = git_odb_stream_write(stream, buffer, read_len);
		written += read_len;
	}

	p_close(fd);

	if (written != file_size || read_len < 0) {
		giterr_set(GITERR_OS, "Failed to read file into stream");
		error = -1;
	}

	if (!error)
		error = git_odb_stream_finalize_write(oid, stream);

	git_odb_stream_free(stream);
	return error;
}
예제 #2
0
PyObject *
Repository_write(Repository *self, PyObject *args)
{
    int err;
    git_oid oid;
    git_odb *odb;
    git_odb_stream* stream;
    int type_id;
    const char* buffer;
    Py_ssize_t buflen;
    git_otype type;

    if (!PyArg_ParseTuple(args, "Is#", &type_id, &buffer, &buflen))
        return NULL;

    type = int_to_loose_object_type(type_id);
    if (type == GIT_OBJ_BAD)
        return PyErr_Format(PyExc_ValueError, "%d", type_id);

    err = git_repository_odb(&odb, self->repo);
    if (err < 0)
        return Error_set(err);

    err = git_odb_open_wstream(&stream, odb, buflen, type);
    git_odb_free(odb);
    if (err < 0)
        return Error_set(err);

    err = git_odb_stream_write(stream, buffer, buflen);
    if (err) {
        git_odb_stream_free(stream);
        return Error_set(err);
    }

    err = git_odb_stream_finalize_write(&oid, stream);
    git_odb_stream_free(stream);
    if (err)
        return Error_set(err);

    return git_oid_to_python(&oid);
}
예제 #3
0
파일: blob.c 프로젝트: brodie/libgit2
int git_blob_create_frombuffer(git_oid *oid, git_repository *repo, const void *buffer, size_t len)
{
	int error;
	git_odb *odb;
	git_odb_stream *stream;

	if ((error = git_repository_odb__weakptr(&odb, repo)) < 0 ||
		(error = git_odb_open_wstream(&stream, odb, len, GIT_OBJ_BLOB)) < 0)
		return error;

	if ((error = git_odb_stream_write(stream, buffer, len)) == 0)
		error = git_odb_stream_finalize_write(oid, stream);

	git_odb_stream_free(stream);
	return error;
}
예제 #4
0
파일: largefiles.c 프로젝트: csware/libgit2
void test_odb_largefiles__streamread(void)
{
	git_oid oid, read_oid;
	git_odb_stream *stream;
	char buf[10240];
	char hdr[64];
	size_t len, hdr_len, total = 0;
	git_hash_ctx hash;
	git_otype type;
	int ret;

#ifndef GIT_ARCH_64
	cl_skip();
#endif

	if (!cl_is_env_set("GITTEST_INVASIVE_FS_SIZE") ||
		!cl_is_env_set("GITTEST_SLOW"))
		cl_skip();

	writefile(&oid);

	cl_git_pass(git_odb_open_rstream(&stream, &len, &type, odb, &oid));

	cl_assert_equal_sz(LARGEFILE_SIZE, len);
	cl_assert_equal_i(GIT_OBJ_BLOB, type);

	cl_git_pass(git_hash_ctx_init(&hash));
	cl_git_pass(git_odb__format_object_header(&hdr_len, hdr, sizeof(hdr), len, type));

	cl_git_pass(git_hash_update(&hash, hdr, hdr_len));

	while ((ret = git_odb_stream_read(stream, buf, 10240)) > 0) {
		cl_git_pass(git_hash_update(&hash, buf, ret));
		total += ret;
	}

	cl_assert_equal_sz(LARGEFILE_SIZE, total);

	git_hash_final(&read_oid, &hash);

	cl_assert_equal_oid(&oid, &read_oid);

	git_hash_ctx_cleanup(&hash);
	git_odb_stream_free(stream);
}
예제 #5
0
파일: largefiles.c 프로젝트: csware/libgit2
static void writefile(git_oid *oid)
{
	static git_odb_stream *stream;
	git_buf buf = GIT_BUF_INIT;
	size_t i;

	for (i = 0; i < 3041; i++)
		cl_git_pass(git_buf_puts(&buf, "Hello, world.\n"));

	cl_git_pass(git_odb_open_wstream(&stream, odb, LARGEFILE_SIZE, GIT_OBJ_BLOB));
	for (i = 0; i < 126103; i++)
		cl_git_pass(git_odb_stream_write(stream, buf.ptr, buf.size));

	cl_git_pass(git_odb_stream_finalize_write(oid, stream));

	git_odb_stream_free(stream);
	git_buf_dispose(&buf);
}
예제 #6
0
int git_odb_write(
	git_oid *oid, git_odb *db, const void *data, size_t len, git_otype type)
{
	size_t i;
	int error = GIT_ERROR;
	git_odb_stream *stream;

	assert(oid && db);

	git_odb_hash(oid, data, len, type);
	if (git_odb_exists(db, oid))
		return 0;

	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->write != NULL)
			error = b->write(b, oid, data, len, type);
	}

	if (!error || error == GIT_PASSTHROUGH)
		return 0;

	/* if no backends were able to write the object directly, we try a
	 * streaming write to the backends; just write the whole object into the
	 * stream in one push
	 */
	if ((error = git_odb_open_wstream(&stream, db, len, type)) != 0)
		return error;

	stream->write(stream, (char*) data, len);
	error = stream->finalize_write(stream, oid);
	git_odb_stream_free(stream);

	return error;
}
예제 #7
0
static void test_readstream_object(object_data *data, size_t blocksize)
{
	git_oid id;
	git_odb *odb;
	git_odb_stream *stream;
	git_rawobj tmp;
	char buf[2048], *ptr = buf;
	size_t remain;
	int ret;

	write_object_files(data);

	cl_git_pass(git_odb_open(&odb, "test-objects"));
	cl_git_pass(git_oid_fromstr(&id, data->id));
	cl_git_pass(git_odb_open_rstream(&stream, &tmp.len, &tmp.type, odb, &id));

	remain = tmp.len;

	while (remain) {
		cl_assert((ret = git_odb_stream_read(stream, ptr, blocksize)) >= 0);
		if (ret == 0)
			break;

		cl_assert(remain >= (size_t)ret);
		remain -= ret;
		ptr += ret;
	}

	cl_assert(remain == 0);

	tmp.data = buf;

	cmp_objects(&tmp, data);

	git_odb_stream_free(stream);
	git_odb_free(odb);
}
예제 #8
0
파일: tag.c 프로젝트: yuanms2/libgit2
int git_tag_create_frombuffer(git_oid *oid, git_repository *repo, const char *buffer, int allow_ref_overwrite)
{
    git_tag tag;
    int error;
    git_odb *odb;
    git_odb_stream *stream;
    git_odb_object *target_obj;

    git_reference *new_ref = NULL;
    git_buf ref_name = GIT_BUF_INIT;

    assert(oid && buffer);

    memset(&tag, 0, sizeof(tag));

    if (git_repository_odb__weakptr(&odb, repo) < 0)
        return -1;

    /* validate the buffer */
    if (tag_parse(&tag, buffer, buffer + strlen(buffer)) < 0)
        return -1;

    /* validate the target */
    if (git_odb_read(&target_obj, odb, &tag.target) < 0)
        goto on_error;

    if (tag.type != target_obj->cached.type) {
        giterr_set(GITERR_TAG, "The type for the given target is invalid");
        goto on_error;
    }

    error = retrieve_tag_reference_oid(oid, &ref_name, repo, tag.tag_name);
    if (error < 0 && error != GIT_ENOTFOUND)
        goto on_error;

    /* We don't need these objects after this */
    git_signature_free(tag.tagger);
    git__free(tag.tag_name);
    git__free(tag.message);
    git_odb_object_free(target_obj);

    /** Ensure the tag name doesn't conflict with an already existing
     *	reference unless overwriting has explicitly been requested **/
    if (error == 0 && !allow_ref_overwrite) {
        giterr_set(GITERR_TAG, "Tag already exists");
        return GIT_EEXISTS;
    }

    /* write the buffer */
    if ((error = git_odb_open_wstream(
                     &stream, odb, strlen(buffer), GIT_OBJ_TAG)) < 0)
        return error;

    if (!(error = git_odb_stream_write(stream, buffer, strlen(buffer))))
        error = git_odb_stream_finalize_write(oid, stream);

    git_odb_stream_free(stream);

    if (error < 0) {
        git_buf_free(&ref_name);
        return error;
    }

    error = git_reference_create(
                &new_ref, repo, ref_name.ptr, oid, allow_ref_overwrite, NULL);

    git_reference_free(new_ref);
    git_buf_free(&ref_name);

    return error;

on_error:
    git_signature_free(tag.tagger);
    git__free(tag.tag_name);
    git__free(tag.message);
    git_odb_object_free(target_obj);
    return -1;
}