#ifndef SharedBuffer_h
#define SharedBuffer_h
#include "FileSystem.h"
#include <runtime/ArrayBuffer.h>
#include <wtf/Forward.h>
#include <wtf/RefCounted.h>
#include <wtf/ThreadSafeRefCounted.h>
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
#if USE(CF)
#include "VNodeTracker.h"
#include <wtf/RetainPtr.h>
#endif
#if USE(SOUP)
#include "GUniquePtrSoup.h"
#endif
#if USE(FOUNDATION)
OBJC_CLASS NSData;
#endif
namespace WebCore {
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)); }
WEBCORE_EXPORT static RefPtr<SharedBuffer> createWithContentsOfFile(const String& filePath);
WEBCORE_EXPORT static PassRefPtr<SharedBuffer> adoptVector(Vector<char>& vector);
WEBCORE_EXPORT ~SharedBuffer();
#if USE(FOUNDATION)
WEBCORE_EXPORT RetainPtr<NSData> createNSData();
WEBCORE_EXPORT static PassRefPtr<SharedBuffer> wrapNSData(NSData *data);
#endif
#if USE(CF)
WEBCORE_EXPORT RetainPtr<CFDataRef> createCFData();
WEBCORE_EXPORT CFDataRef existingCFData();
WEBCORE_EXPORT static PassRefPtr<SharedBuffer> wrapCFData(CFDataRef);
#endif
#if USE(SOUP)
static PassRefPtr<SharedBuffer> wrapSoupBuffer(SoupBuffer*);
#endif
WEBCORE_EXPORT const char* data() const;
PassRefPtr<ArrayBuffer> createArrayBuffer() const;
WEBCORE_EXPORT unsigned size() const;
bool isEmpty() const { return !size(); }
WEBCORE_EXPORT void append(SharedBuffer*);
WEBCORE_EXPORT void append(const char*, unsigned);
void append(const Vector<char>&);
WEBCORE_EXPORT void clear();
const char* platformData() const;
unsigned platformDataSize() const;
#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
static PassRefPtr<SharedBuffer> wrapCFDataArray(CFArrayRef);
void append(CFDataRef);
#endif
WEBCORE_EXPORT Ref<SharedBuffer> copy() const;
WEBCORE_EXPORT unsigned getSomeData(const char*& data, unsigned position = 0) const;
void tryReplaceContentsWithPlatformBuffer(SharedBuffer&);
WEBCORE_EXPORT bool hasPlatformData() const;
struct DataBuffer : public ThreadSafeRefCounted<DataBuffer> {
Vector<char> data;
};
private:
WEBCORE_EXPORT SharedBuffer();
explicit SharedBuffer(unsigned);
WEBCORE_EXPORT SharedBuffer(const char*, unsigned);
WEBCORE_EXPORT SharedBuffer(const unsigned char*, unsigned);
explicit SharedBuffer(MappedFileData&&);
static RefPtr<SharedBuffer> createFromReadingFile(const String& filePath);
const Vector<char>& buffer() const;
void clearPlatformData();
void maybeTransferPlatformData();
bool maybeAppendPlatformData(SharedBuffer*);
void maybeTransferMappedFileData();
void copyBufferAndClear(char* destination, unsigned bytesToCopy) const;
void appendToDataBuffer(const char *, unsigned) const;
void duplicateDataBufferIfNecessary() const;
void clearDataBuffer();
unsigned m_size { 0 };
mutable RefPtr<DataBuffer> m_buffer;
#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 USE(CF)
explicit SharedBuffer(CFDataRef);
RetainPtr<CFDataRef> m_cfData;
VNodeTracker::Token m_vnodeToken;
#endif
#if USE(SOUP)
explicit SharedBuffer(SoupBuffer*);
GUniquePtr<SoupBuffer> m_soupBuffer;
#endif
MappedFileData m_fileData;
};
PassRefPtr<SharedBuffer> utf8Buffer(const String&);
}
#endif // SharedBuffer_h