Another take on menu's. This uses the hosting menu scroll view container as a menuba...
[chromium-blink-merge.git] / chrome_frame / urlmon_upload_data_stream.cc
blob2c40ca2d113738cb2ff66977c4a28ce1289ff3af
1 // Copyright (c) 2009 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 "chrome_frame/urlmon_upload_data_stream.h"
7 #include "net/base/io_buffer.h"
8 #include "net/base/net_errors.h"
10 void UrlmonUploadDataStream::Initialize(net::UploadData* upload_data) {
11 upload_data_ = upload_data;
12 request_body_stream_.reset(net::UploadDataStream::Create(upload_data, NULL));
13 DCHECK(request_body_stream_.get());
16 STDMETHODIMP UrlmonUploadDataStream::Read(void* pv, ULONG cb, ULONG* read) {
17 if (pv == NULL) {
18 NOTREACHED();
19 return E_POINTER;
22 // Have we already read past the end of the stream?
23 if (request_body_stream_->position() >= request_body_stream_->size()) {
24 if (read) {
25 *read = 0;
27 return S_FALSE;
30 uint64 total_bytes_to_copy = std::min(static_cast<uint64>(cb),
31 request_body_stream_->size() - request_body_stream_->position());
32 uint64 initial_position = request_body_stream_->position();
34 uint64 bytes_copied = 0;
36 char* write_pointer = reinterpret_cast<char*>(pv);
37 while (bytes_copied < total_bytes_to_copy) {
38 net::IOBuffer* buf = request_body_stream_->buf();
40 // Make sure our length doesn't run past the end of the available data.
41 size_t bytes_to_copy_now = static_cast<size_t>(
42 std::min(static_cast<uint64>(request_body_stream_->buf_len()),
43 total_bytes_to_copy - bytes_copied));
45 memcpy(write_pointer, buf->data(), bytes_to_copy_now);
47 // Advance our copy tally
48 bytes_copied += bytes_to_copy_now;
50 // Advance our write pointer
51 write_pointer += bytes_to_copy_now;
53 // Advance the UploadDataStream read pointer:
54 request_body_stream_->DidConsume(bytes_to_copy_now);
57 DCHECK(bytes_copied == total_bytes_to_copy);
58 DCHECK(request_body_stream_->position() ==
59 initial_position + total_bytes_to_copy);
61 if (read) {
62 *read = static_cast<ULONG>(total_bytes_to_copy);
65 return S_OK;
68 STDMETHODIMP UrlmonUploadDataStream::Seek(LARGE_INTEGER move, DWORD origin,
69 ULARGE_INTEGER* new_pos) {
70 // UploadDataStream is really not very seek-able, so for now allow
71 // STREAM_SEEK_SETs to work with a 0 offset, but fail on everything else.
72 if (origin == STREAM_SEEK_SET && move.QuadPart == 0) {
73 if (request_body_stream_->position() != 0) {
74 request_body_stream_.reset(
75 net::UploadDataStream::Create(upload_data_, NULL));
76 DCHECK(request_body_stream_.get());
78 if (new_pos) {
79 new_pos->QuadPart = 0;
81 return S_OK;
84 DCHECK(false) << __FUNCTION__;
85 return STG_E_INVALIDFUNCTION;
88 STDMETHODIMP UrlmonUploadDataStream::Stat(STATSTG *stat_stg,
89 DWORD grf_stat_flag) {
90 if (stat_stg == NULL)
91 return E_POINTER;
93 memset(stat_stg, 0, sizeof(STATSTG));
94 if (0 == (grf_stat_flag & STATFLAG_NONAME)) {
95 const wchar_t kStreamBuffer[] = L"PostStream";
96 stat_stg->pwcsName =
97 static_cast<wchar_t*>(::CoTaskMemAlloc(sizeof(kStreamBuffer)));
98 lstrcpy(stat_stg->pwcsName, kStreamBuffer);
100 stat_stg->type = STGTY_STREAM;
101 stat_stg->cbSize.QuadPart = upload_data_->GetContentLength();
102 return S_OK;