<commit_before>// 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 "webkit/glue/plugins/plugin_lib.h"

#include <dlfcn.h>

#include "base/string_util.h"
#include "base/sys_string_conversions.h"
#include "webkit/glue/plugins/plugin_list.h"

// These headers must be included in this order to make the declaration gods
// happy.
#include "base/third_party/nspr/prcpucfg_linux.h"
#include "third_party/mozilla/include/nsplugindefs.h"

namespace NPAPI {

bool PluginLib::ReadWebPluginInfo(const FilePath& filename,
                                  WebPluginInfo* info) {
  // The file to reference is:
  // http://mxr.mozilla.org/firefox/source/modules/plugin/base/src/nsPluginsDirUnix.cpp

  void* dl = base::LoadNativeLibrary(filename);
  if (!dl)
    return false;

  info->path = filename;

  // See comments in plugin_lib_mac regarding this symbol.
  typedef const char* (*NP_GetMimeDescriptionType)();
  NP_GetMimeDescriptionType NP_GetMIMEDescription =
      reinterpret_cast<NP_GetMimeDescriptionType>(
          dlsym(dl, "NP_GetMIMEDescription"));
  const char* mime_description = NULL;
  if (NP_GetMIMEDescription)
    mime_description = NP_GetMIMEDescription();

  if (mime_description) {
    // We parse the description here into WebPluginMimeType structures.
    // Description for Flash 10 looks like (all as one string):
    //   "application/x-shockwave-flash:swf:Shockwave Flash;"
    //   "application/futuresplash:spl:FutureSplash Player"
    std::vector<std::string> descriptions;
    SplitString(mime_description, ';', &descriptions);
    for (size_t i = 0; i < descriptions.size(); ++i) {
      std::vector<std::string> fields;
      SplitString(descriptions[i], ':', &fields);
      if (fields.size() != 3) {
        LOG(WARNING) << "Couldn't parse plugin info: " << descriptions[i];
        continue;
      }

      WebPluginMimeType mime_type;
      mime_type.mime_type = fields[0];
      SplitString(fields[1], ',', &mime_type.file_extensions);
      mime_type.description = ASCIIToWide(fields[2]);
      info->mime_types.push_back(mime_type);
    }
  }

  // The plugin name and description live behind NP_GetValue calls.
  typedef NPError (*NP_GetValueType)(void* unused,
                                     nsPluginVariable variable,
                                     void* value_out);
  NP_GetValueType NP_GetValue =
      reinterpret_cast<NP_GetValueType>(dlsym(dl, "NP_GetValue"));
  if (NP_GetValue) {
    const char* name = NULL;
    NP_GetValue(NULL, nsPluginVariable_NameString, &name);
    if (name)
      info->name = ASCIIToWide(name);

    const char* description = NULL;
    NP_GetValue(NULL, nsPluginVariable_DescriptionString, &description);
    if (description)
      info->desc = ASCIIToWide(description);
  }

  return true;
}

}  // namespace NPAPI
<commit_msg>linux plugins: assume UTF-8 for plugin name/description<commit_after>// 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 "webkit/glue/plugins/plugin_lib.h"

#include <dlfcn.h>

#include "base/string_util.h"
#include "base/sys_string_conversions.h"
#include "webkit/glue/plugins/plugin_list.h"

// These headers must be included in this order to make the declaration gods
// happy.
#include "base/third_party/nspr/prcpucfg_linux.h"
#include "third_party/mozilla/include/nsplugindefs.h"

namespace NPAPI {

bool PluginLib::ReadWebPluginInfo(const FilePath& filename,
                                  WebPluginInfo* info) {
  // The file to reference is:
  // http://mxr.mozilla.org/firefox/source/modules/plugin/base/src/nsPluginsDirUnix.cpp

  void* dl = base::LoadNativeLibrary(filename);
  if (!dl)
    return false;

  info->path = filename;

  // See comments in plugin_lib_mac regarding this symbol.
  typedef const char* (*NP_GetMimeDescriptionType)();
  NP_GetMimeDescriptionType NP_GetMIMEDescription =
      reinterpret_cast<NP_GetMimeDescriptionType>(
          dlsym(dl, "NP_GetMIMEDescription"));
  const char* mime_description = NULL;
  if (NP_GetMIMEDescription)
    mime_description = NP_GetMIMEDescription();

  if (mime_description) {
    // We parse the description here into WebPluginMimeType structures.
    // Description for Flash 10 looks like (all as one string):
    //   "application/x-shockwave-flash:swf:Shockwave Flash;"
    //   "application/futuresplash:spl:FutureSplash Player"
    std::vector<std::string> descriptions;
    SplitString(mime_description, ';', &descriptions);
    for (size_t i = 0; i < descriptions.size(); ++i) {
      if (descriptions[i].empty())
        continue;  // Don't warn if they have trailing semis.

      std::vector<std::string> fields;
      SplitString(descriptions[i], ':', &fields);
      if (fields.size() != 3) {
        LOG(WARNING) << "Couldn't parse plugin info: " << descriptions[i];
        continue;
      }

      WebPluginMimeType mime_type;
      mime_type.mime_type = fields[0];
      SplitString(fields[1], ',', &mime_type.file_extensions);
      mime_type.description = ASCIIToWide(fields[2]);
      info->mime_types.push_back(mime_type);
    }
  }

  // The plugin name and description live behind NP_GetValue calls.
  typedef NPError (*NP_GetValueType)(void* unused,
                                     nsPluginVariable variable,
                                     void* value_out);
  NP_GetValueType NP_GetValue =
      reinterpret_cast<NP_GetValueType>(dlsym(dl, "NP_GetValue"));
  if (NP_GetValue) {
    const char* name = NULL;
    NP_GetValue(NULL, nsPluginVariable_NameString, &name);
    if (name)
      info->name = UTF8ToWide(name);

    const char* description = NULL;
    NP_GetValue(NULL, nsPluginVariable_DescriptionString, &description);
    if (description)
      info->desc = UTF8ToWide(description);
  }

  return true;
}

}  // namespace NPAPI
<|endoftext|>


<commit_before>// 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 "config.h"

#include "webkit/glue/plugins/plugin_lib.h"

#include "base/string_util.h"
#include "base/sys_string_conversions.h"
#include "webkit/glue/plugins/plugin_list.h"

namespace NPAPI {

// static
PluginLib::NativeLibrary PluginLib::LoadNativeLibrary(
    const FilePath& library_path) {
  NOTIMPLEMENTED();
  return NULL;
}

// static
void PluginLib::UnloadNativeLibrary(NativeLibrary library) {
  NOTIMPLEMENTED();
}

// static
void* PluginLib::GetFunctionPointerFromNativeLibrary(
    NativeLibrary library,
    NativeLibraryFunctionNameType name) {
  NOTIMPLEMENTED();
  return NULL;
}

bool PluginLib::ReadWebPluginInfo(const FilePath& filename,
                                  WebPluginInfo* info,
                                  NP_GetEntryPointsFunc* np_getentrypoints,
                                  NP_InitializeFunc* np_initialize,
                                  NP_ShutdownFunc* np_shutdown) {
  *np_getentrypoints = NULL;
  *np_initialize = NULL;
  *np_shutdown = NULL;

  return false;
}

}  // namespace NPAPI
<commit_msg>Linux plugin loader loads and unloads .so files.<commit_after>// 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 "config.h"

#include "webkit/glue/plugins/plugin_lib.h"

#include <dlfcn.h>
#include <errno.h>
#include <string.h>

#include "base/string_util.h"
#include "base/sys_string_conversions.h"
#include "webkit/glue/plugins/plugin_list.h"

namespace NPAPI {

// static
PluginLib::NativeLibrary PluginLib::LoadNativeLibrary(
    const FilePath& library_path) {
  void* dl = dlopen(library_path.value().c_str(), RTLD_LAZY);
  if (!dl)
    NOTREACHED() << "dlopen failed: " << strerror(errno);

  return dl;
}

// static
void PluginLib::UnloadNativeLibrary(NativeLibrary library) {
  int ret = dlclose(library);
  if (ret < 0)
    NOTREACHED() << "dlclose failed: " << strerror(errno);
}

// static
void* PluginLib::GetFunctionPointerFromNativeLibrary(
    NativeLibrary library,
    NativeLibraryFunctionNameType name) {
  return dlsym(library, name);
}

bool PluginLib::ReadWebPluginInfo(const FilePath& filename,
                                  WebPluginInfo* info,
                                  NP_GetEntryPointsFunc* np_getentrypoints,
                                  NP_InitializeFunc* np_initialize,
                                  NP_ShutdownFunc* np_shutdown) {
  // The file to reference is:
  // http://mxr.mozilla.org/firefox/source/modules/plugin/base/src/nsPluginsDirUnix.cpp

  *np_getentrypoints = NULL;
  *np_initialize = NULL;
  *np_shutdown = NULL;

  void* dl = LoadNativeLibrary(filename);
  if (!dl)
    return false;

  void* ns_get_factory = GetFunctionPointerFromNativeLibrary(dl,
                                                             "NSGetFactory");

  if (ns_get_factory) {
    // Mozilla calls this an "almost-new-style plugin", then proceeds to
    // poke at it via XPCOM.  Our testing plugin doesn't use it.
    NOTIMPLEMENTED() << ": " << filename.value()
                     << " is an \"almost-new-style plugin\".";
    UnloadNativeLibrary(dl);
    return false;
  }

  // See comments in plugin_lib_mac regarding this symbol.
  typedef const char* (*GetMimeDescriptionType)();
  GetMimeDescriptionType ns_get_mime_description =
      reinterpret_cast<GetMimeDescriptionType>(
          GetFunctionPointerFromNativeLibrary(dl, "NP_GetMIMEDescription"));
  const char* description = "";
  if (ns_get_mime_description)
    description = ns_get_mime_description();

  // TODO(port): pick up from here.
  LOG(INFO) << description;
  NOTIMPLEMENTED();
  UnloadNativeLibrary(dl);
  return false;
}

}  // namespace NPAPI
<|endoftext|>


