Skip to content

Commit

Permalink
Implementing NSCountedSet collection
Browse files Browse the repository at this point in the history
VSO 5041366
  • Loading branch information
mnithish committed Oct 27, 2015
1 parent 9354ff1 commit cb21947
Show file tree
Hide file tree
Showing 10 changed files with 430 additions and 211 deletions.
29 changes: 29 additions & 0 deletions Frameworks/Foundation/NSCountedSet.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//******************************************************************************
//
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
//
// This code is licensed under the MIT License (MIT).
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
//******************************************************************************

#include "Starboard.h"
#include "Foundation/NSMutableSet.h"

NSUInteger NSSetTableGetValue(NSSet* set, id object);

@implementation NSCountedSet

- (NSUInteger)countForObject:(id)object {
NSUInteger count = NSSetTableGetValue(self, object);
return (count == nil) ? 0 : count;
}

@end
1 change: 1 addition & 0 deletions Frameworks/Foundation/NSException.mm
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
NSString* const NSObjectNotAvailableException = @"NSObjectNotAvailableException";
NSString* const NSDestinationInvalidException = @"NSDestinationInvalidException";
NSString* const NSURLErrorDomain = @"NSURLErrorDomain";
NSString* const NSOverflowException = @"NSOverflowException";

@implementation NSException {
idretaintype(NSString) _name;
Expand Down
3 changes: 2 additions & 1 deletion Frameworks/Foundation/NSMutableSet.mm
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
void NSSetTableRemoveAllObjects(NSSet* set);
NSUInteger NSSetTableCount(NSSet* set);

@implementation NSMutableSet : NSSet
@implementation NSMutableSet

- (id)copyWithZone:(NSZone*)zone {
return [[NSSet allocWithZone:zone] initWithSet:self];
}
Expand Down
84 changes: 67 additions & 17 deletions Frameworks/Foundation/NSSet.mm
Original file line number Diff line number Diff line change
Expand Up @@ -16,41 +16,71 @@

#include "Starboard.h"
#include "Foundation/NSSet.h"
#include "Foundation/NSMutableArray.h"
#include "Foundation/NSMutableSet.h"
#include "Foundation/NSCountedSet.h"
#include "Foundation/NSEnumerator.h"
#include "Foundation/NSKeyedArchiver.h"
#include "Foundation/NSString.h"

void NSSetTableInit(NSSet* set, NSUInteger capacity) {
if (object_getClass(set) != [NSSet class] && object_getClass(set) != [NSMutableSet class]) {
if (object_getClass(set) != [NSSet class] && object_getClass(set) != [NSMutableSet class] &&
object_getClass(set) != [NSCountedSet class]) {
assert(0);
}
set->_table.dict = CFDictionaryCreateMutable(NULL, capacity, &kCFTypeDictionaryKeyCallBacks, NULL);
}

id NSSetTableMember(NSSet* set, id object) {
if (object_getClass(set) != [NSSet class] && object_getClass(set) != [NSMutableSet class]) {
if (object_getClass(set) != [NSSet class] && object_getClass(set) != [NSMutableSet class] &&
object_getClass(set) != [NSCountedSet class]) {
assert(0);
}
id ret = nil;

if (CFDictionaryGetValueIfPresent(set->_table.dict, (void*)object, (const void**)&ret)) {
return ret;
NSUInteger count = nil;

if (CFDictionaryGetValueIfPresent(set->_table.dict, (void*)object, (const void**)&count)) {
return object;
}

return nil;
}

NSUInteger NSSetTableGetValue(NSSet* set, id object) {
if (object_getClass(set) != [NSSet class] && object_getClass(set) != [NSMutableSet class] &&
object_getClass(set) != [NSCountedSet class]) {
assert(0);
}

NSUInteger count = 0;

if (CFDictionaryGetValueIfPresent(set->_table.dict, (void*)object, (const void**)&count)) {
return count;
}

return 0;
}

void NSSetTableAddObject(NSSet* set, id object) {
if (object_getClass(set) != [NSSet class] && object_getClass(set) != [NSMutableSet class]) {
if (object_getClass(set) != [NSSet class] && object_getClass(set) != [NSMutableSet class] &&
object_getClass(set) != [NSCountedSet class]) {
assert(0);
}

if (object == nil) {
return;
}
if (NSSetTableMember(set, object) == nil) {
CFDictionarySetValue(set->_table.dict, (const void*)object, (void*)object);

NSUInteger currentCount = NSSetTableGetValue(set, object);
if (currentCount == 0) {
CFDictionarySetValue(set->_table.dict, (const void*)object, (void*)(NSUInteger)1);
} else {
if (object_getClass(set) == [NSCountedSet class]) {
// Increment the object count. If the count exceeds NSUIntegerMax, throw an exception.
if (currentCount < NSUIntegerMax) {
CFDictionarySetValue(set->_table.dict, (const void*)object, (void*)(currentCount + 1));
} else {
[NSException raise:NSOverflowException format:@"Object count exceeds NSUIntegerMax for object 0x%p!", (void*)object];
}
}
}
}

Expand All @@ -63,31 +93,50 @@ void NSSetTableInitWithObjects(NSSet* set, id* objects, int count) {
}

void NSSetTableFree(NSSet* set) {
if (object_getClass(set) != [NSSet class] && object_getClass(set) != [NSMutableSet class]) {
return;
if (object_getClass(set) != [NSSet class] && object_getClass(set) != [NSMutableSet class] &&
object_getClass(set) != [NSCountedSet class]) {
assert(0);
}

if (set->_table.dict != NULL) {
CFDictionaryRemoveAllValues(set->_table.dict);
_CFDictionaryDestroyInternal(set->_table.dict);
}
}

void NSSetTableRemoveObject(NSSet* set, id object) {
if (object_getClass(set) != [NSSet class] && object_getClass(set) != [NSMutableSet class]) {
if (object_getClass(set) != [NSSet class] && object_getClass(set) != [NSMutableSet class] &&
object_getClass(set) != [NSCountedSet class]) {
assert(0);
}
CFDictionaryRemoveValue(set->_table.dict, (void*)object);

if (object_getClass(set) != [NSCountedSet class]) {
CFDictionaryRemoveValue(set->_table.dict, (void*)object);
} else {
NSUInteger currentCount = NSSetTableGetValue(set, object);
if (currentCount != 0) {
// Remove the object if its count is 1 else just decrement its count and keep the object in the the
// dictionary.
if (currentCount == 1) {
CFDictionaryRemoveValue(set->_table.dict, (void*)object);
} else {
CFDictionarySetValue(set->_table.dict, (const void*)object, (void*)(currentCount - 1));
}
}
}
}

void NSSetTableRemoveAllObjects(NSSet* set) {
if (object_getClass(set) != [NSSet class] && object_getClass(set) != [NSMutableSet class]) {
if (object_getClass(set) != [NSSet class] && object_getClass(set) != [NSMutableSet class] &&
object_getClass(set) != [NSCountedSet class]) {
assert(0);
}
CFDictionaryRemoveAllValues(set->_table.dict);
}

NSUInteger NSSetTableCount(NSSet* set) {
if (object_getClass(set) != [NSSet class] && object_getClass(set) != [NSMutableSet class]) {
if (object_getClass(set) != [NSSet class] && object_getClass(set) != [NSMutableSet class] &&
object_getClass(set) != [NSCountedSet class]) {
assert(0);
}
return CFDictionaryGetCount(set->_table.dict);
Expand All @@ -101,7 +150,8 @@ int NSSetEnumeratorGetNextObject(NSSet* set, void* enumeratorHolder, id* ret, in
return CFDictionaryGetNextKey(set->_table.dict, enumeratorHolder, ret, count);
}

@implementation NSSet : NSObject
@implementation NSSet

+ (id)setWithObject:(id)obj {
return [[[self alloc] initWithObjects:&obj count:1] autorelease];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
<ClangCompile Include="$(MSBuildThisFileDirectory)..\..\..\Frameworks\Foundation\NSCoder.mm" />
<ClangCompile Include="$(MSBuildThisFileDirectory)..\..\..\Frameworks\Foundation\NSColor.mm" />
<ClangCompile Include="$(MSBuildThisFileDirectory)..\..\..\Frameworks\Foundation\NSCondition.mm" />
<ClangCompile Include="$(MSBuildThisFileDirectory)..\..\..\Frameworks\Foundation\NSCountedSet.mm" />
<ClangCompile Include="$(MSBuildThisFileDirectory)..\..\..\Frameworks\Foundation\NSData.mm" />
<ClangCompile Include="$(MSBuildThisFileDirectory)..\..\..\Frameworks\Foundation\NSDate.mm" />
<ClangCompile Include="$(MSBuildThisFileDirectory)..\..\..\Frameworks\Foundation\NSDateComponents.mm" />
Expand Down
Loading

0 comments on commit cb21947

Please sign in to comment.