#ifndef SharedBuffer_h
#define SharedBuffer_h
#include "PlatformString.h"
#include <wtf/Forward.h>
#include <wtf/OwnPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/Vector.h>
#if USE(CF)
#include <wtf/RetainPtr.h>
#endif
#if PLATFORM(MAC)
#ifdef __OBJC__
@class NSData;
#else
class NSData;
#endif
#endif
namespace WebCore {
class PurgeableBuffer;
class SharedBuffer : public RefCounted<SharedBuffer> {
public:
static PassRefPtr<SharedBuffer> create() { return adoptRef(new SharedBuffer); }
static PassRefPtr<SharedBuffer> create(const char* c, int i) { return adoptRef(new SharedBuffer(c, i)); }
static PassRefPtr<SharedBuffer> create(const unsigned char* c, int i) { return adoptRef(new SharedBuffer(c, i)); }
static PassRefPtr<SharedBuffer> createWithContentsOfFile(const String& filePath);
static PassRefPtr<SharedBuffer> adoptVector(Vector<char>& vector);
static PassRefPtr<SharedBuffer> adoptPurgeableBuffer(PassOwnPtr<PurgeableBuffer>);
~SharedBuffer();
#if PLATFORM(MAC)
NSData *createNSData();
static PassRefPtr<SharedBuffer> wrapNSData(NSData *data);
#endif
#if USE(CF)
CFDataRef createCFData();
static PassRefPtr<SharedBuffer> wrapCFData(CFDataRef);
#endif
const char* data() const;
unsigned size() const;
bool isEmpty() const { return !size(); }
void append(const char*, unsigned);
void clear();
const char* platformData() const;
unsigned platformDataSize() const;
#if HAVE(CFNETWORK_DATA_ARRAY_CALLBACK)
void append(CFDataRef);
#endif
PassRefPtr<SharedBuffer> copy() const;
bool hasPurgeableBuffer() const { return m_purgeableBuffer.get(); }
PassOwnPtr<PurgeableBuffer> releasePurgeableBuffer();
unsigned getSomeData(const char*& data, unsigned position = 0) const;
void createPurgeableBuffer() const;
void shouldUsePurgeableMemory(bool use) { m_shouldUsePurgeableMemory = use; }
#if ENABLE(DISK_IMAGE_CACHE)
enum MemoryMappingState { QueuedForMapping, PreviouslyQueuedForMapping, SuccessAlreadyMapped, FailureCacheFull };
MemoryMappingState allowToBeMemoryMapped();
bool isAllowedToBeMemoryMapped() const;
void failedMemoryMap();
void markAsMemoryMapped();
bool isMemoryMapped() const { return m_isMemoryMapped; }
enum CompletionStatus { Failed, Succeeded };
typedef void* MemoryMappedNotifyCallbackData;
typedef void (*MemoryMappedNotifyCallback)(PassRefPtr<SharedBuffer> buffer, CompletionStatus mapStatus, MemoryMappedNotifyCallbackData data);
MemoryMappedNotifyCallbackData memoryMappedNotificationCallbackData() const;
MemoryMappedNotifyCallback memoryMappedNotificationCallback() const;
void setMemoryMappedNotificationCallback(MemoryMappedNotifyCallback callback, MemoryMappedNotifyCallbackData data);
#endif
private:
SharedBuffer();
SharedBuffer(const char*, int);
SharedBuffer(const unsigned char*, int);
const Vector<char>& buffer() const;
void clearPlatformData();
void maybeTransferPlatformData();
bool hasPlatformData() const;
unsigned m_size;
mutable Vector<char> m_buffer;
mutable Vector<char*> m_segments;
bool m_shouldUsePurgeableMemory;
mutable OwnPtr<PurgeableBuffer> m_purgeableBuffer;
#if HAVE(CFNETWORK_DATA_ARRAY_CALLBACK)
mutable Vector<RetainPtr<CFDataRef> > m_dataArray;
void copyDataArrayAndClear(char *destination, unsigned bytesToCopy) const;
#endif
#if ENABLE(DISK_IMAGE_CACHE)
bool m_isMemoryMapped;
unsigned m_diskImageCacheId; MemoryMappedNotifyCallback m_notifyMemoryMappedCallback;
MemoryMappedNotifyCallbackData m_notifyMemoryMappedCallbackData;
#endif
#if USE(CF)
SharedBuffer(CFDataRef);
RetainPtr<CFDataRef> m_cfData;
#endif
};
}
#endif // SharedBuffer_h