/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in * compliance with the NPL. You may obtain a copy of the NPL at * http://www.mozilla.org/NPL/ * * Software distributed under the NPL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL * for the specific language governing rights and limitations under the * NPL. * * The Initial Developer of this code under the NPL is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All Rights * Reserved. */ /* nsDll * * Abstraction of a Dll. Stores modifiedTime and size for easy detection of * change in dll. * * dp Suresh */ #include "xcDll.h" #include "plstr.h" // strdup and strfree nsDll::nsDll(const char *libFullPath) : m_fullpath(NULL), m_instance(NULL), m_status(DLL_OK) { m_lastModTime = LL_ZERO; m_size = 0; if (libFullPath == NULL) { m_status = DLL_INVALID_PARAM; return; } m_fullpath = PL_strdup(libFullPath); if (m_fullpath == NULL) { // No more memory m_status = DLL_NO_MEM; return; } PRFileInfo statinfo; if (PR_GetFileInfo(m_fullpath, &statinfo) != PR_SUCCESS) { // The stat things works only if people pass in the full pathname. // Even if our stat fails, we could be able to load it because of // LD_LIBRARY_PATH and other such paths where dlls are searched for // XXX we need a way of marking this occurance. // XXX m_status = DLL_STAT_ERROR; } else { m_size = statinfo.size; m_lastModTime = statinfo.modifyTime; if (statinfo.type != PR_FILE_FILE) { // Not a file. Cant work with it. m_status = DLL_NOT_FILE; return; } } m_status = DLL_OK; } nsDll::nsDll(const char *libFullPath, PRTime lastModTime, PRUint32 fileSize) : m_fullpath(NULL), m_instance(NULL), m_status(DLL_OK) { m_lastModTime = lastModTime; m_size = fileSize; if (libFullPath == NULL) { m_status = DLL_INVALID_PARAM; return; } m_fullpath = PL_strdup(libFullPath); if (m_fullpath == NULL) { // No more memory m_status = DLL_NO_MEM; return; } m_status = DLL_OK; } nsDll::~nsDll(void) { if (m_instance != NULL) Unload(); if (m_fullpath != NULL) PL_strfree(m_fullpath); m_fullpath = NULL; } PRBool nsDll::Load(void) { if (m_status != DLL_OK) { return (PR_FALSE); } if (m_instance != NULL) { // Already loaded return (PR_TRUE); } #ifdef XP_MAC // err = ConvertUnixPathToMacPath(m_fullpath, &macFileName); char *macFileName = PL_strdup(m_fullpath); if (macFileName != NULL) { if (macFileName[0] == '/') { // convert '/' to ':' int c; char* str = macFileName; while ((c = *str++) != 0) { if (c == '/') str[-1] = ':'; } m_instance = PR_LoadLibrary(&macFileName[1]); // skip over initial slash } else { m_instance = PR_LoadLibrary(macFileName); } PL_strfree(macFileName); } #else // This is the only right way of doing this... m_instance = PR_LoadLibrary(m_fullpath); #endif /* XP_MAC */ return ((m_instance == NULL) ? PR_FALSE : PR_TRUE); } PRBool nsDll::Unload(void) { if (m_status != DLL_OK || m_instance == NULL) return (PR_FALSE); PRStatus ret = PR_UnloadLibrary(m_instance); if (ret == PR_SUCCESS) { m_instance = NULL; return (PR_TRUE); } else return (PR_FALSE); } void * nsDll::FindSymbol(const char *symbol) { if (symbol == NULL) return (NULL); // If not already loaded, load it now. if (Load() != PR_TRUE) return (NULL); return (PR_FindSymbol(m_instance, symbol)); }