#define ENABLE_COOKIE_DEBUG 0
#include "config.h"
#include "CookieMap.h"
#include "CookieManager.h"
#include "Logging.h"
#include "ParsedCookie.h"
#include <wtf/text/CString.h>
#if ENABLE_COOKIE_DEBUG
#include <BlackBerryPlatformLog.h>
#define CookieLog(format, ...) BlackBerry::Platform::logAlways(BlackBerry::Platform::LogLevelInfo, format, ## __VA_ARGS__)
#else
#define CookieLog(format, ...)
#endif // ENABLE_COOKIE_DEBUG
namespace WebCore {
CookieMap::CookieMap(const String& name)
: m_oldestCookie(0)
, m_name(name)
{
}
CookieMap::~CookieMap()
{
deleteAllCookiesAndDomains();
}
ParsedCookie* CookieMap::addOrReplaceCookie(ParsedCookie* cookie)
{
CookieLog("CookieMap - Attempting to add cookie - %s", cookie->name().utf8().data());
ParsedCookie* prevCookie = 0;
size_t cookieCount = m_cookieVector.size();
for (size_t i = 0; i < cookieCount; i++) {
if (m_cookieVector[i]->name() == cookie->name() && m_cookieVector[i]->path() == cookie->path()) {
prevCookie = m_cookieVector[i];
m_cookieVector[i] = cookie;
if (prevCookie == m_oldestCookie)
updateOldestCookie();
return prevCookie;
}
}
m_cookieVector.append(cookie);
if (!cookie->isSession())
cookieManager().addedCookie();
if (!m_oldestCookie || m_oldestCookie->lastAccessed() > cookie->lastAccessed())
m_oldestCookie = cookie;
return 0;
}
ParsedCookie* CookieMap::removeCookieAtIndex(int position, const ParsedCookie* cookie)
{
ASSERT(0 <= position && static_cast<unsigned>(position) < m_cookieVector.size());
ParsedCookie* prevCookie = m_cookieVector[position];
m_cookieVector.remove(position);
if (prevCookie == m_oldestCookie)
updateOldestCookie();
else if (prevCookie != cookie) {
if (cookie->isForceExpired())
prevCookie->forceExpire();
delete cookie;
}
if (!prevCookie->isSession())
cookieManager().removedCookie();
return prevCookie;
}
ParsedCookie* CookieMap::removeCookie(const ParsedCookie* cookie)
{
size_t cookieCount = m_cookieVector.size();
for (size_t position = 0; position < cookieCount; ++position) {
if (m_cookieVector[position]->name() == cookie->name() && m_cookieVector[position]->path() == cookie->path())
return removeCookieAtIndex(position, cookie);
}
return 0;
}
CookieMap* CookieMap::getSubdomainMap(const String& subdomain)
{
#if ENABLE_COOKIE_DEBUG
if (!m_subdomains.contains(subdomain))
CookieLog("CookieMap - %s does not exist in this map", subdomain.utf8().data());
#endif
return m_subdomains.get(subdomain);
}
void CookieMap::addSubdomainMap(const String& subdomain, CookieMap* newDomain)
{
CookieLog("CookieMap - Attempting to add subdomain - %s", subdomain.utf8().data());
m_subdomains.add(subdomain, newDomain);
}
void CookieMap::getAllCookies(Vector<ParsedCookie*>* stackOfCookies)
{
CookieLog("CookieMap - Attempting to copy Map:%s cookies with %d cookies into vectors", m_name.utf8().data(), m_cookieVector.size());
stackOfCookies->reserveCapacity(stackOfCookies->size() + m_cookieVector.size());
size_t position = 0;
while (position < m_cookieVector.size()) {
ParsedCookie* newCookie = m_cookieVector[position];
if (newCookie->hasExpired()) {
ParsedCookie* expired = removeCookieAtIndex(position, newCookie);
delete expired;
} else {
stackOfCookies->append(newCookie);
position++;
}
}
CookieLog("CookieMap - stack of cookies now have %d cookies in it", (*stackOfCookies).size());
}
ParsedCookie* CookieMap::removeOldestCookie()
{
ParsedCookie* oldestCookie = m_oldestCookie;
if (!oldestCookie) {
CookieLog("CookieMap - no oldestCookie exist");
if (!m_subdomains.size()) {
CookieLog("CookieMap - no subdomains, base case reached, return 0");
return 0;
}
CookieLog("CookieMap - looking into subdomains");
for (HashMap<String, CookieMap*>::iterator it = m_subdomains.begin(); it != m_subdomains.end(); ++it) {
oldestCookie = it->second->removeOldestCookie();
if (oldestCookie)
break;
}
} else {
CookieLog("CookieMap - oldestCookie exist.");
oldestCookie = removeCookie(m_oldestCookie);
}
return oldestCookie;
}
void CookieMap::updateOldestCookie()
{
size_t size = m_cookieVector.size();
if (!size) {
m_oldestCookie = 0;
return;
}
m_oldestCookie = m_cookieVector[0];
for (size_t i = 1; i < size; ++i) {
if (m_oldestCookie->lastAccessed() > m_cookieVector[i]->lastAccessed())
m_oldestCookie = m_cookieVector[i];
}
}
void CookieMap::deleteAllCookiesAndDomains()
{
deleteAllValues(m_subdomains);
m_subdomains.clear();
deleteAllValues(m_cookieVector);
m_cookieVector.clear();
m_oldestCookie = 0;
}
void CookieMap::getAllChildCookies(Vector<ParsedCookie*>* stackOfCookies)
{
CookieLog("CookieMap - getAllChildCookies in Map - %s", getName().utf8().data());
getAllCookies(stackOfCookies);
for (HashMap<String, CookieMap*>::iterator it = m_subdomains.begin(); it != m_subdomains.end(); ++it)
it->second->getAllChildCookies(stackOfCookies);
}
}