diff --git a/pygit2/decl.h b/pygit2/decl.h index 4f56006..58676ac 100644 --- a/pygit2/decl.h +++ b/pygit2/decl.h @@ -207,11 +207,30 @@ struct git_remote_callbacks { typedef struct git_remote_callbacks git_remote_callbacks; +typedef enum { + GIT_PROXY_NONE, + GIT_PROXY_AUTO, + GIT_PROXY_SPECIFIED, +} git_proxy_t; + +typedef struct { + unsigned int version; + git_proxy_t type; + const char *url; + git_cred_acquire_cb credentials; + git_transport_certificate_check_cb certificate_check; + void *payload; +} git_proxy_options; + +#define GIT_PROXY_OPTIONS_VERSION ... +int git_proxy_init_options(git_proxy_options *opts, unsigned int version); + typedef struct { unsigned int version; unsigned int pb_parallelism; git_remote_callbacks callbacks; - git_strarray custom_headers; + git_proxy_options proxy_opts; + git_strarray custom_headers; } git_push_options; #define GIT_PUSH_OPTIONS_VERSION ... @@ -236,7 +255,8 @@ typedef struct { git_fetch_prune_t prune; int update_fetchhead; git_remote_autotag_option_t download_tags; - git_strarray custom_headers; + git_proxy_options proxy_opts; + git_strarray custom_headers; } git_fetch_options; #define GIT_FETCH_OPTIONS_VERSION ... @@ -738,7 +758,8 @@ typedef struct { unsigned int rename_threshold; unsigned int target_limit; git_diff_similarity_metric *metric; - unsigned int recursion_limit; + unsigned int recursion_limit; + const char *default_driver; git_merge_file_favor_t file_favor; unsigned int file_flags; } git_merge_options; diff --git a/src/repository.c b/src/repository.c index ad3f4e8..355070e 100644 --- a/src/repository.c +++ b/src/repository.c @@ -862,38 +862,17 @@ Repository_create_blob_fromdisk(Repository *self, PyObject *args) } +#define BUFSIZE 4096 + PyDoc_STRVAR(Repository_create_blob_fromiobase__doc__, "create_blob_fromiobase(io.IOBase) -> Oid\n" "\n" "Create a new blob from an IOBase object."); - -int read_chunk(char *content, size_t max_length, void *payload) -{ - PyObject *py_file; - PyObject *py_bytes; - char *bytes; - Py_ssize_t size; - - py_file = (PyObject *)payload; - py_bytes = PyObject_CallMethod(py_file, "read", "i", max_length); - if (!py_bytes) - return -1; - - size = 0; - if (py_bytes != Py_None) { - bytes = PyBytes_AsString(py_bytes); - size = PyBytes_Size(py_bytes); - memcpy(content, bytes, size); - } - - Py_DECREF(py_bytes); - return size; -} - PyObject * Repository_create_blob_fromiobase(Repository *self, PyObject *py_file) { + git_writestream *stream; git_oid oid; PyObject *py_is_readable; int is_readable; @@ -915,8 +894,47 @@ Repository_create_blob_fromiobase(Repository *self, PyObject *py_file) return NULL; } - err = git_blob_create_fromchunks(&oid, self->repo, NULL, &read_chunk, - py_file); + err = git_blob_create_fromstream(&stream, self->repo, NULL); + if (err < 0) + return Error_set(err); + + for (;;) { + PyObject *py_bytes; + char *bytes; + Py_ssize_t size; + + py_bytes = PyObject_CallMethod(py_file, "read", "i", 4096); + if (!py_bytes) + return NULL; + + if (py_bytes == Py_None) { + Py_DECREF(py_bytes); + goto cleanup; + } + + if (PyBytes_AsStringAndSize(py_bytes, &bytes, &size)) { + Py_DECREF(py_bytes); + return NULL; + } + + if (size == 0) { + Py_DECREF(py_bytes); + break; + } + + err = stream->write(stream, bytes, size); + Py_DECREF(py_bytes); + if (err < 0) + goto cleanup; + } + +cleanup: + if (err < 0) { + stream->free(stream); + return Error_set(err); + } + + err = git_blob_create_fromstream_commit(&oid, stream); if (err < 0) return Error_set(err);