/ NSError.m
NSError.m
  1  //
  2  //  NSError.m
  3  //  CoreFoundation
  4  //
  5  //  Copyright (c) 2014 Apportable. All rights reserved.
  6  //
  7  
  8  #import <Foundation/NSError.h>
  9  #import <Foundation/NSError_Private.h>
 10  
 11  #import <Foundation/NSDictionary.h>
 12  #import "ForFoundationOnly.h"
 13  #import "NSObjectInternal.h"
 14  
 15  CF_PRIVATE
 16  @interface __NSCFError : __NSCFType
 17  @end
 18  
 19  
 20  NSString *const NSCocoaErrorDomain = @"NSCocoaErrorDomain";
 21  NSString *const NSPOSIXErrorDomain = @"NSPOSIXErrorDomain";
 22  NSString *const NSOSStatusErrorDomain = @"NSOSStatusErrorDomain";
 23  NSString *const NSMachErrorDomain = @"NSMachErrorDomain";
 24  NSString *const NSUnderlyingErrorKey = @"NSUnderlyingError";
 25  NSString *const NSLocalizedDescriptionKey = @"NSLocalizedDescription";
 26  NSString *const NSLocalizedFailureReasonErrorKey = @"NSLocalizedFailureReason";
 27  NSString *const NSLocalizedRecoverySuggestionErrorKey = @"NSLocalizedRecoverySuggestion";
 28  NSString *const NSLocalizedRecoveryOptionsErrorKey = @"NSLocalizedRecoveryOptions";
 29  NSString *const NSRecoveryAttempterErrorKey = @"NSRecoveryAttempter";
 30  NSString *const NSHelpAnchorErrorKey = @"NSHelpAnchor";
 31  NSString *const NSStringEncodingErrorKey = @"NSStringEncoding";
 32  NSString *const NSURLErrorKey = @"NSURL";
 33  NSString *const NSFilePathErrorKey = @"NSFilePath";
 34  NSString *const NSDebugDescriptionErrorKey = @"NSDebugDescription";
 35  NSString *const NSLocalizedFailureErrorKey = @"NSLocalizedFailure";
 36  
 37  static NSError *_outOfmemoryError = nil;
 38  
 39  @implementation NSError
 40  
 41  + (void)initialize
 42  {
 43      static dispatch_once_t once = 0L;
 44      dispatch_once(&once, ^{
 45          _outOfmemoryError = [[NSError errorWithDomain:NSPOSIXErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: @"Out of memory"}] retain];
 46      });
 47  }
 48  
 49  + (NSError *)_outOfMemoryError
 50  {
 51      return _outOfmemoryError;
 52  }
 53  
 54  - (CFTypeID)_cfTypeID
 55  {
 56      return CFErrorGetTypeID();
 57  }
 58  
 59  + (id)errorWithDomain:(NSString *)domain code:(NSInteger)code userInfo:(NSDictionary *)dict
 60  {
 61      return [[[self alloc] initWithDomain:domain code:code userInfo:dict] autorelease];
 62  }
 63  
 64  - (id)initWithDomain:(NSString *)domain code:(NSInteger)code userInfo:(NSDictionary *)dict
 65  {
 66      self = [super init];
 67  
 68      if (self)
 69      {
 70          _code = code;
 71          _domain = [domain copy];
 72          _userInfo = [dict copy];
 73      }
 74  
 75      return self;
 76  }
 77  
 78  - (NSString *)domain
 79  {
 80      return _domain;
 81  }
 82  
 83  - (NSInteger)code
 84  {
 85      return _code;
 86  }
 87  
 88  - (NSDictionary *)userInfo
 89  {
 90      return _userInfo;
 91  }
 92  
 93  - (NSString *)description
 94  {
 95      return [(NSString *)_CFErrorCreateDebugDescription((CFErrorRef)self) autorelease];
 96  }
 97  
 98  - (NSString *)localizedDescription
 99  {
100      NSString *desc = [[self userInfo][NSLocalizedDescriptionKey] copy];
101  
102      if (desc == nil)
103      {
104          desc = (NSString *)_CFErrorCreateLocalizedDescription((CFErrorRef)self);
105          if (desc == nil)
106          {
107              desc = (NSString *)CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("Operation could not be completed. %@ %d"), [self domain], [self code]);
108          }
109      }
110      
111      return [desc autorelease];
112  }
113  
114  - (NSString *)localizedFailureReason
115  {
116      return [self userInfo][NSLocalizedFailureReasonErrorKey];
117  }
118  
119  - (NSString *)localizedRecoverySuggestion
120  {
121      return [self userInfo][NSLocalizedRecoverySuggestionErrorKey];
122  }
123  
124  - (NSArray *)localizedRecoveryOptions
125  {
126      return [self userInfo][NSLocalizedRecoveryOptionsErrorKey];
127  }
128  
129  - (id)recoveryAttempter
130  {
131      return [self userInfo][NSRecoveryAttempterErrorKey];
132  }
133  
134  - (NSString *)helpAnchor
135  {
136      return [self userInfo][NSHelpAnchorErrorKey];
137  }
138  
139  - (id)copyWithZone:(NSZone *)zone
140  {
141      return [[NSError allocWithZone:zone] initWithDomain:[self domain] code:[self code] userInfo:[self userInfo]];
142  }
143  
144  + (BOOL)supportsSecureCoding
145  {
146      return NO;
147  }
148  
149  - (id)initWithCoder:(NSCoder *)aDecoder
150  {
151  #warning TODO: FIXME
152      [self release];
153      return nil;
154  }
155  
156  - (void)encodeWithCoder:(NSCoder *)aCoder
157  {
158  
159  }
160  
161  @end
162  
163  @implementation NSError (NSErrorPrivateStuff)
164  
165  + (void)_setFileNameLocalizationEnabled:(BOOL)enabled
166  {
167      // silently ignore it
168  }
169  
170  @end
171  
172  @implementation __NSCFError
173  
174  + (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key
175  {
176      return NO;
177  }
178  
179  - (id)copyWithZone:(NSZone *)zone
180  {
181      return (id)CFErrorCreate(kCFAllocatorDefault, (CFStringRef)[self domain], [self code], (CFDictionaryRef)[self userInfo]);
182  }
183  
184  - (Class)classForCoder
185  {
186      return [NSError class];
187  }
188  
189  - (NSDictionary *)userInfo
190  {
191      return [(NSDictionary *)CFErrorCopyUserInfo((CFErrorRef)self) autorelease];
192  }
193  
194  - (NSString *)domain
195  {
196      return (NSString *)CFErrorGetDomain((CFErrorRef)self);
197  }
198  
199  - (NSInteger)code
200  {
201      return CFErrorGetCode((CFErrorRef)self);
202  }
203  
204  - (NSUInteger)retainCount
205  {
206      return CFGetRetainCount((CFTypeRef)self);
207  }
208  
209  - (BOOL)_isDeallocating
210  {
211      return _CFIsDeallocating((CFTypeRef)self);
212  }
213  
214  - (BOOL)_tryRetain
215  {
216      return _CFTryRetain((CFTypeRef)self) != NULL;
217  }
218  
219  - (oneway void)release
220  {
221      CFRelease((CFTypeRef)self);
222  }
223  
224  - (id)retain
225  {
226      return (id)CFRetain((CFTypeRef)self);
227  }
228  
229  - (NSUInteger)hash
230  {
231      return CFHash((CFTypeRef)self);
232  }
233  
234  - (BOOL)isEqual:(id)other
235  {
236      if (other == nil)
237      {
238          return NO;
239      }
240      return CFEqual((CFTypeRef)self, (CFTypeRef)other);
241  }
242  
243  @end