<commit_before>// Copyright (c) 2010 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 <string>

#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/net/url_fixer_upper.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "net/test/test_server.h"

namespace {

const FilePath::CharType kDocRoot[] = FILE_PATH_LITERAL("chrome/test/data");

}  // namespace

typedef UITest RepostFormWarningTest;

#if defined(OS_WIN)
// http://crbug.com/47228
#define MAYBE_TestDoubleReload FLAKY_TestDoubleReload
#else
#define MAYBE_TestDoubleReload TestDoubleReload
#endif

TEST_F(RepostFormWarningTest, MAYBE_TestDoubleReload) {
  net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  scoped_refptr<TabProxy> tab(browser->GetTab(0));
  ASSERT_TRUE(tab.get());

  // Load a form.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("files/form.html")));
  // Submit it.
  ASSERT_TRUE(tab->NavigateToURL(GURL(
      "javascript:document.getElementById('form').submit()")));

  // Try to reload it twice, checking for repost.
  tab->ReloadAsync();
  tab->ReloadAsync();

  // Navigate away from the page (this is when the test usually crashes).
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("bar")));
}

#if defined(OS_WIN)
// http://crbug.com/47228
#define MAYBE_TestLoginAfterRepost FLAKY_TestLoginAfterRepost
#else
#define MAYBE_TestLoginAfterRepost TestLoginAfterRepost
#endif

TEST_F(RepostFormWarningTest, MAYBE_TestLoginAfterRepost) {
  net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  scoped_refptr<TabProxy> tab(browser->GetTab(0));
  ASSERT_TRUE(tab.get());

  // Load a form.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("files/form.html")));
  // Submit it.
  ASSERT_TRUE(tab->NavigateToURL(GURL(
      "javascript:document.getElementById('form').submit()")));

  // Try to reload it, checking for repost.
  tab->ReloadAsync();

  // Navigate to a page that requires authentication, bringing up another
  // tab-modal sheet.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("auth-basic")));

  // Try to reload it again.
  tab->ReloadAsync();

  // Navigate away from the page.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("bar")));
}
<commit_msg>Make TestLoginAfterRepost flaky on linux.<commit_after>// Copyright (c) 2010 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 <string>

#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/net/url_fixer_upper.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "net/test/test_server.h"

namespace {

const FilePath::CharType kDocRoot[] = FILE_PATH_LITERAL("chrome/test/data");

}  // namespace

typedef UITest RepostFormWarningTest;

#if defined(OS_WIN)
// http://crbug.com/47228
#define MAYBE_TestDoubleReload FLAKY_TestDoubleReload
#else
#define MAYBE_TestDoubleReload TestDoubleReload
#endif

TEST_F(RepostFormWarningTest, MAYBE_TestDoubleReload) {
  net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  scoped_refptr<TabProxy> tab(browser->GetTab(0));
  ASSERT_TRUE(tab.get());

  // Load a form.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("files/form.html")));
  // Submit it.
  ASSERT_TRUE(tab->NavigateToURL(GURL(
      "javascript:document.getElementById('form').submit()")));

  // Try to reload it twice, checking for repost.
  tab->ReloadAsync();
  tab->ReloadAsync();

  // Navigate away from the page (this is when the test usually crashes).
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("bar")));
}

#if defined(OS_WIN) || defined(OS_LINUX)
// http://crbug.com/47228 && http://crbug.com/56401
#define MAYBE_TestLoginAfterRepost FLAKY_TestLoginAfterRepost
#else
#define MAYBE_TestLoginAfterRepost TestLoginAfterRepost
#endif

TEST_F(RepostFormWarningTest, MAYBE_TestLoginAfterRepost) {
  net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  scoped_refptr<TabProxy> tab(browser->GetTab(0));
  ASSERT_TRUE(tab.get());

  // Load a form.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("files/form.html")));
  // Submit it.
  ASSERT_TRUE(tab->NavigateToURL(GURL(
      "javascript:document.getElementById('form').submit()")));

  // Try to reload it, checking for repost.
  tab->ReloadAsync();

  // Navigate to a page that requires authentication, bringing up another
  // tab-modal sheet.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("auth-basic")));

  // Try to reload it again.
  tab->ReloadAsync();

  // Navigate away from the page.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("bar")));
}
<|endoftext|>


<commit_before>/*************************************************************************
 * Copyright (c) 2014 eProsima. All rights reserved.
 *
 * This copy of eProsima Fast RTPS is licensed to you under the terms described in the
 * FASTRTPS_LIBRARY_LICENSE file included in this distribution.
 *
 *************************************************************************/

/**
 * @file ReaderHistory.cpp
 *
 */

#include <fastrtps/rtps/history/ReaderHistory.h>

#include <fastrtps/utils/RTPSLog.h>
#include <fastrtps/rtps/reader/RTPSReader.h>
#include <fastrtps/rtps/reader/ReaderListener.h>

#include <boost/thread/recursive_mutex.hpp>
#include <boost/thread/lock_guard.hpp>
#include <boost/interprocess/sync/interprocess_semaphore.hpp>

namespace eprosima {
namespace fastrtps{
namespace rtps {

static const char* const CLASS_NAME = "ReaderHistory";

//typedef std::pair<InstanceHandle_t,std::vector<CacheChange_t*>> t_pairKeyChanges;
//typedef std::vector<t_pairKeyChanges> t_vectorPairKeyChanges;

inline bool sort_ReaderHistoryCache(CacheChange_t*c1, CacheChange_t*c2)
{
	return c1->sequenceNumber < c2->sequenceNumber;
}

ReaderHistory::ReaderHistory(const HistoryAttributes& att):
						History(att),
						mp_reader(nullptr),
						mp_semaphore(new boost::interprocess::interprocess_semaphore(0))

{

}

ReaderHistory::~ReaderHistory()
{
	// TODO Auto-generated destructor stub
	delete(mp_semaphore);
}

bool ReaderHistory::received_change(CacheChange_t* change, size_t)
{
	return add_change(change);
}

bool ReaderHistory::add_change(CacheChange_t* a_change)
{
	const char* const METHOD_NAME = "add_change";

	if(mp_reader == nullptr || mp_mutex == nullptr)
	{
		logError(RTPS_HISTORY,"You need to create a Reader with this History before adding any changes");
		return false;
	}

	boost::lock_guard<boost::recursive_mutex> guard(*mp_mutex);
	if(a_change->serializedPayload.length > m_att.payloadMaxSize)
	{
		logError(RTPS_HISTORY,"The Payload length is larger than the maximum payload size");
		return false;
	}
	if(a_change->writerGUID == c_Guid_Unknown)
	{
		logError(RTPS_HISTORY,"The Writer GUID_t must be defined");
	}
	m_historyRecord.insert(std::make_pair(a_change->writerGUID,std::set<SequenceNumber_t>()));
	if ((m_historyRecord[a_change->writerGUID].insert(a_change->sequenceNumber)).second)
	{
		m_changes.push_back(a_change);
        sortCacheChanges();
		updateMaxMinSeqNum();
		logInfo(RTPS_HISTORY, "Change " << a_change->sequenceNumber << " added with " << a_change->serializedPayload.length << " bytes");
		return true;
	}
	logInfo(RTPS_HISTORY, "Change "<<  a_change->sequenceNumber << " from "<< a_change->writerGUID << " not added.");
	return false;
}

bool ReaderHistory::remove_change(CacheChange_t* a_change)
{
	const char* const METHOD_NAME = "remove_change";

	if(mp_reader == nullptr || mp_mutex == nullptr)
	{
		logError(RTPS_HISTORY,"You need to create a Reader with this History before removing any changes");
		return false;
	}

	boost::lock_guard<boost::recursive_mutex> guard(*mp_mutex);
	if(a_change == nullptr)
	{
		logError(RTPS_HISTORY,"Pointer is not valid")
		return false;
	}
	for(std::vector<CacheChange_t*>::iterator chit = m_changes.begin();
			chit!=m_changes.end();++chit)
	{
		if((*chit)->sequenceNumber == a_change->sequenceNumber &&
				(*chit)->writerGUID == a_change->writerGUID)
		{
			logInfo(RTPS_HISTORY,"Removing change "<< a_change->sequenceNumber);
			mp_reader->change_removed_by_history(a_change);
			m_changePool.release_Cache(a_change);
			m_changes.erase(chit);
			sortCacheChanges();
			updateMaxMinSeqNum();
			return true;
		}
	}
	logWarning(RTPS_HISTORY,"SequenceNumber "<<a_change->sequenceNumber << " not found");
	return false;
}

void ReaderHistory::sortCacheChanges()
{
	std::sort(m_changes.begin(),m_changes.end(),sort_ReaderHistoryCache);
}

void ReaderHistory::updateMaxMinSeqNum()
{
	if(m_changes.size()==0)
	{
		mp_minSeqCacheChange = mp_invalidCache;
		mp_maxSeqCacheChange = mp_invalidCache;
	}
	else
	{
		mp_minSeqCacheChange = m_changes.front();
		mp_maxSeqCacheChange = m_changes.back();
	}
}

void ReaderHistory::postSemaphore()
{
	return mp_semaphore->post();
}

void ReaderHistory::waitSemaphore() //TODO CAMBIAR NOMBRE PARA que el usuario sepa que es para esperar a un cachechange nuevo
{
	return mp_semaphore->wait();
}

bool ReaderHistory::thereIsRecordOf(GUID_t& guid, SequenceNumber_t& seq)
{
    return m_historyRecord[guid].find(seq) != m_historyRecord[guid].end();
}

bool ReaderHistory::thereIsUpperRecordOf(GUID_t& guid, SequenceNumber_t& seq)
{
    return m_historyRecord[guid].upper_bound(seq) != m_historyRecord[guid].end();
}

}
} /* namespace rtps */
} /* namespace eprosima */
<commit_msg>Cleaning history record<commit_after>/*************************************************************************
 * Copyright (c) 2014 eProsima. All rights reserved.
 *
 * This copy of eProsima Fast RTPS is licensed to you under the terms described in the
 * FASTRTPS_LIBRARY_LICENSE file included in this distribution.
 *
 *************************************************************************/

