[Cocoa] Teach SharedBuffer to return an NSArray of data segments to avoid flattening
[WebKit-https.git] / Source / WebCore / platform / SharedBuffer.h
1 /*
2  * Copyright (C) 2006-2017 Apple Inc. All rights reserved.
3  * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
25  */
26
27 #pragma once
28
29 #include "FileSystem.h"
30 #include <runtime/ArrayBuffer.h>
31 #include <wtf/Forward.h>
32 #include <wtf/RefCounted.h>
33 #include <wtf/ThreadSafeRefCounted.h>
34 #include <wtf/Vector.h>
35 #include <wtf/text/WTFString.h>
36
37 #if USE(CF)
38 #include "VNodeTracker.h"
39 #include <wtf/RetainPtr.h>
40 #endif
41
42 #if USE(SOUP)
43 #include "GUniquePtrSoup.h"
44 #endif
45
46 #if USE(FOUNDATION)
47 OBJC_CLASS NSArray;
48 OBJC_CLASS NSData;
49 #endif
50
51 namespace WebCore {
52     
53 class SharedBuffer : public RefCounted<SharedBuffer> {
54 public:
55     static Ref<SharedBuffer> create() { return adoptRef(*new SharedBuffer); }
56     static Ref<SharedBuffer> create(unsigned size) { return adoptRef(*new SharedBuffer(size)); }
57     static Ref<SharedBuffer> create(const char* c, unsigned i) { return adoptRef(*new SharedBuffer(c, i)); }
58     static Ref<SharedBuffer> create(const unsigned char* data, unsigned size) { return adoptRef(*new SharedBuffer(data, size)); }
59
60     WEBCORE_EXPORT static RefPtr<SharedBuffer> createWithContentsOfFile(const String& filePath);
61
62     WEBCORE_EXPORT static Ref<SharedBuffer> adoptVector(Vector<char>&);
63     
64     WEBCORE_EXPORT ~SharedBuffer();
65     
66 #if USE(FOUNDATION)
67     WEBCORE_EXPORT RetainPtr<NSData> createNSData();
68     WEBCORE_EXPORT RetainPtr<NSArray> createNSDataArray();
69     WEBCORE_EXPORT static Ref<SharedBuffer> wrapNSData(NSData *);
70 #endif
71 #if USE(CF)
72     WEBCORE_EXPORT RetainPtr<CFDataRef> createCFData();
73     WEBCORE_EXPORT CFDataRef existingCFData();
74     WEBCORE_EXPORT static Ref<SharedBuffer> wrapCFData(CFDataRef);
75 #endif
76
77 #if USE(SOUP)
78     GUniquePtr<SoupBuffer> createSoupBuffer(unsigned offset = 0, unsigned size = 0);
79     static Ref<SharedBuffer> wrapSoupBuffer(SoupBuffer*);
80 #endif
81
82     // Calling this function will force internal segmented buffers
83     // to be merged into a flat buffer. Use getSomeData() whenever possible
84     // for better performance.
85     WEBCORE_EXPORT const char* data() const;
86     // Creates an ArrayBuffer and copies this SharedBuffer's contents to that
87     // ArrayBuffer without merging segmented buffers into a flat buffer.
88     WEBCORE_EXPORT RefPtr<ArrayBuffer> createArrayBuffer() const;
89
90     WEBCORE_EXPORT unsigned size() const;
91
92
93     bool isEmpty() const { return !size(); }
94
95     WEBCORE_EXPORT void append(SharedBuffer&);
96     WEBCORE_EXPORT void append(const char*, unsigned);
97     WEBCORE_EXPORT void append(const Vector<char>&);
98
99     WEBCORE_EXPORT void clear();
100     const char* platformData() const;
101     unsigned platformDataSize() const;
102
103 #if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
104     WEBCORE_EXPORT static Ref<SharedBuffer> wrapCFDataArray(CFArrayRef);
105     WEBCORE_EXPORT void append(CFDataRef);
106 #endif
107
108     WEBCORE_EXPORT Ref<SharedBuffer> copy() const;
109     
110     // Return the number of consecutive bytes after "position". "data"
111     // points to the first byte.
112     // Return 0 when no more data left.
113     // When extracting all data with getSomeData(), the caller should
114     // repeat calling it until it returns 0.
115     // Usage:
116     //      const char* segment;
117     //      unsigned pos = 0;
118     //      while (unsigned length = sharedBuffer->getSomeData(segment, pos)) {
119     //          // Use the data. for example: decoder->decode(segment, length);
120     //          pos += length;
121     //      }
122     WEBCORE_EXPORT unsigned getSomeData(const char*& data, unsigned position = 0) const;
123
124     bool tryReplaceContentsWithPlatformBuffer(SharedBuffer&);
125     WEBCORE_EXPORT bool hasPlatformData() const;
126
127     struct DataBuffer : public ThreadSafeRefCounted<DataBuffer> {
128         Vector<char> data;
129     };
130
131     void hintMemoryNotNeededSoon();
132
133 private:
134     WEBCORE_EXPORT SharedBuffer();
135     explicit SharedBuffer(unsigned);
136     WEBCORE_EXPORT SharedBuffer(const char*, unsigned);
137     WEBCORE_EXPORT SharedBuffer(const unsigned char*, unsigned);
138     explicit SharedBuffer(MappedFileData&&);
139
140     static RefPtr<SharedBuffer> createFromReadingFile(const String& filePath);
141
142     // Calling this function will force internal segmented buffers
143     // to be merged into a flat buffer. Use getSomeData() whenever possible
144     // for better performance.
145     const Vector<char>& buffer() const;
146
147     void clearPlatformData();
148     void maybeTransferPlatformData();
149     bool maybeAppendPlatformData(SharedBuffer&);
150
151     void maybeTransferMappedFileData();
152
153     void copyBufferAndClear(char* destination, unsigned bytesToCopy) const;
154
155     void appendToDataBuffer(const char *, unsigned) const;
156     void duplicateDataBufferIfNecessary() const;
157     void clearDataBuffer();
158
159     unsigned m_size { 0 };
160     mutable Ref<DataBuffer> m_buffer;
161
162 #if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
163     explicit SharedBuffer(CFArrayRef);
164     mutable Vector<RetainPtr<CFDataRef>> m_dataArray;
165     unsigned copySomeDataFromDataArray(const char*& someData, unsigned position) const;
166     const char *singleDataArrayBuffer() const;
167     bool maybeAppendDataArray(SharedBuffer&);
168 #else
169     mutable Vector<char*> m_segments;
170 #endif
171
172 #if USE(CF)
173     explicit SharedBuffer(CFDataRef);
174     RetainPtr<CFDataRef> m_cfData;
175     VNodeTracker::Token m_vnodeToken;
176 #endif
177
178 #if USE(SOUP)
179     explicit SharedBuffer(SoupBuffer*);
180     GUniquePtr<SoupBuffer> m_soupBuffer;
181 #endif
182
183     MappedFileData m_fileData;
184 };
185
186 RefPtr<SharedBuffer> utf8Buffer(const String&);
187
188 } // namespace WebCore