|  | #include "http2/adapter/nghttp2_data_provider.h" | 
|  |  | 
|  | #include "http2/adapter/http2_visitor_interface.h" | 
|  | #include "http2/adapter/nghttp2_util.h" | 
|  |  | 
|  | namespace http2 { | 
|  | namespace adapter { | 
|  | namespace callbacks { | 
|  |  | 
|  | namespace { | 
|  | const size_t kFrameHeaderSize = 9; | 
|  | } | 
|  |  | 
|  | ssize_t DataFrameSourceReadCallback(nghttp2_session* /* session */, | 
|  | int32_t /* stream_id */, | 
|  | uint8_t* /* buf */, | 
|  | size_t length, | 
|  | uint32_t* data_flags, | 
|  | nghttp2_data_source* source, | 
|  | void* /* user_data */) { | 
|  | *data_flags |= NGHTTP2_DATA_FLAG_NO_COPY; | 
|  | auto* frame_source = static_cast<DataFrameSource*>(source->ptr); | 
|  | auto [result_length, done] = frame_source->SelectPayloadLength(length); | 
|  | if (result_length == DataFrameSource::kBlocked) { | 
|  | return NGHTTP2_ERR_DEFERRED; | 
|  | } else if (result_length == DataFrameSource::kError) { | 
|  | return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; | 
|  | } | 
|  | if (done) { | 
|  | *data_flags |= NGHTTP2_DATA_FLAG_EOF; | 
|  | } | 
|  | if (!frame_source->send_fin()) { | 
|  | *data_flags |= NGHTTP2_DATA_FLAG_NO_END_STREAM; | 
|  | } | 
|  | return result_length; | 
|  | } | 
|  |  | 
|  | int DataFrameSourceSendCallback(nghttp2_session* /* session */, | 
|  | nghttp2_frame* /* frame */, | 
|  | const uint8_t* framehd, | 
|  | size_t length, | 
|  | nghttp2_data_source* source, | 
|  | void* /* user_data */) { | 
|  | auto* frame_source = static_cast<DataFrameSource*>(source->ptr); | 
|  | frame_source->Send(ToStringView(framehd, kFrameHeaderSize), length); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | }  // namespace callbacks | 
|  |  | 
|  | std::unique_ptr<nghttp2_data_provider> MakeDataProvider( | 
|  | DataFrameSource* source) { | 
|  | if (source == nullptr) { | 
|  | return nullptr; | 
|  | } | 
|  | auto provider = absl::make_unique<nghttp2_data_provider>(); | 
|  | provider->source.ptr = source; | 
|  | provider->read_callback = &callbacks::DataFrameSourceReadCallback; | 
|  | return provider; | 
|  | } | 
|  |  | 
|  | }  // namespace adapter | 
|  | }  // namespace http2 |