/**
 * @file ReaderHistory.cpp
 *
 */

#include <fastrtps/rtps/history/ReaderHistory.h>

#include <fastrtps/utils/RTPSLog.h>
#include <fastrtps/rtps/reader/RTPSReader.h>
#include <fastrtps/rtps/reader/ReaderListener.h>

#include <boost/thread/recursive_mutex.hpp>
#include <boost/thread/lock_guard.hpp>
#include <boost/interprocess/sync/interprocess_semaphore.hpp>

namespace eprosima {
namespace fastrtps{
namespace rtps {

static const char* const CLASS_NAME = "ReaderHistory";

//typedef std::pair<InstanceHandle_t,std::vector<CacheChange_t*>> t_pairKeyChanges;
//typedef std::vector<t_pairKeyChanges> t_vectorPairKeyChanges;

inline bool sort_ReaderHistoryCache(CacheChange_t*c1, CacheChange_t*c2)
{
	return c1->sequenceNumber < c2->sequenceNumber;
}

ReaderHistory::ReaderHistory(const HistoryAttributes& att):
						History(att),
						mp_reader(nullptr),
						mp_semaphore(new boost::interprocess::interprocess_semaphore(0))

{

}

ReaderHistory::~ReaderHistory()
{
	// TODO Auto-generated destructor stub
	delete(mp_semaphore);
}

bool ReaderHistory::received_change(CacheChange_t* change, size_t)
{
	return add_change(change);
}

bool ReaderHistory::add_change(CacheChange_t* a_change)
{
	const char* const METHOD_NAME = "add_change";

	if(mp_reader == nullptr || mp_mutex == nullptr)
	{
		logError(RTPS_HISTORY,"You need to create a Reader with this History before adding any changes");
		return false;
	}

	boost::lock_guard<boost::recursive_mutex> guard(*mp_mutex);
	if(a_change->serializedPayload.length > m_att.payloadMaxSize)
	{
		logError(RTPS_HISTORY,"The Payload length is larger than the maximum payload size");
		return false;
	}
	if(a_change->writerGUID == c_Guid_Unknown)
	{
		logError(RTPS_HISTORY,"The Writer GUID_t must be defined");
	}

	if(m_historyRecord.insert(std::make_pair(a_change->writerGUID,std::set<SequenceNumber_t>())).second)
        m_historyRecord[a_change->writerGUID].insert(SequenceNumber_t());

	if(*m_historyRecord[a_change->writerGUID].begin() < a_change->sequenceNumber && m_historyRecord[a_change->writerGUID].insert(a_change->sequenceNumber).second)
	{
		m_changes.push_back(a_change);
        sortCacheChanges();
		updateMaxMinSeqNum();
		logInfo(RTPS_HISTORY, "Change " << a_change->sequenceNumber << " added with " << a_change->serializedPayload.length << " bytes");

        // Clean history record
        auto set_it = m_historyRecord[a_change->writerGUID].begin();
        auto set_it_next = set_it;
        ++set_it_next;
        while(set_it_next != m_historyRecord[a_change->writerGUID].end() &&
                *set_it == (*set_it_next + 1))
        {
            set_it = m_historyRecord[a_change->writerGUID].erase(set_it);
            set_it_next = set_it;
            ++set_it_next;
        }

		return true;
	}

    logInfo(RTPS_HISTORY, "Change "<<  a_change->sequenceNumber << " from "<< a_change->writerGUID << " not added.");
	return false;
}

bool ReaderHistory::remove_change(CacheChange_t* a_change)
{
	const char* const METHOD_NAME = "remove_change";

	if(mp_reader == nullptr || mp_mutex == nullptr)
	{
		logError(RTPS_HISTORY,"You need to create a Reader with this History before removing any changes");
		return false;
	}

	boost::lock_guard<boost::recursive_mutex> guard(*mp_mutex);
	if(a_change == nullptr)
	{
		logError(RTPS_HISTORY,"Pointer is not valid")
		return false;
	}
	for(std::vector<CacheChange_t*>::iterator chit = m_changes.begin();
			chit!=m_changes.end();++chit)
	{
		if((*chit)->sequenceNumber == a_change->sequenceNumber &&
				(*chit)->writerGUID == a_change->writerGUID)
		{
			logInfo(RTPS_HISTORY,"Removing change "<< a_change->sequenceNumber);
			mp_reader->change_removed_by_history(a_change);
			m_changePool.release_Cache(a_change);
			m_changes.erase(chit);
			sortCacheChanges();
			updateMaxMinSeqNum();
			return true;
		}
	}
	logWarning(RTPS_HISTORY,"SequenceNumber "<<a_change->sequenceNumber << " not found");
	return false;
}

void ReaderHistory::sortCacheChanges()
{
	std::sort(m_changes.begin(),m_changes.end(),sort_ReaderHistoryCache);
}

void ReaderHistory::updateMaxMinSeqNum()
{
	if(m_changes.size()==0)
	{
		mp_minSeqCacheChange = mp_invalidCache;
		mp_maxSeqCacheChange = mp_invalidCache;
	}
	else
	{
		mp_minSeqCacheChange = m_changes.front();
		mp_maxSeqCacheChange = m_changes.back();
	}
}

void ReaderHistory::postSemaphore()
{
	return mp_semaphore->post();
}

void ReaderHistory::waitSemaphore() //TODO CAMBIAR NOMBRE PARA que el usuario sepa que es para esperar a un cachechange nuevo
{
	return mp_semaphore->wait();
}

bool ReaderHistory::thereIsRecordOf(GUID_t& guid, SequenceNumber_t& seq)
{
    return m_historyRecord[guid].find(seq) != m_historyRecord[guid].end();
}

bool ReaderHistory::thereIsUpperRecordOf(GUID_t& guid, SequenceNumber_t& seq)
{
    return m_historyRecord[guid].upper_bound(seq) != m_historyRecord[guid].end();
}

}
} /* namespace rtps */
} /* namespace eprosima */
<|endoftext|>


<commit_before>// 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 "chrome/browser/shell_integration.h"

#include <map>

#include "base/file_path.h"
#include "base/file_util.h"
#include "base/linux_util.h"
#include "base/message_loop.h"
#include "base/scoped_temp_dir.h"
#include "base/stl_util-inl.h"
#include "base/string_util.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths_internal.h"
#include "googleurl/src/gurl.h"
#include "testing/gtest/include/gtest/gtest.h"

#define FPL FILE_PATH_LITERAL

#if defined(OS_LINUX)
namespace {

// Provides mock environment variables values based on a stored map.
class MockEnvironmentVariableGetter : public base::EnvironmentVariableGetter {
 public:
  MockEnvironmentVariableGetter() {
  }

  void Set(const std::string& name, const std::string& value) {
    variables_[name] = value;
  }

  virtual bool Getenv(const char* variable_name, std::string* result) {
    if (ContainsKey(variables_, variable_name)) {
      *result = variables_[variable_name];
      return true;
    }

    return false;
  }

 private:
  std::map<std::string, std::string> variables_;

  DISALLOW_COPY_AND_ASSIGN(MockEnvironmentVariableGetter);
};

}  // namespace

