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
) {
24 // Have we already read past the end of the stream?
25 if (request_body_stream_
->IsEOF()) {
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.
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
);
60 *read
= static_cast<ULONG
>(bytes_copied
);
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
);
77 new_pos
->QuadPart
= 0;
82 DCHECK(false) << __FUNCTION__
;
83 return STG_E_INVALIDFUNCTION
;
86 STDMETHODIMP
UrlmonUploadDataStream::Stat(STATSTG
*stat_stg
,
87 DWORD grf_stat_flag
) {
91 memset(stat_stg
, 0, sizeof(STATSTG
));
92 if (0 == (grf_stat_flag
& STATFLAG_NONAME
)) {
93 const wchar_t kStreamBuffer
[] = L
"PostStream";
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();