Reduce copies and allocations in SharedBuffer::append
[WebKit-https.git] / Source / WebCore / platform / cocoa / SharedBufferCocoa.mm
1 /*
2  * Copyright (C) 2006-2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "SharedBuffer.h"
28
29 #include "WebCoreObjCExtras.h"
30 #include <runtime/InitializeThreading.h>
31 #include <string.h>
32 #include <wtf/MainThread.h>
33
34 using namespace WebCore;
35
36 @interface WebCoreSharedBufferData : NSData
37 {
38     RefPtr<const SharedBuffer::DataSegment> sharedBufferDataSegment;
39 }
40
41 - (id)initWithSharedBufferDataSegment:(const SharedBuffer::DataSegment&)dataSegment;
42 @end
43
44 @implementation WebCoreSharedBufferData
45
46 + (void)initialize
47 {
48 #if !USE(WEB_THREAD)
49     JSC::initializeThreading();
50     WTF::initializeMainThreadToProcessMainThread();
51 #endif // !USE(WEB_THREAD)
52 }
53
54 - (void)dealloc
55 {
56     if (WebCoreObjCScheduleDeallocateOnMainThread([WebCoreSharedBufferData class], self))
57         return;
58
59     [super dealloc];
60 }
61
62 - (id)initWithSharedBufferDataSegment:(const SharedBuffer::DataSegment&)dataSegment
63 {
64     self = [super init];
65     
66     if (self)
67         sharedBufferDataSegment = &dataSegment;
68
69     return self;
70 }
71
72 - (NSUInteger)length
73 {
74     return sharedBufferDataSegment->size();
75 }
76
77 - (const void *)bytes
78 {
79     return sharedBufferDataSegment->data();
80 }
81
82 @end
83
84 namespace WebCore {
85
86 Ref<SharedBuffer> SharedBuffer::create(NSData *nsData)
87 {
88     return adoptRef(*new SharedBuffer((CFDataRef)nsData));
89 }
90
91 RetainPtr<NSData> SharedBuffer::createNSData()
92 {
93     return adoptNS((NSData *)createCFData().leakRef());
94 }
95
96 RetainPtr<CFDataRef> SharedBuffer::createCFData()
97 {
98     combineToOneSegment();
99     if (!m_segments.size())
100         return adoptCF(CFDataCreate(nullptr, nullptr, 0));
101     ASSERT(m_segments.size() == 1);
102     return adoptCF((CFDataRef)adoptNS([[WebCoreSharedBufferData alloc] initWithSharedBufferDataSegment:m_segments[0]]).leakRef());
103 }
104
105 RefPtr<SharedBuffer> SharedBuffer::createFromReadingFile(const String& filePath)
106 {
107     NSData *resourceData = [NSData dataWithContentsOfFile:filePath];
108     if (resourceData) 
109         return SharedBuffer::create(resourceData);
110     return nullptr;
111 }
112
113 RetainPtr<NSArray> SharedBuffer::createNSDataArray() const
114 {
115     auto dataArray = adoptNS([[NSMutableArray alloc] initWithCapacity:m_segments.size()]);
116     for (const auto& segment : m_segments)
117         [dataArray addObject:adoptNS([[WebCoreSharedBufferData alloc] initWithSharedBufferDataSegment:segment]).get()];
118     return WTFMove(dataArray);
119 }
120
121 }