blob: 936c9128833017c91e5738b4338974748ec7af4e [file] [log] [blame]
// 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<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