| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "net/base/upload_data_stream.h" |
| |
| #include "base/callback_helpers.h" |
| #include "base/logging.h" |
| #include "net/base/io_buffer.h" |
| #include "net/base/net_errors.h" |
| |
| namespace net { |
| |
| UploadDataStream::UploadDataStream(bool is_chunked, int64_t identifier) |
| : total_size_(0), |
| current_position_(0), |
| identifier_(identifier), |
| is_chunked_(is_chunked), |
| initialized_successfully_(false), |
| is_eof_(false) { |
| } |
| |
| UploadDataStream::~UploadDataStream() { |
| } |
| |
| int UploadDataStream::Init(const CompletionCallback& callback) { |
| Reset(); |
| DCHECK(!initialized_successfully_); |
| DCHECK(callback_.is_null()); |
| DCHECK(!callback.is_null() || IsInMemory()); |
| int result = InitInternal(); |
| if (result == ERR_IO_PENDING) { |
| DCHECK(!IsInMemory()); |
| callback_ = callback; |
| } else { |
| OnInitCompleted(result); |
| } |
| return result; |
| } |
| |
| int UploadDataStream::Read(IOBuffer* buf, |
| int buf_len, |
| const CompletionCallback& callback) { |
| DCHECK(!callback.is_null() || IsInMemory()); |
| DCHECK(initialized_successfully_); |
| DCHECK_GT(buf_len, 0); |
| if (is_eof_) |
| return 0; |
| int result = ReadInternal(buf, buf_len); |
| if (result == ERR_IO_PENDING) { |
| DCHECK(!IsInMemory()); |
| callback_ = callback; |
| } else { |
| OnReadCompleted(result); |
| } |
| return result; |
| } |
| |
| bool UploadDataStream::IsEOF() const { |
| DCHECK(initialized_successfully_); |
| DCHECK(is_chunked_ || is_eof_ == (current_position_ == total_size_)); |
| return is_eof_; |
| } |
| |
| void UploadDataStream::Reset() { |
| current_position_ = 0; |
| initialized_successfully_ = false; |
| is_eof_ = false; |
| total_size_ = 0; |
| callback_.Reset(); |
| ResetInternal(); |
| } |
| |
| void UploadDataStream::SetSize(uint64_t size) { |
| DCHECK(!initialized_successfully_); |
| DCHECK(!is_chunked_); |
| total_size_ = size; |
| } |
| |
| void UploadDataStream::SetIsFinalChunk() { |
| DCHECK(initialized_successfully_); |
| DCHECK(is_chunked_); |
| DCHECK(!is_eof_); |
| is_eof_ = true; |
| } |
| |
| bool UploadDataStream::IsInMemory() const { |
| return false; |
| } |
| |
| const ScopedVector<UploadElementReader>* |
| UploadDataStream::GetElementReaders() const { |
| return NULL; |
| } |
| |
| void UploadDataStream::OnInitCompleted(int result) { |
| DCHECK_NE(ERR_IO_PENDING, result); |
| DCHECK(!initialized_successfully_); |
| DCHECK_EQ(0u, current_position_); |
| DCHECK(!is_eof_); |
| |
| if (result == OK) { |
| initialized_successfully_ = true; |
| if (!is_chunked_ && total_size_ == 0) |
| is_eof_ = true; |
| } |
| if (!callback_.is_null()) |
| base::ResetAndReturn(&callback_).Run(result); |
| } |
| |
| void UploadDataStream::OnReadCompleted(int result) { |
| DCHECK_GE(result, 0); |
| DCHECK(initialized_successfully_); |
| |
| current_position_ += result; |
| if (!is_chunked_) { |
| DCHECK_LE(current_position_, total_size_); |
| if (current_position_ == total_size_) |
| is_eof_ = true; |
| } |
| |
| DCHECK(result > 0 || is_eof_); |
| |
| if (!callback_.is_null()) |
| base::ResetAndReturn(&callback_).Run(result); |
| } |
| |
| } // namespace net |