gchar *key; /* Key to read/write */
BlueSkyRCStr *data; /* Data read/to write */
+ /* For range requests on reads: starting byte offset and length; len 0
+ * implies reading to the end of the object. At completion, the backend
+ * should set range_done if a range read was made; if not set the entire
+ * object was read and the storage layer will select out just the
+ * appropriate bytes. */
+ size_t start, len;
+ gboolean range_done;
+
int result; /* Result code; 0 for success. */
struct BlueSkyNotifierList *notifiers;
gint notifier_count;
handler.responseHandler.completeCallback = s3store_response_callback;
handler.getObjectDataCallback = s3store_get_handler;
- S3_get_object(&store->bucket, async->key, NULL, 0, 0, NULL,
- &handler, &info);
+ S3_get_object(&store->bucket, async->key, NULL,
+ async->start, async->len, NULL, &handler, &info);
+ async->range_done = TRUE;
if (info.success) {
async->data = bluesky_string_new_from_gstring(info.buf);
async->op = STORE_OP_NONE;
async->key = NULL;
async->data = NULL;
+ async->start = async->len = 0;
+ async->range_done = FALSE;
async->result = -1;
async->notifiers = NULL;
async->notifier_count = 0;
g_mutex_unlock(async->store->lock);
}
+ /* If the request was a range request but the backend read the entire
+ * object, select out the appropriate bytes. */
+ if (async->op == STORE_OP_GET
+ && !async->range_done
+ && async->result == 0
+ && async->data != NULL) {
+ if (async->start != 0 || async->len != 0) {
+ /* If the caller requesteda read outside the object, return an
+ * error. */
+ if (async->start + async->len > async->data->len) {
+ g_warning("Range request outside object boundaries!\n");
+ async->result = -1;
+ } else {
+ if (async->len == 0)
+ async->len = async->data->len - async->start;
+ BlueSkyRCStr *newstr = bluesky_string_new(g_memdup(&async->data->data[async->start], async->len), async->len);
+ bluesky_string_unref(async->data);
+ async->data = newstr;
+ async->range_done = TRUE;
+ }
+ }
+ }
+
async->status = ASYNC_COMPLETE;
g_cond_broadcast(async->completion_cond);