/*============================================================================= CAComponent.cpp $Log: CAComponent.cpp,v $ Revision 1.13.2.1 2005/04/21 21:25:35 dwyatt CA_Tiger branch wasn't laid down in the right place for a few files Revision 1.17 2005/03/13 19:50:29 bills comp names should be parsed as Mac Roman! Revision 1.16 2005/03/13 19:48:25 bills comp names should be parsed as Mac Roman Revision 1.15 2005/03/13 19:40:24 bills fix chance of memory leak Revision 1.14 2005/03/13 19:39:04 bills slightly better if test Revision 1.13 2004/12/10 22:21:19 bills slight tweak to GetResourceVersion Revision 1.12 2004/09/28 23:15:09 jcm10 add missing include Revision 1.11 2004/07/08 17:50:41 bills tweaks to compdesc constructor Revision 1.10 2004/04/21 20:08:34 bills better variable name Revision 1.9 2003/10/01 08:08:52 bills clean up printing Revision 1.8 2003/09/02 23:31:09 bills tweak error handling Revision 1.7 2003/08/09 01:01:09 bills check res version details Revision 1.6 2003/07/05 20:13:26 bills add a constructor Revision 1.5 2003/06/30 21:52:49 bills fix comp name handling Revision 1.4 2003/06/15 23:58:15 bills fix (Component) const Revision 1.3 2003/03/12 05:05:05 bills refactor persistence Revision 1.2 2003/03/11 20:57:29 bills first pass at save/restore state Revision 1.1 2003/03/11 00:38:21 bills initial checkin Created by William Stewart on Sat Mar 08 2003. Copyright (c) 2003 __MyCompanyName__. All rights reserved. =============================================================================*/ #include "CAComponent.h" #include "CAComponentDescription.h" #include "CACFDictionary.h" #include CAComponent::CAComponent (const ComponentDescription& inDesc, CAComponent* next) : mManuName(0), mAUName(0), mCompName(0), mCompInfo (0) { mComp = FindNextComponent ((next ? next->Comp() : NULL), const_cast(&inDesc)); if (mComp) GetComponentInfo (Comp(), &mDesc, NULL, NULL, NULL); else memcpy (&mDesc, &inDesc, sizeof(ComponentDescription)); } CAComponent::CAComponent (const Component& comp) : mComp (comp), mManuName(0), mAUName(0), mCompName(0), mCompInfo (0) { GetComponentInfo (Comp(), &mDesc, NULL, NULL, NULL); } CAComponent::CAComponent (const ComponentInstance& compInst) : mComp (Component(compInst)), mManuName(0), mAUName(0), mCompName(0), mCompInfo (0) { GetComponentInfo (Comp(), &mDesc, NULL, NULL, NULL); } CAComponent::CAComponent (OSType inType, OSType inSubtype, OSType inManu) : mDesc (inType, inSubtype, inManu), mManuName(0), mAUName(0), mCompName(0), mCompInfo (0) { mComp = FindNextComponent (NULL, &mDesc); GetComponentInfo (Comp(), &mDesc, NULL, NULL, NULL); } CAComponent::~CAComponent () { Clear(); } OSStatus CAComponent::GetResourceVersion (UInt32 &outVersion) const { bool versionFound = false; short componentResFileID = kResFileNotOpened; OSStatus result; short thngResourceCount; short curRes = CurResFile(); require_noerr (result = OpenAComponentResFile( mComp, &componentResFileID), home); require_noerr (result = componentResFileID <= 0, home); UseResFile(componentResFileID); thngResourceCount = Count1Resources(kComponentResourceType); require_noerr (result = ResError(), home); // only go on if we successfully found at least 1 thng resource require_noerr (thngResourceCount <= 0 ? -1 : 0, home); // loop through all of the Component thng resources trying to // find one that matches this Component description for (short i = 0; i < thngResourceCount && (!versionFound); i++) { // try to get a handle to this code resource Handle thngResourceHandle = Get1IndResource(kComponentResourceType, i+1); if (thngResourceHandle != NULL && ((*thngResourceHandle) != NULL)) { if (UInt32(GetHandleSize(thngResourceHandle)) >= sizeof(ExtComponentResource)) { ExtComponentResource * componentThng = (ExtComponentResource*) (*thngResourceHandle); // check to see if this is the thng resource for the particular Component that we are looking at // (there often is more than one Component described in the resource) if ((componentThng->cd.componentType == mDesc.Type()) && (componentThng->cd.componentSubType == mDesc.SubType()) && (componentThng->cd.componentManufacturer == mDesc.Manu())) { outVersion = componentThng->componentVersion; versionFound = true; } } ReleaseResource(thngResourceHandle); } } if (!versionFound) result = resNotFound; UseResFile(curRes); // revert if ( componentResFileID != kResFileNotOpened ) CloseComponentResFile(componentResFileID); home: return result; } void CAComponent::Clear () { if (mManuName) { CFRelease (mManuName); mManuName = 0; } if (mAUName) { CFRelease (mAUName); mAUName = 0; } if (mCompName) { CFRelease (mCompName); mCompName = 0; } if (mCompInfo) { CFRelease (mCompInfo); mCompInfo = 0; } } CAComponent& CAComponent::operator= (const CAComponent& y) { Clear(); mComp = y.mComp; mDesc = y.mDesc; if (y.mManuName) { mManuName = y.mManuName; CFRetain (mManuName); } if (y.mAUName) { mAUName = y.mAUName; CFRetain (mAUName); } if (y.mCompName) { mCompName = y.mCompName; CFRetain (mCompName); } if (y.mCompInfo) { mCompInfo = y.mCompInfo; CFRetain (mCompInfo); } return *this; } void CAComponent::SetCompNames () const { if (!mCompName) { Handle h1 = NewHandle(4); CAComponentDescription desc; OSStatus err = GetComponentInfo (Comp(), &desc, h1, 0, 0); if (err) { DisposeHandle(h1); return; } HLock(h1); char* ptr1 = *h1; // Get the manufacturer's name... look for the ':' character convention int len = *ptr1++; char* displayStr = 0; const_cast(this)->mCompName = CFStringCreateWithPascalString(NULL, (const unsigned char*)*h1, kCFStringEncodingMacRoman); for (int i = 0; i < len; ++i) { if (ptr1[i] == ':') { // found the name ptr1[i] = 0; displayStr = ptr1; break; } } if (displayStr) { const_cast(this)->mManuName = CFStringCreateWithCString(NULL, displayStr, kCFStringEncodingMacRoman); //move displayStr ptr past the manu, to the name // we move the characters down a index, because the handle doesn't have any room // at the end for the \0 int i = strlen(displayStr), j = 0; while (displayStr[++i] == ' ' && i < len) ; while (i < len) displayStr[j++] = displayStr[i++]; displayStr[j] = 0; const_cast(this)->mAUName = CFStringCreateWithCString(NULL, displayStr, kCFStringEncodingMacRoman); } DisposeHandle (h1); } } void CAComponent::SetCompInfo () const { if (!mCompInfo) { Handle h1 = NewHandle(4); CAComponentDescription desc; OSStatus err = GetComponentInfo (Comp(), &desc, 0, h1, 0); if (err) return; HLock (h1); const_cast(this)->mCompInfo = CFStringCreateWithPascalString(NULL, (const unsigned char*)*h1, kCFStringEncodingMacRoman); DisposeHandle (h1); } } void _ShowCF (FILE* file, CFStringRef str) { if (CFGetTypeID(str) != CFStringGetTypeID()) { CFShow(str); return; } UInt32 len = CFStringGetLength(str); char* chars = (char*)malloc (len * 2); // give us plenty of room for unichar chars if (CFStringGetCString (str, chars, len * 2, kCFStringEncodingUTF8)) fprintf (file, "%s", chars); else CFShow (str); free (chars); } void CAComponent::Print(FILE* file) const { fprintf (file, "CAComponent: 0x%X", int(Comp())); if (mManuName) { fprintf (file, ", Manu:"); _ShowCF (file, mManuName); if (mAUName) fprintf (file, ", Name:"); _ShowCF (file, mAUName); } fprintf (file, ", "); Desc ().Print(file); }