| #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 == 0 && !done) { | 
 |     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 |