TEST(ShellIntegrationTest, GetDesktopShortcutTemplate) {
#if defined(GOOGLE_CHROME_BUILD)
  const char kTemplateFilename[] = "google-chrome.desktop";
#else  // CHROMIUM_BUILD
  const char kTemplateFilename[] = "chromium-browser.desktop";
#endif

  const char kTestData1[] = "a magical testing string";
  const char kTestData2[] = "a different testing string";

  MessageLoop message_loop;
  ChromeThread file_thread(ChromeThread::FILE, &message_loop);

  {
    ScopedTempDir temp_dir;
    ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

    MockEnvironmentVariableGetter env_getter;
    env_getter.Set("XDG_DATA_HOME", temp_dir.path().value());
    ASSERT_TRUE(file_util::WriteFile(
        temp_dir.path().AppendASCII(kTemplateFilename),
        kTestData1, strlen(kTestData1)));
    std::string contents;
    ASSERT_TRUE(ShellIntegration::GetDesktopShortcutTemplate(&env_getter,
                                                             &contents));
    EXPECT_EQ(kTestData1, contents);
  }

  {
    ScopedTempDir temp_dir;
    ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

    MockEnvironmentVariableGetter env_getter;
    env_getter.Set("XDG_DATA_DIRS", temp_dir.path().value());
    ASSERT_TRUE(file_util::CreateDirectory(
        temp_dir.path().AppendASCII("applications")));
    ASSERT_TRUE(file_util::WriteFile(
        temp_dir.path().AppendASCII("applications")
            .AppendASCII(kTemplateFilename),
        kTestData2, strlen(kTestData2)));
    std::string contents;
    ASSERT_TRUE(ShellIntegration::GetDesktopShortcutTemplate(&env_getter,
                                                             &contents));
    EXPECT_EQ(kTestData2, contents);
  }

  {
    ScopedTempDir temp_dir;
    ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

    MockEnvironmentVariableGetter env_getter;
    env_getter.Set("XDG_DATA_DIRS", temp_dir.path().value() + ":" +
                   temp_dir.path().AppendASCII("applications").value());
    ASSERT_TRUE(file_util::CreateDirectory(
        temp_dir.path().AppendASCII("applications")));
    ASSERT_TRUE(file_util::WriteFile(
        temp_dir.path().AppendASCII(kTemplateFilename),
        kTestData1, strlen(kTestData1)));
    ASSERT_TRUE(file_util::WriteFile(
        temp_dir.path().AppendASCII("applications")
            .AppendASCII(kTemplateFilename),
        kTestData2, strlen(kTestData2)));
    std::string contents;
    ASSERT_TRUE(ShellIntegration::GetDesktopShortcutTemplate(&env_getter,
                                                             &contents));
    EXPECT_EQ(kTestData1, contents);
  }
}

TEST(ShellIntegrationTest, GetDesktopShortcutFilename) {
  const struct {
    const FilePath::CharType* path;
    const char* url;
  } test_cases[] = {
    { FPL("http___foo_.desktop"), "http://foo" },
    { FPL("http___foo_bar_.desktop"), "http://foo/bar/" },
    { FPL("http___foo_bar_a=b&c=d.desktop"), "http://foo/bar?a=b&c=d" },

    // Now we're starting to be more evil...
    { FPL("http___foo_.desktop"), "http://foo/bar/baz/../../../../../" },
    { FPL("http___foo_.desktop"), "http://foo/bar/././../baz/././../" },
    { FPL("http___.._.desktop"), "http://../../../../" },
  };
  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); i++) {
    EXPECT_EQ(WideToASCII(chrome::kBrowserProcessExecutableName) + "-" +
              test_cases[i].path,
              ShellIntegration::GetDesktopShortcutFilename(
                  GURL(test_cases[i].url)).value()) <<
        " while testing " << test_cases[i].url;
  }
}

TEST(ShellIntegrationTest, GetDesktopFileContents) {
  const struct {
    const char* url;
    const char* title;
    const char* icon_name;
    const char* template_contents;
    const char* expected_output;
  } test_cases[] = {
    // Dumb case.
    { "ignored", "ignored", "ignored", "", "#!/usr/bin/env xdg-open\n" },

    // Real-world case.
    { "http://gmail.com",
      "GMail",
      "chrome-http__gmail.com",

      "[Desktop Entry]\n"
      "Version=1.0\n"
      "Encoding=UTF-8\n"
      "Name=Google Chrome\n"
      "Comment=The web browser from Google\n"
      "Exec=/opt/google/chrome/google-chrome %U\n"
      "Terminal=false\n"
      "Icon=/opt/google/chrome/product_logo_48.png\n"
      "Type=Application\n"
      "Categories=Application;Network;WebBrowser;\n"
      "MimeType=text/html;text/xml;application/xhtml_xml;\n",

      "#!/usr/bin/env xdg-open\n"
      "[Desktop Entry]\n"
      "Version=1.0\n"
      "Encoding=UTF-8\n"
      "Name=GMail\n"
      "Exec=/opt/google/chrome/google-chrome --app=\"http://gmail.com/\"\n"
      "Terminal=false\n"
      "Icon=chrome-http__gmail.com\n"
      "Type=Application\n"
      "Categories=Application;Network;WebBrowser;\n"
      "MimeType=text/html;text/xml;application/xhtml_xml;\n"
    },

    // Make sure we don't insert duplicate shebangs.
    { "http://gmail.com",
      "GMail",
      "chrome-http__gmail.com",

      "#!/some/shebang\n"
      "Name=Google Chrome\n"
      "Exec=/opt/google/chrome/google-chrome %U\n",

      "#!/usr/bin/env xdg-open\n"
      "Name=GMail\n"
      "Exec=/opt/google/chrome/google-chrome --app=\"http://gmail.com/\"\n"
    },

    // Make sure i18n-ed comments are removed.
    { "http://gmail.com",
      "GMail",
      "chrome-http__gmail.com",

      "Name=Google Chrome\n"
      "Exec=/opt/google/chrome/google-chrome %U\n"
      "Comment[pl]=Jakis komentarz.\n",

      "#!/usr/bin/env xdg-open\n"
      "Name=GMail\n"
      "Exec=/opt/google/chrome/google-chrome --app=\"http://gmail.com/\"\n"
    },

    // Make sure that empty icons are replaced by the chrome icon.
    { "http://gmail.com",
      "GMail",
      "",

      "Name=Google Chrome\n"
      "Exec=/opt/google/chrome/google-chrome %U\n"
      "Comment[pl]=Jakis komentarz.\n"
      "Icon=/opt/google/chrome/product_logo_48.png\n",

      "#!/usr/bin/env xdg-open\n"
      "Name=GMail\n"
      "Exec=/opt/google/chrome/google-chrome --app=\"http://gmail.com/\"\n"
      "Icon=/opt/google/chrome/product_logo_48.png\n"
    },

    // Now we're starting to be more evil...
    { "http://evil.com/evil --join-the-b0tnet",
      "Ownz0red\nExec=rm -rf /",
      "chrome-http__evil.com_evil",

      "Name=Google Chrome\n"
      "Exec=/opt/google/chrome/google-chrome %U\n",

      "#!/usr/bin/env xdg-open\n"
      "Name=http://evil.com/evil%20--join-the-b0tnet\n"
      "Exec=/opt/google/chrome/google-chrome "
      "--app=\"http://evil.com/evil%20--join-the-b0tnet\"\n"
    },
    { "http://evil.com/evil; rm -rf /; \"; rm -rf $HOME >ownz0red",
      "Innocent Title",
      "chrome-http__evil.com_evil",

      "Name=Google Chrome\n"
      "Exec=/opt/google/chrome/google-chrome %U\n",

      "#!/usr/bin/env xdg-open\n"
      "Name=Innocent Title\n"
      "Exec=/opt/google/chrome/google-chrome "
      "--app=\"http://evil.com/evil%3B%20rm%20-rf%20/%3B%20%22%3B%20rm%20"
      "-rf%20%24HOME%20%3Eownz0red\"\n"
    },
    { "http://evil.com/evil | cat `echo ownz0red` >/dev/null",
      "Innocent Title",
      "chrome-http__evil.com_evil",

      "Name=Google Chrome\n"
      "Exec=/opt/google/chrome/google-chrome %U\n",

      "#!/usr/bin/env xdg-open\n"
      "Name=Innocent Title\n"
      "Exec=/opt/google/chrome/google-chrome "
      "--app=\"http://evil.com/evil%20%7C%20cat%20%60echo%20ownz0red"
      "%60%20%3E/dev/null\"\n"
    },
  };
  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); i++) {
    EXPECT_EQ(test_cases[i].expected_output,
              ShellIntegration::GetDesktopFileContents(
                  test_cases[i].template_contents,
                  GURL(test_cases[i].url),
                  EmptyString16(),
                  ASCIIToUTF16(test_cases[i].title),
                  test_cases[i].icon_name));
  }
}
#elif defined(OS_WIN)
TEST(ShellIntegrationTest, GetChromiumAppIdTest) {
  // Empty profile path should get chrome::kBrowserAppID
  FilePath empty_path;
  EXPECT_EQ(std::wstring(chrome::kBrowserAppID),
            ShellIntegration::GetChromiumAppId(empty_path));

  // Default profile path should get chrome::kBrowserAppID
  FilePath default_user_data_dir;
  chrome::GetDefaultUserDataDirectory(&default_user_data_dir);
  FilePath default_profile_path =
      default_user_data_dir.Append(chrome::kNotSignedInProfile);
  EXPECT_EQ(std::wstring(chrome::kBrowserAppID),
            ShellIntegration::GetChromiumAppId(default_profile_path));

  // Non-default profile path should get chrome::kBrowserAppID joined with
  // profile info.
  FilePath profile_path(FILE_PATH_LITERAL("root"));
  profile_path = profile_path.Append(FILE_PATH_LITERAL("udd"));
  profile_path = profile_path.Append(FILE_PATH_LITERAL("User Data - Test"));
  EXPECT_EQ(std::wstring(chrome::kBrowserAppID) + L".udd.UserDataTest",
            ShellIntegration::GetChromiumAppId(profile_path));
}
#endif
<commit_msg>Fix one other build failure. Only include linux_util.h on Linux.<commit_after>// 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 "chrome/browser/shell_integration.h"

#include <map>

#include "base/file_path.h"
#include "base/file_util.h"
#include "base/message_loop.h"
#include "base/scoped_temp_dir.h"
#include "base/stl_util-inl.h"
#include "base/string_util.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths_internal.h"
#include "googleurl/src/gurl.h"
#include "testing/gtest/include/gtest/gtest.h"

