#pragma once
#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 Ref<SharedBuffer> create() { return adoptRef(*new SharedBuffer); }
static Ref<SharedBuffer> create(unsigned size) { return adoptRef(*new SharedBuffer(size)); }
static Ref<SharedBuffer> create(const char* c, unsigned i) { return adoptRef(*new SharedBuffer(c, i)); }
static Ref<SharedBuffer> create(const unsigned char* data, unsigned size) { return adoptRef(*new SharedBuffer(data, size)); }
WEBCORE_EXPORT static RefPtr<SharedBuffer> createWithContentsOfFile(const String& filePath);
WEBCORE_EXPORT static Ref<SharedBuffer> adoptVector(Vector<char>&);
WEBCORE_EXPORT ~SharedBuffer();
#if USE(FOUNDATION)
WEBCORE_EXPORT RetainPtr<NSData> createNSData();
WEBCORE_EXPORT static Ref<SharedBuffer> wrapNSData(NSData *);
#endif
#if USE(CF)
WEBCORE_EXPORT RetainPtr<CFDataRef> createCFData();
WEBCORE_EXPORT CFDataRef existingCFData();
WEBCORE_EXPORT static Ref<SharedBuffer> wrapCFData(CFDataRef);
#endif
#if USE(SOUP)
static Ref<SharedBuffer> wrapSoupBuffer(SoupBuffer*);
#endif
WEBCORE_EXPORT const char* data() const;
WEBCORE_EXPORT RefPtr<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);
WEBCORE_EXPORT void append(const Vector<char>&);
WEBCORE_EXPORT void clear();
const char* platformData() const;
unsigned platformDataSize() const;
#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
static Ref<SharedBuffer> wrapCFDataArray(CFArrayRef);
void append(CFDataRef);
#endif
WEBCORE_EXPORT Ref<SharedBuffer> copy() const;
WEBCORE_EXPORT unsigned getSomeData(const char*& data, unsigned position = 0) const;
bool tryReplaceContentsWithPlatformBuffer(SharedBuffer&);
WEBCORE_EXPORT bool hasPlatformData() const;
struct DataBuffer : public ThreadSafeRefCounted<DataBuffer> {
Vector<char> data;
};
void hintMemoryNotNeededSoon();
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 Ref<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;
};
RefPtr<SharedBuffer> utf8Buffer(const String&);
}