7cd3fdb17b9891567416f4cab16940d508b90d68
[WebKit-https.git] / Tools / WebKitTestRunner / mac / WebKitTestRunnerPasteboard.mm
1 /*
2  * Copyright (C) 2005, 2006, 2013 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. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WebKitTestRunnerPasteboard.h"
28
29 @interface LocalPasteboard : NSPasteboard
30 {
31     NSMutableArray *typesArray;
32     NSMutableSet *typesSet;
33     NSMutableDictionary *dataByType;
34     NSInteger changeCount;
35     NSString *pasteboardName;
36 }
37
38 -(id)initWithName:(NSString *)name;
39 @end
40
41 static NSMutableDictionary *localPasteboards;
42
43 @implementation WebKitTestRunnerPasteboard
44
45 // Return a local pasteboard so we don't disturb the real pasteboards when running tests.
46 + (NSPasteboard *)_pasteboardWithName:(NSString *)name
47 {
48     static int number = 0;
49     if (!name)
50         name = [NSString stringWithFormat:@"LocalPasteboard%d", ++number];
51     if (!localPasteboards)
52         localPasteboards = [[NSMutableDictionary alloc] init];
53     LocalPasteboard *pasteboard = [localPasteboards objectForKey:name];
54     if (pasteboard)
55         return pasteboard;
56     pasteboard = [[LocalPasteboard alloc] initWithName:name];
57     [localPasteboards setObject:pasteboard forKey:name];
58     [pasteboard release];
59     return pasteboard;
60 }
61
62 + (void)releaseLocalPasteboards
63 {
64     [localPasteboards release];
65     localPasteboards = nil;
66 }
67
68 @end
69
70 @implementation LocalPasteboard
71
72 + (id)alloc
73 {
74     return NSAllocateObject(self, 0, 0);
75 }
76
77 - (id)initWithName:(NSString *)name
78 {
79     typesArray = [[NSMutableArray alloc] init];
80     typesSet = [[NSMutableSet alloc] init];
81     dataByType = [[NSMutableDictionary alloc] init];
82     pasteboardName = [name copy];
83     return self;
84 }
85
86 - (void)dealloc
87 {
88     [typesArray release];
89     [typesSet release];
90     [dataByType release];
91     [pasteboardName release];
92     [super dealloc];
93 }
94
95 - (NSString *)name
96 {
97     return pasteboardName;
98 }
99
100 - (void)releaseGlobally
101 {
102 }
103
104 - (NSInteger)declareTypes:(NSArray *)newTypes owner:(id)newOwner
105 {
106     [typesArray removeAllObjects];
107     [typesSet removeAllObjects];
108     [dataByType removeAllObjects];
109     return [self addTypes:newTypes owner:newOwner];
110 }
111
112 - (NSInteger)addTypes:(NSArray *)newTypes owner:(id)newOwner
113 {
114     unsigned count = [newTypes count];
115     unsigned i;
116     for (i = 0; i < count; ++i) {
117         NSString *type = [newTypes objectAtIndex:i];
118         NSString *setType = [typesSet member:type];
119         if (!setType) {
120             setType = [type copy];
121             [typesArray addObject:setType];
122             [typesSet addObject:setType];
123             [setType release];
124         }
125         if (newOwner && [newOwner respondsToSelector:@selector(pasteboard:provideDataForType:)])
126             [newOwner pasteboard:self provideDataForType:setType];
127     }
128     return ++changeCount;
129 }
130
131 - (NSInteger)changeCount
132 {
133     return changeCount;
134 }
135
136 - (NSArray *)types
137 {
138     return typesArray;
139 }
140
141 - (NSString *)availableTypeFromArray:(NSArray *)types
142 {
143     unsigned count = [types count];
144     unsigned i;
145     for (i = 0; i < count; ++i) {
146         NSString *type = [types objectAtIndex:i];
147         NSString *setType = [typesSet member:type];
148         if (setType)
149             return setType;
150     }
151     return nil;
152 }
153
154 - (BOOL)setData:(NSData *)data forType:(NSString *)dataType
155 {
156     if (!data)
157         data = [NSData data];
158     if (![typesSet containsObject:dataType])
159         return NO;
160     [dataByType setObject:data forKey:dataType];
161     ++changeCount;
162     return YES;
163 }
164
165 - (NSData *)dataForType:(NSString *)dataType
166 {
167     return [dataByType objectForKey:dataType];
168 }
169
170 - (BOOL)setPropertyList:(id)propertyList forType:(NSString *)dataType
171 {
172     CFDataRef data = 0;
173     if (propertyList)
174         data = CFPropertyListCreateXMLData(0, propertyList);
175     BOOL result = [self setData:(NSData *)data forType:dataType];
176     if (data)
177         CFRelease(data);
178     return result;
179 }
180
181 - (BOOL)setString:(NSString *)string forType:(NSString *)dataType
182 {
183     CFDataRef data = 0;
184     if (string) {
185         if (![string length])
186             data = CFDataCreate(0, 0, 0);
187         else
188             data = CFStringCreateExternalRepresentation(0, (CFStringRef)string, kCFStringEncodingUTF8, 0);
189     }
190     BOOL result = [self setData:(NSData *)data forType:dataType];
191     if (data)
192         CFRelease(data);
193     return result;
194 }
195
196 @end