From 8c7be80b924c0df33e4b7dda6dcae4eca1c831aa Mon Sep 17 00:00:00 2001 From: Lubos Dolezel Date: Tue, 28 Feb 2017 17:47:32 +0100 Subject: [PATCH] Foundation building. Networking related classes are excluded until we have CFNetwork --- CMakeLists.txt | 226 +++ include/Foundation/NSAutoreleasePool.h | 3 + include/Foundation/NSBundle.h | 9 + include/Foundation/NSByteCountFormatter.h | 10 + include/Foundation/NSCache.h | 3 + include/Foundation/NSComparisonPredicate.h | 7 + include/Foundation/NSCompoundPredicate.h | 5 + include/Foundation/NSData.h | 19 + include/Foundation/NSDateFormatter.h | 4 + include/Foundation/NSFileManager.h | 21 + include/Foundation/NSGeometry.h | 23 +- include/Foundation/NSHTTPCookie.h | 5 + include/Foundation/NSHTTPCookieStorage.h | 6 + include/Foundation/NSHashTable.h | 277 +++- include/Foundation/NSIndexPath.h | 5 + include/Foundation/NSIndexSet.h | 22 + include/Foundation/NSInvocation.h | 160 +- include/Foundation/NSKeyedArchiver.h | 45 +- include/Foundation/NSLock.h | 32 + include/Foundation/NSMapTable.h | 357 +++- include/Foundation/NSNetServices.h | 14 + include/Foundation/NSNotification.h | 7 +- include/Foundation/NSNotificationQueue.h | 9 +- include/Foundation/NSNumberFormatter.h | 6 + include/Foundation/NSOperation.h | 31 + include/Foundation/NSPointerArray.h | 38 + include/Foundation/NSPointerFunctions.h | 1 + include/Foundation/NSPort.h | 6 + include/Foundation/NSPredicate.h | 8 + include/Foundation/NSProcessInfo.h | 7 + include/Foundation/NSRegularExpression.h | 3 + include/Foundation/NSSet.h | 5 + include/Foundation/NSSortDescriptor.h | 6 + include/Foundation/NSThread.h | 24 +- .../Foundation/NSURLAuthenticationChallenge.h | 8 + include/Foundation/NSURLCache.h | 11 + include/Foundation/NSURLConnection.h | 5 + include/Foundation/NSURLProtectionSpace.h | 5 + include/Foundation/NSURLProtocol.h | 5 + include/Foundation/NSURLRequest.h | 5 + include/Foundation/NSURLResponse.h | 10 + .../Foundation/NSUbiquitousKeyValueStore.h | 7 + include/Foundation/NSUserDefaults.h | 11 + include/Foundation/NSXMLParser.h | 7 + src/GSIMap.h | 1270 ++++++++++++++ src/GSPrivate.h | 61 + src/GSUnion.h | 99 ++ src/NSAffineTransform.m | 2 + src/NSAggregateExpression.m | 3 - src/NSArchiver.h | 8 + src/NSArchiver.m | 7 +- src/NSArray.m | 1 + src/NSAttributedString.m | 6 +- src/NSAutoreleasePool.m | 14 +- src/NSBlockExpression.m | 4 - src/NSBlockPredicate.m | 4 +- src/NSBundle.m | 10 +- src/NSByteCountFormatter.m | 11 +- src/NSCalendar.m | 9 +- src/NSCalendarInternal.h | 8 + src/NSCallBacks.h | 94 ++ src/NSCallBacks.m | 239 +++ src/NSClassDescription.m | 6 +- src/NSCoder.m | 13 +- src/NSCoderInternal.h | 9 +- src/NSComparisonPredicate.m | 6 - src/NSComparisonPredicateOperator.h | 4 + src/NSComparisonPredicateOperator.m | 4 - src/NSCompoundPredicate.m | 5 - src/NSConcreteHashTable.m | 1108 +++++++++++++ src/NSConcreteHashTableInternal.h | 232 +++ src/NSConcreteMapTable.m | 1477 +++++++++++++++++ src/NSConstantValueExpression.m | 3 - src/NSCustomPredicateOperator.h | 3 + src/NSCustomPredicateOperator.m | 3 - src/NSData.m | 88 +- src/NSDataDetector.m | 8 +- src/NSDateFormatter.m | 4 - src/NSDecimal.m | 6 +- src/NSDecimalNumber.m | 3 + src/NSDictionary.m | 1 + src/NSEqualityPredicateOperator.h | 4 + src/NSEqualityPredicateOperator.m | 4 - src/NSException.m | 11 +- src/NSExpressionInternal.h | 45 + src/NSExternals.h | 5 + src/NSExternals.m | 24 +- src/NSFileAttributes.h | 15 + src/NSFileAttributes.m | 21 +- src/NSFileHandle.m | 36 +- src/NSFileManager.m | 30 +- src/NSFilesystemItemRemoveOperation.h | 7 + src/NSFilesystemItemRemoveOperation.m | 18 +- src/NSFunctionExpression.m | 5 - src/NSGeometry.m | 7 +- src/NSHTTPCookie.m | 4 +- src/NSHTTPCookieStorage.m | 5 +- src/NSHashTable.m | 1343 +++------------ src/NSHost.m | 15 +- src/NSInPredicateOperator.h | 7 + src/NSInPredicateOperator.m | 5 - src/NSIndexPath.m | 6 +- src/NSIndexSet.m | 25 +- src/NSJSONSerialization.m | 38 +- src/NSKeyPathSpecifierExpression.m | 3 - src/NSKeyValueAccessor.m | 39 +- src/NSKeyValueCollectionProxies.h | 138 ++ src/NSKeyValueCollectionProxies.m | 138 -- src/NSKeyValueComputedProperty.h | 10 + src/NSKeyValueComputedProperty.m | 11 +- src/NSKeyValueNestedProperty.h | 17 + src/NSKeyValueNestedProperty.m | 17 +- src/NSKeyValueObservance.h | 10 + src/NSKeyValueObservance.m | 8 + src/NSKeyValueObservationInfo.h | 5 +- src/NSKeyValueObservationInfo.m | 3 - src/NSKeyValueObserving.m | 27 +- src/NSKeyedArchiver.m | 20 +- src/NSKeyedUnarchiver.m | 21 +- src/NSLocale.m | 7 +- src/NSLocaleInternal.h | 4 +- src/NSLock.m | 34 +- src/NSMapTable.m | 346 ++-- src/NSMatchingPredicateOperator.h | 4 + src/NSMatchingPredicateOperator.m | 4 - ...bleStringProxyForMutableAttributedString.m | 3 - ...gProxyForMutableAttributedStringInternal.h | 3 + src/NSNetServices.m | 13 +- src/NSNotification.m | 7 +- src/NSNotificationCenter.m | 20 +- src/NSNotificationInternal.h | 6 + src/NSNotificationQueue.m | 8 +- src/NSNumberFormatter.m | 5 +- src/NSObjCRuntime.m | 4 +- src/NSObjectInternal.h | 7 + src/NSObjectInternal.m | 12 +- src/NSOperation.m | 31 +- src/NSOrthography.m | 41 +- src/NSPlatform.m | 5 +- src/NSPointerArray.m | 9 +- src/NSPointerFunctionsInternal.h | 29 +- src/NSPort.m | 7 +- src/NSPredicate.m | 4 - src/NSPredicateInternal.h | 7 +- src/NSPredicateOperator.h | 4 + src/NSPredicateOperator.m | 4 - src/NSPredicateParser.tab.c | 8 +- src/NSProcessInfo.m | 8 +- src/NSRegularExpressionCheckingResult.h | 14 + src/NSRegularExpressionCheckingResult.m | 16 +- src/NSScanner.m | 6 + src/NSSet.m | 6 +- src/NSSetExpression.m | 4 - src/NSSortDescriptor.m | 7 +- src/NSStringPredicateOperator.h | 3 + src/NSStringPredicateOperator.m | 3 - src/NSSubqueryExpression.m | 5 - src/NSSubstringPredicateOperator.h | 3 + src/NSSubstringPredicateOperator.m | 3 - src/NSSymbolicExpression.m | 3 - src/NSTernaryExpression.m | 5 - src/NSThread.m | 37 +- src/NSURL.m | 32 +- src/NSURLAuthenticationChallenge.m | 8 - src/NSURLCache.m | 9 +- src/NSURLConnection.m | 4 +- src/NSURLProtectionSpace.m | 4 +- src/NSURLProtocol.m | 5 - src/NSURLRequest.m | 4 +- src/NSURLResponse.m | 8 +- src/NSURLSession.m | 5 +- src/NSUbiquitousKeyValueStore.m | 5 +- src/NSUserDefaults.m | 9 +- src/NSValue.m | 17 + src/NSValueInternal.h | 1 + src/NSVariableAssignmentExpression.m | 4 - src/NSVariableExpression.m | 4 - src/NSXMLParser.m | 7 +- src/_NSFileIO.m | 1 - src/_NSKeyedCoderOldStyleArray.m | 7 - src/common.h | 2 + src/stub.m | 16 + src/utlist.h | 775 +++++++++ 183 files changed, 7871 insertions(+), 2273 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 src/GSIMap.h create mode 100644 src/GSPrivate.h create mode 100644 src/GSUnion.h create mode 100644 src/NSCallBacks.h create mode 100644 src/NSCallBacks.m create mode 100644 src/NSConcreteHashTable.m create mode 100644 src/NSConcreteHashTableInternal.h create mode 100644 src/NSConcreteMapTable.m create mode 100644 src/common.h create mode 100644 src/stub.m create mode 100644 src/utlist.h diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..7b5f687a8 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,226 @@ +project(foundation) + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdinc -mmacosx-version-min=10.10 \ + -include ${CMAKE_SOURCE_DIR}/src/external/corefoundation/CoreFoundation_Prefix.h \ + -include ${CMAKE_SOURCE_DIR}/src/external/corefoundation/macros.h") + +include(darling_framework) + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/include/Foundation + ${CMAKE_CURRENT_SOURCE_DIR}/src + ${CMAKE_SOURCE_DIR}/src/external/corefoundation + ${CMAKE_SOURCE_DIR}/src/external/objc4/runtime + ${CMAKE_SOURCE_DIR}/src/external/libclosure + ${CMAKE_SOURCE_DIR}/src/external/security/include + ${CMAKE_SOURCE_DIR}/src/external/cfnetwork/include + ${CMAKE_SOURCE_DIR}/src/external/cfnetwork/private_include + ${CMAKE_SOURCE_DIR}/src/external/coregraphics/Headers + ${CMAKE_SOURCE_DIR}/src/launchd/liblaunch + ${CMAKE_SOURCE_DIR}/src/libmalloc/include + ${CMAKE_SOURCE_DIR}/src/copyfile + ${CMAKE_SOURCE_DIR}/src/libc/gen + ${CMAKE_SOURCE_DIR}/src/external/icu/icuSources/i18n + ${CMAKE_SOURCE_DIR}/src/external/icu/icuSources/common + ${CMAKE_SOURCE_DIR}/src/external/libxml2/include + ${CMAKE_BINARY_DIR}/src/external/libxml2/include +) + +add_definitions( + -DNSBUILDINGFOUNDATION=1 + -DINCLUDE_OBJC + -DDEPLOYMENT_TARGET_MACOSX=1 + -D__CONSTANT_CFSTRINGS__=1 + -D__CONSTANT_STRINGS__=1 +) + +set(foundation_sources + src/_DebugUtils.m + src/NSAddressCheckingResult.m + src/NSAffineTransform.m + src/NSAggregateExpression.m + src/NSAnyKeyExpression.m + src/NSArchiver.m + src/NSArray.m + src/NSAttributedString.m + src/NSAutoreleasePool.m + src/NSBetweenPredicateOperator.m + src/NSBlockExpression.m + src/NSBlockPredicate.m + src/NSBOMEncoding.m + src/NSBundle.m + src/NSByteCountFormatter.m + src/NSCalendar.m + src/NSClassDescription.m + src/NSCoder.m + src/NSComparisonPredicate.m + src/NSComparisonPredicateOperator.m + src/NSCompoundPredicate.m + src/NSCompoundPredicateOperator.m + src/NSConstantValueExpression.m + src/NSCustomPredicateOperator.m + src/NSDataDetector.m + src/NSData.m + src/NSDateFormatter.m + src/NSDateCheckingResult.m + src/NSDate.m + src/NSDecimal.m + src/NSDecimalNumber.m + src/NSDictionary.m + src/NSDirectoryEnumerator.m + src/NSEqualityPredicateOperator.m + src/NSException.m + src/NSExpression.m + src/NSExternals.m + src/NSFalsePredicate.m + src/NSFileAttributes.m + src/NSFileCoordinator.m + src/NSFileHandle.m + src/_NSFileIO.m + src/NSFileManager.m + src/NSFilesystemItemRemoveOperation.m + src/NSFormatter.m + src/NSFunctionExpression.m + src/NSGeometry.m + src/NSGrammarCheckingResult.m + src/NSHashTable.m + src/NSHost.m + #src/NSHTTPCookie.m + #src/NSHTTPCookieStorage.m + src/NSIndexPath.m + src/NSIndexSet.m + src/NSInPredicateOperator.m + src/NSJSONSerialization.m + src/NSKeyedArchiver.m + src/_NSKeyedCoderOldStyleArray.m + src/NSKeyedUnarchiver.m + src/NSKeyPathExpression.m + src/NSKeyPathSpecifierExpression.m + src/NSKeyValueAccessor.m + src/NSKeyValueCodingInternal.m + src/NSKeyValueCoding.m + src/NSKeyValueCollectionProxies.m + src/NSKeyValueComputedProperty.m + src/NSKeyValueContainerClass.m + src/NSKeyValueChangeDictionary.m + src/NSKeyValueNestedProperty.m + src/NSKeyValueObservance.m + src/NSKeyValueObservationInfo.m + src/NSKeyValueObserving.m + src/NSKeyValueProperty.m + src/NSKeyValueUnnestedProperty.m + src/NSLikePredicateOperator.m + src/NSLinkCheckingResult.m + src/NSLocale.m + src/NSLocalizableString.m + src/NSLock.m + src/NSLog.m + src/NSMapTable.m + src/NSMatchingPredicateOperator.m + #src/NSMutableStringProxyForMutableAttributedString.m # duplicate?! + src/NSNestedDictionary.m + #src/NSNetServices.m + src/NSNotificationCenter.m + src/NSNotification.m + src/NSNotificationQueue.m + src/NSNumberFormatter.m + src/NSNumber.m + src/NSObjCRuntime.m + src/NSObjectInternal.m + src/NSOperation.m + src/NSOrthographyCheckingResult.m + src/NSOrthography.m + src/NSPathStore.m + src/NSPathUtilities.m + src/NSPhoneNumberCheckingResult.m + src/NSPlatform.m + src/NSPointerArray.m + src/NSPointerFunctions.m + src/NSPort.m + src/NSPredicateLexer.m + src/NSPredicate.m + src/NSPredicateOperator.m + src/NSPredicateParser.tab.c + src/_NSPredicateOperatorUtilities.m + src/_NSPredicateUtilities.m + src/NSProcessInfo.m + src/NSProgress.m + src/NSProxy.m + src/NSRange.m + src/NSRegularExpressionCheckingResult.m + src/NSRegularExpression.m + src/NSRunLoop.m + src/NSRunLoopModes.m + src/NSScanner.m + src/NSSelfExpression.m + src/NSSetExpression.m + src/NSSet.m + src/NSSortDescriptor.m + src/NSSpellCheckingResult.m + src/NSString.m + src/NSStringPredicateOperator.m + src/NSSubqueryExpression.m + src/NSSubstitutionCheckingResult.m + src/NSSubstringPredicateOperator.m + src/NSSymbolicExpression.m + src/NSTernaryExpression.m + src/NSTextCheckingResult.m + src/NSThread.m + src/NSTimer.m + src/NSTimeZone.m + src/NSTokenMatchingPredicateOperator.m + src/NSTransitInformationCheckingResult.m + src/NSTruePredicate.m + src/NSUbiquitousKeyValueStore.m + #src/NSURLAuthenticationChallenge.m + #src/NSURLCache.m + #src/NSURLConnection.m + #src/NSURLCredential.m + #src/NSURLCredentialStorage.m + src/NSURLError.m + # src/NSURLHandle.m # deprecated since 10.4, from GNUstep + src/NSURL.m + #src/NSURLProtectionSpace.m + #src/NSURLProtocol.m + #src/NSURLRequest.m + #src/NSURLResponse.m + #src/NSURLSession.m + src/NSUserDefaults.m + src/NSUUID.m + src/NSValue.m + src/NSValueTransformer.m + src/NSVariableAssignmentExpression.m + src/NSVariableExpression.m + src/NSXMLDocument.m + src/NSXMLDTD.m + src/NSXMLDTDNode.m + src/NSXMLElement.m + src/NSXMLNode.m + src/NSXMLParser.m + src/NSXPCCoder.m + src/NSZone.m + + src/NSConcreteHashTable.m + src/NSConcreteMapTable.m + src/NSCallBacks.m + src/stub.m +) + +# Includes ObjC headers -> must be compiled as ObjC +set_source_files_properties(src/NSPredicateParser.tab.c PROPERTIES COMPILE_FLAGS "-x objective-c -fblocks") + +add_framework(Foundation + FAT + CURRENT_VERSION + SOURCES + ${foundation_sources} + VERSION "A" + DEPENDENCIES + objc + system + CoreFoundation + #CFNetwork + xml2 +) + diff --git a/include/Foundation/NSAutoreleasePool.h b/include/Foundation/NSAutoreleasePool.h index 416865b2f..5ec52ab86 100644 --- a/include/Foundation/NSAutoreleasePool.h +++ b/include/Foundation/NSAutoreleasePool.h @@ -2,6 +2,9 @@ NS_AUTOMATED_REFCOUNT_UNAVAILABLE @interface NSAutoreleasePool : NSObject +{ + void *context; +} + (void)addObject:(id)anObject; - (void)addObject:(id)anObject; diff --git a/include/Foundation/NSBundle.h b/include/Foundation/NSBundle.h index 426bbb36e..6f9ae773e 100644 --- a/include/Foundation/NSBundle.h +++ b/include/Foundation/NSBundle.h @@ -6,10 +6,19 @@ enum { NSBundleExecutableArchitectureX86_64 = 0x01000007, NSBundleExecutableArchitecturePPC64 = 0x01000012 }; +typedef enum { + NSBundleIsLoadedFlag = 0x01, +} NSBundleFlags; +typedef struct __CFBundle *CFBundleRef; @class NSArray, NSDictionary, NSString, NSURL, NSError; @interface NSBundle : NSObject +{ + NSBundleFlags _flags; + CFBundleRef _cfBundle; + Class _principalClass; +} + (NSBundle *)mainBundle; + (NSBundle *)bundleWithPath:(NSString *)path; diff --git a/include/Foundation/NSByteCountFormatter.h b/include/Foundation/NSByteCountFormatter.h index 0878de340..1c5fe5e00 100644 --- a/include/Foundation/NSByteCountFormatter.h +++ b/include/Foundation/NSByteCountFormatter.h @@ -23,6 +23,16 @@ typedef NS_ENUM(NSInteger, NSByteCountFormatterCountStyle) { }; @interface NSByteCountFormatter : NSFormatter +{ + NSByteCountFormatterUnits _allowedUnits; + char _countStyle; + BOOL _allowsNonnumericFormatting; + BOOL _includesUnit; + BOOL _includesCount; + BOOL _includesActualByteCount; + BOOL _adaptive; + BOOL _zeroPadsFractionDigits; +} @property NSByteCountFormatterUnits allowedUnits; @property NSByteCountFormatterCountStyle countStyle; diff --git a/include/Foundation/NSCache.h b/include/Foundation/NSCache.h index d9478dac4..e48bb3844 100644 --- a/include/Foundation/NSCache.h +++ b/include/Foundation/NSCache.h @@ -1,5 +1,6 @@ #import #import +#import @class NSString, NSCache; @@ -8,6 +9,8 @@ - (void)cache:(NSCache *)cache willEvictObject:(id)obj; @end +typedef struct __CFDictionary* CFMutableDictionaryRef; + @interface NSCache : NSObject { CFMutableDictionaryRef _objects; NSMutableSet *_discardableObjects; diff --git a/include/Foundation/NSComparisonPredicate.h b/include/Foundation/NSComparisonPredicate.h index 3a722ebf5..e1abcf27e 100644 --- a/include/Foundation/NSComparisonPredicate.h +++ b/include/Foundation/NSComparisonPredicate.h @@ -31,8 +31,15 @@ typedef NS_ENUM(NSUInteger, NSPredicateOperatorType) { }; @class NSExpression; +@class NSPredicateOperator; @interface NSComparisonPredicate : NSPredicate +{ + void *_reserved2; + NSPredicateOperator *_predicateOperator; + NSExpression *_lhs; + NSExpression *_rhs; +} + (NSPredicate *)predicateWithLeftExpression:(NSExpression *)lhs rightExpression:(NSExpression *)rhs modifier:(NSComparisonPredicateModifier)modifier type:(NSPredicateOperatorType)type options:(NSComparisonPredicateOptions)options; + (NSPredicate *)predicateWithLeftExpression:(NSExpression *)lhs rightExpression:(NSExpression *)rhs customSelector:(SEL)selector; diff --git a/include/Foundation/NSCompoundPredicate.h b/include/Foundation/NSCompoundPredicate.h index 4bcf14441..30a4bc92e 100644 --- a/include/Foundation/NSCompoundPredicate.h +++ b/include/Foundation/NSCompoundPredicate.h @@ -10,6 +10,11 @@ typedef NS_ENUM(NSUInteger, NSCompoundPredicateType) { }; @interface NSCompoundPredicate : NSPredicate +{ + void *_reserved2; + NSCompoundPredicateType _type; + NSArray *_subpredicates; +} + (NSPredicate *)andPredicateWithSubpredicates:(NSArray *)subpredicates; + (NSPredicate *)orPredicateWithSubpredicates:(NSArray *)subpredicates; diff --git a/include/Foundation/NSData.h b/include/Foundation/NSData.h index b8bde47ee..e897be356 100644 --- a/include/Foundation/NSData.h +++ b/include/Foundation/NSData.h @@ -130,5 +130,24 @@ typedef NS_OPTIONS(NSUInteger, NSDataBase64DecodingOptions) { @end +typedef enum { + NSPurgeableDataStorageMapped = 0x1, + NSPurgeableDataStorageAvailable = 0x2, + NSPurgeableDataStorageStored = 0x4, + NSPurgeableDataStorageNeedsFree = 0x8, +} NSPurgeableDataBackingFlags; + +typedef struct { + void *data; + NSPurgeableDataBackingFlags flags; + NSUInteger capacity; +} NSPurgeableDataStorage; + @interface NSPurgeableData : NSMutableData +{ + NSUInteger _length; + int32_t _accessCount; + uint8_t _private[32]; + NSPurgeableDataStorage *_dataStorage; +} @end diff --git a/include/Foundation/NSDateFormatter.h b/include/Foundation/NSDateFormatter.h index 6d6030f96..5dce1e0de 100644 --- a/include/Foundation/NSDateFormatter.h +++ b/include/Foundation/NSDateFormatter.h @@ -17,6 +17,10 @@ typedef NS_ENUM(NSUInteger, NSDateFormatterBehavior) { @class NSLocale, NSDate, NSCalendar, NSTimeZone, NSError, NSArray, NSMutableDictionary; @interface NSDateFormatter : NSFormatter +{ + NSMutableDictionary *_attributes; + struct __CFDateFormatter *_formatter; +} + (NSString *)localizedStringFromDate:(NSDate *)date dateStyle:(NSDateFormatterStyle)dstyle timeStyle:(NSDateFormatterStyle)tstyle; + (NSString *)dateFormatFromTemplate:(NSString *)tmplate options:(NSUInteger)opts locale:(NSLocale *)locale; diff --git a/include/Foundation/NSFileManager.h b/include/Foundation/NSFileManager.h index 55fb2f699..b9cfa1f0f 100644 --- a/include/Foundation/NSFileManager.h +++ b/include/Foundation/NSFileManager.h @@ -84,6 +84,27 @@ FOUNDATION_EXPORT NSString * const NSFileSystemFreeNodes; @end @interface NSFileManager : NSObject +{ + id _delegate; + struct { + int shouldCopyItemAtPathToPath:1; + int shouldCopyItemAtURLToURL:1; + int shouldProceedAfterErrorCopyingItemAtPathToPath:1; + int shouldProceedAfterErrorCopyingItemAtURLToURL:1; + int shouldMoveItemAtPathToPath:1; + int shouldMoveItemAtURLToURL:1; + int shouldProceedAfterErrorMovingItemAtPathToPath:1; + int shouldProceedAfterErrorMovingItemAtURLToURL:1; + int shouldLinkItemAtPathToPath:1; + int shouldLinkItemAtURLToURL:1; + int shouldProceedAfterErrorLinkingItemAtPathToPath:1; + int shouldProceedAfterErrorLinkingItemAtURLToURL:1; + int shouldRemoveItemAtPath:1; + int shouldRemoveItemAtURL:1; + int shouldProceedAfterErrorRemovingItemAtPath:1; + int shouldProceedAfterErrorRemovingItemAtURL:1; + } _flags; +} + (NSFileManager *)defaultManager; - (NSArray *)mountedVolumeURLsIncludingResourceValuesForKeys:(NSArray *)propertyKeys options:(NSVolumeEnumerationOptions)options; diff --git a/include/Foundation/NSGeometry.h b/include/Foundation/NSGeometry.h index 29a6df3cb..d6019f93e 100644 --- a/include/Foundation/NSGeometry.h +++ b/include/Foundation/NSGeometry.h @@ -2,8 +2,18 @@ #import #import -#import -#import +#ifndef CGFLOAT_DEFINED +#if __LP64__ +typedef double CGFloat; +#else +typedef float CGFloat; +#endif +#define CGFLOAT_DEFINED +#endif + +typedef struct CGPoint CGPoint; +typedef struct CGRect CGRect; +typedef struct CGSize CGSize; #if __LP64__ || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64 @@ -22,6 +32,9 @@ typedef CGRect NSRect; typedef NSRect *NSRectPointer; typedef NSRect *NSRectArray; +#import +#import + typedef NS_ENUM(NSUInteger, NSRectEdge) { NSRectEdgeMinX = CGRectMinXEdge, NSRectEdgeMinY = CGRectMinYEdge, @@ -62,6 +75,9 @@ typedef struct _NSRect { typedef NSRect *NSRectPointer; typedef NSRect *NSRectArray; +#import +#import + typedef enum { NSRectEdgeMinX = 0, NSRectEdgeMinY = 1, @@ -239,6 +255,7 @@ FOUNDATION_EXPORT NSPoint NSPointFromString(NSString *aString); FOUNDATION_EXPORT NSSize NSSizeFromString(NSString *aString); FOUNDATION_EXPORT NSRect NSRectFromString(NSString *aString); +#ifdef __OBJC__ @interface NSValue (NSValueGeometryExtensions) + (NSValue *)valueWithPoint:(NSPoint)point; @@ -278,3 +295,5 @@ FOUNDATION_EXPORT NSRect NSRectFromString(NSString *aString); @end +#endif + diff --git a/include/Foundation/NSHTTPCookie.h b/include/Foundation/NSHTTPCookie.h index dc48d568a..6dcea51ce 100644 --- a/include/Foundation/NSHTTPCookie.h +++ b/include/Foundation/NSHTTPCookie.h @@ -16,7 +16,12 @@ FOUNDATION_EXPORT NSString * const NSHTTPCookieDiscard; FOUNDATION_EXPORT NSString * const NSHTTPCookieMaximumAge; FOUNDATION_EXPORT NSString * const NSHTTPCookiePort; +typedef struct __CFHTTPCookie *CFHTTPCookieRef; + @interface NSHTTPCookie : NSObject +{ + CFHTTPCookieRef _cookiePrivate; +} + (id)cookieWithProperties:(NSDictionary *)properties; + (NSDictionary *)requestHeaderFieldsWithCookies:(NSArray *)cookies; diff --git a/include/Foundation/NSHTTPCookieStorage.h b/include/Foundation/NSHTTPCookieStorage.h index 0d1f2b1c4..89fe33d6b 100644 --- a/include/Foundation/NSHTTPCookieStorage.h +++ b/include/Foundation/NSHTTPCookieStorage.h @@ -11,7 +11,13 @@ typedef NS_ENUM(NSUInteger, NSHTTPCookieAcceptPolicy) { FOUNDATION_EXPORT NSString * const NSHTTPCookieManagerAcceptPolicyChangedNotification; FOUNDATION_EXPORT NSString * const NSHTTPCookieManagerCookiesChangedNotification; +typedef struct __CFHTTPCookieStorage *CFHTTPCookieStorageRef; + @interface NSHTTPCookieStorage : NSObject +{ + CFHTTPCookieStorageRef _storage; + NSHTTPCookieAcceptPolicy _acceptPolicy; +} + (NSHTTPCookieStorage *)sharedHTTPCookieStorage; diff --git a/include/Foundation/NSHashTable.h b/include/Foundation/NSHashTable.h index c340aedec..221e43b9e 100644 --- a/include/Foundation/NSHashTable.h +++ b/include/Foundation/NSHashTable.h @@ -1,46 +1,263 @@ -#import -#import -#import +/* NSHashTable interface for GNUStep. + * Copyright (C) 1994, 1995, 1996, 1997, 2002 Free Software Foundation, Inc. + * + * Author: Albin L. Jones + * Created: Mon Dec 12 23:56:03 EST 1994 + * Updated: Thu Mar 21 15:13:46 EST 1996 + * Serial: 96.03.21.06 + * Modified by: Richard Frith-Macdonald + * + * This file is part of the GNUstep Base Library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, 02111 USA. + */ + +#ifndef __NSHashTable_h_GNUSTEP_BASE_INCLUDE +#define __NSHashTable_h_GNUSTEP_BASE_INCLUDE 1 + +/**** Included Headers *******************************************************/ + +#import +#import +#import + +#define GS_EXPORT extern + +#if defined(__cplusplus) +extern "C" { +#endif -#if !defined(__FOUNDATION_NSHASHTABLE__) -#define __FOUNDATION_NSHASHTABLE__ 1 @class NSArray, NSSet, NSHashTable; +/**** Type, Constant, and Macro Definitions **********************************/ + enum { - NSHashTableStrongMemory NS_ENUM_AVAILABLE(10_5, 6_0) = 0, - NSHashTableCopyIn NS_ENUM_AVAILABLE(10_5, 6_0) = NSPointerFunctionsCopyIn, - NSHashTableObjectPointerPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = NSPointerFunctionsObjectPointerPersonality, - NSHashTableWeakMemory NS_ENUM_AVAILABLE(10_8, 6_0) = NSPointerFunctionsWeakMemory, + NSHashTableStrongMemory + = NSPointerFunctionsStrongMemory, + NSHashTableZeroingWeakMemory + = NSPointerFunctionsZeroingWeakMemory, + NSHashTableCopyIn + = NSPointerFunctionsCopyIn, + NSHashTableObjectPointerPersonality + = NSPointerFunctionsObjectPointerPersonality, + NSHashTableWeakMemory + = NSPointerFunctionsWeakMemory }; typedef NSUInteger NSHashTableOptions; @interface NSHashTable : NSObject -+ (id)hashTableWithOptions:(NSPointerFunctionsOptions)options; -+ (id)weakObjectsHashTable; ++ (id) hashTableWithOptions: (NSPointerFunctionsOptions)options; + ++ (id) hashTableWithWeakObjects; +/** + * Creates a hash table that uses zeroing weak references (either using the + * automatic reference counting or garbage collection mechanism, depending on + * which mode this framework is compiled in) so that objects are removed when + * their last other reference disappears. + */ ++ (id) weakObjectsHashTable; + + +- (id) initWithOptions: (NSPointerFunctionsOptions)options + capacity: (NSUInteger)initialCapacity; + +- (id) initWithPointerFunctions: (NSPointerFunctions*)functions + capacity: (NSUInteger)initialCapacity; + +/** Adds the object to the receiver. + */ +- (void) addObject: (id)object; + +/** Returns an array containing all objects in the receiver. + */ +- (NSArray*) allObjects; + +/** Returns any objct from the receiver, or nil if the receiver contains no + * objects. + */ +- (id) anyObject; + +/** Returns YES if the receiver contains an item equal to anObject, or NO + * otherwise. + */ +- (BOOL) containsObject: (id)anObject; + +/** Return the number of items atored in the receiver. + */ +- (NSUInteger) count; + +/** Removes from the receiver any items which are not also present in 'other'. + */ +- (void) intersectHashTable: (NSHashTable*)other; + +/** Returns YES if the receiver and 'other' contain any items in common. + */ +- (BOOL) intersectsHashTable: (NSHashTable*)other; + +/** Returns YES if the receiver and 'other' contain equal sets of items. + */ +- (BOOL) isEqualToHashTable: (NSHashTable*)other; + +/** Returns YES fi all the items in the receiver are also present in 'other' + */ +- (BOOL) isSubsetOfHashTable: (NSHashTable*)other; + +/** Returns an item stored in the receiver which is equal to the supplied + * object argument, or nil if no matchi is found. + */ +- (id) member: (id)object; + +/** Removes from the receivr all those items which are prsent in both + * the receiver and in 'other'. + */ +- (void) minusHashTable: (NSHashTable*)other; + +/** Return an enumerator for the receiver. + */ +- (NSEnumerator*) objectEnumerator; + +/** Return an NSPointerFunctions value describing the functions used by the + * receiver to handle its contents. + */ +- (NSPointerFunctions*) pointerFunctions; + +/** Removes all objects. + */ +- (void) removeAllObjects; + +/** Remove the object (or any equal object) from the receiver. + */ +- (void) removeObject: (id)object; + +/** Returns a set containing all the objects in the receiver. + */ +- (NSSet*) setRepresentation; + +/** Adds to the receiver thse items present in 'other' which were + * not present in the receiver. + */ +- (void) unionHashTable: (NSHashTable*)other; -- (id)initWithOptions:(NSPointerFunctionsOptions)options capacity:(NSUInteger)initialCapacity; -- (id)initWithPointerFunctions:(NSPointerFunctions *)functions capacity:(NSUInteger)initialCapacity; -- (NSPointerFunctions *)pointerFunctions; -- (NSUInteger)count; -- (id)member:(id)object; -- (NSEnumerator *)objectEnumerator; -- (void)addObject:(id)object; -- (void)removeObject:(id)object; -- (void)removeAllObjects; -- (NSArray *)allObjects; -- (id)anyObject; -- (BOOL)containsObject:(id)anObject; -- (BOOL)intersectsHashTable:(NSHashTable *)other; -- (BOOL)isEqualToHashTable:(NSHashTable *)other; -- (BOOL)isSubsetOfHashTable:(NSHashTable *)other; -- (void)intersectHashTable:(NSHashTable *)other; -- (void)unionHashTable:(NSHashTable *)other; -- (void)minusHashTable:(NSHashTable *)other; -- (NSSet *)setRepresentation; @end + +/** + * Type for enumerating.
+ * NB. Implementation detail ... in GNUstep the layout must + * correspond to that used by the GSIMap macros. + */ +typedef struct { void *map; void *node; size_t bucket; } NSHashEnumerator; + +/** Callback functions for an NSHashTable. See NSCreateHashTable() .
*/ +typedef struct _NSHashTableCallBacks +{ + /** NSUInteger (*hash)(NSHashTable *, const void *) ... + * Hashing function. NOTE: Elements with equal values must have equal hash + * function values. The default if NULL uses the pointer addresses + * directly.
*/ + NSUInteger (*hash)(NSHashTable *, const void *); + + /** BOOL (*isEqual)(NSHashTable *, const void *, const void *) + * ... Comparison function. The default if NULL uses '=='. + *
*/ + BOOL (*isEqual)(NSHashTable *, const void *, const void *); + + /** void (*retain)(NSHashTable *, const void *) ... + * Retaining function called when adding elements to the table. + * The default if NULL is a no-op (no reference counting).
*/ + void (*retain)(NSHashTable *, const void *); + + /** void (*release)(NSHashTable *, void *) ... Releasing + * function called when a data element is removed from the table. + * The default if NULL is a no-op (no reference counting).
*/ + void (*release)(NSHashTable *, void *); + + /** NSString *(*describe)(NSHashTable *, const void *) ... + * Description function. The default if NULL prints boilerplate.
*/ + NSString *(*describe)(NSHashTable *, const void *); +} NSHashTableCallBacks; + +GS_EXPORT const NSHashTableCallBacks NSIntegerHashCallBacks; +GS_EXPORT const NSHashTableCallBacks NSIntHashCallBacks; /*DEPRECATED*/ +GS_EXPORT const NSHashTableCallBacks NSNonOwnedPointerHashCallBacks; +GS_EXPORT const NSHashTableCallBacks NSNonRetainedObjectHashCallBacks; +GS_EXPORT const NSHashTableCallBacks NSObjectHashCallBacks; +GS_EXPORT const NSHashTableCallBacks NSOwnedPointerHashCallBacks; +GS_EXPORT const NSHashTableCallBacks NSPointerToStructHashCallBacks; + +GS_EXPORT NSHashTable * +NSCreateHashTable(NSHashTableCallBacks callBacks, + NSUInteger capacity); + +GS_EXPORT NSHashTable * +NSCreateHashTableWithZone(NSHashTableCallBacks callBacks, + NSUInteger capacity, + NSZone *zone); + +GS_EXPORT NSHashTable * +NSCopyHashTableWithZone(NSHashTable *table, NSZone *zone); + +GS_EXPORT void +NSFreeHashTable(NSHashTable *table); + +GS_EXPORT void +NSResetHashTable(NSHashTable *table); + +GS_EXPORT BOOL +NSCompareHashTables(NSHashTable *table1, NSHashTable *table2); + +GS_EXPORT NSUInteger +NSCountHashTable(NSHashTable *table); + +GS_EXPORT void * +NSHashGet(NSHashTable *table, const void *element); + +GS_EXPORT NSArray * +NSAllHashTableObjects(NSHashTable *table); + +GS_EXPORT void +NSEndHashTableEnumeration(NSHashEnumerator *enumerator); + +GS_EXPORT NSHashEnumerator +NSEnumerateHashTable(NSHashTable *table); + +GS_EXPORT void * +NSNextHashEnumeratorItem(NSHashEnumerator *enumerator); + +GS_EXPORT void +NSHashInsert(NSHashTable *table, const void *element); + +GS_EXPORT void +NSHashInsertKnownAbsent(NSHashTable *table, const void *element); + +GS_EXPORT void * +NSHashInsertIfAbsent(NSHashTable *table, const void *element); + +GS_EXPORT void +NSHashRemove(NSHashTable *table, const void *element); + +GS_EXPORT NSString * +NSStringFromHashTable(NSHashTable *table); + +#if defined(__cplusplus) +} #endif + +#endif /* __NSHashTable_h_GNUSTEP_BASE_INCLUDE */ diff --git a/include/Foundation/NSIndexPath.h b/include/Foundation/NSIndexPath.h index 00130fd1f..02d035482 100644 --- a/include/Foundation/NSIndexPath.h +++ b/include/Foundation/NSIndexPath.h @@ -1,6 +1,11 @@ #import @interface NSIndexPath : NSObject +{ + NSUInteger *_indexes; + NSUInteger _hash; + NSUInteger _length; +} + (instancetype)indexPathWithIndex:(NSUInteger)index; + (instancetype)indexPathWithIndexes:(const NSUInteger [])indexes length:(NSUInteger)length; diff --git a/include/Foundation/NSIndexSet.h b/include/Foundation/NSIndexSet.h index 7529e06ea..1c4336259 100644 --- a/include/Foundation/NSIndexSet.h +++ b/include/Foundation/NSIndexSet.h @@ -1,7 +1,29 @@ #import #import +typedef struct RangeList RangeList; +typedef struct NSIndexSetCache NSIndexSetCache; + @interface NSIndexSet : NSObject +{ +@package + struct { + unsigned int _isEmpty:1; + unsigned int _hasSingleRange:1; + unsigned int _cacheValid:1; + unsigned int _arrayBinderController:29; + } _indexSetFlags; + + union { + struct { + NSRange _range; + } _singleRange; + struct { + RangeList *_data; + NSIndexSetCache *_cache; + } _multipleRanges; + } _internal; +} + (instancetype)indexSet; + (instancetype)indexSetWithIndex:(NSUInteger)value; diff --git a/include/Foundation/NSInvocation.h b/include/Foundation/NSInvocation.h index 3c7c69804..a5e6bde4c 100644 --- a/include/Foundation/NSInvocation.h +++ b/include/Foundation/NSInvocation.h @@ -1,145 +1,31 @@ -/* Interface for NSInvocation for GNUStep - Copyright (C) 1998,2003 Free Software Foundation, Inc. +#import +#import - Author: Richard Frith-Macdonald - Date: 1998 - Based on code by: Andrew Kachites McCallum - - This file is part of the GNUstep Base Library. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02111 USA. - */ - -#ifndef __NSInvocation_h_GNUSTEP_BASE_INCLUDE -#define __NSInvocation_h_GNUSTEP_BASE_INCLUDE - -#import - -#if defined(__cplusplus) -extern "C" { -#endif +@class NSMethodSignature; @interface NSInvocation : NSObject { -@public - NSMethodSignature *_sig; - void *_cframe; - void *_retval; - id _target; - SEL _selector; - unsigned int _numArgs; - void *_info; - BOOL _argsRetained; - BOOL _targetRetained; - BOOL _validReturn; - BOOL _sendToSuper; - void *_retptr; + __strong void *_frame; + __strong void *_retdata; + NSMethodSignature *_signature; + id *_container; + uint8_t _retainedArgs; + uint8_t _reserved[15]; } -/* - * Creating instances. - */ -+ (NSInvocation*) invocationWithMethodSignature: (NSMethodSignature*)_signature; - -/* - * Accessing message elements. - */ -- (void) getArgument: (void*)buffer - atIndex: (NSInteger)index; -- (void) getReturnValue: (void*)buffer; -- (SEL) selector; -- (void) setArgument: (void*)buffer - atIndex: (NSInteger)index; -- (void) setReturnValue: (void*)buffer; -- (void) setSelector: (SEL)aSelector; -- (void) setTarget: (id)anObject; -- (id) target; - -/* - * Managing arguments. - */ -- (BOOL) argumentsRetained; -- (void) retainArguments; - -- (BOOL) targetRetained; -- (void) retainArgumentsIncludingTarget: (BOOL)retainTargetFlag; - -/* - * Dispatching an Invocation. - */ -- (void) invoke; -- (void) invokeWithTarget: (id)anObject; - -/* - * Getting the method signature. - */ -- (NSMethodSignature*) methodSignature; ++ (NSInvocation *)invocationWithMethodSignature:(NSMethodSignature *)sig; +- (NSMethodSignature *)methodSignature; +- (void)retainArguments; +- (BOOL)argumentsRetained; +- (id)target; +- (void)setTarget:(id)target; +- (SEL)selector; +- (void)setSelector:(SEL)selector; +- (void)getReturnValue:(void *)retLoc; +- (void)setReturnValue:(void *)retLoc; +- (void)getArgument:(void *)argumentLocation atIndex:(NSInteger)idx; +- (void)setArgument:(void *)argumentLocation atIndex:(NSInteger)idx; +- (void)invoke; +- (void)invokeWithTarget:(id)target; @end - -@interface NSInvocation (GNUstep) -/** - * Returns the status of the flag set by -setSendsToSuper: - */ -- (BOOL) sendsToSuper; -/** - * Sets the flag to tell the invocation that it should actually invoke a - * method in the superclass of the target rather than the method of the - * target itself.
- * This extension permits an invocation to act like a regular method - * call sent to super in the method of a class. - */ -- (void) setSendsToSuper: (BOOL)flag; -@end - -/** For use by macros only. - */ -@interface NSInvocation (MacroSetup) -- (id) initWithMethodSignature: (NSMethodSignature*)aSignature; -+ (id) _newProxyForInvocation: (id)target; -+ (id) _newProxyForMessage: (id)target; -+ (NSInvocation*) _returnInvocationAndDestroyProxy: (id)proxy; -@end -/** - * Creates and returns an autoreleased invocation containing a - * message to an instance of the class. The 'message' consists - * of selector and arguments like a standard ObjectiveC method - * call.
- * Before using the returned invocation, you need to set its target. - */ -#define NS_INVOCATION(aClass, message...) ({\ - id __proxy = [NSInvocation _newProxyForInvocation: aClass]; \ - [__proxy message]; \ - [NSInvocation _returnInvocationAndDestroyProxy: __proxy]; \ -}) - -/** - * Creates and returns an autoreleased invocation containing a - * message to the target object. The 'message' consists - * of selector and arguments like a standard ObjectiveC method - * call. - */ -#define NS_MESSAGE(target, message...) ({\ - id __proxy = [NSInvocation _newProxyForMessage: target]; \ - [__proxy message]; \ - [NSInvocation _returnInvocationAndDestroyProxy: __proxy]; \ -}) - -#if defined(__cplusplus) -} -#endif - -#endif /* __NSInvocation_h_GNUSTEP_BASE_INCLUDE */ diff --git a/include/Foundation/NSKeyedArchiver.h b/include/Foundation/NSKeyedArchiver.h index 6af527088..d12147ccc 100644 --- a/include/Foundation/NSKeyedArchiver.h +++ b/include/Foundation/NSKeyedArchiver.h @@ -1,7 +1,10 @@ #import #import +#import +#import +#import -@class NSArray, NSMutableData, NSData, NSKeyedArchiver, NSKeyedUnarchiver; +@class NSArray, NSMutableArray, NSMutableData, NSData, NSKeyedArchiver, NSKeyedUnarchiver; @protocol NSKeyedArchiverDelegate @optional @@ -28,7 +31,26 @@ FOUNDATION_EXPORT NSString * const NSInvalidArchiveOperationException; FOUNDATION_EXPORT NSString * const NSInvalidUnarchiveOperationException; +typedef const struct __CFKeyedArchiverUID* CFKeyedArchiverUIDRef; + @interface NSKeyedArchiver : NSCoder +{ + CFTypeRef _stream; + unsigned int _flags; + id _delegate; + NSMutableArray *_containers; + NSMutableArray *_objects; + CFMutableDictionaryRef _objRefMap; + CFMutableDictionaryRef _replacementMap; + id _classNameMap; + CFMutableDictionaryRef _conditionals; + id _classes; + NSUInteger _genericKey; + CFKeyedArchiverUIDRef *_cache; + unsigned int _cacheSize; + unsigned int _estimatedCount; + CFMutableSetRef _visited; +} + (NSData *)archivedDataWithRootObject:(id)rootObject; + (BOOL)archiveRootObject:(id)rootObject toFile:(NSString *)path; @@ -55,7 +77,28 @@ FOUNDATION_EXPORT NSString * const NSInvalidUnarchiveOperationException; @end +typedef struct offsetDataStruct offsetDataStruct; +@class _NSKeyedUnarchiverHelper; + @interface NSKeyedUnarchiver : NSCoder +{ + id _delegate; + unsigned int _flags; + CFMutableDictionaryRef _objRefMap; + id _replacementMap; + CFMutableDictionaryRef _nameClassMap; + CFMutableDictionaryRef _tmpRefObjMap; + CFMutableDictionaryRef _refObjMap; + int _genericKey; + CFDataRef _data; + offsetDataStruct *_offsetData; // trailer info + CFMutableArrayRef _containers; // for xml unarchives + CFArrayRef _objects; // for xml unarchives + const char *_bytes; + unsigned long long _len; + _NSKeyedUnarchiverHelper *_helper; + CFMutableDictionaryRef _reservedDictionary; +} + (id)unarchiveObjectWithData:(NSData *)data; + (id)unarchiveObjectWithFile:(NSString *)path; diff --git a/include/Foundation/NSLock.h b/include/Foundation/NSLock.h index 59d721e45..84aca33d0 100644 --- a/include/Foundation/NSLock.h +++ b/include/Foundation/NSLock.h @@ -1,4 +1,5 @@ #import +#import @class NSDate; @@ -10,6 +11,12 @@ @end @interface NSLock : NSObject +{ + pthread_t _thread; + pthread_mutex_t _lock; + NSString *_name; + BOOL _isInitialized; +} - (BOOL)tryLock; - (BOOL)lockBeforeDate:(NSDate *)limit; @@ -18,7 +25,14 @@ @end +@class NSCondition; @interface NSConditionLock : NSObject +{ + NSCondition *_cond; + NSInteger _value; + pthread_t _thread; + BOOL _locked; +} - (id)initWithCondition:(NSInteger)condition; - (NSInteger)condition; @@ -34,6 +48,15 @@ @end @interface NSRecursiveLock : NSObject +{ + pthread_mutex_t _lock; + pthread_mutexattr_t _attrs; + pthread_t _thread; + int _locks; + NSString *_name; + BOOL _lockIsInitialized; + BOOL _mutexAttrsInitialized; +} - (BOOL)tryLock; - (BOOL)lockBeforeDate:(NSDate *)limit; @@ -43,6 +66,15 @@ @end @interface NSCondition : NSObject +{ + pthread_mutex_t _lock; + pthread_mutexattr_t _attrs; + pthread_cond_t _cond; + pthread_condattr_t _condAttrs; + pthread_t _thread; + NSString *_name; + BOOL _isInitialized; +} - (void)wait; - (BOOL)waitUntilDate:(NSDate *)limit; diff --git a/include/Foundation/NSMapTable.h b/include/Foundation/NSMapTable.h index 87d56dd3c..bd9fcc2de 100644 --- a/include/Foundation/NSMapTable.h +++ b/include/Foundation/NSMapTable.h @@ -1,39 +1,340 @@ -#import -#import -#import +/* NSMapTable interface for GNUStep. + * Copyright (C) 1994, 1995, 1996, 2002, 2009 Free Software Foundation, Inc. + * + * Author: Albin L. Jones + * Created: Tue Dec 13 00:05:02 EST 1994 + * Updated: Thu Mar 21 15:12:42 EST 1996 + * Serial: 96.03.21.05 + * Modified by: Richard Frith-Macdonald + * Updated: March 2009 + * + * This file is part of the GNUstep Base Library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02111 USA. + */ -#if !defined(__FOUNDATION_NSMAPTABLE__) -#define __FOUNDATION_NSMAPTABLE__ 1 +#ifndef __NSMapTable_h_GNUSTEP_BASE_INCLUDE +#define __NSMapTable_h_GNUSTEP_BASE_INCLUDE 1 -@class NSArray, NSDictionary, NSMapTable; +/**** Included Headers *******************************************************/ -typedef NS_ENUM(NSUInteger, NSMapTableOptions) { - NSMapTableStrongMemory = 0, - NSMapTableCopyIn = NSPointerFunctionsCopyIn, - NSMapTableObjectPointerPersonality = NSPointerFunctionsObjectPointerPersonality, - NSMapTableWeakMemory = NSPointerFunctionsWeakMemory +#import +#import +#import +#import +#import + +#define GS_EXPORT extern + +#if defined(__cplusplus) +extern "C" { +#endif + +/**** Type, Constant, and Macro Definitions **********************************/ + +enum { + NSMapTableStrongMemory + = NSPointerFunctionsStrongMemory, + NSMapTableZeroingWeakMemory + = NSPointerFunctionsZeroingWeakMemory, + NSMapTableCopyIn + = NSPointerFunctionsCopyIn, + NSMapTableObjectPointerPersonality + = NSPointerFunctionsObjectPointerPersonality, + NSMapTableWeakMemory + = NSPointerFunctionsWeakMemory }; +typedef NSUInteger NSMapTableOptions; + @interface NSMapTable : NSObject -+ (id)mapTableWithKeyOptions:(NSPointerFunctionsOptions)keyOptions valueOptions:(NSPointerFunctionsOptions)valueOptions; -+ (id)strongToStrongObjectsMapTable; -+ (id)weakToStrongObjectsMapTable; -+ (id)strongToWeakObjectsMapTable; -+ (id)weakToWeakObjectsMapTable; -- (id)initWithKeyOptions:(NSPointerFunctionsOptions)keyOptions valueOptions:(NSPointerFunctionsOptions)valueOptions capacity:(NSUInteger)initialCapacity; -- (id)initWithKeyPointerFunctions:(NSPointerFunctions *)keyFunctions valuePointerFunctions:(NSPointerFunctions *)valueFunctions capacity:(NSUInteger)initialCapacity; -- (NSPointerFunctions *)keyPointerFunctions; -- (NSPointerFunctions *)valuePointerFunctions; -- (id)objectForKey:(id)aKey; -- (void)removeObjectForKey:(id)aKey; -- (void)setObject:(id)anObject forKey:(id)aKey; -- (NSUInteger)count; -- (NSEnumerator *)keyEnumerator; -- (NSEnumerator *)objectEnumerator; -- (void)removeAllObjects; -- (NSDictionary *)dictionaryRepresentation; +/** Return a map table initialised using the specified options for + * keys and values. + */ ++ (id) mapTableWithKeyOptions: (NSPointerFunctionsOptions)keyOptions + valueOptions: (NSPointerFunctionsOptions)valueOptions; +/** Convenience method for creating a map table to store object values + * using object keys. + */ ++ (id) mapTableWithStrongToStrongObjects; + +/** Convenience method for creating a map table to store non-retained + * object values with retained object keys. + */ ++ (id) mapTableWithStrongToWeakObjects; + +/** Convenience method for creating a map table to store retained + * object values with non-retained object keys. + */ ++ (id) mapTableWithWeakToStrongObjects; + +/** Convenience method for creating a map table to store non-retained + * object values with non-retained object keys. + */ ++ (id) mapTableWithWeakToWeakObjects; + +/** Convenience method for creating a map table to store object values + * using object keys. The collection will retain both the key and the value. + */ ++ (id) strongToStrongObjectsMapTable; +/** Convenience method for creating a map table to store object values + * using object keys. The collection will retain the key, the value will be a + * zeroing weak reference. + */ ++ (id) strongToWeakObjectsMapTable; +/** Convenience method for creating a map table to store object values + * using object keys. The collection will retain the value, the key will be a + * zeroing weak reference. + */ ++ (id) weakToStrongObjectsMapTable; +/** Convenience method for creating a map table to store object values + * using object keys. The collection will use zeroing weak references for both + * the key and the value. + */ ++ (id) weakToWeakObjectsMapTable; + + +/** Initialiser using option bitmasks to describe the keys and values. + */ +- (id) initWithKeyOptions: (NSPointerFunctionsOptions)keyOptions + valueOptions: (NSPointerFunctionsOptions)valueOptions + capacity: (NSUInteger)initialCapacity; + +/** Initialiser using full pointer function information to describe + * the keys and values. + */ +- (id) initWithKeyPointerFunctions: (NSPointerFunctions*)keyFunctions + valuePointerFunctions: (NSPointerFunctions*)valueFunctions + capacity: (NSUInteger)initialCapacity; + +/** Return the number of items stored in the map. + */ +- (NSUInteger) count; + +/** Return a dictionary containing the keys and values in the receiver. + */ +- (NSDictionary*) dictionaryRepresentation; + +/** Return an enumerator able to enumerate the keys in the receiver. + */ +- (NSEnumerator*) keyEnumerator; + +/** Return an NSPointerFunctions value describind the functions used by the + * receiver to handle keys. + */ +- (NSPointerFunctions*) keyPointerFunctions; + +/** Return an enumerator able to enumerate the values in the receiver. + */ +- (NSEnumerator*) objectEnumerator; + +/** Return the object stored under the specified key. + */ +- (id) objectForKey: (id)aKey; + +/** Empty the receiver of all stored values. + */ +- (void) removeAllObjects; + +/** Remove the object stored under the specified key. + */ +- (void) removeObjectForKey: (id)aKey; + +/** Store the object under the specified key, replacing any object which + * was previously stored under that key. + */ +- (void) setObject: (id)anObject forKey: (id)aKey; + +/** Return an NSPointerFunctions value describind the functions used by the + * receiver to handle values. + */ +- (NSPointerFunctions*) valuePointerFunctions; @end +/** + * Type for enumerating.
+ * NB. Implementation detail ... in GNUstep the layout must + * correspond to that used by the GSIMap macros. + */ +typedef struct { void *map; void *node; size_t bucket; } NSMapEnumerator; + +/** + * Callback functions for a key. + */ +typedef struct _NSMapTableKeyCallBacks +{ + /* + * Hashing function. Must not modify the key.
+ * NOTE: Elements with equal values must + * have equal hash function values. + */ + NSUInteger (*hash)(NSMapTable *, const void *); + + /** + * Comparison function. Must not modify either key. + */ + BOOL (*isEqual)(NSMapTable *, const void *, const void *); + + /** + * Retaining function called when adding elements to table.
+ * Notionally this must not modify the key (the key may not + * actually have a retain count, or the retain count may be stored + * externally to the key, but in practice this often actually + * changes a counter within the key). + */ + void (*retain)(NSMapTable *, const void *); + + /** + * Releasing function called when a data element is + * removed from the table. This may decrease a retain count or may + * actually destroy the key. + */ + void (*release)(NSMapTable *, void *); + + /** + * Description function. Generates a string describing the key + * and does not modify the key itself. + */ + NSString *(*describe)(NSMapTable *, const void *); + + /** + * Quantity that is not a key to the map table. + */ + const void *notAKeyMarker; +} NSMapTableKeyCallBacks; + +/** + * Callback functions for a value. + */ +typedef struct _NSMapTableValueCallBacks NSMapTableValueCallBacks; +struct _NSMapTableValueCallBacks +{ + /** + * Retaining function called when adding elements to table.
+ * Notionally this must not modify the element (the element may not + * actually have a retain count, or the retain count may be stored + * externally to the element, but in practice this often actually + * changes a counter within the element). + */ + void (*retain)(NSMapTable *, const void *); + + /** + * Releasing function called when a data element is + * removed from the table. This may decrease a retain count or may + * actually destroy the element. + */ + void (*release)(NSMapTable *, void *); + + /** + * Description function. Generates a string describing the element + * and does not modify the element itself. + */ + NSString *(*describe)(NSMapTable *, const void *); +}; + +/* Quantities that are never map keys. */ +#define NSNotAnIntMapKey ((const void *)0x80000000) +#define NSNotAPointerMapKey ((const void *)0xffffffff) + +GS_EXPORT const NSMapTableKeyCallBacks NSIntegerMapKeyCallBacks; +GS_EXPORT const NSMapTableKeyCallBacks NSIntMapKeyCallBacks; /*DEPRECATED*/ +GS_EXPORT const NSMapTableKeyCallBacks NSNonOwnedPointerMapKeyCallBacks; +GS_EXPORT const NSMapTableKeyCallBacks NSNonOwnedPointerOrNullMapKeyCallBacks; +GS_EXPORT const NSMapTableKeyCallBacks NSNonRetainedObjectMapKeyCallBacks; +GS_EXPORT const NSMapTableKeyCallBacks NSObjectMapKeyCallBacks; +GS_EXPORT const NSMapTableKeyCallBacks NSOwnedPointerMapKeyCallBacks; +GS_EXPORT const NSMapTableValueCallBacks NSIntegerMapValueCallBacks; +GS_EXPORT const NSMapTableValueCallBacks NSIntMapValueCallBacks; /*DEPRECATED*/ +GS_EXPORT const NSMapTableValueCallBacks NSNonOwnedPointerMapValueCallBacks; +GS_EXPORT const NSMapTableValueCallBacks NSNonRetainedObjectMapValueCallBacks; +GS_EXPORT const NSMapTableValueCallBacks NSObjectMapValueCallBacks; +GS_EXPORT const NSMapTableValueCallBacks NSOwnedPointerMapValueCallBacks; + +GS_EXPORT NSMapTable * +NSCreateMapTable(NSMapTableKeyCallBacks keyCallBacks, + NSMapTableValueCallBacks valueCallBacks, + NSUInteger capacity); + +GS_EXPORT NSMapTable * +NSCreateMapTableWithZone(NSMapTableKeyCallBacks keyCallBacks, + NSMapTableValueCallBacks valueCallBacks, + NSUInteger capacity, + NSZone *zone); + +GS_EXPORT NSMapTable * +NSCopyMapTableWithZone(NSMapTable *table, NSZone *zone); + +GS_EXPORT void +NSFreeMapTable(NSMapTable *table); + +GS_EXPORT void +NSResetMapTable(NSMapTable *table); + +GS_EXPORT BOOL +NSCompareMapTables(NSMapTable *table1, NSMapTable *table2); + +GS_EXPORT NSUInteger +NSCountMapTable(NSMapTable *table); + +GS_EXPORT BOOL +NSMapMember(NSMapTable *table, + const void *key, + void **originalKey, + void **value); + +GS_EXPORT void * +NSMapGet(NSMapTable *table, const void *key); + +GS_EXPORT void +NSEndMapTableEnumeration(NSMapEnumerator *enumerator); + +GS_EXPORT NSMapEnumerator +NSEnumerateMapTable(NSMapTable *table); + +GS_EXPORT BOOL +NSNextMapEnumeratorPair(NSMapEnumerator *enumerator, + void **key, + void **value); + +GS_EXPORT NSArray * +NSAllMapTableKeys(NSMapTable *table); + +GS_EXPORT NSArray * +NSAllMapTableValues(NSMapTable *table); + +GS_EXPORT void +NSMapInsert(NSMapTable *table, const void *key, const void *value); + +GS_EXPORT void * +NSMapInsertIfAbsent(NSMapTable *table, const void *key, const void *value); + +GS_EXPORT void +NSMapInsertKnownAbsent(NSMapTable *table, + const void *key, + const void *value); + +GS_EXPORT void +NSMapRemove(NSMapTable *table, const void *key); + +GS_EXPORT NSString *NSStringFromMapTable (NSMapTable *table); + +#if defined(__cplusplus) +} #endif + +#endif /* __NSMapTable_h_GNUSTEP_BASE_INCLUDE */ diff --git a/include/Foundation/NSNetServices.h b/include/Foundation/NSNetServices.h index 5aa65cdfb..1c656942b 100644 --- a/include/Foundation/NSNetServices.h +++ b/include/Foundation/NSNetServices.h @@ -50,7 +50,14 @@ FOUNDATION_EXPORT NSString * const NSNetServicesErrorDomain; @end +@class NSNetServicesInternal; +typedef struct __CFNetService* CFNetServiceRef; @interface NSNetService : NSObject +{ + CFNetServiceRef _netService; + id _delegate; + NSNetServicesInternal *_reserved; +} + (NSDictionary *)dictionaryFromTXTRecordData:(NSData *)txtData; + (NSData *)dataFromTXTRecordDictionary:(NSDictionary *)txtDictionary; @@ -79,7 +86,14 @@ FOUNDATION_EXPORT NSString * const NSNetServicesErrorDomain; @end +typedef struct __CFNetServiceBrowser* CFNetServiceBrowserRef; @interface NSNetServiceBrowser : NSObject +{ + CFNetServiceBrowserRef _netServiceBrowser; + id _delegate; + void *_tbd; + BOOL _includesPeerToPeer; +} - (id)init; - (id )delegate; diff --git a/include/Foundation/NSNotification.h b/include/Foundation/NSNotification.h index 12b2554c8..f3019f5ad 100644 --- a/include/Foundation/NSNotification.h +++ b/include/Foundation/NSNotification.h @@ -1,6 +1,7 @@ #import +#import -@class NSString, NSDictionary, NSOperationQueue; +@class NSString, NSDictionary, NSOperationQueue, NSMutableArray; @interface NSNotification : NSObject @@ -18,6 +19,10 @@ @end @interface NSNotificationCenter : NSObject +{ + NSMutableArray *_observers; + pthread_mutex_t _observersLock; +} + (id)defaultCenter; - (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSString *)aName object:(id)anObject; diff --git a/include/Foundation/NSNotificationQueue.h b/include/Foundation/NSNotificationQueue.h index 62be27d52..616f64ed1 100644 --- a/include/Foundation/NSNotificationQueue.h +++ b/include/Foundation/NSNotificationQueue.h @@ -1,6 +1,6 @@ #import -@class NSNotification, NSNotificationCenter, NSArray; +@class NSNotification, NSNotificationCenter, NSArray, NSMutableArray; typedef NS_ENUM(NSUInteger, NSPostingStyle) { NSPostWhenIdle = 1, @@ -15,6 +15,13 @@ typedef NS_ENUM(NSUInteger, NSNotificationCoalescing) { }; @interface NSNotificationQueue : NSObject +{ + NSNotificationCenter *_notificationCenter; + NSMutableArray *_asapQueue; + NSMutableArray *_asapObs; + NSMutableArray *_idleQueue; + NSMutableArray *_idleObs; +} + (id)defaultQueue; - (id)initWithNotificationCenter:(NSNotificationCenter *)notificationCenter; diff --git a/include/Foundation/NSNumberFormatter.h b/include/Foundation/NSNumberFormatter.h index 222489521..dad45a5f0 100644 --- a/include/Foundation/NSNumberFormatter.h +++ b/include/Foundation/NSNumberFormatter.h @@ -34,7 +34,13 @@ typedef NS_ENUM(NSUInteger, NSNumberFormatterRoundingMode) { @class NSLocale, NSError, NSMutableDictionary; +typedef struct __CFNumberFormatter* CFNumberFormatterRef; + @interface NSNumberFormatter : NSFormatter +{ + NSMutableDictionary *_attributes; + CFNumberFormatterRef _formatter; +} + (NSString *)localizedStringFromNumber:(NSNumber *)num numberStyle:(NSNumberFormatterStyle)nstyle; + (NSNumberFormatterBehavior)defaultFormatterBehavior; diff --git a/include/Foundation/NSOperation.h b/include/Foundation/NSOperation.h index 4cf23259f..991323ad1 100644 --- a/include/Foundation/NSOperation.h +++ b/include/Foundation/NSOperation.h @@ -1,4 +1,6 @@ #import +#import +#import @class NSArray, NSSet; @@ -17,7 +19,11 @@ enum { FOUNDATION_EXPORT NSString * const NSInvocationOperationVoidResultException; FOUNDATION_EXPORT NSString * const NSInvocationOperationCancelledException; +@class _NSOperationInternal; @interface NSOperation : NSObject +{ + _NSOperationInternal *_internal; +} - (id)init; - (void)start; @@ -43,7 +49,12 @@ FOUNDATION_EXPORT NSString * const NSInvocationOperationCancelledException; @end +@class NSMutableArray; @interface NSBlockOperation : NSOperation +{ + dispatch_block_t _block; + NSMutableArray *_blocks; +} #if NS_BLOCKS_AVAILABLE + (id)blockOperationWithBlock:(void (^)(void))block; @@ -54,6 +65,9 @@ FOUNDATION_EXPORT NSString * const NSInvocationOperationCancelledException; @end @interface NSInvocationOperation : NSOperation +{ + NSInvocation *_inv; +} - (id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg; - (id)initWithInvocation:(NSInvocation *)inv; @@ -62,7 +76,24 @@ FOUNDATION_EXPORT NSString * const NSInvocationOperationCancelledException; @end +@class NSMutableArray, _NSOperationQueueInternal; + @interface NSOperationQueue : NSObject +{ + BOOL _suspended; + NSString *_name; + NSInteger _maxConcurrentOperationCount; + pthread_mutex_t _queuelock; + pthread_mutexattr_t _mta; + + NSMutableArray *_pendingOperations; + NSMutableArray *_operations; + NSMutableArray *_operationsToStart; + + _NSOperationQueueInternal *_internal; + + BOOL _isMainQueue; +} + (id)currentQueue; + (id)mainQueue; diff --git a/include/Foundation/NSPointerArray.h b/include/Foundation/NSPointerArray.h index 67771fc21..93f01c1e1 100644 --- a/include/Foundation/NSPointerArray.h +++ b/include/Foundation/NSPointerArray.h @@ -2,7 +2,45 @@ #import #import +@class NSWeakCallback; + +struct NSSlice { + void **items; + BOOL wantsStrong; + BOOL wantsWeak; + BOOL wantsARC; + BOOL shouldCopyIn; + BOOL usesStrong; + BOOL usesWeak; + BOOL usesARC; + BOOL usesSentinel; + BOOL pointerPersonality; + BOOL integerPersonality; + BOOL simpleReadClear; + NSWeakCallback *callback; + NSUInteger (*sizeFunction)(const void *item); + NSUInteger (*hashFunction)(const void *item, NSUInteger (*size)(const void *item)); + BOOL (*isEqualFunction)(const void *item1, const void*item2, NSUInteger (*size)(const void *item)); + NSString *(*describeFunction)(const void *item); + void *(*acquireFunction)(const void *src, NSUInteger (*size)(const void *item), BOOL shouldCopy); + void (*relinquishFunction)(const void *item, NSUInteger (*size)(const void *item)); + void *(*allocateFunction)(size_t count); + void (*freeFunction)(void **buffer, NSUInteger size); + void *(*readAt)(void **ptr, BOOL *wasSentinel); + void (*clearAt)(void **ptr); + void (*storeAt)(void **buffer, void *item, NSUInteger index); +}; + + @interface NSPointerArray : NSObject +{ + struct NSSlice slice; + NSUInteger count; + NSUInteger capacity; + NSUInteger options; + NSUInteger mutations; + BOOL needsCompaction; +} + (id)pointerArrayWithOptions:(NSPointerFunctionsOptions)options; + (id)pointerArrayWithPointerFunctions:(NSPointerFunctions *)functions; diff --git a/include/Foundation/NSPointerFunctions.h b/include/Foundation/NSPointerFunctions.h index ac2f20dc6..bf4349d81 100644 --- a/include/Foundation/NSPointerFunctions.h +++ b/include/Foundation/NSPointerFunctions.h @@ -5,6 +5,7 @@ enum { NSPointerFunctionsStrongMemory = (0UL << 0), + NSPointerFunctionsZeroingWeakMemory = (1UL << 0), NSPointerFunctionsOpaqueMemory = (2UL << 0), NSPointerFunctionsMallocMemory = (3UL << 0), NSPointerFunctionsMachVirtualMemory = (4UL << 0), diff --git a/include/Foundation/NSPort.h b/include/Foundation/NSPort.h index c84c4d228..65594a5ab 100644 --- a/include/Foundation/NSPort.h +++ b/include/Foundation/NSPort.h @@ -46,6 +46,12 @@ FOUNDATION_EXPORT NSString * const NSPortDidBecomeInvalidNotification; NS_AUTOMATED_REFCOUNT_WEAK_UNAVAILABLE @interface NSMachPort : NSPort +{ + id _delegate; + NSUInteger _flags; + uint32_t _machPort; + NSUInteger _reserved; +} + (NSPort *)portWithMachPort:(uint32_t)machPort; + (NSPort *)portWithMachPort:(uint32_t)machPort options:(NSUInteger)f; diff --git a/include/Foundation/NSPredicate.h b/include/Foundation/NSPredicate.h index c71e59be2..ed04b33ce 100644 --- a/include/Foundation/NSPredicate.h +++ b/include/Foundation/NSPredicate.h @@ -3,7 +3,15 @@ #import #import +typedef NS_OPTIONS(NSUInteger, NSPredicateEvaluationFlags) { + NSPredicateEvaluationBlocked = 1 << 0, +}; + @interface NSPredicate : NSObject +{ + NSPredicateEvaluationFlags _predicateFlags; + NSUInteger reserved; +} + (NSPredicate *)predicateWithFormat:(NSString *)predicateFormat argumentArray:(NSArray *)arguments; + (NSPredicate *)predicateWithFormat:(NSString *)predicateFormat, ...; diff --git a/include/Foundation/NSProcessInfo.h b/include/Foundation/NSProcessInfo.h index 7d6282fa0..6cbc7ea2c 100644 --- a/include/Foundation/NSProcessInfo.h +++ b/include/Foundation/NSProcessInfo.h @@ -15,6 +15,13 @@ enum { @class NSArray, NSString, NSDictionary; @interface NSProcessInfo : NSObject +{ + NSDictionary *environment; // not used it seems + NSArray *arguments; // is really mutable + NSString *hostName; // singly created + NSString *name; // singly created, but replaceable + NSInteger automaticTerminationOptOutCounter; +} + (NSProcessInfo *)processInfo; diff --git a/include/Foundation/NSRegularExpression.h b/include/Foundation/NSRegularExpression.h index dea45cf75..624b01558 100644 --- a/include/Foundation/NSRegularExpression.h +++ b/include/Foundation/NSRegularExpression.h @@ -71,6 +71,9 @@ typedef NS_OPTIONS(NSUInteger, NSMatchingFlags) { @end @interface NSDataDetector : NSRegularExpression +{ + NSTextCheckingTypes _checkingTypes; +} @property (readonly) NSTextCheckingTypes checkingTypes; + (NSDataDetector *)dataDetectorWithTypes:(NSTextCheckingTypes)checkingTypes error:(NSError **)error; diff --git a/include/Foundation/NSSet.h b/include/Foundation/NSSet.h index 5ce68c1fb..a44ecd025 100644 --- a/include/Foundation/NSSet.h +++ b/include/Foundation/NSSet.h @@ -77,7 +77,12 @@ @end +typedef struct __CFBag* CFMutableBagRef; @interface NSCountedSet : NSMutableSet +{ + CFMutableBagRef _table; + void *_reserved; +} - (instancetype)initWithCapacity:(NSUInteger)numItems; - (instancetype)initWithArray:(NSArray *)array; diff --git a/include/Foundation/NSSortDescriptor.h b/include/Foundation/NSSortDescriptor.h index 285b0cbf3..a1a1d9d2b 100644 --- a/include/Foundation/NSSortDescriptor.h +++ b/include/Foundation/NSSortDescriptor.h @@ -2,6 +2,12 @@ #import @interface NSSortDescriptor : NSObject +{ + NSUInteger _sortDescriptorFlags; + NSString *_key; + SEL _selector; + id _selectorOrBlock; +} + (id)sortDescriptorWithKey:(NSString *)key ascending:(BOOL)ascending; + (id)sortDescriptorWithKey:(NSString *)key ascending:(BOOL)ascending selector:(SEL)selector; diff --git a/include/Foundation/NSThread.h b/include/Foundation/NSThread.h index 3a827456e..9a9a87622 100644 --- a/include/Foundation/NSThread.h +++ b/include/Foundation/NSThread.h @@ -1,13 +1,35 @@ #import #import +#import -@class NSArray, NSMutableDictionary, NSDate; +@class NSArray, NSMutableDictionary, NSDate, NSMutableArray; FOUNDATION_EXPORT NSString * const NSWillBecomeMultiThreadedNotification; FOUNDATION_EXPORT NSString * const NSDidBecomeSingleThreadedNotification; FOUNDATION_EXPORT NSString * const NSThreadWillExitNotification; +typedef enum { + NSThreadCreated, + NSThreadStarted, + NSThreadRunning, + NSThreadCancelling, + NSThreadEnding, + NSThreadFinished +} NSThreadState; + @interface NSThread : NSObject +{ +@package + pthread_t _thread; + pthread_attr_t _attr; + NSString *_name; + NSMutableDictionary *_threadDictionary; + NSThreadState _state; + NSMutableArray *_performers; + id _target; + SEL _selector; + id _argument; +} + (NSThread *)currentThread; + (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument; diff --git a/include/Foundation/NSURLAuthenticationChallenge.h b/include/Foundation/NSURLAuthenticationChallenge.h index aa96f4c99..159717d64 100644 --- a/include/Foundation/NSURLAuthenticationChallenge.h +++ b/include/Foundation/NSURLAuthenticationChallenge.h @@ -17,6 +17,14 @@ @end @interface NSURLAuthenticationChallenge : NSObject +{ + NSURLProtectionSpace *_protectionSpace; + NSURLCredential *_proposedCredential; + NSInteger _previousFailureCount; + NSURLResponse *_failureResponse; + NSError *_error; + id _sender; +} - (id)initWithProtectionSpace:(NSURLProtectionSpace *)space proposedCredential:(NSURLCredential *)credential previousFailureCount:(NSInteger)previousFailureCount failureResponse:(NSURLResponse *)response error:(NSError *)error sender:(id)sender; - (id)initWithAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge sender:(id)sender; diff --git a/include/Foundation/NSURLCache.h b/include/Foundation/NSURLCache.h index e31ec37d2..25f08d84e 100644 --- a/include/Foundation/NSURLCache.h +++ b/include/Foundation/NSURLCache.h @@ -8,7 +8,13 @@ typedef NS_ENUM(NSUInteger, NSURLCacheStoragePolicy) { @class NSData, NSDictionary, NSURLRequest, NSURLResponse; +typedef struct _CFCachedURLResponse* CFCachedURLResponseRef; + @interface NSCachedURLResponse : NSObject +{ + NSURLResponse* _response; + CFCachedURLResponseRef _cachedResponseRef; +} - (id)initWithResponse:(NSURLResponse *)response data:(NSData *)data; - (id)initWithResponse:(NSURLResponse *)response data:(NSData *)data userInfo:(NSDictionary *)userInfo storagePolicy:(NSURLCacheStoragePolicy)storagePolicy; @@ -19,7 +25,12 @@ typedef NS_ENUM(NSUInteger, NSURLCacheStoragePolicy) { @end +typedef struct _CFURLCache* CFURLCacheRef; + @interface NSURLCache : NSObject +{ + CFURLCacheRef _cacheRef; +} + (NSURLCache *)sharedURLCache; + (void)setSharedURLCache:(NSURLCache *)cache; diff --git a/include/Foundation/NSURLConnection.h b/include/Foundation/NSURLConnection.h index fa598bf89..4688bc146 100644 --- a/include/Foundation/NSURLConnection.h +++ b/include/Foundation/NSURLConnection.h @@ -6,7 +6,12 @@ @protocol NSURLConnectionDelegate; +@class NSURLConnectionInternal; + @interface NSURLConnection : NSObject +{ + NSURLConnectionInternal *_internal; +} + (NSURLConnection*)connectionWithRequest:(NSURLRequest *)request delegate:(id)delegate; + (BOOL)canHandleRequest:(NSURLRequest *)request; diff --git a/include/Foundation/NSURLProtectionSpace.h b/include/Foundation/NSURLProtectionSpace.h index 4068a2814..c5bd591ba 100644 --- a/include/Foundation/NSURLProtectionSpace.h +++ b/include/Foundation/NSURLProtectionSpace.h @@ -19,7 +19,12 @@ FOUNDATION_EXPORT NSString * const NSURLAuthenticationMethodNegotiate; FOUNDATION_EXPORT NSString * const NSURLAuthenticationMethodClientCertificate; FOUNDATION_EXPORT NSString * const NSURLAuthenticationMethodServerTrust; +@class NSURLProtectionSpaceInternal; + @interface NSURLProtectionSpace : NSObject +{ + NSURLProtectionSpaceInternal *_internal; +} - (id)initWithHost:(NSString *)host port:(NSInteger)port protocol:(NSString *)protocol realm:(NSString *)realm authenticationMethod:(NSString *)authenticationMethod; - (id)initWithProxyHost:(NSString *)host port:(NSInteger)port type:(NSString *)type realm:(NSString *)realm authenticationMethod:(NSString *)authenticationMethod; - (NSString *)realm; diff --git a/include/Foundation/NSURLProtocol.h b/include/Foundation/NSURLProtocol.h index 646613145..2098eabd2 100644 --- a/include/Foundation/NSURLProtocol.h +++ b/include/Foundation/NSURLProtocol.h @@ -18,6 +18,11 @@ @end @interface NSURLProtocol : NSObject +{ + NSCachedURLResponse *_cachedResponse; + NSURLRequest *_request; + id _client; +} + (BOOL)canInitWithRequest:(NSURLRequest *)request; + (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request; diff --git a/include/Foundation/NSURLRequest.h b/include/Foundation/NSURLRequest.h index b34d15725..054adc369 100644 --- a/include/Foundation/NSURLRequest.h +++ b/include/Foundation/NSURLRequest.h @@ -21,7 +21,12 @@ typedef NS_ENUM(NSUInteger, NSURLRequestNetworkServiceType) { NSURLNetworkServiceTypeVoice = 4 }; +@class NSURLRequestInternal; + @interface NSURLRequest : NSObject +{ + NSURLRequestInternal *_internal; +} + (id)requestWithURL:(NSURL *)URL; + (id)requestWithURL:(NSURL *)URL cachePolicy:(NSURLRequestCachePolicy)cachePolicy timeoutInterval:(NSTimeInterval)timeoutInterval; diff --git a/include/Foundation/NSURLResponse.h b/include/Foundation/NSURLResponse.h index b00e54db2..6b76c3107 100644 --- a/include/Foundation/NSURLResponse.h +++ b/include/Foundation/NSURLResponse.h @@ -4,7 +4,12 @@ #define NSURLResponseUnknownLength ((long long)-1) +@class NSURLResponseInternal; + @interface NSURLResponse : NSObject +{ + NSURLResponseInternal *_internal; +} - (id)initWithURL:(NSURL *)URL MIMEType:(NSString *)MIMEType expectedContentLength:(NSInteger)length textEncodingName:(NSString *)name; - (NSURL *)URL; @@ -15,7 +20,12 @@ @end +@class NSHTTPURLResponseInternal; + @interface NSHTTPURLResponse : NSURLResponse +{ + NSHTTPURLResponseInternal *_httpInternal; +} + (NSString *)localizedStringForStatusCode:(NSInteger)statusCode; - (id)initWithURL:(NSURL*)URL statusCode:(NSInteger)statusCode HTTPVersion:(NSString*)HTTPVersion headerFields:(NSDictionary *)headerFields; diff --git a/include/Foundation/NSUbiquitousKeyValueStore.h b/include/Foundation/NSUbiquitousKeyValueStore.h index aa61da3a4..a745dd593 100644 --- a/include/Foundation/NSUbiquitousKeyValueStore.h +++ b/include/Foundation/NSUbiquitousKeyValueStore.h @@ -1,4 +1,5 @@ #import +#import enum { NSUbiquitousKeyValueStoreServerChange NS_ENUM_AVAILABLE(10_7, 5_0), @@ -13,7 +14,13 @@ FOUNDATION_EXPORT NSString * const NSUbiquitousKeyValueStoreDidChangeExternallyN FOUNDATION_EXPORT NSString * const NSUbiquitousKeyValueStoreChangeReasonKey; FOUNDATION_EXPORT NSString * const NSUbiquitousKeyValueStoreChangedKeysKey; +@protocol _NSUbiquitousKeyValueStoreProvider; + @interface NSUbiquitousKeyValueStore : NSObject +{ + id<_NSUbiquitousKeyValueStoreProvider> _provider; + dispatch_queue_t _providerQueue; +} + (NSUbiquitousKeyValueStore *)defaultStore; - (id)objectForKey:(NSString *)aKey; diff --git a/include/Foundation/NSUserDefaults.h b/include/Foundation/NSUserDefaults.h index 5818c7266..870743dea 100644 --- a/include/Foundation/NSUserDefaults.h +++ b/include/Foundation/NSUserDefaults.h @@ -7,7 +7,18 @@ FOUNDATION_EXPORT NSString * const NSArgumentDomain; FOUNDATION_EXPORT NSString * const NSRegistrationDomain; FOUNDATION_EXPORT NSString * const NSUserDefaultsDidChangeNotification; +// Because this the real type is difficult to forward declare +// without modifying CF +#ifndef PREFS_TYPE +# define PREFS_TYPE void +#endif + @interface NSUserDefaults : NSObject +{ + PREFS_TYPE *_cfDataPtr; +} + +#undef PREFS_TYPE + (NSUserDefaults *)standardUserDefaults; + (void)resetStandardUserDefaults; diff --git a/include/Foundation/NSXMLParser.h b/include/Foundation/NSXMLParser.h index fc3a16dad..526a5821e 100644 --- a/include/Foundation/NSXMLParser.h +++ b/include/Foundation/NSXMLParser.h @@ -126,7 +126,14 @@ FOUNDATION_EXPORT NSString * const NSXMLParserErrorDomain; @end +@class _NSXMLParserInfo, NSStream; @interface NSXMLParser : NSObject +{ + id _delegate; + _NSXMLParserInfo *_info; + NSData *_data; + NSStream *_stream; +} - (id)initWithContentsOfURL:(NSURL *)url; - (id)initWithData:(NSData *)data; diff --git a/src/GSIMap.h b/src/GSIMap.h new file mode 100644 index 000000000..1c377123d --- /dev/null +++ b/src/GSIMap.h @@ -0,0 +1,1270 @@ +/* A fast (Inline) map/hash table implementation for NSObjects + * Copyright (C) 1998,1999 Free Software Foundation, Inc. + * + * Author: Richard Frith-Macdonald + * Created: Thu Oct 1 09:30:00 GMT 1998 + * + * Based on original o_map code by Albin L. Jones + * + * This file is part of the GNUstep Base Library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02111 USA. */ + +#if defined(GNUSTEP_BASE_INTERNAL) +#import "Foundation/NSObject.h" +#import "Foundation/NSEnumerator.h" +#import "Foundation/NSException.h" +#import "Foundation/NSGarbageCollector.h" +#import "Foundation/NSZone.h" +#else +#import +#import +#import +#import +#import +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +/* To easily un-inline functions for debugging */ +#ifndef GS_STATIC_INLINE +#define GS_STATIC_INLINE static inline +#endif + + +/* + * NB. This file is intended for internal use by the GNUstep libraries + * and may change siugnificantly between releases. + * While it is unlikley to be removed from the distributiuon any time + * soon, its use by other software is not officially supported. + * + * This file should be INCLUDED in files wanting to use the GSIMap + * functions - these are all declared inline for maximum performance. + * + * The file including this one may predefine some macros to alter + * the behaviour + * + * GSI_MAP_HAS_VALUE + * If defined as 0, then this becomes a hash table rather than + * a map table. + * + * GSI_MAP_RETAIN_KEY() + * Macro to retain the key item in a map or hash table. + * + * GSI_MAP_RETAIN_VAL() + * Macro to retain the value item in a map table. + * + * GSI_MAP_RELEASE_KEY() + * Macro to release the key item in a map or hash table. + * + * GSI_MAP_RELEASE_VAL() + * Macro to release the value item in a map table. + * + * GSI_MAP_WRITE_KEY() + * Macro defining the write barrier for a key. + * + * GSI_MAP_WRITE_VAL() + * Macro defining the write barrier for a value. + * + * GSI_MAP_READ_KEY() + * Macro defining the read barrier for a key. + * + * GSI_MAP_HASH() + * Macro to get the hash of a key item. + * + * GSI_MAP_EQUAL() + * Macro to compare two key items for equality - produces zero + * if the items are not equal. + * + * GSI_MAP_EXTRA + * If this value is defined, there is an 'extra' field in each + * map table whose type is that specified by the value of the + * preprocessor constant. This field can be used + * to store additional information for the map. + * + * GSI_MAP_NOCLEAN + * Define this to a non-zero integer value if the map keys and + * values do not need to be released when the map is emptied. + * This permits some optimisation. + * + * GSI_MAP_NODES() + * Define this macro to allocate nodes for the map using typed + * memory when working with garbage collection. + * + * GSI_MAP_ZEROED() + * Define this macro to check whether a map uses keys which may + * be zeroed weak pointers. + */ + +#ifndef GSI_MAP_HAS_VALUE +#define GSI_MAP_HAS_VALUE 1 +#endif + +#ifndef GSI_MAP_RETAIN_KEY +#define GSI_MAP_RETAIN_KEY(M, X) [(X).obj retain] +#endif +#ifndef GSI_MAP_RELEASE_KEY +#define GSI_MAP_RELEASE_KEY(M, X) [(X).obj release] +#endif +#ifndef GSI_MAP_RETAIN_VAL +#define GSI_MAP_RETAIN_VAL(M, X) [(X).obj retain] +#endif +#ifndef GSI_MAP_RELEASE_VAL +#define GSI_MAP_RELEASE_VAL(M, X) [(X).obj release] +#endif +#ifndef GSI_MAP_HASH +#define GSI_MAP_HASH(M, X) [(X).obj hash] +#endif +#ifndef GSI_MAP_EQUAL +#define GSI_MAP_EQUAL(M, X, Y) [(X).obj isEqual: (Y).obj] +#endif +#ifndef GSI_MAP_NODES +#define GSI_MAP_NODES(M, X) \ +(GSIMapNode)NSAllocateCollectable(X*sizeof(GSIMapNode_t), NSScannedOption) +#endif +#ifndef GSI_MAP_ZEROED +#define GSI_MAP_ZEROED(M) 0 +#endif +#ifndef GSI_MAP_READ_KEY +# define GSI_MAP_READ_KEY(M, x) (*(x)) +#endif +#ifndef GSI_MAP_READ_VALUE +# define GSI_MAP_READ_VALUE(M, x) (*(x)) +#endif +#ifndef GSI_MAP_WRITE_KEY +# define GSI_MAP_WRITE_KEY(M, addr, obj) (*(addr) = obj) +#endif +#ifndef GSI_MAP_WRITE_VAL +# define GSI_MAP_WRITE_VAL(M, addr, obj) (*(addr) = obj) +#endif +#if GSI_MAP_HAS_VALUE +#define GSI_MAP_NODE_IS_EMPTY(M, node) (((GSI_MAP_READ_VALUE(M, &node->key).addr) == 0) || ((GSI_MAP_READ_VALUE(M, &node->value).addr == 0))) +#else +#define GSI_MAP_NODE_IS_EMPTY(M, node) (((GSI_MAP_READ_VALUE(M, &node->key).addr) == 0)) +#endif + +/* + * If there is no bitmask defined to supply the types that + * may be used as keys in the map, default to none. + */ +#ifndef GSI_MAP_KTYPES +#define GSI_MAP_KTYPES 0 +#endif + +/* + * Set up the name of the union to store keys. + */ +#ifdef GSUNION +#undef GSUNION +#endif +#define GSUNION GSIMapKey + +/* + * Set up the types that will be storable in the union. + * See 'GSUnion.h' for further information. + */ +#ifdef GSUNION_TYPES +#undef GSUNION_TYPES +#endif +#define GSUNION_TYPES GSI_MAP_KTYPES +#ifdef GSUNION_EXTRA +#undef GSUNION_EXTRA +#endif +#ifdef GSI_MAP_KEXTRA +#define GSUNION_EXTRA GSI_MAP_KEXTRA +#endif + +/* + * Generate the union typedef + */ +#if defined(GNUSTEP_BASE_INTERNAL) +#include "GNUstepBase/GSUnion.h" +#else +#include "GSUnion.h" +#endif + + +#if (GSI_MAP_KTYPES) & GSUNION_OBJ +#define GSI_MAP_CLEAR_KEY(node) GSI_MAP_WRITE_KEY(map, &node->key, (GSIMapKey)(id)nil) +#elif (GSI_MAP_KTYPES) & GSUNION_PTR +#define GSI_MAP_CLEAR_KEY(node) GSI_MAP_WRITE_KEY(map, &node->key, (GSIMapKey)(void *)NULL) +#else +#define GSI_MAP_CLEAR_KEY(node) +#endif + +/* + * If there is no bitmask defined to supply the types that + * may be used as values in the map, default to none. + */ +#ifndef GSI_MAP_VTYPES +#define GSI_MAP_VTYPES 0 +#endif + +/* + * Set up the name of the union to store map values. + */ +#ifdef GSUNION +#undef GSUNION +#endif +#define GSUNION GSIMapVal + +/* + * Set up the types that will be storable in the union. + * See 'GSUnion.h' for further information. + */ +#ifdef GSUNION_TYPES +#undef GSUNION_TYPES +#endif +#define GSUNION_TYPES GSI_MAP_VTYPES +#ifdef GSUNION_EXTRA +#undef GSUNION_EXTRA +#endif +#ifdef GSI_MAP_VEXTRA +#define GSUNION_EXTRA GSI_MAP_VEXTRA +#endif + +#ifndef GSI_MAP_SIMPLE +#define GSI_MAP_SIMPLE 0 +#endif + +/* + * Generate the union typedef + */ +#if defined(GNUSTEP_BASE_INTERNAL) +#include "GNUstepBase/GSUnion.h" +#else +#include "GSUnion.h" +#endif + +#if (GSI_MAP_VTYPES) & GSUNION_OBJ +#define GSI_MAP_CLEAR_VAL(node) GSI_MAP_WRITE_VAL(map, &node->value, (GSIMapVal)(id)nil) +#elif (GSI_MAP_VTYPES) & GSUNION_PTR +#define GSI_MAP_CLEAR_VAL(node) GSI_MAP_WRITE_VAL(map, &node->value, (GSIMapVal)(void *)NULL) +#else +#define GSI_MAP_CLEAR_VAL(node) +#endif + +/* + * Description of the datastructure + * -------------------------------- + * The complete GSIMap implementation can be viewed in two different ways, + * + * (1) viewed as a structure to add and retrieve elements + * (2) viewed as a memory management structure to facilitate (1) + * + * The first view is best described as follows: + * + * _GSIMapTable -----> C-array of buckets + * + * Where each bucket contains a count (nodeCount), describing the number + * of nodes in the bucket and a pointer (firstNode) to a single linked + * list of nodes. + * + * The second view is slightly more complicated. + * The individual nodes are allocated and deallocated in chunks. + * In order to keep track of this we have: + * + * _GSIMapTable -----> C-array of chunks + * + * Where each chunk points to a C-array of nodes. + * Also the _GSIMapTable contains a pointer to the free nodes + * + * _GSIMapTable -----> single linked list of free nodes + * + * Consequence of this is that EVERY node is part of a single linked list. + * Either it is in use and reachable from a bucket, or it is part of the + * freeNodes linked list. + * Also EVERY node is part of chunk, due to the way the nodes are allocated. + * + * A rough picture is include below: + * + * + * This is the map C - array of the buckets + * +---------------+ +---------------+ + * | _GSIMapTable | /----->| nodeCount | + * |---------------| / | firstNode ----+--\ + * | buckets ---+----/ | .......... | | + * | bucketCount =| size of --> | nodeCount | | + * | nodeChunks ---+--\ | firstNode | | + * | chunkCount =-+\ | | . | | + * | .... || | | . | | + * +---------------+| | | nodeCount | | + * | | | fistNode | | + * / | +---------------+ | + * ---------- v v + * / +----------+ +---------------------------+ + * | | * ------+----->| Node1 | Node2 | Node3 ... | a chunk + * chunkCount | * ------+--\ +---------------------------+ + * is size of = | . | \ +-------------------------------+ + * | . | ->| Node n | Node n + 1 | ... | another + * +----------+ +-------------------------------+ + * array pointing + * to the chunks + * + * + * NOTES on the way chunks are allocated + * ------------------------------------- + * Chunks are allocated when needed, that is a new chunk is allocated + * whenever the freeNodes list is empty and a new node is required. + * In gnustep-base-1.9.0 the size of the new chunk is calculated as + * roughly 3/4 of the number of nodes in use. + * The problem with this approach is that it can lead to unnecessary + * address space fragmentation. So in this version the algorithm we + * will use the 3/4 rule until the nodeCount reaches the "increment" + * member variable. + * If nodeCount is bigger than the "increment" it will allocate chunks + * of size "increment". + */ + +#if !defined(GSI_MAP_TABLE_T) +typedef struct _GSIMapBucket GSIMapBucket_t; +typedef struct _GSIMapNode GSIMapNode_t; + +typedef GSIMapBucket_t *GSIMapBucket; +typedef GSIMapNode_t *GSIMapNode; +#endif + +struct _GSIMapNode { + GSIMapNode nextInBucket; /* Linked list of bucket. */ + GSIMapKey key; +#if GSI_MAP_HAS_VALUE + GSIMapVal value; +#endif +}; + +struct _GSIMapBucket { + uintptr_t nodeCount; /* Number of nodes in bucket. */ + GSIMapNode firstNode; /* The linked list of nodes. */ +}; + +#if defined(GSI_MAP_TABLE_T) +typedef GSI_MAP_TABLE_T *GSIMapTable; +#else +typedef struct _GSIMapTable GSIMapTable_t; +typedef GSIMapTable_t *GSIMapTable; + +struct _GSIMapTable { + NSZone *zone; + uintptr_t nodeCount; /* Number of used nodes in map. */ + uintptr_t bucketCount; /* Number of buckets in map. */ + GSIMapBucket buckets; /* Array of buckets. */ + GSIMapNode freeNodes; /* List of unused nodes. */ + uintptr_t chunkCount; /* Number of chunks in array. */ + GSIMapNode *nodeChunks; /* Chunks of allocated memory. */ + uintptr_t increment; +#ifdef GSI_MAP_EXTRA + GSI_MAP_EXTRA extra; +#endif +}; +#define GSI_MAP_TABLE_T GSIMapTable_t +#endif + +#ifndef GSI_MAP_TABLE_S +#define GSI_MAP_TABLE_S sizeof(GSI_MAP_TABLE_T) +#endif + +typedef struct _GSIMapEnumerator { + GSIMapTable map; /* the map being enumerated. */ + GSIMapNode node; /* The next node to use. */ + uintptr_t bucket; /* The next bucket to use. */ +} *_GSIE; + +#ifdef GSI_MAP_ENUMERATOR +typedef GSI_MAP_ENUMERATOR GSIMapEnumerator_t; +#else +typedef struct _GSIMapEnumerator GSIMapEnumerator_t; +#endif +typedef GSIMapEnumerator_t *GSIMapEnumerator; + +GS_STATIC_INLINE GSIMapBucket +GSIMapPickBucket(unsigned hash, GSIMapBucket buckets, uintptr_t bucketCount) +{ + return buckets + hash % bucketCount; +} + +GS_STATIC_INLINE GSIMapBucket +GSIMapBucketForKey(GSIMapTable map, GSIMapKey key) +{ + return GSIMapPickBucket(GSI_MAP_HASH(map, key), + map->buckets, map->bucketCount); +} + +GS_STATIC_INLINE void +GSIMapLinkNodeIntoBucket(GSIMapBucket bucket, GSIMapNode node) +{ + node->nextInBucket = bucket->firstNode; + bucket->firstNode = node; +} + +GS_STATIC_INLINE void +GSIMapUnlinkNodeFromBucket(GSIMapBucket bucket, GSIMapNode node) +{ + if (node == bucket->firstNode) + { + bucket->firstNode = node->nextInBucket; + } + else + { + GSIMapNode tmp = bucket->firstNode; + + while (tmp->nextInBucket != node) + { + tmp = tmp->nextInBucket; + } + tmp->nextInBucket = node->nextInBucket; + } + node->nextInBucket = 0; +} + +GS_STATIC_INLINE void +GSIMapAddNodeToBucket(GSIMapBucket bucket, GSIMapNode node) +{ + GSIMapLinkNodeIntoBucket(bucket, node); + bucket->nodeCount += 1; +} + +GS_STATIC_INLINE void +GSIMapAddNodeToMap(GSIMapTable map, GSIMapNode node) +{ + GSIMapBucket bucket; + + bucket = GSIMapBucketForKey(map, node->key); + GSIMapAddNodeToBucket(bucket, node); + map->nodeCount++; +} + +GS_STATIC_INLINE void +GSIMapRemoveNodeFromBucket(GSIMapBucket bucket, GSIMapNode node) +{ + bucket->nodeCount--; + GSIMapUnlinkNodeFromBucket(bucket, node); +} + +GS_STATIC_INLINE void +GSIMapRemoveNodeFromMap(GSIMapTable map, GSIMapBucket bkt, GSIMapNode node) +{ + map->nodeCount--; + GSIMapRemoveNodeFromBucket(bkt, node); +} + +GS_STATIC_INLINE void +GSIMapFreeNode(GSIMapTable map, GSIMapNode node) +{ + GSI_MAP_RELEASE_KEY(map, node->key); + GSI_MAP_CLEAR_KEY(node); +#if GSI_MAP_HAS_VALUE + GSI_MAP_RELEASE_VAL(map, node->value); + GSI_MAP_CLEAR_VAL(node); +#endif + + node->nextInBucket = map->freeNodes; + map->freeNodes = node; +} + +GS_STATIC_INLINE GSIMapNode +GSIMapRemoveAndFreeNode(GSIMapTable map, uintptr_t bkt, GSIMapNode node) +{ + GSIMapNode next = node->nextInBucket; + GSIMapRemoveNodeFromMap(map, &(map->buckets[bkt]), node); + GSIMapFreeNode(map, node); + return next; +} + +GS_STATIC_INLINE void +GSIMapRemoveWeak(GSIMapTable map) +{ + if (GSI_MAP_ZEROED(map)) + { + uintptr_t bucketCount = map->bucketCount; + GSIMapBucket bucket = map->buckets; + + while (bucketCount-- > 0) + { + GSIMapNode node = bucket->firstNode; + + while (node != 0) + { + GSIMapNode next = node->nextInBucket; + if (GSI_MAP_NODE_IS_EMPTY(map, node)) + { + GSIMapRemoveNodeFromMap(map, bucket, node); + GSIMapFreeNode(map, node); + } + node = next; + } + bucket++; + } + return; + } +} + +GS_STATIC_INLINE void +GSIMapRemangleBuckets(GSIMapTable map, + GSIMapBucket old_buckets, uintptr_t old_bucketCount, + GSIMapBucket new_buckets, uintptr_t new_bucketCount) +{ + if (GSI_MAP_ZEROED(map)) + { + while (old_bucketCount-- > 0) + { + GSIMapNode node; + + while ((node = old_buckets->firstNode) != 0) + { + if (GSI_MAP_NODE_IS_EMPTY(map, node)) + { + GSIMapRemoveNodeFromMap(map, old_buckets, node); + GSIMapFreeNode(map, node); + } + else + { + GSIMapBucket bkt; + + GSIMapRemoveNodeFromBucket(old_buckets, node); + bkt = GSIMapPickBucket(GSI_MAP_HASH(map, node->key), + new_buckets, new_bucketCount); + GSIMapAddNodeToBucket(bkt, node); + } + } + old_buckets++; + } + return; + } + while (old_bucketCount-- > 0) + { + GSIMapNode node; + + while ((node = old_buckets->firstNode) != 0) + { + GSIMapBucket bkt; + + GSIMapRemoveNodeFromBucket(old_buckets, node); + bkt = GSIMapPickBucket(GSI_MAP_HASH(map, node->key), + new_buckets, new_bucketCount); + GSIMapAddNodeToBucket(bkt, node); + } + old_buckets++; + } +} + +GS_STATIC_INLINE void +GSIMapMoreNodes(GSIMapTable map, unsigned required) +{ + GSIMapNode *newArray; + + newArray = (GSIMapNode*)NSZoneCalloc(map->zone, + (map->chunkCount+1), sizeof(GSIMapNode)); + if (newArray) + { + GSIMapNode newNodes; + uintptr_t chunkCount; + + if (map->nodeChunks != 0) + { + memcpy(newArray, map->nodeChunks, + (map->chunkCount)*sizeof(GSIMapNode)); + NSZoneFree(map->zone, map->nodeChunks); + } + map->nodeChunks = newArray; + + if (required == 0) + { + if (map->chunkCount == 0) + { + chunkCount = map->bucketCount > 1 ? map->bucketCount : 2; + } + else + { + chunkCount = ((map->nodeCount>>2)+1)<<1; + } + } + else + { + chunkCount = required; + } + newNodes + = (GSIMapNode)NSZoneCalloc(map->zone, chunkCount, sizeof(GSIMapNode_t)); + if (newNodes) + { + map->nodeChunks[map->chunkCount++] = newNodes; + newNodes[--chunkCount].nextInBucket = map->freeNodes; + while (chunkCount--) + { + newNodes[chunkCount].nextInBucket = &newNodes[chunkCount+1]; + } + map->freeNodes = newNodes; + } + else + { + [NSException raise: NSMallocException format: @"No memory for nodes"]; + } + } + else + { + [NSException raise: NSMallocException format: @"No memory for chunks"]; + } +} + +GS_STATIC_INLINE GSIMapNode +GSIMapNodeForKeyInBucket(GSIMapTable map, GSIMapBucket bucket, GSIMapKey key) +{ + GSIMapNode node = bucket->firstNode; + + if (GSI_MAP_ZEROED(map)) + { + while ((node != 0) + && GSI_MAP_EQUAL(map, GSI_MAP_READ_KEY(map, &node->key), key) == NO) + { + GSIMapNode tmp = node->nextInBucket; + + if (GSI_MAP_NODE_IS_EMPTY(map, node)) + { + GSIMapRemoveNodeFromMap(map, bucket, node); + GSIMapFreeNode(map, node); + } + node = tmp; + } + return node; + } + while ((node != 0) + && GSI_MAP_EQUAL(map, GSI_MAP_READ_KEY(map, &node->key), key) == NO) + { + node = node->nextInBucket; + } + return node; +} + +GS_STATIC_INLINE GSIMapNode +GSIMapNodeForKey(GSIMapTable map, GSIMapKey key) +{ + GSIMapBucket bucket; + GSIMapNode node; + + if (map->nodeCount == 0) + { + return 0; + } + bucket = GSIMapBucketForKey(map, key); + node = GSIMapNodeForKeyInBucket(map, bucket, key); + return node; +} + +GS_STATIC_INLINE GSIMapNode +GSIMapFirstNode(GSIMapTable map) +{ + if (map->nodeCount > 0) + { + uintptr_t count = map->bucketCount; + uintptr_t bucket = 0; + GSIMapNode node = 0; + + if (GSI_MAP_ZEROED(map)) + { + while (bucket < count) + { + node = map->buckets[bucket].firstNode; + while (node != 0 && GSI_MAP_NODE_IS_EMPTY(map, node)) + { + node = GSIMapRemoveAndFreeNode(map, bucket, node); + } + if (node != 0) + { + break; + } + bucket++; + } + return node; + } + while (bucket < count) + { + node = map->buckets[bucket].firstNode; + if (node != 0) + { + break; + } + bucket++; + } + return node; + } + else + { + return 0; + } +} + +#if (GSI_MAP_KTYPES & GSUNION_INT) +/* + * Specialized lookup for the case where keys are known to be simple integer + * or pointer values that are their own hash values (when converted to unsigned + * integers) and can be compared with a test for integer equality. + */ +GS_STATIC_INLINE GSIMapNode +GSIMapNodeForSimpleKey(GSIMapTable map, GSIMapKey key) +{ + GSIMapBucket bucket; + GSIMapNode node; + + if (map->nodeCount == 0) + { + return 0; + } + bucket = map->buckets + ((unsigned)key.addr) % map->bucketCount; + node = bucket->firstNode; + if (GSI_MAP_ZEROED(map)) + { + while ((node != 0) && GSI_MAP_READ_KEY(map, &node->key).addr != key.addr) + { + GSIMapNode tmp = node->nextInBucket; + + if (GSI_MAP_NODE_IS_EMPTY(map, node)) + { + GSIMapRemoveNodeFromMap(map, bucket, node); + GSIMapFreeNode(map, node); + } + node = tmp; + } + return node; + } + while ((node != 0) && GSI_MAP_READ_KEY(map, &node->key).addr != key.addr) + { + node = node->nextInBucket; + } + return node; +} +#endif + +GS_STATIC_INLINE void +GSIMapResize(GSIMapTable map, uintptr_t new_capacity) +{ + GSIMapBucket new_buckets; + uintptr_t size = 1; + uintptr_t old = 1; + + /* + * Find next size up in the fibonacci series + */ + while (size < new_capacity) + { + uintptr_t tmp = old; + + old = size; + size += tmp; + } + /* + * Avoid even numbers - since hash functions frequently generate uneven + * distributions around powers of two - + * we don't want lots of keys falling into a single bucket. + */ + if (size % 2 == 0) + { + size++; + } + + /* Use the zone specified for this map. + */ + new_buckets = (GSIMapBucket)NSZoneCalloc(map->zone, size, + sizeof(GSIMapBucket_t)); + + if (new_buckets != 0) + { + GSIMapRemangleBuckets(map, map->buckets, map->bucketCount, new_buckets, + size); + if (map->buckets != 0) + { + NSZoneFree(map->zone, map->buckets); + } + map->buckets = new_buckets; + map->bucketCount = size; + } +} + +GS_STATIC_INLINE void +GSIMapRightSizeMap(GSIMapTable map, uintptr_t capacity) +{ + /* FIXME: Now, this is a guess, based solely on my intuition. If anyone + * knows of a better ratio (or other test, for that matter) and can + * provide evidence of its goodness, please get in touch with me, Albin + * L. Jones . */ + + if (3 * capacity >= 4 * map->bucketCount) + { + GSIMapResize(map, (3 * capacity)/4 + 1); + } +} + +/** Enumerating **/ + +/* IMPORTANT WARNING: Enumerators have a wonderous property. + * Once a node has been returned by `GSIMapEnumeratorNextNode()', it may be + * removed from the map without effecting the rest of the current + * enumeration. */ + +/* EXTREMELY IMPORTANT WARNING: The purpose of this warning is point + * out that, various (i.e., many) functions currently depend on + * the behaviour outlined above. So be prepared for some serious + * breakage when you go fudging around with these things. */ + +/** + * Create an return an enumerator for the specified map.
+ * You must call GSIMapEndEnumerator() when you have finished + * with the enumerator.
+ * WARNING You should not alter a map while an enumeration + * is in progress. The results of doing so are reasonably unpredictable. + *
Remember, DON'T MESS WITH A MAP WHILE YOU'RE ENUMERATING IT. + */ +GS_STATIC_INLINE GSIMapEnumerator_t +GSIMapEnumeratorForMap(GSIMapTable map) +{ + GSIMapEnumerator_t enumerator; + + enumerator.map = map; + enumerator.node = 0; + enumerator.bucket = 0; + /* + * Locate next bucket and node to be returned. + */ + if (GSI_MAP_ZEROED(map)) + { + while (enumerator.bucket < map->bucketCount) + { + GSIMapNode node = map->buckets[enumerator.bucket].firstNode; + + while (node != 0 && GSI_MAP_READ_KEY(map, &node->key).addr == 0) + { + node = GSIMapRemoveAndFreeNode(map, enumerator.bucket, node); + } + if ((enumerator.node = node) != 0) + { + return enumerator; + } + enumerator.bucket++; + } + } + while (enumerator.bucket < map->bucketCount) + { + enumerator.node = map->buckets[enumerator.bucket].firstNode; + if (enumerator.node != 0) + { + return enumerator; // Got first node, and recorded its bucket. + } + enumerator.bucket++; + } + + return enumerator; +} + +/** + * Tidies up after map enumeration ... effectively destroys the enumerator. + */ +GS_STATIC_INLINE void +GSIMapEndEnumerator(GSIMapEnumerator enumerator) +{ + ((_GSIE)enumerator)->map = 0; + ((_GSIE)enumerator)->node = 0; + ((_GSIE)enumerator)->bucket = 0; +} + +/** + * Returns the bucket from which the next node in the enumeration will + * come. Once the next node has been enumerated, you can use the + * bucket and node to remove the node from the map using the + * GSIMapRemoveNodeFromMap() function. + */ +GS_STATIC_INLINE GSIMapBucket +GSIMapEnumeratorBucket(GSIMapEnumerator enumerator) +{ + if (((_GSIE)enumerator)->node != 0) + { + GSIMapTable map = ((_GSIE)enumerator)->map; + + return &((map->buckets)[((_GSIE)enumerator)->bucket]); + } + return 0; +} + +/** + * Returns the next node in the map, or a nul pointer if at the end. + */ +GS_STATIC_INLINE GSIMapNode +GSIMapEnumeratorNextNode(GSIMapEnumerator enumerator) +{ + GSIMapNode node = ((_GSIE)enumerator)->node; + GSIMapTable map = ((_GSIE)enumerator)->map; + + /* Find the frst available non-zeroed node. + */ + if (node != 0 && GSI_MAP_ZEROED(map) + && GSI_MAP_READ_KEY(map, &node->key).addr == 0) + { + uintptr_t bucketCount = map->bucketCount; + uintptr_t bucket = ((_GSIE)enumerator)->bucket; + + while (node != 0 && GSI_MAP_READ_KEY(map, &node->key).addr == 0) + { + node = GSIMapRemoveAndFreeNode(map, bucket, node); + while (node == 0 && ++bucket < bucketCount) + { + node = (map->buckets[bucket]).firstNode; + while (node != 0 && GSI_MAP_READ_KEY(map, &node->key).addr == 0) + { + node = GSIMapRemoveAndFreeNode(map, bucket, node); + } + } + ((_GSIE)enumerator)->bucket = bucket; + ((_GSIE)enumerator)->node = node; + } + } + + if (node != 0) + { + GSIMapNode next = node->nextInBucket; + + if (GSI_MAP_ZEROED(map)) + { + uintptr_t bucket = ((_GSIE)enumerator)->bucket; + + while (next != 0 && next->key.addr == 0) + { + next = GSIMapRemoveAndFreeNode(map, bucket, next); + } + } + + if (next == 0) + { + uintptr_t bucketCount = map->bucketCount; + uintptr_t bucket = ((_GSIE)enumerator)->bucket; + + if (GSI_MAP_ZEROED(map)) + { + while (next == 0 && ++bucket < bucketCount) + { + next = (map->buckets[bucket]).firstNode; + while (next != 0 && next->key.addr == 0) + { + next = GSIMapRemoveAndFreeNode(map, bucket, next); + } + } + ((_GSIE)enumerator)->bucket = bucket; + ((_GSIE)enumerator)->node = next; + return node; + } + while (next == 0 && ++bucket < bucketCount) + { + next = (map->buckets[bucket]).firstNode; + } + ((_GSIE)enumerator)->bucket = bucket; + } + ((_GSIE)enumerator)->node = next; + } + return node; +} + +/** + * Used to implement fast enumeration methods in classes that use GSIMap for + * their data storage. + */ +GS_STATIC_INLINE NSUInteger +GSIMapCountByEnumeratingWithStateObjectsCount(GSIMapTable map, + NSFastEnumerationState *state, + id *stackbuf, + NSUInteger len) +{ + NSInteger count; + NSInteger i; + + /* We can store a GSIMapEnumerator inside the extra buffer in state on all + * platforms that don't suck beyond belief (i.e. everything except win64), + * but we can't on anything where long is 32 bits and pointers are 64 bits, + * so we have to construct it here to avoid breaking on that platform. + */ + struct GSPartMapEnumerator + { + GSIMapNode node; + uintptr_t bucket; + }; + GSIMapEnumerator_t enumerator; + + count = MIN(len, map->nodeCount - state->state); + + /* Construct the real enumerator */ + if (0 == state->state) + { + enumerator = GSIMapEnumeratorForMap(map); + } + else + { + enumerator.map = map; + enumerator.node = ((struct GSPartMapEnumerator*)(state->extra))->node; + enumerator.bucket = ((struct GSPartMapEnumerator*)(state->extra))->bucket; + } + /* Get the next count objects and put them in the stack buffer. */ + for (i = 0; i < count; i++) + { + GSIMapNode node = GSIMapEnumeratorNextNode(&enumerator); + if (0 != node) + { + /* UGLY HACK: Lets this compile with any key type. Fast enumeration + * will only work with things that are id-sized, however, so don't + * try using it with non-object collections. + */ + stackbuf[i] = (id)GSI_MAP_READ_KEY(map, &node->key).addr; + } + } + /* Store the important bits of the enumerator in the caller. */ + ((struct GSPartMapEnumerator*)(state->extra))->node = enumerator.node; + ((struct GSPartMapEnumerator*)(state->extra))->bucket = enumerator.bucket; + /* Update the rest of the state. */ + state->state += count; + state->itemsPtr = stackbuf; + return count; +} + +#if GSI_MAP_HAS_VALUE +GS_STATIC_INLINE GSIMapNode +GSIMapAddPairNoRetain(GSIMapTable map, GSIMapKey key, GSIMapVal value) +{ + GSIMapNode node = map->freeNodes; + + if (node == 0) + { + GSIMapMoreNodes(map, map->nodeCount < map->increment ? 0: map->increment); + node = map->freeNodes; + } + map->freeNodes = node->nextInBucket; + GSI_MAP_WRITE_KEY(map, &node->key, key); + GSI_MAP_WRITE_VAL(map, &node->value, value); + node->nextInBucket = 0; + GSIMapRightSizeMap(map, map->nodeCount); + GSIMapAddNodeToMap(map, node); + return node; +} + +GS_STATIC_INLINE GSIMapNode +GSIMapAddPair(GSIMapTable map, GSIMapKey key, GSIMapVal value) +{ + GSIMapNode node = map->freeNodes; + + if (node == 0) + { + GSIMapMoreNodes(map, map->nodeCount < map->increment ? 0: map->increment); + node = map->freeNodes; + } + map->freeNodes = node->nextInBucket; + GSI_MAP_WRITE_KEY(map, &node->key, key); + GSI_MAP_RETAIN_KEY(map, node->key); + GSI_MAP_WRITE_VAL(map, &node->value, value); + GSI_MAP_RETAIN_VAL(map, node->value); + node->nextInBucket = 0; + GSIMapRightSizeMap(map, map->nodeCount); + GSIMapAddNodeToMap(map, node); + return node; +} +#else +GS_STATIC_INLINE GSIMapNode +GSIMapAddKeyNoRetain(GSIMapTable map, GSIMapKey key) +{ + GSIMapNode node = map->freeNodes; + + if (node == 0) + { + GSIMapMoreNodes(map, map->nodeCount < map->increment ? 0: map->increment); + node = map->freeNodes; + } + map->freeNodes = node->nextInBucket; + GSI_MAP_WRITE_KEY(map, &node->key, key); + node->nextInBucket = 0; + GSIMapRightSizeMap(map, map->nodeCount); + GSIMapAddNodeToMap(map, node); + return node; +} + +GS_STATIC_INLINE GSIMapNode +GSIMapAddKey(GSIMapTable map, GSIMapKey key) +{ + GSIMapNode node = map->freeNodes; + + if (node == 0) + { + GSIMapMoreNodes(map, map->nodeCount < map->increment ? 0: map->increment); + node = map->freeNodes; + } + map->freeNodes = node->nextInBucket; + GSI_MAP_WRITE_KEY(map, &node->key, key); + GSI_MAP_RETAIN_KEY(map, node->key); + node->nextInBucket = 0; + GSIMapRightSizeMap(map, map->nodeCount); + GSIMapAddNodeToMap(map, node); + return node; +} +#endif + +/** + * Removes the item for the specified key from the map. + * If the key was present, returns YES, otherwise returns NO. + */ +GS_STATIC_INLINE BOOL +GSIMapRemoveKey(GSIMapTable map, GSIMapKey key) +{ + GSIMapBucket bucket = GSIMapBucketForKey(map, key); + GSIMapNode node; + + node = GSIMapNodeForKeyInBucket(map, bucket, key); + if (node != 0) + { + GSIMapRemoveNodeFromMap(map, bucket, node); + GSIMapFreeNode(map, node); + return YES; + } + return NO; +} + +GS_STATIC_INLINE void +GSIMapCleanMap(GSIMapTable map) +{ + if (map->nodeCount > 0) + { + GSIMapBucket bucket = map->buckets; + unsigned int i; + GSIMapNode startNode = 0; + GSIMapNode prevNode = 0; + GSIMapNode node; + + map->nodeCount = 0; + for (i = 0; i < map->bucketCount; i++) + { + node = bucket->firstNode; + if (prevNode != 0) + { + prevNode->nextInBucket = node; + } + else + { + startNode = node; + } + while(node != 0) + { + GSI_MAP_RELEASE_KEY(map, node->key); + GSI_MAP_CLEAR_KEY(node); + +#if GSI_MAP_HAS_VALUE + GSI_MAP_RELEASE_VAL(map, node->value); + GSI_MAP_CLEAR_VAL(node); +#endif + prevNode = node; + node = node->nextInBucket; + } + bucket->nodeCount = 0; + bucket->firstNode = 0; + bucket++; + } + if (prevNode != 0) + { + prevNode->nextInBucket = map->freeNodes; + } + map->freeNodes = startNode; + } +} + +GS_STATIC_INLINE void +GSIMapEmptyMap(GSIMapTable map) +{ +#ifdef GSI_MAP_NOCLEAN + if (GSI_MAP_NOCLEAN) + { + map->nodeCount = 0; + } + else + { + GSIMapCleanMap(map); + } +#else + GSIMapCleanMap(map); +#endif + if (map->buckets != 0) + { + NSZoneFree(map->zone, map->buckets); + map->buckets = 0; + map->bucketCount = 0; + } + if (map->nodeChunks != 0) + { + unsigned int i; + + for (i = 0; i < map->chunkCount; i++) + { + NSZoneFree(map->zone, map->nodeChunks[i]); + } + NSZoneFree(map->zone, map->nodeChunks); + map->chunkCount = 0; + map->nodeChunks = 0; + } + map->freeNodes = 0; + map->zone = 0; +} + +GS_STATIC_INLINE void +GSIMapInitWithZoneAndCapacity(GSIMapTable map, NSZone *zone, uintptr_t capacity) +{ + map->zone = zone; + map->nodeCount = 0; + map->bucketCount = 0; + map->buckets = 0; + map->nodeChunks = 0; + map->freeNodes = 0; + map->chunkCount = 0; + map->increment = 300000; // choosen so the chunksize will be less than 4Mb + GSIMapRightSizeMap(map, capacity); + GSIMapMoreNodes(map, capacity); +} + +GS_STATIC_INLINE NSUInteger +GSIMapSize(GSIMapTable map) +{ + NSUInteger index; + NSUInteger size; + GSIMapNode node; + + /* Map table plus arrays of pointers to chunks + */ + size = GSI_MAP_TABLE_S + map->chunkCount * sizeof(void*); + + /* Add the array of buckets. + */ + size += map->bucketCount * sizeof(GSIMapBucket_t); + + /* Add the free nodes. + */ + for (node = map->freeNodes; 0 != node; node = node->nextInBucket) + { + size += sizeof(GSIMapNode_t); + } + + /* Add the used nodes (in the buckets). + */ + for (index = 0; index < map->bucketCount; index++) + { + size += sizeof(GSIMapNode_t) * map->buckets[index].nodeCount; + } + return size; +} + +#if defined(__cplusplus) +} +#endif + + diff --git a/src/GSPrivate.h b/src/GSPrivate.h new file mode 100644 index 000000000..10325b04b --- /dev/null +++ b/src/GSPrivate.h @@ -0,0 +1,61 @@ +#define GS_MAX_OBJECTS_FROM_STACK 128 + +/** + * Macro to manage memory for chunks of code that need to work with + * arrays of items. Use this to start the block of code using + * the array and GS_ENDITEMBUF() to end it. The idea is to ensure that small + * arrays are allocated on the stack (for speed), but large arrays are + * allocated from the heap (to avoid stack overflow). + */ +#if __GNUC__ > 3 +__attribute__((unused)) static void GSFreeTempBuffer(void **b) +{ + if (NULL != *b) free(*b); +} +# define GS_BEGINITEMBUF(P, S, T) { \ + T _ibuf[GS_MAX_OBJECTS_FROM_STACK];\ + T *P = _ibuf;\ + __attribute__((cleanup(GSFreeTempBuffer))) void *_base = 0;\ + if (S > GS_MAX_OBJECTS_FROM_STACK)\ + {\ + _base = malloc((S) * sizeof(T));\ + P = _base;\ + } +#else +# define GS_BEGINITEMBUF(P, S, T) { \ + T _ibuf[(S) <= GS_MAX_OBJECTS_FROM_STACK ? (S) : 0]; \ + T *_base = ((S) <= GS_MAX_OBJECTS_FROM_STACK) ? _ibuf \ + : (T*)NSZoneMalloc(NSDefaultMallocZone(), (S) * sizeof(T)); \ + T *(P) = _base; +#endif + +/** + * Macro to manage memory for chunks of code that need to work with + * arrays of items. Use GS_BEGINITEMBUF() to start the block of code using + * the array and this macro to end it. + */ +#if __GNUC__ > 3 +# define GS_ENDITEMBUF() } +#else +# define GS_ENDITEMBUF() \ + if (_base != _ibuf) \ + NSZoneFree(NSDefaultMallocZone(), _base); \ + } +#endif + +/** + * Macro to manage memory for chunks of code that need to work with + * arrays of objects. Use this to start the block of code using + * the array and GS_ENDIDBUF() to end it. The idea is to ensure that small + * arrays are allocated on the stack (for speed), but large arrays are + * allocated from the heap (to avoid stack overflow). + */ +#define GS_BEGINIDBUF(P, S) GS_BEGINITEMBUF(P, S, id) + +/** + * Macro to manage memory for chunks of code that need to work with + * arrays of objects. Use GS_BEGINIDBUF() to start the block of code using + * the array and this macro to end it. + */ +#define GS_ENDIDBUF() GS_ENDITEMBUF() + diff --git a/src/GSUnion.h b/src/GSUnion.h new file mode 100644 index 000000000..5db73b6f9 --- /dev/null +++ b/src/GSUnion.h @@ -0,0 +1,99 @@ +/* + * GSUnion.h + * File to set up a typedef for a union capable of containing various types. + * Copyright (C) 1999 Free Software Foundation, Inc. + * + * Author: Richard Frith-Macdonald + * Created: Apr 1999 + * + * This file is part of the GNUstep Base Library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02111 USA. */ + +/* Need Foundation/NSObjCRuntime.h for type declarations. + */ +#import + +/* These are not defined in older Mac OS X systems */ +#ifndef NSINTEGER_DEFINED +typedef intptr_t NSInteger; +typedef uintptr_t NSUInteger; +#define NSINTEGER_DEFINED 1 +#endif + +/* + * Definitions for bitmap mask of types of element in union. + */ +#ifndef GSUNION_OBJ + +#define GSUNION_OBJ 0x0001 +#define GSUNION_CLS 0x0002 +#define GSUNION_SEL 0x0004 +#define GSUNION_PTR 0x0080 +#define GSUNION_NSINT 0x1000 + +#define GSUNION_ALL 0x1fff + +#endif /* GSUNION_OBJ */ + + +/* + * Produce a typedef for a union with name 'GSUNION' containing elements + * specified in the GSUNION_TYPES mask, and optionally with an extra + * element 'ext' of the type specified in GSUNION_EXTRA + * + * You can include this file more than once in order to produce different + * typedefs as long as you redefine 'GSUNION' before each inclusion. + */ + +#if defined(GSUNION) && defined(GSUNION_TYPES) + +typedef union { + NSUInteger addr; /* Always present */ +#if ((GSUNION_TYPES) & GSUNION_OBJ) + id obj; + NSObject *nso; +#endif +#if ((GSUNION_TYPES) & GSUNION_CLS) + Class cls; +#endif +#if ((GSUNION_TYPES) & GSUNION_SEL) + SEL sel; +#endif +#if ((GSUNION_TYPES) & GSUNION_NSINT) + NSInteger nsi; + NSUInteger nsu; +#endif +#if ((GSUNION_TYPES) & GSUNION_PTR) + void *ptr; + const void *cptr; + char *str; + const char *cstr; +#endif + +/* Warning ... if this value is declared in the union, and its type is not + * the same size as a pointer, then care must be taken in case of confusion + * caused when an assignment to a variable using one of the union's types + * causes part of the variable to ebe left with undefined content from the + * point of view of another of the union's types. + */ +#if defined(GSUNION_EXTRA) + GSUNION_EXTRA ext; +#endif +} GSUNION; + +#endif + diff --git a/src/NSAffineTransform.m b/src/NSAffineTransform.m index 08229e1dd..93530bf2b 100644 --- a/src/NSAffineTransform.m +++ b/src/NSAffineTransform.m @@ -40,6 +40,8 @@ #import "Foundation/NSAffineTransform.h" #import "Foundation/NSCoder.h" +#define NSDebugLLog(fmt, ...) + /* Private definitions */ #define A _matrix.m11 #define B _matrix.m12 diff --git a/src/NSAggregateExpression.m b/src/NSAggregateExpression.m index 549dfb38d..c4eaa69b2 100644 --- a/src/NSAggregateExpression.m +++ b/src/NSAggregateExpression.m @@ -17,9 +17,6 @@ #import "_NSPredicateUtilities.h" @implementation NSAggregateExpression -{ - id _collection; -} static NSString * const NSCollectionKey = @"NSCollection"; diff --git a/src/NSArchiver.h b/src/NSArchiver.h index 8320ade62..6eea87747 100644 --- a/src/NSArchiver.h +++ b/src/NSArchiver.h @@ -1,8 +1,16 @@ #import #import #import +#import +#import @interface NSArchiver : NSCoder +{ + NSMutableData *mdata; + void *ids; + NSMutableDictionary *map; + CFMutableDictionaryRef replacementTable; +} + (BOOL)archiveRootObject:(id)object toFile:(NSString *)path; + (id)archivedDataWithRootObject:(id)object; diff --git a/src/NSArchiver.m b/src/NSArchiver.m index f9b48cfb0..5686702fa 100644 --- a/src/NSArchiver.m +++ b/src/NSArchiver.m @@ -26,12 +26,7 @@ @end -@implementation NSArchiver { - NSMutableData *mdata; - void *ids; - NSMutableDictionary *map; - CFMutableDictionaryRef replacementTable; -} +@implementation NSArchiver + (BOOL)archiveRootObject:(id)object toFile:(NSString *)path { diff --git a/src/NSArray.m b/src/NSArray.m index 42e67256e..c4f540acf 100644 --- a/src/NSArray.m +++ b/src/NSArray.m @@ -14,6 +14,7 @@ #import "NSObjectInternal.h" #import #import +#import "NSExternals.h" CF_EXPORT CFTypeRef _CFPropertyListCreateFromXMLData(CFAllocatorRef allocator, CFDataRef xmlData, CFOptionFlags option, CFStringRef *errorString, Boolean allNewTypes, CFPropertyListFormat *format); diff --git a/src/NSAttributedString.m b/src/NSAttributedString.m index cf8cc72c8..c4af6571f 100644 --- a/src/NSAttributedString.m +++ b/src/NSAttributedString.m @@ -12,6 +12,9 @@ CF_PRIVATE @interface NSMutableStringProxyForMutableAttributedString : NSMutableString +{ + NSMutableAttributedString *_owner; +} - (id)initWithMutableAttributedString:(NSMutableAttributedString *)owner; @end @@ -512,9 +515,6 @@ SINGLETON_RR() @end @implementation NSMutableStringProxyForMutableAttributedString -{ - NSMutableAttributedString *_owner; -} - (id)initWithMutableAttributedString:(NSMutableAttributedString *)owner { diff --git a/src/NSAutoreleasePool.m b/src/NSAutoreleasePool.m index e856de81b..d4711fbf9 100644 --- a/src/NSAutoreleasePool.m +++ b/src/NSAutoreleasePool.m @@ -6,16 +6,14 @@ // #import -#import "ForFoundationOnly.h" +#import -@implementation NSAutoreleasePool { - void *context; -} +@implementation NSAutoreleasePool + (id)allocWithZone:(NSZone *)zone { NSAutoreleasePool *pool = [super allocWithZone:zone]; - pool->context = _CFAutoreleasePoolPush(); + pool->context = _objc_autoreleasePoolPush(); return pool; } @@ -26,7 +24,7 @@ - (void)addObject:(id)anObject { - CFAutorelease((CFTypeRef)anObject); + _objc_rootAutorelease(anObject); } - (id)retain @@ -41,7 +39,7 @@ - (void)drain { - _CFAutoreleasePoolPop(context); + _objc_autoreleasePoolPop(context); [self dealloc]; } @@ -52,7 +50,7 @@ - (void)emptyPool { - _CFAutoreleasePoolPop(context); + _objc_autoreleasePoolPop(context); } @end diff --git a/src/NSBlockExpression.m b/src/NSBlockExpression.m index 0e95efda8..cfbc0a2d8 100644 --- a/src/NSBlockExpression.m +++ b/src/NSBlockExpression.m @@ -10,10 +10,6 @@ #import @implementation NSBlockExpression -{ - id (^_block)(id, NSArray *, NSMutableDictionary *); - NSArray *_arguments; -} - (id)initWithType:(NSExpressionType)type block:(id (^)(id, NSArray *, NSMutableDictionary *))block arguments:(NSArray *)arguments { diff --git a/src/NSBlockPredicate.m b/src/NSBlockPredicate.m index 3821f6e25..22979104a 100644 --- a/src/NSBlockPredicate.m +++ b/src/NSBlockPredicate.m @@ -7,9 +7,7 @@ #import "NSPredicateInternal.h" -@implementation NSBlockPredicate { - BOOL (^_block)(id evaluatedObject, NSDictionary *bindings); -} +@implementation NSBlockPredicate - (void)dealloc { diff --git a/src/NSBundle.m b/src/NSBundle.m index 71366d758..2974b7d8f 100644 --- a/src/NSBundle.m +++ b/src/NSBundle.m @@ -18,15 +18,7 @@ static NSMutableDictionary *loadedBundles = nil; static NSBundle *mainBundle = nil; -typedef enum { - NSBundleIsLoadedFlag = 0x01, -} NSBundleFlags; - -@implementation NSBundle { - NSBundleFlags _flags; - CFBundleRef _cfBundle; - Class _principalClass; -} +@implementation NSBundle + (void)initialize { diff --git a/src/NSByteCountFormatter.m b/src/NSByteCountFormatter.m index 7af0ffb05..04c1903fd 100644 --- a/src/NSByteCountFormatter.m +++ b/src/NSByteCountFormatter.m @@ -10,16 +10,7 @@ #import "NSObjectInternal.h" #import -@implementation NSByteCountFormatter { - NSByteCountFormatterUnits _allowedUnits; - char _countStyle; - BOOL _allowsNonnumericFormatting; - BOOL _includesUnit; - BOOL _includesCount; - BOOL _includesActualByteCount; - BOOL _adaptive; - BOOL _zeroPadsFractionDigits; -} +@implementation NSByteCountFormatter static NSArray *_NSByteCountFormatterUnits; diff --git a/src/NSCalendar.m b/src/NSCalendar.m index 8a8e251c3..f8b4e9c06 100644 --- a/src/NSCalendar.m +++ b/src/NSCalendar.m @@ -21,14 +21,7 @@ OBJC_PROTOCOL_IMPL_POP @end -@implementation NSAutoCalendar { - NSCalendar *cal; - NSLocale *changedLocale; - NSTimeZone *changedTimeZone; - NSUInteger changedFirstWeekday; - NSUInteger changedMinimumDaysinFirstWeek; - NSDate *changedGregorianStartDate; -} +@implementation NSAutoCalendar - (id)init { diff --git a/src/NSCalendarInternal.h b/src/NSCalendarInternal.h index f0d2472c8..52d78a1e5 100644 --- a/src/NSCalendarInternal.h +++ b/src/NSCalendarInternal.h @@ -41,6 +41,14 @@ CF_PRIVATE CF_PRIVATE @interface NSAutoCalendar : NSCalendar +{ + NSCalendar *cal; + NSLocale *changedLocale; + NSTimeZone *changedTimeZone; + NSUInteger changedFirstWeekday; + NSUInteger changedMinimumDaysinFirstWeek; + NSDate *changedGregorianStartDate; +} - (id)init; - (id)initWithCalendarIdentifier:(NSString *)ident; diff --git a/src/NSCallBacks.h b/src/NSCallBacks.h new file mode 100644 index 000000000..159e4cd07 --- /dev/null +++ b/src/NSCallBacks.h @@ -0,0 +1,94 @@ +/* GNUStep callback functions prototypes. + * Copyright(C) 1996 Free Software Foundation, Inc. + * + * Author: Albin L. Jones + * Created: Tue Feb 13 23:10:29 EST 1996 + * Updated: Tue Feb 13 23:10:29 EST 1996 + * Updated: Mon Feb 7 10:25:00 GMT 2000 + * Serial: 96.02.13.01 + * + * This file is part of the GNUstep Base Library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or(at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02111 USA. */ + +#ifndef __NSCallBacks_h_OBJECTS_INCLUDE +#define __NSCallBacks_h_OBJECTS_INCLUDE 1 + +/**** Included Headers *******************************************************/ + +#include "Foundation/NSObject.h" +#include "Foundation/NSString.h" + + +#if ( (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) ) && HAVE_VISIBILITY_ATTRIBUTE ) +#define GS_HIDDEN __attribute__ ((visibility("hidden"))) +#else +#define GS_HIDDEN +#endif + + + +/**** Type, Constant, and Macro Definitions **********************************/ + +/**** Function Prototypes ****************************************************/ + +/** For `int's **/ + +NSUInteger _NS_int_hash(void *table, void* i) GS_HIDDEN; +BOOL _NS_int_is_equal(void *table, void* i, void* j) GS_HIDDEN; +void _NS_int_retain(void *table, void* i) GS_HIDDEN; +void _NS_int_release(void *table, void* i) GS_HIDDEN; +NSString *_NS_int_describe(void *table, void* i) GS_HIDDEN; + +/** For owned `void *' **/ + +NSUInteger _NS_owned_void_p_hash(void *table, void *p) GS_HIDDEN; +BOOL _NS_owned_void_p_is_equal(void *table, void *p, void *q) GS_HIDDEN; +void _NS_owned_void_p_retain(void *table, void *p) GS_HIDDEN; +void _NS_owned_void_p_release(void *table, void *p) GS_HIDDEN; +NSString *_NS_owned_void_p_describe(void *table, void *p) GS_HIDDEN; + +/** For non-retained Objective-C objects **/ +NSUInteger _NS_non_retained_id_hash(void *table, id o) GS_HIDDEN; +BOOL _NS_non_retained_id_is_equal(void *table, + id o, id p) GS_HIDDEN; +void _NS_non_retained_id_retain(void *table, id o) GS_HIDDEN; +void _NS_non_retained_id_release(void *table, id o) GS_HIDDEN; +NSString *_NS_non_retained_id_describe(void *table, id o) GS_HIDDEN; + +/** For(retainable) objects **/ +NSUInteger _NS_id_hash(void *table, id o) GS_HIDDEN; +BOOL _NS_id_is_equal(void *table, id o, id p) GS_HIDDEN; +void _NS_id_retain(void *table, id o) GS_HIDDEN; +void _NS_id_release(void *table, id o) GS_HIDDEN; +NSString *_NS_id_describe(void *table, id o) GS_HIDDEN; + +/** For(non-owned) `void *' **/ +NSUInteger _NS_non_owned_void_p_hash(void *table, void *p) GS_HIDDEN; +BOOL _NS_non_owned_void_p_is_equal(void *table, void *p, void *q) GS_HIDDEN; +void _NS_non_owned_void_p_retain(void *table, void *p) GS_HIDDEN; +void _NS_non_owned_void_p_release(void *table, void *p) GS_HIDDEN; +NSString *_NS_non_owned_void_p_describe(void *table, void *p) GS_HIDDEN; + +/** For pointers to structures and `int *' **/ +NSUInteger _NS_int_p_hash(void *table, int *p) GS_HIDDEN; +BOOL _NS_int_p_is_equal(void *table, int *p, int *q) GS_HIDDEN; +void _NS_int_p_retain(void *table, int *p) GS_HIDDEN; +void _NS_int_p_release(void *table, int *p) GS_HIDDEN; +NSString *_NS_int_p_describe(void *table, int *p) GS_HIDDEN; + +#endif /* __NSCallBacks_h_OBJECTS_INCLUDE **/ + diff --git a/src/NSCallBacks.m b/src/NSCallBacks.m new file mode 100644 index 000000000..0b3c048c7 --- /dev/null +++ b/src/NSCallBacks.m @@ -0,0 +1,239 @@ +/** GNUStep callback functions. Implicitly required by the standard. + * Copyright(C) 1996 Free Software Foundation, Inc. + * + * Author: Albin L. Jones + * Created: Tue Feb 13 23:10:29 EST 1996 + * Updated: Wed Mar 20 19:53:48 EST 1996 + * Updated: Mon Feb 7 10:25:00 GMT 2000 + * Serial: 96.03.20.02 + * + * This file is part of the GNUstep Base Library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or(at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + + NSCallBacks class reference + $Date$ $Revision$ + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02111 USA. */ + +/**** Included Headers *******************************************************/ + +#import "common.h" +#import "NSCallBacks.h" +#include + +#define IF_NO_GC(x) x + +/**** Type, Constant, and Macro Definitions **********************************/ + +/**** Function Implementations ***********************************************/ + +/** For `int's **/ + +NSUInteger +_NS_int_hash(void *table, void* i) +{ + return (uintptr_t)i; +} + +BOOL +_NS_int_is_equal(void *table, void* i, void* j) +{ + return (i == j) ? YES : NO; +} + +void +_NS_int_retain(void *table, void* i) +{ + return; +} + +void +_NS_int_release(void *table, void* i) +{ + return; +} + +NSString * +_NS_int_describe(void *table, void* i) +{ + return [NSString stringWithFormat: @"%d", (int)(intptr_t)i]; +} + +/** For owned `void *' **/ + +NSUInteger +_NS_owned_void_p_hash(void *table, void *p) +{ + /* P may be aligned, so we need to compensate. */ + return ((uintptr_t)p)/4; +} + +BOOL +_NS_owned_void_p_is_equal(void *table, void *p, void *q) +{ + return (p == q) ? YES : NO; +} + +void +_NS_owned_void_p_retain(void *table, void *p) +{ + return; +} + +void +_NS_owned_void_p_release(void *table, void *p) +{ + if (p != 0) + free(p); + return; +} + +NSString * +_NS_owned_void_p_describe(void *table, void *p) +{ + return [NSString stringWithFormat: @"%#"PRIxPTR, (NSUInteger)p]; +} + +/** For non-retained Objective-C objects **/ + +NSUInteger +_NS_non_retained_id_hash(void *table, id o) +{ + return [o hash]; +} + +BOOL +_NS_non_retained_id_is_equal(void *table, id o, id p) +{ + return [o isEqual: p]; +} + +void +_NS_non_retained_id_retain(void *table, id o) +{ + return; +} + +void +_NS_non_retained_id_release(void *table, id o) +{ + return; +} + +NSString * +_NS_non_retained_id_describe(void *table, id o) +{ + return [o description]; +} + +/** For(retainable) objects **/ + +NSUInteger +_NS_id_hash(void *table, id o) +{ + return [o hash]; +} + +BOOL +_NS_id_is_equal(void *table, id o, id p) +{ + return [o isEqual: p]; +} + +void +_NS_id_retain(void *table, id o) +{ + IF_NO_GC(RETAIN(o)); + return; +} + +void +_NS_id_release(void *table, id o) +{ + RELEASE(o); + return; +} + +NSString * +_NS_id_describe(void *table, id o) +{ + return [o description]; +} + + +/** For(non-owned) `void *' **/ + +NSUInteger +_NS_non_owned_void_p_hash(void *table, void *p) +{ + return ((uintptr_t)p)/4; +} + +BOOL +_NS_non_owned_void_p_is_equal(void *table, void *p, void *q) +{ + return (p == q) ? YES : NO; +} + +void +_NS_non_owned_void_p_retain(void *table, void *p) +{ + return; +} + +void +_NS_non_owned_void_p_release(void *table, void *p) +{ + return; +} + +NSString * +_NS_non_owned_void_p_describe(void *table, void *p) +{ + return [NSString stringWithFormat: @"%0"PRIxPTR, (NSUInteger)p]; +} + +/** For pointers to structures and `int *' **/ + +NSUInteger +_NS_int_p_hash(void *table, int *p) +{ + return ((uintptr_t)p)/4; +} + +BOOL +_NS_int_p_is_equal(void *table, int *p, int *q) +{ + return (p == q) ? YES : NO; +} + +void +_NS_int_p_retain(void *table, int *p) +{ + return; +} + +void +_NS_int_p_release(void *table, int *p) +{ + return; +} + +NSString * +_NS_int_p_describe(void *table, int *p) +{ + /* Is this useful? */ + return [NSString stringWithFormat: @"%d(%#"PRIxPTR")", *p, (NSUInteger)p]; +} diff --git a/src/NSClassDescription.m b/src/NSClassDescription.m index 14cefdb1b..ded33eaf3 100644 --- a/src/NSClassDescription.m +++ b/src/NSClassDescription.m @@ -31,6 +31,8 @@ #import "Foundation/NSMapTable.h" #import "Foundation/NSNotification.h" +#define IF_NO_GC(x) x +NSString* const NSClassDescriptionNeededForClassNotification = @"NSClassDescriptionNeededForClassNotification"; /** * Each instance of this class provides descriptive information for an @@ -87,9 +89,9 @@ static NSMapTable *classMap; { classMap = NSCreateMapTable(NSObjectMapKeyCallBacks, NSObjectMapValueCallBacks, 100); - [[NSObject leakAt: &classMap] release]; + // [[NSObject leakAt: &classMap] release]; mapLock = [NSRecursiveLock new]; - [[NSObject leakAt: &mapLock] release]; + // [[NSObject leakAt: &mapLock] release]; } } diff --git a/src/NSCoder.m b/src/NSCoder.m index 441bf3d14..a726f8e78 100644 --- a/src/NSCoder.m +++ b/src/NSCoder.m @@ -13,6 +13,7 @@ #import #import #import +#import #import "NSExternals.h" #import "NSObjectInternal.h" @@ -482,32 +483,32 @@ static inline const char *nextType(const char *type) - (CGRect)decodeRectForKey:(NSString *)key { - return NSRectFromString([self decodeObjectForKey:key]); + return NSRectToCGRect(NSRectFromString([self decodeObjectForKey:key])); } - (CGSize)decodeSizeForKey:(NSString *)key { - return NSSizeFromString([self decodeObjectForKey:key]); + return NSSizeToCGSize(NSSizeFromString([self decodeObjectForKey:key])); } - (CGPoint)decodePointForKey:(NSString *)key { - return NSPointFromString([self decodeObjectForKey:key]); + return NSPointToCGPoint(NSPointFromString([self decodeObjectForKey:key])); } - (void)encodeRect:(CGRect)r forKey:(NSString *)key { - [self encodeObject:NSStringFromRect(r) forKey:key]; + [self encodeObject:NSStringFromRect(NSRectFromCGRect(r)) forKey:key]; } - (void)encodeSize:(CGSize)sz forKey:(NSString *)key { - [self encodeObject:NSStringFromSize(sz) forKey:key]; + [self encodeObject:NSStringFromSize(NSSizeFromCGSize(sz)) forKey:key]; } - (void)encodePoint:(CGPoint)pt forKey:(NSString *)key { - [self encodeObject:NSStringFromPoint(pt) forKey:key]; + [self encodeObject:NSStringFromPoint(NSPointFromCGPoint(pt)) forKey:key]; } @end diff --git a/src/NSCoderInternal.h b/src/NSCoderInternal.h index 3064da958..c97f2b537 100644 --- a/src/NSCoderInternal.h +++ b/src/NSCoderInternal.h @@ -1,5 +1,5 @@ #import -#import "NSExternals.h" +#import enum { NSKeyedArchiverKeyFlag = 0x01, @@ -51,6 +51,13 @@ enum { CF_PRIVATE @interface _NSKeyedCoderOldStyleArray : NSObject +{ + void *_addr; + NSUInteger _count; + NSUInteger _size; + char _type; + BOOL _decoded; +} - (id)initWithCoder:(NSCoder *)decoder; - (void)encodeWithCoder:(NSCoder *)coder; - (void)fillObjCType:(char)type count:(NSUInteger)count at:(void *)addr; diff --git a/src/NSComparisonPredicate.m b/src/NSComparisonPredicate.m index cb90e3f4e..be5d2a2eb 100644 --- a/src/NSComparisonPredicate.m +++ b/src/NSComparisonPredicate.m @@ -21,12 +21,6 @@ static NSString * const NSRightExpressionKey = @"NSRightExpression"; static NSString * const NSPredicateOperatorKey = @"NSPredicateOperator"; @implementation NSComparisonPredicate -{ - void *_reserved2; - NSPredicateOperator *_predicateOperator; - NSExpression *_lhs; - NSExpression *_rhs; -} + (BOOL)supportsSecureCoding { diff --git a/src/NSComparisonPredicateOperator.h b/src/NSComparisonPredicateOperator.h index 629542972..84af07e8e 100644 --- a/src/NSComparisonPredicateOperator.h +++ b/src/NSComparisonPredicateOperator.h @@ -1,6 +1,10 @@ #import "NSPredicateOperator.h" @interface NSComparisonPredicateOperator : NSPredicateOperator +{ + NSPredicateOperatorType _variant; + NSComparisonPredicateOptions _options; +} - (NSPredicateOperatorType)variant; - (id)initWithOperatorType:(NSPredicateOperatorType)type modifier:(NSComparisonPredicateModifier)modifier variant:(NSPredicateOperatorType)variant options:(NSComparisonPredicateOptions)options; diff --git a/src/NSComparisonPredicateOperator.m b/src/NSComparisonPredicateOperator.m index 359ddce91..aa2fdfbff 100644 --- a/src/NSComparisonPredicateOperator.m +++ b/src/NSComparisonPredicateOperator.m @@ -15,10 +15,6 @@ static NSString * const NSOptionsKey = @"NSOptions"; static NSString * const NSVariantKey = @"NSVariant"; @implementation NSComparisonPredicateOperator -{ - NSPredicateOperatorType _variant; - NSComparisonPredicateOptions _options; -} + (BOOL)supportsSecureCoding { diff --git a/src/NSCompoundPredicate.m b/src/NSCompoundPredicate.m index 0448dd4f1..6ac4e4966 100644 --- a/src/NSCompoundPredicate.m +++ b/src/NSCompoundPredicate.m @@ -20,11 +20,6 @@ static NSString * const NSSubpredicatesKey = @"NSSubpredicates"; static NSString * const NSCompoundPredicateTypeKey = @"NSCompoundPredicateType"; @implementation NSCompoundPredicate -{ - void *_reserved2; - NSCompoundPredicateType _type; - NSArray *_subpredicates; -} + (BOOL)supportsSecureCoding { diff --git a/src/NSConcreteHashTable.m b/src/NSConcreteHashTable.m new file mode 100644 index 000000000..6fb7f36f6 --- /dev/null +++ b/src/NSConcreteHashTable.m @@ -0,0 +1,1108 @@ +/** Implementation of NSHashTable for GNUStep + Copyright (C) 2009 Free Software Foundation, Inc. + + Written by: Richard Frith-Macdonald + Date: April 2009 + + Based on original o_hash code by Albin L. Jones + + This file is part of the GNUstep Base Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. + + $Date: 2008-06-08 11:38:33 +0100 (Sun, 08 Jun 2008) $ $Revision: 26606 $ + */ + +#import "common.h" + +#import "Foundation/NSArray.h" +#import "Foundation/NSAutoreleasePool.h" +#import "Foundation/NSDictionary.h" +#import "Foundation/NSEnumerator.h" +#import "Foundation/NSException.h" +#import "Foundation/NSHashTable.h" +#import "NSConcreteHashTableInternal.h" + +#define NSWarnFLog(fmt, ...) +#define NSWarnMLog(fmt, ...) + +#import "NSCallBacks.h" +#import "GSPrivate.h" +#import + +static Class concreteClass = Nil; +static unsigned instanceSize = 0; + + +/* Here is the interface for the concrete class as used by the functions. + */ + +typedef struct _GSIMapBucket GSIMapBucket_t; +typedef struct _GSIMapNode GSIMapNode_t; +typedef GSIMapBucket_t *GSIMapBucket; +typedef GSIMapNode_t *GSIMapNode; + +@interface NSConcreteHashTable : NSHashTable +{ +@public + NSZone *zone; + size_t nodeCount; /* Number of used nodes in hash. */ + size_t bucketCount; /* Number of buckets in hash. */ + GSIMapBucket buckets; /* Array of buckets. */ + GSIMapNode freeNodes; /* List of unused nodes. */ + GSIMapNode *nodeChunks; /* Chunks of allocated memory. */ + size_t chunkCount; /* Number of chunks in array. */ + size_t increment; /* Amount to grow by. */ + unsigned long version; /* For fast enumeration. */ + BOOL legacy; /* old style callbacks? */ + union { + PFInfo pf; + NSHashTableCallBacks old; + }cb; +} +@end + +#define GSI_MAP_HAS_VALUE 0 +#define GSI_MAP_KTYPES GSUNION_PTR | GSUNION_OBJ +#define GSI_MAP_TABLE_T NSConcreteHashTable +#define GSI_MAP_TABLE_S instanceSize + +#define GSI_MAP_HASH(M, X)\ + (M->legacy ? M->cb.old.hash(M, X.ptr) \ + : pointerFunctionsHash(&M->cb.pf, X.ptr)) +#define GSI_MAP_EQUAL(M, X, Y)\ + (M->legacy ? M->cb.old.isEqual(M, X.ptr, Y.ptr) \ + : pointerFunctionsEqual(&M->cb.pf, X.ptr, Y.ptr)) +#define GSI_MAP_RELEASE_KEY(M, X)\ + (M->legacy ? M->cb.old.release(M, X.ptr) \ + : pointerFunctionsRelinquish(&M->cb.pf, &X.ptr)) +#define GSI_MAP_RETAIN_KEY(M, X)\ + (M->legacy ? M->cb.old.retain(M, X.ptr) \ + : pointerFunctionsAcquire(&M->cb.pf, &X.ptr, X.ptr)) +#define GSI_MAP_ZEROED(M)\ + (M->legacy ? 0 \ + : ((M->cb.pf.options & NSPointerFunctionsZeroingWeakMemory) ? YES : NO)) + +#define GSI_MAP_WRITE_KEY(M, addr, x) \ + if (M->legacy) \ + *(addr) = x;\ + else\ + pointerFunctionsAssign(&M->cb.pf, (void**)addr, (x).obj); +#define GSI_MAP_READ_KEY(M,addr) \ + (M->legacy ? *(addr) :\ + (typeof(*addr))pointerFunctionsRead(&M->cb.pf, (void**)addr)) +#define GSI_MAP_ZEROED(M)\ + (M->legacy ? 0 \ + : ((M->cb.pf.options & NSPointerFunctionsZeroingWeakMemory) ? YES : NO)) + +#define GSI_MAP_ENUMERATOR NSHashEnumerator + +#include "GSIMap.h" + +/**** Function Implementations ****/ + +/** + * Returns an array of all the objects in the table. + * NB. The table must contain objects for its keys. + */ +NSArray * +NSAllHashTableObjects(NSHashTable *table) +{ + return [table allObjects]; +} + +/** + * Compares the two hash tables for equality. + * If the tables are different sizes, returns NO. + * Otherwise, compares the values in the two tables + * and returns NO if they differ.
+ * The GNUstep implementation enumerates the values in table1 + * and uses the hash and isEqual functions of table2 for comparison. + */ +BOOL +NSCompareHashTables(NSHashTable *table1, NSHashTable *table2) +{ + if (table1 == table2) + { + return YES; + } + if (table1 == nil) + { + NSWarnFLog(@"Nul first argument supplied"); + return NO; + } + if (table2 == nil) + { + NSWarnFLog(@"Nul second argument supplied"); + return NO; + } + if ([table1 count] != [table2 count]) + { + return NO; + } + if (object_getClass(table1) != concreteClass + && object_getClass(table2) == concreteClass) + { + id t = table1; + + table1 = table2; + table2 = t; + } + if (object_getClass(table1) == concreteClass) + { + BOOL result = YES; + NSHashEnumerator enumerator; + GSIMapNode n1; + + enumerator = NSEnumerateHashTable(table1); + if (object_getClass(table2) == concreteClass) + { + GSIMapTable t2 = (GSIMapTable)table2; + + while ((n1 = GSIMapEnumeratorNextNode(&enumerator)) != 0) + { + if (GSIMapNodeForKey(t2, n1->key) == 0) + { + result = NO; + break; + } + } + } + else + { + while ((n1 = GSIMapEnumeratorNextNode(&enumerator)) != 0) + { + void *v1 = n1->key.ptr; + void *v2; + + v2 = NSHashGet(table2, v1); + if (v2 == 0 && v2 != v1) + { + result = NO; + break; + } + } + } + NSEndHashTableEnumeration(&enumerator); + return result; + } + else + { + BOOL result = YES; + NSHashEnumerator enumerator; + void *v1; + + enumerator = NSEnumerateHashTable(table1); + while ((v1 = NSNextHashEnumeratorItem(&enumerator)) != 0) + { + void *v2; + + v2 = NSHashGet(table2, v1); + if (v2 == 0 && v2 != v1) + { + result = NO; + break; + } + } + NSEndHashTableEnumeration(&enumerator); + return result; + } +} + +/** + * Copy the supplied hash table.
+ * Returns a hash table, space for which is allocated in zone, which + * has (newly retained) copies of table's contents. As always, + * if zone is 0, then NSDefaultMallocZone() is used. + */ +NSHashTable * +NSCopyHashTableWithZone(NSHashTable *table, NSZone *zone) +{ + GSIMapTable o = (GSIMapTable)table; + GSIMapTable t; + GSIMapNode n; + NSHashEnumerator enumerator; + + if (table == nil) + { + NSWarnFLog(@"Null table argument supplied"); + return 0; + } + t = (GSIMapTable)[concreteClass allocWithZone: zone]; + t->legacy = o->legacy; + if (t->legacy == YES) + { + t->cb.old = o->cb.old; + } + else + { + t->cb.pf = o->cb.pf; + } + GSIMapInitWithZoneAndCapacity(t, zone, ((GSIMapTable)table)->nodeCount); + + enumerator = GSIMapEnumeratorForMap((GSIMapTable)table); + while ((n = GSIMapEnumeratorNextNode(&enumerator)) != 0) + { + GSIMapAddKey(t, n->key); + } + GSIMapEndEnumerator((GSIMapEnumerator)&enumerator); + + return (NSHashTable*)t; +} + +/** + * Returns the number of items in the table. + */ +NSUInteger +NSCountHashTable(NSHashTable *table) +{ + return [table count]; +} + +/** + * Create a new hash table by calling NSCreateHashTableWithZone() using + * NSDefaultMallocZone().
+ * Returns a (pointer to) an NSHashTable space for which is allocated + * in the default zone. If capacity is small or 0, then the returned + * table has a reasonable capacity. + */ +NSHashTable * +NSCreateHashTable( + NSHashTableCallBacks callBacks, + NSUInteger capacity) +{ + return NSCreateHashTableWithZone(callBacks, capacity, NSDefaultMallocZone()); +} + +/** + * Create a new hash table using the supplied callbacks structures. + * If any functions in the callback structures are null the default + * values are used ... as for non-owned pointers.
+ * Of course, if you send 0 for zone, then the hash table will be + * created in NSDefaultMallocZone().
+ * The table will be created with the specified capacity ... ie ready + * to hold at least that many items. + */ +NSHashTable * +NSCreateHashTableWithZone( + NSHashTableCallBacks k, + NSUInteger capacity, + NSZone *zone) +{ + GSIMapTable table; + + if (concreteClass == Nil) + { + [NSConcreteHashTable class]; // Force +initialize + NSCAssert(concreteClass != Nil, NSInternalInconsistencyException); + } + table = (GSIMapTable)[concreteClass allocWithZone: zone]; + + if (k.hash == 0) + k.hash = NSNonOwnedPointerHashCallBacks.hash; + if (k.isEqual == 0) + k.isEqual = NSNonOwnedPointerHashCallBacks.isEqual; + if (k.retain == 0) + k.retain = NSNonOwnedPointerHashCallBacks.retain; + if (k.release == 0) + k.release = NSNonOwnedPointerHashCallBacks.release; + if (k.describe == 0) + k.describe = NSNonOwnedPointerHashCallBacks.describe; + + table->legacy = YES; + table->cb.old = k; + + GSIMapInitWithZoneAndCapacity(table, zone, capacity); + + return (NSHashTable*)table; +} + +/** + * Function to be called when finished with the enumerator. + * This permits memory used by the enumerator to be released! + */ +void +NSEndHashTableEnumeration(NSHashEnumerator *enumerator) +{ + if (enumerator == 0) + { + NSWarnFLog(@"Null enumerator argument supplied"); + return; + } + if (enumerator->map != 0) + { + /* The 'map' field is non-null, so this NSHashEnumerator is actually + * a GSIMapEnumerator. + */ + GSIMapEndEnumerator((GSIMapEnumerator)enumerator); + } + else if (enumerator->node != 0) + { + /* The 'map' field is null but the 'node' field is not, so the + * NSHashEnumerator structure actually contains an NSEnumerator + * in the 'node' field. + */ + [(id)enumerator->node release]; + memset(enumerator, '\0', sizeof(NSHashEnumerator)); + } +} + +/** + * Return an enumerator for stepping through a hash table using the + * NSNextHashEnumeratorPair() function. + */ +NSHashEnumerator +NSEnumerateHashTable(NSHashTable *table) +{ + if (table == nil) + { + NSHashEnumerator v = {0, 0, 0}; + + NSWarnFLog(@"Null table argument supplied"); + return v; + } + if (object_getClass(table) == concreteClass) + { + return GSIMapEnumeratorForMap((GSIMapTable)table); + } + else + { + NSHashEnumerator v = {0, 0, 0}; + + v.node = (void*)[[table objectEnumerator] retain]; + return v; + } +} + +/** + * Destroy the hash table and release its contents.
+ * Releases all the keys and values of table (using the key and + * value callbacks specified at the time of table's creation), + * and then proceeds to deallocate the space allocated for table itself. + */ +void +NSFreeHashTable(NSHashTable *table) +{ + [table release]; +} + +/** + * Returns the value for the specified item, or a null pointer if the + * item is not found in the table. + */ +void * +NSHashGet(NSHashTable *table, const void *element) +{ + if (table == nil) + { + NSWarnFLog(@"Null table argument supplied"); + return 0; + } + if (object_getClass(table) == concreteClass) + { + GSIMapNode n; + + n = GSIMapNodeForKey((GSIMapTable)table, (GSIMapKey)element); + if (n == 0) + { + return 0; + } + else + { + return n->key.ptr; + } + } + return [table member: (id)element]; +} + +/** + * Adds the element to table.
+ * If an equal element is already in table, replaces it with the new one.
+ * If element is null raises an NSInvalidArgumentException. + */ +void +NSHashInsert(NSHashTable *table, const void *element) +{ + if (table == 0) + { + [NSException raise: NSInvalidArgumentException + format: @"Attempt to place value in null hash table"]; + } + if (element == 0) + { + [NSException raise: NSInvalidArgumentException + format: @"Attempt to place null in hash table"]; + } + if (object_getClass(table) == concreteClass) + { + GSIMapTable t = (GSIMapTable)table; + GSIMapNode n; + + n = GSIMapNodeForKey(t, (GSIMapKey)element); + if (n == 0) + { + GSIMapAddKey(t, (GSIMapKey)element); + ((NSConcreteHashTable*)table)->version++; + } + else if (element != n->key.ptr) + { + GSI_MAP_RELEASE_KEY(t, n->key); + n->key = (GSIMapKey)element; + GSI_MAP_RETAIN_KEY(t, n->key); + ((NSConcreteHashTable*)table)->version++; + } + } + else + { + [table addObject: (id)element]; + } +} + +/** + * Adds the element to table and returns nul.
+ * If an equal element is already in table, returns the old element + * instead of adding the new one.
+ * If element is nul, raises an NSInvalidArgumentException. + */ +void * +NSHashInsertIfAbsent(NSHashTable *table, const void *element) +{ + if (table == 0) + { + [NSException raise: NSInvalidArgumentException + format: @"Attempt to place value in null hash table"]; + } + if (element == 0) + { + [NSException raise: NSInvalidArgumentException + format: @"Attempt to place null in hash table"]; + } + if (object_getClass(table) == concreteClass) + { + GSIMapTable t = (GSIMapTable)table; + GSIMapNode n; + + n = GSIMapNodeForKey(t, (GSIMapKey)element); + if (n == 0) + { + GSIMapAddKey(t, (GSIMapKey)element); + ((NSConcreteHashTable*)table)->version++; + return 0; + } + else + { + return n->key.ptr; + } + } + else + { + id old = [table member: (id)element]; + + if (old == nil) + { + [table addObject: (id)element]; + return 0; + } + else + { + return (void*)old; + } + } +} + +/** + * Adds the element to table and returns nul.
+ * If an equal element is already present, raises NSInvalidArgumentException. + *
If element is null raises an NSInvalidArgumentException. + */ +void +NSHashInsertKnownAbsent(NSHashTable *table, const void *element) +{ + if (table == 0) + { + [NSException raise: NSInvalidArgumentException + format: @"Attempt to place value in null hash table"]; + } + if (element == 0) + { + [NSException raise: NSInvalidArgumentException + format: @"Attempt to place null in hash table"]; + } + if (object_getClass(table) == concreteClass) + { + GSIMapTable t = (GSIMapTable)table; + GSIMapNode n; + + n = GSIMapNodeForKey(t, (GSIMapKey)element); + if (n == 0) + { + GSIMapAddKey(t, (GSIMapKey)element); + ((NSConcreteHashTable*)table)->version++; + } + else + { + [NSException raise: NSInvalidArgumentException + format: @"NSHashInsertKnownAbsent ... item not absent"]; + } + } + else + { + id old = [table member: (id)element]; + + if (old == nil) + { + [table addObject: (id)element]; + } + else + { + [NSException raise: NSInvalidArgumentException + format: @"NSHashInsertKnownAbsent ... item not absent"]; + } + } +} + +/** + * Remove the specified element from the table. + */ +void +NSHashRemove(NSHashTable *table, const void *element) +{ + if (table == 0) + { + NSWarnFLog(@"Nul table argument supplied"); + return; + } + if (object_getClass(table) == concreteClass) + { + GSIMapTable map = (GSIMapTable)table; + GSIMapBucket bucket; + GSIMapNode node; + + bucket = GSIMapBucketForKey(map, (GSIMapKey)element); + node = GSIMapNodeForKeyInBucket(map, bucket, (GSIMapKey)element); + if (node != 0) + { + GSIMapRemoveNodeFromMap(map, bucket, node); + GSIMapFreeNode(map, node); + ((NSConcreteHashTable*)table)->version++; + } + } + else + { + [table removeObject: (id)element]; + } +} + +/** + * Step through the hash table ... return the next item or + * return nul if we hit the of the table. + */ +void * +NSNextHashEnumeratorItem(NSHashEnumerator *enumerator) +{ + if (enumerator == 0) + { + NSWarnFLog(@"Nul enumerator argument supplied"); + return 0; + } + if (enumerator->map != 0) // Got a GSIMapTable enumerator + { + GSIMapNode n; + + /* The 'map' field is non-null, so this NSHashEnumerator is actually + * a GSIMapEnumerator. + */ + n = GSIMapEnumeratorNextNode((GSIMapEnumerator)enumerator); + if (n == 0) + { + return 0; + } + else + { + return n->key.ptr; + } + } + else if (enumerator->node != 0) // Got an enumerator object + { + /* The 'map' field is null but the 'node' field is not, so the + * NSHashEnumerator structure actually contains an NSEnumerator + * in the 'node' field, and the map table being enumerated in the + * 'bucket' field. + */ + return (void*)[(id)enumerator->node nextObject]; + } + else + { + return 0; + } +} + +/** + * Empty the hash table (releasing all elements), but preserve its capacity. + */ +void +NSResetHashTable(NSHashTable *table) +{ + if (table == 0) + { + NSWarnFLog(@"Nul table argument supplied"); + return; + } + if (object_getClass(table) == concreteClass) + { + NSConcreteHashTable *t = (NSConcreteHashTable*)table; + + if (t->nodeCount > 0) + { + GSIMapCleanMap((GSIMapTable)table); + t->version++; + } + } + else + { + [table removeAllObjects]; + } +} + +/** + * Returns a string describing the table contents.
+ * For each item, a string of the form "value;\n" + * is appended. The appropriate describe function is used to generate + * the strings for each item. + */ +NSString * +NSStringFromHashTable(NSHashTable *table) +{ + GSIMapTable t = (GSIMapTable)table; + NSMutableString *string; + NSHashEnumerator enumerator; + const void *element; + + if (table == 0) + { + NSWarnFLog(@"Nul table argument supplied"); + return nil; + } + + /* This will be our string. */ + string = [NSMutableString stringWithCapacity: 0]; + + /* Get an enumerator for TABLE. */ + enumerator = NSEnumerateHashTable(table); + + /* Iterate over the elements of TABLE, appending the description of + * each to the mutable string STRING. */ + if (t->legacy) + { + while ((element = NSNextHashEnumeratorItem(&enumerator)) != nil) + { + [string appendFormat: @"%@;\n", + (t->cb.old.describe)(table, element)]; + } + } + else + { + while ((element = NSNextHashEnumeratorItem(&enumerator)) != nil) + { + [string appendFormat: @"%@;\n", + (t->cb.pf.descriptionFunction)(element)]; + } + } + NSEndHashTableEnumeration(&enumerator); + return string; +} + + + + +/* These are to increase readabilty locally. */ +typedef NSUInteger (*NSHT_hash_func_t)(NSHashTable *, const void *); +typedef BOOL (*NSHT_isEqual_func_t)(NSHashTable *, const void *, const void *); +typedef void (*NSHT_retain_func_t)(NSHashTable *, const void *); +typedef void (*NSHT_release_func_t)(NSHashTable *, void *); +typedef NSString *(*NSHT_describe_func_t)(NSHashTable *, const void *); + +/** For sets of pointer-sized or smaller quantities. */ +const NSHashTableCallBacks NSIntegerHashCallBacks = +{ + (NSHT_hash_func_t) _NS_int_hash, + (NSHT_isEqual_func_t) _NS_int_is_equal, + (NSHT_retain_func_t) _NS_int_retain, + (NSHT_release_func_t) _NS_int_release, + (NSHT_describe_func_t) _NS_int_describe +}; + +/** For backward compatibility. */ +const NSHashTableCallBacks NSIntHashCallBacks = +{ + (NSHT_hash_func_t) _NS_int_hash, + (NSHT_isEqual_func_t) _NS_int_is_equal, + (NSHT_retain_func_t) _NS_int_retain, + (NSHT_release_func_t) _NS_int_release, + (NSHT_describe_func_t) _NS_int_describe +}; + +/** For sets of pointers hashed by address. */ +const NSHashTableCallBacks NSNonOwnedPointerHashCallBacks = +{ + (NSHT_hash_func_t) _NS_non_owned_void_p_hash, + (NSHT_isEqual_func_t) _NS_non_owned_void_p_is_equal, + (NSHT_retain_func_t) _NS_non_owned_void_p_retain, + (NSHT_release_func_t) _NS_non_owned_void_p_release, + (NSHT_describe_func_t) _NS_non_owned_void_p_describe +}; + +/** For sets of objects without retaining and releasing. */ +const NSHashTableCallBacks NSNonRetainedObjectHashCallBacks = +{ + (NSHT_hash_func_t) _NS_non_retained_id_hash, + (NSHT_isEqual_func_t) _NS_non_retained_id_is_equal, + (NSHT_retain_func_t) _NS_non_retained_id_retain, + (NSHT_release_func_t) _NS_non_retained_id_release, + (NSHT_describe_func_t) _NS_non_retained_id_describe +}; + +/** For sets of objects; similar to [NSSet]. */ +const NSHashTableCallBacks NSObjectHashCallBacks = +{ + (NSHT_hash_func_t) _NS_id_hash, + (NSHT_isEqual_func_t) _NS_id_is_equal, + (NSHT_retain_func_t) _NS_id_retain, + (NSHT_release_func_t) _NS_id_release, + (NSHT_describe_func_t) _NS_id_describe +}; + +/** For sets of pointers with transfer of ownership upon insertion. */ +const NSHashTableCallBacks NSOwnedPointerHashCallBacks = +{ + (NSHT_hash_func_t) _NS_owned_void_p_hash, + (NSHT_isEqual_func_t) _NS_owned_void_p_is_equal, + (NSHT_retain_func_t) _NS_owned_void_p_retain, + (NSHT_release_func_t) _NS_owned_void_p_release, + (NSHT_describe_func_t) _NS_owned_void_p_describe +}; + +/** For sets of pointers to structs when the first field of the + * struct is the size of an int. */ +const NSHashTableCallBacks NSPointerToStructHashCallBacks = +{ + (NSHT_hash_func_t) _NS_int_p_hash, + (NSHT_isEqual_func_t) _NS_int_p_is_equal, + (NSHT_retain_func_t) _NS_int_p_retain, + (NSHT_release_func_t) _NS_int_p_release, + (NSHT_describe_func_t) _NS_int_p_describe +}; + + + +@interface NSConcreteHashTableEnumerator : NSEnumerator +{ + NSConcreteHashTable *table; + GSIMapEnumerator_t enumerator; +} +- (id) initWithHashTable: (NSConcreteHashTable*)t; +@end + +@implementation NSConcreteHashTable + ++ (void) initialize +{ + if (concreteClass == Nil) + { + concreteClass = [NSConcreteHashTable class]; + instanceSize = class_getInstanceSize(concreteClass); + } +} + +- (void) addObject: (id)anObject +{ + GSIMapTable t = (GSIMapTable)self; + GSIMapNode n; + + if (anObject == nil) + { + [NSException raise: NSInvalidArgumentException + format: @"[%@-%@:] given nil argument", + NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + } + + n = GSIMapNodeForKey(t, (GSIMapKey)anObject); + if (n == 0) + { + GSIMapAddKey(t, (GSIMapKey)anObject); + version++; + } + else if (n->key.obj != anObject) + { + GSI_MAP_RELEASE_KEY(t, n->key); + n->key = (GSIMapKey)anObject; + GSI_MAP_RETAIN_KEY(t, n->key); + version++; + } +} + +- (NSArray*) allObjects +{ + NSHashEnumerator enumerator; + NSUInteger index; + NSArray *a; + GS_BEGINITEMBUF(objects, nodeCount, id); + + enumerator = NSEnumerateHashTable(self); + index = 0; + while (index < nodeCount + && (objects[index] = NSNextHashEnumeratorItem(&enumerator)) != nil) + { + index++; + } + NSEndHashTableEnumeration(&enumerator); + a = [[[NSArray alloc] initWithObjects: objects count: index] autorelease]; + GS_ENDITEMBUF(); + return a; +} + +- (id) anyObject +{ + GSIMapNode node = GSIMapFirstNode(self); + + if (node == 0) + { + return nil; + } + return node->key.obj; +} + +- (BOOL) containsObject: (id)anObject +{ + if (anObject != nil) + { + GSIMapNode node = GSIMapNodeForKey(self, (GSIMapKey)anObject); + + if (node) + { + return YES; + } + } + return NO; +} + +- (id) copyWithZone: (NSZone*)aZone +{ + return NSCopyHashTableWithZone(self, aZone); +} + +- (NSUInteger) count +{ + GSIMapRemoveWeak(self); + return (NSUInteger)nodeCount; +} + +- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState*)state + objects: (id*)stackbuf + count: (NSUInteger)len +{ + state->mutationsPtr = (unsigned long *)&version; + return GSIMapCountByEnumeratingWithStateObjectsCount + (self, state, stackbuf, len); +} + +- (void) dealloc +{ + GSIMapEmptyMap(self); + [super dealloc]; +} + +- (void) encodeWithCoder: (NSCoder*)aCoder +{ + [self subclassResponsibility: _cmd]; +} + +- (void) finalize +{ + GSIMapEmptyMap(self); +} + +- (NSUInteger) hash +{ + return (NSUInteger)nodeCount; +} + +- (id) init +{ + return [self initWithPointerFunctions: nil capacity: 0]; +} + +- (id) initWithCoder: (NSCoder*)aCoder +{ + [self subclassResponsibility: _cmd]; + return nil; +} + +- (id) initWithPointerFunctions: (NSPointerFunctions*)functions + capacity: (NSUInteger)initialCapacity +{ + legacy = NO; + if (![functions isKindOfClass: [NSPointerFunctions class]]) + { + static NSPointerFunctions *defaultFunctions = nil; + + if (defaultFunctions == nil) + { + defaultFunctions + = [[NSPointerFunctions alloc] initWithOptions: 0]; + } + functions = defaultFunctions; + } + self->cb.pf.acquireFunction = functions.acquireFunction; + self->cb.pf.descriptionFunction = functions.descriptionFunction; + self->cb.pf.isEqualFunction = functions.isEqualFunction; + self->cb.pf.relinquishFunction = functions.relinquishFunction; + self->cb.pf.sizeFunction = functions.sizeFunction; + +#if GC_WITH_GC + if (self->cb.pf.usesWeakReadAndWriteBarriers) + { + zone = (NSZone*)nodeW; + } + else + { + zone = (NSZone*)nodeS; + } +#endif + GSIMapInitWithZoneAndCapacity(self, zone, initialCapacity); + return self; +} + +- (NSEnumerator*) objectEnumerator +{ + NSEnumerator *e; + + e = [[NSConcreteHashTableEnumerator alloc] initWithHashTable: self]; + return [e autorelease]; +} + +- (id) member: (id)aKey +{ + if (aKey != nil) + { + GSIMapNode node = GSIMapNodeForKey(self, (GSIMapKey)aKey); + + if (node) + { + return node->key.obj; + } + } + return nil; +} + +- (NSPointerFunctions*) pointerFunctions +{ + NSPointerFunctions *p = [NSPointerFunctions new]; + + p.acquireFunction = self->cb.pf.acquireFunction; + p.descriptionFunction = self->cb.pf.descriptionFunction; + p.isEqualFunction = self->cb.pf.isEqualFunction; + p.relinquishFunction = self->cb.pf.relinquishFunction; + p.sizeFunction = self->cb.pf.sizeFunction; + return [p autorelease]; +} + +- (void) removeAllObjects +{ + if (nodeCount > 0) + { + GSIMapCleanMap(self); + version++; + } +} + +- (void) removeObject: (id)anObject +{ + if (anObject == nil) + { + NSWarnMLog(@"attempt to remove nil object from hash table %@", self); + return; + } + if (nodeCount > 0) + { + GSIMapTable map = (GSIMapTable)self; + GSIMapBucket bucket; + GSIMapNode node; + + bucket = GSIMapBucketForKey(map, (GSIMapKey)anObject); + node = GSIMapNodeForKeyInBucket(map, bucket, (GSIMapKey)anObject); + if (node != 0) + { + GSIMapRemoveNodeFromMap(map, bucket, node); + GSIMapFreeNode(map, node); + version++; + } + } +} + +- (NSUInteger) sizeInBytesExcluding: (NSHashTable*)exclude +{ + NSUInteger size = [super sizeInBytesExcluding: exclude]; + + if (size > 0) + { +/* If we knew that this table held objects, we could return their size... + * + * GSIMapEnumerator_t enumerator = GSIMapEnumeratorForMap(self); + * GSIMapNode node = GSIMapEnumeratorNextNode(&enumerator); + * + * while (node != 0) + * { + * node = GSIMapEnumeratorNextNode(&enumerator); + * size += [node->key.obj sizeInBytesExcluding: exclude]; + * } + * GSIMapEndEnumerator(&enumerator); + */ + size += GSIMapSize(self) - instanceSize; + } + return size; +} +@end + +@implementation NSConcreteHashTableEnumerator + +- (id) initWithHashTable: (NSConcreteHashTable*)t +{ + table = RETAIN(t); + enumerator = GSIMapEnumeratorForMap(table); + return self; +} + +- (id) nextObject +{ + GSIMapNode node = GSIMapEnumeratorNextNode(&enumerator); + + if (node == 0) + { + return nil; + } + return node->key.obj; +} + +- (void) dealloc +{ + GSIMapEndEnumerator(&enumerator); + RELEASE(table); + [super dealloc]; +} + +@end + diff --git a/src/NSConcreteHashTableInternal.h b/src/NSConcreteHashTableInternal.h new file mode 100644 index 000000000..0f1ee86c4 --- /dev/null +++ b/src/NSConcreteHashTableInternal.h @@ -0,0 +1,232 @@ +/**Interface for NSConcretePointerFunctions for GNUStep + Copyright (C) 2009 Free Software Foundation, Inc. + + Written by: Richard Frith-Macdonald + Date: 2009 + + This file is part of the GNUstep Base Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. + + */ + +#import "Foundation/NSPointerFunctions.h" + +#ifdef __GNUSTEP_RUNTIME__ +# include +#endif + +#if defined(OBJC_CAP_ARC) +# include +# define ARC_WEAK_READ(x) objc_loadWeak((id*)x) +# define ARC_WEAK_WRITE(addr, x) objc_storeWeak((id*)addr, (id)x) +# define WEAK_READ(x) (*x) +# define WEAK_WRITE(addr, x) (*(addr) = x) +# define STRONG_WRITE(addr, x) objc_storeStrong((id*)addr, (id)x) +# define STRONG_ACQUIRE(x) objc_retain(x) +#else +# define WEAK_READ(x) (*x) +# define WEAK_WRITE(addr, x) (*(addr) = x) +# define STRONG_WRITE(addr, x) ASSIGN(*((id*)addr), ((id)x)) +# define STRONG_ACQUIRE(x) RETAIN(((id)x)) +#endif +#ifndef ARC_WEAK_WRITE +# define ARC_WEAK_WRITE(addr, x) WEAK_WRITE(addr, x) +#endif +#ifndef ARC_WEAK_READ +# define ARC_WEAK_READ(x) WEAK_READ(x) +#endif + + +/* Declare a structure type to copy pointer functions information + * around easily. + */ +typedef struct +{ + void* (*acquireFunction)(const void *item, + NSUInteger (*size)(const void *item), BOOL shouldCopy); + + NSString *(*descriptionFunction)(const void *item); + + NSUInteger (*hashFunction)(const void *item, + NSUInteger (*size)(const void *item)); + + BOOL (*isEqualFunction)(const void *item1, const void *item2, + NSUInteger (*size)(const void *item)); + + void (*relinquishFunction)(const void *item, + NSUInteger (*size)(const void *item)); + + NSUInteger (*sizeFunction)(const void *item); + + NSPointerFunctionsOptions options; + +} PFInfo; + +inline static BOOL memoryType(int options, int flag) +{ + return (options & 0xff) == flag; +} + +/* Declare the concrete pointer functions class as a wrapper around + * an instance of the PFInfo structure. + */ +@interface NSConcretePointerFunctions : NSPointerFunctions +{ +@public + PFInfo _x; +} +@end + +/* Wrapper functions to make use of the pointer functions. + */ + +/** + * Reads the pointer from the specified address, inserting a read barrier if + * required. + */ +static inline void *pointerFunctionsRead(PFInfo *PF, void **addr) +{ + if (memoryType(PF->options, NSPointerFunctionsWeakMemory)) + { + return ARC_WEAK_READ((id*)addr); + } + if (memoryType(PF->options, NSPointerFunctionsZeroingWeakMemory)) + { + return WEAK_READ((id*)addr); + } + return *addr; +} + +/** + * Assigns a pointer, inserting the correct write barrier if required. + */ +static inline void pointerFunctionsAssign(PFInfo *PF, void **addr, void *value) +{ + if (memoryType(PF->options, NSPointerFunctionsWeakMemory)) + { + ARC_WEAK_WRITE(addr, value); + } + else if (memoryType(PF->options, NSPointerFunctionsZeroingWeakMemory)) + { + WEAK_WRITE(addr, value); + } + else if (memoryType(PF->options, NSPointerFunctionsStrongMemory)) + { + STRONG_WRITE(addr, value); + } + else + { + *addr = value; + } +} + +/* Acquire the pointer value to store for the specified item. + */ +static inline void * +pointerFunctionsAcquire(PFInfo *PF, void **dst, void *src) +{ + if (PF->acquireFunction != 0) + src = (*PF->acquireFunction)(src, PF->sizeFunction, + PF->options & NSPointerFunctionsCopyIn ? YES : NO); + // FIXME: This shouldn't be here. Acquire and assign are separate + // operations. Acquire is for copy-in operations (i.e. retain / copy), + // assign is for move operations of already-owned pointers. Combining them + // like this is Just Plain Wrongâ„¢ + pointerFunctionsAssign(PF, dst, src); + return src; +} + + +/** + * Moves a pointer from location to another. + */ +static inline void pointerFunctionsMove(PFInfo *PF, void **new, void **old) +{ + pointerFunctionsAssign(PF, new, pointerFunctionsRead(PF, old)); +} + + +/* Generate an NSString description of the item + */ +static inline NSString * +pointerFunctionsDescribe(PFInfo *PF, void *item) +{ + if (PF->descriptionFunction != 0) + return (*PF->descriptionFunction)(item); + return nil; +} + + +/* Generate the hash of the item + */ +static inline NSUInteger +pointerFunctionsHash(PFInfo *PF, void *item) +{ + if (PF->hashFunction != 0) + return (*PF->hashFunction)(item, PF->sizeFunction); + return (NSUInteger)(uintptr_t)item; +} + + +/* Compare two items for equality + */ +static inline BOOL +pointerFunctionsEqual(PFInfo *PF, void *item1, void *item2) +{ + if (PF->isEqualFunction != 0) + return (*PF->isEqualFunction)(item1, item2, PF->sizeFunction); + if (item1 == item2) + return YES; + return NO; +} + + +/* Relinquish the specified item and set it to zero. + */ +static inline void +pointerFunctionsRelinquish(PFInfo *PF, void **itemptr) +{ + + if (PF->relinquishFunction != 0) + (*PF->relinquishFunction)(*itemptr, PF->sizeFunction); + if (memoryType(PF->options, NSPointerFunctionsWeakMemory)) + ARC_WEAK_WRITE(itemptr, 0); + else if (memoryType(PF->options, NSPointerFunctionsZeroingWeakMemory)) + WEAK_WRITE(itemptr, (void*)0); + else + *itemptr = 0; +} + + +static inline void +pointerFunctionsReplace(PFInfo *PF, void **dst, void *src) +{ + if (src != *dst) + { + if (PF->acquireFunction != 0) + src = (*PF->acquireFunction)(src, PF->sizeFunction, + PF->options & NSPointerFunctionsCopyIn ? YES : NO); + if (PF->relinquishFunction != 0) + (*PF->relinquishFunction)(*dst, PF->sizeFunction); + if (memoryType(PF->options, NSPointerFunctionsWeakMemory)) + ARC_WEAK_WRITE(dst, 0); + else if (memoryType(PF->options, NSPointerFunctionsZeroingWeakMemory)) + WEAK_WRITE(dst, (void*)0); + else + *dst = src; + } +} diff --git a/src/NSConcreteMapTable.m b/src/NSConcreteMapTable.m new file mode 100644 index 000000000..38c79d67d --- /dev/null +++ b/src/NSConcreteMapTable.m @@ -0,0 +1,1477 @@ +/** Implementation of NSMapTable for GNUStep + Copyright (C) 2009 Free Software Foundation, Inc. + + Written by: Richard Frith-Macdonald + Date: Feb 2009 + + Based on original o_map code by Albin L. Jones + + This file is part of the GNUstep Base Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. + + $Date: 2008-06-08 11:38:33 +0100 (Sun, 08 Jun 2008) $ $Revision: 26606 $ + */ + +#import "common.h" + +#import "Foundation/NSArray.h" +#import "Foundation/NSAutoreleasePool.h" +#import "Foundation/NSDictionary.h" +#import "Foundation/NSEnumerator.h" +#import "Foundation/NSException.h" +#import "Foundation/NSMapTable.h" +#import "Foundation/NSHashTable.h" +#import "NSConcreteHashTableInternal.h" + +#import "NSPointerFunctions.h" +#import "NSCallBacks.h" +#import + +#define NSWarnFLog(fmt, ...) +#define NSWarnMLog(fmt, ...) + +static Class concreteClass = Nil; +static unsigned instanceSize = 0; + +#define GS_CONSUMED(x) + +/* Here is the interface for the concrete class as used by the functions. + */ + +typedef struct _GSIMapBucket GSIMapBucket_t; +typedef struct _GSIMapNode GSIMapNode_t; +typedef GSIMapBucket_t *GSIMapBucket; +typedef GSIMapNode_t *GSIMapNode; + +@interface NSConcreteMapTable : NSMapTable +{ +@public + NSZone *zone; + size_t nodeCount; /* Number of used nodes in map. */ + size_t bucketCount; /* Number of buckets in map. */ + GSIMapBucket buckets; /* Array of buckets. */ + GSIMapNode freeNodes; /* List of unused nodes. */ + GSIMapNode *nodeChunks; /* Chunks of allocated memory. */ + size_t chunkCount; /* Number of chunks in array. */ + size_t increment; /* Amount to grow by. */ + unsigned long version; /* For fast enumeration. */ + BOOL legacy; /* old style callbacks? */ + union { + struct { + PFInfo k; + PFInfo v; + } pf; + struct { + NSMapTableKeyCallBacks k; + NSMapTableValueCallBacks v; + } old; + }cb; +} +@end + +#define GSI_MAP_TABLE_T NSConcreteMapTable +#define GSI_MAP_TABLE_S instanceSize + +#define GSI_MAP_KTYPES GSUNION_PTR | GSUNION_OBJ +#define GSI_MAP_VTYPES GSUNION_PTR | GSUNION_OBJ +#define GSI_MAP_HASH(M, X)\ + (M->legacy ? M->cb.old.k.hash(M, X.ptr) \ + : pointerFunctionsHash(&M->cb.pf.k, X.ptr)) +#define GSI_MAP_EQUAL(M, X, Y)\ + (M->legacy ? M->cb.old.k.isEqual(M, X.ptr, Y.ptr) \ + : pointerFunctionsEqual(&M->cb.pf.k, X.ptr, Y.ptr)) +#define GSI_MAP_RELEASE_KEY(M, X)\ + (M->legacy ? M->cb.old.k.release(M, X.ptr) \ + : pointerFunctionsRelinquish(&M->cb.pf.k, &X.ptr)) +#define GSI_MAP_RETAIN_KEY(M, X)\ + (M->legacy ? M->cb.old.k.retain(M, X.ptr) \ + : pointerFunctionsAcquire(&M->cb.pf.k, &X.ptr, X.ptr)) +#define GSI_MAP_RELEASE_VAL(M, X)\ + (M->legacy ? M->cb.old.v.release(M, X.ptr) \ + : pointerFunctionsRelinquish(&M->cb.pf.v, &X.ptr)) +#define GSI_MAP_RETAIN_VAL(M, X)\ + (M->legacy ? M->cb.old.v.retain(M, X.ptr) \ + : pointerFunctionsAcquire(&M->cb.pf.v, &X.ptr, X.ptr)) + +/* 2013-05-25 Here are the macros originally added for GC/ARC ... + * but they caused map table entries to be doubly retained :-( + * The question is, are the new versions I hacked in below to + * fix this correct? + +#define GSI_MAP_WRITE_KEY(M, addr, x) \ + if (M->legacy) \ + *(addr) = x;\ + else\ + pointerFunctionsAssign(&M->cb.pf.k, (void**)addr, (x).obj); +#define GSI_MAP_WRITE_VAL(M, addr, x) \ + if (M->legacy) \ + *(addr) = x;\ + else\ + pointerFunctionsAssign(&M->cb.pf.v, (void**)addr, (x).obj); +*/ +#define GSI_MAP_WRITE_KEY(M, addr, x) \ + if (M->legacy) \ + *(addr) = x;\ + else\ + *(id*)(addr) = (x).obj; +#define GSI_MAP_WRITE_VAL(M, addr, x) \ + if (M->legacy) \ + *(addr) = x;\ + else\ + *(id*)(addr) = (x).obj; +#define GSI_MAP_READ_KEY(M,addr) \ + (M->legacy ? *(addr)\ + : (typeof(*addr))pointerFunctionsRead(&M->cb.pf.k, (void**)addr)) +#define GSI_MAP_READ_VALUE(M,addr) \ + (M->legacy ? *(addr)\ + : (typeof(*addr))pointerFunctionsRead(&M->cb.pf.v, (void**)addr)) +#define GSI_MAP_ZEROED(M)\ + (M->legacy ? 0\ + : (((M->cb.pf.k.options | M->cb.pf.v.options)\ + & NSPointerFunctionsZeroingWeakMemory) ? YES : NO)) + +#define GSI_MAP_ENUMERATOR NSMapEnumerator + +#include "GSIMap.h" + +/**** Function Implementations ****/ + +/** + * Returns an array of all the keys in the table. + * NB. The table must contain objects for its keys. + */ +NSArray * +NSAllMapTableKeys(NSMapTable *table) +{ + NSMutableArray *keyArray; + NSMapEnumerator enumerator; + id key = nil; + void *dummy; + + if (table == nil) + { + NSWarnFLog(@"Null table argument supplied"); + return nil; + } + + /* Create our mutable key array. */ + keyArray = [NSMutableArray arrayWithCapacity: NSCountMapTable(table)]; + + /* Get an enumerator for TABLE. */ + enumerator = NSEnumerateMapTable(table); + + /* Step through TABLE... */ + while (NSNextMapEnumeratorPair(&enumerator, (void **)(&key), &dummy)) + { + [keyArray addObject: key]; + } + NSEndMapTableEnumeration(&enumerator); + return keyArray; +} + +/** + * Returns an array of all the values in the table. + * NB. The table must contain objects for its values. + */ +NSArray * +NSAllMapTableValues(NSMapTable *table) +{ + NSMapEnumerator enumerator; + NSMutableArray *valueArray; + id value = nil; + void *dummy; + + if (table == nil) + { + NSWarnFLog(@"Null table argument supplied"); + return nil; + } + + /* Create our mutable value array. */ + valueArray = [NSMutableArray arrayWithCapacity: NSCountMapTable(table)]; + + /* Get an enumerator for TABLE. */ + enumerator = NSEnumerateMapTable(table); + + /* Step through TABLE... */ + while (NSNextMapEnumeratorPair(&enumerator, &dummy, (void **)(&value))) + { + [valueArray addObject: value]; + } + NSEndMapTableEnumeration(&enumerator); + return valueArray; +} + +static BOOL +equalPointers(const void *item1, const void *item2, + NSUInteger (*size)(const void *item)) +{ + return (item1 == item2) ? YES : NO; +} + +/** + * Compares the two map tables for equality. + * If the tables are different sizes, returns NO. + * Otherwise, compares the keys (not the values) + * in the two map tables and returns NO if they differ.
+ * The GNUstep implementation enumerates the keys in table1 + * and uses the hash and isEqual functions of table2 for comparison. + */ +BOOL +NSCompareMapTables(NSMapTable *table1, NSMapTable *table2) +{ + if (table1 == table2) + { + return YES; + } + if (table1 == nil) + { + NSWarnFLog(@"Null first argument supplied"); + return NO; + } + if (table2 == nil) + { + NSWarnFLog(@"Null second argument supplied"); + return NO; + } + + if ([table1 count] != [table2 count]) + { + return NO; + } + + if (object_getClass(table1) != concreteClass + && object_getClass(table2) == concreteClass) + { + id t = table1; + + table1 = table2; + table2 = t; + } + + if (object_getClass(table1) == concreteClass) + { + NSConcreteMapTable *c1 = (NSConcreteMapTable*)table1; + GSIMapTable t1 = (GSIMapTable)table1; + BOOL result = YES; + NSMapEnumerator enumerator; + GSIMapNode n1; + + enumerator = GSIMapEnumeratorForMap(t1); + if (object_getClass(table2) == concreteClass) + { + GSIMapTable t2 = (GSIMapTable)table2; + + while ((n1 = GSIMapEnumeratorNextNode(&enumerator)) != 0) + { + GSIMapNode n2; + + n2 = GSIMapNodeForKey(t2, n1->key); + if (n2 == 0) + { + result = NO; + } + else + { + void *v1 = n1->value.ptr; + void *v2 = n2->value.ptr; + + result = (c1->legacy + ? c1->cb.old.k.isEqual(c1, v1, v2) + : pointerFunctionsEqual(&c1->cb.pf.v, v2, v2)); + } + if (result == NO) + { + break; + } + } + } + else + { + while ((n1 = GSIMapEnumeratorNextNode(&enumerator)) != 0) + { + void *k1 = n1->key.ptr; + void *v1 = n1->value.ptr; + void *v2 = NSMapGet(table2, k1); + + result = (c1->legacy + ? c1->cb.old.k.isEqual(c1, v1, v2) + : pointerFunctionsEqual(&c1->cb.pf.v, v1, v2)); + if (result == NO) + { + break; + } + } + } + GSIMapEndEnumerator((GSIMapEnumerator)&enumerator); + return result; + } + else + { + BOOL result = YES; + NSMapEnumerator enumerator; + void *k1; + void *v1; + NSPointerFunctions *pf; + BOOL (*isEqualFunction)(const void *item1, const void *item2, + NSUInteger (*size)(const void *item)); + NSUInteger (*sizeFunction)(const void *item); + + /* Get functions needed for comparison. + */ + pf = [table1 valuePointerFunctions]; + isEqualFunction = [pf isEqualFunction]; + sizeFunction = [pf sizeFunction]; + if (isEqualFunction == 0) isEqualFunction = equalPointers; + + enumerator = NSEnumerateMapTable(table1); + while (NSNextMapEnumeratorPair(&enumerator, &k1, &v1) == YES) + { + void *v2 = NSMapGet(table2, k1); + + if ((*isEqualFunction)(v1, v2, sizeFunction) == NO) + { + result = NO; + break; + } + } + NSEndMapTableEnumeration(&enumerator); + return result; + } +} + +/** + * Copy the supplied map table.
+ * Returns a map table, space for which is allocated in zone, which + * has (newly retained) copies of table's keys and values. As always, + * if zone is 0, then NSDefaultMallocZone() is used. + */ +NSMapTable * +NSCopyMapTableWithZone(NSMapTable *table, NSZone *zone) +{ + GSIMapTable o = (GSIMapTable)table; + GSIMapTable t; + GSIMapNode n; + + if (table == nil) + { + NSWarnFLog(@"Null table argument supplied"); + return 0; + } + t = (GSIMapTable)[concreteClass allocWithZone: zone]; + t->legacy = o->legacy; + if (t->legacy == YES) + { + t->cb.old.k = o->cb.old.k; + t->cb.old.v = o->cb.old.v; + } + else + { + t->cb.pf.k = o->cb.pf.k; + t->cb.pf.v = o->cb.pf.v; + } + GSIMapInitWithZoneAndCapacity(t, zone, ((GSIMapTable)table)->nodeCount); + + if (object_getClass(table) == concreteClass) + { + NSMapEnumerator enumerator; + + enumerator = GSIMapEnumeratorForMap((GSIMapTable)table); + while ((n = GSIMapEnumeratorNextNode(&enumerator)) != 0) + { + GSIMapAddPair(t, n->key, n->value); + } + GSIMapEndEnumerator((GSIMapEnumerator)&enumerator); + } + else + { + NSEnumerator *enumerator; + id k; + + enumerator = [table keyEnumerator]; + while ((k = [enumerator nextObject]) != nil) + { + GSIMapAddPair(t, (GSIMapKey)k, (GSIMapVal)[table objectForKey: k]); + } + } + + return (NSMapTable*)t; +} + +/** + * Returns the number of key/value pairs in the table. + */ +NSUInteger +NSCountMapTable(NSMapTable *table) +{ + if (table == nil) + { + NSWarnFLog(@"Null table argument supplied"); + return 0; + } + if (object_getClass(table) == concreteClass) + { + return ((GSIMapTable)table)->nodeCount; + } + return [table count]; +} + +/** + * Create a new map table by calling NSCreateMapTableWithZone() using + * NSDefaultMallocZone().
+ * Returns a (pointer to) an NSMapTable space for which is allocated + * in the default zone. If capacity is small or 0, then the returned + * table has a reasonable capacity. + */ +NSMapTable * +NSCreateMapTable( + NSMapTableKeyCallBacks keyCallBacks, + NSMapTableValueCallBacks valueCallBacks, + NSUInteger capacity) +{ + return NSCreateMapTableWithZone(keyCallBacks, valueCallBacks, + capacity, NSDefaultMallocZone()); +} + +/** + * Create a new map table using the supplied callbacks structures. + * If any functions in the callback structures are null the default + * values are used ... as for non-owned pointers.
+ * Of course, if you send 0 for zone, then the map table will be + * created in NSDefaultMallocZone().
+ * The table will be created with the specified capacity ... ie ready + * to hold at least that many items. + */ +NSMapTable * +NSCreateMapTableWithZone( + NSMapTableKeyCallBacks k, + NSMapTableValueCallBacks v, + NSUInteger capacity, + NSZone *zone) +{ + GSIMapTable table; + + if (concreteClass == Nil) + { + [NSConcreteMapTable class]; // Force +initialize + NSCAssert(concreteClass != Nil, NSInternalInconsistencyException); + } + table = (GSIMapTable)[concreteClass allocWithZone: zone]; + + if (k.hash == 0) + k.hash = NSNonOwnedPointerMapKeyCallBacks.hash; + if (k.isEqual == 0) + k.isEqual = NSNonOwnedPointerMapKeyCallBacks.isEqual; + if (k.retain == 0) + k.retain = NSNonOwnedPointerMapKeyCallBacks.retain; + if (k.release == 0) + k.release = NSNonOwnedPointerMapKeyCallBacks.release; + if (k.describe == 0) + k.describe = NSNonOwnedPointerMapKeyCallBacks.describe; + + if (v.retain == 0) + v.retain = NSNonOwnedPointerMapValueCallBacks.retain; + if (v.release == 0) + v.release = NSNonOwnedPointerMapValueCallBacks.release; + if (v.describe == 0) + v.describe = NSNonOwnedPointerMapValueCallBacks.describe; + + table->legacy = YES; + table->cb.old.k = k; + table->cb.old.v = v; + + GSIMapInitWithZoneAndCapacity(table, zone, capacity); + + return (NSMapTable*)table; +} + +/** + * Function to be called when finished with the enumerator. + * This permits memory used by the enumerator to be released! + */ +void +NSEndMapTableEnumeration(NSMapEnumerator *enumerator) +{ + if (enumerator == 0) + { + NSWarnFLog(@"Null enumerator argument supplied"); + return; + } + if (enumerator->map != 0) + { + /* The 'map' field is non-null, so this NSMapEnumerator is actually + * a GSIMapEnumerator. + */ + GSIMapEndEnumerator((GSIMapEnumerator)enumerator); + } + else if (enumerator->node != 0) + { + /* The 'map' field is null but the 'node' field is not, so the + * NSMapEnumerator structure actually contains an NSEnumerator + * in the 'node' field, and the map table being enumerated in the + * 'bucket' field. + */ + [(id)enumerator->node release]; + memset(enumerator, '\0', sizeof(NSMapEnumerator)); + } +} + +/** + * Return an enumerator for stepping through a map table using the + * NSNextMapEnumeratorPair() function. + */ +NSMapEnumerator +NSEnumerateMapTable(NSMapTable *table) +{ + if (table == nil) + { + NSMapEnumerator v = {0, 0, 0}; + + NSWarnFLog(@"Null table argument supplied"); + return v; + } + if (object_getClass(table) == concreteClass) + { + return GSIMapEnumeratorForMap((GSIMapTable)table); + } + else + { + NSMapEnumerator v = {0, 0, 0}; + NSEnumerator *e = [[table keyEnumerator] retain]; + + v.node = (void*)e; + GS_CONSUMED(e) + v.bucket = (unsigned long)(uintptr_t)table; + return v; + } +} + +/** + * Destroy the map table and release its contents.
+ * Releases all the keys and values of table (using the key and + * value callbacks specified at the time of table's creation), + * and then proceeds to deallocate the space allocated for table itself. + */ +void +NSFreeMapTable(NSMapTable *table) +{ + if (table == nil) + { + NSWarnFLog(@"Null table argument supplied"); + } + else + { + [table release]; + } +} + +/** + * Returns the value for the specified key, or a null pointer if the + * key is not found in the table. + */ +void * +NSMapGet(NSMapTable *table, const void *key) +{ + if (table == nil) + { + NSWarnFLog(@"Null table argument supplied"); + return 0; + } + if (object_getClass(table) == concreteClass) + { + GSIMapNode n; + + n = GSIMapNodeForKey((GSIMapTable)table, (GSIMapKey)key); + if (n == 0) + { + return 0; + } + else + { + return n->value.ptr; + } + } + else + { + return [table objectForKey: (id)key]; + } +} + +/** + * Adds the key and value to table.
+ * If an equal key is already in table, replaces its mapped value + * with the new one, without changing the key itself.
+ * If key is equal to the notAKeyMarker field of the table's + * NSMapTableKeyCallBacks, raises an NSInvalidArgumentException. + */ +void +NSMapInsert(NSMapTable *table, const void *key, const void *value) +{ + if (table == nil) + { + [NSException raise: NSInvalidArgumentException + format: @"Attempt to place key-value in null table"]; + } + if (object_getClass(table) == concreteClass) + { + GSIMapTable t = (GSIMapTable)table; + GSIMapNode n; + + if (t->legacy == YES) + { + if (key == t->cb.old.k.notAKeyMarker) + { + [NSException raise: NSInvalidArgumentException + format: @"Attempt to place notAKeyMarker in map"]; + } + } + else if (key == 0) + { + [NSException raise: NSInvalidArgumentException + format: @"Attempt to place nil key in map"]; + } + n = GSIMapNodeForKey(t, (GSIMapKey)key); + if (n == 0) + { + GSIMapAddPair(t, (GSIMapKey)key, (GSIMapVal)value); + t->version++; + } + else if (n->value.ptr != value) + { + GSIMapVal tmp = n->value; + + n->value = (GSIMapVal)value; + GSI_MAP_RETAIN_VAL(t, n->value); + GSI_MAP_RELEASE_VAL(t, tmp); + t->version++; + } + } + else + { + [table setObject: (id)value forKey: (id)key]; + } +} + +/** + * Adds the key and value to table and returns nul.
+ * If an equal key is already in table, returns the old key + * instead of adding the new key-value pair.
+ * If key is equal to the notAKeyMarker field of the table's + * NSMapTableKeyCallBacks, raises an NSInvalidArgumentException. + */ +void * +NSMapInsertIfAbsent(NSMapTable *table, const void *key, const void *value) +{ + if (table == nil) + { + [NSException raise: NSInvalidArgumentException + format: @"Attempt to place key-value in null table"]; + } + if (object_getClass(table) == concreteClass) + { + GSIMapTable t = (GSIMapTable)table; + GSIMapNode n; + + if (t->legacy == YES) + { + if (key == t->cb.old.k.notAKeyMarker) + { + [NSException raise: NSInvalidArgumentException + format: @"Attempt to place notAKeyMarker in map table"]; + } + } + else if (key == 0) + { + [NSException raise: NSInvalidArgumentException + format: @"Attempt to place nil key in map"]; + } + n = GSIMapNodeForKey(t, (GSIMapKey)key); + if (n == 0) + { + GSIMapAddPair(t, (GSIMapKey)key, (GSIMapVal)value); + t->version++; + return 0; + } + else + { + return n->key.ptr; + } + } + else + { + void *v = (void*)[table objectForKey: (id)key]; + + if (v == 0) + { + [table setObject: (id)value forKey: (id)v]; + return 0; + } + return v; + } +} + +/** + * Adds the key and value to table and returns nul.
+ * If an equal key is already in table, raises an NSInvalidArgumentException. + *
If key is equal to the notAKeyMarker field of the table's + * NSMapTableKeyCallBacks, raises an NSInvalidArgumentException. + */ +void +NSMapInsertKnownAbsent(NSMapTable *table, const void *key, const void *value) +{ + if (table == nil) + { + [NSException raise: NSInvalidArgumentException + format: @"Attempt to place key-value in null table"]; + } + if (object_getClass(table) == concreteClass) + { + GSIMapTable t = (GSIMapTable)table; + GSIMapNode n; + + if (t->legacy == YES) + { + if (key == t->cb.old.k.notAKeyMarker) + { + [NSException raise: NSInvalidArgumentException + format: @"Attempt to place notAKeyMarker in map table"]; + } + } + else if (key == 0) + { + [NSException raise: NSInvalidArgumentException + format: @"Attempt to place nil key in map"]; + } + n = GSIMapNodeForKey(t, (GSIMapKey)key); + if (n == 0) + { + GSIMapAddPair(t, (GSIMapKey)key, (GSIMapVal)value); + t->version++; + } + else + { + [NSException raise: NSInvalidArgumentException + format: @"NSMapInsertKnownAbsent ... key not absent"]; + } + } + else + { + void *v = (void*)[table objectForKey: (id)key]; + + if (v == 0) + { + [table setObject: (id)value forKey: (id)v]; + } + else + { + [NSException raise: NSInvalidArgumentException + format: @"NSMapInsertKnownAbsent ... key not absent"]; + } + } +} + +/** + * Returns a flag to say whether the table contains the specified key. + * Returns the original key and the value it maps to.
+ * The GNUstep implementation checks originalKey and value to see if + * they are null pointers, and only updates them if non-null. + */ +BOOL +NSMapMember(NSMapTable *table, const void *key, + void **originalKey, void **value) +{ + if (table == nil) + { + NSWarnFLog(@"Null table argument supplied"); + return NO; + } + if (object_getClass(table) == concreteClass) + { + GSIMapNode n; + + n = GSIMapNodeForKey((GSIMapTable)table, (GSIMapKey)key); + if (n == 0) + { + return NO; + } + else + { + if (originalKey != 0) + { + *originalKey = n->key.ptr; + } + if (value != 0) + { + *value = n->value.ptr; + } + return YES; + } + } + else + { + return [table objectForKey: (id)key] ? YES : NO; + } +} + +/** + * Remove the specified key from the table (if present).
+ * Causes the key and its associated value to be released. + */ +void +NSMapRemove(NSMapTable *table, const void *key) +{ + if (table == nil) + { + NSWarnFLog(@"Null table argument supplied"); + return; + } + if (object_getClass(table) == concreteClass) + { + if (((GSIMapTable)table)->nodeCount > 0) + { + GSIMapRemoveKey((GSIMapTable)table, (GSIMapKey)key); + ((GSIMapTable)table)->version++; + } + } + else + { + [table removeObjectForKey: (id)key]; + } +} + +/** + * Step through the map table ... return the next key-value pair and + * return YES, or hit the end of the table and return NO.
+ * The enumerator parameter is a value supplied by NSEnumerateMapTable() + * and must be destroyed using NSEndMapTableEnumeration().
+ * The GNUstep implementation permits either key or value to be a + * null pointer, and refrains from attempting to return the appropriate + * result in that case. + */ +BOOL +NSNextMapEnumeratorPair(NSMapEnumerator *enumerator, + void **key, void **value) +{ + if (enumerator == 0) + { + NSWarnFLog(@"Null enumerator argument supplied"); + return NO; + } + if (enumerator->map != 0) + { + GSIMapNode n; + + /* The 'map' field is non-null, so this NSMapEnumerator is actually + * a GSIMapEnumerator and we can use the GSIMap... functions to work + * with it. + */ + n = GSIMapEnumeratorNextNode((GSIMapEnumerator)enumerator); + if (n == 0) + { + return NO; + } + else + { + if (key != 0) + { + *key = n->key.ptr; + } + else + { + NSWarnFLog(@"Null key return address"); + } + + if (value != 0) + { + *value = n->value.ptr; + } + else + { + NSWarnFLog(@"Null value return address"); + } + return YES; + } + } + else if (enumerator->node != 0) + { + id k; + + /* The 'map' field is null but the 'node' field is not, so the + * NSMapEnumerator structure actually contains an NSEnumerator + * in the 'node' field, and the map table being enumerated in the + * 'bucket' field. + */ + k = [(NSEnumerator*)enumerator->node nextObject]; + if (k == nil) + { + return NO; + } + if (key != 0) + { + *key = k; + } + else + { + NSWarnFLog(@"Null key return address"); + } + if (value != 0) + { + *value = [(NSMapTable*)enumerator->bucket objectForKey: k]; + } + else + { + NSWarnFLog(@"Null value return address"); + } + return YES; + } + else + { + return NO; + } +} + +/** + * Empty the map table (releasing every key and value), + * but preserve its capacity. + */ +void +NSResetMapTable(NSMapTable *table) +{ + if (table == nil) + { + NSWarnFLog(@"Null table argument supplied"); + return; + } + if (object_getClass(table) == concreteClass) + { + if (((GSIMapTable)table)->nodeCount > 0) + { + GSIMapCleanMap((GSIMapTable)table); + ((GSIMapTable)table)->version++; + } + } + else + { + [table removeAllObjects]; + } +} + +/** + * Returns a string describing the table contents.
+ * For each key-value pair, a string of the form "key = value;\n" + * is appended. The appropriate describe functions are used to generate + * the strings for each key and value. + */ +NSString * +NSStringFromMapTable(NSMapTable *table) +{ + if (table == nil) + { + NSWarnFLog(@"Null table argument supplied"); + return nil; + } + if (object_getClass(table) == concreteClass) + { + GSIMapTable t = (GSIMapTable)table; + NSMutableString *string; + NSMapEnumerator enumerator; + void *key; + void *value; + + string = [NSMutableString stringWithCapacity: 0]; + enumerator = NSEnumerateMapTable(table); + + /* + * Now, just step through the elements of the table, and add their + * descriptions to the string. + */ + if (t->legacy) + { + while (NSNextMapEnumeratorPair(&enumerator, &key, &value) == YES) + { + [string appendFormat: @"%@ = %@;\n", + (t->cb.old.k.describe)(table, key), + (t->cb.old.v.describe)(table, value)]; + } + } + else + { + while (NSNextMapEnumeratorPair(&enumerator, &key, &value) == YES) + { + [string appendFormat: @"%@ = %@;\n", + (t->cb.pf.k.descriptionFunction)(key), + (t->cb.pf.v.descriptionFunction)(value)]; + } + } + NSEndMapTableEnumeration(&enumerator); + return string; + } + else + { + return [table description]; + } +} + + + + +/* These are to increase readabilty locally. */ +typedef NSUInteger (*NSMT_hash_func_t)(NSMapTable *, const void *); +typedef BOOL (*NSMT_is_equal_func_t)(NSMapTable *, const void *, const void *); +typedef void (*NSMT_retain_func_t)(NSMapTable *, const void *); +typedef void (*NSMT_release_func_t)(NSMapTable *, void *); +typedef NSString *(*NSMT_describe_func_t)(NSMapTable *, const void *); + + +/** For keys that are pointer-sized or smaller quantities. */ +const NSMapTableKeyCallBacks NSIntegerMapKeyCallBacks = +{ + (NSMT_hash_func_t) _NS_int_hash, + (NSMT_is_equal_func_t) _NS_int_is_equal, + (NSMT_retain_func_t) _NS_int_retain, + (NSMT_release_func_t) _NS_int_release, + (NSMT_describe_func_t) _NS_int_describe, + NSNotAnIntMapKey +}; + +/** For backward compatibility. */ +const NSMapTableKeyCallBacks NSIntMapKeyCallBacks = +{ + (NSMT_hash_func_t) _NS_int_hash, + (NSMT_is_equal_func_t) _NS_int_is_equal, + (NSMT_retain_func_t) _NS_int_retain, + (NSMT_release_func_t) _NS_int_release, + (NSMT_describe_func_t) _NS_int_describe, + NSNotAnIntMapKey +}; + +/** For keys that are pointers not freed. */ +const NSMapTableKeyCallBacks NSNonOwnedPointerMapKeyCallBacks = +{ + (NSMT_hash_func_t) _NS_non_owned_void_p_hash, + (NSMT_is_equal_func_t) _NS_non_owned_void_p_is_equal, + (NSMT_retain_func_t) _NS_non_owned_void_p_retain, + (NSMT_release_func_t) _NS_non_owned_void_p_release, + (NSMT_describe_func_t) _NS_non_owned_void_p_describe, + NSNotAPointerMapKey +}; + +/** For keys that are pointers not freed, or 0. */ +const NSMapTableKeyCallBacks NSNonOwnedPointerOrNullMapKeyCallBacks = +{ + (NSMT_hash_func_t) _NS_non_owned_void_p_hash, + (NSMT_is_equal_func_t) _NS_non_owned_void_p_is_equal, + (NSMT_retain_func_t) _NS_non_owned_void_p_retain, + (NSMT_release_func_t) _NS_non_owned_void_p_release, + (NSMT_describe_func_t) _NS_non_owned_void_p_describe, + NSNotAPointerMapKey +}; + +/** For sets of objects without retaining and releasing. */ +const NSMapTableKeyCallBacks NSNonRetainedObjectMapKeyCallBacks = +{ + (NSMT_hash_func_t) _NS_non_retained_id_hash, + (NSMT_is_equal_func_t) _NS_non_retained_id_is_equal, + (NSMT_retain_func_t) _NS_non_retained_id_retain, + (NSMT_release_func_t) _NS_non_retained_id_release, + (NSMT_describe_func_t) _NS_non_retained_id_describe, + NSNotAPointerMapKey +}; + +/** For keys that are objects. */ +const NSMapTableKeyCallBacks NSObjectMapKeyCallBacks = +{ + (NSMT_hash_func_t) _NS_id_hash, + (NSMT_is_equal_func_t) _NS_id_is_equal, + (NSMT_retain_func_t) _NS_id_retain, + (NSMT_release_func_t) _NS_id_release, + (NSMT_describe_func_t) _NS_id_describe, + NSNotAPointerMapKey +}; + +/** For keys that are pointers with transfer of ownership upon insertion. */ +const NSMapTableKeyCallBacks NSOwnedPointerMapKeyCallBacks = +{ + (NSMT_hash_func_t) _NS_owned_void_p_hash, + (NSMT_is_equal_func_t) _NS_owned_void_p_is_equal, + (NSMT_retain_func_t) _NS_owned_void_p_retain, + (NSMT_release_func_t) _NS_owned_void_p_release, + (NSMT_describe_func_t) _NS_owned_void_p_describe, + NSNotAPointerMapKey +}; + +/** For values that are pointer-sized integer quantities. */ +const NSMapTableValueCallBacks NSIntegerMapValueCallBacks = +{ + (NSMT_retain_func_t) _NS_int_retain, + (NSMT_release_func_t) _NS_int_release, + (NSMT_describe_func_t) _NS_int_describe +}; + +/** For backward compatibilty. */ +const NSMapTableValueCallBacks NSIntMapValueCallBacks = +{ + (NSMT_retain_func_t) _NS_int_retain, + (NSMT_release_func_t) _NS_int_release, + (NSMT_describe_func_t) _NS_int_describe +}; + +/** For values that are pointers not freed. */ +const NSMapTableValueCallBacks NSNonOwnedPointerMapValueCallBacks = +{ + (NSMT_retain_func_t) _NS_non_owned_void_p_retain, + (NSMT_release_func_t) _NS_non_owned_void_p_release, + (NSMT_describe_func_t) _NS_non_owned_void_p_describe +}; + +/** For sets of objects without retaining and releasing. */ +const NSMapTableValueCallBacks NSNonRetainedObjectMapValueCallBacks = +{ + (NSMT_retain_func_t) _NS_non_retained_id_retain, + (NSMT_release_func_t) _NS_non_retained_id_release, + (NSMT_describe_func_t) _NS_non_retained_id_describe +}; + +/** For values that are objects. */ +const NSMapTableValueCallBacks NSObjectMapValueCallBacks = +{ + (NSMT_retain_func_t) _NS_id_retain, + (NSMT_release_func_t) _NS_id_release, + (NSMT_describe_func_t) _NS_id_describe +}; + +/** For values that are pointers with transfer of ownership upon insertion. */ +const NSMapTableValueCallBacks NSOwnedPointerMapValueCallBacks = +{ + (NSMT_retain_func_t) _NS_owned_void_p_retain, + (NSMT_release_func_t) _NS_owned_void_p_release, + (NSMT_describe_func_t) _NS_owned_void_p_describe +}; + + + +@interface NSConcreteMapTableKeyEnumerator : NSEnumerator +{ + NSConcreteMapTable *table; + GSIMapEnumerator_t enumerator; +} +- (id) initWithMapTable: (NSConcreteMapTable*)m; +@end + +@interface NSConcreteMapTableObjectEnumerator : NSConcreteMapTableKeyEnumerator +@end + +@implementation NSConcreteMapTable + ++ (void) initialize +{ + if (concreteClass == Nil) + { + concreteClass = [NSConcreteMapTable class]; + instanceSize = class_getInstanceSize(concreteClass); + } +} + +- (id) copyWithZone: (NSZone*)aZone +{ + return NSCopyMapTableWithZone(self, aZone); +} + +- (NSUInteger) count +{ + GSIMapRemoveWeak(self); + return (NSUInteger)nodeCount; +} + +- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState*)state + objects: (id*)stackbuf + count: (NSUInteger)len +{ + state->mutationsPtr = (unsigned long *)&version; + return GSIMapCountByEnumeratingWithStateObjectsCount + (self, state, stackbuf, len); +} + +- (void) dealloc +{ + GSIMapEmptyMap(self); + [super dealloc]; +} + +- (void) encodeWithCoder: (NSCoder*)aCoder +{ + [self subclassResponsibility: _cmd]; +} + +- (void) finalize +{ + GSIMapEmptyMap(self); +} + +- (NSUInteger) hash +{ + return (NSUInteger)nodeCount; +} + +- (id) init +{ + return [self initWithKeyPointerFunctions: nil + valuePointerFunctions: nil + capacity: 0]; +} + +- (id) initWithCoder: (NSCoder*)aCoder +{ + [self subclassResponsibility: _cmd]; + return nil; +} + +- (id) initWithKeyPointerFunctions: (NSPointerFunctions*)keyFunctions + valuePointerFunctions: (NSPointerFunctions*)valueFunctions + capacity: (NSUInteger)initialCapacity +{ + legacy = NO; + + self->cb.pf.k.acquireFunction = keyFunctions.acquireFunction; + self->cb.pf.k.descriptionFunction = keyFunctions.descriptionFunction; + self->cb.pf.k.isEqualFunction = keyFunctions.isEqualFunction; + self->cb.pf.k.relinquishFunction = keyFunctions.relinquishFunction; + self->cb.pf.k.sizeFunction = keyFunctions.sizeFunction; + + self->cb.pf.v.acquireFunction = valueFunctions.acquireFunction; + self->cb.pf.v.descriptionFunction = valueFunctions.descriptionFunction; + self->cb.pf.v.isEqualFunction = valueFunctions.isEqualFunction; + self->cb.pf.v.relinquishFunction = valueFunctions.relinquishFunction; + self->cb.pf.v.sizeFunction = valueFunctions.sizeFunction; + +#if GC_WITH_GC + if (self->cb.pf.k.usesWeakReadAndWriteBarriers) + { + if (self->cb.pf.v.usesWeakReadAndWriteBarriers) + { + zone = (NSZone*)nodeWW; + } + else + { + zone = (NSZone*)nodeWS; + } + } + else + { + if (self->cb.pf.v.usesWeakReadAndWriteBarriers) + { + zone = (NSZone*)nodeSW; + } + else + { + zone = (NSZone*)nodeSS; + } + } +#endif + GSIMapInitWithZoneAndCapacity(self, zone, initialCapacity); + return self; +} + +- (BOOL) isEqual: (id)other +{ + return NSCompareMapTables(self, other); +} + +- (NSEnumerator*) keyEnumerator +{ + NSEnumerator *e; + + e = [[NSConcreteMapTableKeyEnumerator alloc] initWithMapTable: self]; + return [e autorelease]; +} + +- (NSPointerFunctions*) keyPointerFunctions +{ + NSPointerFunctions *p = [NSPointerFunctions new]; + + p.acquireFunction = self->cb.pf.k.acquireFunction; + p.descriptionFunction = self->cb.pf.k.descriptionFunction; + p.isEqualFunction = self->cb.pf.k.isEqualFunction; + p.relinquishFunction = self->cb.pf.k.relinquishFunction; + p.sizeFunction = self->cb.pf.k.sizeFunction; + return [p autorelease]; +} + +- (NSEnumerator*) objectEnumerator +{ + NSEnumerator *e; + + e = [[NSConcreteMapTableObjectEnumerator alloc] initWithMapTable: self]; + return [e autorelease]; +} + +- (id) objectForKey: (id)aKey +{ + if (aKey != nil) + { + GSIMapNode node = GSIMapNodeForKey(self, (GSIMapKey)aKey); + + if (node) + { + return node->value.obj; + } + } + return nil; +} + +- (void) removeAllObjects +{ + if (nodeCount > 0) + { + GSIMapEmptyMap(self); + version++; + } +} + +- (void) removeObjectForKey: (id)aKey +{ + if (aKey == nil) + { + NSWarnMLog(@"attempt to remove nil key from map table %@", self); + return; + } + if (nodeCount > 0) + { + GSIMapTable map = (GSIMapTable)self; + GSIMapBucket bucket; + GSIMapNode node; + + bucket = GSIMapBucketForKey(map, (GSIMapKey)aKey); + node = GSIMapNodeForKeyInBucket(map, bucket, (GSIMapKey)aKey); + if (node != 0) + { + GSIMapRemoveNodeFromMap(map, bucket, node); + GSIMapFreeNode(map, node); + version++; + } + } +} + +- (void) setObject: (id)anObject forKey: (id)aKey +{ + GSIMapNode node; + + if (aKey == nil) + { + [NSException raise: NSInvalidArgumentException + format: @"[%@-%@:] given nil argument", + NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + } + node = GSIMapNodeForKey(self, (GSIMapKey)aKey); + if (node) + { + if (node->value.obj != anObject) + { + GSI_MAP_RELEASE_VAL(self, node->value); + node->value.obj = anObject; + GSI_MAP_RETAIN_VAL(self, node->value); + version++; + } + } + else + { + GSIMapAddPair(self, (GSIMapKey)aKey, (GSIMapVal)anObject); + version++; + } +} + +- (NSPointerFunctions*) valuePointerFunctions +{ + NSPointerFunctions *p = [NSPointerFunctions new]; + + p.acquireFunction = self->cb.pf.v.acquireFunction; + p.descriptionFunction = self->cb.pf.v.descriptionFunction; + p.isEqualFunction = self->cb.pf.v.isEqualFunction; + p.relinquishFunction = self->cb.pf.v.relinquishFunction; + p.sizeFunction = self->cb.pf.v.sizeFunction; + return [p autorelease]; +} + +- (NSUInteger) sizeInBytesExcluding: (NSHashTable*)exclude +{ + NSUInteger size = [super sizeInBytesExcluding: exclude]; + + if (size > 0) + { +/* If we knew that this table held objects, we could return their size... + * + * GSIMapEnumerator_t enumerator = GSIMapEnumeratorForMap(self); + * GSIMapNode node = GSIMapEnumeratorNextNode(&enumerator); + * + * while (node != 0) + * { + * node = GSIMapEnumeratorNextNode(&enumerator); + * size += [node->key.obj sizeInBytesExcluding: exclude]; + * size += [node->value.obj sizeInBytesExcluding: exclude]; + * } + * GSIMapEndEnumerator(&enumerator); + */ + size += GSIMapSize(self) - instanceSize; + } + return size; +} +@end + +@implementation NSConcreteMapTableKeyEnumerator + +- (id) initWithMapTable: (NSConcreteMapTable*)t +{ + table = RETAIN(t); + enumerator = GSIMapEnumeratorForMap(table); + return self; +} + +- (id) nextObject +{ + GSIMapNode node = GSIMapEnumeratorNextNode(&enumerator); + + if (node == 0) + { + return nil; + } + return node->key.obj; +} + +- (void) dealloc +{ + GSIMapEndEnumerator(&enumerator); + RELEASE(table); + [super dealloc]; +} + +@end + +@implementation NSConcreteMapTableObjectEnumerator + +- (id) nextObject +{ + GSIMapNode node = GSIMapEnumeratorNextNode(&enumerator); + + if (node == 0) + { + return nil; + } + return node->value.obj; +} + +@end + diff --git a/src/NSConstantValueExpression.m b/src/NSConstantValueExpression.m index b12e41e82..8ea518774 100644 --- a/src/NSConstantValueExpression.m +++ b/src/NSConstantValueExpression.m @@ -14,9 +14,6 @@ static NSString * const NSConstantValueKey = @"NSConstantValue"; static NSString * const NSConstantValueClassNameKey = @"NSConstantValueClassName"; @implementation NSConstantValueExpression -{ - id constantValue; -} + (BOOL)supportsSecureCoding { diff --git a/src/NSCustomPredicateOperator.h b/src/NSCustomPredicateOperator.h index 876e5cbf2..605f146b4 100644 --- a/src/NSCustomPredicateOperator.h +++ b/src/NSCustomPredicateOperator.h @@ -2,6 +2,9 @@ CF_PRIVATE @interface NSCustomPredicateOperator : NSPredicateOperator +{ + SEL _selector; +} - (id)initWithCustomSelector:(SEL)customSelector modifier:(NSComparisonPredicateModifier)modifier; diff --git a/src/NSCustomPredicateOperator.m b/src/NSCustomPredicateOperator.m index 231e98a48..cafce8b8b 100644 --- a/src/NSCustomPredicateOperator.m +++ b/src/NSCustomPredicateOperator.m @@ -12,9 +12,6 @@ static NSString * const NSSelectorNameKey = @"NSSelectorName"; @implementation NSCustomPredicateOperator -{ - SEL _selector; -} + (BOOL)supportsSecureCoding { diff --git a/src/NSData.m b/src/NSData.m index 79cc2c75d..c51209852 100644 --- a/src/NSData.m +++ b/src/NSData.m @@ -29,14 +29,41 @@ - (id)initWithBytes:(void *)bytes length:(NSUInteger)length copy:(BOOL)shouldCopy freeWhenDone:(BOOL)shouldFree bytesAreVM:(BOOL)vm; @end +#define NSCONCRETEDATA_BUFFER_SIZE 12 CF_PRIVATE @interface NSConcreteData : NSData +{ + // isa: 4 bytes + unsigned int _isInline:1; + unsigned int _retainCount:31; + // 8 bytes + NSUInteger _length; + NSUInteger _capacity; + // 16 bytes + void *_bytes; + // 20 bytes + union { + unsigned char _space[NSCONCRETEDATA_BUFFER_SIZE]; + /* 12 makes a full allocation size of 32 bytes */ + void (^_deallocator)(void *buffer, NSUInteger size); + } _u; +} + @end CF_PRIVATE @interface NSConcreteMutableData : NSMutableData +{ + unsigned int _reserved:1; + unsigned int _bytesNotYetInitialized:1; + unsigned int _hasVM:1; + unsigned int _retainCount:29; + unsigned int _length; + unsigned int _capacity; + void *_bytes; +} @end @@ -52,6 +79,12 @@ CF_PRIVATE CF_PRIVATE @interface NSSubrangeData : NSData +{ + unsigned int _reserved:3; + unsigned int _retainCount:29; + NSRange _range; + NSData *_data; +} - (id)initWithData:(NSData *)data range:(NSRange)range; @end @@ -100,25 +133,8 @@ SINGLETON_RR() @end -#define NSCONCRETEDATA_BUFFER_SIZE 12 - -@implementation NSConcreteData { - // isa: 4 bytes - unsigned int _isInline:1; - unsigned int _retainCount:31; - // 8 bytes - NSUInteger _length; - NSUInteger _capacity; - // 16 bytes - void *_bytes; - // 20 bytes - union { - unsigned char _space[NSCONCRETEDATA_BUFFER_SIZE]; - /* 12 makes a full allocation size of 32 bytes */ - void (^_deallocator)(void *buffer, NSUInteger size); - } _u; -} +@implementation NSConcreteData - (id)initWithBytes:(void *)bytes length:(NSUInteger)length copy:(BOOL)shouldCopy deallocator:(void (^)(void *, NSUInteger))deallocator { self = [super init]; @@ -1199,12 +1215,7 @@ static uint8_t base64EncodeLookup[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm @end -@implementation NSSubrangeData { - unsigned int _reserved:3; - unsigned int _retainCount:29; - NSRange _range; - NSData *_data; -} +@implementation NSSubrangeData - (id)initWithData:(NSData *)data range:(NSRange)range { @@ -1272,15 +1283,7 @@ static uint8_t base64EncodeLookup[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm @end -@implementation NSConcreteMutableData { - unsigned int _reserved:1; - unsigned int _bytesNotYetInitialized:1; - unsigned int _hasVM:1; - unsigned int _retainCount:29; - unsigned int _length; - unsigned int _capacity; - void *_bytes; -} +@implementation NSConcreteMutableData - (id)initWithBytes:(void *)bytes length:(NSUInteger)length copy:(BOOL)shouldCopy deallocator:(void (^)(void *bytes, NSUInteger length))deallocator { @@ -1515,18 +1518,6 @@ static uint8_t base64EncodeLookup[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm @end -typedef enum { - NSPurgeableDataStorageMapped = 0x1, - NSPurgeableDataStorageAvailable = 0x2, - NSPurgeableDataStorageStored = 0x4, - NSPurgeableDataStorageNeedsFree = 0x8, -} NSPurgeableDataBackingFlags; - -typedef struct { - void *data; - NSPurgeableDataBackingFlags flags; - NSUInteger capacity; -} NSPurgeableDataStorage; static void NSPurgeableDataStorageConvert(NSPurgeableDataStorage *storage, NSUInteger length) { @@ -1559,12 +1550,7 @@ static void NSPurgeableDataStorageDiscard(NSPurgeableDataStorage *storage, NSUIn storage->flags &= ~NSPurgeableDataStorageAvailable; } -@implementation NSPurgeableData { - NSUInteger _length; - int32_t _accessCount; - uint8_t _private[32]; - NSPurgeableDataStorage *_dataStorage; -} +@implementation NSPurgeableData - (id)init { diff --git a/src/NSDataDetector.m b/src/NSDataDetector.m index 8a73836ba..5841a7e5f 100644 --- a/src/NSDataDetector.m +++ b/src/NSDataDetector.m @@ -1,8 +1,6 @@ -#import "NSRegularExpression.h" +#import "Foundation/NSRegularExpression.h" -@implementation NSDataDetector { - NSTextCheckingTypes _checkingTypes; -} +@implementation NSDataDetector @synthesize checkingTypes = _checkingTypes; @@ -23,4 +21,4 @@ return self; } -@end \ No newline at end of file +@end diff --git a/src/NSDateFormatter.m b/src/NSDateFormatter.m index 600a3abf6..b7247e081 100644 --- a/src/NSDateFormatter.m +++ b/src/NSDateFormatter.m @@ -16,10 +16,6 @@ #import @implementation NSDateFormatter -{ - NSMutableDictionary *_attributes; - struct __CFDateFormatter *_formatter; -} + (NSString *)localizedStringFromDate:(NSDate *)date dateStyle:(NSDateFormatterStyle)dateStyle timeStyle:(NSDateFormatterStyle)timeStyle { diff --git a/src/NSDecimal.m b/src/NSDecimal.m index 172f334a4..e1d741004 100644 --- a/src/NSDecimal.m +++ b/src/NSDecimal.m @@ -1132,8 +1132,10 @@ NSString *NSDecimalString(const NSDecimal *dcm, id locale) #warning NSDecimalString using lossy unsigned long long version is no better than primitive number stringizing unsigned long long resultNum = 0ULL; - - for (int i = 0; i < MAX(dcm->_length, sizeof(unsigned long long) / sizeof(short)); i++) + + // originally used MAX uses typeof which doesn't work with bitfields +#define spec_max(a,b) ((a) > (b)) ? (a) : (b) + for (int i = 0; i < spec_max(dcm->_length, sizeof(unsigned long long) / sizeof(short)); i++) { // stamp successive unsigned shorts into place inside result resultNum |= (unsigned long long)dcm->_mantissa[i] << (i * 16); diff --git a/src/NSDecimalNumber.m b/src/NSDecimalNumber.m index 7db9a71d8..41b6a29bd 100644 --- a/src/NSDecimalNumber.m +++ b/src/NSDecimalNumber.m @@ -28,6 +28,9 @@ NSString *const NSDecimalNumberOverflowException = @"NSDecimalNumberOverflowExce NSString *const NSDecimalNumberUnderflowException = @"NSDecimalNumberUnderflowException"; NSString *const NSDecimalNumberDivideByZeroException = @"NSDecimalNumberDivideByZeroException"; +#ifndef ULONG_LONG_MAX +# define ULONG_LONG_MAX 0xffffffffffffffffull +#endif CF_PRIVATE @interface NSDecimalNumberPlaceholder : NSDecimalNumber diff --git a/src/NSDictionary.m b/src/NSDictionary.m index 705481192..b3087355b 100644 --- a/src/NSDictionary.m +++ b/src/NSDictionary.m @@ -23,6 +23,7 @@ #import #import +#import "NSExternals.h" @implementation NSDictionary (NSDictionary) diff --git a/src/NSEqualityPredicateOperator.h b/src/NSEqualityPredicateOperator.h index f8de3d872..195bd012f 100644 --- a/src/NSEqualityPredicateOperator.h +++ b/src/NSEqualityPredicateOperator.h @@ -1,6 +1,10 @@ #import "NSPredicateOperator.h" @interface NSEqualityPredicateOperator : NSPredicateOperator +{ + BOOL _negate; + NSComparisonPredicateOptions _options; +} - (id)initWithOperatorType:(NSPredicateOperatorType)type modifier:(NSComparisonPredicateModifier)modifier negate:(BOOL)negate options:(NSComparisonPredicateOptions)options; - (id)initWithOperatorType:(NSPredicateOperatorType)type modifier:(NSComparisonPredicateModifier)modifier negate:(BOOL)negate; diff --git a/src/NSEqualityPredicateOperator.m b/src/NSEqualityPredicateOperator.m index 64a47dd34..8e8104441 100644 --- a/src/NSEqualityPredicateOperator.m +++ b/src/NSEqualityPredicateOperator.m @@ -12,10 +12,6 @@ #import @implementation NSEqualityPredicateOperator -{ - BOOL _negate; - NSComparisonPredicateOptions _options; -} static NSString * const NSNegateKey = @"NSNegate"; static NSString * const NSOptionsKey = @"NSOptions"; diff --git a/src/NSException.m b/src/NSException.m index 364870145..d68e18223 100644 --- a/src/NSException.m +++ b/src/NSException.m @@ -12,10 +12,19 @@ #import #import -#import #import +#define __is_being_debugged__ 0 + +#if __OBJC2__ extern void objc_setUncaughtExceptionHandler(void (*handler)(id, void *)); +#else +# import +static void objc_setUncaughtExceptionHandler(void (*handler)(id, void *)) +{ + _CFDoExceptionOperation(kCFDoExceptionOperationSetUncaughtHandler, handler); +} +#endif static NSUncaughtExceptionHandler *handler = nil; BOOL NSHangOnUncaughtException = NO; diff --git a/src/NSExpressionInternal.h b/src/NSExpressionInternal.h index b3eb8661c..a83486c4a 100644 --- a/src/NSExpressionInternal.h +++ b/src/NSExpressionInternal.h @@ -29,6 +29,9 @@ CF_PRIVATE @interface NSAggregateExpression : NSExpression +{ + id _collection; +} - (id)initWithCollection:(id)collection; @end @@ -37,14 +40,26 @@ CF_PRIVATE @end @interface NSBlockExpression : NSExpression +{ + id (^_block)(id, NSArray *, NSMutableDictionary *); + NSArray *_arguments; +} - (id)initWithType:(NSExpressionType)type block:(id (^)(id, NSArray *, NSMutableDictionary *))block arguments:(NSArray *)arguments; @end @interface NSConstantValueExpression : NSExpression +{ + id constantValue; +} - (id)initWithObject:(id)object; @end @interface NSFunctionExpression : NSExpression +{ + NSExpression *_operand; + SEL _selector; + NSArray *_arguments; +} - (id)initWithSelector:(SEL)selector argumentArray:(NSArray *)argumentArray; - (id)initWithTarget:(id)target selectorName:(NSString *)selectorName arguments:(NSArray *)arguments; - (id)initWithExpressionType:(NSExpressionType)type operand:(id)operand selector:(SEL)selector argumentArray:(NSArray *)args; @@ -55,6 +70,9 @@ CF_PRIVATE @end @interface NSKeyPathSpecifierExpression : NSExpression +{ + NSString *_value; +} - (id)initWithObject:(id)object; @end @@ -63,28 +81,55 @@ CF_PRIVATE @end @interface NSSetExpression : NSExpression +{ + NSExpression *_left; + NSExpression *_right; +} - (id)initWithType:(NSExpressionType)type leftExpression:(NSExpression *)left rightExpression:(NSExpression *)right; @end @interface NSSubqueryExpression : NSExpression +{ + NSExpression *_collection; + NSExpression *_variableExpression; + NSPredicate *_subpredicate; +} - (id)initWithExpression:(NSExpression *)expression usingIteratorVariable:(NSString *)variable predicate:(NSPredicate *)predicate; @end CF_PRIVATE @interface NSSymbolicExpression : NSExpression +{ + NSString *_token; +} - (id)initWithString:(NSString *)string; @end @interface NSTernaryExpression : NSExpression +{ + NSPredicate *_predicate; + NSExpression *_trueExpression; + NSExpression *_falseExpression; +} - (id)initWithPredicate:(NSPredicate *)predicate trueExpression:(NSExpression *)trueExpression falseExpression:(NSExpression *)falseExpression; @end +@class NSVariableExpression; + CF_PRIVATE @interface NSVariableAssignmentExpression : NSExpression +{ + NSVariableExpression *_assignmentVariable; + NSExpression *_subexpression; +} - (id)initWithAssignmentVariable:(NSString *)variableName expression:(NSExpression *)expression; @end @interface NSVariableExpression : NSExpression +{ + NSString *_variable; +} + - (id)initWithObject:(id)object; @end diff --git a/src/NSExternals.h b/src/NSExternals.h index 2062fee82..70f8643a0 100644 --- a/src/NSExternals.h +++ b/src/NSExternals.h @@ -54,6 +54,7 @@ typedef float CGFloat; #define CGFLOAT_DEFINED #endif +#if 0 struct CGPoint { CGFloat x; CGFloat y; @@ -92,6 +93,7 @@ typedef struct UIOffset { CGFloat horizontal; CGFloat vertical; } UIOffset; +#endif extern NSString *const NS_objects CF_PRIVATE; extern NSString *const NS_keys CF_PRIVATE; @@ -115,9 +117,12 @@ extern NSString *const NS_offset_h CF_PRIVATE; extern NSString *const NS_offset_v CF_PRIVATE; extern NSString *const NS_time CF_PRIVATE; +#if 0 NSString *NSStringFromPoint(CGPoint pt); NSString *NSStringFromSize(CGSize sz); NSString *NSStringFromRect(CGRect r); CGSize NSSizeFromString(NSString *string); CGPoint NSPointFromString(NSString *string); CGRect NSRectFromString(NSString *string); +#endif + diff --git a/src/NSExternals.m b/src/NSExternals.m index d49fda966..1f5d77e93 100644 --- a/src/NSExternals.m +++ b/src/NSExternals.m @@ -10,6 +10,7 @@ #import #import #import +#import NSString *const NS_objects = @"NS.objects"; NSString *const NS_keys = @"NS.keys"; @@ -33,20 +34,22 @@ NSString *const NS_offset_h = @"NS.offset.h"; NSString *const NS_offset_v = @"NS.offset.v"; NSString *const NS_time = @"NS.time"; -NSString *NSStringFromPoint(CGPoint pt) +#if 0 +NSString *NSStringFromPoint(NSPoint pt) { return [NSString stringWithFormat:@"{%.8g, %.8g}", pt.x, pt.y]; } -NSString *NSStringFromSize(CGSize sz) +NSString *NSStringFromSize(NSSize sz) { return [NSString stringWithFormat:@"{%.8g, %.8g}", sz.width, sz.height]; } -NSString *NSStringFromRect(CGRect r) +NSString *NSStringFromRect(NSRect r) { return [NSString stringWithFormat:@"{{%.8g, %.8g}, {%.8g, %.8g}}", r.origin.x, r.origin.y, r.size.width, r.size.height]; } +#endif static NSArray *CGFloatArrayFromString(NSString *string) { @@ -70,9 +73,10 @@ static NSArray *CGFloatArrayFromString(NSString *string) return [result autorelease]; } -CGSize NSSizeFromString(NSString *string) +#if 0 +NSSize NSSizeFromString(NSString *string) { - CGSize sz = {0, 0}; + NSSize sz = {0, 0}; NSArray *components = CGFloatArrayFromString(string); if ([components count] == 2) { @@ -82,9 +86,9 @@ CGSize NSSizeFromString(NSString *string) return sz; } -CGPoint NSPointFromString(NSString *string) +NSPoint NSPointFromString(NSString *string) { - CGPoint pt = {0, 0}; + NSPoint pt = {0, 0}; NSArray *components = CGFloatArrayFromString(string); if ([components count] == 2) { @@ -94,9 +98,9 @@ CGPoint NSPointFromString(NSString *string) return pt; } -CGRect NSRectFromString(NSString *string) +NSRect NSRectFromString(NSString *string) { - CGRect r = {{0, 0}, {0, 0}}; + NSRect r = {{0, 0}, {0, 0}}; NSArray *components = CGFloatArrayFromString(string); if ([components count] == 4) { @@ -107,3 +111,5 @@ CGRect NSRectFromString(NSString *string) } return r; } +#endif + diff --git a/src/NSFileAttributes.h b/src/NSFileAttributes.h index cdcd5ebee..8e960ae33 100644 --- a/src/NSFileAttributes.h +++ b/src/NSFileAttributes.h @@ -3,6 +3,21 @@ CF_PRIVATE @interface NSFileAttributes : NSDictionary +{ + NSMutableDictionary *dict; + struct stat statInfo; + struct { + char extensionHidden; + NSDate *creationDate; + struct _fields { + unsigned int extensionHidden:1; + unsigned int creationDate:1; + unsigned int reserved:30; + } validFields; + } catInfo; + NSDictionary *extendedAttrs; + int fileProtectionClass; +} + (id)attributesWithStat:(struct stat *)info; + (id)_attributesAtURL:(NSURL *)url partialReturn:(BOOL)partial filterResourceFork:(BOOL)filter error:(NSError **)error; diff --git a/src/NSFileAttributes.m b/src/NSFileAttributes.m index 4dd6fc199..d1628e674 100644 --- a/src/NSFileAttributes.m +++ b/src/NSFileAttributes.m @@ -12,6 +12,7 @@ #import #import #import +#import @implementation NSDictionary (NSFileAttributes) @@ -107,21 +108,7 @@ } @end -@implementation NSFileAttributes { - NSMutableDictionary *dict; - struct stat statInfo; - struct { - char extensionHidden; - NSDate *creationDate; - struct _fields { - unsigned int extensionHidden:1; - unsigned int creationDate:1; - unsigned int reserved:30; - } validFields; - } catInfo; - NSDictionary *extendedAttrs; - int fileProtectionClass; -} +@implementation NSFileAttributes + (id)attributesWithStat:(struct stat *)info { @@ -165,6 +152,9 @@ #ifdef ANDROID dict[NSFileCreationDate] = [NSDate dateWithTimeIntervalSince1970:(NSTimeInterval)(info->st_ctime * NSEC_PER_SEC + info->st_ctime_nsec) / (NSTimeInterval)NSEC_PER_SEC]; dict[NSFileModificationDate] = [NSDate dateWithTimeIntervalSince1970:(NSTimeInterval)(info->st_mtime * NSEC_PER_SEC + info->st_mtime_nsec) / (NSTimeInterval)NSEC_PER_SEC]; +#elif defined(__APPLE__) + dict[NSFileCreationDate] = [NSDate dateWithTimeIntervalSince1970:(NSTimeInterval)(info->st_ctime * NSEC_PER_SEC + info->st_ctimespec.tv_nsec) / (NSTimeInterval)NSEC_PER_SEC]; + dict[NSFileModificationDate] = [NSDate dateWithTimeIntervalSince1970:(NSTimeInterval)(info->st_mtime * NSEC_PER_SEC + info->st_mtimespec.tv_nsec) / (NSTimeInterval)NSEC_PER_SEC]; #else #error Implementation needed for file time specs #endif @@ -252,6 +242,7 @@ return kUnknownType; } +// Lubos: struct stat's st_flags contains these two flags - (BOOL)fileIsImmutable { return NO; // where is this derived from? diff --git a/src/NSFileHandle.m b/src/NSFileHandle.m index 0bdcf4a09..af73c0dc7 100644 --- a/src/NSFileHandle.m +++ b/src/NSFileHandle.m @@ -8,6 +8,7 @@ #import #import #import +#import #import #import #import @@ -46,20 +47,7 @@ typedef NS_ENUM(unsigned int, NSFileHandleActivity) { CF_PRIVATE @interface NSConcreteFileHandle : NSFileHandle -@end - -CF_PRIVATE -@interface _NSStdIOFileHandle : NSConcreteFileHandle -@end - -CF_PRIVATE -@interface NSNullFileHandle : NSFileHandle -@end - -@interface NSFileHandle () -@end - -@interface NSConcreteFileHandle () { +{ @public int _fd; unsigned short _flags; @@ -79,8 +67,25 @@ CF_PRIVATE } @end +CF_PRIVATE +@interface _NSStdIOFileHandle : NSConcreteFileHandle +@end + +CF_PRIVATE +@interface NSNullFileHandle : NSFileHandle +@end + +@interface NSFileHandle () +@end + +@interface NSConcreteFileHandle () +@end + CF_PRIVATE @interface NSConcreteFileHandleARCWeakRef : NSObject +{ + NSConcreteFileHandle *ref; +} - (void)storeWeak:(NSConcreteFileHandle *)fh; - (id)loadWeak; @end @@ -1389,9 +1394,6 @@ SINGLETON_RR() @end @implementation NSConcreteFileHandleARCWeakRef -{ - NSConcreteFileHandle *ref; -} - (void)storeWeak:(NSConcreteFileHandle *)fh { diff --git a/src/NSFileManager.m b/src/NSFileManager.m index d8aa13ea6..5480b68d7 100644 --- a/src/NSFileManager.m +++ b/src/NSFileManager.m @@ -82,27 +82,7 @@ enum { - (NSArray *)directoryContentsAtPath:(NSString *)path matchingExtension:(NSString *)extension options:(NSDirectoryEnumerationOptions)options keepExtension:(BOOL)keepExtension error:(NSError **)error; @end -@implementation NSFileManager { - id _delegate; - struct { - int shouldCopyItemAtPathToPath:1; - int shouldCopyItemAtURLToURL:1; - int shouldProceedAfterErrorCopyingItemAtPathToPath:1; - int shouldProceedAfterErrorCopyingItemAtURLToURL:1; - int shouldMoveItemAtPathToPath:1; - int shouldMoveItemAtURLToURL:1; - int shouldProceedAfterErrorMovingItemAtPathToPath:1; - int shouldProceedAfterErrorMovingItemAtURLToURL:1; - int shouldLinkItemAtPathToPath:1; - int shouldLinkItemAtURLToURL:1; - int shouldProceedAfterErrorLinkingItemAtPathToPath:1; - int shouldProceedAfterErrorLinkingItemAtURLToURL:1; - int shouldRemoveItemAtPath:1; - int shouldRemoveItemAtURL:1; - int shouldProceedAfterErrorRemovingItemAtPath:1; - int shouldProceedAfterErrorRemovingItemAtURL:1; - } _flags; -} +@implementation NSFileManager static void initializeDirectories(NSMutableSet *paths, NSSearchPathDirectory directory) { @@ -441,6 +421,8 @@ static inline BOOL _NSFileAccessibleForMode(NSString *path, int mode) { #ifdef ANDROID value = [[NSDate alloc] initWithTimeIntervalSince1970:(NSTimeInterval)(s.st_ctime * NSEC_PER_SEC + s.st_ctime_nsec) / (NSTimeInterval)NSEC_PER_SEC]; +#elif defined(__APPLE__) + value = [[NSDate alloc] initWithTimeIntervalSince1970:(NSTimeInterval)(s.st_ctime * NSEC_PER_SEC + s.st_ctimespec.tv_nsec) / (NSTimeInterval)NSEC_PER_SEC]; #else #error Implementation needed for file time specs #endif @@ -449,6 +431,8 @@ static inline BOOL _NSFileAccessibleForMode(NSString *path, int mode) { #ifdef ANDROID value = [[NSDate alloc] initWithTimeIntervalSince1970:(NSTimeInterval)(s.st_atime * NSEC_PER_SEC + s.st_atime_nsec) / (NSTimeInterval)NSEC_PER_SEC]; +#elif defined(__APPLE__) + value = [[NSDate alloc] initWithTimeIntervalSince1970:(NSTimeInterval)(s.st_atime * NSEC_PER_SEC + s.st_atimespec.tv_nsec) / (NSTimeInterval)NSEC_PER_SEC]; #else #error Implementation needed for file time specs #endif @@ -457,6 +441,8 @@ static inline BOOL _NSFileAccessibleForMode(NSString *path, int mode) { #ifdef ANDROID value = [[NSDate alloc] initWithTimeIntervalSince1970:(NSTimeInterval)(s.st_mtime * NSEC_PER_SEC + s.st_mtime_nsec) / (NSTimeInterval)NSEC_PER_SEC]; +#elif defined(__APPLE__) + value = [[NSDate alloc] initWithTimeIntervalSince1970:(NSTimeInterval)(s.st_mtime * NSEC_PER_SEC + s.st_mtimespec.tv_nsec) / (NSTimeInterval)NSEC_PER_SEC]; #else #error Implementation needed for file time specs #endif @@ -465,6 +451,8 @@ static inline BOOL _NSFileAccessibleForMode(NSString *path, int mode) { #ifdef ANDROID value = [[NSDate alloc] initWithTimeIntervalSince1970:(NSTimeInterval)(s.st_mtime * NSEC_PER_SEC + s.st_mtime_nsec) / (NSTimeInterval)NSEC_PER_SEC]; +#elif defined(__APPLE__) + value = [[NSDate alloc] initWithTimeIntervalSince1970:(NSTimeInterval)(s.st_mtime * NSEC_PER_SEC + s.st_mtimespec.tv_nsec) / (NSTimeInterval)NSEC_PER_SEC]; #else #error Implementation needed for file time specs #endif diff --git a/src/NSFilesystemItemRemoveOperation.h b/src/NSFilesystemItemRemoveOperation.h index a3a6d23ec..095b84470 100644 --- a/src/NSFilesystemItemRemoveOperation.h +++ b/src/NSFilesystemItemRemoveOperation.h @@ -3,6 +3,13 @@ CF_PRIVATE @interface NSFilesystemItemRemoveOperation : NSOperation +{ + NSFileManager *_delegate; + NSString *_removePath; + NSError *_error; + void *_state; + BOOL _filterUnderbars; +} + (id)filesystemItemRemoveOperationWithPath:(NSString *)path; + (NSError *)_errorWithErrno:(int)err atPath:(NSString *)path; diff --git a/src/NSFilesystemItemRemoveOperation.m b/src/NSFilesystemItemRemoveOperation.m index 908ce7372..9a93eed1e 100644 --- a/src/NSFilesystemItemRemoveOperation.m +++ b/src/NSFilesystemItemRemoveOperation.m @@ -13,13 +13,7 @@ #import #import -@implementation NSFilesystemItemRemoveOperation { - NSFileManager *_delegate; - NSString *_removePath; - NSError *_error; - void *_state; - BOOL _filterUnderbars; -} +@implementation NSFilesystemItemRemoveOperation + (id)filesystemItemRemoveOperationWithPath:(NSString *)path { @@ -59,7 +53,9 @@ [super dealloc]; } -static int NSFilesystemItemRemoveOperationFunction(const char *path, const struct stat *stat_info, int flags, struct FTW *info, void *ctx) +static _Thread_local void* ctx = NULL; + +static int NSFilesystemItemRemoveOperationFunction(const char *path, const struct stat *stat_info, int flags, struct FTW *info) { NSFilesystemItemRemoveOperation *op = (NSFilesystemItemRemoveOperation *)ctx; NSFileManager *fm = [op delegate]; @@ -100,8 +96,10 @@ static int NSFilesystemItemRemoveOperationFunction(const char *path, const struc { @autoreleasepool { - extern int _nftw_context(const char *path, int (*fn)(const char *, const struct stat *, int, struct FTW *, void *), int nfds, int ftwflags, void *ctx); - int err = _nftw_context([_removePath cString], NSFilesystemItemRemoveOperationFunction, 0, FTW_DEPTH, self); + // extern int _nftw_context(const char *path, int (*fn)(const char *, const struct stat *, int, struct FTW *, void *), int nfds, int ftwflags, void *ctx); + ctx = self; + int err = nftw([_removePath cString], NSFilesystemItemRemoveOperationFunction, 0, FTW_DEPTH); + ctx = NULL; if (_error == nil && err != 0) { NSError *error = [NSFilesystemItemRemoveOperation _errorWithErrno:errno atPath:_removePath]; diff --git a/src/NSFunctionExpression.m b/src/NSFunctionExpression.m index b9c9664f1..77e3ccc94 100644 --- a/src/NSFunctionExpression.m +++ b/src/NSFunctionExpression.m @@ -19,11 +19,6 @@ static NSString * const NSOperandKey = @"NSOperand"; static NSString * const NSSelectorNameKey = @"NSSelectorName"; @implementation NSFunctionExpression -{ - NSExpression *_operand; - SEL _selector; - NSArray *_arguments; -} + (BOOL)supportsSecureCoding { diff --git a/src/NSGeometry.m b/src/NSGeometry.m index 9dff9f014..7b60678af 100644 --- a/src/NSGeometry.m +++ b/src/NSGeometry.m @@ -9,6 +9,7 @@ */ #import "NSGeometry.h" +#import "NSScanner.h" /* * Constant structs @@ -58,7 +59,7 @@ BOOL NSIsEmptyRect(NSRect aRect) /** Returns the rectangle obtained by translating aRect * horizontally by dx and vertically by dy. */ -NSRect NSOffsetRect(NSRect aRect, float dx, float dy) +NSRect NSOffsetRect(NSRect aRect, CGFloat dx, CGFloat dy) { NSRect rect = aRect; @@ -70,7 +71,7 @@ NSRect NSOffsetRect(NSRect aRect, float dx, float dy) /** Returns the rectangle obtained by moving each of aRect's * horizontal sides inward by dy and each of aRect's vertical * sides inward by dx. */ -NSRect NSInsetRect(NSRect aRect, float dX, float dY) +NSRect NSInsetRect(NSRect aRect, CGFloat dX, CGFloat dY) { NSRect rect; @@ -257,7 +258,7 @@ NSRect NSIntegralRect(NSRect aRect) return rect; } -void NSDivideRect(NSRect aRect, NSRect *slice, NSRect *remainder, float amount, NSRectEdge edge) +void NSDivideRect(NSRect aRect, NSRect *slice, NSRect *remainder, CGFloat amount, NSRectEdge edge) { static NSRect sRect; static NSRect rRect; diff --git a/src/NSHTTPCookie.m b/src/NSHTTPCookie.m index 452b88e4c..33faa0f57 100644 --- a/src/NSHTTPCookie.m +++ b/src/NSHTTPCookie.m @@ -31,9 +31,7 @@ NSString * const NSHTTPCookieMaximumAge = @"Max-Age"; NSString * const NSHTTPCookiePort = @"Port"; -@implementation NSHTTPCookie { - CFHTTPCookieRef _cookiePrivate; -} +@implementation NSHTTPCookie + (id)cookieWithProperties:(NSDictionary *)properties { diff --git a/src/NSHTTPCookieStorage.m b/src/NSHTTPCookieStorage.m index af3cd5f82..b0fb596be 100644 --- a/src/NSHTTPCookieStorage.m +++ b/src/NSHTTPCookieStorage.m @@ -14,10 +14,7 @@ #import #import "NSHTTPCookie+private.h" -@implementation NSHTTPCookieStorage { - CFHTTPCookieStorageRef _storage; - NSHTTPCookieAcceptPolicy _acceptPolicy; -} +@implementation NSHTTPCookieStorage + (NSHTTPCookieStorage *)sharedHTTPCookieStorage { diff --git a/src/NSHashTable.m b/src/NSHashTable.m index 81afe0681..edf1a8ee5 100644 --- a/src/NSHashTable.m +++ b/src/NSHashTable.m @@ -1,1122 +1,317 @@ -// -// NSHashTable.m -// Foundation -// -// Copyright (c) 2014 Apportable. All rights reserved. -// +/** NSHashTable implementation for GNUStep. + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * Author: Richard Frith-Macdonald + * + * This file is part of the GNUstep Base Library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02111 USA. + * + * NSHashTable class reference + * $Date$ $Revision$ + */ -#import +#import "common.h" +#import "Foundation/NSArray.h" +#import "Foundation/NSException.h" +#import "Foundation/NSPointerFunctions.h" +#import "Foundation/NSSet.h" +#import "Foundation/NSHashTable.h" +#import "NSCallBacks.h" +#import "GSPrivate.h" -#import -#import "NSFastEnumerationEnumerator.h" -#import "NSObjectInternal.h" -#import "NSPointerFunctionsInternal.h" -#import - -#define NSHashTableZeroingWeakMemory NSPointerFunctionsZeroingWeakMemory - -CF_PRIVATE -@interface NSConcreteHashTable : NSHashTable +@interface NSConcreteHashTable : NSHashTable @end -@implementation NSHashTable +@implementation NSHashTable -+ (id)hashTableWithOptions:(NSPointerFunctionsOptions)options + +static Class abstractClass = 0; +static Class concreteClass = 0; + ++ (id) allocWithZone: (NSZone*)aZone { - return [[[NSConcreteHashTable alloc] initWithOptions:options capacity:0] autorelease]; -} - -+ (id)weakObjectsHashTable -{ - return [[[NSConcreteHashTable alloc] initWithOptions:NSHashTableZeroingWeakMemory capacity:0] autorelease]; -} - -+ (id)hashTableWithWeakObjects -{ - return [[[NSConcreteHashTable alloc] initWithOptions:NSHashTableZeroingWeakMemory capacity:0] autorelease]; -} - -+ (id)allocWithZone:(NSZone *)zone -{ - return NSAllocateObject([NSConcreteHashTable self], 0, NULL); -} - -+ (id)alloc -{ - return NSAllocateObject([NSConcreteHashTable self], 0, NULL); -} - -- (id)init -{ - NSRequestConcreteImplementation(); - return nil; -} - -- (id)initWithOptions:(NSPointerFunctionsOptions)options capacity:(NSUInteger)capacity -{ - NSRequestConcreteImplementation(); - return nil; -} - -- (id)initWithPointerFunctions:(NSPointerFunctions *)pointerFunctions capacity:(NSUInteger)capacity -{ - NSRequestConcreteImplementation(); - return nil; -} - -- (id)mutableCopyWithZone:(NSZone *)zone -{ - return [self copy]; -} - -- (id)copyWithZone:(NSZone *)zone -{ - return [self copy]; -} - -- (NSSet *)setRepresentation -{ - NSMutableSet *set = [NSMutableSet set]; - - for (id obj in self) + if (self == abstractClass) { - [set addObject:obj]; + return NSAllocateObject(concreteClass, 0, aZone); } - - return set; + return NSAllocateObject(self, 0, aZone); } -- (NSMutableSet *)mutableSet ++ (void) initialize { - NSMutableSet *set = [NSMutableSet set]; - - for (id obj in self) + if (abstractClass == 0) { - [set addObject:obj]; - } - - return set; -} - -- (void)minusHashTable:(NSHashTable *)hashTable -{ - if (self == hashTable) - { - [self removeAllObjects]; - return; - } - - for (id obj in hashTable) - { - [self removeObject:obj]; + abstractClass = [NSHashTable class]; + concreteClass = [NSConcreteHashTable class]; } } -- (void)unionHashTable:(NSHashTable *)hashTable ++ (id) hashTableWithOptions: (NSPointerFunctionsOptions)options { - if (self == hashTable) - { - return; - } + NSHashTable *t; - for (id obj in hashTable) + t = [self allocWithZone: NSDefaultMallocZone()]; + t = [t initWithOptions: options + capacity: 0]; + return AUTORELEASE(t); +} + ++ (id) hashTableWithWeakObjects +{ + return [self hashTableWithOptions: + NSPointerFunctionsObjectPersonality | NSPointerFunctionsZeroingWeakMemory]; +} + ++ (id) weakObjectsHashTable +{ + return [self hashTableWithOptions: + NSPointerFunctionsObjectPersonality | NSPointerFunctionsWeakMemory]; +} + +- (id) initWithOptions: (NSPointerFunctionsOptions)options + capacity: (NSUInteger)initialCapacity +{ + NSPointerFunctions *k; + id o; + + k = [[NSPointerFunctions alloc] initWithOptions: options]; + o = [self initWithPointerFunctions: k capacity: initialCapacity]; + [k release]; + return o; +} + +- (id) initWithPointerFunctions: (NSPointerFunctions*)functions + capacity: (NSUInteger)initialCapacity +{ + [self subclassResponsibility: _cmd]; + return nil; +} + +- (void) addObject: (id)object +{ + [self subclassResponsibility: _cmd]; +} + +- (NSArray*) allObjects +{ + NSEnumerator *enumerator; + unsigned nodeCount = [self count]; + unsigned index; + NSArray *a; + GS_BEGINITEMBUF(objects, nodeCount, id); + + enumerator = [self objectEnumerator]; + index = 0; + while (index < nodeCount && (objects[index] = [enumerator nextObject]) != nil) { - [self addObject:obj]; + index++; + } + a = [[[NSArray alloc] initWithObjects: objects count: index] autorelease]; + GS_ENDITEMBUF(); + return a; +} + +- (id) anyObject +{ + return [[self objectEnumerator] nextObject]; +} + +- (BOOL) containsObject: (id)anObject +{ + return [self member: anObject] ? YES : NO; +} + +- (id) copyWithZone: (NSZone*)aZone +{ + [self subclassResponsibility: _cmd]; + return nil; +} + +- (NSUInteger) count +{ + return (NSUInteger)[self subclassResponsibility: _cmd]; +} + +- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState*)state + objects: (id*)stackbuf + count: (NSUInteger)len +{ + return (NSUInteger)[self subclassResponsibility: _cmd]; +} + +- (void) encodeWithCoder: (NSCoder*)aCoder +{ + [self subclassResponsibility: _cmd]; +} + +- (NSUInteger) hash +{ + return [self count]; +} + +- (id) initWithCoder: (NSCoder*)aCoder +{ + [self subclassResponsibility: _cmd]; + return nil; +} + +- (void) intersectHashTable: (NSHashTable*)other +{ + unsigned count = [self count]; + + if (count > 0) + { + NSEnumerator *enumerator; + NSMutableArray *array; + id object; + + array = [NSMutableArray arrayWithCapacity: count]; + enumerator = [self objectEnumerator]; + while ((object = [enumerator nextObject]) != nil) + { + if ([other member: object] == nil) + { + [array addObject: object]; + } + } + enumerator = [array objectEnumerator]; + while ((object = [enumerator nextObject]) != nil) + { + [self removeObject: object]; + } } } -- (void)intersectHashTable:(NSHashTable *)hashTable +- (BOOL) intersectsHashTable: (NSHashTable*)other { - if (self == hashTable) + NSEnumerator *enumerator; + id object; + + enumerator = [self objectEnumerator]; + while ((object = [enumerator nextObject]) != nil) { - return; + if ([other member: object] != nil) + { + return YES; + } } + return NO; +} - NSUInteger count = [self count]; +- (BOOL) isEqual: (id)other +{ + if ([other isKindOfClass: abstractClass] == NO) return NO; + return NSCompareHashTables(self, other); +} - id *objects = malloc(count * sizeof(id)); - if (objects == NULL) +- (BOOL) isEqualToHashTable: (NSHashTable*)other +{ + return NSCompareHashTables(self, other); +} + +- (BOOL) isSubsetOfHashTable: (NSHashTable*)other +{ + NSEnumerator *enumerator; + id object; + + enumerator = [self objectEnumerator]; + while ((object = [enumerator nextObject]) != nil) { - [NSException raise:NSMallocException format:@"Could not allocate buffer"]; - return; + if ([other member: object] == nil) + { + return NO; + } } + return YES; +} - NSUInteger removeIdx = 0; +- (id) member: (id)object +{ + return [self subclassResponsibility: _cmd]; +} - for (id obj in self) +- (void) minusHashTable: (NSHashTable*)other +{ + if ([self count] > 0 && [other count] > 0) { - id member = [hashTable member:obj]; - if (member == nil) - { - objects[removeIdx++] = obj; - } - } + NSEnumerator *enumerator; + id object; - for (NSUInteger idx = 0; idx < removeIdx; idx++) + enumerator = [other objectEnumerator]; + while ((object = [enumerator nextObject]) != nil) + { + [self removeObject: object]; + } + } +} + +- (NSEnumerator*) objectEnumerator +{ + return [self subclassResponsibility: _cmd]; +} + +- (NSPointerFunctions*) pointerFunctions +{ + return [self subclassResponsibility: _cmd]; +} + +- (void) removeAllObjects +{ + NSEnumerator *enumerator; + id object; + + enumerator = [[self allObjects] objectEnumerator]; + while ((object = [enumerator nextObject]) != nil) { - [self removeObject:objects[idx]]; + [self removeObject: object]; } - - free(objects); } -- (BOOL)isSubsetOfHashTable:(NSHashTable *)hashTable +- (void) removeObject: (id)object { - for (id obj in self) + [self subclassResponsibility: _cmd]; +} + +- (NSSet*) setRepresentation +{ + NSEnumerator *enumerator; + NSMutableSet *set; + id object; + + set = [NSMutableSet setWithCapacity: [self count]]; + enumerator = [[self allObjects] objectEnumerator]; + while ((object = [enumerator nextObject]) != nil) { - if ([hashTable member:obj] == nil) - { - return NO; - } + [set addObject: object]; } - - return YES; + return [[set copy] autorelease]; } -- (BOOL)isEqualToHashTable:(NSHashTable *)hashTable +- (void) unionHashTable: (NSHashTable*)other { - if (self == hashTable) + NSEnumerator *enumerator; + id object; + + enumerator = [other objectEnumerator]; + while ((object = [enumerator nextObject]) != nil) { - return YES; + [self addObject: object]; } - - if ([self count] != [hashTable count]) - { - return NO; - } - - for (id obj in self) - { - if ([hashTable member:obj] == nil) - { - return NO; - } - } - - for (id obj in hashTable) - { - if ([self member:obj] == nil) - { - return NO; - } - } - - return YES; -} - -- (BOOL)intersectsHashTable:(NSHashTable *)hashTable -{ - for (id obj in self) - { - if ([hashTable member:obj] != nil) - { - return YES; - } - } - - return NO; -} - -- (BOOL)containsObject:(id)object -{ - return [self getItem:object] ? YES : NO; -} - -- (id)anyObject -{ - for (id object in self) - { - return object; - } - return nil; -} - -- (void)removeAllObjects -{ - [self removeAllItems]; -} - -- (void)removeObject:(id)object -{ - [self removeItem:object]; -} - -- (id)member:(id)object -{ - return (id)[self getItem:object]; -} - -- (NSPointerFunctions *)pointerFunctions -{ - NSRequestConcreteImplementation(); - return nil; -} - -- (void)getKeys:(const void **)keys count:(NSUInteger *)count -{ - NSRequestConcreteImplementation(); -} - -- (void)removeAllItems -{ - NSRequestConcreteImplementation(); -} - -- (id)copy -{ - NSRequestConcreteImplementation(); - return nil; -} - -- (void)removeItem:(const void *)item -{ - NSRequestConcreteImplementation(); -} - -- (void)insertKnownAbsentItem:(const void *)item -{ - NSRequestConcreteImplementation(); -} - -- (void)addObject:(id)object -{ - NSRequestConcreteImplementation(); -} - -- (void *)getItem:(const void *)item -{ - NSRequestConcreteImplementation(); - return NULL; -} - -- (NSUInteger)weakCount -{ - NSRequestConcreteImplementation(); - return 0; -} - -- (NSArray *)allObjects -{ - NSRequestConcreteImplementation(); - return nil; -} - -- (NSUInteger)count -{ - NSRequestConcreteImplementation(); - return 0; -} - -- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)objects count:(NSUInteger)count -{ - NSRequestConcreteImplementation(); - return 0; -} - -- (void)encodeWithCoder:(NSCoder *)coder -{ - NSRequestConcreteImplementation(); -} - -- (id)initWithCoder:(NSCoder *)decoder -{ - [super dealloc]; - return [[NSConcreteHashTable alloc] initWithCoder:decoder]; -} - -- (NSEnumerator *)objectEnumerator -{ - NSRequestConcreteImplementation(); - return nil; -} - -- (NSString *)description -{ - NSRequestConcreteImplementation(); - return nil; } @end -@implementation NSConcreteHashTable -{ - struct NSSlice slice; - NSUInteger count; - NSUInteger capacity; - NSPointerFunctionsOptions options; - NSUInteger mutations; -} - -// NSConcreteHashTable preserves the following invariants: - -// If hash(X) points to nothing, X is not in the table. - -// If hash(X) points to something, X may be in the table. If so, it is -// found by iterating through the items at hash(X), hash(X) + 1, etc. -// until either X is found or nothing is found. - -// This means that adding X to the table means computing hash(X), -// and putting it in the first available slot. - -// This also implies that removing X from the table means restoring -// the invariant. This is the purpose of the rehashAround: method. - -// In particular, if hash(X) == hash(Y) == idx, and X was put in the -// table before Y, the layout before removal will be something like: -// ... | idx - 1 | idx + 0 | idx + 1 | idx + 2 | ... -// ... | NOTHING | X | Y | NOTHING | ... - -// The layout after removing X is then: -// ... | idx - 1 | idx + 0 | idx + 1 | idx + 2 | ... -// ... | NOTHING | NOTHING | Y | NOTHING | ... -// which breaks the invariant above, as hash(Y) points to nothing. - -// Thus we must rehashAround: and move Y back to idx: -// ... | idx - 1 | idx + 0 | idx + 1 | idx + 2 | ... -// ... | NOTHING | Y | NOTHING | NOTHING | ... - - -#define NSDefaultHashTableCapacity 16 - -static inline BOOL decrementCount(NSConcreteHashTable *ht) -{ - if (ht->count > 0) - { - ht->count--; - return YES; - } - else - { - [ht raiseCountUnderflowException]; - return NO; - } -} - -static inline void incrementIndex(NSConcreteHashTable *ht, NSUInteger *idx) -{ - (*idx)++; - if (*idx == ht->capacity) - { - *idx = 0; - } -} - -static inline void decrementIndex(NSConcreteHashTable *ht, NSUInteger *idx) -{ - if (*idx == 0) - { - *idx = ht->capacity; - } - (*idx)--; -} - -// The following is taken from objc-weak.mm -static inline uintptr_t hash_pointer(const void *key) { - uintptr_t k = (uintptr_t)key; - - // Code from CFSet.c -#if __LP64__ - uintptr_t a = 0x4368726973746F70ULL; - uintptr_t b = 0x686572204B616E65ULL; -#else - uintptr_t a = 0x4B616E65UL; - uintptr_t b = 0x4B616E65UL; -#endif - uintptr_t c = 1; - a += k; -#if __LP64__ - a -= b; a -= c; a ^= (c >> 43); - b -= c; b -= a; b ^= (a << 9); - c -= a; c -= b; c ^= (b >> 8); - a -= b; a -= c; a ^= (c >> 38); - b -= c; b -= a; b ^= (a << 23); - c -= a; c -= b; c ^= (b >> 5); - a -= b; a -= c; a ^= (c >> 35); - b -= c; b -= a; b ^= (a << 49); - c -= a; c -= b; c ^= (b >> 11); - a -= b; a -= c; a ^= (c >> 12); - b -= c; b -= a; b ^= (a << 18); - c -= a; c -= b; c ^= (b >> 22); -#else - a -= b; a -= c; a ^= (c >> 13); - b -= c; b -= a; b ^= (a << 8); - c -= a; c -= b; c ^= (b >> 13); - a -= b; a -= c; a ^= (c >> 12); - b -= c; b -= a; b ^= (a << 16); - c -= a; c -= b; c ^= (b >> 5); - a -= b; a -= c; a ^= (c >> 3); - b -= c; b -= a; b ^= (a << 10); - c -= a; c -= b; c ^= (b >> 15); -#endif - return c; -} - -static inline NSUInteger hash(NSConcreteHashTable *ht, const void *item) -{ - return hash_pointer(item) % ht->capacity; -} - -// Returns the index of the first entry in the hash table which is -// equal to the sought item or is nothing. -static NSUInteger searchHashTable(NSConcreteHashTable *ht, const void *searchItem, const void **gotItem, BOOL preserveSentinels) -{ - NSUInteger startingIdx = hash(ht, searchItem); - NSUInteger idx = startingIdx; - - do { - BOOL wasSentinel = YES; - void *item = ht->slice.readAt(ht->slice.items + idx, &wasSentinel); - - if (item != NULL) - { - if (ht->slice.isEqualFunction(item, searchItem, ht->slice.sizeFunction)) - { - if (gotItem != NULL) - { - *gotItem = item; - } - return idx; - } - } - else if (wasSentinel) - { - if (gotItem != NULL) - { - *gotItem = NULL; - } - return idx; - } - else if (!preserveSentinels) - { - ht->slice.clearAt(ht->slice.items + idx); - if (!decrementCount(ht)) - { - return NSNotFound; - } - [ht rehashAround:idx]; - } - - incrementIndex(ht, &idx); - } while (idx != startingIdx); - - if (gotItem != NULL) - { - *gotItem = NULL; - } - return NSNotFound; -} - -static void empty(struct NSSlice *slice, NSUInteger capacity) -{ - for (NSUInteger idx = 0; idx < capacity; idx++) - { - void *item = slice->readAt(slice->items + idx, NULL); - if (item != NULL && slice->relinquishFunction != NULL) - { - slice->relinquishFunction(item, slice->sizeFunction); - } - slice->clearAt(slice->items + idx); - } -} - -static NSUInteger roundCapacityToPowerOfTwo(NSUInteger n) -{ - if (n == 0) - { - return NSDefaultHashTableCapacity; - } - - if ((n & (n - 1)) == 0) - { - return n; - } - - NSUInteger ret = 1; - while (n != 0) - { - ret <<= 1; - n >>= 1; - } - - return ret; -} - -static void NSConcreteHashTableAllocationFailure(void) -{ - [NSException raise:NSMallocException format:@"Unable to allocate backing store for hash table"]; -} - -static BOOL initBackingStore(struct NSSlice *slice, NSUInteger capacity) -{ - [NSConcretePointerFunctions initializeBackingStore:slice sentinel:YES compactable:NO]; - slice->items = slice->allocateFunction(capacity); - - if (slice->items == NULL) - { - NSConcreteHashTableAllocationFailure(); - return NO; - } - - return YES; -} - -- (void)dealloc -{ - empty(&slice, capacity); - slice.freeFunction(slice.items, capacity); - slice.items = NULL; - [super dealloc]; -} - -- (id)initWithPointerFunctions:(NSPointerFunctions *)pointerFunctions capacity:(NSUInteger)cap -{ - if (pointerFunctions == nil) - { - [self release]; - [NSException raise:NSInternalInconsistencyException format:@"Cannot init hash table with nil pointer functions"]; - return nil; - } - - if ([pointerFunctions class] != [NSConcretePointerFunctions self]) - { - [self release]; - [NSException raise:NSInvalidArgumentException format:@"Cannot use unknown subclass of NSPointerFunctions to init hash table"]; - return nil; - } - - NSConcretePointerFunctions *cpf = (NSConcretePointerFunctions *)pointerFunctions; - - memcpy(&slice, &cpf->slice, sizeof(struct NSSlice)); - slice.items = NULL; - - capacity = roundCapacityToPowerOfTwo(cap); - count = 0; - mutations = 0; - options = NSPointerFunctionsOptionsInvalid; - - [self _initBlock]; - - if (!initBackingStore(&slice, capacity)) - { - [self release]; - return nil; - } - - return self; -} - -- (id)initWithOptions:(NSPointerFunctionsOptions)opts capacity:(NSUInteger)cap -{ - options = opts; - capacity = roundCapacityToPowerOfTwo(cap); - count = 0; - mutations = 0; - - [self _initBlock]; - if (![NSConcretePointerFunctions initializeSlice:&slice withOptions:options]) - { - [self release]; - [NSException raise:NSInvalidArgumentException format:@"Bad options to init hash table"]; - return nil; - } - - if (!initBackingStore(&slice, capacity)) - { - [self release]; - return nil; - } - - return self; -} - -- (id)init -{ - return [self initWithOptions:0 capacity:NSDefaultHashTableCapacity]; -} - -- (void)_initBlock -{ - slice.callback = nil; -} - -- (void)encodeWithCoder:(NSCoder *)coder -{ - NSUInteger memoryType = options & NSPointerFunctionsMemoryTypeMask; - if (memoryType != NSPointerFunctionsStrongMemory && - memoryType != NSPointerFunctionsOpaqueMemory) - { - [NSException raise:NSInvalidArgumentException format:@"Cannot encode hash table with weak references"]; - return; - } - - NSUInteger personality = options & NSPointerFunctionsPersonalityMask; - if (personality != NSPointerFunctionsObjectPersonality && - personality != NSPointerFunctionsOpaquePersonality && - personality != NSPointerFunctionsStructPersonality && - personality != NSPointerFunctionsIntegerPersonality) - { - [NSException raise:NSInvalidArgumentException format:@"Cannot encode hash table with object pointer or c string personality"]; - return; - } - - if ((options & NSPointerFunctionsCopyIn) != 0) - { - [NSException raise:NSInvalidArgumentException format:@"Cannot encode hash table created with copy-in option"]; - return; - } - - [coder encodeValueOfObjCType:@encode(NSPointerFunctionsOptions) at:&options]; - - for (id obj in self) - { - if (obj == nil) - { - [NSException raise:NSInvalidArgumentException format:@"Cannot encode nil"]; - return; - } - [coder encodeObject:obj]; - } - - [coder encodeObject:nil]; -} - -- (id)initWithCoder:(NSCoder *)decoder -{ - NSPointerFunctionsOptions decodedOptions = 0; - [decoder decodeValueOfObjCType:@encode(NSPointerFunctionsOptions) at:&decodedOptions]; - - self = [self initWithOptions:decodedOptions capacity:capacity]; - if (self != nil) - { - for (id obj = nil; obj != nil; obj = [decoder decodeObject]) - { - [self addObject:obj]; - } - } - return self; -} - -- (Class)classForCoder -{ - return [NSHashTable self]; -} - -- (id)copy -{ - NSConcreteHashTable *copy = [NSConcreteHashTable alloc]; - - copy->count = 0; - copy->mutations = 0; - copy->options = options; - copy->capacity = capacity; - - memcpy(©->slice, &slice, sizeof(struct NSSlice)); - copy->slice.items = NULL; - - [copy _initBlock]; - - copy->slice.items = copy->slice.allocateFunction(copy->capacity); - if (copy->slice.items == NULL) - { - [self release]; - [NSException raise:NSMallocException format:@"Unable to allocate backing store for hash table"]; - return nil; - } - - for (id item in self) - { - [copy insertItem:item]; - } - - return copy; -} - -- (NSEnumerator *)objectEnumerator -{ - return [[[__NSFastEnumerationEnumerator alloc] initWithObject:self] autorelease]; -} - -- (BOOL)isEqual:(id)other -{ - if (self == other) - { - return YES; - } - - if (other == nil) - { - return NO; - } - - if (![other isKindOfClass:[NSConcreteHashTable self]]) - { - return NO; - } - - NSConcreteHashTable *hashTable = (NSConcreteHashTable *)other; - - if (count != hashTable->count) - { - return NO; - } - - if (slice.isEqualFunction != hashTable->slice.isEqualFunction) - { - return NO; - } - - if (slice.sizeFunction != hashTable->slice.sizeFunction) - { - return NO; - } - - for (NSUInteger idx = 0; idx < capacity; idx++) - { - void *item = slice.readAt(slice.items + idx, NULL); - if (item == NULL) - { - break; - } - - void *otherItem = [hashTable getItem:item]; - - if (!slice.isEqualFunction(item, otherItem, slice.sizeFunction)) - { - return NO; - } - } - - return YES; -} - -- (NSUInteger)hash -{ - if (slice.usesWeak) - { - return (NSUInteger)self; - } - else - { - return count; - } -} - -- (NSString *)description -{ - NSMutableString *desc = [NSMutableString stringWithString:@"NSHashTable {\n"]; - - for (NSUInteger idx = 0; idx < capacity; idx++) - { - id obj = slice.readAt(slice.items + idx, NULL); - if (obj != nil) - { - [desc appendFormat:@"[%llu] %@\n", (unsigned long long)idx, slice.describeFunction(obj)]; - } - } - - [desc appendString:@"}\n"]; - - return desc; -} - -- (void)getKeys:(const void **)keys count:(NSUInteger *)outCount -{ - NSUInteger nonNilIdx = 0; - - for (NSUInteger idx = 0; idx < capacity; idx++) - { - void *item = slice.readAt(slice.items + idx, NULL); - if (item != NULL) - { - keys[nonNilIdx++] = item; - } - } - - if (outCount != NULL) - { - *outCount = nonNilIdx; - } -} - -- (NSArray *)allObjects -{ - NSMutableArray *array = [NSMutableArray array]; - - for (id obj in self) - { - [array addObject:obj]; - } - - return array; -} - -- (void)removeAllItems -{ - empty(&slice, capacity); - mutations++; - count = 0; -} - -- (void)removeItem:(const void *)item -{ - if (item == NULL) - { - return; - } - - const void *gotItem = NULL; - NSUInteger idx = searchHashTable(self, item, &gotItem, YES); - - if (gotItem == NULL) - { - return; - } - - if (slice.relinquishFunction != NULL) - { - slice.relinquishFunction(gotItem, slice.sizeFunction); - } - - slice.clearAt(slice.items + idx); - - if (!decrementCount(self)) - { - return; - } - - mutations++; - - [self rehashAround:idx]; -} - -- (void)insertKnownAbsentItem:(const void *)item -{ - if (item == NULL) - { - return; - } - - void *gotItem = NULL; - NSUInteger idx = searchHashTable(self, item, (const void **)&gotItem, YES); - - if (gotItem != NULL) - { - [NSException raise:NSInvalidArgumentException format:@"Item was not absent from hash table"]; - return; - } - - [self assign:idx key:item]; - - count++; - if (count * 2 > capacity) - { - [self hashGrow]; - } -} - -- (void)addObject:(id)object -{ - if (object == nil) - { - return; - } - - id gotObject = nil; - NSUInteger idx = searchHashTable(self, object, (const void **)&gotObject, YES); - - if (gotObject != nil) - { - return; - } - - [self assign:idx key:object]; - - count++; - if (count * 2 > capacity) - { - [self hashGrow]; - } -} - -- (void)insertItem:(const void *)item -{ - if (item == NULL) - { - return; - } - - void *gotItem = NULL; - NSUInteger idx = searchHashTable(self, item, (const void **)&gotItem, YES); - - [self assign:idx key:item]; - - if (gotItem == NULL) - { - count++; - if (count * 2 > capacity) - { - [self hashGrow]; - } - } -} - -- (void *)getItem:(const void *)item -{ - if (item == NULL) - { - return NULL; - } - - void *gotItem = NULL; - searchHashTable(self, item, (const void **)&gotItem, NO); - - return gotItem; -} - -- (void)rehash -{ - if (count == 0) - { - return; - } - - void * const sentinel = slice.usesSentinel ? _NSPointerFunctionsSentinel : NULL; - - for (NSUInteger idx = 0; idx < count; idx++) - { - void *item = slice.items[idx]; - if (item == sentinel) - { - NSUInteger newIdx = [self rehashAround:idx]; - if (newIdx < idx) - { - return; - } - idx = newIdx; - } - } -} - -- (void)assign:(NSUInteger)idx key:(const void *)key -{ - mutations++; - - if (slice.acquireFunction != NULL) - { - key = slice.acquireFunction(key, slice.sizeFunction, slice.shouldCopyIn); - } - - slice.storeAt(slice.items, (void *)key, idx); -} - -- (void)hashGrow -{ - NSUInteger oldCapacity = capacity; - capacity *= 2; - void **oldItems = slice.items; - slice.items = slice.allocateFunction(capacity); - if (slice.items == NULL) - { - NSConcreteHashTableAllocationFailure(); - return; - } - count = 0; - - - for (NSUInteger idx = 0; idx < oldCapacity; idx++) - { - void *item = slice.readAt(oldItems + idx, NULL); - if (item != NULL) - { - count++; - NSUInteger newIdx = searchHashTable(self, item, NULL, NO); - slice.storeAt(slice.items, item, newIdx); - slice.clearAt(oldItems + idx); - } - } - - slice.freeFunction(oldItems, oldCapacity); -} - -- (NSUInteger)rehashAround:(NSUInteger)startingIdx -{ - void * const sentinel = slice.usesSentinel ? _NSPointerFunctionsSentinel : NULL; - - // Find the first empty empty slot to the left of startingIdx - NSUInteger idx = startingIdx; - do { - decrementIndex(self, &idx); - } while (slice.items[idx] != sentinel); - - while (YES) - { - incrementIndex(self, &idx); - if (idx == startingIdx) - { - incrementIndex(self, &idx); - } - - BOOL wasSentinel = NO; - void *item = slice.readAt(slice.items + idx, &wasSentinel); - - if (item == NULL) - { - slice.clearAt(slice.items + idx); - - if (wasSentinel) - { - return idx; - } - - if (!decrementCount(self)) - { - return NSNotFound; - } - } - else - { - slice.clearAt(slice.items + idx); - NSUInteger newIdx = searchHashTable(self, item, NULL, NO); - slice.storeAt(slice.items, item, newIdx); - } - } -} - -- (void)raiseCountUnderflowException -{ - [NSException raise:NSInternalInconsistencyException format:@"Count underflow in NSConcreteHashTable"]; -} - -- (NSUInteger)count -{ - return count; -} - -- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)objects count:(NSUInteger)count -{ - state->mutationsPtr = (unsigned long *)&mutations; - - while (state->state < capacity) - { - void *item = slice.readAt(slice.items + state->state, NULL); - state->state++; - if (item != NULL) - { - state->itemsPtr = (id *)&state->extra[2]; - *state->itemsPtr = item; - return 1; - } - } - - return 0; -} - -- (NSPointerFunctions *)pointerFunctions -{ - NSConcretePointerFunctions *pf = [[NSConcretePointerFunctions alloc] autorelease]; - memcpy(&pf->slice, &slice, sizeof(struct NSSlice)); - pf->slice.items = NULL; - return pf; -} - -@end diff --git a/src/NSHost.m b/src/NSHost.m index 594b1904b..87c8f59bf 100644 --- a/src/NSHost.m +++ b/src/NSHost.m @@ -37,6 +37,10 @@ #import "Foundation/NSNull.h" #import "Foundation/NSSet.h" #import "Foundation/NSCoder.h" +#import "Foundation/NSString.h" +#include +#include +#include #if defined(_WIN32) #include @@ -55,6 +59,8 @@ extern int inet_pton(int , const char *, void *); #define INADDR_NONE -1 #endif +#define IF_NO_GC(x) x + static NSString *localHostName = @"GNUstep local host"; static Class hostClass; static NSRecursiveLock *_hostCacheLock = nil; @@ -388,11 +394,11 @@ myHostName() { hostClass = self; null = [[NSNull null] retain]; - [[NSObject leakAt: &null] release]; + // [[NSObject leakAt: &null] release]; _hostCacheLock = [[NSRecursiveLock alloc] init]; - [[NSObject leakAt: &_hostCacheLock] release]; + // [[NSObject leakAt: &_hostCacheLock] release]; _hostCache = [NSMutableDictionary new]; - [[NSObject leakAt: &_hostCache] release]; + // [[NSObject leakAt: &_hostCache] release]; } } @@ -590,11 +596,12 @@ myHostName() } /* Methods for encoding/decoding*/ - +#if 0 - (id) replacementObjectForPortCoder: (NSPortCoder*)aCoder { return self; } +#endif - (void) encodeWithCoder: (NSCoder*)aCoder { diff --git a/src/NSInPredicateOperator.h b/src/NSInPredicateOperator.h index dc80c9ea0..3f64e1b3a 100644 --- a/src/NSInPredicateOperator.h +++ b/src/NSInPredicateOperator.h @@ -1,6 +1,13 @@ #import "NSPredicateOperator.h" +#import "NSSubstringPredicateOperator.h" +#import @interface NSInPredicateOperator : NSPredicateOperator +{ + NSComparisonPredicateOptions _flags; + NSSubstringPredicateOperator * _stringVersion; + pthread_mutex_t _mutex; +} - (id)initWithOperatorType:(NSPredicateOperatorType)type modifier:(NSComparisonPredicateModifier)modifier options:(NSComparisonPredicateOptions)options; - (NSComparisonPredicateOptions)flags; diff --git a/src/NSInPredicateOperator.m b/src/NSInPredicateOperator.m index 796b5b1cd..6854fcc90 100644 --- a/src/NSInPredicateOperator.m +++ b/src/NSInPredicateOperator.m @@ -15,11 +15,6 @@ static NSString * NSFlagsKey = @"NSFlags"; @implementation NSInPredicateOperator -{ - NSComparisonPredicateOptions _flags; - NSSubstringPredicateOperator * _stringVersion; - pthread_mutex_t _mutex; -} + (BOOL)supportsSecureCoding { diff --git a/src/NSIndexPath.m b/src/NSIndexPath.m index 376e1fb41..f33ae277e 100644 --- a/src/NSIndexPath.m +++ b/src/NSIndexPath.m @@ -9,11 +9,7 @@ #import #import -@implementation NSIndexPath { - NSUInteger *_indexes; - NSUInteger _hash; - NSUInteger _length; -} +@implementation NSIndexPath + (id)indexPathWithIndex:(NSUInteger)index { diff --git a/src/NSIndexSet.m b/src/NSIndexSet.m index acf014bc9..7774cb6d4 100644 --- a/src/NSIndexSet.m +++ b/src/NSIndexSet.m @@ -10,7 +10,8 @@ #import #import #import -#import +#import +#import "utlist.h" typedef struct RangeList { NSRange range; @@ -18,7 +19,7 @@ typedef struct RangeList { struct RangeList *prev; } RangeList; -typedef struct { +typedef struct NSIndexSetCache { CFArrayRef ranges; NSUInteger count; NSUInteger rangeCount; @@ -79,25 +80,7 @@ SET_CACHE(set, NULL) }) -@implementation NSIndexSet { -@package - struct { - unsigned int _isEmpty:1; - unsigned int _hasSingleRange:1; - unsigned int _cacheValid:1; - unsigned int _arrayBinderController:29; - } _indexSetFlags; - - union { - struct { - NSRange _range; - } _singleRange; - struct { - RangeList *_data; - NSIndexSetCache *_cache; - } _multipleRanges; - } _internal; -} +@implementation NSIndexSet static inline void NSIndexSetPurgeCache(NSIndexSetCache *cache) { diff --git a/src/NSJSONSerialization.m b/src/NSJSONSerialization.m index d2fae5ed7..82ff84f1c 100644 --- a/src/NSJSONSerialization.m +++ b/src/NSJSONSerialization.m @@ -18,17 +18,29 @@ #import "NSBOMEncoding.h" @interface _NSJSONReader : NSObject -@end - -@interface _NSJSONWriter : NSObject -- (int)appendString:(NSString *)string range:(NSRange)range; -@end - -@implementation _NSJSONReader { +{ id input; NSJSONReadingOptions kind; NSError *error; } +@end + +@interface _NSJSONWriter : NSObject +{ + NSOutputStream *outputStream; + NSJSONWritingOptions kind; + char *dataBuffer; + NSUInteger dataBufferLen; + NSUInteger dataLen; + BOOL freeDataBuffer; + char *tempBuffer; + NSUInteger tempBufferLen; + NSInteger totalDataWritten; +} +- (int)appendString:(NSString *)string range:(NSRange)range; +@end + +@implementation _NSJSONReader + (BOOL)validForJSON:(id)obj depth:(NSUInteger)depth allowFragments:(BOOL)frags { @@ -1174,17 +1186,7 @@ static inline BOOL writeObject(_NSJSONWriter *writer, id object, NSJSONWritingOp } } -@implementation _NSJSONWriter { - NSOutputStream *outputStream; - NSJSONWritingOptions kind; - char *dataBuffer; - NSUInteger dataBufferLen; - NSUInteger dataLen; - BOOL freeDataBuffer; - char *tempBuffer; - NSUInteger tempBufferLen; - NSInteger totalDataWritten; -} +@implementation _NSJSONWriter - (id)init { diff --git a/src/NSKeyPathSpecifierExpression.m b/src/NSKeyPathSpecifierExpression.m index 86982d197..10c8c03a0 100644 --- a/src/NSKeyPathSpecifierExpression.m +++ b/src/NSKeyPathSpecifierExpression.m @@ -10,9 +10,6 @@ #import "_NSPredicateUtilities.h" @implementation NSKeyPathSpecifierExpression -{ - NSString *_value; -} static NSString * const NSKeyPathKey = @"NSKeyPath"; diff --git a/src/NSKeyValueAccessor.m b/src/NSKeyValueAccessor.m index 84449095e..05eca8889 100644 --- a/src/NSKeyValueAccessor.m +++ b/src/NSKeyValueAccessor.m @@ -250,6 +250,20 @@ static void _NSSet ## INFIX ##ValueForKeyWithMethod(id obj, SEL cmd, id value, N } \ } +#define DEFINE_SET_WITH_METHOD2(INFIX, TYPE, GETTER, WRAPPER) \ +static void _NSSet ## INFIX ##ValueForKeyWithMethod(id obj, SEL cmd, id value, NSString *key, Method method) \ +{ \ + if (value) \ + { \ + ((void(*)(id, Method, TYPE))method_invoke)(obj, method, WRAPPER([value GETTER])); \ + } \ + else \ + { \ + [obj setNilValueForKey:key]; \ + } \ +} + + DEFINE_SET_WITH_METHOD(Char, char, charValue) DEFINE_SET_WITH_METHOD(UnsignedChar, unsigned char, unsignedCharValue) DEFINE_SET_WITH_METHOD(Short, short, shortValue) @@ -264,9 +278,9 @@ DEFINE_SET_WITH_METHOD(Float, float, floatValue) DEFINE_SET_WITH_METHOD(Double, double, doubleValue) DEFINE_SET_WITH_METHOD(Bool, BOOL, boolValue) DEFINE_SET_WITH_METHOD(Range, NSRange, rangeValue) -DEFINE_SET_WITH_METHOD(Point, CGPoint, pointValue) -DEFINE_SET_WITH_METHOD(Size, CGSize, sizeValue) -DEFINE_SET_WITH_METHOD(Rect, CGRect, rectValue) +DEFINE_SET_WITH_METHOD2(Point, CGPoint, pointValue, NSPointToCGPoint) +DEFINE_SET_WITH_METHOD2(Size, CGSize, sizeValue, NSSizeToCGSize) +DEFINE_SET_WITH_METHOD2(Rect, CGRect, rectValue, NSRectToCGRect) #undef DEFINE_SET_WITH_METHOD @@ -374,6 +388,19 @@ static void _NSSet ## INFIX ##ValueForKeyInIvar(id obj, SEL cmd, id value, NSStr [obj setNilValueForKey:key]; \ } \ } +#define DEFINE_SET_IN_IVAR2(INFIX, TYPE, GETTER, WRAPPER) \ +static void _NSSet ## INFIX ##ValueForKeyInIvar(id obj, SEL cmd, id value, NSString *key, Ivar ivar) \ +{ \ + if (value) \ + { \ + *(TYPE*)((char*)obj + ivar_getOffset(ivar)) = WRAPPER([value GETTER]); \ + } \ + else \ + { \ + [obj setNilValueForKey:key]; \ + } \ +} + DEFINE_SET_IN_IVAR(Char, char, charValue) DEFINE_SET_IN_IVAR(UnsignedChar, unsigned char, unsignedCharValue) @@ -389,9 +416,9 @@ DEFINE_SET_IN_IVAR(Float, float, floatValue) DEFINE_SET_IN_IVAR(Double, double, doubleValue) DEFINE_SET_IN_IVAR(Bool, BOOL, boolValue) DEFINE_SET_IN_IVAR(Range, NSRange, rangeValue) -DEFINE_SET_IN_IVAR(Point, CGPoint, pointValue) -DEFINE_SET_IN_IVAR(Size, CGSize, sizeValue) -DEFINE_SET_IN_IVAR(Rect, CGRect, rectValue) +DEFINE_SET_IN_IVAR2(Point, CGPoint, pointValue, NSPointToCGPoint) +DEFINE_SET_IN_IVAR2(Size, CGSize, sizeValue, NSSizeToCGSize) +DEFINE_SET_IN_IVAR2(Rect, CGRect, rectValue, NSRectToCGRect) #undef DEFINE_SET_IN_IVAR diff --git a/src/NSKeyValueCollectionProxies.h b/src/NSKeyValueCollectionProxies.h index af07130d1..c7fb04c0a 100644 --- a/src/NSKeyValueCollectionProxies.h +++ b/src/NSKeyValueCollectionProxies.h @@ -39,14 +39,35 @@ CF_PRIVATE CF_PRIVATE @interface NSKeyValueNonmutatingArrayMethodSet : NSKeyValueNonmutatingCollectionMethodSet +{ +@public + Method count; + Method objectAtIndex; + Method getObjectsRange; + Method objectsAtIndexes; +} @end CF_PRIVATE @interface NSKeyValueNonmutatingOrderedSetMethodSet : NSKeyValueNonmutatingCollectionMethodSet +{ +@public + Method count; + Method objectAtIndex; + Method indexOfObject; + Method getObjectsRange; + Method objectsAtIndexes; +} @end CF_PRIVATE @interface NSKeyValueNonmutatingSetMethodSet : NSKeyValueNonmutatingCollectionMethodSet +{ +@public + Method count; + Method enumerator; + Method member; +} @end CF_PRIVATE @@ -110,35 +131,59 @@ CF_PRIVATE CF_PRIVATE @interface NSKeyValueProxyGetter : NSKeyValueGetter +{ + Class _proxyClass; +} @end CF_PRIVATE @interface NSKeyValueCollectionGetter : NSKeyValueProxyGetter +{ + NSKeyValueNonmutatingCollectionMethodSet *_methods; +} - (NSKeyValueNonmutatingCollectionMethodSet *)methods; @end CF_PRIVATE @interface NSKeyValueSlowMutableCollectionGetter : NSKeyValueProxyGetter +{ + NSKeyValueGetter *_baseGetter; + NSKeyValueSetter *_baseSetter; +} - (id)initWithContainerClassID:(Class)cls key:(NSString *)key baseGetter:(NSKeyValueGetter *)baseGetter baseSetter:(NSKeyValueSetter *)baseSetter containerIsa:(Class)containerIsa proxyClass:(Class)proxyClass; @end CF_PRIVATE @interface NSKeyValueFastMutableCollection1Getter : NSKeyValueProxyGetter +{ + NSKeyValueNonmutatingCollectionMethodSet *_nonmutatingMethods; + NSKeyValueMutatingCollectionMethodSet *_mutatingMethods; +} - (id)initWithContainerClassID:(Class)cls key:(NSString *)key nonmutatingMethods:(NSKeyValueNonmutatingCollectionMethodSet *)nonmutatingMethods mutatingMethods:(NSKeyValueMutatingCollectionMethodSet *)mutatingMethods proxyClass:(Class)proxyClass; @end CF_PRIVATE @interface NSKeyValueFastMutableCollection2Getter : NSKeyValueProxyGetter +{ + NSKeyValueGetter *_baseGetter; + NSKeyValueMutatingCollectionMethodSet *_mutatingMethods; +} - (id)initWithContainerClassID:(Class)cls key:(NSString *)key baseGetter:(NSKeyValueGetter *)baseGetter mutatingMethods:(NSKeyValueMutatingCollectionMethodSet *)mutatingMethods proxyClass:(Class)proxyClass; @end CF_PRIVATE @interface NSKeyValueIvarMutableCollectionGetter : NSKeyValueProxyGetter +{ + Ivar _ivar; +} - (id)initWithContainerClassID:(Class)cls key:(NSString *)key containerIsa:(Class)containerIsa ivar:(Ivar)ivar proxyClass:(Class)proxyClass; @end CF_PRIVATE @interface NSKeyValueNotifyingMutableCollectionGetter : NSKeyValueProxyGetter +{ + NSKeyValueProxyGetter *_mutableCollectionGetter; +} - (id)initWithContainerClassID:(Class)cls key:(NSString*)key mutableCollectionGetter:(NSKeyValueProxyGetter*)getter proxyClass:(Class)proxyClass; @end @@ -153,120 +198,213 @@ CF_PRIVATE CF_PRIVATE @interface NSKeyValueArray : NSArray +{ + NSObject *_container; + NSString *_key; + NSKeyValueNonmutatingArrayMethodSet *_methods; +} - (id)_proxyInitWithContainer:(NSObject *)container getter:(NSKeyValueCollectionGetter *)getter; @end CF_PRIVATE @interface NSKeyValueOrderedSet : NSOrderedSet +{ + NSObject *_container; + NSString *_key; + NSKeyValueNonmutatingOrderedSetMethodSet *_methods; +} - (id)_proxyInitWithContainer:(NSObject *)container getter:(NSKeyValueCollectionGetter *)getter; @end CF_PRIVATE @interface NSKeyValueSet : NSSet +{ + NSObject *_container; + NSString *_key; + NSKeyValueNonmutatingSetMethodSet *_methods; +} - (id)_proxyInitWithContainer:(NSObject *)container getter:(NSKeyValueCollectionGetter *)getter; @end CF_PRIVATE @interface NSKeyValueMutableArray : NSMutableArray +{ +@public + NSObject *_container; + NSString *_key; +} - (id)_proxyInitWithContainer:(NSObject *)container getter:(NSKeyValueCollectionGetter *)getter; @end CF_PRIVATE @interface NSKeyValueMutableOrderedSet : NSMutableOrderedSet +{ +@public + NSObject *_container; + NSString *_key; +} - (id)_proxyInitWithContainer:(NSObject *)container getter:(NSKeyValueCollectionGetter *)getter; @end CF_PRIVATE @interface NSKeyValueMutableSet : NSMutableSet +{ +@public + NSObject *_container; + NSString *_key; +} - (id)_proxyInitWithContainer:(NSObject *)container getter:(NSKeyValueCollectionGetter *)getter; @end CF_PRIVATE @interface NSKeyValueSlowMutableArray : NSKeyValueMutableArray +{ + NSKeyValueGetter *_valueGetter; + NSKeyValueSetter *_valueSetter; + BOOL _treatNilValuesLikeEmptyArrays; + char _padding[3]; +} - (id)_proxyInitWithContainer:(NSObject *)container getter:(NSKeyValueSlowMutableCollectionGetter *)getter; @end CF_PRIVATE @interface NSKeyValueSlowMutableOrderedSet : NSKeyValueMutableOrderedSet +{ + NSKeyValueGetter *_valueGetter; + NSKeyValueSetter *_valueSetter; + BOOL _treatNilValuesLikeEmptyOrderedSets; + char _padding[3]; +} - (id)_proxyInitWithContainer:(NSObject *)container getter:(NSKeyValueSlowMutableCollectionGetter *)getter; @end CF_PRIVATE @interface NSKeyValueSlowMutableSet : NSKeyValueMutableSet +{ + NSKeyValueGetter *_valueGetter; + NSKeyValueSetter *_valueSetter; + BOOL _treatNilValuesLikeEmptySets; + char _padding[3]; +} - (id)_proxyInitWithContainer:(NSObject *)container getter:(NSKeyValueSlowMutableCollectionGetter *)getter; @end CF_PRIVATE @interface NSKeyValueFastMutableArray : NSKeyValueMutableArray +{ + NSKeyValueMutatingArrayMethodSet *_mutatingMethods; +} - (id)_proxyInitWithContainer:(NSObject *)container getter:(NSKeyValueProxyGetter *)getter; @end CF_PRIVATE @interface NSKeyValueFastMutableArray1 : NSKeyValueFastMutableArray +{ + NSKeyValueNonmutatingArrayMethodSet *_nonmutatingMethods; +} - (id)_proxyInitWithContainer:(NSObject *)container getter:(NSKeyValueFastMutableCollection1Getter *)getter; @end CF_PRIVATE @interface NSKeyValueFastMutableArray2 : NSKeyValueFastMutableArray +{ + NSKeyValueGetter *_valueGetter; +} - (id)_proxyInitWithContainer:(NSObject *)container getter:(NSKeyValueFastMutableCollection2Getter *)getter; @end CF_PRIVATE @interface NSKeyValueFastMutableOrderedSet : NSKeyValueMutableOrderedSet +{ + NSKeyValueMutatingOrderedSetMethodSet *_mutatingMethods; +} - (id)_proxyInitWithContainer:(NSObject *)container getter:(NSKeyValueProxyGetter *)getter; @end CF_PRIVATE @interface NSKeyValueFastMutableOrderedSet1 : NSKeyValueFastMutableOrderedSet +{ + NSKeyValueNonmutatingOrderedSetMethodSet *_nonmutatingMethods; +} - (id)_proxyInitWithContainer:(NSObject *)container getter:(NSKeyValueFastMutableCollection1Getter *)getter; @end CF_PRIVATE @interface NSKeyValueFastMutableOrderedSet2 : NSKeyValueFastMutableOrderedSet +{ + NSKeyValueGetter *_valueGetter; +} - (id)_proxyInitWithContainer:(NSObject *)container getter:(NSKeyValueFastMutableCollection2Getter *)getter; @end CF_PRIVATE @interface NSKeyValueFastMutableSet : NSKeyValueMutableSet +{ + NSKeyValueMutatingSetMethodSet *_mutatingMethods; +} - (id)_proxyInitWithContainer:(NSObject *)container getter:(NSKeyValueProxyGetter *)getter; @end CF_PRIVATE @interface NSKeyValueFastMutableSet1 : NSKeyValueFastMutableSet +{ + NSKeyValueNonmutatingSetMethodSet *_nonmutatingMethods; +} - (id)_proxyInitWithContainer:(NSObject *)container getter:(NSKeyValueFastMutableCollection1Getter *)getter; @end CF_PRIVATE @interface NSKeyValueFastMutableSet2 : NSKeyValueFastMutableSet +{ + NSKeyValueGetter *_valueGetter; +} - (id)_proxyInitWithContainer:(NSObject *)container getter:(NSKeyValueFastMutableCollection2Getter *)getter; @end CF_PRIVATE @interface NSKeyValueIvarMutableArray : NSKeyValueMutableArray +{ + Ivar _ivar; +} - (id)_proxyInitWithContainer:(NSObject *)container getter:(NSKeyValueIvarMutableCollectionGetter*)getter; @end CF_PRIVATE @interface NSKeyValueIvarMutableOrderedSet : NSKeyValueMutableOrderedSet +{ + Ivar _ivar; +} - (id)_proxyInitWithContainer:(NSObject *)container getter:(NSKeyValueIvarMutableCollectionGetter*)getter; @end CF_PRIVATE @interface NSKeyValueIvarMutableSet : NSKeyValueMutableSet +{ + Ivar _ivar; +} - (id)_proxyInitWithContainer:(NSObject *)container getter:(NSKeyValueIvarMutableCollectionGetter*)getter; @end CF_PRIVATE @interface NSKeyValueNotifyingMutableArray : NSKeyValueMutableArray +{ + NSMutableArray *_mutableArray; +} - (id)_proxyInitWithContainer:(NSObject *)container getter:(NSKeyValueNotifyingMutableCollectionGetter *)getter; @end CF_PRIVATE @interface NSKeyValueNotifyingMutableOrderedSet : NSKeyValueMutableOrderedSet +{ + NSMutableOrderedSet *_mutableOrderedSet; +} - (id)_proxyInitWithContainer:(NSObject *)container getter:(NSKeyValueNotifyingMutableCollectionGetter *)getter; @end CF_PRIVATE @interface NSKeyValueNotifyingMutableSet : NSKeyValueMutableSet +{ + NSMutableSet *_mutableSet; +} - (id)_proxyInitWithContainer:(NSObject *)container getter:(NSKeyValueNotifyingMutableCollectionGetter *)getter; @end diff --git a/src/NSKeyValueCollectionProxies.m b/src/NSKeyValueCollectionProxies.m index 1a783f23f..34a97f23d 100644 --- a/src/NSKeyValueCollectionProxies.m +++ b/src/NSKeyValueCollectionProxies.m @@ -25,33 +25,12 @@ static OSSpinLock _NSKeyValueProxySpinlock = OS_SPINLOCK_INIT; @end @implementation NSKeyValueNonmutatingArrayMethodSet -{ -@public - Method count; - Method objectAtIndex; - Method getObjectsRange; - Method objectsAtIndexes; -} @end @implementation NSKeyValueNonmutatingOrderedSetMethodSet -{ -@public - Method count; - Method objectAtIndex; - Method indexOfObject; - Method getObjectsRange; - Method objectsAtIndexes; -} @end @implementation NSKeyValueNonmutatingSetMethodSet -{ -@public - Method count; - Method enumerator; - Method member; -} @end @implementation NSKeyValueMutatingCollectionMethodSet @@ -115,9 +94,6 @@ static OSSpinLock _NSKeyValueProxySpinlock = OS_SPINLOCK_INIT; @end @implementation NSKeyValueProxyGetter -{ - Class _proxyClass; -} static id _NSGetProxyValueWithGetterNoLock(id obj, NSKeyValueProxyGetter* getter) { @@ -176,9 +152,6 @@ static id _NSGetProxyValueWithGetter(id obj, SEL sel, NSKeyValueProxyGetter* get @end @implementation NSKeyValueCollectionGetter -{ - NSKeyValueNonmutatingCollectionMethodSet *_methods; -} - (NSKeyValueNonmutatingCollectionMethodSet *)methods { @@ -204,10 +177,6 @@ static id _NSGetProxyValueWithGetter(id obj, SEL sel, NSKeyValueProxyGetter* get @end @implementation NSKeyValueSlowMutableCollectionGetter -{ - NSKeyValueGetter *_baseGetter; - NSKeyValueSetter *_baseSetter; -} - (void)dealloc { @@ -266,10 +235,6 @@ static id _NSGetProxyValueWithGetter(id obj, SEL sel, NSKeyValueProxyGetter* get @end @implementation NSKeyValueFastMutableCollection1Getter -{ - NSKeyValueNonmutatingCollectionMethodSet *_nonmutatingMethods; - NSKeyValueMutatingCollectionMethodSet *_mutatingMethods; -} - (void)dealloc { @@ -302,10 +267,6 @@ static id _NSGetProxyValueWithGetter(id obj, SEL sel, NSKeyValueProxyGetter* get @end @implementation NSKeyValueFastMutableCollection2Getter -{ - NSKeyValueGetter *_baseGetter; - NSKeyValueMutatingCollectionMethodSet *_mutatingMethods; -} - (void)dealloc { @@ -338,9 +299,6 @@ static id _NSGetProxyValueWithGetter(id obj, SEL sel, NSKeyValueProxyGetter* get @end @implementation NSKeyValueIvarMutableCollectionGetter -{ - Ivar _ivar; -} - (id)initWithContainerClassID:(Class)cls key:(NSString *)key containerIsa:(Class)containerIsa ivar:(Ivar)ivar proxyClass:(Class)proxyClass { @@ -359,9 +317,6 @@ static id _NSGetProxyValueWithGetter(id obj, SEL sel, NSKeyValueProxyGetter* get @end @implementation NSKeyValueNotifyingMutableCollectionGetter -{ - NSKeyValueProxyGetter *_mutableCollectionGetter; -} - (void)dealloc { @@ -481,11 +436,6 @@ static BOOL _NSKeyValueProxyDeallocate(id proxy) } @implementation NSKeyValueArray -{ - NSObject *_container; - NSString *_key; - NSKeyValueNonmutatingArrayMethodSet *_methods; -} + (NSHashTable *)_proxyShare { @@ -588,11 +538,6 @@ static BOOL _NSKeyValueProxyDeallocate(id proxy) @end @implementation NSKeyValueOrderedSet -{ - NSObject *_container; - NSString *_key; - NSKeyValueNonmutatingOrderedSetMethodSet *_methods; -} + (NSHashTable *)_proxyShare { @@ -701,11 +646,6 @@ static BOOL _NSKeyValueProxyDeallocate(id proxy) @end @implementation NSKeyValueSet -{ - NSObject *_container; - NSString *_key; - NSKeyValueNonmutatingSetMethodSet *_methods; -} + (NSHashTable *)_proxyShare { @@ -779,11 +719,6 @@ static BOOL _NSKeyValueProxyDeallocate(id proxy) @end @implementation NSKeyValueMutableArray -{ -@public - NSObject *_container; - NSString *_key; -} + (NSHashTable *)_proxyShare { @@ -848,11 +783,6 @@ static BOOL _NSKeyValueProxyDeallocate(id proxy) @end @implementation NSKeyValueMutableOrderedSet -{ -@public - NSObject *_container; - NSString *_key; -} + (NSHashTable *)_proxyShare { @@ -908,11 +838,6 @@ static BOOL _NSKeyValueProxyDeallocate(id proxy) @end @implementation NSKeyValueMutableSet -{ -@public - NSObject *_container; - NSString *_key; -} + (NSHashTable *)_proxyShare { @@ -968,12 +893,6 @@ static BOOL _NSKeyValueProxyDeallocate(id proxy) @end @implementation NSKeyValueSlowMutableArray -{ - NSKeyValueGetter *_valueGetter; - NSKeyValueSetter *_valueSetter; - BOOL _treatNilValuesLikeEmptyArrays; - char _padding[3]; -} + (NSKeyValueProxyPool *)_proxyNonGCPoolPointer { @@ -1185,12 +1104,6 @@ static BOOL _NSKeyValueProxyDeallocate(id proxy) @end @implementation NSKeyValueSlowMutableOrderedSet -{ - NSKeyValueGetter *_valueGetter; - NSKeyValueSetter *_valueSetter; - BOOL _treatNilValuesLikeEmptyOrderedSets; - char _padding[3]; -} + (NSKeyValueProxyPool *)_proxyNonGCPoolPointer { @@ -1379,12 +1292,6 @@ static BOOL _NSKeyValueProxyDeallocate(id proxy) @end @implementation NSKeyValueSlowMutableSet -{ - NSKeyValueGetter *_valueGetter; - NSKeyValueSetter *_valueSetter; - BOOL _treatNilValuesLikeEmptySets; - char _padding[3]; -} + (NSKeyValueProxyPool *)_proxyNonGCPoolPointer { @@ -1590,9 +1497,6 @@ static BOOL _NSKeyValueProxyDeallocate(id proxy) @end @implementation NSKeyValueFastMutableArray -{ - NSKeyValueMutatingArrayMethodSet *_mutatingMethods; -} - (id)_proxyInitWithContainer:(NSObject *)container getter:(NSKeyValueProxyGetter *)getter { @@ -1715,9 +1619,6 @@ static BOOL _NSKeyValueProxyDeallocate(id proxy) @end @implementation NSKeyValueFastMutableArray1 -{ - NSKeyValueNonmutatingArrayMethodSet *_nonmutatingMethods; -} + (NSKeyValueProxyPool *)_proxyNonGCPoolPointer { @@ -1790,9 +1691,6 @@ static BOOL _NSKeyValueProxyDeallocate(id proxy) @end @implementation NSKeyValueFastMutableArray2 -{ - NSKeyValueGetter *_valueGetter; -} + (NSKeyValueProxyPool *)_proxyNonGCPoolPointer { @@ -1852,9 +1750,6 @@ static BOOL _NSKeyValueProxyDeallocate(id proxy) @end @implementation NSKeyValueFastMutableOrderedSet -{ - NSKeyValueMutatingOrderedSetMethodSet *_mutatingMethods; -} - (id)_proxyInitWithContainer:(NSObject *)container getter:(NSKeyValueProxyGetter *)getter { @@ -1967,9 +1862,6 @@ static BOOL _NSKeyValueProxyDeallocate(id proxy) @end @implementation NSKeyValueFastMutableOrderedSet1 -{ - NSKeyValueNonmutatingOrderedSetMethodSet *_nonmutatingMethods; -} + (NSKeyValueProxyPool *)_proxyNonGCPoolPointer { @@ -2047,9 +1939,6 @@ static BOOL _NSKeyValueProxyDeallocate(id proxy) @end @implementation NSKeyValueFastMutableOrderedSet2 -{ - NSKeyValueGetter *_valueGetter; -} + (NSKeyValueProxyPool *)_proxyNonGCPoolPointer { @@ -2114,9 +2003,6 @@ static BOOL _NSKeyValueProxyDeallocate(id proxy) @end @implementation NSKeyValueFastMutableSet -{ - NSKeyValueMutatingSetMethodSet *_mutatingMethods; -} - (id)_proxyInitWithContainer:(NSObject *)container getter:(NSKeyValueProxyGetter *)getter { @@ -2240,9 +2126,6 @@ static BOOL _NSKeyValueProxyDeallocate(id proxy) @end @implementation NSKeyValueFastMutableSet1 -{ - NSKeyValueNonmutatingSetMethodSet *_nonmutatingMethods; -} + (NSKeyValueProxyPool *)_proxyNonGCPoolPointer { @@ -2285,9 +2168,6 @@ static BOOL _NSKeyValueProxyDeallocate(id proxy) @end @implementation NSKeyValueFastMutableSet2 -{ - NSKeyValueGetter *_valueGetter; -} + (NSKeyValueProxyPool *)_proxyNonGCPoolPointer { @@ -2342,9 +2222,6 @@ static BOOL _NSKeyValueProxyDeallocate(id proxy) @end @implementation NSKeyValueIvarMutableArray -{ - Ivar _ivar; -} + (NSKeyValueProxyPool *)_proxyNonGCPoolPointer { @@ -2500,9 +2377,6 @@ static BOOL _NSKeyValueProxyDeallocate(id proxy) @end @implementation NSKeyValueIvarMutableOrderedSet -{ - Ivar _ivar; -} + (NSKeyValueProxyPool *)_proxyNonGCPoolPointer { @@ -2647,9 +2521,6 @@ static BOOL _NSKeyValueProxyDeallocate(id proxy) @end @implementation NSKeyValueIvarMutableSet -{ - Ivar _ivar; -} + (NSKeyValueProxyPool *)_proxyNonGCPoolPointer { @@ -2784,9 +2655,6 @@ static BOOL _NSKeyValueProxyDeallocate(id proxy) @end @implementation NSKeyValueNotifyingMutableArray -{ - NSMutableArray *_mutableArray; -} + (NSKeyValueProxyPool *)_proxyNonGCPoolPointer { @@ -2910,9 +2778,6 @@ static BOOL _NSKeyValueProxyDeallocate(id proxy) @end @implementation NSKeyValueNotifyingMutableOrderedSet -{ - NSMutableOrderedSet *_mutableOrderedSet; -} + (NSKeyValueProxyPool *)_proxyNonGCPoolPointer { @@ -3018,9 +2883,6 @@ static BOOL _NSKeyValueProxyDeallocate(id proxy) @end @implementation NSKeyValueNotifyingMutableSet -{ - NSMutableSet *_mutableSet; -} + (NSKeyValueProxyPool *)_proxyNonGCPoolPointer { diff --git a/src/NSKeyValueComputedProperty.h b/src/NSKeyValueComputedProperty.h index 2d6d036b1..991b80fc0 100644 --- a/src/NSKeyValueComputedProperty.h +++ b/src/NSKeyValueComputedProperty.h @@ -4,6 +4,16 @@ CF_PRIVATE @interface NSKeyValueComputedProperty : NSKeyValueProperty +{ + NSKeyValueProperty* _operationArgumentProperty; + NSString* _operationArgumentKeyPath; + NSString* _operationName; +} + +@property (nonatomic, retain) NSKeyValueProperty *operationArgumentProperty; +@property (nonatomic, copy) NSString *operationArgumentKeyPath; +@property (nonatomic, copy) NSString *operationName; + - (NSString *)_keyPathIfAffectedByValueForMemberOfKeys:(NSSet *)keys; - (NSString *)_keyPathIfAffectedByValueForKey:(NSString *)key exactMatch:(BOOL *)exactMatch; - (Class)_isaForAutonotifying; diff --git a/src/NSKeyValueComputedProperty.m b/src/NSKeyValueComputedProperty.m index e57dbf4a3..b7aebc2e0 100644 --- a/src/NSKeyValueComputedProperty.m +++ b/src/NSKeyValueComputedProperty.m @@ -8,13 +8,12 @@ #import "NSKeyValueComputedProperty.h" #import -@interface NSKeyValueComputedProperty () -@property (nonatomic, retain) NSKeyValueProperty *operationArgumentProperty; -@property (nonatomic, copy) NSString *operationArgumentKeyPath; -@property (nonatomic, copy) NSString *operationName; -@end - @implementation NSKeyValueComputedProperty + +@synthesize operationArgumentProperty = _operationArgumentProperty; +@synthesize operationArgumentKeyPath = _operationArgumentKeyPath; +@synthesize operationName = _operationName; + - (instancetype)_initWithContainerClass:(NSKeyValueContainerClass *)containerClass keyPath:(NSString *)keyPath propertiesBeingInitialized:(CFMutableSetRef)propertiesBeingInitialized { self = [super _initWithContainerClass:containerClass keyPath:keyPath propertiesBeingInitialized:propertiesBeingInitialized]; diff --git a/src/NSKeyValueNestedProperty.h b/src/NSKeyValueNestedProperty.h index e8a36195e..6fc5f215d 100644 --- a/src/NSKeyValueNestedProperty.h +++ b/src/NSKeyValueNestedProperty.h @@ -4,6 +4,23 @@ CF_PRIVATE @interface NSKeyValueNestedProperty : NSKeyValueProperty +{ + NSString* _relationshipKey; + NSString* _keyPathFromRelatedObject; + NSKeyValueProperty* _relationshipProperty; + NSString* _keyPathWithoutOperatorComponents; + BOOL _isAllowedToResultInForwarding; + id _dependentValueKeyOrKeys; + BOOL _dependentValueKeyOrKeysIsASet; +} + +@property (copy, nonatomic) NSString *relationshipKey; +@property (copy, nonatomic) NSString *keyPathFromRelatedObject; +@property (retain, nonatomic) NSKeyValueProperty *relationshipProperty; +@property (copy, nonatomic) NSString *keyPathWithoutOperatorComponents; +@property (assign, nonatomic) BOOL isAllowedToResultInForwarding; +@property (retain, nonatomic) id dependentValueKeyOrKeys; +@property (assign, nonatomic) BOOL dependentValueKeyOrKeysIsASet; // TODO: this is dumb. Make it always a set. - (NSString *)_keyPathIfAffectedByValueForMemberOfKeys:(NSSet *)keys; - (NSString *)_keyPathIfAffectedByValueForKey:(NSString *)key exactMatch:(BOOL *)exactMatch; diff --git a/src/NSKeyValueNestedProperty.m b/src/NSKeyValueNestedProperty.m index 27ee3eaa4..c4563b035 100644 --- a/src/NSKeyValueNestedProperty.m +++ b/src/NSKeyValueNestedProperty.m @@ -13,17 +13,14 @@ #import #import -@interface NSKeyValueNestedProperty () -@property (copy, nonatomic) NSString *relationshipKey; -@property (copy, nonatomic) NSString *keyPathFromRelatedObject; -@property (retain, nonatomic) NSKeyValueProperty *relationshipProperty; -@property (copy, nonatomic) NSString *keyPathWithoutOperatorComponents; -@property (assign, nonatomic) BOOL isAllowedToResultInForwarding; -@property (retain, nonatomic) id dependentValueKeyOrKeys; -@property (assign, nonatomic) BOOL dependentValueKeyOrKeysIsASet; // TODO: this is dumb. Make it always a set. -@end - @implementation NSKeyValueNestedProperty +@synthesize relationshipKey = _relationshipKey; +@synthesize keyPathFromRelatedObject = _keyPathFromRelatedObject; +@synthesize relationshipProperty = _relationshipProperty; +@synthesize keyPathWithoutOperatorComponents = _keyPathWithoutOperatorComponents; +@synthesize isAllowedToResultInForwarding = _isAllowedToResultInForwarding; +@synthesize dependentValueKeyOrKeys = _dependentValueKeyOrKeys; +@synthesize dependentValueKeyOrKeysIsASet = _dependentValueKeyOrKeysIsASet; - (BOOL)matchesWithoutOperatorComponentsKeyPath:(NSString *)keyPath { diff --git a/src/NSKeyValueObservance.h b/src/NSKeyValueObservance.h index 69c9fe7c5..6fc85cfc5 100644 --- a/src/NSKeyValueObservance.h +++ b/src/NSKeyValueObservance.h @@ -5,6 +5,16 @@ CF_PRIVATE @interface NSKeyValueObservance : NSObject +{ + NSObject* _observer; + NSString* _keyPath; + NSKeyValueProperty* _property; + NSObject* _originalObservable; + void* _context; + NSKeyValueSetter* _setter; + NSKeyValueObservingOptions _options; +} + @property (assign) NSObject *observer; @property (copy) NSString *keyPath; @property (retain) NSKeyValueProperty *property; //TODO: assign? diff --git a/src/NSKeyValueObservance.m b/src/NSKeyValueObservance.m index be2080499..34ee47d15 100644 --- a/src/NSKeyValueObservance.m +++ b/src/NSKeyValueObservance.m @@ -11,6 +11,14 @@ #import "NSKeyValueProperty.h" @implementation NSKeyValueObservance +@synthesize observer = _observer; +@synthesize keyPath = _keyPath; +@synthesize property = _property; +@synthesize originalObservable = _originalObservable; +@synthesize context = _context; +@synthesize setter = _setter; +@synthesize options = _options; + - (instancetype)initWithObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath ofObject:(NSObject *)object withContext:(void *)context options:(NSKeyValueObservingOptions)options { self = [super init]; diff --git a/src/NSKeyValueObservationInfo.h b/src/NSKeyValueObservationInfo.h index e6a743abb..e528c423c 100644 --- a/src/NSKeyValueObservationInfo.h +++ b/src/NSKeyValueObservationInfo.h @@ -1,9 +1,12 @@ #import -@class NSArray, NSKeyValueObservance; +@class NSArray, NSKeyValueObservance, NSMutableArray; CF_PRIVATE @interface NSKeyValueObservationInfo : NSObject +{ + NSMutableArray *_observances; +} - (NSArray *)observances; - (void)addObservance:(NSKeyValueObservance *)observance; - (void)removeObservance:(NSKeyValueObservance *)observance; diff --git a/src/NSKeyValueObservationInfo.m b/src/NSKeyValueObservationInfo.m index b6fa40071..ce02fbb4e 100644 --- a/src/NSKeyValueObservationInfo.m +++ b/src/NSKeyValueObservationInfo.m @@ -11,9 +11,6 @@ #import "NSKeyValueObservance.h" @implementation NSKeyValueObservationInfo -{ - NSMutableArray *_observances; -} - (instancetype)init { self = [super init]; diff --git a/src/NSKeyValueObserving.m b/src/NSKeyValueObserving.m index 89fe5836c..d540652f3 100644 --- a/src/NSKeyValueObserving.m +++ b/src/NSKeyValueObserving.m @@ -24,7 +24,6 @@ #import "NSKeyValueObservationInfo.h" #import "NSKeyValueChangeDictionary.h" #import -#import "NSInvocationInternal.h" #import #import #import "NSExternals.h" @@ -34,6 +33,7 @@ #import #import #import +#import static void NSKVOForwardInvocation(id self, SEL _cmd, NSInvocation *invocation); static void NSKVONotifyingSetMethodImplementation(NSKVONotifyingInfo *notifyingInfo, SEL selector, IMP newImplementation, NSString *optionalKey); @@ -1008,7 +1008,8 @@ void _NSKVONotifyingEnableForInfoAndKey(NSKVONotifyingInfo *notifyingInfo, NSStr } else { - replacementSetter = (IMP)&_CF_forwarding_prep_0; // aha - this is how other structs work. + // replacementSetter = (IMP)&_CF_forwarding_prep_0; // aha - this is how other structs work. + replacementSetter = (IMP)NULL; } } else @@ -1059,15 +1060,9 @@ void _NSKVONotifyingEnableForInfoAndKey(NSKVONotifyingInfo *notifyingInfo, NSStr } } free(argtype); + SEL selector = method_getName(m); - NSKVONotifyingSetMethodImplementation(notifyingInfo, selector, replacementSetter, key); - - // Ensuring that the setValue:forKey: for the notifying object point to the correct - // method implementation - NSKeyValueSetter *notifyingSetter = [NSObject _createValueSetterWithContainerClassID:notifyingInfo->_notifyingClass key:key]; - [notifyingSetter setMethod:class_getInstanceMethod(notifyingInfo->_notifyingClass, selector)]; - - if (replacementSetter == (IMP)&_CF_forwarding_prep_0) + if (replacementSetter == NULL) { NSKVONotifyingSetMethodImplementation(notifyingInfo, @selector(forwardInvocation:), (IMP)&NSKVOForwardInvocation, nil); Class otherClass= notifyingInfo->_notifyingClass; @@ -1082,6 +1077,14 @@ void _NSKVONotifyingEnableForInfoAndKey(NSKVONotifyingInfo *notifyingInfo, NSStr const char *originalTypeEncoding = method_getTypeEncoding(m); class_addMethod(otherClass, newForwardingSelector, originalIMP, originalTypeEncoding); } + else + NSKVONotifyingSetMethodImplementation(notifyingInfo, selector, replacementSetter, key); + + // Ensuring that the setValue:forKey: for the notifying object point to the correct + // method implementation + NSKeyValueSetter *notifyingSetter = [NSObject _createValueSetterWithContainerClassID:notifyingInfo->_notifyingClass key:key]; + [notifyingSetter setMethod:class_getInstanceMethod(notifyingInfo->_notifyingClass, selector)]; + } } } @@ -1139,7 +1142,11 @@ static void NSKVOForwardInvocation(id self, SEL _cmd, NSInvocation *invocation) { struct objc_super super = { .receiver = self, +#if !__OBJC2__ + .class = class_getSuperclass(object_getClass(self)) +#else .super_class = class_getSuperclass(object_getClass(self)) +#endif }; (void)(void (*)(id, SEL))objc_msgSendSuper(&super, _cmd); } diff --git a/src/NSKeyedArchiver.m b/src/NSKeyedArchiver.m index 931f59262..0fc438109 100644 --- a/src/NSKeyedArchiver.m +++ b/src/NSKeyedArchiver.m @@ -18,8 +18,6 @@ #import #import "NSTemporaryDirectory.h" #import "NSObjectInternal.h" -#import -#import #import "ForFoundationOnly.h" #import #import @@ -58,23 +56,7 @@ NSString *const NSInvalidArchiveOperationException = @"NSInvalidArchiveOperation static dispatch_once_t archiverClassesOnce = 0L; static NSMutableDictionary *archiverClasses = nil; -@implementation NSKeyedArchiver { - CFTypeRef _stream; - unsigned int _flags; - id _delegate; - NSMutableArray *_containers; - NSMutableArray *_objects; - CFMutableDictionaryRef _objRefMap; - CFMutableDictionaryRef _replacementMap; - id _classNameMap; - CFMutableDictionaryRef _conditionals; - id _classes; - NSUInteger _genericKey; - CFKeyedArchiverUIDRef *_cache; - unsigned int _cacheSize; - unsigned int _estimatedCount; - CFMutableSetRef _visited; -} +@implementation NSKeyedArchiver static NSString *escapeKey(NSString *key) { diff --git a/src/NSKeyedUnarchiver.m b/src/NSKeyedUnarchiver.m index 06bb9f2a5..ddd4896e4 100644 --- a/src/NSKeyedUnarchiver.m +++ b/src/NSKeyedUnarchiver.m @@ -104,30 +104,13 @@ NSString *const NSInvalidUnarchiveOperationException = @"NSInvalidUnarchiveOpera @end -typedef struct { +typedef struct offsetDataStruct { CFBinaryPlistTrailer trailer; uint64_t offset; uint64_t valueOffset; } offsetDataStruct; -@implementation NSKeyedUnarchiver { - id _delegate; - unsigned int _flags; - CFMutableDictionaryRef _objRefMap; - id _replacementMap; - CFMutableDictionaryRef _nameClassMap; - CFMutableDictionaryRef _tmpRefObjMap; - CFMutableDictionaryRef _refObjMap; - int _genericKey; - CFDataRef _data; - offsetDataStruct *_offsetData; // trailer info - CFMutableArrayRef _containers; // for xml unarchives - CFArrayRef _objects; // for xml unarchives - const char *_bytes; - unsigned long long _len; - _NSKeyedUnarchiverHelper *_helper; - CFMutableDictionaryRef _reservedDictionary; -} +@implementation NSKeyedUnarchiver static NSString *unescapeKey(NSString *key) { diff --git a/src/NSLocale.m b/src/NSLocale.m index 0848d7337..026191796 100644 --- a/src/NSLocale.m +++ b/src/NSLocale.m @@ -13,6 +13,9 @@ CF_PRIVATE @interface NSAutoLocale : NSLocale +{ + NSLocale *loc; +} - (id)_init; @end @@ -36,9 +39,7 @@ CF_PRIVATE @end -@implementation NSAutoLocale { - NSLocale *loc; -} +@implementation NSAutoLocale + (BOOL)supportsSecureCoding { diff --git a/src/NSLocaleInternal.h b/src/NSLocaleInternal.h index 0661f112f..dd507453b 100644 --- a/src/NSLocaleInternal.h +++ b/src/NSLocaleInternal.h @@ -26,9 +26,7 @@ __attribute__((visibility("hidden"))) @end __attribute__((visibility("hidden"))) -@interface NSAutoLocale : NSLocale { - NSLocale *loc; -} +@interface NSAutoLocale : NSLocale + (BOOL)supportsSecureCoding; - (Class)classForCoder; diff --git a/src/NSLock.m b/src/NSLock.m index d807f2dd5..323ceea2b 100644 --- a/src/NSLock.m +++ b/src/NSLock.m @@ -69,12 +69,7 @@ static inline void waitCheck(id lock, SEL cmd, pthread_t thread) } } -@implementation NSLock { - pthread_t _thread; - pthread_mutex_t _lock; - NSString *_name; - BOOL _isInitialized; -} +@implementation NSLock - (id)init { @@ -202,12 +197,7 @@ static inline void waitCheck(id lock, SEL cmd, pthread_t thread) // All reads or writes to _value, _thread, and _locked (outside of // init) must be guarded by the _cond lock. -@implementation NSConditionLock { - NSCondition *_cond; - NSInteger _value; - pthread_t _thread; - BOOL _locked; -} +@implementation NSConditionLock - (id)init { @@ -407,15 +397,7 @@ static inline void waitCheck(id lock, SEL cmd, pthread_t thread) @end -@implementation NSRecursiveLock { - pthread_mutex_t _lock; - pthread_mutexattr_t _attrs; - pthread_t _thread; - int _locks; - NSString *_name; - BOOL _lockIsInitialized; - BOOL _mutexAttrsInitialized; -} +@implementation NSRecursiveLock - (id)init { @@ -540,15 +522,7 @@ static inline void waitCheck(id lock, SEL cmd, pthread_t thread) @end -@implementation NSCondition { - pthread_mutex_t _lock; - pthread_mutexattr_t _attrs; - pthread_cond_t _cond; - pthread_condattr_t _condAttrs; - pthread_t _thread; - NSString *_name; - BOOL _isInitialized; -} +@implementation NSCondition - (id)init { diff --git a/src/NSMapTable.m b/src/NSMapTable.m index d154e161f..26e3d93ec 100644 --- a/src/NSMapTable.m +++ b/src/NSMapTable.m @@ -1,204 +1,272 @@ -// -// NSMapTable.m -// Foundation -// -// Copyright (c) 2014 Apportable. All rights reserved. -// +/** NSMapTable implementation for GNUStep. + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * Author: Richard Frith-Macdonald + * + * This file is part of the GNUstep Base Library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02111 USA. + * + * NSMapTable class reference + * $Date$ $Revision$ + */ -#import -#import -#import "NSPointerFunctionsInternal.h" +#import "common.h" +#import "Foundation/NSArray.h" +#import "Foundation/NSDictionary.h" +#import "Foundation/NSException.h" +#import "Foundation/NSPointerFunctions.h" +#import "Foundation/NSMapTable.h" +#import "NSCallBacks.h" -CF_PRIVATE -@interface NSConcreteMapTable : NSMapTable +@interface NSConcreteMapTable : NSMapTable @end -@implementation NSMapTable +@implementation NSMapTable -+ (id)allocWithZone:(NSZone *)zone +static Class abstractClass = 0; +static Class concreteClass = 0; + ++ (id) allocWithZone: (NSZone*)aZone { - if (self == [NSMapTable class]) + if (self == abstractClass) { - return [NSConcreteMapTable allocWithZone:zone]; + return NSAllocateObject(concreteClass, 0, aZone); } - else + return NSAllocateObject(self, 0, aZone); +} + ++ (void) initialize +{ + if (abstractClass == 0) { - return [super allocWithZone:zone]; + abstractClass = [NSMapTable class]; + concreteClass = [NSConcreteMapTable class]; } } -+ (id)mapTableWithKeyOptions:(NSPointerFunctionsOptions)keyOptions valueOptions:(NSPointerFunctionsOptions)valueOptions ++ (id) mapTableWithKeyOptions: (NSPointerFunctionsOptions)keyOptions + valueOptions: (NSPointerFunctionsOptions)valueOptions { - return [[[self alloc] initWithKeyOptions:keyOptions valueOptions:valueOptions capacity:0] autorelease]; + NSMapTable *t; + + t = [self allocWithZone: NSDefaultMallocZone()]; + t = [t initWithKeyOptions: keyOptions + valueOptions: valueOptions + capacity: 0]; + return AUTORELEASE(t); } -+ (id)strongToStrongObjectsMapTable ++ (id) mapTableWithStrongToStrongObjects { - - return [[[self alloc] initWithKeyOptions:NSPointerFunctionsStrongMemory | NSPointerFunctionsObjectPersonality - valueOptions:NSPointerFunctionsStrongMemory | NSPointerFunctionsObjectPersonality - capacity:0] autorelease]; + return [self mapTableWithKeyOptions: NSPointerFunctionsObjectPersonality + valueOptions: NSPointerFunctionsObjectPersonality]; } -+ (id)weakToStrongObjectsMapTable ++ (id) mapTableWithStrongToWeakObjects { - - return [[[self alloc] initWithKeyOptions:NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality - valueOptions:NSPointerFunctionsStrongMemory | NSPointerFunctionsObjectPersonality - capacity:0] autorelease]; + return [self mapTableWithKeyOptions: NSPointerFunctionsObjectPersonality + valueOptions: NSPointerFunctionsObjectPersonality + | NSPointerFunctionsZeroingWeakMemory]; } -+ (id)strongToWeakObjectsMapTable ++ (id) mapTableWithWeakToStrongObjects { - return [[[self alloc] initWithKeyOptions:NSPointerFunctionsStrongMemory | NSPointerFunctionsObjectPersonality - valueOptions:NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality - capacity:0] autorelease]; + return [self mapTableWithKeyOptions: NSPointerFunctionsObjectPersonality + | NSPointerFunctionsZeroingWeakMemory + valueOptions: NSPointerFunctionsObjectPersonality]; } -+ (id)weakToWeakObjectsMapTable ++ (id) mapTableWithWeakToWeakObjects { - return [[[self alloc] initWithKeyOptions:NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality - valueOptions:NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality - capacity:0] autorelease]; + return [self mapTableWithKeyOptions: NSPointerFunctionsObjectPersonality + | NSPointerFunctionsZeroingWeakMemory + valueOptions: NSPointerFunctionsObjectPersonality + | NSPointerFunctionsZeroingWeakMemory]; } -- (id)initWithKeyOptions:(NSPointerFunctionsOptions)keyOptions valueOptions:(NSPointerFunctionsOptions)valueOptions capacity:(NSUInteger)initialCapacity ++ (id) strongToStrongObjectsMapTable { - NSRequestConcreteImplementation(); - [self release]; - return nil; + return [self mapTableWithKeyOptions: NSMapTableObjectPointerPersonality + valueOptions: NSMapTableObjectPointerPersonality]; } -- (id)initWithKeyPointerFunctions:(NSPointerFunctions *)keyFunctions valuePointerFunctions:(NSPointerFunctions *)valueFunctions capacity:(NSUInteger)initialCapacity ++ (id) strongToWeakObjectsMapTable { - NSRequestConcreteImplementation(); - [self release]; - return nil; + return [self mapTableWithKeyOptions: NSMapTableObjectPointerPersonality + valueOptions: NSMapTableObjectPointerPersonality | + NSMapTableWeakMemory]; } -- (NSPointerFunctions *)keyPointerFunctions ++ (id) weakToStrongObjectsMapTable { - NSRequestConcreteImplementation(); - return nil; + return [self mapTableWithKeyOptions: NSMapTableObjectPointerPersonality | + NSMapTableWeakMemory + valueOptions: NSMapTableObjectPointerPersonality]; } -- (NSPointerFunctions *)valuePointerFunctions ++ (id) weakToWeakObjectsMapTable { - NSRequestConcreteImplementation(); - return nil; + return [self mapTableWithKeyOptions: NSMapTableObjectPointerPersonality | + NSMapTableWeakMemory + valueOptions: NSMapTableObjectPointerPersonality | + NSMapTableWeakMemory]; } -- (id)objectForKey:(id)aKey +- (id) initWithKeyOptions: (NSPointerFunctionsOptions)keyOptions + valueOptions: (NSPointerFunctionsOptions)valueOptions + capacity: (NSUInteger)initialCapacity { - NSRequestConcreteImplementation(); - return nil; + NSPointerFunctions *k; + NSPointerFunctions *v; + id o; + + k = [[NSPointerFunctions alloc] initWithOptions: keyOptions]; + v = [[NSPointerFunctions alloc] initWithOptions: valueOptions]; + o = [self initWithKeyPointerFunctions: k + valuePointerFunctions: v + capacity: initialCapacity]; + [k release]; + [v release]; + return o; } -- (void)removeObjectForKey:(id)aKey +- (id) initWithKeyPointerFunctions: (NSPointerFunctions*)keyFunctions + valuePointerFunctions: (NSPointerFunctions*)valueFunctions + capacity: (NSUInteger)initialCapacity { - NSRequestConcreteImplementation(); + [self subclassResponsibility: _cmd]; + return nil; } -- (void)setObject:(id)anObject forKey:(id)aKey +- (id) copyWithZone: (NSZone*)aZone { - NSRequestConcreteImplementation(); + [self subclassResponsibility: _cmd]; + return nil; } -- (NSUInteger)count +- (NSUInteger) count { - NSRequestConcreteImplementation(); - return 0; + [self subclassResponsibility: _cmd]; + return (NSUInteger)0; } -- (NSEnumerator *)keyEnumerator +- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState*)state + objects: (id*)stackbuf + count: (NSUInteger)len { - NSRequestConcreteImplementation(); - return nil; + [self subclassResponsibility: _cmd]; + return (NSUInteger)0; } -- (NSEnumerator *)objectEnumerator +- (NSDictionary*) dictionaryRepresentation { - NSRequestConcreteImplementation(); - return nil; -} + NSEnumerator *enumerator; + NSMutableDictionary *dictionary; + id key; -- (void)removeAllObjects -{ - NSRequestConcreteImplementation(); -} - -- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id __unsafe_unretained [])buffer count:(NSUInteger)len -{ - NSRequestConcreteImplementation(); - return 0; -} - -- (NSDictionary *)dictionaryRepresentation -{ - NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; - for (id key in self) + dictionary = [NSMutableDictionary dictionaryWithCapacity: [self count]]; + enumerator = [self keyEnumerator]; + while ((key = [enumerator nextObject]) != nil) { - [dictionary setObject:[self objectForKey:key] forKey:key]; + [dictionary setObject: [self objectForKey: key] forKey: key]; } - return [dictionary autorelease]; + return [[dictionary copy] autorelease]; } -/*! -@bug This is backwards on iOS... -*/ -- (id)copyWithZone:(NSZone *)zone +- (void) encodeWithCoder: (NSCoder*)aCoder { - return [self copy]; + [self subclassResponsibility: _cmd]; } +- (NSUInteger) hash +{ + return [self count]; +} + +- (id) initWithCoder: (NSCoder*)aCoder +{ + [self subclassResponsibility: _cmd]; + return nil; +} + +- (BOOL) isEqual: (id)other +{ + if ([other isKindOfClass: abstractClass] == NO) return NO; + return NSCompareMapTables(self, other); +} + +- (NSEnumerator*) keyEnumerator +{ + return [self subclassResponsibility: _cmd]; +} + +- (NSPointerFunctions*) keyPointerFunctions +{ + return [self subclassResponsibility: _cmd]; +} + +- (NSEnumerator*) objectEnumerator +{ + return [self subclassResponsibility: _cmd]; +} + +- (id) objectForKey: (id)aKey +{ + return [self subclassResponsibility: _cmd]; +} + +- (void) removeAllObjects +{ + NSUInteger count = [self count]; + + if (count > 0) + { + NSEnumerator *enumerator; + NSMutableArray *array; + id key; + + array = [[NSMutableArray alloc] initWithCapacity: count]; + enumerator = [self objectEnumerator]; + while ((key = [enumerator nextObject]) != nil) + { + [array addObject: key]; + } + enumerator = [array objectEnumerator]; + while ((key = [enumerator nextObject]) != nil) + { + [self removeObjectForKey: key]; + } + [array release]; + } +} + +- (void) removeObjectForKey: (id)aKey +{ + [self subclassResponsibility: _cmd]; +} + +- (void) setObject: (id)anObject forKey: (id)aKey +{ + [self subclassResponsibility: _cmd]; +} + +- (NSPointerFunctions*) valuePointerFunctions +{ + return [self subclassResponsibility: _cmd]; +} @end -@implementation NSConcreteMapTable -{ - struct NSSlice keys; - struct NSSlice values; - NSUInteger count; - NSUInteger capacity; - NSPointerFunctionsOptions keyOptions; - NSPointerFunctionsOptions valueOptions; - NSUInteger mutations; - int32_t growLock; - BOOL shouldRehash; -} - -- (id)initWithKeyOptions:(NSPointerFunctionsOptions)keyOpts valueOptions:(NSPointerFunctionsOptions)valOpts capacity:(NSUInteger)initialCapacity -{ - self = [super init]; - if (self) - { - if (initialCapacity == 0) - { - capacity = 31; - } - else - { - capacity = initialCapacity; - } - - count = 0; - - keyOptions = keyOpts; - valueOptions = valOpts; - - mutations = 0; - - [NSConcretePointerFunctions initializeSlice:&keys withOptions:keyOpts]; - [NSConcretePointerFunctions initializeSlice:&values withOptions:valOpts]; - - keys.items = keys.allocateFunction(keys.sizeFunction(NULL) * capacity); - if (keys.items == NULL) - { - // [NSException raise:] - [self release]; - return nil; - } - values.items = values.allocateFunction(values.sizeFunction(NULL) * capacity); - } - return self; -} -@end diff --git a/src/NSMatchingPredicateOperator.h b/src/NSMatchingPredicateOperator.h index fbdff58b0..27891348c 100644 --- a/src/NSMatchingPredicateOperator.h +++ b/src/NSMatchingPredicateOperator.h @@ -9,6 +9,10 @@ struct regexContext { CF_PRIVATE @interface NSMatchingPredicateOperator : NSStringPredicateOperator +{ + OSSpinLock _contextLock; + struct regexContext *_regexContext; +} - (BOOL)_shouldEscapeForLike; - (void)_clearContext; diff --git a/src/NSMatchingPredicateOperator.m b/src/NSMatchingPredicateOperator.m index 986ab5dea..0cf3c95b9 100644 --- a/src/NSMatchingPredicateOperator.m +++ b/src/NSMatchingPredicateOperator.m @@ -13,10 +13,6 @@ #import @implementation NSMatchingPredicateOperator -{ - OSSpinLock _contextLock; - struct regexContext *_regexContext; -} - (void)dealloc { diff --git a/src/NSMutableStringProxyForMutableAttributedString.m b/src/NSMutableStringProxyForMutableAttributedString.m index 5319f963b..89f52024a 100644 --- a/src/NSMutableStringProxyForMutableAttributedString.m +++ b/src/NSMutableStringProxyForMutableAttributedString.m @@ -8,9 +8,6 @@ #import "NSMutableStringProxyForMutableAttributedStringInternal.h" @implementation NSMutableStringProxyForMutableAttributedString -{ - NSMutableAttributedString *_owner; -} - (id)initWithMutableAttributedString:(NSMutableAttributedString *)owner { diff --git a/src/NSMutableStringProxyForMutableAttributedStringInternal.h b/src/NSMutableStringProxyForMutableAttributedStringInternal.h index 8de165264..3dcdd6f9c 100644 --- a/src/NSMutableStringProxyForMutableAttributedStringInternal.h +++ b/src/NSMutableStringProxyForMutableAttributedStringInternal.h @@ -3,6 +3,9 @@ __attribute__((visibility("hidden"))) @interface NSMutableStringProxyForMutableAttributedString : NSMutableString +{ + NSMutableAttributedString *_owner; +} - (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)str; - (void)getCharacters:(unichar *)buffer range:(NSRange)aRange; diff --git a/src/NSNetServices.m b/src/NSNetServices.m index fceb85576..4e69574eb 100644 --- a/src/NSNetServices.m +++ b/src/NSNetServices.m @@ -72,11 +72,7 @@ CF_PRIVATE @end -@implementation NSNetService { - CFNetServiceRef _netService; - id _delegate; - NSNetServicesInternal *_reserved; -} +@implementation NSNetService + (NSDictionary *)dictionaryFromTXTRecordData:(NSData *)txtData { @@ -427,12 +423,7 @@ static void _netServiceDispatchCallbackForResolving(CFNetServiceRef theService, @end -@implementation NSNetServiceBrowser { - CFNetServiceBrowserRef _netServiceBrowser; - id _delegate; - void *_tbd; - BOOL _includesPeerToPeer; -} +@implementation NSNetServiceBrowser static void _netServiceBrowserDispatchCallBack(CFNetServiceBrowserRef browser, CFOptionFlags flags, CFTypeRef domainOrService, CFStreamError *error, void *info) { [(NSNetServiceBrowser *)info _dispatchCallBack:domainOrService flags:flags error:error]; diff --git a/src/NSNotification.m b/src/NSNotification.m index ef7517ff6..cc9e0fe81 100644 --- a/src/NSNotification.m +++ b/src/NSNotification.m @@ -124,12 +124,7 @@ static NSString * const NSUserInfoKey = @"NS.userinfo"; @end -@implementation NSConcreteNotification { - NSString *name; - id object; - NSDictionary *userInfo; - BOOL dyingObject; -} +@implementation NSConcreteNotification static OSSpinLock notificationPoolLock = OS_SPINLOCK_INIT; static NSMutableSet *notificationPool = nil; diff --git a/src/NSNotificationCenter.m b/src/NSNotificationCenter.m index 60f86d87a..0034834e1 100644 --- a/src/NSNotificationCenter.m +++ b/src/NSNotificationCenter.m @@ -14,6 +14,14 @@ #import @interface _NSNotificationObserver : NSObject +{ + id _observer; + SEL _selector; + NSString* _name; + id _object; + NSOperationQueue* _queue; + void (^_block)(NSNotification *note); +} @property (nonatomic, readonly) id observer; @property (nonatomic, readonly) SEL selector; @@ -27,6 +35,13 @@ @implementation _NSNotificationObserver +@synthesize observer = _observer; +@synthesize selector = _selector; +@synthesize name = _name; +@synthesize object = _object; +@synthesize queue = _queue; +@synthesize block = _block; + - (id)initWithObserver:(id)observer selector:(SEL)selector name:(NSString *)name object:(id)object queue:(NSOperationQueue *)queue block:(void (^)(NSNotification *note))block { self = [super init]; @@ -74,10 +89,7 @@ @end -@implementation NSNotificationCenter { - NSMutableArray *_observers; - pthread_mutex_t _observersLock; -} +@implementation NSNotificationCenter + (id)defaultCenter { diff --git a/src/NSNotificationInternal.h b/src/NSNotificationInternal.h index 4c4f6aa6e..d0002842c 100644 --- a/src/NSNotificationInternal.h +++ b/src/NSNotificationInternal.h @@ -2,6 +2,12 @@ CF_PRIVATE @interface NSConcreteNotification : NSNotification +{ + NSString *name; + id object; + NSDictionary *userInfo; + BOOL dyingObject; +} + (id)newTempNotificationWithName:(NSString *)name object:(id)anObject userInfo:(NSDictionary *)aUserInfo; - (id)initWithName:(NSString *)name object:(id)anObject userInfo:(NSDictionary *)aUserInfo; - (void)recycle; diff --git a/src/NSNotificationQueue.m b/src/NSNotificationQueue.m index ec0a3738c..9bb1c771c 100644 --- a/src/NSNotificationQueue.m +++ b/src/NSNotificationQueue.m @@ -15,13 +15,7 @@ static NSString *NSDefaultNotificationQueue = @"NSDefaultNotificationQueue"; -@implementation NSNotificationQueue { - NSNotificationCenter *_notificationCenter; - NSMutableArray *_asapQueue; - NSMutableArray *_asapObs; - NSMutableArray *_idleQueue; - NSMutableArray *_idleObs; -} +@implementation NSNotificationQueue + (id)defaultQueue { diff --git a/src/NSNumberFormatter.m b/src/NSNumberFormatter.m index d1208b77b..54b223285 100644 --- a/src/NSNumberFormatter.m +++ b/src/NSNumberFormatter.m @@ -12,10 +12,7 @@ #import #import -@implementation NSNumberFormatter { - NSMutableDictionary *_attributes; - CFNumberFormatterRef _formatter; -} +@implementation NSNumberFormatter + (NSString *)localizedStringFromNumber:(NSNumber *)num numberStyle:(NSNumberFormatterStyle)nstyle { diff --git a/src/NSObjCRuntime.m b/src/NSObjCRuntime.m index 3dc093c41..95b4c150f 100644 --- a/src/NSObjCRuntime.m +++ b/src/NSObjCRuntime.m @@ -8,6 +8,7 @@ #import #import "ForFoundationOnly.h" #import +#import extern Class NSClassFromObject(id object); Class NSClassFromObject(id object) @@ -78,7 +79,6 @@ Protocol *NSProtocolFromString(NSString *namestr) } } -extern CFTypeRef _CFAutoreleasePoolAddObject(CFTypeRef obj); #pragma clang diagnostic push @@ -150,7 +150,7 @@ NSUInteger NSExtraRefCount(id object) extern id NSAutoreleaseObject(id obj); id NSAutoreleaseObject(id obj) { - return (id)_CFAutoreleasePoolAddObject((CFTypeRef)obj); + return _objc_rootAutorelease(obj); } __attribute__((visibility("default"))) extern NSString *_NSNewStringFromCString(const char *cString); diff --git a/src/NSObjectInternal.h b/src/NSObjectInternal.h index caa22b9aa..55eef6750 100644 --- a/src/NSObjectInternal.h +++ b/src/NSObjectInternal.h @@ -48,6 +48,10 @@ extern NSString *_NSFullMethodName(id object, SEL selector); @end +@interface NSObject (_AbstractClasses) +- (void) subclassResponsibility: (SEL)aSelector; +@end + static inline BOOL NSIsPlistType(NSObject *object) { if ([object isNSString__] || @@ -113,6 +117,9 @@ _Pragma("clang diagnostic pop") __attribute__((visibility("hidden"))) @interface _NSWeakRef: NSObject +{ + id _weakRef; +} @property (nonatomic, retain) id object; diff --git a/src/NSObjectInternal.m b/src/NSObjectInternal.m index dfd0fe69a..45b17657d 100644 --- a/src/NSObjectInternal.m +++ b/src/NSObjectInternal.m @@ -1,9 +1,7 @@ #import "NSObjectInternal.h" #import -@implementation _NSWeakRef { - id _weakRef; -} +@implementation _NSWeakRef - (id)init { @@ -37,3 +35,11 @@ } @end + +@implementation NSObject (_AbstractClasses) +- (void) subclassResponsibility: (SEL)aSelector +{ + _NSRequestConcreteImplementation([self class], aSelector); +} +@end + diff --git a/src/NSOperation.m b/src/NSOperation.m index e32c3c04a..35ac7b93d 100644 --- a/src/NSOperation.m +++ b/src/NSOperation.m @@ -31,10 +31,7 @@ enum __NSOperationState { typedef NSUInteger _NSOperationState; -@class _NSOperationInternal; -@interface NSOperation() { - _NSOperationInternal *_internal; -} +@interface NSOperation() @property (nonatomic, readonly) _NSOperationInternal* _internal; @@ -77,22 +74,7 @@ typedef NSUInteger _NSOperationState; static volatile int32_t _NSOperationQueueID = 0; -@interface NSOperationQueue() { - BOOL _suspended; - NSString *_name; - NSInteger _maxConcurrentOperationCount; - pthread_mutex_t _queuelock; - pthread_mutexattr_t _mta; - - NSMutableArray *_pendingOperations; - NSMutableArray *_operations; - NSMutableArray *_operationsToStart; - - _NSOperationQueueInternal *_internal; - - BOOL _isMainQueue; -} - +@interface NSOperationQueue() - (void)_removeFinishedOperation:(_NSOperationInternal *)opi; - (void)_queueSchedulerRun; @@ -1112,9 +1094,7 @@ static NSComparisonResult compareOperationEffectivePriorities(id obj1, id obj2, } @end -@implementation NSInvocationOperation { - NSInvocation *_inv; -} +@implementation NSInvocationOperation - (id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg { @@ -1175,10 +1155,7 @@ static NSComparisonResult compareOperationEffectivePriorities(id obj1, id obj2, @end -@implementation NSBlockOperation { - dispatch_block_t _block; - NSMutableArray *_blocks; -} +@implementation NSBlockOperation - (id)initWithBlock:(void (^)(void))block { diff --git a/src/NSOrthography.m b/src/NSOrthography.m index 773b8dc10..060420906 100644 --- a/src/NSOrthography.m +++ b/src/NSOrthography.m @@ -6,11 +6,29 @@ // #import +#import +#import "NSObjectInternal.h" typedef NS_OPTIONS(NSUInteger, NSOrthographyFlags) { - + __some_enum_elem_to_keep_compiler_happy }; +@interface NSComplexOrthography : NSOrthography +{ + NSString *_dominantScript; + NSDictionary *_languageMap; + NSOrthographyFlags _orthographyFlags; +} + ++ (void)initialize; +- (id)initWithDominantScript:(NSString *)script languageMap:(NSDictionary *)map; +- (NSOrthographyFlags)orthographyFlags; +- (NSDictionary *)languageMap; +- (NSString *)dominantScript; +- (void)dealloc; + +@end + @implementation NSOrthography + (void)initialize @@ -32,7 +50,7 @@ typedef NS_OPTIONS(NSUInteger, NSOrthographyFlags) { + (id)orthographyWithDominantScript:(NSString *)script languageMap:(NSDictionary *)map { - return [[[self alloc] initWithDominantScript:script languageMap:map] autorelase]; + return [[[self alloc] initWithDominantScript:script languageMap:map] autorelease]; } - (id)initWithDominantScript:(NSString *)script languageMap:(NSDictionary *)map @@ -51,9 +69,9 @@ typedef NS_OPTIONS(NSUInteger, NSOrthographyFlags) { NSArray *scriptLangs = [self languagesForScript:script]; for (NSString *language in scriptLangs) { - if (![langs containsObject:langauge]) + if (![langs containsObject:language]) { - [langs addObject:langauge]; + [langs addObject:language]; } } } @@ -166,21 +184,6 @@ typedef NS_OPTIONS(NSUInteger, NSOrthographyFlags) { @end -@interface NSComplexOrthography : NSOrthography -{ - NSString *_dominantScript; - NSDictionary *_languageMap; - NSOrthographyFlags _orthographyFlags; -} - -+ (void)initialize; -- (id)initWithDominantScript:(NSString *)script languageMap:(NSDictionary *)map; -- (NSOrthographyFlags)orthographyFlags; -- (NSDictionary *)languageMap; -- (NSString *)dominantScript; -- (void)dealloc; - -@end @implementation NSSimpleOrthography @end diff --git a/src/NSPlatform.m b/src/NSPlatform.m index 35ae92092..7dbaed47f 100644 --- a/src/NSPlatform.m +++ b/src/NSPlatform.m @@ -12,7 +12,7 @@ #import #import #import -#import "wrap.h" +//#import "wrap.h" extern void __CFInitialize(); extern char ***_NSGetArgv(void); @@ -27,11 +27,12 @@ static void NSPlatformInitialize() { __CFInitialize(); @autoreleasepool { +#if 0 NSString* appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(id)kCFBundleExecutableKey]; __printf_tag = strdup([appName UTF8String]); char ***argv = _NSGetArgv(); snprintf((*argv)[0], PATH_MAX, "%s/%s", __virtual_prefix(virtual_bundle), __printf_tag); - +#endif objc_setEnumerationMutationHandler(_enumerationMutationHandler); } } diff --git a/src/NSPointerArray.m b/src/NSPointerArray.m index 6881327e3..41755fb85 100644 --- a/src/NSPointerArray.m +++ b/src/NSPointerArray.m @@ -152,14 +152,7 @@ CF_PRIVATE @end -@implementation NSConcretePointerArray { - struct NSSlice slice; - NSUInteger count; - NSUInteger capacity; - NSUInteger options; - NSUInteger mutations; - BOOL needsCompaction; -} +@implementation NSConcretePointerArray static inline BOOL NSPointerArrayRangeCheck(NSUInteger index, NSUInteger count, NSString * const exceptionName) { diff --git a/src/NSPointerFunctionsInternal.h b/src/NSPointerFunctionsInternal.h index 6cad01abb..1ff8668dc 100644 --- a/src/NSPointerFunctionsInternal.h +++ b/src/NSPointerFunctionsInternal.h @@ -1,4 +1,5 @@ #import +#import #import "NSObjectInternal.h" #define NSPointerFunctionsMemoryTypeMask 0xff @@ -8,7 +9,6 @@ #define NSPointerFunctionsPersonality(options) (options & NSPointerFunctionsPersonalityMask) #define NSPointerFunctionsOptionsInvalid (-1) -#define NSPointerFunctionsZeroingWeakMemory (1UL << 0) CF_PRIVATE @interface NSWeakCallback : NSObject { @@ -19,33 +19,6 @@ CF_PRIVATE @end -struct NSSlice { - void **items; - BOOL wantsStrong; - BOOL wantsWeak; - BOOL wantsARC; - BOOL shouldCopyIn; - BOOL usesStrong; - BOOL usesWeak; - BOOL usesARC; - BOOL usesSentinel; - BOOL pointerPersonality; - BOOL integerPersonality; - BOOL simpleReadClear; - NSWeakCallback *callback; - NSUInteger (*sizeFunction)(const void *item); - NSUInteger (*hashFunction)(const void *item, NSUInteger (*size)(const void *item)); - BOOL (*isEqualFunction)(const void *item1, const void*item2, NSUInteger (*size)(const void *item)); - NSString *(*describeFunction)(const void *item); - void *(*acquireFunction)(const void *src, NSUInteger (*size)(const void *item), BOOL shouldCopy); - void (*relinquishFunction)(const void *item, NSUInteger (*size)(const void *item)); - void *(*allocateFunction)(size_t count); - void (*freeFunction)(void **buffer, NSUInteger size); - void *(*readAt)(void **ptr, BOOL *wasSentinel); - void (*clearAt)(void **ptr); - void (*storeAt)(void **buffer, void *item, NSUInteger index); -}; - CF_PRIVATE extern void * const _NSPointerFunctionsSentinel; diff --git a/src/NSPort.m b/src/NSPort.m index f911fb1c3..2bfe66899 100644 --- a/src/NSPort.m +++ b/src/NSPort.m @@ -114,12 +114,7 @@ NSString *const NSPortDidBecomeInvalidNotification = @"NSPortDidBecomeInvalidNot @end -@implementation NSMachPort { - id _delegate; - NSUInteger _flags; - uint32_t _machPort; - NSUInteger _reserved; -} +@implementation NSMachPort + (NSPort *)portWithMachPort:(uint32_t)machPort { diff --git a/src/NSPredicate.m b/src/NSPredicate.m index 9d8701e92..3733a47e9 100644 --- a/src/NSPredicate.m +++ b/src/NSPredicate.m @@ -18,10 +18,6 @@ #import @implementation NSPredicate -{ - NSPredicateEvaluationFlags _predicateFlags; - NSUInteger reserved; -} + (NSPredicate *)predicateWithFormat:(NSString *)predicateFormat argumentArray:(NSArray *)arguments { diff --git a/src/NSPredicateInternal.h b/src/NSPredicateInternal.h index 4e9bf29b5..87e8d6659 100644 --- a/src/NSPredicateInternal.h +++ b/src/NSPredicateInternal.h @@ -8,10 +8,6 @@ #import #import -typedef NS_OPTIONS(NSUInteger, NSPredicateEvaluationFlags) { - NSPredicateEvaluationBlocked = 1 << 0, -}; - typedef NS_OPTIONS(NSUInteger, NSPredicateVisitorFlags) { NSPredicateVisitorVisitExpressions = 1 << 0, NSPredicateVisitorVisitOperators = 1 << 1, @@ -37,6 +33,9 @@ typedef NS_OPTIONS(NSUInteger, NSPredicateVisitorFlags) { @end @interface NSBlockPredicate : NSPredicate +{ + BOOL (^_block)(id evaluatedObject, NSDictionary *bindings); +} - (id)initWithBlock:(BOOL (^)(id evaluatedObject, NSDictionary *bindings))block; @end diff --git a/src/NSPredicateOperator.h b/src/NSPredicateOperator.h index 8ad21408b..c4da27ae5 100644 --- a/src/NSPredicateOperator.h +++ b/src/NSPredicateOperator.h @@ -4,6 +4,10 @@ #import "NSPredicateInternal.h" @interface NSPredicateOperator : NSObject +{ + NSPredicateOperatorType _operatorType; + NSComparisonPredicateModifier _modifier; +} + (id)operatorWithCustomSelector:(SEL)customSelector modifier:(NSComparisonPredicateModifier)modifier; + (id)_newOperatorWithType:(NSPredicateOperatorType)type modifier:(NSComparisonPredicateModifier)modifier options:(NSComparisonPredicateOptions)options; diff --git a/src/NSPredicateOperator.m b/src/NSPredicateOperator.m index e039dd79e..5f1aed40a 100644 --- a/src/NSPredicateOperator.m +++ b/src/NSPredicateOperator.m @@ -22,10 +22,6 @@ #import @implementation NSPredicateOperator -{ - NSPredicateOperatorType _operatorType; - NSComparisonPredicateModifier _modifier; -} static NSString * const NSOperatorTypeKey = @"NSOperatorType"; static NSString * const NSModifierKey = @"NSModifier"; diff --git a/src/NSPredicateParser.tab.c b/src/NSPredicateParser.tab.c index e83b3cbd6..89e77f3af 100644 --- a/src/NSPredicateParser.tab.c +++ b/src/NSPredicateParser.tab.c @@ -2340,7 +2340,7 @@ NSPredicate *_parsePredicateArray(NSString *format, NSArray *args) NSPredicate *_parsePredicateVarArgs(NSString *format, va_list originalArgs) { - __block va_list args = originalArgs; + __block va_list* args = &originalArgs; __block BOOL done = NO; return parsePredicate(format, ^NSExpression *(NSString *formatType) { @@ -2352,15 +2352,15 @@ NSPredicate *_parsePredicateVarArgs(NSString *format, va_list originalArgs) if ([formatType isEqualToString:@"@"] || [formatType isEqualToString:@"K"]) { - object = va_arg(args, id); + object = va_arg(*args, id); } else if ([formatType isEqualToString:@"d"]) { - object = [NSNumber numberWithInt:va_arg(args, int)]; + object = [NSNumber numberWithInt:va_arg(*args, int)]; } else if ([formatType isEqualToString:@"f"]) { - object = [NSNumber numberWithDouble:va_arg(args, double)]; + object = [NSNumber numberWithDouble:va_arg(*args, double)]; } if (object == nil) { diff --git a/src/NSProcessInfo.m b/src/NSProcessInfo.m index 1a485140b..90fe688bb 100644 --- a/src/NSProcessInfo.m +++ b/src/NSProcessInfo.m @@ -29,13 +29,7 @@ extern char ***_NSGetEnviron(); guaranteed to be stable across all threads; ala setenv etc. */ -@implementation NSProcessInfo { - NSDictionary *environment; // not used it seems - NSArray *arguments; // is really mutable - NSString *hostName; // singly created - NSString *name; // singly created, but replaceable - NSInteger automaticTerminationOptOutCounter; -} +@implementation NSProcessInfo + (NSProcessInfo *)processInfo { diff --git a/src/NSRegularExpressionCheckingResult.h b/src/NSRegularExpressionCheckingResult.h index e35289982..2f6f2a640 100644 --- a/src/NSRegularExpressionCheckingResult.h +++ b/src/NSRegularExpressionCheckingResult.h @@ -2,6 +2,11 @@ @class NSArray, NSRegularExpression; +typedef NS_ENUM(NSUInteger, NSRegularExpressionCheckingResultLimits) { + NSRegularExpressionCheckingResultSimpleLimit = 3, + NSRegularExpressionCheckingResultExtendedLimit = 7, +}; + NS_REQUIRES_PROPERTY_DEFINITIONS @interface NSRegularExpressionCheckingResult : NSTextCheckingResult @@ -19,6 +24,11 @@ NS_REQUIRES_PROPERTY_DEFINITIONS @end @interface NSSimpleRegularExpressionCheckingResult : NSRegularExpressionCheckingResult +{ + NSRegularExpression *_regularExpression; + NSRange _ranges[NSRegularExpressionCheckingResultSimpleLimit]; + NSUInteger _numberOfRanges; +} - (id)initWithRangeArray:(NSArray *)ranges regularExpression:(NSRegularExpression *)expression; - (id)initWithRanges:(NSRangePointer)ranges count:(NSUInteger)count regularExpression:(NSRegularExpression *)expression; @@ -33,6 +43,10 @@ NS_REQUIRES_PROPERTY_DEFINITIONS @end @interface NSExtendedRegularExpressionCheckingResult : NSRegularExpressionCheckingResult +{ + NSRegularExpression *_regularExpression; + NSRange _ranges[NSRegularExpressionCheckingResultExtendedLimit]; +} - (id)initWithRangeArray:(NSArray *)ranges regularExpression:(NSRegularExpression *)expression; - (id)initWithRanges:(NSRangePointer)ranges count:(NSUInteger)count regularExpression:(NSRegularExpression *)expression; diff --git a/src/NSRegularExpressionCheckingResult.m b/src/NSRegularExpressionCheckingResult.m index fd72d3f5b..b8b629631 100644 --- a/src/NSRegularExpressionCheckingResult.m +++ b/src/NSRegularExpressionCheckingResult.m @@ -11,11 +11,6 @@ #import #import "NSObjectInternal.h" -typedef NS_ENUM(NSUInteger, NSRegularExpressionCheckingResultLimits) { - NSRegularExpressionCheckingResultSimpleLimit = 3, - NSRegularExpressionCheckingResultExtendedLimit = 7, -}; - @implementation NSRegularExpressionCheckingResult - (id)initWithRangeArray:(NSArray *)ranges regularExpression:(NSRegularExpression *)expression @@ -82,11 +77,7 @@ typedef NS_ENUM(NSUInteger, NSRegularExpressionCheckingResultLimits) { @end -@implementation NSSimpleRegularExpressionCheckingResult { - NSRegularExpression *_regularExpression; - NSRange _ranges[NSRegularExpressionCheckingResultSimpleLimit]; - NSUInteger _numberOfRanges; -} +@implementation NSSimpleRegularExpressionCheckingResult - (id)initWithRangeArray:(NSArray *)ranges regularExpression:(NSRegularExpression *)expression { @@ -167,10 +158,7 @@ typedef NS_ENUM(NSUInteger, NSRegularExpressionCheckingResultLimits) { @end -@implementation NSExtendedRegularExpressionCheckingResult { - NSRegularExpression *_regularExpression; - NSRange _ranges[NSRegularExpressionCheckingResultExtendedLimit]; -} +@implementation NSExtendedRegularExpressionCheckingResult - (id)initWithRangeArray:(NSArray *)ranges regularExpression:(NSRegularExpression *)expression { diff --git a/src/NSScanner.m b/src/NSScanner.m index 4563c7eae..4a4fff25b 100644 --- a/src/NSScanner.m +++ b/src/NSScanner.m @@ -14,6 +14,12 @@ #import #import +#ifndef ULONG_LONG_MAX +# define ULONG_LONG_MAX 0xffffffffffffffffull +# define LONG_LONG_MAX 0x7fffffffffffffffll +# define LONG_LONG_MIN 0x8fffffffffffffffll +#endif + @interface NSScanner(Private) - (id)_invertedSkipSet; - (BOOL)_scanDecimal:(unsigned int)decimal into:(int *)addr; diff --git a/src/NSSet.m b/src/NSSet.m index b842ec34b..820a079c2 100644 --- a/src/NSSet.m +++ b/src/NSSet.m @@ -18,6 +18,7 @@ #import "NSFastEnumerationEnumerator.h" #import "NSKeyValueCodingInternal.h" #import "NSObjectInternal.h" +#import "NSExternals.h" @interface NSSet () - (NSUInteger)countForObject:(id)obj; @@ -305,10 +306,7 @@ OBJC_PROTOCOL_IMPL_POP @end -@implementation NSCountedSet { - CFMutableBagRef _table; - void *_reserved; -} +@implementation NSCountedSet + (BOOL)supportsSecureCoding { diff --git a/src/NSSetExpression.m b/src/NSSetExpression.m index 8afe0b7d0..5ba65a447 100644 --- a/src/NSSetExpression.m +++ b/src/NSSetExpression.m @@ -12,10 +12,6 @@ #import @implementation NSSetExpression -{ - NSExpression *_left; - NSExpression *_right; -} static NSString * const NSLeftExpressionKey = @"NSLeftExpression"; static NSString * const NSRightExpressionKey = @"NSRightExpression"; diff --git a/src/NSSortDescriptor.m b/src/NSSortDescriptor.m index 48a603399..a99d6a7ac 100644 --- a/src/NSSortDescriptor.m +++ b/src/NSSortDescriptor.m @@ -25,12 +25,7 @@ enum { NSSortDescriptorComparator = 0x2, }; -@implementation NSSortDescriptor { - NSUInteger _sortDescriptorFlags; - NSString *_key; - SEL _selector; - id _selectorOrBlock; -} +@implementation NSSortDescriptor + (id)sortDescriptorWithKey:(NSString *)key ascending:(BOOL)ascending { diff --git a/src/NSStringPredicateOperator.h b/src/NSStringPredicateOperator.h index 5f4587448..d0df07266 100644 --- a/src/NSStringPredicateOperator.h +++ b/src/NSStringPredicateOperator.h @@ -1,6 +1,9 @@ #import "NSPredicateOperator.h" @interface NSStringPredicateOperator : NSPredicateOperator +{ + NSComparisonPredicateOptions _flags; +} - (id)initWithOperatorType:(NSPredicateOperatorType)type modifier:(NSComparisonPredicateModifier)modifier variant:(NSUInteger)variant; - (NSComparisonPredicateOptions)flags; diff --git a/src/NSStringPredicateOperator.m b/src/NSStringPredicateOperator.m index 386c6a4bd..6f2d0d72b 100644 --- a/src/NSStringPredicateOperator.m +++ b/src/NSStringPredicateOperator.m @@ -10,9 +10,6 @@ static NSString * const NSFlagsKey = @"NSFlags"; @implementation NSStringPredicateOperator -{ - NSComparisonPredicateOptions _flags; -} + (BOOL)supportsSecureCoding { diff --git a/src/NSSubqueryExpression.m b/src/NSSubqueryExpression.m index bfa93f191..8fc2e5b0f 100644 --- a/src/NSSubqueryExpression.m +++ b/src/NSSubqueryExpression.m @@ -18,11 +18,6 @@ static NSString * const NSSubpredicateKey = @"NSSubpredicate"; static NSString * const NSVariableKey = @"NSVariable"; @implementation NSSubqueryExpression -{ - NSExpression *_collection; - NSExpression *_variableExpression; - NSPredicate *_subpredicate; -} + (BOOL)supportsSecureCoding { diff --git a/src/NSSubstringPredicateOperator.h b/src/NSSubstringPredicateOperator.h index 5953ea6e5..cfe4fa1ef 100644 --- a/src/NSSubstringPredicateOperator.h +++ b/src/NSSubstringPredicateOperator.h @@ -7,6 +7,9 @@ typedef NS_ENUM(NSUInteger, NSSubstringPredicateOperatorPosition) { }; @interface NSSubstringPredicateOperator : NSStringPredicateOperator +{ + NSSubstringPredicateOperatorPosition _position; +} - (id)initWithOperatorType:(NSPredicateOperatorType)type modifier:(NSComparisonPredicateModifier)modifier variant:(NSUInteger)variant position:(NSSubstringPredicateOperatorPosition)position; - (NSSubstringPredicateOperatorPosition)position; diff --git a/src/NSSubstringPredicateOperator.m b/src/NSSubstringPredicateOperator.m index b312db26c..31af68f30 100644 --- a/src/NSSubstringPredicateOperator.m +++ b/src/NSSubstringPredicateOperator.m @@ -12,9 +12,6 @@ #import @implementation NSSubstringPredicateOperator -{ - NSSubstringPredicateOperatorPosition _position; -} static NSString * const NSPositionKey = @"NSPosition"; diff --git a/src/NSSymbolicExpression.m b/src/NSSymbolicExpression.m index ed24123da..46444fe05 100644 --- a/src/NSSymbolicExpression.m +++ b/src/NSSymbolicExpression.m @@ -8,9 +8,6 @@ #import "NSExpressionInternal.h" @implementation NSSymbolicExpression -{ - NSString *_token; -} static NSString * const NSTokenKey = @"NSToken"; diff --git a/src/NSTernaryExpression.m b/src/NSTernaryExpression.m index 3259ebf6b..38731c4c7 100644 --- a/src/NSTernaryExpression.m +++ b/src/NSTernaryExpression.m @@ -13,11 +13,6 @@ #import @implementation NSTernaryExpression -{ - NSPredicate *_predicate; - NSExpression *_trueExpression; - NSExpression *_falseExpression; -} static NSString * const NSPredicateKey = @"NSPredicate"; static NSString * const NSTrueExpressionKey = @"NSTrueExpression"; diff --git a/src/NSThread.m b/src/NSThread.m index 7f483e679..0c8da84d8 100644 --- a/src/NSThread.m +++ b/src/NSThread.m @@ -27,15 +27,6 @@ NSString *const NSWillBecomeMultiThreadedNotification = @"NSWillBecomeMultiThrea NSString *const NSDidBecomeSingleThreadedNotification = @"NSDidBecomeSingleThreadedNotification"; NSString *const NSThreadWillExitNotification = @"NSThreadWillExitNotification"; -typedef enum { - NSThreadCreated, - NSThreadStarted, - NSThreadRunning, - NSThreadCancelling, - NSThreadEnding, - NSThreadFinished -} NSThreadState; - static pthread_key_t NSThreadKey; static NSThread *NSMainThread = nil; @@ -50,14 +41,20 @@ static void NSThreadInitialize() NSMainThread = [NSThread currentThread]; } +#ifdef APPORTABLE extern void __do_backtrace(int, int, int, int(*)(int, void *, char *, int, void *), void *); +#endif +#ifdef DARLING +void __do_backtrace(int xxx, ...) +{ +# warning Missing __do_backtrace implementation +} +#endif CF_PRIVATE @interface _NSThreadPerformInfo : NSObject -@end - -@implementation _NSThreadPerformInfo { +{ @package id target; SEL selector; @@ -67,6 +64,9 @@ CF_PRIVATE BOOL *signalled; CFRunLoopSourceRef source; } +@end + +@implementation _NSThreadPerformInfo - (void)dealloc { @@ -93,18 +93,7 @@ CF_PRIVATE - (BOOL)_setThreadPriority:(double)p; @end -@implementation NSThread { -@package - pthread_t _thread; - pthread_attr_t _attr; - NSString *_name; - NSMutableDictionary *_threadDictionary; - NSThreadState _state; - NSMutableArray *_performers; - id _target; - SEL _selector; - id _argument; -} +@implementation NSThread static void NSThreadEnd(NSThread *thread) { diff --git a/src/NSURL.m b/src/NSURL.m index c676a502f..74d5e20c5 100644 --- a/src/NSURL.m +++ b/src/NSURL.m @@ -42,11 +42,9 @@ OBJC_PROTOCOL_IMPL_PUSH [self release]; return nil; } - else if (!_CFURLInitWithFileSystemPath([self _cfurl], (CFStringRef)path, kCFURLPOSIXPathStyle, isDirectory, NULL)) - { - [self release]; - return nil; - } + + [self release]; + self = (NSURL*) CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)path, kCFURLPOSIXPathStyle, isDirectory); return self; } else @@ -67,11 +65,9 @@ OBJC_PROTOCOL_IMPL_PUSH BOOL isDir = NO; [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDir]; - if (!_CFURLInitWithFileSystemPath([self _cfurl], (CFStringRef)path, kCFURLPOSIXPathStyle, isDir, NULL)) - { - [self release]; - return nil; - } + [self release]; + self = (NSURL*) CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)path, kCFURLPOSIXPathStyle, isDir); + return self; } OBJC_PROTOCOL_IMPL_POP @@ -80,11 +76,8 @@ OBJC_PROTOCOL_IMPL_POP { if ([self class] == [NSURL class]) { - if (!_CFURLInitWithFileSystemRepresentation((CFURLRef)self, (const UInt8 *)path, strlen(path), isDir, (CFURLRef)baseURL)) - { - [self release]; - return nil; - } + [self release]; + self = (NSURL*) CFURLCreateFromFileSystemRepresentationRelativeToBase(kCFAllocatorDefault, (const UInt8 *)path, strlen(path), isDir, (CFURLRef)baseURL); } else { @@ -102,7 +95,7 @@ OBJC_PROTOCOL_IMPL_POP { if (self == [NSURL class]) { - return (NSURL *)_CFURLAlloc(kCFAllocatorDefault); + return (NSURL *)CFURLCreateWithString(kCFAllocatorDefault, @"", NULL); } else { @@ -562,11 +555,8 @@ OBJC_PROTOCOL_IMPL_PUSH { if ([self class] == [NSURL class]) { - if (!_CFURLInitWithURLString([self _cfurl], (CFStringRef)string, true, [url _cfurl])) - { - [self release]; - return nil; - } + [self release]; + self = CFURLCreateWithString(kCFAllocatorDefault, (CFStringRef)string, [url _cfurl]); } else { diff --git a/src/NSURLAuthenticationChallenge.m b/src/NSURLAuthenticationChallenge.m index f40df8db4..5c59e7eea 100644 --- a/src/NSURLAuthenticationChallenge.m +++ b/src/NSURLAuthenticationChallenge.m @@ -14,14 +14,6 @@ #import @implementation NSURLAuthenticationChallenge -{ - NSURLProtectionSpace *_protectionSpace; - NSURLCredential *_proposedCredential; - NSInteger _previousFailureCount; - NSURLResponse *_failureResponse; - NSError *_error; - id _sender; -} + (BOOL)supportsSecureCoding { diff --git a/src/NSURLCache.m b/src/NSURLCache.m index d5a29b77b..c2d834f6f 100644 --- a/src/NSURLCache.m +++ b/src/NSURLCache.m @@ -15,10 +15,7 @@ static NSUInteger NSURLCacheDefaultMemoryCapacity = 512000; static NSUInteger NSURLCacheDefaultDiskCapacity = 10000000; -@implementation NSCachedURLResponse { - NSURLResponse* _response; - CFCachedURLResponseRef _cachedResponseRef; -} +@implementation NSCachedURLResponse - (id)initWithResponse:(NSURLResponse*)response data:(NSData*)data { @@ -125,9 +122,7 @@ static NSUInteger NSURLCacheDefaultDiskCapacity = 10000000; @end -@implementation NSURLCache { - CFURLCacheRef _cacheRef; -} +@implementation NSURLCache static NSURLCache* sharedURLCache = nil; static Boolean sharedURLCacheSet = false; diff --git a/src/NSURLConnection.m b/src/NSURLConnection.m index c99ac3df0..b9ba1ba3c 100644 --- a/src/NSURLConnection.m +++ b/src/NSURLConnection.m @@ -524,9 +524,7 @@ static CFCachedURLResponseRef cache(const void *info, CFCachedURLResponseRef cac @end -@implementation NSURLConnection { - NSURLConnectionInternal *_internal; -} +@implementation NSURLConnection + (NSURLConnection*)connectionWithRequest:(NSURLRequest *)request delegate:(id)delegate { diff --git a/src/NSURLProtectionSpace.m b/src/NSURLProtectionSpace.m index bd24e9183..552a029bd 100644 --- a/src/NSURLProtectionSpace.m +++ b/src/NSURLProtectionSpace.m @@ -28,9 +28,7 @@ NSString * const NSURLAuthenticationMethodServerTrust = @"NSURLAuthenticationMet @class NSURLProtectionSpaceInternal; -@implementation NSURLProtectionSpace { - NSURLProtectionSpaceInternal *_internal; -} +@implementation NSURLProtectionSpace static CFURLProtectionSpaceServerType protocolToCFServerType(NSString * const protocol) { diff --git a/src/NSURLProtocol.m b/src/NSURLProtocol.m index 9a3bb1c44..034eef126 100644 --- a/src/NSURLProtocol.m +++ b/src/NSURLProtocol.m @@ -66,11 +66,6 @@ static NSMutableArray *sRegisteredClasses = nil; @end @implementation NSURLProtocol -{ - NSCachedURLResponse *_cachedResponse; - NSURLRequest *_request; - id _client; -} + (void)initialize { diff --git a/src/NSURLRequest.m b/src/NSURLRequest.m index f35ee83c9..571435d8b 100644 --- a/src/NSURLRequest.m +++ b/src/NSURLRequest.m @@ -22,9 +22,7 @@ @end -@implementation NSURLRequest { - NSURLRequestInternal *_internal; -} +@implementation NSURLRequest static NSTimeInterval defaultTimeout = 60.0; diff --git a/src/NSURLResponse.m b/src/NSURLResponse.m index ae3ca1afa..50302344e 100644 --- a/src/NSURLResponse.m +++ b/src/NSURLResponse.m @@ -29,9 +29,7 @@ @end -@implementation NSURLResponse { - NSURLResponseInternal *_internal; -} +@implementation NSURLResponse + (id)_responseWithCFURLResponse:(CFURLResponseRef)response { @@ -159,9 +157,7 @@ static inline NSString *NSURLLocalizedString(NSString *key) @end -@implementation NSHTTPURLResponse { - NSHTTPURLResponseInternal *_httpInternal; -} +@implementation NSHTTPURLResponse + (BOOL)isErrorStatusCode:(NSInteger)statusCode { diff --git a/src/NSURLSession.m b/src/NSURLSession.m index 2e492b83c..d0632d48c 100644 --- a/src/NSURLSession.m +++ b/src/NSURLSession.m @@ -6,7 +6,8 @@ // #import "NSURLSession.h" -#import +#import + const int64_t NSURLSessionTransferSizeUnknown = -1LL; @implementation NSURLSession @@ -15,7 +16,7 @@ const int64_t NSURLSessionTransferSizeUnknown = -1LL; { static dispatch_once_t once = 0L; dispatch_once(&once, ^{ - Class cls = objc_lookupClass("__NSCFURLSession"); + Class cls = objc_lookUpClass("__NSCFURLSession"); assert(cls != Nil); class_setSuperclass(self, cls); }); diff --git a/src/NSUbiquitousKeyValueStore.m b/src/NSUbiquitousKeyValueStore.m index d37c18f32..d0eb43448 100644 --- a/src/NSUbiquitousKeyValueStore.m +++ b/src/NSUbiquitousKeyValueStore.m @@ -19,10 +19,7 @@ NSString * const NSUbiquitousKeyValueStoreDidChangeExternallyNotification = @"NS NSString * const NSUbiquitousKeyValueStoreChangeReasonKey = @"NSUbiquitousKeyValueStoreChangeReasonKey"; NSString * const NSUbiquitousKeyValueStoreChangedKeysKey = @"NSUbiquitousKeyValueStoreChangedKeysKey"; -@implementation NSUbiquitousKeyValueStore { - id<_NSUbiquitousKeyValueStoreProvider> _provider; - dispatch_queue_t _providerQueue; -} +@implementation NSUbiquitousKeyValueStore + (NSUbiquitousKeyValueStore *)defaultStore { diff --git a/src/NSUserDefaults.m b/src/NSUserDefaults.m index 8e89e56ad..fd3d2ea70 100644 --- a/src/NSUserDefaults.m +++ b/src/NSUserDefaults.m @@ -5,15 +5,16 @@ // Copyright (c) 2014 Apportable. All rights reserved. // +#import +#include "ForFoundationOnly.h" +#define PREFS_TYPE _CFApplicationPreferences #import #import #import #import #import #import "NSObjectInternal.h" -#import #import -#include "ForFoundationOnly.h" NSString * const NSGlobalDomain = @"NSGlobalDomain"; NSString * const NSArgumentDomain = @"NSArgumentDomain"; @@ -26,9 +27,7 @@ static dispatch_source_t synchronizeTimer; static dispatch_queue_t synchronizeQueue; #define SYNC_INTERVAL 30 -@implementation NSUserDefaults { - _CFApplicationPreferences *_cfDataPtr; -} +@implementation NSUserDefaults + (NSUserDefaults *)standardUserDefaults { diff --git a/src/NSValue.m b/src/NSValue.m index 338f19959..8e7eefff5 100644 --- a/src/NSValue.m +++ b/src/NSValue.m @@ -15,6 +15,7 @@ #include #include #import "ForFoundationOnly.h" +#import static NSValue *_NSNewValue(void *value, const char *type); @@ -363,7 +364,11 @@ static id newDecodedValue(NSCoder *aCoder) } case NSEdgeInsetsType: case NSEdgeType: { // probably good enough +#ifdef __arm__ UIEdgeInsets insets; +#else + NSEdgeInsets insets; +#endif #if __LP64__ insets.top = [aCoder decodeDoubleForKey:NS_edgeval_top]; insets.left = [aCoder decodeDoubleForKey:NS_edgeval_left]; @@ -375,8 +380,13 @@ static id newDecodedValue(NSCoder *aCoder) insets.bottom = [aCoder decodeFloatForKey:NS_edgeval_bottom]; insets.right = [aCoder decodeFloatForKey:NS_edgeval_right]; #endif +#ifdef __arm__ return createValue((uint8_t *)&insets, @encode(UIEdgeInsets), sizeof(UIEdgeInsets), flags); +#else + return createValue((uint8_t *)&insets, @encode(NSEdgeInsets), sizeof(NSEdgeInsets), flags); +#endif } +#ifdef __arm__ case NSOffsetType: { UIOffset offset; #if __LP64__ @@ -388,6 +398,7 @@ static id newDecodedValue(NSCoder *aCoder) #endif return createValue((uint8_t *)&offset, @encode(UIOffset), sizeof(UIOffset), flags); } +#endif default: { [NSException raise:NSInternalInconsistencyException format:@"Incorrect special type encoding for value"]; return nil; @@ -672,7 +683,11 @@ static id newDecodedValue(NSCoder *aCoder) } case NSEdgeInsetsType: case NSEdgeType: { +#ifdef __arm__ UIEdgeInsets insets; +#else + NSEdgeInsets insets; +#endif [self getValue:&insets]; #if __LP64__ [aCoder encodeDouble:insets.top forKey:NS_edgeval_top]; @@ -687,6 +702,7 @@ static id newDecodedValue(NSCoder *aCoder) #endif break; } +#ifdef __arm__ case NSOffsetType: { UIOffset offset; [self getValue:&offset]; @@ -699,6 +715,7 @@ static id newDecodedValue(NSCoder *aCoder) #endif break; } +#endif } } } diff --git a/src/NSValueInternal.h b/src/NSValueInternal.h index ecf502690..7c4b57eec 100644 --- a/src/NSValueInternal.h +++ b/src/NSValueInternal.h @@ -2,6 +2,7 @@ #import "CFInternal.h" #import "NSExternals.h" #import +#import CF_EXPORT Boolean _CFNumberGetValue(CFNumberRef number, CFNumberType type, void *valuePtr); CF_EXPORT CFNumberType _CFNumberGetType(CFNumberRef num); diff --git a/src/NSVariableAssignmentExpression.m b/src/NSVariableAssignmentExpression.m index 24113d088..0361576d8 100644 --- a/src/NSVariableAssignmentExpression.m +++ b/src/NSVariableAssignmentExpression.m @@ -16,10 +16,6 @@ static NSString * const NSAssignmentVariableKey = @"NSAssignmentVariable"; static NSString * const NSSubexpressionKey = @"NSSubexpression"; @implementation NSVariableAssignmentExpression -{ - NSVariableExpression *_assignmentVariable; - NSExpression *_subexpression; -} + (BOOL)supportsSecureCoding { diff --git a/src/NSVariableExpression.m b/src/NSVariableExpression.m index 67664f04d..2e6195235 100644 --- a/src/NSVariableExpression.m +++ b/src/NSVariableExpression.m @@ -15,10 +15,6 @@ static NSString * const NSVariableKey = @"NSVariable"; @implementation NSVariableExpression -{ - NSString *_variable; -} - + (BOOL)supportsSecureCoding { return YES; diff --git a/src/NSXMLParser.m b/src/NSXMLParser.m index 14a1a3d68..5e50659bd 100644 --- a/src/NSXMLParser.m +++ b/src/NSXMLParser.m @@ -73,12 +73,7 @@ CF_PRIVATE @end -@implementation NSXMLParser { - id _delegate; - _NSXMLParserInfo *_info; - NSData *_data; - NSStream *_stream; -} +@implementation NSXMLParser static inline Boolean cStringEqual(const void *value1, const void *value2) { diff --git a/src/_NSFileIO.m b/src/_NSFileIO.m index 890dae2aa..008eb8b80 100644 --- a/src/_NSFileIO.m +++ b/src/_NSFileIO.m @@ -7,7 +7,6 @@ #import "_NSFileIO.h" -#import #import #import #import diff --git a/src/_NSKeyedCoderOldStyleArray.m b/src/_NSKeyedCoderOldStyleArray.m index 8a43245da..2483fd28c 100644 --- a/src/_NSKeyedCoderOldStyleArray.m +++ b/src/_NSKeyedCoderOldStyleArray.m @@ -11,13 +11,6 @@ #import @implementation _NSKeyedCoderOldStyleArray -{ - void *_addr; - NSUInteger _count; - NSUInteger _size; - char _type; - BOOL _decoded; -} - (id)initWithCoder:(NSCoder *)decoder { diff --git a/src/common.h b/src/common.h new file mode 100644 index 000000000..140abacaf --- /dev/null +++ b/src/common.h @@ -0,0 +1,2 @@ +#include + diff --git a/src/stub.m b/src/stub.m new file mode 100644 index 000000000..5eb1b3e02 --- /dev/null +++ b/src/stub.m @@ -0,0 +1,16 @@ +#import +#import +#import + +@implementation NSURLResponse +@end + +@implementation NSHTTPURLResponse +@end + +@implementation NSURLConnection +@end + +@implementation NSURLRequest +@end + diff --git a/src/utlist.h b/src/utlist.h new file mode 100644 index 000000000..8a02fe71a --- /dev/null +++ b/src/utlist.h @@ -0,0 +1,775 @@ +/* +Copyright (c) 2007-2014, Troy D. Hanson http://troydhanson.github.com/uthash/ +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef UTLIST_H +#define UTLIST_H + +#define UTLIST_VERSION 1.9.9 + +#include + +/* + * This file contains macros to manipulate singly and doubly-linked lists. + * + * 1. LL_ macros: singly-linked lists. + * 2. DL_ macros: doubly-linked lists. + * 3. CDL_ macros: circular doubly-linked lists. + * + * To use singly-linked lists, your structure must have a "next" pointer. + * To use doubly-linked lists, your structure must "prev" and "next" pointers. + * Either way, the pointer to the head of the list must be initialized to NULL. + * + * ----------------.EXAMPLE ------------------------- + * struct item { + * int id; + * struct item *prev, *next; + * } + * + * struct item *list = NULL: + * + * int main() { + * struct item *item; + * ... allocate and populate item ... + * DL_APPEND(list, item); + * } + * -------------------------------------------------- + * + * For doubly-linked lists, the append and delete macros are O(1) + * For singly-linked lists, append and delete are O(n) but prepend is O(1) + * The sort macro is O(n log(n)) for all types of single/double/circular lists. + */ + +/* These macros use decltype or the earlier __typeof GNU extension. + As decltype is only available in newer compilers (VS2010 or gcc 4.3+ + when compiling c++ code), this code uses whatever method is needed + or, for VS2008 where neither is available, uses casting workarounds. */ +#ifdef _MSC_VER /* MS compiler */ +#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ +#define LDECLTYPE(x) decltype(x) +#else /* VS2008 or older (or VS2010 in C mode) */ +#define NO_DECLTYPE +#define LDECLTYPE(x) char* +#endif +#elif defined(__ICCARM__) +#define NO_DECLTYPE +#define LDECLTYPE(x) char* +#else /* GNU, Sun and other compilers */ +#define LDECLTYPE(x) __typeof(x) +#endif + +/* for VS2008 we use some workarounds to get around the lack of decltype, + * namely, we always reassign our tmp variable to the list head if we need + * to dereference its prev/next pointers, and save/restore the real head.*/ +#ifdef NO_DECLTYPE +#define _SV(elt,list) _tmp = (char*)(list); {char **_alias = (char**)&(list); *_alias = (elt); } +#define _NEXT(elt,list,next) ((char*)((list)->next)) +#define _NEXTASGN(elt,list,to,next) { char **_alias = (char**)&((list)->next); *_alias=(char*)(to); } +/* #define _PREV(elt,list,prev) ((char*)((list)->prev)) */ +#define _PREVASGN(elt,list,to,prev) { char **_alias = (char**)&((list)->prev); *_alias=(char*)(to); } +#define _RS(list) { char **_alias = (char**)&(list); *_alias=_tmp; } +#define _CASTASGN(a,b) { char **_alias = (char**)&(a); *_alias=(char*)(b); } +#else +#define _SV(elt,list) +#define _NEXT(elt,list,next) ((elt)->next) +#define _NEXTASGN(elt,list,to,next) ((elt)->next)=(to) +/* #define _PREV(elt,list,prev) ((elt)->prev) */ +#define _PREVASGN(elt,list,to,prev) ((elt)->prev)=(to) +#define _RS(list) +#define _CASTASGN(a,b) (a)=(b) +#endif + +/****************************************************************************** + * The sort macro is an adaptation of Simon Tatham's O(n log(n)) mergesort * + * Unwieldy variable names used here to avoid shadowing passed-in variables. * + *****************************************************************************/ +#define LL_SORT(list, cmp) \ + LL_SORT2(list, cmp, next) + +#define LL_SORT2(list, cmp, next) \ +do { \ + LDECLTYPE(list) _ls_p; \ + LDECLTYPE(list) _ls_q; \ + LDECLTYPE(list) _ls_e; \ + LDECLTYPE(list) _ls_tail; \ + int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ + if (list) { \ + _ls_insize = 1; \ + _ls_looping = 1; \ + while (_ls_looping) { \ + _CASTASGN(_ls_p,list); \ + list = NULL; \ + _ls_tail = NULL; \ + _ls_nmerges = 0; \ + while (_ls_p) { \ + _ls_nmerges++; \ + _ls_q = _ls_p; \ + _ls_psize = 0; \ + for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ + _ls_psize++; \ + _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list,next); _RS(list); \ + if (!_ls_q) break; \ + } \ + _ls_qsize = _ls_insize; \ + while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ + if (_ls_psize == 0) { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ + _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + } else if (_ls_qsize == 0 || !_ls_q) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ + _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + } else if (cmp(_ls_p,_ls_q) <= 0) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ + _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + } else { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ + _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + } \ + if (_ls_tail) { \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list); \ + } else { \ + _CASTASGN(list,_ls_e); \ + } \ + _ls_tail = _ls_e; \ + } \ + _ls_p = _ls_q; \ + } \ + if (_ls_tail) { \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL,next); _RS(list); \ + } \ + if (_ls_nmerges <= 1) { \ + _ls_looping=0; \ + } \ + _ls_insize *= 2; \ + } \ + } \ +} while (0) + + +#define DL_SORT(list, cmp) \ + DL_SORT2(list, cmp, prev, next) + +#define DL_SORT2(list, cmp, prev, next) \ +do { \ + LDECLTYPE(list) _ls_p; \ + LDECLTYPE(list) _ls_q; \ + LDECLTYPE(list) _ls_e; \ + LDECLTYPE(list) _ls_tail; \ + int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ + if (list) { \ + _ls_insize = 1; \ + _ls_looping = 1; \ + while (_ls_looping) { \ + _CASTASGN(_ls_p,list); \ + list = NULL; \ + _ls_tail = NULL; \ + _ls_nmerges = 0; \ + while (_ls_p) { \ + _ls_nmerges++; \ + _ls_q = _ls_p; \ + _ls_psize = 0; \ + for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ + _ls_psize++; \ + _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list,next); _RS(list); \ + if (!_ls_q) break; \ + } \ + _ls_qsize = _ls_insize; \ + while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ + if (_ls_psize == 0) { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ + _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + } else if (_ls_qsize == 0 || !_ls_q) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ + _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + } else if (cmp(_ls_p,_ls_q) <= 0) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ + _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + } else { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ + _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + } \ + if (_ls_tail) { \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list); \ + } else { \ + _CASTASGN(list,_ls_e); \ + } \ + _SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail,prev); _RS(list); \ + _ls_tail = _ls_e; \ + } \ + _ls_p = _ls_q; \ + } \ + _CASTASGN(list->prev, _ls_tail); \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL,next); _RS(list); \ + if (_ls_nmerges <= 1) { \ + _ls_looping=0; \ + } \ + _ls_insize *= 2; \ + } \ + } \ +} while (0) + + +#define DL_HEAD(list) (list) +#define DL_TAIL(list) ((list) ? (list)->prev : NULL) + +#define CDL_SORT(list, cmp) \ + CDL_SORT2(list, cmp, prev, next) + +#define CDL_SORT2(list, cmp, prev, next) \ +do { \ + LDECLTYPE(list) _ls_p; \ + LDECLTYPE(list) _ls_q; \ + LDECLTYPE(list) _ls_e; \ + LDECLTYPE(list) _ls_tail; \ + LDECLTYPE(list) _ls_oldhead; \ + LDECLTYPE(list) _tmp; \ + int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ + if (list) { \ + _ls_insize = 1; \ + _ls_looping = 1; \ + while (_ls_looping) { \ + _CASTASGN(_ls_p,list); \ + _CASTASGN(_ls_oldhead,list); \ + list = NULL; \ + _ls_tail = NULL; \ + _ls_nmerges = 0; \ + while (_ls_p) { \ + _ls_nmerges++; \ + _ls_q = _ls_p; \ + _ls_psize = 0; \ + for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ + _ls_psize++; \ + _SV(_ls_q,list); \ + if (_NEXT(_ls_q,list,next) == _ls_oldhead) { \ + _ls_q = NULL; \ + } else { \ + _ls_q = _NEXT(_ls_q,list,next); \ + } \ + _RS(list); \ + if (!_ls_q) break; \ + } \ + _ls_qsize = _ls_insize; \ + while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ + if (_ls_psize == 0) { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ + _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ + } else if (_ls_qsize == 0 || !_ls_q) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ + _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ + } else if (cmp(_ls_p,_ls_q) <= 0) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ + _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ + } else { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ + _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ + } \ + if (_ls_tail) { \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list); \ + } else { \ + _CASTASGN(list,_ls_e); \ + } \ + _SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail,prev); _RS(list); \ + _ls_tail = _ls_e; \ + } \ + _ls_p = _ls_q; \ + } \ + _CASTASGN(list->prev,_ls_tail); \ + _CASTASGN(_tmp,list); \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_tmp,next); _RS(list); \ + if (_ls_nmerges <= 1) { \ + _ls_looping=0; \ + } \ + _ls_insize *= 2; \ + } \ + } \ +} while (0) + +/****************************************************************************** + * singly linked list macros (non-circular) * + *****************************************************************************/ +#define LL_PREPEND(head,add) \ + LL_PREPEND2(head,add,next) + +#define LL_PREPEND2(head,add,next) \ +do { \ + (add)->next = head; \ + head = add; \ +} while (0) + +#define LL_CONCAT(head1,head2) \ + LL_CONCAT2(head1,head2,next) + +#define LL_CONCAT2(head1,head2,next) \ +do { \ + LDECLTYPE(head1) _tmp; \ + if (head1) { \ + _tmp = head1; \ + while (_tmp->next) { _tmp = _tmp->next; } \ + _tmp->next=(head2); \ + } else { \ + (head1)=(head2); \ + } \ +} while (0) + +#define LL_APPEND(head,add) \ + LL_APPEND2(head,add,next) + +#define LL_APPEND2(head,add,next) \ +do { \ + LDECLTYPE(head) _tmp; \ + (add)->next=NULL; \ + if (head) { \ + _tmp = head; \ + while (_tmp->next) { _tmp = _tmp->next; } \ + _tmp->next=(add); \ + } else { \ + (head)=(add); \ + } \ +} while (0) + +#define LL_DELETE(head,del) \ + LL_DELETE2(head,del,next) + +#define LL_DELETE2(head,del,next) \ +do { \ + LDECLTYPE(head) _tmp; \ + if ((head) == (del)) { \ + (head)=(head)->next; \ + } else { \ + _tmp = head; \ + while (_tmp->next && (_tmp->next != (del))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = ((del)->next); \ + } \ + } \ +} while (0) + +/* Here are VS2008 replacements for LL_APPEND and LL_DELETE */ +#define LL_APPEND_VS2008(head,add) \ + LL_APPEND2_VS2008(head,add,next) + +#define LL_APPEND2_VS2008(head,add,next) \ +do { \ + if (head) { \ + (add)->next = head; /* use add->next as a temp variable */ \ + while ((add)->next->next) { (add)->next = (add)->next->next; } \ + (add)->next->next=(add); \ + } else { \ + (head)=(add); \ + } \ + (add)->next=NULL; \ +} while (0) + +#define LL_DELETE_VS2008(head,del) \ + LL_DELETE2_VS2008(head,del,next) + +#define LL_DELETE2_VS2008(head,del,next) \ +do { \ + if ((head) == (del)) { \ + (head)=(head)->next; \ + } else { \ + char *_tmp = (char*)(head); \ + while ((head)->next && ((head)->next != (del))) { \ + head = (head)->next; \ + } \ + if ((head)->next) { \ + (head)->next = ((del)->next); \ + } \ + { \ + char **_head_alias = (char**)&(head); \ + *_head_alias = _tmp; \ + } \ + } \ +} while (0) +#ifdef NO_DECLTYPE +#undef LL_APPEND +#define LL_APPEND LL_APPEND_VS2008 +#undef LL_DELETE +#define LL_DELETE LL_DELETE_VS2008 +#undef LL_DELETE2 +#define LL_DELETE2 LL_DELETE2_VS2008 +#undef LL_APPEND2 +#define LL_APPEND2 LL_APPEND2_VS2008 +#undef LL_CONCAT /* no LL_CONCAT_VS2008 */ +#undef DL_CONCAT /* no DL_CONCAT_VS2008 */ +#endif +/* end VS2008 replacements */ + +#define LL_COUNT(head,el,counter) \ + LL_COUNT2(head,el,counter,next) \ + +#define LL_COUNT2(head,el,counter,next) \ +{ \ + counter = 0; \ + LL_FOREACH2(head,el,next){ ++counter; } \ +} + +#define LL_FOREACH(head,el) \ + LL_FOREACH2(head,el,next) + +#define LL_FOREACH2(head,el,next) \ + for(el=head;el;el=(el)->next) + +#define LL_FOREACH_SAFE(head,el,tmp) \ + LL_FOREACH_SAFE2(head,el,tmp,next) + +#define LL_FOREACH_SAFE2(head,el,tmp,next) \ + for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp) + +#define LL_SEARCH_SCALAR(head,out,field,val) \ + LL_SEARCH_SCALAR2(head,out,field,val,next) + +#define LL_SEARCH_SCALAR2(head,out,field,val,next) \ +do { \ + LL_FOREACH2(head,out,next) { \ + if ((out)->field == (val)) break; \ + } \ +} while(0) + +#define LL_SEARCH(head,out,elt,cmp) \ + LL_SEARCH2(head,out,elt,cmp,next) + +#define LL_SEARCH2(head,out,elt,cmp,next) \ +do { \ + LL_FOREACH2(head,out,next) { \ + if ((cmp(out,elt))==0) break; \ + } \ +} while(0) + +#define LL_REPLACE_ELEM(head, el, add) \ +do { \ + LDECLTYPE(head) _tmp; \ + assert(head != NULL); \ + assert(el != NULL); \ + assert(add != NULL); \ + (add)->next = (el)->next; \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + _tmp = head; \ + while (_tmp->next && (_tmp->next != (el))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = (add); \ + } \ + } \ +} while (0) + +#define LL_PREPEND_ELEM(head, el, add) \ +do { \ + LDECLTYPE(head) _tmp; \ + assert(head != NULL); \ + assert(el != NULL); \ + assert(add != NULL); \ + (add)->next = (el); \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + _tmp = head; \ + while (_tmp->next && (_tmp->next != (el))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = (add); \ + } \ + } \ +} while (0) \ + + +/****************************************************************************** + * doubly linked list macros (non-circular) * + *****************************************************************************/ +#define DL_PREPEND(head,add) \ + DL_PREPEND2(head,add,prev,next) + +#define DL_PREPEND2(head,add,prev,next) \ +do { \ + (add)->next = head; \ + if (head) { \ + (add)->prev = (head)->prev; \ + (head)->prev = (add); \ + } else { \ + (add)->prev = (add); \ + } \ + (head) = (add); \ +} while (0) + +#define DL_APPEND(head,add) \ + DL_APPEND2(head,add,prev,next) + +#define DL_APPEND2(head,add,prev,next) \ +do { \ + if (head) { \ + (add)->prev = (head)->prev; \ + (head)->prev->next = (add); \ + (head)->prev = (add); \ + (add)->next = NULL; \ + } else { \ + (head)=(add); \ + (head)->prev = (head); \ + (head)->next = NULL; \ + } \ +} while (0) + +#define DL_INSERT(head, next_node, add) \ + do { \ + if (head == next_node) \ + DL_PREPEND(head, add); \ + else if (next_node == NULL) { \ + DL_APPEND(head, add); \ + } else { \ + (add)->prev = (next_node)->prev; \ + (next_node)->prev->next = (add); \ + (add)->next = (next_node); \ + (next_node)->prev = (add); \ + } \ + } while (0) + +#define DL_CONCAT(head1,head2) \ + DL_CONCAT2(head1,head2,prev,next) + +#define DL_CONCAT2(head1,head2,prev,next) \ +do { \ + LDECLTYPE(head1) _tmp; \ + if (head2) { \ + if (head1) { \ + _tmp = (head2)->prev; \ + (head2)->prev = (head1)->prev; \ + (head1)->prev->next = (head2); \ + (head1)->prev = _tmp; \ + } else { \ + (head1)=(head2); \ + } \ + } \ +} while (0) + +#define DL_DELETE(head,del) \ + DL_DELETE2(head,del,prev,next) + +#define DL_DELETE2(head,del,prev,next) \ +do { \ + assert((del)->prev != NULL); \ + if ((del)->prev == (del)) { \ + (head)=NULL; \ + } else if ((del)==(head)) { \ + (del)->next->prev = (del)->prev; \ + (head) = (del)->next; \ + } else { \ + (del)->prev->next = (del)->next; \ + if ((del)->next) { \ + (del)->next->prev = (del)->prev; \ + } else { \ + (head)->prev = (del)->prev; \ + } \ + } \ +} while (0) + +#define DL_COUNT(head,el,counter) \ + DL_COUNT2(head,el,counter,next) \ + +#define DL_COUNT2(head,el,counter,next) \ +{ \ + counter = 0; \ + DL_FOREACH2(head,el,next){ ++counter; } \ +} + +#define DL_FOREACH(head,el) \ + DL_FOREACH2(head,el,next) + +#define DL_FOREACH2(head,el,next) \ + for(el=head;el;el=(el)->next) + +/* this version is safe for deleting the elements during iteration */ +#define DL_FOREACH_SAFE(head,el,tmp) \ + DL_FOREACH_SAFE2(head,el,tmp,next) + +#define DL_FOREACH_SAFE2(head,el,tmp,next) \ + for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp) + +/* these are identical to their singly-linked list counterparts */ +#define DL_SEARCH_SCALAR LL_SEARCH_SCALAR +#define DL_SEARCH LL_SEARCH +#define DL_SEARCH_SCALAR2 LL_SEARCH_SCALAR2 +#define DL_SEARCH2 LL_SEARCH2 + +#define DL_REPLACE_ELEM(head, el, add) \ +do { \ + assert(head != NULL); \ + assert(el != NULL); \ + assert(add != NULL); \ + if ((head) == (el)) { \ + (head) = (add); \ + (add)->next = (el)->next; \ + if ((el)->next == NULL) { \ + (add)->prev = (add); \ + } else { \ + (add)->prev = (el)->prev; \ + (add)->next->prev = (add); \ + } \ + } else { \ + (add)->next = (el)->next; \ + (add)->prev = (el)->prev; \ + (add)->prev->next = (add); \ + if ((el)->next == NULL) { \ + (head)->prev = (add); \ + } else { \ + (add)->next->prev = (add); \ + } \ + } \ +} while (0) + +#define DL_PREPEND_ELEM(head, el, add) \ +do { \ + assert(head != NULL); \ + assert(el != NULL); \ + assert(add != NULL); \ + (add)->next = (el); \ + (add)->prev = (el)->prev; \ + (el)->prev = (add); \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + (add)->prev->next = (add); \ + } \ +} while (0) \ + + +/****************************************************************************** + * circular doubly linked list macros * + *****************************************************************************/ +#define CDL_PREPEND(head,add) \ + CDL_PREPEND2(head,add,prev,next) + +#define CDL_PREPEND2(head,add,prev,next) \ +do { \ + if (head) { \ + (add)->prev = (head)->prev; \ + (add)->next = (head); \ + (head)->prev = (add); \ + (add)->prev->next = (add); \ + } else { \ + (add)->prev = (add); \ + (add)->next = (add); \ + } \ +(head)=(add); \ +} while (0) + +#define CDL_DELETE(head,del) \ + CDL_DELETE2(head,del,prev,next) + +#define CDL_DELETE2(head,del,prev,next) \ +do { \ + if ( ((head)==(del)) && ((head)->next == (head))) { \ + (head) = 0L; \ + } else { \ + (del)->next->prev = (del)->prev; \ + (del)->prev->next = (del)->next; \ + if ((del) == (head)) (head)=(del)->next; \ + } \ +} while (0) + +#define CDL_COUNT(head,el,counter) \ + CDL_COUNT2(head,el,counter,next) \ + +#define CDL_COUNT2(head, el, counter,next) \ +{ \ + counter = 0; \ + CDL_FOREACH2(head,el,next){ ++counter; } \ +} + +#define CDL_FOREACH(head,el) \ + CDL_FOREACH2(head,el,next) + +#define CDL_FOREACH2(head,el,next) \ + for(el=head;el;el=((el)->next==head ? 0L : (el)->next)) + +#define CDL_FOREACH_SAFE(head,el,tmp1,tmp2) \ + CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next) + +#define CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next) \ + for((el)=(head), ((tmp1)=(head)?((head)->prev):NULL); \ + (el) && ((tmp2)=(el)->next, 1); \ + ((el) = (((el)==(tmp1)) ? 0L : (tmp2)))) + +#define CDL_SEARCH_SCALAR(head,out,field,val) \ + CDL_SEARCH_SCALAR2(head,out,field,val,next) + +#define CDL_SEARCH_SCALAR2(head,out,field,val,next) \ +do { \ + CDL_FOREACH2(head,out,next) { \ + if ((out)->field == (val)) break; \ + } \ +} while(0) + +#define CDL_SEARCH(head,out,elt,cmp) \ + CDL_SEARCH2(head,out,elt,cmp,next) + +#define CDL_SEARCH2(head,out,elt,cmp,next) \ +do { \ + CDL_FOREACH2(head,out,next) { \ + if ((cmp(out,elt))==0) break; \ + } \ +} while(0) + +#define CDL_REPLACE_ELEM(head, el, add) \ +do { \ + assert(head != NULL); \ + assert(el != NULL); \ + assert(add != NULL); \ + if ((el)->next == (el)) { \ + (add)->next = (add); \ + (add)->prev = (add); \ + (head) = (add); \ + } else { \ + (add)->next = (el)->next; \ + (add)->prev = (el)->prev; \ + (add)->next->prev = (add); \ + (add)->prev->next = (add); \ + if ((head) == (el)) { \ + (head) = (add); \ + } \ + } \ +} while (0) + +#define CDL_PREPEND_ELEM(head, el, add) \ +do { \ + assert(head != NULL); \ + assert(el != NULL); \ + assert(add != NULL); \ + (add)->next = (el); \ + (add)->prev = (el)->prev; \ + (el)->prev = (add); \ + (add)->prev->next = (add); \ + if ((head) == (el)) { \ + (head) = (add); \ + } \ +} while (0) \ + +#endif /* UTLIST_H */ +