1 /*
   2  * Copyright (c) 2014, 2015, Oracle and/or its affiliates.
   3  * All rights reserved. Use is subject to license terms.
   4  *
   5  * This file is available and licensed under the following license:
   6  *
   7  * Redistribution and use in source and binary forms, with or without
   8  * modification, are permitted provided that the following conditions
   9  * are met:
  10  *
  11  *  - Redistributions of source code must retain the above copyright
  12  *    notice, this list of conditions and the following disclaimer.
  13  *  - Redistributions in binary form must reproduce the above copyright
  14  *    notice, this list of conditions and the following disclaimer in
  15  *    the documentation and/or other materials provided with the distribution.
  16  *  - Neither the name of Oracle Corporation nor the names of its
  17  *    contributors may be used to endorse or promote products derived
  18  *    from this software without specific prior written permission.
  19  *
  20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31  */
  32 
  33 
  34 #include "Platform.h"
  35 #include "Lock.h"
  36 #include "Messages.h"
  37 
  38 #include "WindowsPlatform.h"
  39 #include "LinuxPlatform.h"
  40 #include "MacPlatform.h"
  41 
  42 
  43 //--------------------------------------------------------------------------------------------------
  44 
  45 Platform& Platform::GetInstance() {
  46     //Lock lock(true);
  47 #ifdef WINDOWS
  48     static WindowsPlatform instance;
  49 #endif // WINDOWS
  50 #ifdef LINUX
  51     static LinuxPlatform instance;
  52 #endif // LINUX
  53 #ifdef MAC
  54     static MacPlatform instance;
  55 #endif // MAC
  56     return instance;
  57 }
  58 
  59 //--------------------------------------------------------------------------------------------------
  60 
  61 
  62 Library::Library() {
  63     Initialize();
  64 }
  65 
  66 Library::Library(const TString &FileName) {
  67     Initialize();
  68     Load(FileName);
  69 }
  70 
  71 Library::~Library() {
  72     Unload();
  73 }
  74 
  75 void Library::Initialize() {
  76     FModule = NULL;
  77     FDependentLibraryNames = NULL;
  78     FDependenciesLibraries = NULL;
  79 }
  80 
  81 void Library::InitializeDependencies() {
  82     if (FDependentLibraryNames == NULL) {
  83         FDependentLibraryNames = new std::vector<TString>();
  84     }
  85 
  86     if (FDependenciesLibraries == NULL) {
  87         FDependenciesLibraries = new std::vector<Library*>();
  88     }
  89 }
  90 
  91 void Library::LoadDependencies() {
  92     if (FDependentLibraryNames != NULL && FDependenciesLibraries != NULL) {
  93         for (std::vector<TString>::const_iterator iterator = FDependentLibraryNames->begin();
  94                 iterator != FDependentLibraryNames->end(); iterator++) {
  95             Library* library = new Library();
  96 
  97             if (library->Load(*iterator) == true) {
  98                 FDependenciesLibraries->push_back(library);
  99             }
 100         }
 101 
 102         delete FDependentLibraryNames;
 103         FDependentLibraryNames = NULL;
 104     }
 105 }
 106 
 107 void Library::UnloadDependencies() {
 108     if (FDependenciesLibraries != NULL) {
 109         for (std::vector<Library*>::const_iterator iterator = FDependenciesLibraries->begin();
 110                 iterator != FDependenciesLibraries->end(); iterator++) {
 111             Library* library = *iterator;
 112 
 113             if (library != NULL) {
 114                 library->Unload();
 115                 delete library;
 116             }
 117         }
 118 
 119         delete FDependenciesLibraries;
 120         FDependenciesLibraries = NULL;
 121     }
 122 }
 123 
 124 Procedure Library::GetProcAddress(std::string MethodName) {
 125     Platform& platform = Platform::GetInstance();
 126     return platform.GetProcAddress(FModule, MethodName);
 127 }
 128 
 129 bool Library::Load(const TString &FileName) {
 130     bool result = true;
 131 
 132     if (FModule == NULL) {
 133         LoadDependencies();
 134         Platform& platform = Platform::GetInstance();
 135         FModule = platform.LoadLibrary(FileName);
 136 
 137         if (FModule == NULL) {
 138             Messages& messages = Messages::GetInstance();
 139             platform.ShowMessage(messages.GetMessage(LIBRARY_NOT_FOUND), FileName);
 140             result = false;
 141         }
 142     }
 143 
 144     return result;
 145 }
 146 
 147 bool Library::Unload() {
 148     bool result = false;
 149 
 150     if (FModule != NULL) {
 151         Platform& platform = Platform::GetInstance();
 152         platform.FreeLibrary(FModule);
 153         FModule = NULL;
 154         UnloadDependencies();
 155         result = true;
 156     }
 157 
 158     return result;
 159 }
 160 
 161 void Library::AddDependency(const TString &FileName) {
 162     InitializeDependencies();
 163 
 164     if (FDependentLibraryNames != NULL) {
 165         FDependentLibraryNames->push_back(FileName);
 166     }
 167 }
 168 
 169 void Library::AddDependencies(const std::vector<TString> &Dependencies) {
 170     if (Dependencies.size() > 0) {
 171         InitializeDependencies();
 172 
 173         if (FDependentLibraryNames != NULL) {
 174             for (std::vector<TString>::const_iterator iterator = FDependentLibraryNames->begin();
 175                 iterator != FDependentLibraryNames->end(); iterator++) {
 176                 TString fileName = *iterator;
 177                 AddDependency(fileName);
 178             }
 179         }
 180     }
 181 }
 182 //--------------------------------------------------------------------------------------------------