Skip to content

Commit 577674f

Browse files
committed
Adds PGCFMutableArray which wraps CFMutableArray and provides access to its callbacks. Toll-free bridging won't do because the callbacks sometimes get ignored.
1 parent d04b431 commit 577674f

File tree

3 files changed

+188
-0
lines changed

3 files changed

+188
-0
lines changed

Diff for: PGCFMutableArray.h

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/* Copyright © 2007-2008 The Sequential Project. All rights reserved.
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a
4+
copy of this software and associated documentation files (the "Software"),
5+
to deal with the Software without restriction, including without limitation
6+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
7+
and/or sell copies of the Software, and to permit persons to whom the
8+
Software is furnished to do so, subject to the following conditions:
9+
1. Redistributions of source code must retain the above copyright notice,
10+
this list of conditions and the following disclaimers.
11+
2. Redistributions in binary form must reproduce the above copyright
12+
notice, this list of conditions and the following disclaimers in the
13+
documentation and/or other materials provided with the distribution.
14+
3. Neither the name of The Sequential Project nor the names of its
15+
contributors may be used to endorse or promote products derived from
16+
this Software without specific prior written permission.
17+
18+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21+
THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24+
DEALINGS WITH THE SOFTWARE. */
25+
#import <Cocoa/Cocoa.h>
26+
27+
@interface PGCFMutableArray : NSMutableArray // Toll-free bridging a CFArray to NSArray causes the callbacks to occasionally be ignored.
28+
{
29+
@private
30+
CFMutableArrayRef _array;
31+
}
32+
33+
@end
34+
35+
@interface NSMutableArray (PGExtendedMutableArray)
36+
37+
- (id)initWithCallbacks:(CFArrayCallBacks const *)callbacks;
38+
39+
@end

Diff for: PGCFMutableArray.m

+143
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/* Copyright © 2007-2008 The Sequential Project. All rights reserved.
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a
4+
copy of this software and associated documentation files (the "Software"),
5+
to deal with the Software without restriction, including without limitation
6+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
7+
and/or sell copies of the Software, and to permit persons to whom the
8+
Software is furnished to do so, subject to the following conditions:
9+
1. Redistributions of source code must retain the above copyright notice,
10+
this list of conditions and the following disclaimers.
11+
2. Redistributions in binary form must reproduce the above copyright
12+
notice, this list of conditions and the following disclaimers in the
13+
documentation and/or other materials provided with the distribution.
14+
3. Neither the name of The Sequential Project nor the names of its
15+
contributors may be used to endorse or promote products derived from
16+
this Software without specific prior written permission.
17+
18+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21+
THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24+
DEALINGS WITH THE SOFTWARE. */
25+
#import "PGCFMutableArray.h"
26+
27+
static CFIndex PGUnsignedToCFIndex(unsigned i)
28+
{
29+
return NSNotFound == i ? kCFNotFound : (CFIndex)i;
30+
}
31+
static unsigned PGCFIndexToUnsigned(CFIndex i)
32+
{
33+
return kCFNotFound == i ? NSNotFound : (unsigned)i;
34+
}
35+
36+
@implementation PGCFMutableArray
37+
38+
#pragma mark PGExtendedMutableArray Protocol
39+
40+
- (id)initWithCallbacks:(CFArrayCallBacks const *)callbacks
41+
{
42+
if((self = [super init])) {
43+
_array = CFArrayCreateMutable(kCFAllocatorDefault, 0, callbacks);
44+
}
45+
return self;
46+
}
47+
48+
#pragma mark NSExtendedMutableArray Protocol
49+
50+
- (void)removeAllObjects
51+
{
52+
CFArrayRemoveAllValues(_array);
53+
}
54+
- (void)addObjectsFromArray:(NSArray *)otherArray
55+
{
56+
CFArrayAppendArray(_array, (CFArrayRef)otherArray, CFRangeMake(0, CFArrayGetCount((CFArrayRef)otherArray)));
57+
}
58+
59+
#pragma mark NSExtendedArray Protocol
60+
61+
- (BOOL)containsObject:(id)anObject
62+
{
63+
return kCFNotFound != CFArrayGetFirstIndexOfValue(_array, CFRangeMake(0, CFArrayGetCount(_array)), anObject);
64+
}
65+
- (NSString *)description
66+
{
67+
return [(NSString *)CFCopyDescription(_array) autorelease];
68+
}
69+
- (BOOL)isEqualToArray:(NSArray *)otherArray
70+
{
71+
return CFEqual(_array, (CFArrayRef)otherArray);
72+
}
73+
- (unsigned)indexOfObject:(id)anObject
74+
inRange:(NSRange)range
75+
{
76+
return PGCFIndexToUnsigned(CFArrayGetFirstIndexOfValue(_array, CFRangeMake(PGUnsignedToCFIndex(range.location), PGUnsignedToCFIndex(range.length)), anObject));
77+
}
78+
- (unsigned)indexOfObjectIdenticalTo:(id)anObject
79+
inRange:(NSRange)range
80+
{
81+
return [self indexOfObject:anObject inRange:range];
82+
}
83+
84+
#pragma mark NSMutableArray
85+
86+
- (void)addObject:(id)anObject
87+
{
88+
CFArrayAppendValue(_array, anObject);
89+
}
90+
- (void)insertObject:(id)anObject
91+
atIndex:(unsigned)index
92+
{
93+
CFArrayInsertValueAtIndex(_array, PGUnsignedToCFIndex(index), anObject);
94+
}
95+
- (void)removeLastObject
96+
{
97+
unsigned const count = [self count];
98+
if(count) CFArrayRemoveValueAtIndex(_array, PGUnsignedToCFIndex(count - 1));
99+
}
100+
- (void)removeObjectAtIndex:(unsigned)index
101+
{
102+
CFArrayRemoveValueAtIndex(_array, PGUnsignedToCFIndex(index));
103+
}
104+
- (void)replaceObjectAtIndex:(unsigned)index
105+
withObject:(id)anObject
106+
{
107+
CFArraySetValueAtIndex(_array, PGUnsignedToCFIndex(index), anObject);
108+
}
109+
110+
#pragma mark NSArray
111+
112+
- (unsigned)count
113+
{
114+
return PGCFIndexToUnsigned(CFArrayGetCount(_array));
115+
}
116+
- (id)objectAtIndex:(unsigned)index
117+
{
118+
return (id)CFArrayGetValueAtIndex(_array, PGUnsignedToCFIndex(index));
119+
}
120+
121+
#pragma mark NSObject
122+
123+
- (id)init
124+
{
125+
return [self initWithCallbacks:NULL];
126+
}
127+
- (void)dealloc
128+
{
129+
if(_array) CFRelease(_array);
130+
[super dealloc];
131+
}
132+
133+
@end
134+
135+
@implementation NSMutableArray (PGExtendedMutableArray)
136+
137+
- (id)initWithCallbacks:(CFArrayCallBacks const *)callbacks
138+
{
139+
[self release];
140+
return [[PGCFMutableArray alloc] initWithCallbacks:callbacks];
141+
}
142+
143+
@end

