#ifndef COMPONENTS_CRONET_NATIVE_UPLOAD_DATA_SINK_H_
#define COMPONENTS_CRONET_NATIVE_UPLOAD_DATA_SINK_H_
#include <memory>
#include "base/memory/raw_ptr.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "base/task/single_thread_task_runner.h"
#include "components/cronet/cronet_context.h"
#include "components/cronet/cronet_upload_data_stream.h"
#include "components/cronet/cronet_url_request.h"
#include "components/cronet/native/generated/cronet.idl_impl_interface.h"
namespace cronet {
class Cronet_UrlRequestImpl;
class Cronet_BufferWithIOBuffer;
class Cronet_UploadDataSinkImpl : public Cronet_UploadDataSink {
public:
Cronet_UploadDataSinkImpl(Cronet_UrlRequestImpl* url_request,
Cronet_UploadDataProvider* upload_data_provider,
Cronet_Executor* upload_data_provider_executor);
Cronet_UploadDataSinkImpl(const Cronet_UploadDataSinkImpl&) = delete;
Cronet_UploadDataSinkImpl& operator=(const Cronet_UploadDataSinkImpl&) =
delete;
~Cronet_UploadDataSinkImpl() override;
void InitRequest(CronetURLRequest* request);
void PostCloseToExecutor();
private:
class NetworkTasks;
enum UserCallback { READ, REWIND, GET_LENGTH, NOT_IN_CALLBACK };
void OnReadSucceeded(uint64_t bytes_read, bool final_chunk) override;
void OnReadError(Cronet_String error_message) override;
void OnRewindSucceeded() override;
void OnRewindError(Cronet_String error_message) override;
void InitializeUploadDataStream(
base::WeakPtr<CronetUploadDataStream> upload_data_stream,
scoped_refptr<base::SingleThreadTaskRunner> network_task_runner);
void Read(scoped_refptr<net::IOBuffer> buffer, int buf_len);
void Rewind();
void Close();
void CheckState(UserCallback expected_state);
const raw_ptr<Cronet_UrlRequestImpl> url_request_ = nullptr;
Cronet_ExecutorPtr const upload_data_provider_executor_ = nullptr;
scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
base::WeakPtr<CronetUploadDataStream> upload_data_stream_;
bool is_chunked_ = false;
uint64_t length_ = 0;
uint64_t remaining_length_ = 0;
base::Lock lock_;
Cronet_UploadDataProviderPtr upload_data_provider_ = nullptr;
UserCallback in_which_user_callback_ = NOT_IN_CALLBACK;
bool close_when_not_in_callback_ = false;
std::unique_ptr<Cronet_BufferWithIOBuffer> buffer_;
};
}
#endif