1 // Copyright (c) 2011 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
) {
22 // Have we already read past the end of the stream?
23 if (request_body_stream_
->eof()) {
30 uint64 total_bytes_to_copy
= std::min(static_cast<uint64
>(cb
),
31 static_cast<uint64
>(request_body_stream_
->buf_len()));
33 uint64 bytes_copied
= 0;
35 char* write_pointer
= reinterpret_cast<char*>(pv
);
36 while (bytes_copied
< total_bytes_to_copy
) {
37 net::IOBuffer
* buf
= request_body_stream_
->buf();
39 // Make sure our length doesn't run past the end of the available data.
40 size_t bytes_to_copy_now
= static_cast<size_t>(
41 std::min(static_cast<uint64
>(request_body_stream_
->buf_len()),
42 total_bytes_to_copy
- bytes_copied
));
44 memcpy(write_pointer
, buf
->data(), bytes_to_copy_now
);
46 // Advance our copy tally
47 bytes_copied
+= bytes_to_copy_now
;
49 // Advance our write pointer
50 write_pointer
+= bytes_to_copy_now
;
52 // Advance the UploadDataStream read pointer:
53 request_body_stream_
->MarkConsumedAndFillBuffer(bytes_to_copy_now
);
56 DCHECK(bytes_copied
== total_bytes_to_copy
);
59 *read
= static_cast<ULONG
>(total_bytes_to_copy
);
65 STDMETHODIMP
UrlmonUploadDataStream::Seek(LARGE_INTEGER move
, DWORD origin
,
66 ULARGE_INTEGER
* new_pos
) {
67 // UploadDataStream is really not very seek-able, so for now allow
68 // STREAM_SEEK_SETs to work with a 0 offset, but fail on everything else.
69 if (origin
== STREAM_SEEK_SET
&& move
.QuadPart
== 0) {
70 if (request_body_stream_
->position() != 0) {
71 request_body_stream_
.reset(
72 net::UploadDataStream::Create(upload_data_
, NULL
));
73 DCHECK(request_body_stream_
.get());
76 new_pos
->QuadPart
= 0;
81 DCHECK(false) << __FUNCTION__
;
82 return STG_E_INVALIDFUNCTION
;
85 STDMETHODIMP
UrlmonUploadDataStream::Stat(STATSTG
*stat_stg
,
86 DWORD grf_stat_flag
) {
90 memset(stat_stg
, 0, sizeof(STATSTG
));
91 if (0 == (grf_stat_flag
& STATFLAG_NONAME
)) {
92 const wchar_t kStreamBuffer
[] = L
"PostStream";
94 static_cast<wchar_t*>(::CoTaskMemAlloc(sizeof(kStreamBuffer
)));
95 lstrcpy(stat_stg
->pwcsName
, kStreamBuffer
);
97 stat_stg
->type
= STGTY_STREAM
;
98 stat_stg
->cbSize
.QuadPart
= upload_data_
->GetContentLength();