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 #ifndef CHROME_FRAME_URLMON_BIND_STATUS_CALLBACK_H_
6 #define CHROME_FRAME_URLMON_BIND_STATUS_CALLBACK_H_
11 #include "base/memory/scoped_ptr.h"
12 #include "chrome_frame/bind_status_callback_impl.h"
13 #include "chrome_frame/stream_impl.h"
16 // A fake stream class to serve cached data to arbitrary
17 // IBindStatusCallback
18 class CacheStream
: public CComObjectRoot
, public StreamImpl
{
20 BEGIN_COM_MAP(CacheStream
)
21 COM_INTERFACE_ENTRY(IStream
)
22 COM_INTERFACE_ENTRY(ISequentialStream
)
25 CacheStream() : size_(0), position_(0), eof_(false) {
27 HRESULT
Initialize(const char* cache
, size_t size
, bool eof
);
28 static HRESULT
BSCBFeedData(IBindStatusCallback
* bscb
, const char* data
,
29 size_t size
, CLIPFORMAT clip_format
,
30 size_t flags
, bool eof
);
33 STDMETHOD(Read
)(void* pv
, ULONG cb
, ULONG
* read
);
36 scoped_ptr
<char[]> cache_
;
42 DISALLOW_COPY_AND_ASSIGN(CacheStream
);
45 // Utility class for data sniffing
48 SniffData() : renderer_type_(OTHER
), size_(0), eof_(false) {}
56 HRESULT
InitializeCache(const std::wstring
& url
);
57 HRESULT
ReadIntoCache(IStream
* stream
, bool force_determination
);
58 HRESULT
DrainCache(IBindStatusCallback
* bscb
, DWORD bscf
,
59 CLIPFORMAT clip_format
);
60 void DetermineRendererType(bool last_chance
);
62 bool is_undetermined() const {
63 return (UNDETERMINED
== renderer_type_
);
65 bool is_chrome() const {
66 return (CHROME
== renderer_type_
);
69 RendererType
renderer_type() const {
70 return renderer_type_
;
77 bool is_cache_valid() {
81 base::win::ScopedComPtr
<IStream
> cache_
;
83 RendererType renderer_type_
;
86 static const size_t kMaxSniffSize
= 2 * 1024;
90 DISALLOW_COPY_AND_ASSIGN(SniffData
);
93 // A wrapper for bind status callback in IMoniker::BindToStorage
94 class BSCBStorageBind
: public BSCBImpl
{
96 typedef BSCBImpl CallbackImpl
;
100 BEGIN_COM_MAP(BSCBStorageBind
)
101 COM_INTERFACE_ENTRY(IBindStatusCallback
)
102 COM_INTERFACE_ENTRY_CHAIN(CallbackImpl
)
105 HRESULT
Initialize(IMoniker
* moniker
, IBindCtx
* bind_ctx
);
106 HRESULT
MayPlayBack(DWORD flags
);
108 // IBindStatusCallback
109 STDMETHOD(OnProgress
)(ULONG progress
, ULONG progress_max
, ULONG status_code
,
110 LPCWSTR status_text
);
111 STDMETHOD(OnDataAvailable
)(DWORD flags
, DWORD size
, FORMATETC
* format_etc
,
113 STDMETHOD(OnStopBinding
)(HRESULT hresult
, LPCWSTR error
);
116 // is it a good time to start caching progress notifications
117 bool ShouldCacheProgress(ULONG status_code
) const;
120 SniffData data_sniffer_
;
122 // A structure to cache the progress notifications.
125 Progress(ULONG progress
, ULONG progress_max
, ULONG status_code
,
126 const wchar_t* status_text
)
127 : progress_(progress
),
128 progress_max_(progress_max
),
129 status_code_(status_code
) {
131 int len
= lstrlenW(status_text
) + 1;
132 status_text_
.reset(new wchar_t[len
]);
133 if (status_text_
.get()) {
134 lstrcpynW(status_text_
.get(), status_text
, len
);
144 ULONG
progress() const {
148 ULONG
progress_max() const {
149 return progress_max_
;
152 ULONG
status_code() const {
156 const wchar_t* status_text() const {
157 return status_text_
.get();
164 // We don't use std::wstring here since we want to be able to play
165 // progress notifications back exactly as we got them. NULL and L"" are
167 scoped_ptr
<wchar_t[]> status_text_
;
170 typedef std::vector
<Progress
*> ProgressVector
;
171 ProgressVector saved_progress_
;
172 CLIPFORMAT clip_format_
;
175 DISALLOW_COPY_AND_ASSIGN(BSCBStorageBind
);
178 #endif // CHROME_FRAME_URLMON_BIND_STATUS_CALLBACK_H_