Delete WebMetal implementation in favor of WebGPU
[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 <JavaScriptCore/ArrayBuffer.h>
30 #include <wtf/FileSystem.h>
31 #include <wtf/Forward.h>
32 #include <wtf/RefCounted.h>
33 #include <wtf/ThreadSafeRefCounted.h>
34 #include <wtf/Variant.h>
35 #include <wtf/Vector.h>
36 #include <wtf/text/WTFString.h>
37
38 #if USE(CF)
39 #include <wtf/RetainPtr.h>
40 #endif
41
42 #if USE(SOUP)
43 #include "GUniquePtrSoup.h"
44 #endif
45
46 #if USE(GLIB)
47 #include <wtf/glib/GRefPtr.h>
48 typedef struct _GBytes GBytes;
49 #endif
50
51 #if USE(GSTREAMER)
52 #include "GStreamerCommon.h"
53 #endif
54
55 #if USE(FOUNDATION)
56 OBJC_CLASS NSArray;
57 OBJC_CLASS NSData;
58 #endif
59
60 namespace WebCore {
61
62 class SharedBufferDataView;
63
64 class WEBCORE_EXPORT SharedBuffer : public RefCounted<SharedBuffer> {
65 public:
66     static Ref<SharedBuffer> create() { return adoptRef(*new SharedBuffer); }
67     static Ref<SharedBuffer> create(const char* data, size_t size) { return adoptRef(*new SharedBuffer(data, size)); }
68     static Ref<SharedBuffer> create(const unsigned char* data, size_t size) { return adoptRef(*new SharedBuffer(data, size)); }
69     static RefPtr<SharedBuffer> createWithContentsOfFile(const String& filePath);
70
71     static Ref<SharedBuffer> create(Vector<char>&&);
72     static Ref<SharedBuffer> create(Vector<uint8_t>&&);
73
74 #if USE(FOUNDATION)
75     RetainPtr<NSData> createNSData() const;
76     RetainPtr<NSArray> createNSDataArray() const;
77     static Ref<SharedBuffer> create(NSData *);
78     void append(NSData *);
79 #endif
80 #if USE(CF)
81     RetainPtr<CFDataRef> createCFData() const;
82     static Ref<SharedBuffer> create(CFDataRef);
83     void append(CFDataRef);
84 #endif
85
86 #if USE(SOUP)
87     GUniquePtr<SoupBuffer> createSoupBuffer(unsigned offset = 0, unsigned size = 0);
88     static Ref<SharedBuffer> wrapSoupBuffer(SoupBuffer*);
89 #endif
90
91 #if USE(GLIB)
92     static Ref<SharedBuffer> create(GBytes*);
93 #endif
94
95 #if USE(GSTREAMER)
96     static Ref<SharedBuffer> create(GstMappedBuffer&);
97 #endif
98     // Calling data() causes all the data segments to be copied into one segment if they are not already.
99     // Iterate the segments using begin() and end() instead.
100     // FIXME: Audit the call sites of this function and replace them with iteration if possible.
101     const char* data() const;
102
103     // Creates an ArrayBuffer and copies this SharedBuffer's contents to that
104     // ArrayBuffer without merging segmented buffers into a flat buffer.
105     RefPtr<ArrayBuffer> tryCreateArrayBuffer() const;
106
107     size_t size() const { return m_size; }
108
109     bool isEmpty() const { return !size(); }
110
111     void append(const SharedBuffer&);
112     void append(const char*, size_t);
113     void append(Vector<char>&&);
114
115     void clear();
116
117     Ref<SharedBuffer> copy() const;
118
119     // Data wrapped by a DataSegment should be immutable because it can be referenced by other objects.
120     // To modify or combine the data, allocate a new DataSegment.
121     class DataSegment : public ThreadSafeRefCounted<DataSegment> {
122     public:
123         WEBCORE_EXPORT const char* data() const;
124         WEBCORE_EXPORT size_t size() const;
125
126         static Ref<DataSegment> create(Vector<char>&& data) { return adoptRef(*new DataSegment(WTFMove(data))); }
127 #if USE(CF)
128         static Ref<DataSegment> create(RetainPtr<CFDataRef>&& data) { return adoptRef(*new DataSegment(WTFMove(data))); }
129 #endif
130 #if USE(SOUP)
131         static Ref<DataSegment> create(GUniquePtr<SoupBuffer>&& data) { return adoptRef(*new DataSegment(WTFMove(data))); }
132 #endif
133 #if USE(GLIB)
134         static Ref<DataSegment> create(GRefPtr<GBytes>&& data) { return adoptRef(*new DataSegment(WTFMove(data))); }
135 #endif
136 #if USE(GSTREAMER)
137         static Ref<DataSegment> create(RefPtr<GstMappedBuffer>&& data) { return adoptRef(*new DataSegment(WTFMove(data))); }
138 #endif
139         static Ref<DataSegment> create(FileSystem::MappedFileData&& data) { return adoptRef(*new DataSegment(WTFMove(data))); }
140
141     private:
142         DataSegment(Vector<char>&& data)
143             : m_immutableData(WTFMove(data)) { }
144 #if USE(CF)
145         DataSegment(RetainPtr<CFDataRef>&& data)
146             : m_immutableData(WTFMove(data)) { }
147 #endif
148 #if USE(SOUP)
149         DataSegment(GUniquePtr<SoupBuffer>&& data)
150             : m_immutableData(WTFMove(data)) { }
151 #endif
152 #if USE(GLIB)
153         DataSegment(GRefPtr<GBytes>&& data)
154             : m_immutableData(WTFMove(data)) { }
155 #endif
156 #if USE(GSTREAMER)
157         DataSegment(RefPtr<GstMappedBuffer>&& data)
158             : m_immutableData(WTFMove(data)) { }
159 #endif
160         DataSegment(FileSystem::MappedFileData&& data)
161             : m_immutableData(WTFMove(data)) { }
162
163         Variant<Vector<char>,
164 #if USE(CF)
165             RetainPtr<CFDataRef>,
166 #endif
167 #if USE(SOUP)
168             GUniquePtr<SoupBuffer>,
169 #endif
170 #if USE(GLIB)
171             GRefPtr<GBytes>,
172 #endif
173 #if USE(GSTREAMER)
174             RefPtr<GstMappedBuffer>,
175 #endif
176             FileSystem::MappedFileData> m_immutableData;
177         friend class SharedBuffer;
178     };
179
180     struct DataSegmentVectorEntry {
181         size_t beginPosition;
182         Ref<DataSegment> segment;
183     };
184     using DataSegmentVector = Vector<DataSegmentVectorEntry, 1>;
185     DataSegmentVector::const_iterator begin() const { return m_segments.begin(); }
186     DataSegmentVector::const_iterator end() const { return m_segments.end(); }
187     
188     // begin and end take O(1) time, this takes O(log(N)) time.
189     SharedBufferDataView getSomeData(size_t position) const;
190
191     void hintMemoryNotNeededSoon() const;
192
193     bool operator==(const SharedBuffer&) const;
194     bool operator!=(const SharedBuffer& other) const { return !operator==(other); }
195
196 private:
197     explicit SharedBuffer() = default;
198     explicit SharedBuffer(const char*, size_t);
199     explicit SharedBuffer(const unsigned char*, size_t);
200     explicit SharedBuffer(Vector<char>&&);
201     explicit SharedBuffer(FileSystem::MappedFileData&&);
202 #if USE(CF)
203     explicit SharedBuffer(CFDataRef);
204 #endif
205 #if USE(SOUP)
206     explicit SharedBuffer(SoupBuffer*);
207 #endif
208 #if USE(GLIB)
209     explicit SharedBuffer(GBytes*);
210 #endif
211 #if USE(GSTREAMER)
212     explicit SharedBuffer(GstMappedBuffer&);
213 #endif
214
215     void combineIntoOneSegment() const;
216     
217     static RefPtr<SharedBuffer> createFromReadingFile(const String& filePath);
218
219     size_t m_size { 0 };
220     mutable DataSegmentVector m_segments;
221
222 #if !ASSERT_DISABLED
223     mutable bool m_hasBeenCombinedIntoOneSegment { false };
224     bool internallyConsistent() const;
225 #endif
226 };
227
228 inline bool operator==(const Ref<SharedBuffer>& left, const SharedBuffer& right)
229 {
230     return left.get() == right;
231 }
232
233 inline bool operator!=(const Ref<SharedBuffer>& left, const SharedBuffer& right)
234 {
235     return left.get() != right;
236 }
237
238 class WEBCORE_EXPORT SharedBufferDataView {
239 public:
240     SharedBufferDataView(Ref<SharedBuffer::DataSegment>&&, size_t);
241     size_t size() const;
242     const char* data() const;
243 private:
244     size_t m_positionWithinSegment;
245     Ref<SharedBuffer::DataSegment> m_segment;
246 };
247
248 RefPtr<SharedBuffer> utf8Buffer(const String&);
249
250 } // namespace WebCore