| Index: chrome_frame/urlmon_upload_data_stream.cc
|
| ===================================================================
|
| --- chrome_frame/urlmon_upload_data_stream.cc (revision 0)
|
| +++ chrome_frame/urlmon_upload_data_stream.cc (revision 0)
|
| @@ -0,0 +1,99 @@
|
| +// Copyright (c) 2009 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 "chrome_frame/urlmon_upload_data_stream.h"
|
| +
|
| +#include "net/base/io_buffer.h"
|
| +
|
| +void UrlmonUploadDataStream::Initialize(net::UploadData* upload_data) {
|
| + upload_data_ = upload_data;
|
| + request_body_stream_.reset(new net::UploadDataStream(upload_data));
|
| +}
|
| +
|
| +STDMETHODIMP UrlmonUploadDataStream::Read(void* pv, ULONG cb, ULONG* read) {
|
| + if (pv == NULL) {
|
| + NOTREACHED();
|
| + return E_POINTER;
|
| + }
|
| +
|
| + // Have we already read past the end of the stream?
|
| + if (request_body_stream_->position() >= request_body_stream_->size()) {
|
| + if (read) {
|
| + *read = 0;
|
| + }
|
| + return S_FALSE;
|
| + }
|
| +
|
| + uint64 total_bytes_to_copy = std::min(static_cast<uint64>(cb),
|
| + request_body_stream_->size() - request_body_stream_->position());
|
| + uint64 initial_position = request_body_stream_->position();
|
| +
|
| + uint64 bytes_copied = 0;
|
| +
|
| + char* write_pointer = reinterpret_cast<char*>(pv);
|
| + while (bytes_copied < total_bytes_to_copy) {
|
| + net::IOBuffer* buf = request_body_stream_->buf();
|
| +
|
| + // Make sure our length doesn't run past the end of the available data.
|
| + size_t bytes_to_copy_now = static_cast<size_t>(
|
| + std::min(static_cast<uint64>(request_body_stream_->buf_len()),
|
| + total_bytes_to_copy - bytes_copied));
|
| +
|
| + memcpy(write_pointer, buf->data(), bytes_to_copy_now);
|
| +
|
| + // Advance our copy tally
|
| + bytes_copied += bytes_to_copy_now;
|
| +
|
| + // Advance our write pointer
|
| + write_pointer += bytes_to_copy_now;
|
| +
|
| + // Advance the UploadDataStream read pointer:
|
| + request_body_stream_->DidConsume(bytes_to_copy_now);
|
| + }
|
| +
|
| + DCHECK(bytes_copied == total_bytes_to_copy);
|
| + DCHECK(request_body_stream_->position() ==
|
| + initial_position + total_bytes_to_copy);
|
| +
|
| + if (read) {
|
| + *read = static_cast<ULONG>(total_bytes_to_copy);
|
| + }
|
| +
|
| + return S_OK;
|
| +}
|
| +
|
| +STDMETHODIMP UrlmonUploadDataStream::Seek(LARGE_INTEGER move, DWORD origin,
|
| + ULARGE_INTEGER* new_pos) {
|
| + // UploadDataStream is really not very seek-able, so for now allow
|
| + // STREAM_SEEK_SETs to work with a 0 offset, but fail on everything else.
|
| + if (origin == STREAM_SEEK_SET && move.QuadPart == 0) {
|
| + if (request_body_stream_->position() != 0) {
|
| + request_body_stream_.reset(new net::UploadDataStream(upload_data_));
|
| + }
|
| + if (new_pos) {
|
| + new_pos->QuadPart = 0;
|
| + }
|
| + return S_OK;
|
| + }
|
| +
|
| + DCHECK(false) << __FUNCTION__;
|
| + return STG_E_INVALIDFUNCTION;
|
| +}
|
| +
|
| +STDMETHODIMP UrlmonUploadDataStream::Stat(STATSTG *stat_stg,
|
| + DWORD grf_stat_flag) {
|
| + if (stat_stg == NULL)
|
| + return E_POINTER;
|
| +
|
| + memset(stat_stg, 0, sizeof(STATSTG));
|
| + if (0 == (grf_stat_flag & STATFLAG_NONAME)) {
|
| + const wchar_t kStreamBuffer[] = L"PostStream";
|
| + stat_stg->pwcsName =
|
| + static_cast<wchar_t*>(::CoTaskMemAlloc(sizeof(kStreamBuffer)));
|
| + lstrcpy(stat_stg->pwcsName, kStreamBuffer);
|
| + }
|
| + stat_stg->type = STGTY_STREAM;
|
| + stat_stg->cbSize.QuadPart = upload_data_->GetContentLength();
|
| + return S_OK;
|
| +}
|
|
|