示例#1
0
文件: hash.c 项目: Asquera/libgit2
void test_object_raw_hash__hash_by_blocks(void)
{
    git_hash_ctx *ctx;
    git_oid id1, id2;

    cl_assert((ctx = git_hash_new_ctx()) != NULL);

	/* should already be init'd */
    git_hash_update(ctx, hello_text, strlen(hello_text));
    git_hash_final(&id2, ctx);
    cl_git_pass(git_oid_fromstr(&id1, hello_id));
    cl_assert(git_oid_cmp(&id1, &id2) == 0);

	/* reinit should permit reuse */
    git_hash_init(ctx);
    git_hash_update(ctx, bye_text, strlen(bye_text));
    git_hash_final(&id2, ctx);
    cl_git_pass(git_oid_fromstr(&id1, bye_id));
    cl_assert(git_oid_cmp(&id1, &id2) == 0);

    git_hash_free_ctx(ctx);
}
示例#2
0
文件: index.c 项目: hef/libgit2
int git_index__write(git_index *index, git_filelock *file)
{
	static const char NULL_BYTES[] = {0, 0, 0, 0, 0, 0, 0, 0};

	int error = 0;
	unsigned int i;

	git_hash_ctx *digest;
	git_oid hash_final;

	assert(index && file && file->is_locked);

	if ((digest = git_hash_new_ctx()) == NULL)
		return GIT_ENOMEM;

#define WRITE_WORD(_word) {\
	uint32_t network_word = htonl((_word));\
	git_filelock_write(file, &network_word, 4);\
	git_hash_update(digest, &network_word, 4);\
}

#define WRITE_SHORT(_shrt) {\
	uint16_t network_shrt = htons((_shrt));\
	git_filelock_write(file, &network_shrt, 2);\
	git_hash_update(digest, &network_shrt, 2);\
}

#define WRITE_BYTES(_bytes, _n) {\
	git_filelock_write(file, _bytes, _n);\
	git_hash_update(digest, _bytes, _n);\
}

	WRITE_BYTES(INDEX_HEADER_SIG, 4);

	WRITE_WORD(INDEX_VERSION_NUMBER);
	WRITE_WORD(index->entry_count);

	for (i = 0; i < index->entry_count; ++i) {
		git_index_entry *entry;
		size_t path_length, padding;

		entry = &index->entries[i];
		path_length = strlen(entry->path);

		WRITE_WORD(entry->ctime.seconds);
		WRITE_WORD(entry->ctime.nanoseconds);
		WRITE_WORD(entry->mtime.seconds);
		WRITE_WORD(entry->mtime.nanoseconds);
		WRITE_WORD(entry->dev);
		WRITE_WORD(entry->ino);
		WRITE_WORD(entry->mode);
		WRITE_WORD(entry->uid);
		WRITE_WORD(entry->gid);
		WRITE_WORD(entry->file_size);
		WRITE_BYTES(entry->oid.id, GIT_OID_RAWSZ);
		WRITE_SHORT(entry->flags);

		if (entry->flags & GIT_IDXENTRY_EXTENDED) {
			WRITE_SHORT(entry->flags_extended);
			padding = long_entry_padding(path_length);
		} else
			padding = short_entry_padding(path_length);

		WRITE_BYTES(entry->path, path_length);
		WRITE_BYTES(NULL_BYTES, padding);
	}

