261 lines
7.8 KiB
C++
261 lines
7.8 KiB
C++
// Copyright (c) 2014 The Chromium Embedded Framework 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 CEF_LIBCEF_DLL_WRAPPER_CEF_BROWSER_INFO_MAP_H_
|
|
#define CEF_LIBCEF_DLL_WRAPPER_CEF_BROWSER_INFO_MAP_H_
|
|
#pragma once
|
|
|
|
#include <map>
|
|
|
|
#include "include/base/cef_logging.h"
|
|
#include "include/base/cef_macros.h"
|
|
|
|
// Default traits for CefBrowserInfoMap. Override to provide different object
|
|
// destruction behavior.
|
|
template <typename ObjectType>
|
|
struct DefaultCefBrowserInfoMapTraits {
|
|
static void Destruct(ObjectType info) { delete info; }
|
|
};
|
|
|
|
// Maps an arbitrary IdType to an arbitrary ObjectType on a per-browser basis.
|
|
template <typename IdType,
|
|
typename ObjectType,
|
|
typename Traits = DefaultCefBrowserInfoMapTraits<ObjectType>>
|
|
class CefBrowserInfoMap {
|
|
public:
|
|
// Implement this interface to visit and optionally delete objects in the map.
|
|
class Visitor {
|
|
public:
|
|
typedef IdType InfoIdType;
|
|
typedef ObjectType InfoObjectType;
|
|
|
|
// Called once for each info object. Set |remove| to true to remove the
|
|
// object from the map. It is safe to destruct removed objects in this
|
|
// callback. Return true to continue iterating or false to stop iterating.
|
|
virtual bool OnNextInfo(int browser_id,
|
|
InfoIdType info_id,
|
|
InfoObjectType info,
|
|
bool* remove) = 0;
|
|
|
|
protected:
|
|
virtual ~Visitor() {}
|
|
};
|
|
|
|
CefBrowserInfoMap() {}
|
|
|
|
~CefBrowserInfoMap() { clear(); }
|
|
|
|
// Add an object associated with the specified ID values.
|
|
void Add(int browser_id, IdType info_id, ObjectType info) {
|
|
InfoMap* info_map = nullptr;
|
|
typename BrowserInfoMap::const_iterator it_browser =
|
|
browser_info_map_.find(browser_id);
|
|
if (it_browser == browser_info_map_.end()) {
|
|
// No InfoMap exists for the browser ID so create it.
|
|
info_map = new InfoMap;
|
|
browser_info_map_.insert(std::make_pair(browser_id, info_map));
|
|
} else {
|
|
info_map = it_browser->second;
|
|
// The specified ID should not already exist in the map.
|
|
DCHECK(info_map->find(info_id) == info_map->end());
|
|
}
|
|
|
|
info_map->insert(std::make_pair(info_id, info));
|
|
}
|
|
|
|
// Find the object with the specified ID values. |visitor| can optionally be
|
|
// used to evaluate or remove the object at the same time. If the object is
|
|
// removed using the Visitor the caller is responsible for destroying it.
|
|
ObjectType Find(int browser_id, IdType info_id, Visitor* vistor) {
|
|
if (browser_info_map_.empty())
|
|
return ObjectType();
|
|
|
|
typename BrowserInfoMap::iterator it_browser =
|
|
browser_info_map_.find(browser_id);
|
|
if (it_browser == browser_info_map_.end())
|
|
return ObjectType();
|
|
|
|
InfoMap* info_map = it_browser->second;
|
|
typename InfoMap::iterator it_info = info_map->find(info_id);
|
|
if (it_info == info_map->end())
|
|
return ObjectType();
|
|
|
|
ObjectType info = it_info->second;
|
|
|
|
bool remove = false;
|
|
if (vistor)
|
|
vistor->OnNextInfo(browser_id, it_info->first, info, &remove);
|
|
if (remove) {
|
|
info_map->erase(it_info);
|
|
|
|
if (info_map->empty()) {
|
|
// No more entries in the InfoMap so remove it.
|
|
browser_info_map_.erase(it_browser);
|
|
delete info_map;
|
|
}
|
|
}
|
|
|
|
return info;
|
|
}
|
|
|
|
// Find all objects. If any objects are removed using the Visitor the caller
|
|
// is responsible for destroying them.
|
|
void FindAll(Visitor* visitor) {
|
|
DCHECK(visitor);
|
|
|
|
if (browser_info_map_.empty())
|
|
return;
|
|
|
|
bool remove, keepgoing = true;
|
|
|
|
typename BrowserInfoMap::iterator it_browser = browser_info_map_.begin();
|
|
while (it_browser != browser_info_map_.end()) {
|
|
InfoMap* info_map = it_browser->second;
|
|
|
|
typename InfoMap::iterator it_info = info_map->begin();
|
|
while (it_info != info_map->end()) {
|
|
remove = false;
|
|
keepgoing = visitor->OnNextInfo(it_browser->first, it_info->first,
|
|
it_info->second, &remove);
|
|
|
|
if (remove)
|
|
info_map->erase(it_info++);
|
|
else
|
|
++it_info;
|
|
|
|
if (!keepgoing)
|
|
break;
|
|
}
|
|
|
|
if (info_map->empty()) {
|
|
// No more entries in the InfoMap so remove it.
|
|
browser_info_map_.erase(it_browser++);
|
|
delete info_map;
|
|
} else {
|
|
++it_browser;
|
|
}
|
|
|
|
if (!keepgoing)
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Find all objects associated with the specified browser. If any objects are
|
|
// removed using the Visitor the caller is responsible for destroying them.
|
|
void FindAll(int browser_id, Visitor* visitor) {
|
|
DCHECK(visitor);
|
|
|
|
if (browser_info_map_.empty())
|
|
return;
|
|
|
|
typename BrowserInfoMap::iterator it_browser =
|
|
browser_info_map_.find(browser_id);
|
|
if (it_browser == browser_info_map_.end())
|
|
return;
|
|
|
|
InfoMap* info_map = it_browser->second;
|
|
bool remove, keepgoing;
|
|
|
|
typename InfoMap::iterator it_info = info_map->begin();
|
|
while (it_info != info_map->end()) {
|
|
remove = false;
|
|
keepgoing = visitor->OnNextInfo(browser_id, it_info->first,
|
|
it_info->second, &remove);
|
|
|
|
if (remove)
|
|
info_map->erase(it_info++);
|
|
else
|
|
++it_info;
|
|
|
|
if (!keepgoing)
|
|
break;
|
|
}
|
|
|
|
if (info_map->empty()) {
|
|
// No more entries in the InfoMap so remove it.
|
|
browser_info_map_.erase(it_browser);
|
|
delete info_map;
|
|
}
|
|
}
|
|
|
|
// Returns true if the map is empty.
|
|
bool empty() const { return browser_info_map_.empty(); }
|
|
|
|
// Returns the number of objects in the map.
|
|
size_t size() const {
|
|
if (browser_info_map_.empty())
|
|
return 0;
|
|
|
|
size_t size = 0;
|
|
typename BrowserInfoMap::const_iterator it_browser =
|
|
browser_info_map_.begin();
|
|
for (; it_browser != browser_info_map_.end(); ++it_browser)
|
|
size += it_browser->second->size();
|
|
return size;
|
|
}
|
|
|
|
// Returns the number of objects in the map that are associated with the
|
|
// specified browser.
|
|
size_t size(int browser_id) const {
|
|
if (browser_info_map_.empty())
|
|
return 0;
|
|
|
|
typename BrowserInfoMap::const_iterator it_browser =
|
|
browser_info_map_.find(browser_id);
|
|
if (it_browser != browser_info_map_.end())
|
|
return it_browser->second->size();
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Remove all objects from the map. The objects will be destructed.
|
|
void clear() {
|
|
if (browser_info_map_.empty())
|
|
return;
|
|
|
|
typename BrowserInfoMap::const_iterator it_browser =
|
|
browser_info_map_.begin();
|
|
for (; it_browser != browser_info_map_.end(); ++it_browser) {
|
|
InfoMap* info_map = it_browser->second;
|
|
typename InfoMap::const_iterator it_info = info_map->begin();
|
|
for (; it_info != info_map->end(); ++it_info)
|
|
Traits::Destruct(it_info->second);
|
|
delete info_map;
|
|
}
|
|
browser_info_map_.clear();
|
|
}
|
|
|
|
// Remove all objects from the map that are associated with the specified
|
|
// browser. The objects will be destructed.
|
|
void clear(int browser_id) {
|
|
if (browser_info_map_.empty())
|
|
return;
|
|
|
|
typename BrowserInfoMap::iterator it_browser =
|
|
browser_info_map_.find(browser_id);
|
|
if (it_browser == browser_info_map_.end())
|
|
return;
|
|
|
|
InfoMap* info_map = it_browser->second;
|
|
typename InfoMap::const_iterator it_info = info_map->begin();
|
|
for (; it_info != info_map->end(); ++it_info)
|
|
Traits::Destruct(it_info->second);
|
|
|
|
browser_info_map_.erase(it_browser);
|
|
delete info_map;
|
|
}
|
|
|
|
private:
|
|
// Map IdType to ObjectType instance.
|
|
typedef std::map<IdType, ObjectType> InfoMap;
|
|
// Map browser ID to InfoMap instance.
|
|
typedef std::map<int, InfoMap*> BrowserInfoMap;
|
|
|
|
BrowserInfoMap browser_info_map_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(CefBrowserInfoMap);
|
|
};
|
|
|
|
#endif // CEF_LIBCEF_DLL_WRAPPER_CEF_BROWSER_INFO_MAP_H_
|