Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: src/plugin/Wrapper.cpp

Issue 5750789393874944: [IE] First round of ATL removal (Closed)
Patch Set: Created June 20, 2014, 9:22 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/plugin/Wrapper.cpp
===================================================================
new file mode 100644
--- /dev/null
+++ b/src/plugin/Wrapper.cpp
@@ -0,0 +1,267 @@
+#include "Wrapper.h"
+#include "COM_Client.h"
+#include <Shlwapi.h>
+#include <WinInet.h>
+
+#include <memory>
+#include <string>
+#include <sstream>
+
+namespace Wrapper {
+
+ std::wstring & Unescape_URL( std::wstring & url )
Oleksandr 2014/06/26 00:48:43 This belongs to Utils.cpp, I think
Eric 2014/06/26 15:13:56 Since I started on this file, I've come to think t
+ {
+ DWORD result_length = INTERNET_MAX_URL_LENGTH;
+ /*
+ * The choice to allocate the result buffer is because the maximum length is larger than 2 Kb.
+ */
+ std::unique_ptr< wchar_t > result( new wchar_t[ result_length ] );
+ /*
+ * Casting away const here is harmless because we're not using the in-place modification mode of UrlUnescape
+ */
+ HRESULT hr = ::UrlUnescapeW( const_cast< wchar_t * >( url.c_str() ), result.get(), & result_length, 0 );
+ if ( hr == S_OK ) {
+ url = std::wstring( result.get(), result_length );
+ }
+ /*
+ * If the call to UrlUnescape fails, we don't alter the string.
+ * This matches the behavior of the previous wrapper.
+ * Because there's no error handling, however, there might be masked failures in UrlUnescape.
+ */
+ return url;
+ }
+
+ HRESULT Browser::navigate( std::wstring url )
+ {
+ /*
+ * Try first in a new tab.
+ */
+ BSTR_Argument url_arg( url );
+ VARIANT flags;
+ flags.vt = VT_I4;
+ flags.intVal = navOpenInNewTab;
+ HRESULT hr = _browser->Navigate( url_arg, &flags, 0, 0, 0 );
+ if ( !FAILED(hr) )
+ {
+ return hr;
+ }
+ /*
+ * The failure code seems to be mostly 0x80004005, an unspecified error from a COM object.
+ * What does seem to be consistent is that this error is "sticky", that is, once it starts happening, it keeps happening on that object.
+ * There are some related reports on the internet that this happens in other contexts.
+ * It's fairly clear this is some kind of defect internal to IE,
+ * and there's some reason to believe that this might be from some kind of internal race condition or other multiprocessing failure.
+ */
+ /*
+ * Try next in a new window.
+ */
+ flags.intVal = navOpenInNewWindow;
+ /*
+ * We're not copying the URL a second time, since the first copy was purely defensive.
+ * Nevertheless, if there are problems with this function, it should be verified that url_temp is not getting modified.
+ */
+ hr = _browser->Navigate( url_arg, &flags, 0, 0, 0 );
+ return hr;
+ }
+
+ bool Browser::Location_URL( std::wstring & value ) const
+ {
+ BSTR result;
+ HRESULT hr = _browser->get_LocationURL( &result );
+ if ( hr == S_OK )
+ {
+ value = result ? Returned_BSTR( result ) : std::wstring();
+ return true;
+ }
+ return false;
+ }
+
+ std::wstring Internet_Bind_Info::bind_string_single( BINDSTRING type )
+ {
+ unsigned long n_results;
+ LPOLESTR results[10];
+ HRESULT hr = _bind_info->GetBindString( type, results, 10, &n_results );
+ if ( hr == S_OK && n_results > 0)
+ {
+ return std::wstring( results[0] );
+ }
+ return std::wstring();
+ }
+
+ /*
+ * A return value of S_OK does not indicate that an attribute is present.
+ * Instead, the variant type is something other than VT_NULL if present.
+ * See comments at MSDN http://msdn.microsoft.com/en-us/library/aa752280%28v=vs.85%29.aspx
+ */
+ bool HTML_Element::attribute( std::wstring attr_name, std::wstring & attr_value ) const
+ {
+ VARIANT result;
+ BSTR_Argument name( attr_name );
+
+ _element->getAttribute( name, 0, &result );
+ if ( result.vt == VT_NULL )
+ {
+ return false;
+ }
+ if ( result.vt == VT_BSTR )
+ {
+ attr_value = Returned_BSTR( result.bstrVal );
+ }
+ else if ( result.vt == VT_I2 )
+ {
+ //
+ std::wostringstream ss;
+ ss << result.iVal;
+ attr_value = ss.str();
+ }
+ else if ( result.vt == VT_I4 )
+ {
+ std::wostringstream ss;
+ ss << result.lVal;
+ attr_value = ss.str();
+ }
+ /*
+ * If the result variant does not return one of the above supported types,
+ * we return true, indicating the attribute is found, but no attribute value.
+ */
+ return true;
+ }
+
+ /*
+ * This implementation relies on the behavior that IE returns a variant of type VT_I4 for integer values.
+ */
+ bool HTML_Element::attribute( std::wstring attr_name, int & attr_value ) const
+ {
+ static_assert( sizeof( int ) >= 4, "Size of 'int' must be at least 4" );
+ VARIANT result;
+ BSTR_Argument name( attr_name );
+
+ _element->getAttribute( name, 0, &result );
+ /*
+ * VT_I4 and VT_I2 are supported, VT_I2 just to be defensive.
+ */
+ if ( result.vt == VT_I4 )
+ {
+ attr_value = result.lVal;
+ return true;
+ }
+ else if ( result.vt == VT_I2 )
+ {
+ attr_value = result.iVal;
+ return true;
+ }
+ /*
+ * Any other return type will return false,
+ * whether the attribute is not present or whether it's present but not a (supported) integer type.
+ */
+ if ( result.vt == VT_BSTR )
+ {
+ /*
+ * If we get a BSTR return value, we need to release it, even if we're not using it.
+ * The destructor for Returned_BSTR takes care of that
+ */
+ Returned_BSTR( result.bstrVal );
+ }
+ return false;
+ }
+
+ bool HTML_Element::id( std::wstring & value ) const
+ {
+ BSTR result;
+ HRESULT hr = _element->get_id( &result );
+ if ( hr == S_OK )
+ {
+ value = result ? Returned_BSTR( result ) : std::wstring();
+ return true;
+ }
+ return false;
+ }
+
+ bool HTML_Element::class_name( std::wstring & value ) const
+ {
+ BSTR result;
+ HRESULT hr = _element->get_className( &result );
+ /*
+ * get_className seems to return S_OK and result==NULL as a valid answer.
+ */
+ if ( hr == S_OK )
+ {
+ value = result ? Returned_BSTR( result ) : std::wstring();
+ return true;
+ }
+ return false;
+ }
+
+ bool HTML_Element::inner_HTML( std::wstring & value ) const
+ {
+ BSTR result;
+ HRESULT hr = _element->get_innerHTML( &result );
+ if ( hr == S_OK )
+ {
+ value = result ? Returned_BSTR( result ) : std::wstring();
+ return true;
+ }
+ return false;
+ }
+
+ bool HTML_Element::tag_name( std::wstring & value ) const
+ {
+ BSTR result;
+ HRESULT hr = _element->get_tagName( &result );
+ if ( hr == S_OK )
+ {
+ value = result ? Returned_BSTR( result ) : std::wstring();
+ return true;
+ }
+ return false;
+ }
+
+ bool HTML_Style::display( std::wstring & value ) const
+ {
+ BSTR result;
+ HRESULT hr = _style->get_display( &result );
+ if ( hr == S_OK )
+ {
+ value = result ? Returned_BSTR( result ) : std::wstring();
+ return true;
+ }
+ return false;
+ }
+
+ bool HTML_Style::assign_display( const std::wstring & value )
+ {
+ BSTR_Argument value_arg( value );
+ HRESULT hr = _style->put_display( value_arg );
+ return hr == S_OK;
+ }
+
+ bool HTML_Style::CSS_text( std::wstring & value ) const
+ {
+ BSTR result;
+ HRESULT hr = _style->get_cssText( &result );
+ if ( hr == S_OK )
+ {
+ value = result ? Returned_BSTR( result ) : std::wstring();
+ return true;
+ }
+ return false;
+ }
+
+ IDispatch * HTML_Element_Collection::at( long index )
+ {
+ VARIANT index_arg;
+ index_arg.vt = VT_I4;
+ index_arg.lVal = index;
+
+ VARIANT nothing;
+ nothing.vt = VT_EMPTY;
+
+ IDispatch * result;
+ HRESULT hr = _elements->item( index_arg, nothing, &result );
+ /*
+ * Although item() returns S_OK if the element is not found,
+ * it still might return other values and have undocumented effects on 'result'.
+ */
+ return ( hr != S_OK ) ? 0 : result;
+ }
+}
« src/plugin/Wrapper.h ('K') | « src/plugin/Wrapper.h ('k') | test/Util_Test.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld