roll skia to 4057
[chromium-blink-merge.git] / chrome_frame / urlmon_upload_data_stream.cc
blob90dd458b4dde2f4193814049c66b8b5b96815967
1 // Copyright (c) 2012 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(
13 new net::UploadDataStream(upload_data));
14 const int result = request_body_stream_->Init();
15 DCHECK_EQ(net::OK, result);
18 STDMETHODIMP UrlmonUploadDataStream::Read(void* pv, ULONG cb, ULONG* read) {
19 if (pv == NULL) {
20 NOTREACHED();
21 return E_POINTER;
24 // Have we already read past the end of the stream?
25 if (request_body_stream_->IsEOF()) {
26 if (read) {
27 *read = 0;
29 return S_FALSE;
32 // The data in request_body_stream_ can be smaller than 'cb' so it's not
33 // guaranteed that we'll be able to read total_bytes_to_copy bytes.
34 uint64 total_bytes_to_copy = cb;
36 uint64 bytes_copied = 0;
38 char* write_pointer = reinterpret_cast<char*>(pv);
39 while (bytes_copied < total_bytes_to_copy) {
40 size_t bytes_to_copy_now = total_bytes_to_copy - bytes_copied;
42 scoped_refptr<net::IOBufferWithSize> buf(
43 new net::IOBufferWithSize(bytes_to_copy_now));
44 int bytes_read = request_body_stream_->Read(buf, buf->size());
45 if (bytes_read == 0) // Reached the end of the stream.
46 break;
48 memcpy(write_pointer, buf->data(), bytes_read);
50 // Advance our copy tally
51 bytes_copied += bytes_read;
53 // Advance our write pointer
54 write_pointer += bytes_read;
57 DCHECK_LE(bytes_copied, total_bytes_to_copy);
59 if (read) {
60 *read = static_cast<ULONG>(bytes_copied);
63 return S_OK;
66 STDMETHODIMP UrlmonUploadDataStream::Seek(LARGE_INTEGER move, DWORD origin,
67 ULARGE_INTEGER* new_pos) {
68 // UploadDataStream is really not very seek-able, so for now allow
69 // STREAM_SEEK_SETs to work with a 0 offset, but fail on everything else.
70 if (origin == STREAM_SEEK_SET && move.QuadPart == 0) {
71 if (request_body_stream_->position() != 0) {
72 request_body_stream_.reset(new net::UploadDataStream(upload_data_));
73 const int result = request_body_stream_->Init();
74 DCHECK_EQ(net::OK, result);
76 if (new_pos) {
77 new_pos->QuadPart = 0;
79 return S_OK;
82 DCHECK(false) << __FUNCTION__;
83 return STG_E_INVALIDFUNCTION;
86 STDMETHODIMP UrlmonUploadDataStream::Stat(STATSTG *stat_stg,
87 DWORD grf_stat_flag) {
88 if (stat_stg == NULL)
89 return E_POINTER;
91 memset(stat_stg, 0, sizeof(STATSTG));
92 if (0 == (grf_stat_flag & STATFLAG_NONAME)) {
93 const wchar_t kStreamBuffer[] = L"PostStream";
94 stat_stg->pwcsName =
95 static_cast<wchar_t*>(::CoTaskMemAlloc(sizeof(kStreamBuffer)));
96 lstrcpy(stat_stg->pwcsName, kStreamBuffer);
98 stat_stg->type = STGTY_STREAM;
99 stat_stg->cbSize.QuadPart = upload_data_->GetContentLengthSync();
100 return S_OK;