diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-12 21:58:18 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-12 21:58:18 +0000 |
commit | 8c3dc79bc13ba84f418d3c135e1bf296a3e29722 (patch) | |
tree | 32eb9688d500a90eb74a7c4f8cb5a97e507dd0fc /app | |
parent | abaccb2cb8cff8138e5ea9daf420645e5852c9eb (diff) | |
download | chromium_src-8c3dc79bc13ba84f418d3c135e1bf296a3e29722.zip chromium_src-8c3dc79bc13ba84f418d3c135e1bf296a3e29722.tar.gz chromium_src-8c3dc79bc13ba84f418d3c135e1bf296a3e29722.tar.bz2 |
Refactors OSExchangeData for easier portability.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/164401
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@23230 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'app')
-rw-r--r-- | app/app.gyp | 18 | ||||
-rw-r--r-- | app/os_exchange_data.cc | 125 | ||||
-rw-r--r-- | app/os_exchange_data.h | 164 | ||||
-rw-r--r-- | app/os_exchange_data_provider_gtk.cc | 170 | ||||
-rw-r--r-- | app/os_exchange_data_provider_gtk.h | 106 | ||||
-rw-r--r-- | app/os_exchange_data_provider_win.cc (renamed from app/os_exchange_data_win.cc) | 183 | ||||
-rw-r--r-- | app/os_exchange_data_provider_win.h | 128 | ||||
-rw-r--r-- | app/os_exchange_data_win_unittest.cc | 127 |
8 files changed, 813 insertions, 208 deletions
diff --git a/app/app.gyp b/app/app.gyp index 77e3a3d..0a36bd5 100644 --- a/app/app.gyp +++ b/app/app.gyp @@ -95,8 +95,11 @@ 'l10n_util_win.cc', 'l10n_util_win.h', 'message_box_flags.h', - 'os_exchange_data_win.cc', - 'os_exchange_data_gtk.cc', + 'os_exchange_data_provider_gtk.cc', + 'os_exchange_data_provider_gtk.h', + 'os_exchange_data_provider_win.cc', + 'os_exchange_data_provider_win.h', + 'os_exchange_data.cc', 'os_exchange_data.h', 'resource_bundle.cc', 'resource_bundle.h', @@ -131,11 +134,20 @@ # Note: because of gyp predence rules this has to be defined as # 'sources/' rather than 'sources!'. 'sources/': [ - ['exclude', '^os_exchange_data_gtk.cc'], + ['exclude', '^os_exchange_data.cc'], ['exclude', '^os_exchange_data.h'], + ['exclude', '^os_exchange_data_provider_gtk.cc'], + ['exclude', '^os_exchange_data_provider_gtk.h'], ['exclude', '^drag_drop_types_gtk.cc'], ], }], + ['toolkit_views==1 or chromeos==1', { + # Note: because of gyp predence rules this has to be defined as + # 'sources/' rather than 'sources!'. + 'sources/': [ + ['include', '^os_exchange_data.cc'], + ], + }], ], }], ['OS=="win"', { diff --git a/app/os_exchange_data.cc b/app/os_exchange_data.cc new file mode 100644 index 0000000..9361466 --- /dev/null +++ b/app/os_exchange_data.cc @@ -0,0 +1,125 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "app/os_exchange_data.h" + +#include "base/pickle.h" +#include "googleurl/src/gurl.h" + +OSExchangeData::OSExchangeData() : provider_(CreateProvider()) { +} + +OSExchangeData::OSExchangeData(Provider* provider) : provider_(provider) { +} + +OSExchangeData::~OSExchangeData() { +} + +void OSExchangeData::SetString(const std::wstring& data) { + provider_->SetString(data); +} + +void OSExchangeData::SetURL(const GURL& url, const std::wstring& title) { + provider_->SetURL(url, title); +} + +void OSExchangeData::SetFilename(const std::wstring& full_path) { + provider_->SetFilename(full_path); +} + +void OSExchangeData::SetPickledData(CustomFormat format, const Pickle& data) { + provider_->SetPickledData(format, data); +} + +void OSExchangeData::SetFileContents(const std::wstring& filename, + const std::string& file_contents) { + provider_->SetFileContents(filename, file_contents); +} + +void OSExchangeData::SetHtml(const std::wstring& html, const GURL& base_url) { + provider_->SetHtml(html, base_url); +} + +bool OSExchangeData::GetString(std::wstring* data) const { + return provider_->GetString(data); +} + +bool OSExchangeData::GetURLAndTitle(GURL* url, std::wstring* title) const { + return provider_->GetURLAndTitle(url, title); +} + +bool OSExchangeData::GetFilename(std::wstring* full_path) const { + return provider_->GetFilename(full_path); +} + +bool OSExchangeData::GetPickledData(CustomFormat format, Pickle* data) const { + return provider_->GetPickledData(format, data); +} + +bool OSExchangeData::GetFileContents(std::wstring* filename, + std::string* file_contents) const { + return provider_->GetFileContents(filename, file_contents); +} + +bool OSExchangeData::GetHtml(std::wstring* html, GURL* base_url) const { + return provider_->GetHtml(html, base_url); +} + +bool OSExchangeData::HasString() const { + return provider_->HasString(); +} + +bool OSExchangeData::HasURL() const { + return provider_->HasURL(); +} + +bool OSExchangeData::HasFile() const { + return provider_->HasFile(); +} + +bool OSExchangeData::HasCustomFormat(CustomFormat format) const { + return provider_->HasCustomFormat(format); +} + +bool OSExchangeData::HasAllFormats( + int formats, + const std::set<CustomFormat>& custom_formats) const { + if ((formats & STRING) != 0 && !HasString()) + return false; + if ((formats & URL) != 0 && !HasURL()) + return false; + if ((formats & FILE_CONTENTS) != 0 && !provider_->HasFileContents()) + return false; + if ((formats & FILE_NAME) != 0 && !provider_->HasFile()) + return false; + if ((formats & HTML) != 0 && !provider_->HasHtml()) + return false; + for (std::set<CustomFormat>::const_iterator i = custom_formats.begin(); + i != custom_formats.end(); ++i) { + if (!HasCustomFormat(*i)) + return false; + } + return true; +} + +bool OSExchangeData::HasAnyFormat( + int formats, + const std::set<CustomFormat>& custom_formats) const { + if ((formats & STRING) != 0 && HasString()) + return true; + if ((formats & URL) != 0 && HasURL()) + return true; + if ((formats & FILE_CONTENTS) != 0 && provider_->HasFileContents()) + return true; + if ((formats & FILE_NAME) != 0 && provider_->HasFile()) + return true; + if ((formats & HTML) != 0 && provider_->HasHtml()) + return true; + for (std::set<CustomFormat>::const_iterator i = custom_formats.begin(); + i != custom_formats.end(); ++i) { + if (HasCustomFormat(*i)) + return true; + } + return false; +} diff --git a/app/os_exchange_data.h b/app/os_exchange_data.h index 2400266..a956b80 100644 --- a/app/os_exchange_data.h +++ b/app/os_exchange_data.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -7,15 +7,18 @@ #include "build/build_config.h" +#include <set> +#include <string> +#include <vector> + #if defined(OS_WIN) #include <objidl.h> -#include "base/scoped_comptr_win.h" +#elif defined(OS_LINUX) +#include <gtk/gtk.h> #endif -#include <string> -#include <vector> - #include "base/basictypes.h" +#include "base/scoped_ptr.h" class GURL; class Pickle; @@ -29,25 +32,71 @@ class Pickle; // translating that into something the OS can understand. // /////////////////////////////////////////////////////////////////////////////// -#if defined(OS_WIN) -class OSExchangeData : public IDataObject { -#else class OSExchangeData { -#endif public: + // CustomFormats are used for non-standard data types. For example, bookmark + // nodes are written using a CustomFormat. #if defined(OS_WIN) - // Returns true if source has plain text that is a valid url. - static bool HasPlainTextURL(IDataObject* source); + typedef CLIPFORMAT CustomFormat; +#elif defined(OS_LINUX) + typedef GdkAtom CustomFormat; +#endif - // Returns true if source has plain text that is a valid URL and sets url to - // that url. - static bool GetPlainTextURL(IDataObject* source, GURL* url); + // Enumeration of the known formats. + enum Format { + STRING = 1 << 0, + URL = 1 << 1, + FILE_CONTENTS = 1 << 2, + FILE_NAME = 1 << 3, + PICKLED_DATA = 1 << 4, + HTML = 1 << 5 + }; - explicit OSExchangeData(IDataObject* source); -#endif + // Provider defines the platform specific part of OSExchangeData that + // interacts with the native system. + class Provider { + public: + Provider() {} + virtual ~Provider() {} + + virtual void SetString(const std::wstring& data) = 0; + virtual void SetURL(const GURL& url, const std::wstring& title) = 0; + virtual void SetFilename(const std::wstring& full_path) = 0; + virtual void SetPickledData(CustomFormat format, const Pickle& data) = 0; + virtual void SetFileContents(const std::wstring& filename, + const std::string& file_contents) = 0; + virtual void SetHtml(const std::wstring& html, const GURL& base_url) = 0; + + virtual bool GetString(std::wstring* data) const = 0; + virtual bool GetURLAndTitle(GURL* url, std::wstring* title) const = 0; + virtual bool GetFilename(std::wstring* full_path) const = 0; + virtual bool GetPickledData(CustomFormat format, Pickle* data) const = 0; + virtual bool GetFileContents(std::wstring* filename, + std::string* file_contents) const = 0; + virtual bool GetHtml(std::wstring* html, GURL* base_url) const = 0; + + virtual bool HasString() const = 0; + virtual bool HasURL() const = 0; + virtual bool HasFile() const = 0; + virtual bool HasFileContents() const = 0; + virtual bool HasHtml() const = 0; + virtual bool HasCustomFormat( + OSExchangeData::CustomFormat format) const = 0; + }; OSExchangeData(); - virtual ~OSExchangeData(); + // Creates an OSExchangeData with the specified provider. OSExchangeData + // takes ownership of the supplied provider. + explicit OSExchangeData(Provider* provider); + + ~OSExchangeData(); + + // Registers the specific string as a possible format for data. + static CustomFormat RegisterCustomFormat(const std::string& type); + + // Returns the Provider, which actually stores and manages the data. + const Provider& provider() const { return *provider_; } + Provider& provider() { return *provider_; } // These functions add data to the OSExchangeData object of various Chrome // types. The OSExchangeData object takes care of translating the data into @@ -64,10 +113,8 @@ class OSExchangeData { void SetURL(const GURL& url, const std::wstring& title); // A full path to a file void SetFilename(const std::wstring& full_path); -#if defined(OS_WIN) // Adds pickled data of the specified format. - void SetPickledData(CLIPFORMAT format, const Pickle& data); -#endif + void SetPickledData(CustomFormat format, const Pickle& data); // Adds the bytes of a file (CFSTR_FILECONTENTS and CFSTR_FILEDESCRIPTOR). void SetFileContents(const std::wstring& filename, const std::string& file_contents); @@ -83,9 +130,7 @@ class OSExchangeData { bool GetURLAndTitle(GURL* url, std::wstring* title) const; // Return the path of a file, if available. bool GetFilename(std::wstring* full_path) const; -#if defined(OS_WIN) - bool GetPickledData(CLIPFORMAT format, Pickle* data) const; -#endif + bool GetPickledData(CustomFormat format, Pickle* data) const; bool GetFileContents(std::wstring* filename, std::string* file_contents) const; bool GetHtml(std::wstring* html, GURL* base_url) const; @@ -94,70 +139,25 @@ class OSExchangeData { // returning anything. bool HasString() const; bool HasURL() const; - bool HasURLTitle() const; bool HasFile() const; -#if defined(OS_WIN) - bool HasFormat(CLIPFORMAT format) const; - - // IDataObject implementation: - HRESULT __stdcall GetData(FORMATETC* format_etc, STGMEDIUM* medium); - HRESULT __stdcall GetDataHere(FORMATETC* format_etc, STGMEDIUM* medium); - HRESULT __stdcall QueryGetData(FORMATETC* format_etc); - HRESULT __stdcall GetCanonicalFormatEtc( - FORMATETC* format_etc, FORMATETC* result); - HRESULT __stdcall SetData( - FORMATETC* format_etc, STGMEDIUM* medium, BOOL should_release); - HRESULT __stdcall EnumFormatEtc( - DWORD direction, IEnumFORMATETC** enumerator); - HRESULT __stdcall DAdvise( - FORMATETC* format_etc, DWORD advf, IAdviseSink* sink, DWORD* connection); - HRESULT __stdcall DUnadvise(DWORD connection); - HRESULT __stdcall EnumDAdvise(IEnumSTATDATA** enumerator); - - // IUnknown implementation: - HRESULT __stdcall QueryInterface(const IID& iid, void** object); - ULONG __stdcall AddRef(); - ULONG __stdcall Release(); -#endif + bool HasCustomFormat(CustomFormat format) const; - private: -#if defined(OS_WIN) - // FormatEtcEnumerator only likes us for our StoredDataMap typedef. - friend class FormatEtcEnumerator; - - // Our internal representation of stored data & type info. - struct StoredDataInfo { - FORMATETC format_etc; - STGMEDIUM* medium; - bool owns_medium; - - StoredDataInfo(CLIPFORMAT cf, STGMEDIUM* a_medium) { - format_etc.cfFormat = cf; - format_etc.dwAspect = DVASPECT_CONTENT; - format_etc.lindex = -1; - format_etc.ptd = NULL; - format_etc.tymed = a_medium->tymed; - - owns_medium = true; - - medium = a_medium; - } - - ~StoredDataInfo() { - if (owns_medium) { - ReleaseStgMedium(medium); - delete medium; - } - } - }; + // Returns true if this OSExchangeData has data for ALL the formats in + // |formats| and ALL the custom formats in |custom_formats|. + bool HasAllFormats(int formats, + const std::set<CustomFormat>& custom_formats) const; - typedef std::vector<StoredDataInfo*> StoredData; - StoredData contents_; + // Returns true if this OSExchangeData has data in any of the formats in + // |formats| or any custom format in |custom_formats|. + bool HasAnyFormat(int formats, + const std::set<CustomFormat>& custom_formats) const; - ScopedComPtr<IDataObject> source_object_; + private: + // Creates the platform specific Provider. + static Provider* CreateProvider(); - LONG ref_count_; -#endif + // Provides the actual data. + scoped_ptr<Provider> provider_; DISALLOW_COPY_AND_ASSIGN(OSExchangeData); }; diff --git a/app/os_exchange_data_provider_gtk.cc b/app/os_exchange_data_provider_gtk.cc new file mode 100644 index 0000000..5aaa414 --- /dev/null +++ b/app/os_exchange_data_provider_gtk.cc @@ -0,0 +1,170 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "app/os_exchange_data_provider_gtk.h" + +#include <algorithm> + +#include "base/string_util.h" + +OSExchangeDataProviderGtk::OSExchangeDataProviderGtk( + int known_formats, + const std::set<GdkAtom>& known_custom_formats) + : known_formats_(known_formats), + known_custom_formats_(known_custom_formats), + formats_(0) { +} + +OSExchangeDataProviderGtk::OSExchangeDataProviderGtk() + : known_formats_(0), + formats_(0) { +} + +OSExchangeDataProviderGtk::~OSExchangeDataProviderGtk() { +} + +bool OSExchangeDataProviderGtk::HasDataForAllFormats( + int formats, + const std::set<GdkAtom>& custom_formats) const { + if ((formats_ & formats) != formats) + return false; + return std::includes(custom_formats_.begin(), + custom_formats_.end(), + custom_formats.begin(), custom_formats.end()); +} + +void OSExchangeDataProviderGtk::SetString(const std::wstring& data) { + string_ = WideToUTF16Hack(data); + formats_ |= OSExchangeData::STRING; +} + +void OSExchangeDataProviderGtk::SetURL(const GURL& url, + const std::wstring& title) { + url_ = url; + title_ = WideToUTF16Hack(title); + formats_ |= OSExchangeData::URL; +} + +void OSExchangeDataProviderGtk::SetFilename(const std::wstring& full_path) { + filename_ = WideToUTF16Hack(full_path); + formats_ |= OSExchangeData::FILE_NAME; +} + +void OSExchangeDataProviderGtk::SetPickledData(GdkAtom format, + const Pickle& data) { + pickle_data_[format] = data; + formats_ |= OSExchangeData::PICKLED_DATA; +} + +void OSExchangeDataProviderGtk::SetFileContents( + const std::wstring& filename, + const std::string& file_contents) { + filename_ = WideToUTF16Hack(filename); + file_contents_ = file_contents; + formats_ |= OSExchangeData::FILE_CONTENTS; +} + +void OSExchangeDataProviderGtk::SetHtml(const std::wstring& html, + const GURL& base_url) { + html_ = WideToUTF16Hack(html); + base_url_ = base_url; + formats_ |= OSExchangeData::HTML; +} + +bool OSExchangeDataProviderGtk::GetString(std::wstring* data) const { + if (formats_ & OSExchangeData::STRING == 0) + return false; + *data = UTF16ToWideHack(string_); + return true; +} + +bool OSExchangeDataProviderGtk::GetURLAndTitle(GURL* url, + std::wstring* title) const { + if (formats_ & OSExchangeData::URL == 0) + return false; + if (!url_.is_valid()) + return false; + + *url = url_; + *title = UTF16ToWideHack(title_); + return true; +} + +bool OSExchangeDataProviderGtk::GetFilename(std::wstring* full_path) const { + if (formats_ & OSExchangeData::FILE_NAME == 0) + return false; + *full_path = UTF16ToWideHack(filename_); + return true; +} + +bool OSExchangeDataProviderGtk::GetPickledData(GdkAtom format, + Pickle* data) const { + PickleData::const_iterator i = pickle_data_.find(format); + if (i == pickle_data_.end()) + return false; + + *data = i->second; + return true; +} + +bool OSExchangeDataProviderGtk::GetFileContents( + std::wstring* filename, + std::string* file_contents) const { + if (formats_ & OSExchangeData::FILE_CONTENTS == 0) + return false; + *filename = UTF16ToWideHack(filename_); + *file_contents = file_contents_; + return true; +} + +bool OSExchangeDataProviderGtk::GetHtml(std::wstring* html, + GURL* base_url) const { + if (formats_ & OSExchangeData::HTML == 0) + return false; + *html = UTF16ToWideHack(filename_); + *base_url = base_url_; + return true; +} + +bool OSExchangeDataProviderGtk::HasString() const { + return (known_formats_ & OSExchangeData::STRING) != 0 || + (formats_ & OSExchangeData::STRING) != 0; +} + +bool OSExchangeDataProviderGtk::HasURL() const { + return (known_formats_ & OSExchangeData::URL) != 0 || + (formats_ & OSExchangeData::URL) != 0; +} + +bool OSExchangeDataProviderGtk::HasFile() const { + return (known_formats_ & OSExchangeData::FILE_NAME) != 0 || + (formats_ & OSExchangeData::FILE_NAME) != 0; + } + +bool OSExchangeDataProviderGtk::HasFileContents() const { + return (known_formats_ & OSExchangeData::FILE_CONTENTS) != 0 || + (formats_ & OSExchangeData::FILE_CONTENTS) != 0; +} + +bool OSExchangeDataProviderGtk::HasHtml() const { + return (known_formats_ & OSExchangeData::HTML) != 0 || + (formats_ & OSExchangeData::HTML) != 0; +} + +bool OSExchangeDataProviderGtk::HasCustomFormat(GdkAtom format) const { + return known_custom_formats_.find(format) != known_custom_formats_.end() || + custom_formats_.find(format) != custom_formats_.end(); +} + +/////////////////////////////////////////////////////////////////////////////// +// OSExchangeData, public: + +// static +OSExchangeData::Provider* OSExchangeData::CreateProvider() { + return new OSExchangeDataProviderGtk(); +} + +GdkAtom OSExchangeData::RegisterCustomFormat(const std::string& type) { + return gdk_atom_intern(type.c_str(), false); +} diff --git a/app/os_exchange_data_provider_gtk.h b/app/os_exchange_data_provider_gtk.h new file mode 100644 index 0000000..dd9c009 --- /dev/null +++ b/app/os_exchange_data_provider_gtk.h @@ -0,0 +1,106 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef APP_OS_EXCHANGE_DATA_PROVIDER_GTK_H_ +#define APP_OS_EXCHANGE_DATA_PROVIDER_GTK_H_ + +#include <gtk/gtk.h> +#include <map> +#include <set> +#include <string> +#include <vector> + +#include "app/os_exchange_data.h" +#include "base/pickle.h" +#include "base/string16.h" +#include "googleurl/src/gurl.h" + +// OSExchangeData::Provider implementation for Gtk. OSExchangeDataProviderGtk +// is created with a set of known data types. In addition specific data +// types can be set on OSExchangeDataProviderGtk by way of the various setters. +// The various has methods return true if the format was supplied to the +// constructor, or explicitly set. +class OSExchangeDataProviderGtk : public OSExchangeData::Provider { + public: + OSExchangeDataProviderGtk(int known_formats, + const std::set<GdkAtom>& known_custom_formats_); + OSExchangeDataProviderGtk(); + + virtual ~OSExchangeDataProviderGtk(); + + int known_formats() const { return known_formats_; } + const std::set<GdkAtom>& known_custom_formats() const { + return known_custom_formats_; + } + + // Returns true if all the formats and custom formats identified by |formats| + // and |custom_formats| have been set in this provider. + // + // NOTE: this is NOT the same as whether a format may be provided (as is + // returned by the various HasXXX methods), but rather if the data for the + // formats has been set on this provider by way of the various Setter + // methods. + bool HasDataForAllFormats(int formats, + const std::set<GdkAtom>& custom_formats) const; + + // Provider methods. + virtual void SetString(const std::wstring& data); + virtual void SetURL(const GURL& url, const std::wstring& title); + virtual void SetFilename(const std::wstring& full_path); + virtual void SetPickledData(OSExchangeData::CustomFormat format, + const Pickle& data); + virtual void SetFileContents(const std::wstring& filename, + const std::string& file_contents); + virtual void SetHtml(const std::wstring& html, const GURL& base_url); + virtual bool GetString(std::wstring* data) const; + virtual bool GetURLAndTitle(GURL* url, std::wstring* title) const; + virtual bool GetFilename(std::wstring* full_path) const; + virtual bool GetPickledData(OSExchangeData::CustomFormat format, + Pickle* data) const; + virtual bool GetFileContents(std::wstring* filename, + std::string* file_contents) const; + virtual bool GetHtml(std::wstring* html, GURL* base_url) const; + virtual bool HasString() const; + virtual bool HasURL() const; + virtual bool HasFile() const; + virtual bool HasFileContents() const; + virtual bool HasHtml() const; + virtual bool HasCustomFormat(OSExchangeData::CustomFormat format) const; + + private: + typedef std::map<OSExchangeData::CustomFormat, Pickle> PickleData; + + // These are the possible formats the OSExchangeData may contain. Don't + // confuse this with the actual formats that have been set, which are + // |formats_| and |custom_formats_|. + const int known_formats_; + const std::set<GdkAtom> known_custom_formats_; + + // Actual formats that have been set. See comment above |known_formats_| + // for details. + int formats_; + std::set<GdkAtom> custom_formats_; + + // String contents. + string16 string_; + + // URL contents. + GURL url_; + string16 title_; + + // File contents. + string16 filename_; + std::string file_contents_; + + // HTML contents. + string16 html_; + GURL base_url_; + + // PICKLED_DATA contents. + PickleData pickle_data_; + + DISALLOW_COPY_AND_ASSIGN(OSExchangeDataProviderGtk); +}; + +#endif // APP_OS_EXCHANGE_DATA_PROVIDER_GTK_H_ diff --git a/app/os_exchange_data_win.cc b/app/os_exchange_data_provider_win.cc index c7bd18b..1d8bdd8 100644 --- a/app/os_exchange_data_win.cc +++ b/app/os_exchange_data_provider_win.cc @@ -1,8 +1,8 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "app/os_exchange_data.h" +#include "app/os_exchange_data_provider_win.h" #include "app/l10n_util.h" #include "base/clipboard_util.h" @@ -48,8 +48,8 @@ static STGMEDIUM* GetStorageForFileDescriptor( // class FormatEtcEnumerator : public IEnumFORMATETC { public: - FormatEtcEnumerator(OSExchangeData::StoredData::const_iterator begin, - OSExchangeData::StoredData::const_iterator end); + FormatEtcEnumerator(DataObjectImpl::StoredData::const_iterator begin, + DataObjectImpl::StoredData::const_iterator end); ~FormatEtcEnumerator(); // IEnumFORMATETC implementation: @@ -99,8 +99,8 @@ static void CloneFormatEtc(FORMATETC* source, FORMATETC* clone) { } FormatEtcEnumerator::FormatEtcEnumerator( - OSExchangeData::StoredData::const_iterator start, - OSExchangeData::StoredData::const_iterator end) + DataObjectImpl::StoredData::const_iterator start, + DataObjectImpl::StoredData::const_iterator end) : ref_count_(0), cursor_(0) { // Copy FORMATETC data from our source into ourselves. while (start != end) { @@ -200,17 +200,18 @@ FormatEtcEnumerator* FormatEtcEnumerator::CloneFromOther( } /////////////////////////////////////////////////////////////////////////////// -// OSExchangeData, public: +// OSExchangeDataProviderWin, public: // static -bool OSExchangeData::HasPlainTextURL(IDataObject* source) { +bool OSExchangeDataProviderWin::HasPlainTextURL(IDataObject* source) { std::wstring plain_text; return (ClipboardUtil::GetPlainText(source, &plain_text) && !plain_text.empty() && GURL(plain_text).is_valid()); } // static -bool OSExchangeData::GetPlainTextURL(IDataObject* source, GURL* url) { +bool OSExchangeDataProviderWin::GetPlainTextURL(IDataObject* source, + GURL* url) { std::wstring plain_text; if (ClipboardUtil::GetPlainText(source, &plain_text) && !plain_text.empty()) { @@ -223,29 +224,39 @@ bool OSExchangeData::GetPlainTextURL(IDataObject* source, GURL* url) { return false; } -OSExchangeData::OSExchangeData() - : ref_count_(0) { +// static +IDataObject* OSExchangeDataProviderWin::GetIDataObject( + const OSExchangeData& data) { + return static_cast<const OSExchangeDataProviderWin&>(data.provider()). + data_object(); } -OSExchangeData::OSExchangeData(IDataObject* source) - : ref_count_(0) { - source_object_ = source; +OSExchangeDataProviderWin::OSExchangeDataProviderWin(IDataObject* source) + : data_(new DataObjectImpl()), + source_object_(source) { } -OSExchangeData::~OSExchangeData() { - STLDeleteContainerPointers(contents_.begin(), contents_.end()); +OSExchangeDataProviderWin::OSExchangeDataProviderWin() + : data_(new DataObjectImpl()), + source_object_(data_.get()) { } -void OSExchangeData::SetString(const std::wstring& data) { +OSExchangeDataProviderWin::~OSExchangeDataProviderWin() { +} + +void OSExchangeDataProviderWin::SetString(const std::wstring& data) { STGMEDIUM* storage = GetStorageForWString(data); - contents_.push_back(new StoredDataInfo(CF_UNICODETEXT, storage)); + data_->contents_.push_back( + new DataObjectImpl::StoredDataInfo(CF_UNICODETEXT, storage)); // Also add plain text. storage = GetStorageForString(WideToUTF8(data)); - contents_.push_back(new StoredDataInfo(CF_TEXT, storage)); + data_->contents_.push_back( + new DataObjectImpl::StoredDataInfo(CF_TEXT, storage)); } -void OSExchangeData::SetURL(const GURL& url, const std::wstring& title) { +void OSExchangeDataProviderWin::SetURL(const GURL& url, + const std::wstring& title) { // NOTE WELL: // Every time you change the order of the first two CLIPFORMATS that get // added here, you need to update the EnumerationViaCOM test case in @@ -257,7 +268,7 @@ void OSExchangeData::SetURL(const GURL& url, const std::wstring& title) { x_moz_url_str += '\n'; x_moz_url_str += title; STGMEDIUM* storage = GetStorageForWString(x_moz_url_str); - contents_.push_back(new StoredDataInfo( + data_->contents_.push_back(new DataObjectImpl::StoredDataInfo( ClipboardUtil::GetMozUrlFormat()->cfFormat, storage)); // Add a .URL shortcut file for dragging to Explorer. @@ -269,10 +280,10 @@ void OSExchangeData::SetURL(const GURL& url, const std::wstring& title) { // Add a UniformResourceLocator link for apps like IE and Word. storage = GetStorageForWString(UTF8ToWide(url.spec())); - contents_.push_back(new StoredDataInfo( + data_->contents_.push_back(new DataObjectImpl::StoredDataInfo( ClipboardUtil::GetUrlWFormat()->cfFormat, storage)); storage = GetStorageForString(url.spec()); - contents_.push_back(new StoredDataInfo( + data_->contents_.push_back(new DataObjectImpl::StoredDataInfo( ClipboardUtil::GetUrlFormat()->cfFormat, storage)); // TODO(beng): (http://b/1085501) add CF_HTML... @@ -280,12 +291,14 @@ void OSExchangeData::SetURL(const GURL& url, const std::wstring& title) { // Also add text representations (these should be last since they're the // least preferable). storage = GetStorageForWString(UTF8ToWide(url.spec())); - contents_.push_back(new StoredDataInfo(CF_UNICODETEXT, storage)); + data_->contents_.push_back( + new DataObjectImpl::StoredDataInfo(CF_UNICODETEXT, storage)); storage = GetStorageForString(url.spec()); - contents_.push_back(new StoredDataInfo(CF_TEXT, storage)); + data_->contents_.push_back( + new DataObjectImpl::StoredDataInfo(CF_TEXT, storage)); } -void OSExchangeData::SetFilename(const std::wstring& full_path) { +void OSExchangeDataProviderWin::SetFilename(const std::wstring& full_path) { const size_t drop_size = sizeof(DROPFILES); const size_t bytes = drop_size + (full_path.length() + 2) * sizeof(wchar_t); HANDLE hdata = ::GlobalAlloc(GMEM_MOVEABLE, bytes); @@ -308,51 +321,57 @@ void OSExchangeData::SetFilename(const std::wstring& full_path) { storage->pUnkForRelease = NULL; // Set up the StoredDataInfo - StoredDataInfo* info = new StoredDataInfo(CF_HDROP, storage); - contents_.push_back(info); + DataObjectImpl::StoredDataInfo* info = + new DataObjectImpl::StoredDataInfo(CF_HDROP, storage); + data_->contents_.push_back(info); } -void OSExchangeData::SetPickledData(CLIPFORMAT format, const Pickle& data) { +void OSExchangeDataProviderWin::SetPickledData(CLIPFORMAT format, + const Pickle& data) { STGMEDIUM* storage = GetStorageForString( std::string(static_cast<const char *>(data.data()), static_cast<size_t>(data.size()))); - contents_.push_back(new StoredDataInfo(format, storage)); + data_->contents_.push_back( + new DataObjectImpl::StoredDataInfo(format, storage)); } -void OSExchangeData::SetFileContents(const std::wstring& filename, - const std::string& file_contents) { +void OSExchangeDataProviderWin::SetFileContents( + const std::wstring& filename, + const std::string& file_contents) { // Add CFSTR_FILEDESCRIPTOR STGMEDIUM* storage = GetStorageForFileDescriptor(filename); - contents_.push_back(new StoredDataInfo( + data_->contents_.push_back(new DataObjectImpl::StoredDataInfo( ClipboardUtil::GetFileDescriptorFormat()->cfFormat, storage)); // Add CFSTR_FILECONTENTS storage = GetStorageForBytes(file_contents.data(), file_contents.length()); - contents_.push_back(new StoredDataInfo( + data_->contents_.push_back(new DataObjectImpl::StoredDataInfo( ClipboardUtil::GetFileContentFormatZero()->cfFormat, storage)); } -void OSExchangeData::SetHtml(const std::wstring& html, const GURL& base_url) { +void OSExchangeDataProviderWin::SetHtml(const std::wstring& html, + const GURL& base_url) { // Add both MS CF_HTML and text/html format. CF_HTML should be in utf-8. std::string utf8_html = WideToUTF8(html); std::string url = base_url.is_valid() ? base_url.spec() : std::string(); std::string cf_html = ClipboardUtil::HtmlToCFHtml(utf8_html, url); STGMEDIUM* storage = GetStorageForBytes(cf_html.c_str(), cf_html.size()); - contents_.push_back(new StoredDataInfo( + data_->contents_.push_back(new DataObjectImpl::StoredDataInfo( ClipboardUtil::GetHtmlFormat()->cfFormat, storage)); STGMEDIUM* storage_plain = GetStorageForBytes(utf8_html.c_str(), utf8_html.size()); - contents_.push_back(new StoredDataInfo( + data_->contents_.push_back(new DataObjectImpl::StoredDataInfo( ClipboardUtil::GetTextHtmlFormat()->cfFormat, storage_plain)); } -bool OSExchangeData::GetString(std::wstring* data) const { +bool OSExchangeDataProviderWin::GetString(std::wstring* data) const { return ClipboardUtil::GetPlainText(source_object_, data); } -bool OSExchangeData::GetURLAndTitle(GURL* url, std::wstring* title) const { +bool OSExchangeDataProviderWin::GetURLAndTitle(GURL* url, + std::wstring* title) const { std::wstring url_str; bool success = ClipboardUtil::GetUrl(source_object_, &url_str, title); if (success) { @@ -368,7 +387,7 @@ bool OSExchangeData::GetURLAndTitle(GURL* url, std::wstring* title) const { return false; } -bool OSExchangeData::GetFilename(std::wstring* full_path) const { +bool OSExchangeDataProviderWin::GetFilename(std::wstring* full_path) const { std::vector<std::wstring> filenames; bool success = ClipboardUtil::GetFilenames(source_object_, &filenames); if (success) @@ -376,7 +395,8 @@ bool OSExchangeData::GetFilename(std::wstring* full_path) const { return success; } -bool OSExchangeData::GetPickledData(CLIPFORMAT format, Pickle* data) const { +bool OSExchangeDataProviderWin::GetPickledData(CLIPFORMAT format, + Pickle* data) const { DCHECK(data); FORMATETC format_etc = { format, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; @@ -395,13 +415,15 @@ bool OSExchangeData::GetPickledData(CLIPFORMAT format, Pickle* data) const { return success; } -bool OSExchangeData::GetFileContents(std::wstring* filename, - std::string* file_contents) const { +bool OSExchangeDataProviderWin::GetFileContents( + std::wstring* filename, + std::string* file_contents) const { return ClipboardUtil::GetFileContents(source_object_, filename, file_contents); } -bool OSExchangeData::GetHtml(std::wstring* html, GURL* base_url) const { +bool OSExchangeDataProviderWin::GetHtml(std::wstring* html, + GURL* base_url) const { std::string url; bool success = ClipboardUtil::GetHtml(source_object_, html, &url); if (success) @@ -409,27 +431,35 @@ bool OSExchangeData::GetHtml(std::wstring* html, GURL* base_url) const { return success; } -bool OSExchangeData::HasString() const { +bool OSExchangeDataProviderWin::HasString() const { return ClipboardUtil::HasPlainText(source_object_); } -bool OSExchangeData::HasURL() const { +bool OSExchangeDataProviderWin::HasURL() const { return (ClipboardUtil::HasUrl(source_object_) || HasPlainTextURL(source_object_)); } -bool OSExchangeData::HasFile() const { +bool OSExchangeDataProviderWin::HasFile() const { return ClipboardUtil::HasFilenames(source_object_); } -bool OSExchangeData::HasFormat(CLIPFORMAT format) const { +bool OSExchangeDataProviderWin::HasFileContents() const { + return ClipboardUtil::HasFileContents(source_object_); +} + +bool OSExchangeDataProviderWin::HasHtml() const { + return ClipboardUtil::HasHtml(source_object_); +} + +bool OSExchangeDataProviderWin::HasCustomFormat(CLIPFORMAT format) const { FORMATETC format_etc = { format, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; return (source_object_->QueryGetData(&format_etc) == S_OK); } /////////////////////////////////////////////////////////////////////////////// -// OSExchangeData, IDataObject implementation: +// DataObjectImpl, IDataObject implementation: // The following function, DuplicateMedium, is derived from WCDataObject.cpp // in the WebKit source code. This is the license information for the file: @@ -502,7 +532,15 @@ static void DuplicateMedium(CLIPFORMAT source_clipformat, destination->pUnkForRelease->AddRef(); } -HRESULT OSExchangeData::GetData(FORMATETC* format_etc, STGMEDIUM* medium) { +DataObjectImpl::DataObjectImpl() : ref_count_(0) { + STLDeleteContainerPointers(contents_.begin(), contents_.end()); +} + +DataObjectImpl::~DataObjectImpl() { + STLDeleteContainerPointers(contents_.begin(), contents_.end()); +} + +HRESULT DataObjectImpl::GetData(FORMATETC* format_etc, STGMEDIUM* medium) { StoredData::const_iterator iter = contents_.begin(); while (iter != contents_.end()) { if ((*iter)->format_etc.cfFormat == format_etc->cfFormat) { @@ -515,11 +553,12 @@ HRESULT OSExchangeData::GetData(FORMATETC* format_etc, STGMEDIUM* medium) { return DV_E_FORMATETC; } -HRESULT OSExchangeData::GetDataHere(FORMATETC* format_etc, STGMEDIUM* medium) { +HRESULT DataObjectImpl::GetDataHere(FORMATETC* format_etc, + STGMEDIUM* medium) { return DATA_E_FORMATETC; } -HRESULT OSExchangeData::QueryGetData(FORMATETC* format_etc) { +HRESULT DataObjectImpl::QueryGetData(FORMATETC* format_etc) { StoredData::const_iterator iter = contents_.begin(); while (iter != contents_.end()) { if ((*iter)->format_etc.cfFormat == format_etc->cfFormat) @@ -529,13 +568,13 @@ HRESULT OSExchangeData::QueryGetData(FORMATETC* format_etc) { return DV_E_FORMATETC; } -HRESULT OSExchangeData::GetCanonicalFormatEtc( +HRESULT DataObjectImpl::GetCanonicalFormatEtc( FORMATETC* format_etc, FORMATETC* result) { format_etc->ptd = NULL; return E_NOTIMPL; } -HRESULT OSExchangeData::SetData( +HRESULT DataObjectImpl::SetData( FORMATETC* format_etc, STGMEDIUM* medium, BOOL should_release) { STGMEDIUM* local_medium = new STGMEDIUM; if (should_release) { @@ -544,8 +583,8 @@ HRESULT OSExchangeData::SetData( DuplicateMedium(format_etc->cfFormat, medium, local_medium); } - StoredDataInfo* info = - new StoredDataInfo(format_etc->cfFormat, local_medium); + DataObjectImpl::StoredDataInfo* info = + new DataObjectImpl::StoredDataInfo(format_etc->cfFormat, local_medium); info->medium->tymed = format_etc->tymed; info->owns_medium = !!should_release; contents_.push_back(info); @@ -553,7 +592,7 @@ HRESULT OSExchangeData::SetData( return S_OK; } -HRESULT OSExchangeData::EnumFormatEtc( +HRESULT DataObjectImpl::EnumFormatEtc( DWORD direction, IEnumFORMATETC** enumerator) { if (direction == DATADIR_GET) { FormatEtcEnumerator* e = @@ -565,23 +604,23 @@ HRESULT OSExchangeData::EnumFormatEtc( return E_NOTIMPL; } -HRESULT OSExchangeData::DAdvise( +HRESULT DataObjectImpl::DAdvise( FORMATETC* format_etc, DWORD advf, IAdviseSink* sink, DWORD* connection) { return OLE_E_ADVISENOTSUPPORTED; } -HRESULT OSExchangeData::DUnadvise(DWORD connection) { +HRESULT DataObjectImpl::DUnadvise(DWORD connection) { return OLE_E_ADVISENOTSUPPORTED; } -HRESULT OSExchangeData::EnumDAdvise(IEnumSTATDATA** enumerator) { +HRESULT DataObjectImpl::EnumDAdvise(IEnumSTATDATA** enumerator) { return OLE_E_ADVISENOTSUPPORTED; } /////////////////////////////////////////////////////////////////////////////// -// OSExchangeData, IUnknown implementation: +// DataObjectImpl, IUnknown implementation: -HRESULT OSExchangeData::QueryInterface(const IID& iid, void** object) { +HRESULT DataObjectImpl::QueryInterface(const IID& iid, void** object) { *object = NULL; if (IsEqualIID(iid, IID_IUnknown) || IsEqualIID(iid, IID_IDataObject)) { *object = this; @@ -592,11 +631,11 @@ HRESULT OSExchangeData::QueryInterface(const IID& iid, void** object) { return S_OK; } -ULONG OSExchangeData::AddRef() { +ULONG DataObjectImpl::AddRef() { return InterlockedIncrement(&ref_count_); } -ULONG OSExchangeData::Release() { +ULONG DataObjectImpl::Release() { if (InterlockedDecrement(&ref_count_) == 0) { ULONG copied_refcnt = ref_count_; delete this; @@ -606,7 +645,7 @@ ULONG OSExchangeData::Release() { } /////////////////////////////////////////////////////////////////////////////// -// OSExchangeData, private: +// DataObjectImpl, private: static STGMEDIUM* GetStorageForBytes(const char* data, size_t bytes) { HANDLE handle = GlobalAlloc(GPTR, static_cast<int>(bytes)); @@ -702,3 +741,17 @@ static STGMEDIUM* GetStorageForFileDescriptor( storage->pUnkForRelease = NULL; return storage; } + +/////////////////////////////////////////////////////////////////////////////// +// OSExchangeData, public: + +// static +OSExchangeData::Provider* OSExchangeData::CreateProvider() { + return new OSExchangeDataProviderWin(); +} + +// static +OSExchangeData::CustomFormat OSExchangeData::RegisterCustomFormat( + const std::string& type) { + return RegisterClipboardFormat(ASCIIToWide(type).c_str()); +} diff --git a/app/os_exchange_data_provider_win.h b/app/os_exchange_data_provider_win.h new file mode 100644 index 0000000..42b11e2 --- /dev/null +++ b/app/os_exchange_data_provider_win.h @@ -0,0 +1,128 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef APP_OS_EXCHANGE_DATA_PROVIDER_WIN_H_ +#define APP_OS_EXCHANGE_DATA_PROVIDER_WIN_H_ + +#include <objidl.h> +#include <string> + +#include "app/os_exchange_data.h" +#include "base/scoped_comptr_win.h" + +class DataObjectImpl : public IDataObject { + public: + DataObjectImpl(); + ~DataObjectImpl(); + + // IDataObject implementation: + HRESULT __stdcall GetData(FORMATETC* format_etc, STGMEDIUM* medium); + HRESULT __stdcall GetDataHere(FORMATETC* format_etc, STGMEDIUM* medium); + HRESULT __stdcall QueryGetData(FORMATETC* format_etc); + HRESULT __stdcall GetCanonicalFormatEtc( + FORMATETC* format_etc, FORMATETC* result); + HRESULT __stdcall SetData( + FORMATETC* format_etc, STGMEDIUM* medium, BOOL should_release); + HRESULT __stdcall EnumFormatEtc( + DWORD direction, IEnumFORMATETC** enumerator); + HRESULT __stdcall DAdvise(FORMATETC* format_etc, DWORD advf, + IAdviseSink* sink, DWORD* connection); + HRESULT __stdcall DUnadvise(DWORD connection); + HRESULT __stdcall EnumDAdvise(IEnumSTATDATA** enumerator); + + // IUnknown implementation: + HRESULT __stdcall QueryInterface(const IID& iid, void** object); + ULONG __stdcall AddRef(); + ULONG __stdcall Release(); + + private: + // FormatEtcEnumerator only likes us for our StoredDataMap typedef. + friend class FormatEtcEnumerator; + friend class OSExchangeDataProviderWin; + + // Our internal representation of stored data & type info. + struct StoredDataInfo { + FORMATETC format_etc; + STGMEDIUM* medium; + bool owns_medium; + + StoredDataInfo(CLIPFORMAT cf, STGMEDIUM* a_medium) { + format_etc.cfFormat = cf; + format_etc.dwAspect = DVASPECT_CONTENT; + format_etc.lindex = -1; + format_etc.ptd = NULL; + format_etc.tymed = a_medium->tymed; + + owns_medium = true; + + medium = a_medium; + } + + ~StoredDataInfo() { + if (owns_medium) { + ReleaseStgMedium(medium); + delete medium; + } + } + }; + + typedef std::vector<StoredDataInfo*> StoredData; + StoredData contents_; + + ScopedComPtr<IDataObject> source_object_; + + LONG ref_count_; +}; + +class OSExchangeDataProviderWin : public OSExchangeData::Provider { + public: + // Returns true if source has plain text that is a valid url. + static bool HasPlainTextURL(IDataObject* source); + + // Returns true if source has plain text that is a valid URL and sets url to + // that url. + static bool GetPlainTextURL(IDataObject* source, GURL* url); + + static IDataObject* GetIDataObject(const OSExchangeData& data); + + explicit OSExchangeDataProviderWin(IDataObject* source); + OSExchangeDataProviderWin(); + + virtual ~OSExchangeDataProviderWin(); + + IDataObject* data_object() const { return data_.get(); } + + // OSExchangeData::Provider methods. + virtual void SetString(const std::wstring& data); + virtual void SetURL(const GURL& url, const std::wstring& title); + virtual void SetFilename(const std::wstring& full_path); + virtual void SetPickledData(OSExchangeData::CustomFormat format, + const Pickle& data); + virtual void SetFileContents(const std::wstring& filename, + const std::string& file_contents); + virtual void SetHtml(const std::wstring& html, const GURL& base_url); + + virtual bool GetString(std::wstring* data) const; + virtual bool GetURLAndTitle(GURL* url, std::wstring* title) const; + virtual bool GetFilename(std::wstring* full_path) const; + virtual bool GetPickledData(OSExchangeData::CustomFormat format, + Pickle* data) const; + virtual bool GetFileContents(std::wstring* filename, + std::string* file_contents) const; + virtual bool GetHtml(std::wstring* html, GURL* base_url) const; + virtual bool HasString() const; + virtual bool HasURL() const; + virtual bool HasFile() const; + virtual bool HasFileContents() const; + virtual bool HasHtml() const; + virtual bool HasCustomFormat(OSExchangeData::CustomFormat format) const; + + private: + scoped_refptr<DataObjectImpl> data_; + ScopedComPtr<IDataObject> source_object_; + + DISALLOW_COPY_AND_ASSIGN(OSExchangeDataProviderWin); +}; + +#endif // APP_OS_EXCHANGE_DATA_PROVIDER_WIN_H_ diff --git a/app/os_exchange_data_win_unittest.cc b/app/os_exchange_data_win_unittest.cc index 981a8d1..88f33b0 100644 --- a/app/os_exchange_data_win_unittest.cc +++ b/app/os_exchange_data_win_unittest.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "app/os_exchange_data.h" +#include "app/os_exchange_data_provider_win.h" #include "base/clipboard_util.h" #include "base/pickle.h" #include "base/ref_counted.h" @@ -14,32 +15,40 @@ typedef testing::Test OSExchangeDataTest; +namespace { + +OSExchangeData::Provider* CloneProvider(const OSExchangeData& data) { + return new OSExchangeDataProviderWin( + OSExchangeDataProviderWin::GetIDataObject(data)); +} + +} // namespace + // Test setting/getting using the OSExchangeData API TEST(OSExchangeDataTest, StringDataGetAndSet) { - OSExchangeData* data = new OSExchangeData; + OSExchangeData data; std::wstring input = L"I can has cheezburger?"; - data->SetString(input); + data.SetString(input); - OSExchangeData* data2 = new OSExchangeData(data); + OSExchangeData data2(CloneProvider(data)); std::wstring output; - EXPECT_TRUE(data2->GetString(&output)); + EXPECT_TRUE(data2.GetString(&output)); EXPECT_EQ(input, output); std::string url_spec = "http://www.goats.com/"; GURL url(url_spec); std::wstring title; - EXPECT_FALSE(data2->GetURLAndTitle(&url, &title)); + EXPECT_FALSE(data2.GetURLAndTitle(&url, &title)); // No URLs in |data|, so url should be untouched. EXPECT_EQ(url_spec, url.spec()); - // data gets freed when data2 releases the ref on it - delete data2; } // Test getting using the IDataObject COM API TEST(OSExchangeDataTest, StringDataAccessViaCOM) { - OSExchangeData* data = new OSExchangeData; + OSExchangeData data; std::wstring input = L"O hai googlz."; - data->SetString(input); - ScopedComPtr<IDataObject> com_data(data); + data.SetString(input); + ScopedComPtr<IDataObject> com_data( + OSExchangeDataProviderWin::GetIDataObject(data)); FORMATETC format_etc = { CF_UNICODETEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; @@ -55,10 +64,11 @@ TEST(OSExchangeDataTest, StringDataAccessViaCOM) { // Test setting using the IDataObject COM API TEST(OSExchangeDataTest, StringDataWritingViaCOM) { - OSExchangeData* data = new OSExchangeData; + OSExchangeData data; std::wstring input = L"http://www.google.com/"; - ScopedComPtr<IDataObject> com_data(data); + ScopedComPtr<IDataObject> com_data( + OSExchangeDataProviderWin::GetIDataObject(data)); // Store data in the object using the COM SetData API. CLIPFORMAT cfstr_ineturl = RegisterClipboardFormat(CFSTR_INETURL); @@ -78,22 +88,21 @@ TEST(OSExchangeDataTest, StringDataWritingViaCOM) { // Construct a new object with the old object so that we can use our access // APIs. - OSExchangeData* data2 = new OSExchangeData(com_data); - EXPECT_TRUE(data2->HasURL()); + OSExchangeData data2(CloneProvider(data)); + EXPECT_TRUE(data2.HasURL()); GURL url_from_data; std::wstring title; - EXPECT_TRUE(data2->GetURLAndTitle(&url_from_data, &title)); + EXPECT_TRUE(data2.GetURLAndTitle(&url_from_data, &title)); GURL reference_url(input); EXPECT_EQ(reference_url.spec(), url_from_data.spec()); - // deleting data2 will free data because it holds a ref to it. - delete data2; } TEST(OSExchangeDataTest, URLDataAccessViaCOM) { - OSExchangeData* data = new OSExchangeData; + OSExchangeData data; GURL url("http://www.google.com/"); - data->SetURL(url, L""); - ScopedComPtr<IDataObject> com_data(data); + data.SetURL(url, L""); + ScopedComPtr<IDataObject> com_data( + OSExchangeDataProviderWin::GetIDataObject(data)); CLIPFORMAT cfstr_ineturl = RegisterClipboardFormat(CFSTR_INETURL); FORMATETC format_etc = @@ -109,14 +118,15 @@ TEST(OSExchangeDataTest, URLDataAccessViaCOM) { } TEST(OSExchangeDataTest, MultipleFormatsViaCOM) { - OSExchangeData* data = new OSExchangeData; + OSExchangeData data; std::string url_spec = "http://www.google.com/"; GURL url(url_spec); std::wstring text = L"O hai googlz."; - data->SetURL(url, L"Google"); - data->SetString(text); + data.SetURL(url, L"Google"); + data.SetString(text); - ScopedComPtr<IDataObject> com_data(data); + ScopedComPtr<IDataObject> com_data( + OSExchangeDataProviderWin::GetIDataObject(data)); CLIPFORMAT cfstr_ineturl = RegisterClipboardFormat(CFSTR_INETURL); FORMATETC url_format_etc = @@ -143,15 +153,16 @@ TEST(OSExchangeDataTest, MultipleFormatsViaCOM) { } TEST(OSExchangeDataTest, EnumerationViaCOM) { - OSExchangeData* data = new OSExchangeData; - data->SetURL(GURL("http://www.google.com/"), L""); - data->SetString(L"O hai googlz."); + OSExchangeData data; + data.SetURL(GURL("http://www.google.com/"), L""); + data.SetString(L"O hai googlz."); CLIPFORMAT cfstr_file_group_descriptor = RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR); CLIPFORMAT text_x_moz_url = RegisterClipboardFormat(L"text/x-moz-url"); - ScopedComPtr<IDataObject> com_data(data); + ScopedComPtr<IDataObject> com_data( + OSExchangeDataProviderWin::GetIDataObject(data)); ScopedComPtr<IEnumFORMATETC> enumerator; EXPECT_EQ(S_OK, com_data.get()->EnumFormatEtc(DATADIR_GET, enumerator.Receive())); @@ -231,29 +242,30 @@ TEST(OSExchangeDataTest, EnumerationViaCOM) { } TEST(OSExchangeDataTest, TestURLExchangeFormats) { - OSExchangeData* data = new OSExchangeData; + OSExchangeData data; std::string url_spec = "http://www.google.com/"; GURL url(url_spec); std::wstring url_title = L"Google"; - data->SetURL(url, url_title); + data.SetURL(url, url_title); std::wstring output; - OSExchangeData* data2 = new OSExchangeData(data); + OSExchangeData data2(CloneProvider(data)); // URL spec and title should match GURL output_url; std::wstring output_title; - EXPECT_TRUE(data2->GetURLAndTitle(&output_url, &output_title)); + EXPECT_TRUE(data2.GetURLAndTitle(&output_url, &output_title)); EXPECT_EQ(url_spec, output_url.spec()); EXPECT_EQ(url_title, output_title); std::wstring output_string; // URL should be the raw text response - EXPECT_TRUE(data2->GetString(&output_string)); + EXPECT_TRUE(data2.GetString(&output_string)); EXPECT_EQ(url_spec, WideToUTF8(output_string)); // File contents access via COM - ScopedComPtr<IDataObject> com_data(data); + ScopedComPtr<IDataObject> com_data( + OSExchangeDataProviderWin::GetIDataObject(data)); { CLIPFORMAT cfstr_file_contents = RegisterClipboardFormat(CFSTR_FILECONTENTS); @@ -271,9 +283,6 @@ TEST(OSExchangeDataTest, TestURLExchangeFormats) { EXPECT_EQ(file_contents, output); ReleaseStgMedium(&medium); } - - // Need to manually free data2 since we never stuff it into a COMPtr. - delete data2; } TEST(OSExchangeDataTest, TestPickledData) { @@ -282,14 +291,14 @@ TEST(OSExchangeDataTest, TestPickledData) { Pickle saved_pickle; saved_pickle.WriteInt(1); saved_pickle.WriteInt(2); - scoped_refptr<OSExchangeData> data(new OSExchangeData()); - data->SetPickledData(test_cf, saved_pickle); + OSExchangeData data; + data.SetPickledData(test_cf, saved_pickle); - scoped_refptr<OSExchangeData> copy(new OSExchangeData(data.get())); - EXPECT_TRUE(copy->HasFormat(test_cf)); + OSExchangeData copy(CloneProvider(data)); + EXPECT_TRUE(copy.HasCustomFormat(test_cf)); Pickle restored_pickle; - EXPECT_TRUE(copy->GetPickledData(test_cf, &restored_pickle)); + EXPECT_TRUE(copy.GetPickledData(test_cf, &restored_pickle)); void* p_iterator = NULL; int value; EXPECT_TRUE(restored_pickle.ReadInt(&p_iterator, &value)); @@ -299,30 +308,30 @@ TEST(OSExchangeDataTest, TestPickledData) { } TEST(OSExchangeDataTest, FileContents) { - scoped_refptr<OSExchangeData> data(new OSExchangeData); + OSExchangeData data; std::string file_contents("data\0with\0nulls", 15); - data->SetFileContents(L"filename.txt", file_contents); + data.SetFileContents(L"filename.txt", file_contents); - scoped_refptr<OSExchangeData> copy(new OSExchangeData(data.get())); + OSExchangeData copy(CloneProvider(data)); std::wstring filename; std::string read_contents; - EXPECT_TRUE(copy->GetFileContents(&filename, &read_contents)); + EXPECT_TRUE(copy.GetFileContents(&filename, &read_contents)); EXPECT_EQ(L"filename.txt", filename); EXPECT_EQ(file_contents, read_contents); } TEST(OSExchangeDataTest, Html) { - scoped_refptr<OSExchangeData> data(new OSExchangeData); + OSExchangeData data; GURL url("http://www.google.com/"); std::wstring html( L"<HTML>\n<BODY>\n" L"<b>bold.</b> <i><b>This is bold italic.</b></i>\n" L"</BODY>\n</HTML>"); - data->SetHtml(html, url); + data.SetHtml(html, url); - scoped_refptr<OSExchangeData> copy(new OSExchangeData(data.get())); + OSExchangeData copy(CloneProvider(data)); std::wstring read_html; - EXPECT_TRUE(copy->GetHtml(&read_html, &url)); + EXPECT_TRUE(copy.GetHtml(&read_html, &url)); EXPECT_EQ(html, read_html); // Check the CF_HTML too. @@ -335,7 +344,9 @@ TEST(OSExchangeDataTest, Html) { expected_cf_html.append("\r\n<!--EndFragment-->\r\n</body>\r\n</html>"); STGMEDIUM medium; - EXPECT_EQ(S_OK, data->GetData(ClipboardUtil::GetHtmlFormat(), &medium)); + IDataObject* data_object = OSExchangeDataProviderWin::GetIDataObject(data); + EXPECT_EQ(S_OK, + data_object->GetData(ClipboardUtil::GetHtmlFormat(), &medium)); ScopedHGlobal<char> glob(medium.hGlobal); std::string output(glob.get(), glob.Size()); EXPECT_EQ(expected_cf_html, output); @@ -343,19 +354,19 @@ TEST(OSExchangeDataTest, Html) { } TEST(OSExchangeDataTest, SetURLWithMaxPath) { - scoped_refptr<OSExchangeData> data(new OSExchangeData); + OSExchangeData data; std::wstring long_title(L'a', MAX_PATH + 1); - data->SetURL(GURL("http://google.com"), long_title); + data.SetURL(GURL("http://google.com"), long_title); } TEST(OSExchangeDataTest, ProvideURLForPlainTextURL) { - scoped_refptr<OSExchangeData> data(new OSExchangeData); - data->SetString(L"http://google.com"); + OSExchangeData data; + data.SetString(L"http://google.com"); - scoped_ptr<OSExchangeData> data2(new OSExchangeData(data.get())); - ASSERT_TRUE(data2->HasURL()); + OSExchangeData data2(CloneProvider(data)); + ASSERT_TRUE(data2.HasURL()); GURL read_url; std::wstring title; - EXPECT_TRUE(data2->GetURLAndTitle(&read_url, &title)); + EXPECT_TRUE(data2.GetURLAndTitle(&read_url, &title)); EXPECT_EQ(GURL("http://google.com"), read_url); } |