#if defined(OS_LINUX)
#include "base/linux_util.h"
#endif  // defined(OS_LINUX)

#define FPL FILE_PATH_LITERAL

#if defined(OS_LINUX)
namespace {

// Provides mock environment variables values based on a stored map.
class MockEnvironmentVariableGetter : public base::EnvironmentVariableGetter {
 public:
  MockEnvironmentVariableGetter() {
  }

  void Set(const std::string& name, const std::string& value) {
    variables_[name] = value;
  }

  virtual bool Getenv(const char* variable_name, std::string* result) {
    if (ContainsKey(variables_, variable_name)) {
      *result = variables_[variable_name];
      return true;
    }

    return false;
  }

 private:
  std::map<std::string, std::string> variables_;

  DISALLOW_COPY_AND_ASSIGN(MockEnvironmentVariableGetter);
};

}  // namespace

TEST(ShellIntegrationTest, GetDesktopShortcutTemplate) {
#if defined(GOOGLE_CHROME_BUILD)
  const char kTemplateFilename[] = "google-chrome.desktop";
#else  // CHROMIUM_BUILD
  const char kTemplateFilename[] = "chromium-browser.desktop";
#endif

  const char kTestData1[] = "a magical testing string";
  const char kTestData2[] = "a different testing string";

  MessageLoop message_loop;
  ChromeThread file_thread(ChromeThread::FILE, &message_loop);

  {
    ScopedTempDir temp_dir;
    ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

    MockEnvironmentVariableGetter env_getter;
    env_getter.Set("XDG_DATA_HOME", temp_dir.path().value());
    ASSERT_TRUE(file_util::WriteFile(
        temp_dir.path().AppendASCII(kTemplateFilename),
        kTestData1, strlen(kTestData1)));
    std::string contents;
    ASSERT_TRUE(ShellIntegration::GetDesktopShortcutTemplate(&env_getter,
                                                             &contents));
    EXPECT_EQ(kTestData1, contents);
  }

  {
    ScopedTempDir temp_dir;
    ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

    MockEnvironmentVariableGetter env_getter;
    env_getter.Set("XDG_DATA_DIRS", temp_dir.path().value());
    ASSERT_TRUE(file_util::CreateDirectory(
        temp_dir.path().AppendASCII("applications")));
    ASSERT_TRUE(file_util::WriteFile(
        temp_dir.path().AppendASCII("applications")
            .AppendASCII(kTemplateFilename),
        kTestData2, strlen(kTestData2)));
    std::string contents;
    ASSERT_TRUE(ShellIntegration::GetDesktopShortcutTemplate(&env_getter,
                                                             &contents));
    EXPECT_EQ(kTestData2, contents);
  }

  {
    ScopedTempDir temp_dir;
    ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

    MockEnvironmentVariableGetter env_getter;
    env_getter.Set("XDG_DATA_DIRS", temp_dir.path().value() + ":" +
                   temp_dir.path().AppendASCII("applications").value());
    ASSERT_TRUE(file_util::CreateDirectory(
        temp_dir.path().AppendASCII("applications")));
    ASSERT_TRUE(file_util::WriteFile(
        temp_dir.path().AppendASCII(kTemplateFilename),
        kTestData1, strlen(kTestData1)));
    ASSERT_TRUE(file_util::WriteFile(
        temp_dir.path().AppendASCII("applications")
            .AppendASCII(kTemplateFilename),
        kTestData2, strlen(kTestData2)));
    std::string contents;
    ASSERT_TRUE(ShellIntegration::GetDesktopShortcutTemplate(&env_getter,
                                                             &contents));
    EXPECT_EQ(kTestData1, contents);
  }
}

TEST(ShellIntegrationTest, GetDesktopShortcutFilename) {
  const struct {
    const FilePath::CharType* path;
    const char* url;
  } test_cases[] = {
    { FPL("http___foo_.desktop"), "http://foo" },
    { FPL("http___foo_bar_.desktop"), "http://foo/bar/" },
    { FPL("http___foo_bar_a=b&c=d.desktop"), "http://foo/bar?a=b&c=d" },

    // Now we're starting to be more evil...
    { FPL("http___foo_.desktop"), "http://foo/bar/baz/../../../../../" },
    { FPL("http___foo_.desktop"), "http://foo/bar/././../baz/././../" },
    { FPL("http___.._.desktop"), "http://../../../../" },
  };
  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); i++) {
    EXPECT_EQ(WideToASCII(chrome::kBrowserProcessExecutableName) + "-" +
              test_cases[i].path,
              ShellIntegration::GetDesktopShortcutFilename(
                  GURL(test_cases[i].url)).value()) <<
        " while testing " << test_cases[i].url;
  }
}

TEST(ShellIntegrationTest, GetDesktopFileContents) {
  const struct {
    const char* url;
    const char* title;
    const char* icon_name;
    const char* template_contents;
    const char* expected_output;
  } test_cases[] = {
    // Dumb case.
    { "ignored", "ignored", "ignored", "", "#!/usr/bin/env xdg-open\n" },

    // Real-world case.
    { "http://gmail.com",
      "GMail",
      "chrome-http__gmail.com",

      "[Desktop Entry]\n"
      "Version=1.0\n"
      "Encoding=UTF-8\n"
      "Name=Google Chrome\n"
      "Comment=The web browser from Google\n"
      "Exec=/opt/google/chrome/google-chrome %U\n"
      "Terminal=false\n"
      "Icon=/opt/google/chrome/product_logo_48.png\n"
      "Type=Application\n"
      "Categories=Application;Network;WebBrowser;\n"
      "MimeType=text/html;text/xml;application/xhtml_xml;\n",

      "#!/usr/bin/env xdg-open\n"
      "[Desktop Entry]\n"
      "Version=1.0\n"
      "Encoding=UTF-8\n"
      "Name=GMail\n"
      "Exec=/opt/google/chrome/google-chrome --app=\"http://gmail.com/\"\n"
      "Terminal=false\n"
      "Icon=chrome-http__gmail.com\n"
      "Type=Application\n"
      "Categories=Application;Network;WebBrowser;\n"
      "MimeType=text/html;text/xml;application/xhtml_xml;\n"
    },

    // Make sure we don't insert duplicate shebangs.
    { "http://gmail.com",
      "GMail",
      "chrome-http__gmail.com",

      "#!/some/shebang\n"
      "Name=Google Chrome\n"
      "Exec=/opt/google/chrome/google-chrome %U\n",

      "#!/usr/bin/env xdg-open\n"
      "Name=GMail\n"
      "Exec=/opt/google/chrome/google-chrome --app=\"http://gmail.com/\"\n"
    },

    // Make sure i18n-ed comments are removed.
    { "http://gmail.com",
      "GMail",
      "chrome-http__gmail.com",

      "Name=Google Chrome\n"
      "Exec=/opt/google/chrome/google-chrome %U\n"
      "Comment[pl]=Jakis komentarz.\n",

      "#!/usr/bin/env xdg-open\n"
      "Name=GMail\n"
      "Exec=/opt/google/chrome/google-chrome --app=\"http://gmail.com/\"\n"
    },

    // Make sure that empty icons are replaced by the chrome icon.
    { "http://gmail.com",
      "GMail",
      "",

      "Name=Google Chrome\n"
      "Exec=/opt/google/chrome/google-chrome %U\n"
      "Comment[pl]=Jakis komentarz.\n"
      "Icon=/opt/google/chrome/product_logo_48.png\n",

      "#!/usr/bin/env xdg-open\n"
      "Name=GMail\n"
      "Exec=/opt/google/chrome/google-chrome --app=\"http://gmail.com/\"\n"
      "Icon=/opt/google/chrome/product_logo_48.png\n"
    },

    // Now we're starting to be more evil...
    { "http://evil.com/evil --join-the-b0tnet",
      "Ownz0red\nExec=rm -rf /",
      "chrome-http__evil.com_evil",

      "Name=Google Chrome\n"
      "Exec=/opt/google/chrome/google-chrome %U\n",

      "#!/usr/bin/env xdg-open\n"
      "Name=http://evil.com/evil%20--join-the-b0tnet\n"
      "Exec=/opt/google/chrome/google-chrome "
      "--app=\"http://evil.com/evil%20--join-the-b0tnet\"\n"
    },
    { "http://evil.com/evil; rm -rf /; \"; rm -rf $HOME >ownz0red",
      "Innocent Title",
      "chrome-http__evil.com_evil",

      "Name=Google Chrome\n"
      "Exec=/opt/google/chrome/google-chrome %U\n",

      "#!/usr/bin/env xdg-open\n"
      "Name=Innocent Title\n"
      "Exec=/opt/google/chrome/google-chrome "
      "--app=\"http://evil.com/evil%3B%20rm%20-rf%20/%3B%20%22%3B%20rm%20"
      "-rf%20%24HOME%20%3Eownz0red\"\n"
    },
    { "http://evil.com/evil | cat `echo ownz0red` >/dev/null",
      "Innocent Title",
      "chrome-http__evil.com_evil",

      "Name=Google Chrome\n"
      "Exec=/opt/google/chrome/google-chrome %U\n",

      "#!/usr/bin/env xdg-open\n"
      "Name=Innocent Title\n"
      "Exec=/opt/google/chrome/google-chrome "
      "--app=\"http://evil.com/evil%20%7C%20cat%20%60echo%20ownz0red"
      "%60%20%3E/dev/null\"\n"
    },
  };
  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); i++) {
    EXPECT_EQ(test_cases[i].expected_output,
              ShellIntegration::GetDesktopFileContents(
                  test_cases[i].template_contents,
                  GURL(test_cases[i].url),
                  EmptyString16(),
                  ASCIIToUTF16(test_cases[i].title),
                  test_cases[i].icon_name));
  }
}
#elif defined(OS_WIN)
TEST(ShellIntegrationTest, GetChromiumAppIdTest) {
  // Empty profile path should get chrome::kBrowserAppID
  FilePath empty_path;
  EXPECT_EQ(std::wstring(chrome::kBrowserAppID),
            ShellIntegration::GetChromiumAppId(empty_path));

  // Default profile path should get chrome::kBrowserAppID
  FilePath default_user_data_dir;
  chrome::GetDefaultUserDataDirectory(&default_user_data_dir);
  FilePath default_profile_path =
      default_user_data_dir.Append(chrome::kNotSignedInProfile);
  EXPECT_EQ(std::wstring(chrome::kBrowserAppID),
            ShellIntegration::GetChromiumAppId(default_profile_path));

  // Non-default profile path should get chrome::kBrowserAppID joined with
  // profile info.
  FilePath profile_path(FILE_PATH_LITERAL("root"));
  profile_path = profile_path.Append(FILE_PATH_LITERAL("udd"));
  profile_path = profile_path.Append(FILE_PATH_LITERAL("User Data - Test"));
  EXPECT_EQ(std::wstring(chrome::kBrowserAppID) + L".udd.UserDataTest",
            ShellIntegration::GetChromiumAppId(profile_path));
}
#endif
<|endoftext|>


