size_t Net::Request::Read(void *_buffer, size_t buffer_size, unsigned long timeout) { assert(handle != NULL); const int timeout_ms = timeout == INFINITE ? -1 : timeout; Buffer::Range range; CURLMcode mcode = CURLM_CALL_MULTI_PERFORM; while (true) { range = buffer.Read(); if (!range.IsEmpty()) break; CURLcode code = session.InfoRead(handle); if (code != CURLE_AGAIN) return 0; if (mcode != CURLM_CALL_MULTI_PERFORM && !session.Select(timeout_ms)) return 0; CURLMcode mcode = session.Perform(); if (mcode != CURLM_OK && mcode != CURLM_CALL_MULTI_PERFORM) return 0; } --buffer_size; if (buffer_size > range.length) buffer_size = range.length; uint8_t *p = (uint8_t *)_buffer; std::copy(range.data, range.data + buffer_size, p); p[buffer_size] = 0; buffer.Consume(buffer_size); curl_easy_pause(handle, CURLPAUSE_CONT); return buffer_size; }
size_t Net::Request::Read(void *_buffer, size_t buffer_size, unsigned _timeout_ms) { const int timeout_ms = _timeout_ms == INFINITE ? -1 : _timeout_ms; Buffer::Range range; CURLMcode mcode = CURLM_CALL_MULTI_PERFORM; while (true) { range = buffer.Read(); if (!range.IsEmpty()) break; CURLcode code = session.InfoRead(handle.GetHandle()); if (code != CURLE_AGAIN) { if (code != CURLE_OK) throw std::runtime_error(curl_easy_strerror(code)); return 0; } if (mcode != CURLM_CALL_MULTI_PERFORM) session.Select(timeout_ms); mcode = session.Perform(); if (mcode != CURLM_OK && mcode != CURLM_CALL_MULTI_PERFORM) throw std::runtime_error(curl_multi_strerror(mcode)); } --buffer_size; if (buffer_size > range.size) buffer_size = range.size; uint8_t *p = (uint8_t *)_buffer; std::copy_n(range.data, buffer_size, p); p[buffer_size] = 0; buffer.Consume(buffer_size); handle.Unpause(); return buffer_size; }