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"
9 void UrlmonUploadDataStream::Initialize(net::UploadData
* upload_data
) {
10 upload_data_
= upload_data
;
11 request_body_stream_
.reset(new net::UploadDataStream(upload_data
));
14 STDMETHODIMP
UrlmonUploadDataStream::Read(void* pv
, ULONG cb
, ULONG
* read
) {
20 // Have we already read past the end of the stream?
21 if (request_body_stream_
->position() >= request_body_stream_
->size()) {
28 uint64 total_bytes_to_copy
= std::min(static_cast<uint64
>(cb
),
29 request_body_stream_
->size() - request_body_stream_
->position());
30 uint64 initial_position
= request_body_stream_
->position();
32 uint64 bytes_copied
= 0;
34 char* write_pointer
= reinterpret_cast<char*>(pv
);
35 while (bytes_copied
< total_bytes_to_copy
) {
36 net::IOBuffer
* buf
= request_body_stream_
->buf();
38 // Make sure our length doesn't run past the end of the available data.
39 size_t bytes_to_copy_now
= static_cast<size_t>(
40 std::min(static_cast<uint64
>(request_body_stream_
->buf_len()),
41 total_bytes_to_copy
- bytes_copied
));
43 memcpy(write_pointer
, buf
->data(), bytes_to_copy_now
);
45 // Advance our copy tally
46 bytes_copied
+= bytes_to_copy_now
;
48 // Advance our write pointer
49 write_pointer
+= bytes_to_copy_now
;
51 // Advance the UploadDataStream read pointer:
52 request_body_stream_
->DidConsume(bytes_to_copy_now
);
55 DCHECK(bytes_copied
== total_bytes_to_copy
);
56 DCHECK(request_body_stream_
->position() ==
57 initial_position
+ total_bytes_to_copy
);
60 *read
= static_cast<ULONG
>(total_bytes_to_copy
);
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_
));
75 new_pos
->QuadPart
= 0;
80 DCHECK(false) << __FUNCTION__
;
81 return STG_E_INVALIDFUNCTION
;
84 STDMETHODIMP
UrlmonUploadDataStream::Stat(STATSTG
*stat_stg
,
85 DWORD grf_stat_flag
) {
89 memset(stat_stg
, 0, sizeof(STATSTG
));
90 if (0 == (grf_stat_flag
& STATFLAG_NONAME
)) {
91 const wchar_t kStreamBuffer
[] = L
"PostStream";
93 static_cast<wchar_t*>(::CoTaskMemAlloc(sizeof(kStreamBuffer
)));
94 lstrcpy(stat_stg
->pwcsName
, kStreamBuffer
);
96 stat_stg
->type
= STGTY_STREAM
;
97 stat_stg
->cbSize
.QuadPart
= upload_data_
->GetContentLength();