<commit_before>// Copyright (C) 2016 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <rapidjson/rapidjson.h>
#include <rapidjson/memorystream.h>
#include <rapidjson/document.h>
#include "SpriteFrame.h"
#include "core/Engine.h"
#include "core/Cache.h"
#include "graphics/Texture.h"
#include "graphics/MeshBuffer.h"
#include "utils/Utils.h"

namespace ouzel
{
    namespace scene
    {
        std::vector<SpriteFramePtr> SpriteFrame::loadSpriteFrames(const std::string& filename, bool mipmaps)
        {
            std::vector<SpriteFramePtr> frames;

            std::vector<uint8_t> data;
            if (!sharedEngine->getFileSystem()->loadFile(filename, data))
            {
                return frames;
            }

            rapidjson::MemoryStream is(reinterpret_cast<char*>(data.data()), data.size());

            rapidjson::Document document;
            document.ParseStream<0>(is);

            if (document.HasParseError())
            {
                log("Failed to parse %s", filename.c_str());
                return frames;
            }

            const rapidjson::Value& metaObject = document["meta"];
            const rapidjson::Value& sizeObject = metaObject["size"];

            Size2 textureSize(static_cast<float>(sizeObject["w"].GetInt()),
                              static_cast<float>(sizeObject["h"].GetInt()));

            graphics::TexturePtr texture = sharedEngine->getCache()->getTexture(metaObject["image"].GetString(), false, mipmaps);

            const rapidjson::Value& framesArray = document["frames"];

            frames.reserve(framesArray.Size());

            for (rapidjson::SizeType index = 0; index < framesArray.Size(); ++index)
            {
                const rapidjson::Value& frameObject = framesArray[index];

                const rapidjson::Value& frameRectangleObject = frameObject["frame"];

                Rectangle frameRectangle(static_cast<float>(frameRectangleObject["x"].GetInt()),
                                         static_cast<float>(frameRectangleObject["y"].GetInt()),
                                         static_cast<float>(frameRectangleObject["w"].GetInt()),
                                         static_cast<float>(frameRectangleObject["h"].GetInt()));

                bool rotated = frameObject["rotated"].GetBool();

                const rapidjson::Value& sourceSizeObject = frameObject["sourceSize"];

                Size2 sourceSize(static_cast<float>(sourceSizeObject["w"].GetInt()),
                                 static_cast<float>(sourceSizeObject["h"].GetInt()));

                const rapidjson::Value& spriteSourceSizeObject = frameObject["spriteSourceSize"];

                Vector2 sourceOffset(static_cast<float>(spriteSourceSizeObject["x"].GetInt()),
                                     static_cast<float>(spriteSourceSizeObject["y"].GetInt()));

                const rapidjson::Value& pivotObject = frameObject["pivot"];

                Vector2 pivot(pivotObject["x"].GetFloat(),
                              pivotObject["y"].GetFloat());

                frames.push_back(std::make_shared<SpriteFrame>(texture, frameRectangle, rotated, sourceSize, sourceOffset, pivot));
            }

            return frames;
        }

        SpriteFrame::SpriteFrame(const graphics::TexturePtr& pTexture,
                                 const Rectangle& frameRectangle,
                                 bool rotated,
                                 const Size2& sourceSize,
                                 const Vector2& sourceOffset,
                                 const Vector2& pivot)
        {
            texture = pTexture;

            std::vector<uint16_t> indices = {0, 1, 2, 1, 3, 2};

            Vector2 textCoords[4];
            Vector2 finalOffset(-sourceSize.width * pivot.x + sourceOffset.x,
                                -sourceSize.height * pivot.y + (sourceSize.height - frameRectangle.height - sourceOffset.y));

            const Size2& textureSize = texture->getSize();

            if (!rotated)
            {
                Vector2 leftTop(frameRectangle.x / textureSize.width,
                                frameRectangle.y / textureSize.height);

                Vector2 rightBottom((frameRectangle.x + frameRectangle.width) / textureSize.width,
                                    (frameRectangle.y + frameRectangle.height) / textureSize.height);

                if (texture->isFlipped())
                {
                    leftTop.y = 1.0f - leftTop.y;
                    rightBottom.y = 1.0f - rightBottom.y;
                }

                textCoords[0] = Vector2(leftTop.x, rightBottom.y);
                textCoords[1] = Vector2(rightBottom.x, rightBottom.y);
                textCoords[2] = Vector2(leftTop.x, leftTop.y);
                textCoords[3] = Vector2(rightBottom.x, leftTop.y);
            }
            else
            {
                Vector2 leftTop = Vector2(frameRectangle.x / textureSize.width,
                                          frameRectangle.y / textureSize.height);

                Vector2 rightBottom = Vector2((frameRectangle.x + frameRectangle.height) / textureSize.width,
                                              (frameRectangle.y + frameRectangle.width) / textureSize.height);

                if (texture->isFlipped())
                {
                    leftTop.y = 1.0f - leftTop.y;
                    rightBottom.y = 1.0f - rightBottom.y;
                }

                textCoords[0] = Vector2(leftTop.x, leftTop.y);
                textCoords[1] = Vector2(leftTop.x, rightBottom.y);
                textCoords[2] = Vector2(rightBottom.x, leftTop.y);
                textCoords[3] = Vector2(rightBottom.x, rightBottom.y);
            }

            std::vector<graphics::VertexPCT> vertices = {
                graphics::VertexPCT(Vector3(finalOffset.x, finalOffset.y, 0.0f), graphics::Color(255, 255, 255, 255), textCoords[0]),
                graphics::VertexPCT(Vector3(finalOffset.x + frameRectangle.width, finalOffset.y, 0.0f), graphics::Color(255, 255, 255, 255), textCoords[1]),
                graphics::VertexPCT(Vector3(finalOffset.x, finalOffset.y + frameRectangle.height, 0.0f),  graphics::Color(255, 255, 255, 255), textCoords[2]),
                graphics::VertexPCT(Vector3(finalOffset.x + frameRectangle.width, finalOffset.y + frameRectangle.height, 0.0f),  graphics::Color(255, 255, 255, 255), textCoords[3])
            };

            boundingBox.set(finalOffset, finalOffset + Vector2(frameRectangle.width, frameRectangle.height));

            rectangle = Rectangle(finalOffset.x, finalOffset.y,
                                  sourceSize.width, sourceSize.height);

            meshBuffer = sharedEngine->getRenderer()->createMeshBuffer();

            meshBuffer->initFromBuffer(indices.data(), sizeof(uint16_t),
                                       static_cast<uint32_t>(indices.size()), false,
                                       vertices.data(), graphics::VertexPCT::ATTRIBUTES,
                                       static_cast<uint32_t>(vertices.size()), true);
        }

        SpriteFrame::SpriteFrame(const graphics::TexturePtr& pTexture,
                                 const std::vector<uint16_t>& indices,
                                 const std::vector<graphics::VertexPCT>& vertices,
                                 const Rectangle& frameRectangle,
                                 const Size2& sourceSize,
                                 const Vector2& sourceOffset,
                                 const Vector2& pivot)
        {
            texture = pTexture;

            for (const graphics::VertexPCT& vertex : vertices)
            {
                boundingBox.insertPoint(vertex.position);
            }

            Vector2 finalOffset(-sourceSize.width * pivot.x + sourceOffset.x,
                                -sourceSize.height * pivot.y + (sourceSize.height - frameRectangle.height - sourceOffset.y));

            rectangle = Rectangle(finalOffset.x, finalOffset.y,
                                  sourceSize.width, sourceSize.height);

            meshBuffer = sharedEngine->getRenderer()->createMeshBuffer();

            meshBuffer->initFromBuffer(indices.data(), sizeof(uint16_t),
                                       static_cast<uint32_t>(indices.size()), false,
                                       vertices.data(), graphics::VertexPCT::ATTRIBUTES,
                                       static_cast<uint32_t>(vertices.size()), true);
        }

    } // scene
} // ouzel
<commit_msg>Implement sprite mesh loading from json file<commit_after>// Copyright (C) 2016 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <rapidjson/rapidjson.h>
#include <rapidjson/memorystream.h>
#include <rapidjson/document.h>
#include "SpriteFrame.h"
#include "core/Engine.h"
#include "core/Cache.h"
#include "graphics/Texture.h"
#include "graphics/MeshBuffer.h"
#include "utils/Utils.h"

