PageRenderTime 61ms CodeModel.GetById 16ms app.highlight 40ms RepoModel.GetById 1ms app.codeStats 0ms

/core/externals/update-engine/externals/google-toolbox-for-mac/Foundation/GTMSystemVersion.m

http://macfuse.googlecode.com/
Objective C | 280 lines | 203 code | 30 blank | 47 comment | 45 complexity | 29f4ab79bddf41d518b075d03fedc800 MD5 | raw file
  1//
  2//  GTMSystemVersion.m
  3//
  4//  Copyright 2007-2008 Google Inc.
  5//
  6//  Licensed under the Apache License, Version 2.0 (the "License"); you may not
  7//  use this file except in compliance with the License.  You may obtain a copy
  8//  of the License at
  9// 
 10//  http://www.apache.org/licenses/LICENSE-2.0
 11// 
 12//  Unless required by applicable law or agreed to in writing, software
 13//  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 14//  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 15//  License for the specific language governing permissions and limitations under
 16//  the License.
 17//
 18
 19#import "GTMSystemVersion.h"
 20#import "GTMObjC2Runtime.h"
 21#if GTM_MACOS_SDK
 22#import <CoreServices/CoreServices.h>
 23#else
 24// On iOS we cheat and pull in the header for UIDevice to get the selectors,
 25// but call it via runtime since GTMSystemVersion is supposed to only depend on
 26// Foundation.
 27#import "UIKit/UIDevice.h"
 28#endif
 29
 30static SInt32 sGTMSystemVersionMajor = 0;
 31static SInt32 sGTMSystemVersionMinor = 0;
 32static SInt32 sGTMSystemVersionBugFix = 0;
 33static NSString *sBuild = nil;
 34
 35NSString *const kGTMArch_iPhone = @"iPhone";
 36NSString *const kGTMArch_ppc = @"ppc";
 37NSString *const kGTMArch_ppc64 = @"ppc64";
 38NSString *const kGTMArch_x86_64 = @"x86_64";
 39NSString *const kGTMArch_i386 = @"i386";
 40
 41static NSString *const kSystemVersionPlistPath = @"/System/Library/CoreServices/SystemVersion.plist";
 42
 43@implementation GTMSystemVersion
 44+ (void)initialize {
 45  if (self == [GTMSystemVersion class]) {
 46    // Gestalt is the recommended way of getting the OS version (despite a
 47    // comment to the contrary in the 10.4 headers and docs; see
 48    // <http://lists.apple.com/archives/carbon-dev/2007/Aug/msg00089.html>).
 49    // The iPhone doesn't have Gestalt though, so use the plist there.
 50#if GTM_MACOS_SDK
 51    require_noerr(Gestalt(gestaltSystemVersionMajor, &sGTMSystemVersionMajor), failedGestalt);
 52    require_noerr(Gestalt(gestaltSystemVersionMinor, &sGTMSystemVersionMinor), failedGestalt);
 53    require_noerr(Gestalt(gestaltSystemVersionBugFix, &sGTMSystemVersionBugFix), failedGestalt);
 54    
 55    return;
 56
 57  failedGestalt:
 58    ;
 59#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_3
 60    // gestaltSystemVersionMajor et al are only on 10.4 and above, so they
 61    // could fail when running on 10.3.
 62    SInt32 binaryCodedDec;
 63    OSStatus err = err = Gestalt(gestaltSystemVersion, &binaryCodedDec);
 64    _GTMDevAssert(!err, @"Unable to get version from Gestalt");
 65
 66    // Note that this code will return x.9.9 for any system rev parts that are
 67    // greater than 9 (i.e., 10.10.10 will be 10.9.9). This shouldn't ever be a
 68    // problem as the code above takes care of 10.4+.
 69    SInt32 msb = (binaryCodedDec & 0x0000F000L) >> 12;
 70    msb *= 10;
 71    SInt32 lsb = (binaryCodedDec & 0x00000F00L) >> 8;
 72    sGTMSystemVersionMajor = msb + lsb;
 73    sGTMSystemVersionMinor = (binaryCodedDec & 0x000000F0L) >> 4;
 74    sGTMSystemVersionBugFix = (binaryCodedDec & 0x0000000FL);
 75#endif // MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_3
 76
 77#else // GTM_MACOS_SDK
 78    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 79    NSString *version = nil;
 80
 81    // The intent is for this file to be Foundation level, so don't directly
 82    // call out to UIDevice, but try to get it at runtime before falling back
 83    // to the plist.  The problem with using the plist on the Simulator is that
 84    // the path will be on the host system, and give us a MacOS (10.x.y) 
 85    // version number instead of an iOS version number.
 86    Class uideviceClass = NSClassFromString(@"UIDevice");
 87    if (uideviceClass) {
 88      id currentDevice = objc_msgSend(uideviceClass, @selector(currentDevice));
 89      version = [currentDevice performSelector:@selector(systemVersion)];
 90    }
 91    if (!version) {
 92      // Fall back to the info in the Plist.
 93      NSDictionary *systemVersionPlist
 94        = [NSDictionary dictionaryWithContentsOfFile:kSystemVersionPlistPath];
 95      version = [systemVersionPlist objectForKey:@"ProductVersion"];
 96    }
 97    _GTMDevAssert(version, @"Unable to get version");
 98
 99    NSArray *versionInfo = [version componentsSeparatedByString:@"."];
100    NSUInteger length = [versionInfo count];
101    _GTMDevAssert(length > 1 && length < 4, 
102                  @"Unparseable version %@", version);
103    sGTMSystemVersionMajor = [[versionInfo objectAtIndex:0] intValue];
104    _GTMDevAssert(sGTMSystemVersionMajor != 0, 
105                  @"Unknown version for %@", version);
106    sGTMSystemVersionMinor = [[versionInfo objectAtIndex:1] intValue];
107    if (length == 3) {
108      sGTMSystemVersionBugFix = [[versionInfo objectAtIndex:2] intValue];
109    }
110    [pool release];
111#endif // GTM_MACOS_SDK
112  }
113}
114
115+ (void)getMajor:(SInt32*)major minor:(SInt32*)minor bugFix:(SInt32*)bugFix {
116  if (major) {
117    *major = sGTMSystemVersionMajor;
118  }
119  if (minor) {
120    *minor = sGTMSystemVersionMinor;
121  }
122  if (bugFix) {
123    *bugFix = sGTMSystemVersionBugFix;
124  }
125}
126
127+ (NSString*)build {
128  @synchronized(self) {
129    // Not cached at initialization time because we don't expect "real"
130    // software to want this, and it costs a bit to get at startup.
131    // This will mainly be for unit test cases.
132    if (!sBuild) {
133      NSDictionary *systemVersionPlist 
134        = [NSDictionary dictionaryWithContentsOfFile:kSystemVersionPlistPath];
135      sBuild = [[systemVersionPlist objectForKey:@"ProductBuildVersion"] retain];
136      _GTMDevAssert(sBuild, @"Unable to get build version");
137    }
138  }
139  return sBuild;
140}
141
142+ (BOOL)isBuildLessThan:(NSString*)build {
143  NSComparisonResult result 
144    = [[self build] compare:build 
145                    options:NSNumericSearch | NSCaseInsensitiveSearch];
146  return result == NSOrderedAscending;
147}
148  
149+ (BOOL)isBuildLessThanOrEqualTo:(NSString*)build {
150  NSComparisonResult result 
151    = [[self build] compare:build 
152                    options:NSNumericSearch | NSCaseInsensitiveSearch];
153  return result != NSOrderedDescending;
154}
155
156+ (BOOL)isBuildGreaterThan:(NSString*)build {
157  NSComparisonResult result 
158    = [[self build] compare:build 
159                    options:NSNumericSearch | NSCaseInsensitiveSearch];
160  return result == NSOrderedDescending;
161}
162
163+ (BOOL)isBuildGreaterThanOrEqualTo:(NSString*)build {
164  NSComparisonResult result 
165    = [[self build] compare:build 
166                    options:NSNumericSearch | NSCaseInsensitiveSearch];
167  return result != NSOrderedAscending;
168}
169
170+ (BOOL)isBuildEqualTo:(NSString *)build {
171  NSComparisonResult result 
172    = [[self build] compare:build 
173                    options:NSNumericSearch | NSCaseInsensitiveSearch];
174  return result == NSOrderedSame;
175}
176
177#if GTM_MACOS_SDK
178+ (BOOL)isPanther {
179#if defined(__MAC_10_4) && __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_4
180  return NO;
181#else
182  return sGTMSystemVersionMajor == 10 && sGTMSystemVersionMinor == 3;
183#endif
184}
185
186+ (BOOL)isTiger {
187#if defined(__MAC_10_5) && __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_5
188  return NO;
189#else
190  return sGTMSystemVersionMajor == 10 && sGTMSystemVersionMinor == 4;
191#endif
192}
193
194+ (BOOL)isLeopard {
195#if defined(__MAC_10_6) && __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_6
196  return NO;
197#else
198  return sGTMSystemVersionMajor == 10 && sGTMSystemVersionMinor == 5;
199#endif
200}
201
202+ (BOOL)isSnowLeopard {
203#if defined(__MAC_10_7) && __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_7
204  return NO;
205#else
206  return sGTMSystemVersionMajor == 10 && sGTMSystemVersionMinor == 6;
207#endif
208}
209
210+ (BOOL)isPantherOrGreater {
211#if defined(__MAC_10_3) && __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_3
212  return YES;
213#else
214  return (sGTMSystemVersionMajor > 10) ||
215          (sGTMSystemVersionMajor == 10 && sGTMSystemVersionMinor >= 3);
216#endif
217}
218
219+ (BOOL)isTigerOrGreater {
220#if defined(__MAC_10_4) && __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_4
221  return YES;
222#else
223  return (sGTMSystemVersionMajor > 10) ||
224          (sGTMSystemVersionMajor == 10 && sGTMSystemVersionMinor >= 4);
225#endif
226}
227
228+ (BOOL)isLeopardOrGreater {
229#if defined(__MAC_10_5) && __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_5
230  return YES;
231#else
232  return (sGTMSystemVersionMajor > 10) ||
233          (sGTMSystemVersionMajor == 10 && sGTMSystemVersionMinor >= 5);
234#endif
235}
236
237+ (BOOL)isSnowLeopardOrGreater {
238#if defined(__MAC_10_6) && __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_6
239  return YES;
240#else
241  return (sGTMSystemVersionMajor > 10) ||
242          (sGTMSystemVersionMajor == 10 && sGTMSystemVersionMinor >= 6);
243#endif
244}
245
246#endif // GTM_MACOS_SDK
247
248+ (NSString *)runtimeArchitecture {
249  NSString *architecture = nil;
250#if GTM_IPHONE_SDK
251  architecture = kGTMArch_iPhone;
252#else // !GTM_IPHONE_SDK
253  // In reading arch(3) you'd thing this would work:
254  //
255  // const NXArchInfo *localInfo = NXGetLocalArchInfo();
256  // _GTMDevAssert(localInfo && localInfo->name, @"Couldn't get NXArchInfo");
257  // const NXArchInfo *genericInfo = NXGetArchInfoFromCpuType(localInfo->cputype, 0);
258  // _GTMDevAssert(genericInfo && genericInfo->name, @"Couldn't get generic NXArchInfo");
259  // extensions[0] = [NSString stringWithFormat:@".%s", genericInfo->name];
260  //
261  // but on 64bit it returns the same things as on 32bit, so...
262#if __POWERPC__
263#if __LP64__
264  architecture = kGTMArch_ppc64;
265#else // !__LP64__
266  architecture = kGTMArch_ppc;
267#endif // __LP64__
268#else // !__POWERPC__
269#if __LP64__
270  architecture = kGTMArch_x86_64;
271#else // !__LP64__
272  architecture = kGTMArch_i386;
273#endif // __LP64__
274#endif // !__POWERPC__
275  
276#endif // GTM_IPHONE_SDK
277  return architecture;
278}  
279
280@end