Diff for: Sequential.xcodeproj/project.pbxproj

+6
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
0E1D39F40A7F24E700C542A6 /* PGFullscreenWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E1D39F30A7F24E700C542A6 /* PGFullscreenWindow.m */; };
4545
0E1D3A4C0A7FA7B500C542A6 /* PGClipView.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E1D3A4B0A7FA7B500C542A6 /* PGClipView.m */; };
4646
0E1D3EC90A8091FE00C542A6 /* PGDocumentController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E1D3EC80A8091FE00C542A6 /* PGDocumentController.m */; };
47+
0E20AF370EA6E325002A7854 /* PGCFMutableArray.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E20AF360EA6E325002A7854 /* PGCFMutableArray.m */; };
4748
0E255B960E3A99AA00EDF04C /* PGTimer.nib in Resources */ = {isa = PBXBuildFile; fileRef = 0E255B940E3A99AA00EDF04C /* PGTimer.nib */; };
4849
0E255B9B0E3A9A1E00EDF04C /* PGTimerPanelController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E255B9A0E3A9A1E00EDF04C /* PGTimerPanelController.m */; };
4950
0E255BA70E3A9D2E00EDF04C /* PGCircleProgressIndicator.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E255BA60E3A9D2E00EDF04C /* PGCircleProgressIndicator.m */; };
@@ -277,6 +278,8 @@
277278
0E1D3A4B0A7FA7B500C542A6 /* PGClipView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PGClipView.m; sourceTree = "<group>"; };
278279
0E1D3EC70A8091FD00C542A6 /* PGDocumentController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PGDocumentController.h; sourceTree = "<group>"; };
279280
0E1D3EC80A8091FE00C542A6 /* PGDocumentController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PGDocumentController.m; sourceTree = "<group>"; };
281+
0E20AF350EA6E325002A7854 /* PGCFMutableArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PGCFMutableArray.h; sourceTree = "<group>"; };
282+
0E20AF360EA6E325002A7854 /* PGCFMutableArray.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PGCFMutableArray.m; sourceTree = "<group>"; };
280283
0E255B950E3A99AA00EDF04C /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/PGTimer.nib; sourceTree = "<group>"; };
281284
0E255B990E3A9A1E00EDF04C /* PGTimerPanelController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PGTimerPanelController.h; sourceTree = "<group>"; };
282285
0E255B9A0E3A9A1E00EDF04C /* PGTimerPanelController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PGTimerPanelController.m; sourceTree = "<group>"; };
@@ -719,6 +722,8 @@
719722
0E4793920DF15FD90083B7CA /* PGAttachments.m */,
720723
0EC11DF10CA02B98003E492C /* PGByteOrdering.h */,
721724
0EC11DF20CA02B98003E492C /* PGByteOrdering.m */,
725+
0E20AF350EA6E325002A7854 /* PGCFMutableArray.h */,
726+
0E20AF360EA6E325002A7854 /* PGCFMutableArray.m */,
722727
0E92E1340E2CA88400276801 /* PGGeometry.h */,
723728
0E92E1350E2CA88400276801 /* PGGeometry.m */,
724729
0E7B2FF40E9266A600F537CD /* PGKeyboardLayout.h */,
@@ -1189,6 +1194,7 @@
11891194
0EDB9A760EA1896400B7342A /* PGColumnView.m in Sources */,
11901195
0EDB9A790EA1899300B7342A /* PGThumbnailBrowser.m in Sources */,
11911196
0EDB9BFF0EA1E27D00B7342A /* PGThumbnailView.m in Sources */,
1197+
0E20AF370EA6E325002A7854 /* PGCFMutableArray.m in Sources */,
11921198
);
11931199
runOnlyForDeploymentPostprocessing = 0;
11941200
};

0 commit comments

Comments
 (0)