// // TKEndianUtilities.m // ThemeKit // // Created by Colin Cornaby on 11/4/06. // Copyright 2006 __MyCompanyName__. All rights reserved. // // 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.1 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 // Lesser 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 02110-1301 USA #import "TKEndianUtilities.h" //This function will resolve an endinanness given to it //to the current platform. For example, passing it kNativeEndian //on the Intel platform will return kLittleEndian. TKEndianness resolveEndianness(TKEndianness endianness) { if (endianness==kNativeEndian) { #ifdef __BIG_ENDIAN__ return kBigEndian; #endif #ifdef __LITTLE_ENDIAN__ return kLittleEndian; #endif } return endianness; } unsigned short swapShort(short x, TKEndianness fromPlatform, TKEndianness toPlatform) { if(resolveEndianness(fromPlatform)==resolveEndianness(toPlatform)) return x; if(toPlatform==kNativeEndian){ if(fromPlatform == kBigEndian) return NSSwapBigShortToHost(x); if(fromPlatform == kLittleEndian) return NSSwapLittleShortToHost(x); } if(toPlatform==kBigEndian){ if(fromPlatform == kBigEndian) return (x); if(fromPlatform == kLittleEndian) return NSSwapShort(x); } if(toPlatform==kLittleEndian){ if(fromPlatform == kBigEndian) return NSSwapShort(x); if(fromPlatform == kLittleEndian) return x; } return -1; } //The following is an slightly edited version of Jason Harris's code //for dealing with Endn resources //http://www.geekspiff.com/themeEndianness/ ThemeDataError ThemeDataFormatForResourceFile(SInt16 inRefNum, TKEndianness *outFormat) { SInt16 oldRefNum; Handle theResource; ThemeDataError result = kThemeDataNoError; if ( -1 == inRefNum || ! outFormat ) return kThemeDataBadParameter; oldRefNum = CurResFile(); UseResFile(inRefNum); theResource = Get1Resource('Endn', 128); if ( theResource ) { HLock(theResource); ThemeEndianness *endn = (ThemeEndianness *)*theResource; endn->version = CFSwapInt32BigToHost(endn->version); endn->isLittleEndian = CFSwapInt32BigToHost(endn->isLittleEndian); if ( 0 == endn->version ) { if ( endn->isLittleEndian ) *outFormat = kLittleEndian; else *outFormat = kBigEndian; } else { *outFormat = kUnknownEndian; result = kThemeDataBadResource; } ReleaseResource(theResource); } else *outFormat = kBigEndian; UseResFile(oldRefNum); return result; } ThemeDataError SetThemeDataFormatForResourceFile(SInt16 inRefNum, TKEndianness inFormat) { SInt16 oldRefNum; Handle endnHandle, newResource = NULL; ThemeDataError result = kThemeDataUnexpectedError; if ( -1 == inRefNum || kUnknownEndian == inFormat ) return kThemeDataBadParameter; inFormat = resolveEndianness(inFormat); oldRefNum = CurResFile(); UseResFile(inRefNum); endnHandle = NewHandle(sizeof(ThemeEndianness)); if ( ! endnHandle ) goto DONE; HLock(endnHandle); ThemeEndianness *endn = (ThemeEndianness *)*endnHandle; endn->version = CFSwapInt32HostToBig(0); endn->isLittleEndian = CFSwapInt32HostToBig((kLittleEndian == inFormat) ? 1 : 0); // if this resource is already in the file, delete it SetResLoad(false); result = kThemeDataBadResource; Handle oldResource = Get1Resource('Endn', 128); if ( oldResource ) { RemoveResource(oldResource); if ( noErr != ResError() ) goto DONE; DisposeHandle(oldResource); } SetResLoad(true); // add in the new resource data AddResource( endnHandle, 'Endn', 128, "\p" ); if( noErr != ResError() ) goto DONE; newResource = endnHandle; endnHandle = NULL; ChangedResource(newResource); if( noErr != ResError() ) goto DONE; WriteResource(newResource); if( noErr != ResError() ) goto DONE; result = kThemeDataNoError; DONE: if ( endnHandle ) DisposeHandle(endnHandle); if ( newResource ) ReleaseResource(newResource); UseResFile(oldRefNum); return result; }