From cb21947d6e44ee85991d0735f7f8699f4ef981aa Mon Sep 17 00:00:00 2001 From: Nithish Mahalingam Date: Tue, 27 Oct 2015 10:40:41 -0700 Subject: [PATCH] Implementing NSCountedSet collection VSO 5041366 --- Frameworks/Foundation/NSCountedSet.mm | 29 +++ Frameworks/Foundation/NSException.mm | 1 + Frameworks/Foundation/NSMutableSet.mm | 3 +- Frameworks/Foundation/NSSet.mm | 84 +++++-- .../Foundation.Shared.vcxitems | 1 + .../Foundation.Shared/Foundation.def | 230 +++++++++--------- build/UnitTests/UnitTests.vcxproj | 1 + include/Foundation/NSCountedSet.h | 30 ++- include/Foundation/NSException.h | 137 ++++++----- tests/unittests/foundation_NSCountedSet.mm | 125 ++++++++++ 10 files changed, 430 insertions(+), 211 deletions(-) create mode 100644 Frameworks/Foundation/NSCountedSet.mm create mode 100644 tests/unittests/foundation_NSCountedSet.mm diff --git a/Frameworks/Foundation/NSCountedSet.mm b/Frameworks/Foundation/NSCountedSet.mm new file mode 100644 index 0000000000..7d79b3f6ea --- /dev/null +++ b/Frameworks/Foundation/NSCountedSet.mm @@ -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 diff --git a/Frameworks/Foundation/NSException.mm b/Frameworks/Foundation/NSException.mm index 20115f6aa0..ea0aca1467 100644 --- a/Frameworks/Foundation/NSException.mm +++ b/Frameworks/Foundation/NSException.mm @@ -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; diff --git a/Frameworks/Foundation/NSMutableSet.mm b/Frameworks/Foundation/NSMutableSet.mm index e3f83fd15b..16b1cf13ba 100644 --- a/Frameworks/Foundation/NSMutableSet.mm +++ b/Frameworks/Foundation/NSMutableSet.mm @@ -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]; } diff --git a/Frameworks/Foundation/NSSet.mm b/Frameworks/Foundation/NSSet.mm index 0c2a82152f..97723679f5 100644 --- a/Frameworks/Foundation/NSSet.mm +++ b/Frameworks/Foundation/NSSet.mm @@ -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]; + } + } } } @@ -63,9 +93,11 @@ 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); @@ -73,21 +105,38 @@ void NSSetTableFree(NSSet* set) { } 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); @@ -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]; } diff --git a/build/Foundation/Foundation.Shared/Foundation.Shared.vcxitems b/build/Foundation/Foundation.Shared/Foundation.Shared.vcxitems index c3bf71e521..d9968d5314 100644 --- a/build/Foundation/Foundation.Shared/Foundation.Shared.vcxitems +++ b/build/Foundation/Foundation.Shared/Foundation.Shared.vcxitems @@ -31,6 +31,7 @@ + diff --git a/build/Foundation/Foundation.Shared/Foundation.def b/build/Foundation/Foundation.Shared/Foundation.def index 5976d74b30..1f92850188 100644 --- a/build/Foundation/Foundation.Shared/Foundation.def +++ b/build/Foundation/Foundation.Shared/Foundation.def @@ -1,138 +1,140 @@ LIBRARY Foundation EXPORTS - _OBJC_CLASS_CFConstantString CONSTANT - __objc_class_name_CFConstantString CONSTANT - _OBJC_CLASS_NSArray DATA - __objc_class_name_NSArray CONSTANT - _OBJC_CLASS_NSEnumerator DATA - __objc_class_name_NSEnumerator CONSTANT - _OBJC_CLASS_NSMutableArray DATA - __objc_class_name_NSMutableArray CONSTANT - _OBJC_CLASS_NSData DATA - __objc_class_name_NSData CONSTANT - _OBJC_CLASS_NSDictionary DATA - __objc_class_name_NSDictionary CONSTANT - _OBJC_CLASS_NSMutableDictionary DATA - __objc_class_name_NSMutableDictionary CONSTANT - _OBJC_CLASS_NSCharacterSet DATA - __objc_class_name_NSCharacterSet CONSTANT - _OBJC_CLASS_NSMutableCharacterSet DATA - __objc_class_name_NSMutableCharacterSet CONSTANT - _OBJC_CLASS_NSData DATA - __objc_class_name_NSData CONSTANT - _OBJC_CLASS_NSMutableData DATA - __objc_class_name_NSMutableData CONSTANT - _OBJC_CLASS_NSString DATA - __objc_class_name_NSString CONSTANT - _OBJC_CLASS_NSMutableString DATA - __objc_class_name_NSMutableString CONSTANT - _OBJC_CLASS_NSNumber DATA - __objc_class_name_NSNumber CONSTANT - _OBJC_CLASS_NSDecimalNumber DATA - __objc_class_name_NSDecimalNumber CONSTANT - _OBJC_CLASS_NSURL DATA - __objc_class_name_NSURL CONSTANT - _OBJC_CLASS_NSURLConnection DATA - __objc_class_name_NSURLConnection CONSTANT - _OBJC_CLASS_NSURLRequest DATA - __objc_class_name_NSURLRequest CONSTANT - _OBJC_CLASS_NSMutableURLRequest DATA - __objc_class_name_NSMutableURLRequest CONSTANT - _OBJC_CLASS_NSDate DATA - __objc_class_name_NSDate CONSTANT - _OBJC_CLASS_NSDateComponents DATA - __objc_class_name_NSDateComponents CONSTANT - _OBJC_CLASS_NSDateFormatter DATA - __objc_class_name_NSDateFormatter CONSTANT - _OBJC_CLASS_NSFileManager DATA - __objc_class_name_NSFileManager CONSTANT - _OBJC_CLASS_NSBundle DATA - __objc_class_name_NSBundle CONSTANT - _OBJC_CLASS_NSRunLoop DATA - __objc_class_name_NSRunLoop CONSTANT - _OBJC_CLASS_NSRunLoopSource DATA - __objc_class_name_NSRunLoopSource CONSTANT - _OBJC_CLASS_NSTimer DATA - __objc_class_name_NSTimer CONSTANT - _OBJC_CLASS_NSTimeZone DATA - __objc_class_name_NSTimeZone CONSTANT - _OBJC_CLASS_NSValue DATA - __objc_class_name_NSValue CONSTANT - _OBJC_CLASS_NSNull DATA - __objc_class_name_NSNull CONSTANT - _OBJC_CLASS_NSThread DATA - __objc_class_name_NSThread CONSTANT - _OBJC_CLASS_NSColor DATA - __objc_class_name_NSColor CONSTANT - _OBJC_CLASS_NSOperation DATA - __objc_class_name_NSOperation CONSTANT - _OBJC_CLASS_NSOperationQueue DATA - __objc_class_name_NSOperationQueue CONSTANT - _OBJC_CLASS_NSBlockOperation DATA - __objc_class_name_NSBlockOperation CONSTANT - _OBJC_CLASS_NSError DATA - __objc_class_name_NSError CONSTANT - _OBJC_CLASS_NSException DATA - __objc_class_name_NSException CONSTANT - _OBJC_CLASS_NSFormatter DATA - __objc_class_name_NSFormatter CONSTANT - _OBJC_CLASS_NSNotificationCenter DATA - __objc_class_name_NSNotificationCenter CONSTANT - _OBJC_CLASS_NSNotification DATA - __objc_class_name_NSNotification CONSTANT - _OBJC_CLASS_NSSet DATA - __objc_class_name_NSSet CONSTANT - _OBJC_CLASS_NSMutableSet DATA - __objc_class_name_NSMutableSet CONSTANT - _OBJC_CLASS_NSNib DATA - __objc_class_name_NSNib CONSTANT - _OBJC_CLASS_NSIndexPath DATA - __objc_class_name_NSIndexPath CONSTANT - _OBJC_CLASS_NSIndexSet DATA - __objc_class_name_NSIndexSet CONSTANT - _OBJC_CLASS_NSMutableIndexSet DATA - __objc_class_name_NSMutableIndexSet CONSTANT - _OBJC_CLASS_NSUserDefaults DATA - __objc_class_name_NSUserDefaults CONSTANT - _OBJC_CLASS_NSCalendar DATA - __objc_class_name_NSCalendar CONSTANT + _OBJC_CLASS_CFConstantString CONSTANT + __objc_class_name_CFConstantString CONSTANT + _OBJC_CLASS_NSArray DATA + __objc_class_name_NSArray CONSTANT + _OBJC_CLASS_NSEnumerator DATA + __objc_class_name_NSEnumerator CONSTANT + _OBJC_CLASS_NSMutableArray DATA + __objc_class_name_NSMutableArray CONSTANT + _OBJC_CLASS_NSData DATA + __objc_class_name_NSData CONSTANT + _OBJC_CLASS_NSDictionary DATA + __objc_class_name_NSDictionary CONSTANT + _OBJC_CLASS_NSMutableDictionary DATA + __objc_class_name_NSMutableDictionary CONSTANT + _OBJC_CLASS_NSCharacterSet DATA + __objc_class_name_NSCharacterSet CONSTANT + _OBJC_CLASS_NSMutableCharacterSet DATA + __objc_class_name_NSMutableCharacterSet CONSTANT + _OBJC_CLASS_NSData DATA + __objc_class_name_NSData CONSTANT + _OBJC_CLASS_NSMutableData DATA + __objc_class_name_NSMutableData CONSTANT + _OBJC_CLASS_NSString DATA + __objc_class_name_NSString CONSTANT + _OBJC_CLASS_NSMutableString DATA + __objc_class_name_NSMutableString CONSTANT + _OBJC_CLASS_NSNumber DATA + __objc_class_name_NSNumber CONSTANT + _OBJC_CLASS_NSDecimalNumber DATA + __objc_class_name_NSDecimalNumber CONSTANT + _OBJC_CLASS_NSURL DATA + __objc_class_name_NSURL CONSTANT + _OBJC_CLASS_NSURLConnection DATA + __objc_class_name_NSURLConnection CONSTANT + _OBJC_CLASS_NSURLRequest DATA + __objc_class_name_NSURLRequest CONSTANT + _OBJC_CLASS_NSMutableURLRequest DATA + __objc_class_name_NSMutableURLRequest CONSTANT + _OBJC_CLASS_NSDate DATA + __objc_class_name_NSDate CONSTANT + _OBJC_CLASS_NSDateComponents DATA + __objc_class_name_NSDateComponents CONSTANT + _OBJC_CLASS_NSDateFormatter DATA + __objc_class_name_NSDateFormatter CONSTANT + _OBJC_CLASS_NSFileManager DATA + __objc_class_name_NSFileManager CONSTANT + _OBJC_CLASS_NSBundle DATA + __objc_class_name_NSBundle CONSTANT + _OBJC_CLASS_NSRunLoop DATA + __objc_class_name_NSRunLoop CONSTANT + _OBJC_CLASS_NSRunLoopSource DATA + __objc_class_name_NSRunLoopSource CONSTANT + _OBJC_CLASS_NSTimer DATA + __objc_class_name_NSTimer CONSTANT + _OBJC_CLASS_NSTimeZone DATA + __objc_class_name_NSTimeZone CONSTANT + _OBJC_CLASS_NSValue DATA + __objc_class_name_NSValue CONSTANT + _OBJC_CLASS_NSNull DATA + __objc_class_name_NSNull CONSTANT + _OBJC_CLASS_NSThread DATA + __objc_class_name_NSThread CONSTANT + _OBJC_CLASS_NSColor DATA + __objc_class_name_NSColor CONSTANT + _OBJC_CLASS_NSOperation DATA + __objc_class_name_NSOperation CONSTANT + _OBJC_CLASS_NSOperationQueue DATA + __objc_class_name_NSOperationQueue CONSTANT + _OBJC_CLASS_NSBlockOperation DATA + __objc_class_name_NSBlockOperation CONSTANT + _OBJC_CLASS_NSError DATA + __objc_class_name_NSError CONSTANT + _OBJC_CLASS_NSException DATA + __objc_class_name_NSException CONSTANT + _OBJC_CLASS_NSFormatter DATA + __objc_class_name_NSFormatter CONSTANT + _OBJC_CLASS_NSNotificationCenter DATA + __objc_class_name_NSNotificationCenter CONSTANT + _OBJC_CLASS_NSNotification DATA + __objc_class_name_NSNotification CONSTANT + _OBJC_CLASS_NSSet DATA + __objc_class_name_NSSet CONSTANT + _OBJC_CLASS_NSMutableSet DATA + __objc_class_name_NSMutableSet CONSTANT + _OBJC_CLASS_NSNib DATA + __objc_class_name_NSNib CONSTANT + _OBJC_CLASS_NSIndexPath DATA + __objc_class_name_NSIndexPath CONSTANT + _OBJC_CLASS_NSIndexSet DATA + __objc_class_name_NSIndexSet CONSTANT + _OBJC_CLASS_NSMutableIndexSet DATA + __objc_class_name_NSMutableIndexSet CONSTANT + _OBJC_CLASS_NSUserDefaults DATA + __objc_class_name_NSUserDefaults CONSTANT + _OBJC_CLASS_NSCalendar DATA + __objc_class_name_NSCalendar CONSTANT _OBJC_CLASS_NSSortDescriptor DATA - __objc_class_name_NSSortDescriptor CONSTANT + __objc_class_name_NSSortDescriptor CONSTANT _OBJC_CLASS_NSInvocation DATA - __objc_class_name_NSInvocation CONSTANT + __objc_class_name_NSInvocation CONSTANT _OBJC_CLASS_NSInvocationOperation DATA - __objc_class_name_NSInvocationOperation CONSTANT + __objc_class_name_NSInvocationOperation CONSTANT _OBJC_CLASS_NSNumberFormatter DATA - __objc_class_name_NSNumberFormatter CONSTANT + __objc_class_name_NSNumberFormatter CONSTANT _OBJC_CLASS_NSHTTPCookie DATA - __objc_class_name_NSHTTPCookie CONSTANT + __objc_class_name_NSHTTPCookie CONSTANT _OBJC_CLASS_NSHTTPURLResponse DATA - __objc_class_name_NSHTTPURLResponse CONSTANT + __objc_class_name_NSHTTPURLResponse CONSTANT _OBJC_CLASS_NSLock DATA - __objc_class_name_NSLock CONSTANT + __objc_class_name_NSLock CONSTANT _OBJC_CLASS_NSConditionLock DATA - __objc_class_name_NSConditionLock CONSTANT + __objc_class_name_NSConditionLock CONSTANT _OBJC_CLASS_NSRecursiveLock DATA - __objc_class_name_NSRecursiveLock CONSTANT + __objc_class_name_NSRecursiveLock CONSTANT _OBJC_CLASS_NSCondition DATA - __objc_class_name_NSCondition CONSTANT + __objc_class_name_NSCondition CONSTANT _OBJC_CLASS_NSXMLParser DATA - __objc_class_name_NSXMLParser CONSTANT + __objc_class_name_NSXMLParser CONSTANT _OBJC_CLASS_NSScanner DATA - __objc_class_name_NSScanner CONSTANT + __objc_class_name_NSScanner CONSTANT _OBJC_CLASS_NSNetService DATA - __objc_class_name_NSNetService CONSTANT + __objc_class_name_NSNetService CONSTANT _OBJC_CLASS_NSJSONSerialization DATA - __objc_class_name_NSJSONSerialization CONSTANT + __objc_class_name_NSJSONSerialization CONSTANT _OBJC_CLASS_NSAssertionHandler DATA - __objc_class_name_NSAssertionHandler CONSTANT + __objc_class_name_NSAssertionHandler CONSTANT _OBJC_CLASS_NSKeyedArchiver DATA - __objc_class_name_NSKeyedArchiver CONSTANT + __objc_class_name_NSKeyedArchiver CONSTANT _OBJC_CLASS_NSKeyedUnarchiver DATA __objc_class_name_NSKeyedUnarchiver CONSTANT _OBJC_CLASS_NSPropertyListSerialization DATA __objc_class_name_NSPropertyListSerialization CONSTANT _OBJC_CLASS_NSLocale DATA - __objc_class_name_NSLocale CONSTANT + __objc_class_name_NSLocale CONSTANT _OBJC_CLASS_NSUUID DATA - __objc_class_name_NSUUID CONSTANT + __objc_class_name_NSUUID CONSTANT + _OBJC_CLASS_NSCountedSet DATA + __objc_class_name_NSCountedSet CONSTANT diff --git a/build/UnitTests/UnitTests.vcxproj b/build/UnitTests/UnitTests.vcxproj index a48ee8a5d6..32e7c52e43 100644 --- a/build/UnitTests/UnitTests.vcxproj +++ b/build/UnitTests/UnitTests.vcxproj @@ -184,6 +184,7 @@ + diff --git a/include/Foundation/NSCountedSet.h b/include/Foundation/NSCountedSet.h index c50ebac2f9..543dc82d66 100644 --- a/include/Foundation/NSCountedSet.h +++ b/include/Foundation/NSCountedSet.h @@ -1,18 +1,24 @@ -/* Copyright (c) 2006-2007 Christopher J. W. Lloyd - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -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. */ +//****************************************************************************** +// +// 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. +// +//****************************************************************************** #import -@interface NSCountedSet : NSMutableSet { - // what is this.. - //void *_table; -} +FOUNDATION_EXPORT_CLASS +@interface NSCountedSet : NSMutableSet --(NSUInteger)countForObject:object; +- (NSUInteger)countForObject:(id)object; @end diff --git a/include/Foundation/NSException.h b/include/Foundation/NSException.h index 566cefda9d..d6e63277e4 100644 --- a/include/Foundation/NSException.h +++ b/include/Foundation/NSException.h @@ -1,10 +1,16 @@ /* Copyright (c) 2006-2007 Christopher J. W. Lloyd -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the +following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -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. */ +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. */ #ifndef _NSEXCEPTION_H_ #define _NSEXCEPTION_H_ @@ -12,93 +18,90 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #import #import -@class NSDictionary,NSArray; - -FOUNDATION_EXPORT NSString * const NSGenericException; -FOUNDATION_EXPORT NSString * const NSInvalidArgumentException; -FOUNDATION_EXPORT NSString * const NSRangeException; - -FOUNDATION_EXPORT NSString * const NSInternalInconsistencyException; -FOUNDATION_EXPORT NSString * const NSMallocException; - -FOUNDATION_EXPORT NSString * const NSParseErrorException; -FOUNDATION_EXPORT NSString * const NSInconsistentArchiveException; - -FOUNDATION_EXPORT NSString * const NSGenericException; -FOUNDATION_EXPORT NSString * const NSRangeException; -FOUNDATION_EXPORT NSString * const NSInvalidArgumentException; -FOUNDATION_EXPORT NSString * const NSInternalInconsistencyException; -FOUNDATION_EXPORT NSString * const NSMallocException; -FOUNDATION_EXPORT NSString * const NSObjectInaccessibleException; -FOUNDATION_EXPORT NSString * const NSObjectNotAvailableException; -FOUNDATION_EXPORT NSString * const NSDestinationInvalidException; -FOUNDATION_EXPORT NSString * const NSPortTimeoutException; -FOUNDATION_EXPORT NSString * const NSInvalidSendPortException; -FOUNDATION_EXPORT NSString * const NSInvalidReceivePortException; -FOUNDATION_EXPORT NSString * const NSPortSendException; -FOUNDATION_EXPORT NSString * const NSPortReceiveException; -FOUNDATION_EXPORT NSString * const NSOldStyleException; +@class NSDictionary, NSArray; + +FOUNDATION_EXPORT NSString* const NSGenericException; +FOUNDATION_EXPORT NSString* const NSRangeException; +FOUNDATION_EXPORT NSString* const NSInvalidArgumentException; +FOUNDATION_EXPORT NSString* const NSInternalInconsistencyException; +FOUNDATION_EXPORT NSString* const NSMallocException; +FOUNDATION_EXPORT NSString* const NSObjectInaccessibleException; +FOUNDATION_EXPORT NSString* const NSObjectNotAvailableException; +FOUNDATION_EXPORT NSString* const NSDestinationInvalidException; +FOUNDATION_EXPORT NSString* const NSPortTimeoutException; +FOUNDATION_EXPORT NSString* const NSInvalidSendPortException; +FOUNDATION_EXPORT NSString* const NSInvalidReceivePortException; +FOUNDATION_EXPORT NSString* const NSPortSendException; +FOUNDATION_EXPORT NSString* const NSPortReceiveException; +FOUNDATION_EXPORT NSString* const NSParseErrorException; +FOUNDATION_EXPORT NSString* const NSInconsistentArchiveException; +FOUNDATION_EXPORT NSString* const NSOldStyleException; +FOUNDATION_EXPORT NSString* const NSOverflowException; FOUNDATION_EXPORT_CLASS -@interface NSException:NSObject +@interface NSException : NSObject -+(void)raise:(NSString *)name format:(NSString *)format,...; -+(void)raise:(NSString *)name format:(NSString *)format arguments:(va_list)arguments; ++ (void)raise:(NSString*)name format:(NSString*)format, ...; ++ (void)raise:(NSString*)name format:(NSString*)format arguments:(va_list)arguments; --initWithName:(NSString *)name reason:(NSString *)reason userInfo:(NSDictionary *)userInfo; +- initWithName:(NSString*)name reason:(NSString*)reason userInfo:(NSDictionary*)userInfo; -+(NSException *)exceptionWithName:(NSString *)name reason:(NSString *)reason userInfo:(NSDictionary *)userInfo; ++ (NSException*)exceptionWithName:(NSString*)name reason:(NSString*)reason userInfo:(NSDictionary*)userInfo; --(void)raise; +- (void)raise; --(NSString *)name; --(NSString *)reason; --(NSDictionary *)userInfo; +- (NSString*)name; +- (NSString*)reason; +- (NSDictionary*)userInfo; --(NSArray *)callStackReturnAddresses; +- (NSArray*)callStackReturnAddresses; @end -@interface NSException(WinObjC) -+ (void)raiseWithLogging:(NSString *)name format : (NSString *)format, ...; +@interface NSException (WinObjC) ++ (void)raiseWithLogging:(NSString*)name format:(NSString*)format, ...; @end -typedef void NSUncaughtExceptionHandler(NSException *exception); +typedef void NSUncaughtExceptionHandler(NSException* exception); -FOUNDATION_EXPORT NSUncaughtExceptionHandler *NSGetUncaughtExceptionHandler(void); -FOUNDATION_EXPORT void NSSetUncaughtExceptionHandler(NSUncaughtExceptionHandler *); +FOUNDATION_EXPORT NSUncaughtExceptionHandler* NSGetUncaughtExceptionHandler(void); +FOUNDATION_EXPORT void NSSetUncaughtExceptionHandler(NSUncaughtExceptionHandler*); typedef struct NSExceptionFrame { - jmp_buf state; - struct NSExceptionFrame *parent; - __unsafe_unretained NSException *exception; + jmp_buf state; + struct NSExceptionFrame* parent; + __unsafe_unretained NSException* exception; } NSExceptionFrame; -FOUNDATION_EXPORT void __NSPushExceptionFrame(NSExceptionFrame *frame); -FOUNDATION_EXPORT void __NSPopExceptionFrame(NSExceptionFrame *frame); +FOUNDATION_EXPORT void __NSPushExceptionFrame(NSExceptionFrame* frame); +FOUNDATION_EXPORT void __NSPopExceptionFrame(NSExceptionFrame* frame); -#define NS_DURING \ - { \ - NSExceptionFrame __exceptionFrame; \ - __NSPushExceptionFrame(&__exceptionFrame); \ - if(setjmp(__exceptionFrame.state)==0){ - -#define NS_HANDLER \ +#define NS_DURING \ + { \ + NSExceptionFrame __exceptionFrame; \ + __NSPushExceptionFrame(&__exceptionFrame); \ + if (setjmp(__exceptionFrame.state) == 0) { +#define NS_HANDLER \ __NSPopExceptionFrame(&__exceptionFrame); \ - } \ - else{ \ - NSException *localException=__exceptionFrame.exception; + } \ + else { \ + NSException* localException = __exceptionFrame.exception; #define NS_ENDHANDLER \ - } \ - } - -#define NS_VALUERETURN(val,type) \ - { __NSPopExceptionFrame(&__exceptionFrame); return val; } - -#define NS_VOIDRETURN \ - { __NSPopExceptionFrame(&__exceptionFrame); return; } - + } \ + } + +#define NS_VALUERETURN(val, type) \ + { \ + __NSPopExceptionFrame(&__exceptionFrame); \ + return val; \ + } + +#define NS_VOIDRETURN \ + { \ + __NSPopExceptionFrame(&__exceptionFrame); \ + return; \ + } #import diff --git a/tests/unittests/foundation_NSCountedSet.mm b/tests/unittests/foundation_NSCountedSet.mm new file mode 100644 index 0000000000..b248281ffc --- /dev/null +++ b/tests/unittests/foundation_NSCountedSet.mm @@ -0,0 +1,125 @@ +//****************************************************************************** +// +// 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 "gtest-api.h" +#import + +TEST(Foundation, NSCountedSet_SanityTest) { + LOG_INFO("NSCountedSet sanity test: "); + + LOG_INFO("Basic set compare test"); + + NSCountedSet* countedSet1 = [[NSCountedSet alloc] initWithCapacity:2]; + [countedSet1 addObject:@1]; + [countedSet1 addObject:@2]; + NSSet* countedSet2 = [NSCountedSet setWithObjects:@1, @2, nil]; + + ASSERT_TRUE_MSG([countedSet1 isEqualToSet:countedSet2], "FAILED: countedSet1 and countedSet2 should be equal!\n"); + + [countedSet1 release]; + [countedSet2 release]; + + LOG_INFO("Basic count test"); + + NSCountedSet* carSet = [NSCountedSet setWithObjects:@"Honda Civic", @"Nissan Versa", @"BMW M1", nil]; + NSUInteger carCount = [carSet countForObject:@"BMW M1"]; + ASSERT_EQ_MSG(1, carCount, "FAILED: carCount should be 1!\n"); + + carCount = [carSet countForObject:@"AUDI Q5"]; + ASSERT_EQ_MSG(0, carCount, "FAILED: carCount should be 0!\n"); + + [carSet release]; +} + +TEST(Foundation, NSCountedSet_AddToSetTest) { + LOG_INFO("NSCountedSet add to set test: "); + + NSCountedSet* colorSet = [[NSCountedSet alloc] initWithCapacity:1]; + [colorSet addObject:@"Red"]; + [colorSet addObject:@"Blue"]; + [colorSet addObject:@"Green"]; + + NSUInteger redColorCount = [colorSet countForObject:@"Red"]; + ASSERT_EQ_MSG(1, redColorCount, "FAILED: redColorCount should be 1!\n"); + NSUInteger blueColorCount = [colorSet countForObject:@"Blue"]; + ASSERT_EQ_MSG(1, blueColorCount, "FAILED: blueColorCount should be 1!\n"); + NSUInteger greenColorCount = [colorSet countForObject:@"Green"]; + ASSERT_EQ_MSG(1, greenColorCount, "FAILED: greenColorCount should be 1!\n"); + + [colorSet addObjectsFromArray:@[ @"Blue", @"Blue", @"Red" ]]; + + redColorCount = [colorSet countForObject:@"Red"]; + ASSERT_EQ_MSG(2, redColorCount, "FAILED: redColorCount should be 2!\n"); + blueColorCount = [colorSet countForObject:@"Blue"]; + ASSERT_EQ_MSG(3, blueColorCount, "FAILED: blueColorCount should be 3!\n"); + greenColorCount = [colorSet countForObject:@"Green"]; + ASSERT_EQ_MSG(1, greenColorCount, "FAILED: greenColorCount should be 1!\n"); + + [colorSet addObject:@"Green"]; + [colorSet addObject:@"Green"]; + [colorSet addObject:@"Green"]; + + redColorCount = [colorSet countForObject:@"Red"]; + ASSERT_EQ_MSG(2, redColorCount, "FAILED: redColorCount should be 2!\n"); + blueColorCount = [colorSet countForObject:@"Blue"]; + ASSERT_EQ_MSG(3, blueColorCount, "FAILED: blueColorCount should be 3!\n"); + greenColorCount = [colorSet countForObject:@"Green"]; + ASSERT_EQ_MSG(4, greenColorCount, "FAILED: greenColorCount should be 4!\n"); + + [colorSet release]; +} + +TEST(Foundation, NSCountedSet_RemoveFromSetTest) { + LOG_INFO("NSCountedSet remove from set test: "); + + NSCountedSet* shapeSet = [[NSCountedSet alloc] initWithCapacity:5]; + + NSUInteger squareShapeCount = [shapeSet countForObject:@"Square"]; + ASSERT_EQ_MSG(0, squareShapeCount, "FAILED: squareShapeCount should be 0!\n"); + NSUInteger roundShapeCount = [shapeSet countForObject:@"Round"]; + ASSERT_EQ_MSG(0, roundShapeCount, "FAILED: roundShapeCount should be 0!\n"); + + [shapeSet addObjectsFromArray:@[ @"Square", @"Round" ]]; + + squareShapeCount = [shapeSet countForObject:@"Square"]; + ASSERT_EQ_MSG(1, squareShapeCount, "FAILED: squareShapeCount should be 1!\n"); + roundShapeCount = [shapeSet countForObject:@"Round"]; + ASSERT_EQ_MSG(1, roundShapeCount, "FAILED: roundShapeCount should be 1!\n"); + + [shapeSet addObjectsFromArray:@[ @"Square", @"Round", @"Square", @"Square" ]]; + + squareShapeCount = [shapeSet countForObject:@"Square"]; + ASSERT_EQ_MSG(4, squareShapeCount, "FAILED: squareShapeCount should be 4!\n"); + roundShapeCount = [shapeSet countForObject:@"Round"]; + ASSERT_EQ_MSG(2, roundShapeCount, "FAILED: roundShapeCount should be 2!\n"); + + [shapeSet removeObject:@"Square"]; + [shapeSet removeObject:@"Square"]; + + squareShapeCount = [shapeSet countForObject:@"Square"]; + ASSERT_EQ_MSG(2, squareShapeCount, "FAILED: squareShapeCount should be 2!\n"); + roundShapeCount = [shapeSet countForObject:@"Round"]; + ASSERT_EQ_MSG(2, roundShapeCount, "FAILED: roundShapeCount should be 2!\n"); + + [shapeSet removeAllObjects]; + + squareShapeCount = [shapeSet countForObject:@"Square"]; + ASSERT_EQ_MSG(0, squareShapeCount, "FAILED: squareShapeCount should be 0!\n"); + roundShapeCount = [shapeSet countForObject:@"Round"]; + ASSERT_EQ_MSG(0, roundShapeCount, "FAILED: roundShapeCount should be 0!\n"); + + [shapeSet release]; +} \ No newline at end of file