#pragma once
#include "MessageReceiver.h"
#include "StorageAreaIdentifier.h"
#include "StorageAreaImplIdentifier.h"
#include <WebCore/SecurityOrigin.h>
#include <WebCore/StorageArea.h>
#include <wtf/Forward.h>
#include <wtf/HashCountedSet.h>
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
#include <wtf/WeakPtr.h>
namespace WebCore {
class SecurityOrigin;
class StorageMap;
}
namespace WebKit {
class StorageAreaImpl;
class StorageNamespaceImpl;
class StorageAreaMap final : private IPC::MessageReceiver, public CanMakeWeakPtr<StorageAreaMap> {
WTF_MAKE_FAST_ALLOCATED;
public:
StorageAreaMap(StorageNamespaceImpl&, Ref<WebCore::SecurityOrigin>&&);
~StorageAreaMap();
WebCore::StorageType type() const { return m_type; }
unsigned length();
String key(unsigned index);
String item(const String& key);
void setItem(WebCore::Frame* sourceFrame, StorageAreaImpl* sourceArea, const String& key, const String& value, bool& quotaException);
void removeItem(WebCore::Frame* sourceFrame, StorageAreaImpl* sourceArea, const String& key);
void clear(WebCore::Frame* sourceFrame, StorageAreaImpl* sourceArea);
bool contains(const String& key);
void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final;
const WebCore::SecurityOrigin& securityOrigin() const { return m_securityOrigin.get(); }
const Optional<StorageAreaIdentifier>& identifier() const { return m_mapID; }
void disconnect();
void incrementUseCount();
void decrementUseCount();
private:
void didSetItem(uint64_t mapSeed, const String& key, bool quotaError);
void didRemoveItem(uint64_t mapSeed, const String& key);
void didClear(uint64_t mapSeed);
void dispatchStorageEvent(const Optional<StorageAreaImplIdentifier>& sourceStorageAreaID, const String& key, const String& oldValue, const String& newValue, const String& urlString);
void clearCache();
void resetValues();
WebCore::StorageMap& ensureMap();
bool shouldApplyChangeForKey(const String& key) const;
void applyChange(const String& key, const String& newValue);
void dispatchSessionStorageEvent(const Optional<StorageAreaImplIdentifier>&, const String& key, const String& oldValue, const String& newValue, const String& urlString);
void dispatchLocalStorageEvent(const Optional<StorageAreaImplIdentifier>&, const String& key, const String& oldValue, const String& newValue, const String& urlString);
void connect();
StorageNamespaceImpl& m_namespace;
Ref<WebCore::SecurityOrigin> m_securityOrigin;
RefPtr<WebCore::StorageMap> m_map;
Optional<StorageAreaIdentifier> m_mapID;
HashCountedSet<String> m_pendingValueChanges;
uint64_t m_currentSeed { 0 };
unsigned m_quotaInBytes;
WebCore::StorageType m_type;
uint64_t m_useCount { 0 };
bool m_hasPendingClear { false };
};
}