elements_upload_data_stream.cc 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "net/base/elements_upload_data_stream.h"
  5. #include <utility>
  6. #include "base/bind.h"
  7. #include "base/check_op.h"
  8. #include "net/base/io_buffer.h"
  9. #include "net/base/net_errors.h"
  10. #include "net/base/upload_bytes_element_reader.h"
  11. #include "net/base/upload_element_reader.h"
  12. namespace net {
  13. ElementsUploadDataStream::ElementsUploadDataStream(
  14. std::vector<std::unique_ptr<UploadElementReader>> element_readers,
  15. int64_t identifier)
  16. : UploadDataStream(false, identifier),
  17. element_readers_(std::move(element_readers)) {}
  18. ElementsUploadDataStream::~ElementsUploadDataStream() = default;
  19. std::unique_ptr<UploadDataStream> ElementsUploadDataStream::CreateWithReader(
  20. std::unique_ptr<UploadElementReader> reader,
  21. int64_t identifier) {
  22. std::vector<std::unique_ptr<UploadElementReader>> readers;
  23. readers.push_back(std::move(reader));
  24. return std::make_unique<ElementsUploadDataStream>(std::move(readers),
  25. identifier);
  26. }
  27. int ElementsUploadDataStream::InitInternal(const NetLogWithSource& net_log) {
  28. return InitElements(0);
  29. }
  30. int ElementsUploadDataStream::ReadInternal(
  31. IOBuffer* buf,
  32. int buf_len) {
  33. DCHECK_GT(buf_len, 0);
  34. return ReadElements(base::MakeRefCounted<DrainableIOBuffer>(buf, buf_len));
  35. }
  36. bool ElementsUploadDataStream::IsInMemory() const {
  37. for (const std::unique_ptr<UploadElementReader>& it : element_readers_) {
  38. if (!it->IsInMemory())
  39. return false;
  40. }
  41. return true;
  42. }
  43. const std::vector<std::unique_ptr<UploadElementReader>>*
  44. ElementsUploadDataStream::GetElementReaders() const {
  45. return &element_readers_;
  46. }
  47. void ElementsUploadDataStream::ResetInternal() {
  48. weak_ptr_factory_.InvalidateWeakPtrs();
  49. read_error_ = OK;
  50. element_index_ = 0;
  51. }
  52. int ElementsUploadDataStream::InitElements(size_t start_index) {
  53. // Call Init() for all elements.
  54. for (size_t i = start_index; i < element_readers_.size(); ++i) {
  55. UploadElementReader* reader = element_readers_[i].get();
  56. // When new_result is ERR_IO_PENDING, InitInternal() will be called
  57. // with start_index == i + 1 when reader->Init() finishes.
  58. int result = reader->Init(
  59. base::BindOnce(&ElementsUploadDataStream::OnInitElementCompleted,
  60. weak_ptr_factory_.GetWeakPtr(), i));
  61. DCHECK(result != ERR_IO_PENDING || !reader->IsInMemory());
  62. DCHECK_LE(result, OK);
  63. if (result != OK)
  64. return result;
  65. }
  66. uint64_t total_size = 0;
  67. for (const std::unique_ptr<UploadElementReader>& it : element_readers_) {
  68. total_size += it->GetContentLength();
  69. }
  70. SetSize(total_size);
  71. return OK;
  72. }
  73. void ElementsUploadDataStream::OnInitElementCompleted(size_t index,
  74. int result) {
  75. DCHECK_NE(ERR_IO_PENDING, result);
  76. // Check the last result.
  77. if (result == OK)
  78. result = InitElements(index + 1);
  79. if (result != ERR_IO_PENDING)
  80. OnInitCompleted(result);
  81. }
  82. int ElementsUploadDataStream::ReadElements(
  83. const scoped_refptr<DrainableIOBuffer>& buf) {
  84. while (read_error_ == OK && element_index_ < element_readers_.size()) {
  85. UploadElementReader* reader = element_readers_[element_index_].get();
  86. if (reader->BytesRemaining() == 0) {
  87. ++element_index_;
  88. continue;
  89. }
  90. if (buf->BytesRemaining() == 0)
  91. break;
  92. int result = reader->Read(
  93. buf.get(), buf->BytesRemaining(),
  94. base::BindOnce(&ElementsUploadDataStream::OnReadElementCompleted,
  95. weak_ptr_factory_.GetWeakPtr(), buf));
  96. if (result == ERR_IO_PENDING)
  97. return ERR_IO_PENDING;
  98. ProcessReadResult(buf, result);
  99. }
  100. if (buf->BytesConsumed() > 0)
  101. return buf->BytesConsumed();
  102. return read_error_;
  103. }
  104. void ElementsUploadDataStream::OnReadElementCompleted(
  105. const scoped_refptr<DrainableIOBuffer>& buf,
  106. int result) {
  107. ProcessReadResult(buf, result);
  108. result = ReadElements(buf);
  109. if (result != ERR_IO_PENDING)
  110. OnReadCompleted(result);
  111. }
  112. void ElementsUploadDataStream::ProcessReadResult(
  113. const scoped_refptr<DrainableIOBuffer>& buf,
  114. int result) {
  115. DCHECK_NE(ERR_IO_PENDING, result);
  116. DCHECK(!read_error_);
  117. if (result >= 0) {
  118. buf->DidConsume(result);
  119. } else {
  120. read_error_ = result;
  121. }
  122. }
  123. } // namespace net