root/ossie/trunk/ossie/framework/LoadableDevice_impl.cpp @ 3646

Revision 3646, 6.6 KB (checked in by balister, 6 years ago)

Loadable device load method caches copy of file.

  • Property svn:eol-style set to native
Line 
1/****************************************************************************
2
3Copyright 2004, Virginia Polytechnic Institute and State University
4
5This file is part of the OSSIE Core Framework.
6
7OSSIE Core Framework is free software; you can redistribute it and/or modify
8it under the terms of the Lesser GNU General Public License as published by
9the Free Software Foundation; either version 2.1 of the License, or
10(at your option) any later version.
11
12OSSIE Core Framework is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15Lesser GNU General Public License for more details.
16
17You should have received a copy of the Lesser GNU General Public License
18along with OSSIE Core Framework; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
21LOADABLEDEVICE_IMPL.CPP
22Functions for class LoadableDevice_impl. Provides a mechanism to load and unload
23software on the device.
24
25Craig Neely, Carlos Aguayo, 12 December 2003
26
27****************************************************************************/
28
29#include <fstream>
30#include <string>
31#include <iostream>
32
33#include <boost/filesystem/path.hpp>
34#include <boost/filesystem/operations.hpp>
35
36#include "ossie/LoadableDevice_impl.h"
37#include "ossie/debug.h"
38
39namespace fs = boost::filesystem;
40
41LoadableDevice_impl::LoadableDevice_impl (char *id, char *lbl, char *sftwrPrfl) : Device_impl (id, lbl, sftwrPrfl)
42{
43
44    init();
45}
46
47
48LoadableDevice_impl::LoadableDevice_impl (char *id, char *lbl, char *sftwrPrfl, CF::Properties capacities) : Device_impl (id, lbl, sftwrPrfl, capacities)
49{
50
51    init();
52}
53
54
55LoadableDevice_impl::~LoadableDevice_impl ()
56{
57}
58
59void LoadableDevice_impl::init()
60{
61
62    localFileRoot = "/sdr";
63    localFileRoot /= label();
64    fs::create_directory(localFileRoot);
65
66    // Assumption: all executable files named as /bin/exec_name
67    fs::path binDir = localFileRoot / "bin";
68    fs::create_directory(binDir);
69}
70
71void LoadableDevice_impl::load (CF::FileSystem_ptr fs, const char *fileName, CF::LoadableDevice::LoadType loadKind)
72throw (CORBA::SystemException, CF::Device::InvalidState,
73CF::LoadableDevice::InvalidLoadKind, CF::InvalidFileName,
74CF::LoadableDevice::LoadFail)
75{
76
77    //CF::File_ptr fileToLoad;                      // file pointer
78    bool readOnly = true;                         // read only flag
79   
80    // verify that the device is in a valid state for loading
81    if (!isUnlocked () || isDisabled ()) {
82        throw (CF::Device::InvalidState("Cannot load. System is either LOCKED, SHUTTING DOWN or DISABLED."));
83    }
84   
85    // verify that the loadKind is supported (only executable is supported by this version)
86    if (loadKind != CF::LoadableDevice::EXECUTABLE) {
87        throw CF::LoadableDevice::InvalidLoadKind ();
88    }
89   
90    // verify the file name exists in the file system and get a pointer to it
91   
92    if (!fs->exists ((char *) fileName))
93        throw (CF::InvalidFileName (CF::CFENOENT, "Cannot load. File name is invalid."));
94   
95    if (incrementFile (fileName) == 1) { // First use of file update local cache
96        CF::File_var execFile = fs->open(fileName, true);
97        unsigned long remoteFileSize = execFile->sizeOf();
98        unsigned long localFileSize;
99        if (exists(localFileRoot / fileName))
100            localFileSize = fs::file_size(localFileRoot / fileName);
101        else
102            localFileSize = 0;
103
104        ///\todo Make a better check for identical files
105        if (remoteFileSize != localFileSize) { // Update local cache
106            fs::path filePath = localFileRoot / fileName;
107
108            std::fstream f;
109            std::ios_base::openmode mode(std::ios::in|std::ios::out|std::ios::trunc);
110            f.open(filePath.string().c_str(), mode);
111           
112            if (!f.is_open()) {
113                DEBUG(3, LoadableDevice, "File " << filePath.string() << " did not open succesfully.");
114                return;
115            }
116           
117            bool done(false);
118            do {
119                CF::OctetSequence_var data;
120                execFile->read(data, 8192);
121                f.write((const char *)data->get_buffer(), data->length());
122
123                done = (data->length() != 0);
124            } while (done);
125            f.close();
126        }
127
128        execFile->close();
129       
130    }
131}
132
133
134int LoadableDevice_impl::incrementFile (const char *fileName)
135{
136    for (unsigned int i = 0; i < loadedFiles.size (); i++) {
137        if (loadedFiles[i].fileId == fileName) {
138            loadedFiles[i].counter++;
139            return loadedFiles[i].counter++;
140        }
141    }
142    //If the file is not loaded yet, then add a new element to loadedFiles
143    fileCount tempNode;
144    tempNode.fileId = fileName;
145    tempNode.counter = 1;
146    loadedFiles.push_back (tempNode);
147    return 1;
148}
149
150
151void LoadableDevice_impl::unload (const char *fileName)
152throw (CORBA::SystemException, CF::Device::InvalidState, CF::InvalidFileName)
153{
154   
155    // verify that the device is in a valid state for loading
156    if (isLocked () || isDisabled ()) {
157        throw (CF::Device::InvalidState("Cannot unload. System is either LOCKED or DISABLED."));
158    }
159   
160    // decrement the list entry counter for this file
161    decrementFile (fileName);
162   
163}
164
165
166int LoadableDevice_impl::decrementFile (const char *fileName)
167{
168    for (unsigned int i = 0; i < loadedFiles.size (); i++) {
169        if (loadedFiles[i].fileId == fileName) {
170            if (--loadedFiles[i].counter == 0) {
171               
172                // unload fileName using API (device specific, not currently implemented)
173               
174                loadedFiles.erase (loadedFiles.begin () + i);
175            }
176            return loadedFiles[i].counter;
177        }
178    }
179   
180    //If it gets to this point the file was not loaded previously
181    throw (CF::InvalidFileName (CF::CFENOENT, "Cannot unload. File was not already loaded."));
182}
183
184
185bool LoadableDevice_impl::isFileLoaded (const char *fileName)
186{
187    for (unsigned int i = 0; i < loadedFiles.size (); i++) {
188        if (loadedFiles[i].fileId == fileName) {
189            return true;
190        }
191    }
192    return false;
193}
194
195
196void LoadableDevice_impl ::configure (const CF::Properties & capacities)
197throw (CF::PropertySet::PartialConfiguration, CF::PropertySet::
198InvalidConfiguration, CORBA::SystemException)
199{
200    Device_impl::configure(capacities);
201}
202
203
204#ifdef AUTOMATIC_TEST
205
206/* displayLoadedFiles *****************************************************************************
207    - prints the list of loaded files to the console (not currently implemented)
208************************************************************************************************ */
209void LoadableDevice_impl::displayLoadedFiles()
210{
211    printf("\nDisplaying Loaded Files\n\n");
212    for(int i = 0; i<loadedFiles.size();i++)
213    {
214        printf("%s has been loaded %d time(s)\n",loadedFiles[i].fileId,loadedFiles[i].counter);
215    }
216
217}
218#endif
Note: See TracBrowser for help on using the browser.