// 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 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 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* 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