int git_blob_create_fromchunks( git_oid *oid, git_repository *repo, const char *hintpath, int (*source_cb)(char *content, size_t max_length, void *payload), void *payload) { int error; char *content = NULL; git_filebuf file = GIT_FILEBUF_INIT; git_buf path = GIT_BUF_INIT; assert(oid && repo && source_cb); if ((error = git_buf_joinpath( &path, git_repository_path(repo), GIT_OBJECTS_DIR "streamed")) < 0) goto cleanup; content = git__malloc(BUFFER_SIZE); GITERR_CHECK_ALLOC(content); if ((error = git_filebuf_open( &file, git_buf_cstr(&path), GIT_FILEBUF_TEMPORARY, 0666)) < 0) goto cleanup; while (1) { int read_bytes = source_cb(content, BUFFER_SIZE, payload); if (!read_bytes) break; if (read_bytes > BUFFER_SIZE) { giterr_set(GITERR_OBJECT, "Invalid chunk size while creating blob"); error = GIT_EBUFS; } else if (read_bytes < 0) { error = giterr_set_after_callback(read_bytes); } else { error = git_filebuf_write(&file, content, read_bytes); } if (error < 0) goto cleanup; } if ((error = git_filebuf_flush(&file)) < 0) goto cleanup; error = git_blob__create_from_paths( oid, NULL, repo, file.path_lock, hintpath, 0, hintpath != NULL); cleanup: git_buf_free(&path); git_filebuf_cleanup(&file); git__free(content); return error; }
int git_blob_create_fromchunks( git_oid *oid, git_repository *repo, const char *hintpath, int (*source_cb)(char *content, size_t max_length, void *payload), void *payload) { int error = -1, read_bytes; char *content = NULL; git_filebuf file = GIT_FILEBUF_INIT; git_buf path = GIT_BUF_INIT; if (git_buf_join_n( &path, '/', 3, git_repository_path(repo), GIT_OBJECTS_DIR, "streamed") < 0) goto cleanup; content = git__malloc(BUFFER_SIZE); GITERR_CHECK_ALLOC(content); if (git_filebuf_open(&file, git_buf_cstr(&path), GIT_FILEBUF_TEMPORARY) < 0) goto cleanup; while (1) { read_bytes = source_cb(content, BUFFER_SIZE, payload); assert(read_bytes <= BUFFER_SIZE); if (read_bytes <= 0) break; if (git_filebuf_write(&file, content, read_bytes) < 0) goto cleanup; } if (read_bytes < 0) goto cleanup; if (git_filebuf_flush(&file) < 0) goto cleanup; error = blob_create_internal(oid, repo, file.path_lock, hintpath, hintpath != NULL); cleanup: git_buf_free(&path); git_filebuf_cleanup(&file); git__free(content); return error; }
int git_blob_create_fromstream_commit(git_oid *out, git_writestream *_stream) { int error; blob_writestream *stream = (blob_writestream *) _stream; /* * We can make this more officient by avoiding writing to * disk, but for now let's re-use the helper functions we * have. */ if ((error = git_filebuf_flush(&stream->fbuf)) < 0) goto cleanup; error = git_blob__create_from_paths(out, NULL, stream->repo, stream->fbuf.path_lock, stream->hintpath, 0, !!stream->hintpath); cleanup: blob_writestream_free(_stream); return error; }