namespace ouzel
{
    namespace scene
    {
        std::vector<SpriteFramePtr> SpriteFrame::loadSpriteFrames(const std::string& filename, bool mipmaps)
        {
            std::vector<SpriteFramePtr> frames;

            std::vector<uint8_t> data;
            if (!sharedEngine->getFileSystem()->loadFile(filename, data))
            {
                return frames;
            }

            rapidjson::MemoryStream is(reinterpret_cast<char*>(data.data()), data.size());

            rapidjson::Document document;
            document.ParseStream<0>(is);

            if (document.HasParseError())
            {
                log("Failed to parse %s", filename.c_str());
                return frames;
            }

            const rapidjson::Value& metaObject = document["meta"];
            const rapidjson::Value& sizeObject = metaObject["size"];

            Size2 textureSize(static_cast<float>(sizeObject["w"].GetInt()),
                              static_cast<float>(sizeObject["h"].GetInt()));

            graphics::TexturePtr texture = sharedEngine->getCache()->getTexture(metaObject["image"].GetString(), false, mipmaps);

            const rapidjson::Value& framesArray = document["frames"];

            frames.reserve(framesArray.Size());

            for (rapidjson::SizeType index = 0; index < framesArray.Size(); ++index)
            {
                const rapidjson::Value& frameObject = framesArray[index];

                const rapidjson::Value& frameRectangleObject = frameObject["frame"];

                Rectangle frameRectangle(static_cast<float>(frameRectangleObject["x"].GetInt()),
                                         static_cast<float>(frameRectangleObject["y"].GetInt()),
                                         static_cast<float>(frameRectangleObject["w"].GetInt()),
                                         static_cast<float>(frameRectangleObject["h"].GetInt()));

                const rapidjson::Value& sourceSizeObject = frameObject["sourceSize"];

                Size2 sourceSize(static_cast<float>(sourceSizeObject["w"].GetInt()),
                                 static_cast<float>(sourceSizeObject["h"].GetInt()));

                const rapidjson::Value& spriteSourceSizeObject = frameObject["spriteSourceSize"];

                Vector2 sourceOffset(static_cast<float>(spriteSourceSizeObject["x"].GetInt()),
                                     static_cast<float>(spriteSourceSizeObject["y"].GetInt()));

                const rapidjson::Value& pivotObject = frameObject["pivot"];

                Vector2 pivot(pivotObject["x"].GetFloat(),
                              pivotObject["y"].GetFloat());

                if (frameObject.HasMember("vertices") &&
                    frameObject.HasMember("verticesUV") &&
                    frameObject.HasMember("triangles"))
                {
                    std::vector<uint16_t> indices;

                    const rapidjson::Value& trianglesObject = frameObject["triangles"];

                    for (rapidjson::SizeType triangleIndex = 0; triangleIndex < trianglesObject.Size(); ++triangleIndex)
                    {
                        const rapidjson::Value& triangleObject = trianglesObject[triangleIndex];

                        for (rapidjson::SizeType i = 0; i < triangleObject.Size(); ++i)
                        {
                            indices.push_back(static_cast<uint16_t>(triangleObject[i].GetUint()));
                        }
                    }

                    std::vector<graphics::VertexPCT> vertices;

                    const rapidjson::Value& verticesObject = frameObject["vertices"];
                    const rapidjson::Value& verticesUVObject = frameObject["verticesUV"];

                    const Size2& textureSize = texture->getSize();

                    Vector2 finalOffset(-sourceSize.width * pivot.x + sourceOffset.x,
                                        -sourceSize.height * pivot.y + (sourceSize.height - frameRectangle.height - sourceOffset.y));

                    for (rapidjson::SizeType vertexIndex = 0; vertexIndex < verticesObject.Size(); ++vertexIndex)
                    {
                        const rapidjson::Value& vertexObject = verticesObject[vertexIndex];
                        const rapidjson::Value& vertexUVObject = verticesUVObject[vertexIndex];

                        vertices.push_back(graphics::VertexPCT(Vector3(static_cast<float>(vertexObject[0].GetInt()) + finalOffset.x,
                                                                       -static_cast<float>(vertexObject[1].GetInt()) - finalOffset.y,
                                                                       0.0f),
                                                               graphics::Color(255, 255, 255, 255),
                                                               Vector2(static_cast<float>(vertexUVObject[0].GetInt()) / textureSize.width,
                                                                       static_cast<float>(vertexUVObject[1].GetInt()) / textureSize.height)));
                    }

                    frames.push_back(std::make_shared<SpriteFrame>(texture, indices, vertices, frameRectangle, sourceSize, sourceOffset, pivot));
                }
                else
                {
                    bool rotated = frameObject["rotated"].GetBool();

                    frames.push_back(std::make_shared<SpriteFrame>(texture, frameRectangle, rotated, sourceSize, sourceOffset, pivot));
                }
            }

            return frames;
        }

        SpriteFrame::SpriteFrame(const graphics::TexturePtr& pTexture,
                                 const Rectangle& frameRectangle,
                                 bool rotated,
                                 const Size2& sourceSize,
                                 const Vector2& sourceOffset,
                                 const Vector2& pivot)
        {
            texture = pTexture;

            std::vector<uint16_t> indices = {0, 1, 2, 1, 3, 2};

            Vector2 textCoords[4];
            Vector2 finalOffset(-sourceSize.width * pivot.x + sourceOffset.x,
                                -sourceSize.height * pivot.y + (sourceSize.height - frameRectangle.height - sourceOffset.y));

            const Size2& textureSize = texture->getSize();

            if (!rotated)
            {
                Vector2 leftTop(frameRectangle.x / textureSize.width,
                                frameRectangle.y / textureSize.height);

                Vector2 rightBottom((frameRectangle.x + frameRectangle.width) / textureSize.width,
                                    (frameRectangle.y + frameRectangle.height) / textureSize.height);

                if (texture->isFlipped())
                {
                    leftTop.y = 1.0f - leftTop.y;
                    rightBottom.y = 1.0f - rightBottom.y;
                }

                textCoords[0] = Vector2(leftTop.x, rightBottom.y);
                textCoords[1] = Vector2(rightBottom.x, rightBottom.y);
                textCoords[2] = Vector2(leftTop.x, leftTop.y);
                textCoords[3] = Vector2(rightBottom.x, leftTop.y);
            }
            else
            {
                Vector2 leftTop = Vector2(frameRectangle.x / textureSize.width,
                                          frameRectangle.y / textureSize.height);

                Vector2 rightBottom = Vector2((frameRectangle.x + frameRectangle.height) / textureSize.width,
                                              (frameRectangle.y + frameRectangle.width) / textureSize.height);

                if (texture->isFlipped())
                {
                    leftTop.y = 1.0f - leftTop.y;
                    rightBottom.y = 1.0f - rightBottom.y;
                }

                textCoords[0] = Vector2(leftTop.x, leftTop.y);
                textCoords[1] = Vector2(leftTop.x, rightBottom.y);
                textCoords[2] = Vector2(rightBottom.x, leftTop.y);
                textCoords[3] = Vector2(rightBottom.x, rightBottom.y);
            }

            std::vector<graphics::VertexPCT> vertices = {
                graphics::VertexPCT(Vector3(finalOffset.x, finalOffset.y, 0.0f), graphics::Color(255, 255, 255, 255), textCoords[0]),
                graphics::VertexPCT(Vector3(finalOffset.x + frameRectangle.width, finalOffset.y, 0.0f), graphics::Color(255, 255, 255, 255), textCoords[1]),
                graphics::VertexPCT(Vector3(finalOffset.x, finalOffset.y + frameRectangle.height, 0.0f),  graphics::Color(255, 255, 255, 255), textCoords[2]),
                graphics::VertexPCT(Vector3(finalOffset.x + frameRectangle.width, finalOffset.y + frameRectangle.height, 0.0f),  graphics::Color(255, 255, 255, 255), textCoords[3])
            };

            boundingBox.set(finalOffset, finalOffset + Vector2(frameRectangle.width, frameRectangle.height));

            rectangle = Rectangle(finalOffset.x, finalOffset.y,
                                  sourceSize.width, sourceSize.height);

            meshBuffer = sharedEngine->getRenderer()->createMeshBuffer();

            meshBuffer->initFromBuffer(indices.data(), sizeof(uint16_t),
                                       static_cast<uint32_t>(indices.size()), false,
                                       vertices.data(), graphics::VertexPCT::ATTRIBUTES,
                                       static_cast<uint32_t>(vertices.size()), true);
        }

        SpriteFrame::SpriteFrame(const graphics::TexturePtr& pTexture,
                                 const std::vector<uint16_t>& indices,
                                 const std::vector<graphics::VertexPCT>& vertices,
                                 const Rectangle& frameRectangle,
                                 const Size2& sourceSize,
                                 const Vector2& sourceOffset,
                                 const Vector2& pivot)
        {
            texture = pTexture;

            for (const graphics::VertexPCT& vertex : vertices)
            {
                boundingBox.insertPoint(vertex.position);
            }

            Vector2 finalOffset(-sourceSize.width * pivot.x + sourceOffset.x,
                                -sourceSize.height * pivot.y + (sourceSize.height - frameRectangle.height - sourceOffset.y));

            rectangle = Rectangle(finalOffset.x, finalOffset.y,
                                  sourceSize.width, sourceSize.height);

            meshBuffer = sharedEngine->getRenderer()->createMeshBuffer();

            meshBuffer->initFromBuffer(indices.data(), sizeof(uint16_t),
                                       static_cast<uint32_t>(indices.size()), false,
                                       vertices.data(), graphics::VertexPCT::ATTRIBUTES,
                                       static_cast<uint32_t>(vertices.size()), true);
        }

    } // scene
} // ouzel
<|endoftext|>


