/MapView/GTM/GTMSystemVersion.m

http://github.com/route-me/route-me · Objective C · 228 lines · 162 code · 28 blank · 38 comment · 39 complexity · 52f4c5b49edb8987218238a394df9ff0 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. #import "GTMSystemVersion.h"
  19. #import "GTMGarbageCollection.h"
  20. #if GTM_MACOS_SDK
  21. #import <CoreServices/CoreServices.h>
  22. #endif
  23. static SInt32 sGTMSystemVersionMajor = 0;
  24. static SInt32 sGTMSystemVersionMinor = 0;
  25. static SInt32 sGTMSystemVersionBugFix = 0;
  26. static NSString *sBuild = nil;
  27. NSString *const kGTMArch_iPhone = @"iPhone";
  28. NSString *const kGTMArch_ppc = @"ppc";
  29. NSString *const kGTMArch_ppc64 = @"ppc64";
  30. NSString *const kGTMArch_x86_64 = @"x86_64";
  31. NSString *const kGTMArch_i386 = @"i386";
  32. static NSString *const kSystemVersionPlistPath = @"/System/Library/CoreServices/SystemVersion.plist";
  33. @implementation GTMSystemVersion
  34. + (void)initialize {
  35. if (self == [GTMSystemVersion class]) {
  36. // Gestalt is the recommended way of getting the OS version (despite a
  37. // comment to the contrary in the 10.4 headers and docs; see
  38. // <http://lists.apple.com/archives/carbon-dev/2007/Aug/msg00089.html>).
  39. // The iPhone doesn't have Gestalt though, so use the plist there.
  40. #if GTM_MACOS_SDK
  41. require_noerr(Gestalt(gestaltSystemVersionMajor, &sGTMSystemVersionMajor), failedGestalt);
  42. require_noerr(Gestalt(gestaltSystemVersionMinor, &sGTMSystemVersionMinor), failedGestalt);
  43. require_noerr(Gestalt(gestaltSystemVersionBugFix, &sGTMSystemVersionBugFix), failedGestalt);
  44. return;
  45. failedGestalt:
  46. ;
  47. #if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_3
  48. // gestaltSystemVersionMajor et al are only on 10.4 and above, so they
  49. // could fail when running on 10.3.
  50. SInt32 binaryCodedDec;
  51. OSStatus err = err = Gestalt(gestaltSystemVersion, &binaryCodedDec);
  52. _GTMDevAssert(!err, @"Unable to get version from Gestalt");
  53. // Note that this code will return x.9.9 for any system rev parts that are
  54. // greater than 9 (i.e., 10.10.10 will be 10.9.9). This shouldn't ever be a
  55. // problem as the code above takes care of 10.4+.
  56. SInt32 msb = (binaryCodedDec & 0x0000F000L) >> 12;
  57. msb *= 10;
  58. SInt32 lsb = (binaryCodedDec & 0x00000F00L) >> 8;
  59. sGTMSystemVersionMajor = msb + lsb;
  60. sGTMSystemVersionMinor = (binaryCodedDec & 0x000000F0L) >> 4;
  61. sGTMSystemVersionBugFix = (binaryCodedDec & 0x0000000FL);
  62. #endif // MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_3
  63. #else // GTM_MACOS_SDK
  64. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  65. NSDictionary *systemVersionPlist
  66. = [NSDictionary dictionaryWithContentsOfFile:kSystemVersionPlistPath];
  67. NSString *version = [systemVersionPlist objectForKey:@"ProductVersion"];
  68. _GTMDevAssert(version, @"Unable to get version");
  69. NSArray *versionInfo = [version componentsSeparatedByString:@"."];
  70. NSUInteger length = [versionInfo count];
  71. _GTMDevAssert(length > 1 && length < 4,
  72. @"Unparseable version %@", version);
  73. sGTMSystemVersionMajor = [[versionInfo objectAtIndex:0] intValue];
  74. _GTMDevAssert(sGTMSystemVersionMajor != 0,
  75. @"Unknown version for %@", version);
  76. sGTMSystemVersionMinor = [[versionInfo objectAtIndex:1] intValue];
  77. if (length == 3) {
  78. sGTMSystemVersionBugFix = [[versionInfo objectAtIndex:2] intValue];
  79. }
  80. [pool release];
  81. #endif // GTM_MACOS_SDK
  82. }
  83. }
  84. + (void)getMajor:(SInt32*)major minor:(SInt32*)minor bugFix:(SInt32*)bugFix {
  85. if (major) {
  86. *major = sGTMSystemVersionMajor;
  87. }
  88. if (minor) {
  89. *minor = sGTMSystemVersionMinor;
  90. }
  91. if (bugFix) {
  92. *bugFix = sGTMSystemVersionBugFix;
  93. }
  94. }
  95. + (NSString*)build {
  96. @synchronized(self) {
  97. // Not cached at initialization time because we don't expect "real"
  98. // software to want this, and it costs a bit to get at startup.
  99. // This will mainly be for unit test cases.
  100. if (!sBuild) {
  101. NSDictionary *systemVersionPlist
  102. = [NSDictionary dictionaryWithContentsOfFile:kSystemVersionPlistPath];
  103. sBuild = [[systemVersionPlist objectForKey:@"ProductBuildVersion"] retain];
  104. GTMNSMakeUncollectable(sBuild);
  105. _GTMDevAssert(sBuild, @"Unable to get build version");
  106. }
  107. }
  108. return sBuild;
  109. }
  110. + (BOOL)isBuildLessThan:(NSString*)build {
  111. NSComparisonResult result
  112. = [[self build] compare:build
  113. options:NSNumericSearch | NSCaseInsensitiveSearch];
  114. return result == NSOrderedAscending;
  115. }
  116. + (BOOL)isBuildLessThanOrEqualTo:(NSString*)build {
  117. NSComparisonResult result
  118. = [[self build] compare:build
  119. options:NSNumericSearch | NSCaseInsensitiveSearch];
  120. return result != NSOrderedDescending;
  121. }
  122. + (BOOL)isBuildGreaterThan:(NSString*)build {
  123. NSComparisonResult result
  124. = [[self build] compare:build
  125. options:NSNumericSearch | NSCaseInsensitiveSearch];
  126. return result == NSOrderedDescending;
  127. }
  128. + (BOOL)isBuildGreaterThanOrEqualTo:(NSString*)build {
  129. NSComparisonResult result
  130. = [[self build] compare:build
  131. options:NSNumericSearch | NSCaseInsensitiveSearch];
  132. return result != NSOrderedAscending;
  133. }
  134. + (BOOL)isBuildEqualTo:(NSString *)build {
  135. NSComparisonResult result
  136. = [[self build] compare:build
  137. options:NSNumericSearch | NSCaseInsensitiveSearch];
  138. return result == NSOrderedSame;
  139. }
  140. #if GTM_MACOS_SDK
  141. + (BOOL)isPanther {
  142. return sGTMSystemVersionMajor == 10 && sGTMSystemVersionMinor == 3;
  143. }
  144. + (BOOL)isTiger {
  145. return sGTMSystemVersionMajor == 10 && sGTMSystemVersionMinor == 4;
  146. }
  147. + (BOOL)isLeopard {
  148. return sGTMSystemVersionMajor == 10 && sGTMSystemVersionMinor == 5;
  149. }
  150. + (BOOL)isSnowLeopard {
  151. return sGTMSystemVersionMajor == 10 && sGTMSystemVersionMinor == 6;
  152. }
  153. + (BOOL)isPantherOrGreater {
  154. return (sGTMSystemVersionMajor > 10) ||
  155. (sGTMSystemVersionMajor == 10 && sGTMSystemVersionMinor >= 3);
  156. }
  157. + (BOOL)isTigerOrGreater {
  158. return (sGTMSystemVersionMajor > 10) ||
  159. (sGTMSystemVersionMajor == 10 && sGTMSystemVersionMinor >= 4);
  160. }
  161. + (BOOL)isLeopardOrGreater {
  162. return (sGTMSystemVersionMajor > 10) ||
  163. (sGTMSystemVersionMajor == 10 && sGTMSystemVersionMinor >= 5);
  164. }
  165. + (BOOL)isSnowLeopardOrGreater {
  166. return (sGTMSystemVersionMajor > 10) ||
  167. (sGTMSystemVersionMajor == 10 && sGTMSystemVersionMinor >= 6);
  168. }
  169. #endif // GTM_MACOS_SDK
  170. + (NSString *)runtimeArchitecture {
  171. NSString *architecture = nil;
  172. #if GTM_IPHONE_SDK
  173. architecture = kGTMArch_iPhone;
  174. #else // !GTM_IPHONE_SDK
  175. // In reading arch(3) you'd thing this would work:
  176. //
  177. // const NXArchInfo *localInfo = NXGetLocalArchInfo();
  178. // _GTMDevAssert(localInfo && localInfo->name, @"Couldn't get NXArchInfo");
  179. // const NXArchInfo *genericInfo = NXGetArchInfoFromCpuType(localInfo->cputype, 0);
  180. // _GTMDevAssert(genericInfo && genericInfo->name, @"Couldn't get generic NXArchInfo");
  181. // extensions[0] = [NSString stringWithFormat:@".%s", genericInfo->name];
  182. //
  183. // but on 64bit it returns the same things as on 32bit, so...
  184. #if __POWERPC__
  185. #if __LP64__
  186. architecture = kGTMArch_ppc64;
  187. #else // !__LP64__
  188. architecture = kGTMArch_ppc;
  189. #endif // __LP64__
  190. #else // !__POWERPC__
  191. #if __LP64__
  192. architecture = kGTMArch_x86_64;
  193. #else // !__LP64__
  194. architecture = kGTMArch_i386;
  195. #endif // __LP64__
  196. #endif // !__POWERPC__
  197. #endif // GTM_IPHONE_SDK
  198. return architecture;
  199. }
  200. @end