blob: dc310396acc0c7596e5da71e6b55c4228694041a [file] [log] [blame]
[email protected]3b63f8f42011-03-28 01:54:151// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]051236f2010-03-12 22:06:142// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_FRAME_URLMON_BIND_STATUS_CALLBACK_H_
6#define CHROME_FRAME_URLMON_BIND_STATUS_CALLBACK_H_
7
8#include <atlbase.h>
9#include <atlcom.h>
10
[email protected]3b63f8f42011-03-28 01:54:1511#include "base/memory/scoped_ptr.h"
[email protected]97965e12010-04-09 00:51:1012#include "chrome_frame/bind_status_callback_impl.h"
13#include "chrome_frame/stream_impl.h"
[email protected]051236f2010-03-12 22:06:1414
[email protected]97965e12010-04-09 00:51:1015
16// A fake stream class to serve cached data to arbitrary
17// IBindStatusCallback
18class CacheStream : public CComObjectRoot, public StreamImpl {
[email protected]051236f2010-03-12 22:06:1419 public:
[email protected]97965e12010-04-09 00:51:1020 BEGIN_COM_MAP(CacheStream)
21 COM_INTERFACE_ENTRY(IStream)
22 COM_INTERFACE_ENTRY(ISequentialStream)
23 END_COM_MAP()
[email protected]051236f2010-03-12 22:06:1424
[email protected]de5bc352010-04-16 01:38:4825 CacheStream() : cache_(NULL), size_(0), position_(0), eof_(false) {
[email protected]051236f2010-03-12 22:06:1426 }
[email protected]f1917ed2010-05-13 20:21:0827 HRESULT Initialize(const char* cache, size_t size, bool eof);
[email protected]97965e12010-04-09 00:51:1028 static HRESULT BSCBFeedData(IBindStatusCallback* bscb, const char* data,
29 size_t size, CLIPFORMAT clip_format,
[email protected]de5bc352010-04-16 01:38:4830 size_t flags, bool eof);
[email protected]051236f2010-03-12 22:06:1431
[email protected]97965e12010-04-09 00:51:1032 // IStream overrides
33 STDMETHOD(Read)(void* pv, ULONG cb, ULONG* read);
[email protected]051236f2010-03-12 22:06:1434
35 protected:
[email protected]f1917ed2010-05-13 20:21:0836 scoped_ptr<char> cache_;
[email protected]97965e12010-04-09 00:51:1037 size_t size_;
38 size_t position_;
[email protected]de5bc352010-04-16 01:38:4839 bool eof_;
[email protected]051236f2010-03-12 22:06:1440
41 private:
[email protected]97965e12010-04-09 00:51:1042 DISALLOW_COPY_AND_ASSIGN(CacheStream);
43};
44
45// Utility class for data sniffing
46class SniffData {
47 public:
[email protected]de5bc352010-04-16 01:38:4848 SniffData() : renderer_type_(OTHER), size_(0), eof_(false) {}
[email protected]97965e12010-04-09 00:51:1049
50 enum RendererType {
51 UNDETERMINED,
52 CHROME,
53 OTHER
54 };
55
[email protected]040b800f2010-05-05 23:46:3056 HRESULT InitializeCache(const std::wstring& url);
[email protected]97965e12010-04-09 00:51:1057 HRESULT ReadIntoCache(IStream* stream, bool force_determination);
58 HRESULT DrainCache(IBindStatusCallback* bscb, DWORD bscf,
59 CLIPFORMAT clip_format);
[email protected]37a3a4b2010-04-14 22:37:4060 void DetermineRendererType(bool last_chance);
[email protected]97965e12010-04-09 00:51:1061
62 bool is_undetermined() const {
63 return (UNDETERMINED == renderer_type_);
64 }
65 bool is_chrome() const {
66 return (CHROME == renderer_type_);
67 }
68
69 RendererType renderer_type() const {
70 return renderer_type_;
71 }
72
73 size_t size() const {
74 return size_;
75 }
76
77 bool is_cache_valid() {
78 return (size_ != 0);
79 }
80
[email protected]8ee65ba2011-04-12 20:53:2381 base::win::ScopedComPtr<IStream> cache_;
[email protected]97965e12010-04-09 00:51:1082 std::wstring url_;
83 RendererType renderer_type_;
84 size_t size_;
85
86 static const size_t kMaxSniffSize = 2 * 1024;
[email protected]de5bc352010-04-16 01:38:4887 bool eof_;
[email protected]97965e12010-04-09 00:51:1088
89 private:
90 DISALLOW_COPY_AND_ASSIGN(SniffData);
91};
92
93// A wrapper for bind status callback in IMoniker::BindToStorage
94class BSCBStorageBind : public BSCBImpl {
95 public:
96 typedef BSCBImpl CallbackImpl;
[email protected]74e9983a2010-05-14 02:27:3497 BSCBStorageBind();
98 ~BSCBStorageBind();
[email protected]97965e12010-04-09 00:51:1099
100BEGIN_COM_MAP(BSCBStorageBind)
101 COM_INTERFACE_ENTRY(IBindStatusCallback)
102 COM_INTERFACE_ENTRY_CHAIN(CallbackImpl)
103END_COM_MAP()
104
[email protected]70277f62010-04-15 01:39:26105 HRESULT Initialize(IMoniker* moniker, IBindCtx* bind_ctx);
[email protected]97965e12010-04-09 00:51:10106 HRESULT MayPlayBack(DWORD flags);
107
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,
112 STGMEDIUM* stgmed);
113 STDMETHOD(OnStopBinding)(HRESULT hresult, LPCWSTR error);
114
115 protected:
[email protected]b31b9ff2010-05-07 18:29:24116 // is it a good time to start caching progress notifications
117 bool ShouldCacheProgress(ULONG status_code) const;
118
119 protected:
[email protected]97965e12010-04-09 00:51:10120 SniffData data_sniffer_;
121
[email protected]74e9983a2010-05-14 02:27:34122 // A structure to cache the progress notifications.
123 class Progress {
124 public:
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),
130 status_text_(NULL) {
131 if (status_text) {
132 int len = lstrlenW(status_text) + 1;
133 status_text_.reset(new wchar_t[len]);
134 if (status_text_.get()) {
[email protected]77d7aee2010-05-14 20:31:55135 lstrcpynW(status_text_.get(), status_text, len);
[email protected]74e9983a2010-05-14 02:27:34136 } else {
137 NOTREACHED();
138 }
139 }
140 }
141
142 ~Progress() {
143 }
144
145 ULONG progress() const {
146 return progress_;
147 }
148
149 ULONG progress_max() const {
150 return progress_max_;
151 }
152
153 ULONG status_code() const {
154 return status_code_;
155 }
156
157 const wchar_t* status_text() const {
158 return status_text_.get();
159 }
160
161 protected:
[email protected]97965e12010-04-09 00:51:10162 ULONG progress_;
163 ULONG progress_max_;
164 ULONG status_code_;
[email protected]74e9983a2010-05-14 02:27:34165 // We don't use std::wstring here since we want to be able to play
166 // progress notifications back exactly as we got them. NULL and L"" are
167 // not equal.
168 scoped_ptr<wchar_t> status_text_;
[email protected]97965e12010-04-09 00:51:10169 };
170
[email protected]77d7aee2010-05-14 20:31:55171 typedef std::vector<Progress*> ProgressVector;
172 ProgressVector saved_progress_;
[email protected]97965e12010-04-09 00:51:10173 CLIPFORMAT clip_format_;
174
175 private:
176 DISALLOW_COPY_AND_ASSIGN(BSCBStorageBind);
[email protected]051236f2010-03-12 22:06:14177};
178
179#endif // CHROME_FRAME_URLMON_BIND_STATUS_CALLBACK_H_