home *** CD-ROM | disk | FTP | other *** search
- /*
- File: ODNewObj.cpp
-
- Contains: xxx put contents here xxx
-
- Owned by: Vincent Lo
-
- Copyright: © 1996 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <3> 1/23/96 VL 1170098: Put back the CFM loading code
- removed in the last checkin. The code was
- used for debugging and getting CFM errors.
- <2> 1/16/96 VL 1170098: Removed code for GetSharedLibrary.
-
- To Do:
- */
-
- /*
- File: ODNewObj.cpp
-
- Contains: Abstract wrapper for instantiating objects by class-name
-
- Owned by: Jens Alfke
-
- Copyright: © 1994 - 1995 by Apple Computer, Inc., all rights reserved.
-
- */
-
- #ifndef _ODMEMORY_
- #include "ODMemory.h"
- #endif
-
- #ifndef _ODNEWOBJ_
- #include "ODNewObj.h"
- #endif
-
- #ifndef _PLFMDEF_
- #include "PlfmDef.h"
- #endif
-
- #ifndef _EXCEPT_
- #include "Except.h"
- #endif
-
- #ifndef _ODDEBUG_
- #include "ODDebug.h"
- #endif
-
- #ifndef _ODUTILS_
- #include <ODUtils.h>
- #endif
-
- #ifndef _PASCLSTR_
- #include <PasclStr.h>
- #endif
-
- #ifndef _UTILERRS_
- #include "UtilErrs.h"
- #endif
-
- #ifndef __SOM__
- #include <som.xh>
- #endif
-
- #ifndef SOM_SOMClassMgr_xh
- #include <somcm.xh>
- #endif
-
-
- #ifdef _PLATFORM_MACINTOSH_
-
- #ifndef __STRINGS__
- #include <strings.h>
- #endif
-
- #include <CodeFragments.h>
-
- #define LOAD_UNDER_ASSUMED_NAME 1
- /* SOM requires that the library name (in the 'cfrg') be of the form "Module::ClassName".
- This obviously won't match the library's SYM file name. This causes problems for source
- level debuggers; they can't associate the two and you end up not being able to debug
- the library.
- To work around this, we give the library two names (two 'cfrg' entries), the second of
- which is just the classname. Then if the SYM file name matches the classname, we can first
- load the library by the classname, which will signal the debugger that it can link the
- library up with the similarly-named SYM file.
- Got that?? Off we go!!
- */
- #endif
-
- #ifndef _ODDEBUG_
- #include "ODDebug.h"
- #endif
-
-
- const ODSize kMinAppFreeSpace = 48 * 1024;
- const ODSize kMinAppContigSpace = 8 * 1024;
-
- static somTD_SOMError *gOld_SOMError;
-
-
- extern "C" {
- static void
- Temp_GetClass_SOMError( int error, corbastring filename, int linenum );
- }
-
-
- static void
- Temp_GetClass_SOMError( int error, corbastring filename, int linenum )
- {
- int severity = error % 10;
- if( severity == SOM_Fatal ) {
- WARN("Fatal SOM err %d caught during GetClass; throwing...",error);
- THROW(error);
- } else if( gOld_SOMError )
- gOld_SOMError(error,filename,linenum);
- }
-
-
- static SOMClass*
- GetClass( const char *className )
- {
- ODRequireFreeSpace(kMinAppFreeSpace,kMinAppContigSpace,kODTrue);
-
- char libname[64];
-
- #if LOAD_UNDER_ASSUMED_NAME
- // First grab everything after the last colon in className:
- const char *lastcolon = strrchr(className,':');
- if (lastcolon == nil) {
- // Hack to load Bento:
- if( strcmp(className,"ODFileContainer")==0 ||
- strcmp(className,"ODMemContainer")==0 ||
- strcmp(className,"ODEmbeddedContainer")==0 )
- strcpy(libname, "OpenDoc Bento");
- else
- strcpy(libname, className);
- }
- else {
- strncpy(libname,lastcolon+1,sizeof(libname)-1);
- libname[sizeof(libname)-1] = '\0';
- }
- #else
- strcpy(libname,className);
- #endif /*LOAD_UNDER_ASSUMED_NAME*/
-
- c2pstr(libname);
-
- CFragConnectionID connID;
- Ptr mainAddr;
- Str255 errName;
- ODBoolean unloadLib = kODFalse;
-
- // First see if the library is already loaded:
- OSErr err = GetSharedLibrary((StringPtr)libname, kCurrentCFragArch,
- kFindCFrag, &connID,&mainAddr,errName);
-
- if( err == fragLibNotFound || err==fragLibConnErr ) {
- // Nope, need to load it:
- err = GetSharedLibrary((StringPtr)libname, kCurrentCFragArch,
- kLoadCFrag, &connID,&mainAddr,errName);
- if( err==noErr && !ODHaveFreeSpace(kMinAppFreeSpace,
- kMinAppContigSpace,kODTrue) ) {
- CloseConnection(&connID);
- err = fragNoMem;
- #if ODDebug
- CopyPascalString(errName,"\pOD free space too low");
- #endif
- }
- else
- unloadLib = kODTrue;
- }
-
- if( err ) {
- p2cstr(errName);
- WARN("Can't load lib '%s'; error %hd, '%s'",
- p2cstr((StringPtr)libname),err,errName);
- THROW(err,(char*)errName);
- }
-
- /* Now try to load the class. Install a temporary error handler that
- converts a fatal SOM error into a THROW, in case SOM runs out of
- memory. */
- SOMClass *c;
- gOld_SOMError = SOMError;
- SOMError = &Temp_GetClass_SOMError;
- TRY{
- long majorVersion = 0;
- long minorVersion = 0;
- somId id = somIdFromString((corbastring)className);
- c = somGetDynamicClassReference(id,majorVersion,minorVersion, kODNULL);
- SOMFree(id);
- if (unloadLib)
- {
- unloadLib = kODFalse;
- CloseConnection(&connID);
- }
- }CATCH_ALL{
- if (unloadLib)
- CloseConnection(&connID);
- SOMError = gOld_SOMError;
- RERAISE;
- }ENDTRY
- SOMError = gOld_SOMError;
-
-
- if( !c )
- THROW(kODErrCantLoadSOMClass);
- return c;
- }
-
-
- SOMObject*
- ODNewObject( const char *className )
- {
- SOMClass *cls = GetClass(className);
- THROW_IF_NULL (cls); // would have thrown anyway...
- SOMObject* obj = cls->somNew();
- somReleaseClassReference(cls); // must release class reference
- THROW_IF_NULL (obj); // similar to new ODObject, must throw if nil
- return obj;
- }
-
-
- ODBoolean
- ODClassExists( const char *className )
- {
- /* This function will now propagate errors if the library _does_ exist
- but just couldn't be loaded due to e.g. insufficient memory or missing
- imports. This allows for better error display to the user since otherwise
- the error would be eaten and replaced with a simple Boolean return value. */
-
- ODBoolean result = kODTrue;
- TRY
- SOMClass *cls = GetClass(className);
- somReleaseClassReference ( cls );
- CATCH_ALL
- if( ErrorCode()==kODErrCantLoadSOMClass || ErrorCode()==fragLibNotFound )
- result = kODFalse;
- else
- RERAISE;
- ENDTRY
- return result;
- }
-