#undef WRITE_WORD
#undef WRITE_BYTES
#undef WRITE_SHORT
#undef WRITE_FLAGS

	/* TODO: write extensions (tree cache) */

	git_hash_final(&hash_final, digest);
	git_hash_free_ctx(digest);
	git_filelock_write(file, hash_final.id, GIT_OID_RAWSZ);

	return error;
}
int git_filebuf_open(git_filebuf *file, const char *path, int flags)
{
	int compression;
	size_t path_len;

	/* opening an already open buffer is a programming error;
	 * assert that this never happens instead of returning
	 * an error code */
	assert(file && path && file->buffer == NULL);

	memset(file, 0x0, sizeof(git_filebuf));

	if (flags & GIT_FILEBUF_DO_NOT_BUFFER)
		file->do_not_buffer = true;

	file->buf_size = WRITE_BUFFER_SIZE;
	file->buf_pos = 0;
	file->fd = -1;
	file->last_error = BUFERR_OK;

	/* Allocate the main cache buffer */
	if (!file->do_not_buffer) {
		file->buffer = git__malloc(file->buf_size);
		GITERR_CHECK_ALLOC(file->buffer);
	}

	/* If we are hashing on-write, allocate a new hash context */
	if (flags & GIT_FILEBUF_HASH_CONTENTS) {
		file->digest = git_hash_new_ctx();
		GITERR_CHECK_ALLOC(file->digest);
	}

	compression = flags >> GIT_FILEBUF_DEFLATE_SHIFT;

	/* If we are deflating on-write, */
	if (compression != 0) {
		/* Initialize the ZLib stream */
		if (deflateInit(&file->zs, compression) != Z_OK) {
			giterr_set(GITERR_ZLIB, "Failed to initialize zlib");
			goto cleanup;
		}

		/* Allocate the Zlib cache buffer */
		file->z_buf = git__malloc(file->buf_size);
		GITERR_CHECK_ALLOC(file->z_buf);

		/* Never flush */
		file->flush_mode = Z_NO_FLUSH;
		file->write = &write_deflate;
	} else {
		file->write = &write_normal;
	}

	/* If we are writing to a temp file */
	if (flags & GIT_FILEBUF_TEMPORARY) {
		git_buf tmp_path = GIT_BUF_INIT;

		/* Open the file as temporary for locking */
		file->fd = git_futils_mktmp(&tmp_path, path);

		if (file->fd < 0) {
			git_buf_free(&tmp_path);
			goto cleanup;
		}
		file->fd_is_open = true;

		/* No original path */
		file->path_original = NULL;
		file->path_lock = git_buf_detach(&tmp_path);
		GITERR_CHECK_ALLOC(file->path_lock);
	} else {
		path_len = strlen(path);

		/* Save the original path of the file */
		file->path_original = git__strdup(path);
		GITERR_CHECK_ALLOC(file->path_original);

		/* create the locking path by appending ".lock" to the original */
		file->path_lock = git__malloc(path_len + GIT_FILELOCK_EXTLENGTH);
		GITERR_CHECK_ALLOC(file->path_lock);

		memcpy(file->path_lock, file->path_original, path_len);
		memcpy(file->path_lock + path_len, GIT_FILELOCK_EXTENSION, GIT_FILELOCK_EXTLENGTH);

		/* open the file for locking */
		if (lock_file(file, flags) < 0)
			goto cleanup;
	}

	return 0;

cleanup:
	git_filebuf_cleanup(file);
	return -1;
}
示例#4
0
int git_filebuf_open(git_filebuf *file, const char *path, int flags)
{
    int error;
    size_t path_len;

    assert(file && path);

    memset(file, 0x0, sizeof(git_filebuf));

    file->buf_size = WRITE_BUFFER_SIZE;
    file->buf_pos = 0;
    file->fd = -1;

    /* Allocate the main cache buffer */
    file->buffer = git__malloc(file->buf_size);
    if (file->buffer == NULL) {
        error = GIT_ENOMEM;
        goto cleanup;
    }

    /* If we are hashing on-write, allocate a new hash context */
    if (flags & GIT_FILEBUF_HASH_CONTENTS) {
        if ((file->digest = git_hash_new_ctx()) == NULL) {
            error = GIT_ENOMEM;
            goto cleanup;
        }
    }

    /* If we are deflating on-write, */
    if (flags & GIT_FILEBUF_DEFLATE_CONTENTS) {

        /* Initialize the ZLib stream */
        if (deflateInit(&file->zs, Z_BEST_SPEED) != Z_OK) {
            error = git__throw(GIT_EZLIB, "Failed to initialize zlib");
            goto cleanup;
        }

        /* Allocate the Zlib cache buffer */
        file->z_buf = git__malloc(file->buf_size);
        if (file->z_buf == NULL) {
            error = GIT_ENOMEM;
            goto cleanup;
        }

        /* Never flush */
        file->flush_mode = Z_NO_FLUSH;
        file->write = &write_deflate;
    } else {
        file->write = &write_normal;
    }

    /* If we are writing to a temp file */
    if (flags & GIT_FILEBUF_TEMPORARY) {
        char tmp_path[GIT_PATH_MAX];

        /* Open the file as temporary for locking */
        file->fd = gitfo_mktemp(tmp_path, path);
        if (file->fd < 0) {
            error = GIT_EOSERR;
            goto cleanup;
        }

        /* No original path */
        file->path_original = NULL;
        file->path_lock = git__strdup(tmp_path);

        if (file->path_lock == NULL) {
            error = GIT_ENOMEM;
            goto cleanup;
        }
    } else {
        path_len = strlen(path);

        /* Save the original path of the file */
        file->path_original = git__strdup(path);
        if (file->path_original == NULL) {
            error = GIT_ENOMEM;
            goto cleanup;
        }

        /* create the locking path by appending ".lock" to the original */
        file->path_lock = git__malloc(path_len + GIT_FILELOCK_EXTLENGTH);
        if (file->path_lock == NULL) {
            error = GIT_ENOMEM;
            goto cleanup;
        }

        memcpy(file->path_lock, file->path_original, path_len);
        memcpy(file->path_lock + path_len, GIT_FILELOCK_EXTENSION, GIT_FILELOCK_EXTLENGTH);

        /* open the file for locking */
        if ((error = lock_file(file, flags)) < GIT_SUCCESS)
            goto cleanup;
    }

    return GIT_SUCCESS;

cleanup:
    git_filebuf_cleanup(file);
    return git__rethrow(error, "Failed to open file buffer for '%s'", path);
}
示例#5
0
int git_filebuf_open(git_filebuf *file, const char *path, int flags)
{
	int error;
	size_t path_len;

	if (file == NULL || path == NULL)
		return GIT_ERROR;

	memset(file, 0x0, sizeof(git_filebuf));

	file->buf_size = WRITE_BUFFER_SIZE;
	file->buf_pos = 0;
	file->fd = -1;

	path_len = strlen(path);

	file->path_original = git__strdup(path);
	if (file->path_original == NULL) {
		error = GIT_ENOMEM;
		goto cleanup;
	}

	file->path_lock = git__malloc(path_len + GIT_FILELOCK_EXTLENGTH);
	if (file->path_lock == NULL) {
		error = GIT_ENOMEM;
		goto cleanup;
	}

	memcpy(file->path_lock, file->path_original, path_len);
	memcpy(file->path_lock + path_len, GIT_FILELOCK_EXTENSION, GIT_FILELOCK_EXTLENGTH);

	file->buffer = git__malloc(file->buf_size);
	if (file->buffer == NULL){
		error = GIT_ENOMEM;
		goto cleanup;
	}

#ifdef GIT_FILEBUF_THREADS
	file->buffer_back = git__malloc(file->buf_size);
	if (file->buffer_back == NULL){
		error = GIT_ENOMEM;
		goto cleanup;
	}
#endif

	if (flags & GIT_FILEBUF_HASH_CONTENTS) {
		if ((file->digest = git_hash_new_ctx()) == NULL) {
			error = GIT_ENOMEM;
			goto cleanup;
		}
	}

	if ((error = lock_file(file, flags)) < GIT_SUCCESS)
		goto cleanup;

	return GIT_SUCCESS;

cleanup:
	git_filebuf_cleanup(file);
	return error;
}