input/curl: move _seek() into the CurlInputStream class
This commit is contained in:
parent
2ae60767a3
commit
0dd5ebbdbe
@ -184,6 +184,8 @@ struct CurlInputStream {
|
|||||||
return easy == nullptr && buffers.empty();
|
return easy == nullptr && buffers.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Seek(InputPlugin::offset_type offset, int whence, Error &error);
|
||||||
|
|
||||||
Tag *ReadTag();
|
Tag *ReadTag();
|
||||||
|
|
||||||
bool IsAvailable() const {
|
bool IsAvailable() const {
|
||||||
@ -1063,21 +1065,17 @@ CurlInputStream::InitEasy(Error &error)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
inline bool
|
||||||
input_curl_seek(InputStream *is, InputPlugin::offset_type offset,
|
CurlInputStream::Seek(InputPlugin::offset_type offset, int whence,
|
||||||
int whence,
|
Error &error)
|
||||||
Error &error)
|
|
||||||
{
|
{
|
||||||
CurlInputStream *c = (CurlInputStream *)is;
|
assert(base.ready);
|
||||||
bool ret;
|
|
||||||
|
|
||||||
assert(is->ready);
|
if (whence == SEEK_SET && offset == base.offset)
|
||||||
|
|
||||||
if (whence == SEEK_SET && offset == is->offset)
|
|
||||||
/* no-op */
|
/* no-op */
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (!is->seekable)
|
if (!base.seekable)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* calculate the absolute offset */
|
/* calculate the absolute offset */
|
||||||
@ -1087,15 +1085,15 @@ input_curl_seek(InputStream *is, InputPlugin::offset_type offset,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SEEK_CUR:
|
case SEEK_CUR:
|
||||||
offset += is->offset;
|
offset += base.offset;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SEEK_END:
|
case SEEK_END:
|
||||||
if (is->size < 0)
|
if (base.size < 0)
|
||||||
/* stream size is not known */
|
/* stream size is not known */
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
offset += is->size;
|
offset += base.size;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -1107,67 +1105,75 @@ input_curl_seek(InputStream *is, InputPlugin::offset_type offset,
|
|||||||
|
|
||||||
/* check if we can fast-forward the buffer */
|
/* check if we can fast-forward the buffer */
|
||||||
|
|
||||||
while (offset > is->offset && !c->buffers.empty()) {
|
while (offset > base.offset && !buffers.empty()) {
|
||||||
auto &buffer = c->buffers.front();
|
auto &buffer = buffers.front();
|
||||||
size_t length = buffer.Available();
|
size_t length = buffer.Available();
|
||||||
if (offset - is->offset < (InputPlugin::offset_type)length)
|
if (offset - base.offset < (InputPlugin::offset_type)length)
|
||||||
length = offset - is->offset;
|
length = offset - base.offset;
|
||||||
|
|
||||||
const bool empty = !buffer.Consume(length);
|
const bool empty = !buffer.Consume(length);
|
||||||
if (empty)
|
if (empty)
|
||||||
c->buffers.pop_front();
|
buffers.pop_front();
|
||||||
|
|
||||||
is->offset += length;
|
base.offset += length;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset == is->offset)
|
if (offset == base.offset)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* close the old connection and open a new one */
|
/* close the old connection and open a new one */
|
||||||
|
|
||||||
c->base.mutex.unlock();
|
base.mutex.unlock();
|
||||||
|
|
||||||
c->FreeEasyIndirect();
|
FreeEasyIndirect();
|
||||||
c->buffers.clear();
|
buffers.clear();
|
||||||
|
|
||||||
is->offset = offset;
|
base.offset = offset;
|
||||||
if (is->offset == is->size) {
|
if (base.offset == base.size) {
|
||||||
/* seek to EOF: simulate empty result; avoid
|
/* seek to EOF: simulate empty result; avoid
|
||||||
triggering a "416 Requested Range Not Satisfiable"
|
triggering a "416 Requested Range Not Satisfiable"
|
||||||
response */
|
response */
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = c->InitEasy(error);
|
if (!InitEasy(error))
|
||||||
if (!ret)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* send the "Range" header */
|
/* send the "Range" header */
|
||||||
|
|
||||||
if (is->offset > 0) {
|
if (base.offset > 0) {
|
||||||
sprintf(c->range, "%lld-", (long long)is->offset);
|
sprintf(range, "%lld-", (long long)base.offset);
|
||||||
curl_easy_setopt(c->easy, CURLOPT_RANGE, c->range);
|
curl_easy_setopt(easy, CURLOPT_RANGE, range);
|
||||||
}
|
}
|
||||||
|
|
||||||
c->base.ready = false;
|
base.ready = false;
|
||||||
|
|
||||||
if (!input_curl_easy_add_indirect(c, error))
|
if (!input_curl_easy_add_indirect(this, error))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
c->base.mutex.lock();
|
base.mutex.lock();
|
||||||
|
|
||||||
while (!c->base.ready)
|
while (!base.ready)
|
||||||
c->base.cond.wait(c->base.mutex);
|
base.cond.wait(base.mutex);
|
||||||
|
|
||||||
if (c->postponed_error.IsDefined()) {
|
if (postponed_error.IsDefined()) {
|
||||||
error = std::move(c->postponed_error);
|
error = std::move(postponed_error);
|
||||||
c->postponed_error.Clear();
|
postponed_error.Clear();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
input_curl_seek(InputStream *is, InputPlugin::offset_type offset,
|
||||||
|
int whence,
|
||||||
|
Error &error)
|
||||||
|
{
|
||||||
|
CurlInputStream &c = *(CurlInputStream *)is;
|
||||||
|
return c.Seek(offset, whence, error);
|
||||||
|
}
|
||||||
|
|
||||||
static InputStream *
|
static InputStream *
|
||||||
input_curl_open(const char *url, Mutex &mutex, Cond &cond,
|
input_curl_open(const char *url, Mutex &mutex, Cond &cond,
|
||||||
Error &error)
|
Error &error)
|
||||||
|
Loading…
Reference in New Issue
Block a user