<commit_before>// Copyright 2015 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 "chrome/browser/ui/webui/large_icon_source.h"

#include <vector>

#include "base/memory/ref_counted_memory.h"
#include "chrome/browser/search/instant_io_context.h"
#include "chrome/common/favicon/large_icon_url_parser.h"
#include "chrome/common/url_constants.h"
#include "components/favicon/core/fallback_icon_service.h"
#include "components/favicon/core/favicon_service.h"
#include "components/favicon_base/fallback_icon_style.h"
#include "net/url_request/url_request.h"
#include "third_party/skia/include/core/SkColor.h"

namespace {

int kDefaultLargeIconSize = 96;
int kMaxLargeIconSize = 192;  // Arbitrary bound to safeguard endpoint.

}  // namespace

LargeIconSource::IconRequest::IconRequest() : size(kDefaultLargeIconSize) {
}

LargeIconSource::IconRequest::IconRequest(
    const content::URLDataSource::GotDataCallback& callback_in,
    const GURL& url_in,
    int size_in)
    : callback(callback_in),
      url(url_in),
      size(size_in) {
}

LargeIconSource::IconRequest::~IconRequest() {
}

LargeIconSource::LargeIconSource(favicon::FaviconService* favicon_service,
                                 FallbackIconService* fallback_icon_service)
    : favicon_service_(favicon_service),
      fallback_icon_service_(fallback_icon_service) {
}

LargeIconSource::~LargeIconSource() {
}

std::string LargeIconSource::GetSource() const {
  return chrome::kChromeUILargeIconHost;
}

void LargeIconSource::StartDataRequest(
    const std::string& path,
    int render_process_id,
    int render_frame_id,
    const content::URLDataSource::GotDataCallback& callback) {
  if (!favicon_service_) {
    SendNotFoundResponse(callback);
    return;
  }

  LargeIconUrlParser parser;
  bool success = parser.Parse(path);
  if (!success ||
      parser.size_in_pixels() <= 0 ||
      parser.size_in_pixels() > kMaxLargeIconSize) {
    SendNotFoundResponse(callback);
    return;
  }

  GURL url(parser.url_string());
  if (!url.is_valid()) {
    SendNotFoundResponse(callback);
    return;
  }

  favicon_service_->GetRawFaviconForPageURL(
      url,
      favicon_base::TOUCH_ICON | favicon_base::TOUCH_PRECOMPOSED_ICON,
      parser.size_in_pixels(),
      base::Bind(
          &LargeIconSource::OnIconDataAvailable,
          base::Unretained(this),
          IconRequest(callback, url, parser.size_in_pixels())),
      &cancelable_task_tracker_);
}

std::string LargeIconSource::GetMimeType(const std::string&) const {
  // We need to explicitly return a mime type, otherwise if the user tries to
  // drag the image they get no extension.
  return "image/png";
}

bool LargeIconSource::ShouldReplaceExistingSource() const {
  // Leave the existing DataSource in place, otherwise we'll drop any pending
  // requests on the floor.
  return false;
}

bool LargeIconSource::ShouldServiceRequest(
    const net::URLRequest* request) const {
  if (request->url().SchemeIs(chrome::kChromeSearchScheme))
    return InstantIOContext::ShouldServiceRequest(request);
  return URLDataSource::ShouldServiceRequest(request);
}

void LargeIconSource::OnIconDataAvailable(
    const IconRequest& request,
    const favicon_base::FaviconRawBitmapResult& bitmap_result) {
  if (!bitmap_result.is_valid())
    SendFallbackIcon(request);
  else
    request.callback.Run(bitmap_result.bitmap_data.get());
}

void LargeIconSource::SendFallbackIcon(const IconRequest& request) {
  if (!fallback_icon_service_) {
    SendNotFoundResponse(request.callback);
    return;
  }
  favicon_base::FallbackIconStyle style;
  style.background_color = SkColorSetRGB(0xcc, 0xcc, 0xcc);
  favicon_base::MatchFallbackIconTextColorAgainstBackgroundColor(&style);
  style.roundness = 1.0;
  std::vector<unsigned char> bitmap_data =
      fallback_icon_service_->RenderFallbackIconBitmap(
          request.url, request.size, style);
  request.callback.Run(base::RefCountedBytes::TakeVector(&bitmap_data));
}

void LargeIconSource::SendNotFoundResponse(
    const content::URLDataSource::GotDataCallback& callback) {
  callback.Run(nullptr);
}
<commit_msg>[Icons NTP] Tweak fallback icon style to be in line with design.<commit_after>// Copyright 2015 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 "chrome/browser/ui/webui/large_icon_source.h"

#include <vector>

#include "base/memory/ref_counted_memory.h"
#include "chrome/browser/search/instant_io_context.h"
#include "chrome/common/favicon/large_icon_url_parser.h"
#include "chrome/common/url_constants.h"
#include "components/favicon/core/fallback_icon_service.h"
#include "components/favicon/core/favicon_service.h"
#include "components/favicon_base/fallback_icon_style.h"
#include "net/url_request/url_request.h"
#include "third_party/skia/include/core/SkColor.h"

namespace {

int kDefaultLargeIconSize = 96;
int kMaxLargeIconSize = 192;  // Arbitrary bound to safeguard endpoint.

}  // namespace

LargeIconSource::IconRequest::IconRequest() : size(kDefaultLargeIconSize) {
}

LargeIconSource::IconRequest::IconRequest(
    const content::URLDataSource::GotDataCallback& callback_in,
    const GURL& url_in,
    int size_in)
    : callback(callback_in),
      url(url_in),
      size(size_in) {
}

LargeIconSource::IconRequest::~IconRequest() {
}

LargeIconSource::LargeIconSource(favicon::FaviconService* favicon_service,
                                 FallbackIconService* fallback_icon_service)
    : favicon_service_(favicon_service),
      fallback_icon_service_(fallback_icon_service) {
}

LargeIconSource::~LargeIconSource() {
}

std::string LargeIconSource::GetSource() const {
  return chrome::kChromeUILargeIconHost;
}

void LargeIconSource::StartDataRequest(
    const std::string& path,
    int render_process_id,
    int render_frame_id,
    const content::URLDataSource::GotDataCallback& callback) {
  if (!favicon_service_) {
    SendNotFoundResponse(callback);
    return;
  }

  LargeIconUrlParser parser;
  bool success = parser.Parse(path);
  if (!success ||
      parser.size_in_pixels() <= 0 ||
      parser.size_in_pixels() > kMaxLargeIconSize) {
    SendNotFoundResponse(callback);
    return;
  }

  GURL url(parser.url_string());
  if (!url.is_valid()) {
    SendNotFoundResponse(callback);
    return;
  }

  favicon_service_->GetRawFaviconForPageURL(
      url,
      favicon_base::TOUCH_ICON | favicon_base::TOUCH_PRECOMPOSED_ICON,
      parser.size_in_pixels(),
      base::Bind(
          &LargeIconSource::OnIconDataAvailable,
          base::Unretained(this),
          IconRequest(callback, url, parser.size_in_pixels())),
      &cancelable_task_tracker_);
}

std::string LargeIconSource::GetMimeType(const std::string&) const {
  // We need to explicitly return a mime type, otherwise if the user tries to
  // drag the image they get no extension.
  return "image/png";
}

bool LargeIconSource::ShouldReplaceExistingSource() const {
  // Leave the existing DataSource in place, otherwise we'll drop any pending
  // requests on the floor.
  return false;
}

bool LargeIconSource::ShouldServiceRequest(
    const net::URLRequest* request) const {
  if (request->url().SchemeIs(chrome::kChromeSearchScheme))
    return InstantIOContext::ShouldServiceRequest(request);
  return URLDataSource::ShouldServiceRequest(request);
}

void LargeIconSource::OnIconDataAvailable(
    const IconRequest& request,
    const favicon_base::FaviconRawBitmapResult& bitmap_result) {
  if (!bitmap_result.is_valid())
    SendFallbackIcon(request);
  else
    request.callback.Run(bitmap_result.bitmap_data.get());
}

void LargeIconSource::SendFallbackIcon(const IconRequest& request) {
  if (!fallback_icon_service_) {
    SendNotFoundResponse(request.callback);
    return;
  }
  favicon_base::FallbackIconStyle style;
  style.background_color = SkColorSetRGB(0xcc, 0xcc, 0xcc);
  style.text_color = SK_ColorWHITE;
  style.font_size_ratio = 0.44;
  style.roundness = 0;  // Square. Round corners can be applied by JavaScript.
  std::vector<unsigned char> bitmap_data =
      fallback_icon_service_->RenderFallbackIconBitmap(
          request.url, request.size, style);
  request.callback.Run(base::RefCountedBytes::TakeVector(&bitmap_data));
}

void LargeIconSource::SendNotFoundResponse(
    const content::URLDataSource::GotDataCallback& callback) {
  callback.Run(nullptr);
}
<|endoftext|>