1 // Copyright 2014 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.
5 #include "net/base/chunked_upload_data_stream.h"
7 #include "base/logging.h"
8 #include "base/stl_util.h"
9 #include "net/base/io_buffer.h"
10 #include "net/base/net_errors.h"
14 ChunkedUploadDataStream::ChunkedUploadDataStream(int64 identifier
)
15 : UploadDataStream(true, identifier
),
18 all_data_appended_(false),
22 ChunkedUploadDataStream::~ChunkedUploadDataStream() {
25 void ChunkedUploadDataStream::AppendData(
26 const char* data
, int data_len
, bool is_done
) {
27 DCHECK(!all_data_appended_
);
28 DCHECK(data_len
> 0 || is_done
);
31 upload_data_
.push_back(new std::vector
<char>(data
, data
+ data_len
));
33 all_data_appended_
= is_done
;
35 if (!read_buffer_
.get())
38 int result
= ReadChunk(read_buffer_
.get(), read_buffer_len_
);
39 // Shouldn't get an error or ERR_IO_PENDING.
43 OnReadCompleted(result
);
46 int ChunkedUploadDataStream::InitInternal() {
47 // ResetInternal should already have been called.
48 DCHECK(!read_buffer_
.get());
49 DCHECK_EQ(0u, read_index_
);
50 DCHECK_EQ(0u, read_offset_
);
54 int ChunkedUploadDataStream::ReadInternal(IOBuffer
* buf
, int buf_len
) {
55 DCHECK_LT(0, buf_len
);
56 DCHECK(!read_buffer_
.get());
58 int result
= ReadChunk(buf
, buf_len
);
59 if (result
== ERR_IO_PENDING
) {
61 read_buffer_len_
= buf_len
;
66 void ChunkedUploadDataStream::ResetInternal() {
73 int ChunkedUploadDataStream::ReadChunk(IOBuffer
* buf
, int buf_len
) {
74 // Copy as much data as possible from |upload_data_| to |buf|.
76 while (read_index_
< upload_data_
.size() && bytes_read
< buf_len
) {
77 std::vector
<char>* data
= upload_data_
[read_index_
];
78 size_t bytes_to_read
=
79 std::min(static_cast<size_t>(buf_len
- bytes_read
),
80 data
->size() - read_offset_
);
81 memcpy(buf
->data() + bytes_read
,
82 vector_as_array(data
) + read_offset_
,
84 bytes_read
+= bytes_to_read
;
85 read_offset_
+= bytes_to_read
;
86 if (read_offset_
== data
->size()) {
91 DCHECK_LE(bytes_read
, buf_len
);
93 // If no data was written, and not all data has been appended, return
94 // ERR_IO_PENDING. The read will be completed in the next call to AppendData.
95 if (bytes_read
== 0 && !all_data_appended_
)
96 return ERR_IO_PENDING
;
98 if (read_index_
== upload_data_
.size() && all_data_appended_
)