From f56107fc613a2cbe8983cc4004c76cc06922e314 Mon Sep 17 00:00:00 2001 From: Michal Niewrzal Date: Tue, 10 Dec 2019 03:51:56 -0800 Subject: [PATCH] uplinkc: add download_range function (#3704) --- lib/uplinkc/object.go | 25 ++++++++++++++++++++++++ lib/uplinkc/testdata/object_test.c | 31 ++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/lib/uplinkc/object.go b/lib/uplinkc/object.go index e7005553b..7ce355055 100644 --- a/lib/uplinkc/object.go +++ b/lib/uplinkc/object.go @@ -278,6 +278,31 @@ func download(bucketRef C.BucketRef, path *C.char, cErr **C.char) C.DownloaderRe })} } +//export download_range +// download_range returns an Object's data from specified range +func download_range(bucketRef C.BucketRef, path *C.char, start, limit int64, cErr **C.char) C.DownloaderRef { + bucket, ok := universe.Get(bucketRef._handle).(*Bucket) + if !ok { + *cErr = C.CString("invalid bucket") + return C.DownloaderRef{} + } + + scope := bucket.scope.child() + + rc, err := bucket.DownloadRange(scope.ctx, C.GoString(path), start, limit) + if err != nil { + if !errs2.IsCanceled(err) { + *cErr = C.CString(fmt.Sprintf("%+v", err)) + } + return C.DownloaderRef{} + } + + return C.DownloaderRef{universe.Add(&Download{ + scope: scope, + rc: rc, + })} +} + //export download_read // download_read reads data upto `length` bytes into `bytes` buffer and returns // the count of bytes read. The exact number of bytes returned depends on different diff --git a/lib/uplinkc/testdata/object_test.c b/lib/uplinkc/testdata/object_test.c index 0c29dbb08..5ede8c14d 100644 --- a/lib/uplinkc/testdata/object_test.c +++ b/lib/uplinkc/testdata/object_test.c @@ -187,6 +187,37 @@ void handle_project(ProjectRef project) { free_downloader(downloader); } + { // download range + long start = 100 + (i+1); + long limit = 1024 * (i+1); + DownloaderRef downloader = download_range(bucket, object_paths[i], start, limit, err); + require_noerror(*err); + + uint8_t *downloaded_data = malloc(limit); + memset(downloaded_data, '\0', limit); + size_t downloaded_total = 0; + + size_t size_to_read = 256 + i; + while (downloaded_total < limit) { + size_t read_size = download_read(downloader, &downloaded_data[downloaded_total], size_to_read, err); + require_noerror(*err); + + if (read_size == 0) { + break; + } + + downloaded_total += read_size; + } + + download_close(downloader, err); + require_noerror(*err); + require(limit == downloaded_total); + require(memcmp(&data[start], downloaded_data, limit) == 0); + + free(downloaded_data); + free_downloader(downloader); + } + if (data != NULL) { free(data); }