#ifndef SharedBuffer_h
#define SharedBuffer_h
#include <runtime/ArrayBuffer.h>
#include <wtf/Forward.h>
#include <wtf/OwnPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/ThreadSafeRefCounted.h>
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
#if USE(CF)
#include <wtf/RetainPtr.h>
#endif
#if USE(SOUP)
#include "GUniquePtrSoup.h"
#endif
#if USE(FOUNDATION)
OBJC_CLASS NSData;
#endif
namespace WebCore {
class PurgeableBuffer;
class SharedBuffer : public RefCounted<SharedBuffer> {
public:
static PassRefPtr<SharedBuffer> create() { return adoptRef(new SharedBuffer); }
static PassRefPtr<SharedBuffer> create(unsigned size) { return adoptRef(new SharedBuffer(size)); }
static PassRefPtr<SharedBuffer> create(const char* c, unsigned i) { return adoptRef(new SharedBuffer(c, i)); }
static PassRefPtr<SharedBuffer> create(const unsigned char* c, unsigned 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 USE(FOUNDATION)
RetainPtr<NSData> createNSData();
static PassRefPtr<SharedBuffer> wrapNSData(NSData *data);
#endif
#if USE(CF)
RetainPtr<CFDataRef> createCFData();
CFDataRef existingCFData();
static PassRefPtr<SharedBuffer> wrapCFData(CFDataRef);
#endif
#if USE(SOUP)
static PassRefPtr<SharedBuffer> wrapSoupBuffer(SoupBuffer*);
#endif
const char* data() const;
PassRefPtr<ArrayBuffer> createArrayBuffer() const;
unsigned size() const;
bool isEmpty() const { return !size(); }
void append(SharedBuffer*);
void append(const char*, unsigned);
void append(const Vector<char>&);
void clear();
const char* platformData() const;
unsigned platformDataSize() const;
#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
static PassRefPtr<SharedBuffer> wrapCFDataArray(CFArrayRef);
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 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>, CompletionStatus, MemoryMappedNotifyCallbackData);
MemoryMappedNotifyCallbackData memoryMappedNotificationCallbackData() const;
MemoryMappedNotifyCallback memoryMappedNotificationCallback() const;
void setMemoryMappedNotificationCallback(MemoryMappedNotifyCallback, MemoryMappedNotifyCallbackData);
#endif
void createPurgeableBuffer() const;
void tryReplaceContentsWithPlatformBuffer(SharedBuffer*);
bool hasPlatformData() const;
struct DataBuffer : public ThreadSafeRefCounted<DataBuffer> {
Vector<char> data;
};
private:
SharedBuffer();
explicit SharedBuffer(unsigned);
SharedBuffer(const char*, unsigned);
SharedBuffer(const unsigned char*, unsigned);
const Vector<char>& buffer() const;
void clearPlatformData();
void maybeTransferPlatformData();
bool maybeAppendPlatformData(SharedBuffer*);
void copyBufferAndClear(char* destination, unsigned bytesToCopy) const;
void appendToDataBuffer(const char *, unsigned) const;
void duplicateDataBufferIfNecessary() const;
void clearDataBuffer();
unsigned m_size;
mutable RefPtr<DataBuffer> m_buffer;
bool m_shouldUsePurgeableMemory;
mutable OwnPtr<PurgeableBuffer> m_purgeableBuffer;
#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
explicit SharedBuffer(CFArrayRef);
mutable Vector<RetainPtr<CFDataRef>> m_dataArray;
unsigned copySomeDataFromDataArray(const char*& someData, unsigned position) const;
const char *singleDataArrayBuffer() const;
bool maybeAppendDataArray(SharedBuffer*);
#else
mutable Vector<char*> m_segments;
#endif
#if ENABLE(DISK_IMAGE_CACHE)
bool m_isMemoryMapped;
unsigned m_diskImageCacheId; MemoryMappedNotifyCallback m_notifyMemoryMappedCallback;
MemoryMappedNotifyCallbackData m_notifyMemoryMappedCallbackData;
#endif
#if USE(CF)
explicit SharedBuffer(CFDataRef);
RetainPtr<CFDataRef> m_cfData;
#endif
#if USE(SOUP)
explicit SharedBuffer(SoupBuffer*);
GUniquePtr<SoupBuffer> m_soupBuffer;
#endif
};
PassRefPtr<SharedBuffer> utf8Buffer(const String&);
}
#endif // SharedBuffer_h