/* * ETMachineInfo_PlatformIndependent.m - platform indepenent for ETMachineInfo * * Copyright 2006, David Chisnall * 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. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 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. */ #import "ETMachineInfo.h" #import #import #import #import // Ordered array of SI unit prefixes static const char *UnitPrefixes = "kMGTPEZY"; static inline int my_round (double value) { return (int) (value + 0.5); } /** * Reformats a number and returns a string with SI unit suffixes * as necessary. * * @param value The value which to reformat * @param unitScale Defines the size of the unit between two unit skips. * For example, for bytes, this is 1024 (1024B = 1kB, 1024kB = 1MB, ...), * and frequencies it is 1000 (1000Hz = 1kHz, 1000kHz = 1MHz, ...). * @param unit The unit name which to append to the reformatted number, * e.g. @"Hz" or @"B". * @param maxRoundedPrefix An index into the UnitPrefixes array which * defines which of the units (at most) to round. For example for * an input value which lies in the 'M' (mega) unit scale, which * is index '1' in the array, if this argument is greater than or * equal to one, the resulting number will be rounded to the nearest * integer. Otherwise it would have been a real-number representation. * This is useful for rounding memory sizes up to the MB scale, * but representing them with real-numbers in scales higher than that. */ static NSString * humanReadableNumber (double value, unsigned int unitScale, NSString *unit, int maxRoundedPrefix) { int prefix = -1; // Divide by the size of a prefix interval until we have a value // smaller than the prefix interval while (value >= unitScale) { value /= unitScale; prefix++; } if (prefix <= maxRoundedPrefix) { if (prefix >= 0) { return [NSString stringWithFormat:@"%d%c%@", my_round (value), UnitPrefixes[prefix], unit]; } else { return [NSString stringWithFormat:@"%d%@", my_round (value), unit]; } } else { if (prefix >= 0) { return [NSString stringWithFormat:@"%#3.2f%c%@", value, UnitPrefixes[prefix], unit]; } else { return [NSString stringWithFormat:@"%#3.2f%@", value, unit]; } } } @implementation ETMachineInfo /** * Returns the real memory size in bytes. */ + (unsigned long long) realMemory { return 0; } /** * Returns the CPU speed in MHz. */ + (unsigned int) cpuMHzSpeed { return 0; } /** * Returns the plain CPU name as known to the operating system. */ + (NSString *) cpuName { return nil; } /** * Returns whether the current platform is supported. This is used * by other routines inside ETMachineInfo to determine whether to * return strings like "(unknown)". The default class implementation * always returns NO. */ + (BOOL) platformSupported { return NO; } /** * Retrurns a reformatted real memory size. */ + (NSString *) humanReadableRealMemory { if ([self platformSupported]) { return humanReadableNumber ((double) [self realMemory], 1024, @"B", 1); } else { return _(@"(unknown)"); } } /** * Returns a reformatted CPU MHz speed. */ + (NSString *) humanReadableCPUSpeed { if ([self platformSupported]) { // Reformat the MHz speed return humanReadableNumber ((double) [self cpuMHzSpeed] * 1000000, 1000, @"Hz", 1); } else { return _(@"(unknown)"); } } /** * Returns the CPU name with the following modifications: * * - '(R)' sequences are removed * - '(TM)' sequences are removed * - 'processor' sequences are removed * - converts a tab character to a single space * - if a 'CPU' word is found, it is stripped and anything that follows it. * - sequences of spaces are reduced to a single space * * @return The cleaned CPU name. */ + (NSString *) tidyCPUName { if ([self platformSupported]) { NSMutableString *name = [NSMutableString stringWithString: [self cpuName]]; NSRange cpuStringRange; [name replaceOccurrencesOfString: @"(R)" withString: @"" options: NSCaseInsensitiveSearch range: NSMakeRange (0, [name length])]; [name replaceOccurrencesOfString: @"(TM)" withString: @"" options: NSCaseInsensitiveSearch range: NSMakeRange (0, [name length])]; [name replaceOccurrencesOfString: @"processor" withString: @"" options: NSCaseInsensitiveSearch range: NSMakeRange (0, [name length])]; [name replaceString: @"\t" withString: @" "]; cpuStringRange = [name rangeOfString: @"CPU"]; if (cpuStringRange.location != NSNotFound) { [name deleteCharactersInRange: NSMakeRange (cpuStringRange.location, [name length] - cpuStringRange.location)]; } int i, n; for (i = 0, n = [name length]; i < n; i++) { unichar c = [name characterAtIndex: i]; if (c == ' ' && i < n - 1 && [name characterAtIndex: i + 1] == ' ') { [name deleteCharactersInRange: NSMakeRange (i, 1)]; i--; n--; } } return name; } else { return _(@"(unknown)"); } } /** * Returns the operating system's name. */ + (NSString *) operatingSystem { struct utsname buf; uname (&buf); return [NSString stringWithUTF8String: buf.sysname]; } /** * Returns the operating system version. */ + (NSString *) operatingSystemVersion { struct utsname buf; uname (&buf); return [NSString stringWithUTF8String: buf.release]; } /** * Returns the host on which we are running. */ + (NSString *) hostName { struct utsname buf; NSString *hostname; NSArray *components; uname (&buf); hostname = [NSString stringWithUTF8String: buf.nodename]; components = [hostname componentsSeparatedByString: @"."]; return [components objectAtIndex:0]; } /** * Returns the machine type we are running on. */ + (NSString *) machineType { struct utsname buf; uname (&buf); return [NSString stringWithUTF8String: buf.machine]; } @end