shared_file.cpp
Go to the documentation of this file.
00001 
00008 /*****************************************************************************
00009 ** Cross Platform Functionality
00010 *****************************************************************************/
00011 // Only because there is only ofile_pos support so far.
00012 
00013 #include <ecl/config/ecl.hpp>
00014 
00015 /*****************************************************************************
00016 ** Includes
00017 *****************************************************************************/
00018 
00019 #include <iostream>
00020 #include <map>
00021 #include <string>
00022 #include <ecl/errors/handlers.hpp>
00023 #include <ecl/exceptions/standard_exception.hpp>
00024 #include <ecl/exceptions/macros.hpp>
00025 #include "../../include/ecl/devices/shared_file.hpp"
00026 
00027 /*****************************************************************************
00028 ** Namespaces
00029 *****************************************************************************/
00030 
00031 namespace ecl {
00032 namespace devices {
00033 
00034 /****************************************************************************
00035 ** Using
00036 *****************************************************************************/
00037 
00038 using std::string;
00039 using ecl::WriteMode;
00040 using ecl::CloseError;
00041 using ecl::StandardException;
00042 using ecl::Mutex;
00043 
00044 /*****************************************************************************
00045 ** Implementation [SharedFileCommon]
00046 *****************************************************************************/
00047 
00048 SharedFileCommon::SharedFileCommon(const std::string &name, ecl::WriteMode mode) ecl_throw_decl(StandardException) :
00049         count(1),
00050         error_handler(NoError)
00051 {
00052         ecl_try {
00053                 if ( !file.open(name,mode) ) {
00054                         error_handler = file.error();
00055                 }
00056         } ecl_catch( StandardException &e ) {
00057                 error_handler = file.error();
00058                 ecl_throw(StandardException(LOC,e));
00059         }
00060 }
00061 
00062 /*****************************************************************************
00063 ** Static Variable Initialisation [SharedFileManager]
00064 *****************************************************************************/
00065 
00066 Mutex SharedFileManager::mutex;
00067 std::map<string,SharedFileCommon*> SharedFileManager::opened_files;
00068 
00069 /*****************************************************************************
00070 ** Implementation [SharedFileManager]
00071 *****************************************************************************/
00072 
00073 SharedFileCommon* SharedFileManager::RegisterSharedFile(const std::string& name, ecl::WriteMode mode) ecl_throw_decl(StandardException) {
00074 
00075         mutex.lock();
00076         std::map<std::string,SharedFileCommon*>::iterator iter = opened_files.find(name);
00077         SharedFileCommon* shared_instance;
00078         if ( iter != opened_files.end() ) {
00079         /******************************************
00080         ** File exists - do not open
00081         *******************************************/
00082         iter->second->count += 1;
00083         shared_instance = iter->second;
00084     } else {
00085         /******************************************
00086         ** File does not exist - open it
00087         *******************************************/
00088         ecl_try {
00089                 shared_instance = new SharedFileCommon(name,mode);
00090                 opened_files.insert(std::pair<string,SharedFileCommon*>(name,shared_instance));
00091         } ecl_catch ( StandardException &e ) {
00092                 shared_instance = NULL;
00093                 ecl_throw(StandardException(LOC,e));
00094         }
00095     }
00096     mutex.unlock();
00097     return shared_instance;
00098 }
00104 bool SharedFileManager::DeRegisterSharedFile(const std::string& name) ecl_throw_decl(StandardException) {
00105 
00106         mutex.lock();
00107         std::map<std::string,SharedFileCommon*>::iterator iter = opened_files.find(name);
00108 
00109         if ( iter == opened_files.end() ) {
00110                 ecl_throw(StandardException(LOC,CloseError,"The specified shared object file could not be closed - was not found."));
00111                 return false;
00112         }
00113     if ( iter->second->count == 1 ) {
00114         delete iter->second;
00115         opened_files.erase(iter);
00116     } else {
00117         iter->second->count -= 1;
00118     }
00119     mutex.unlock();
00120     return true;
00121 }
00122 
00123 }; // namespace Interfaces
00124 
00125 /*****************************************************************************
00126 ** Using
00127 *****************************************************************************/
00128 
00129 using std::string;
00130 
00131 /*****************************************************************************
00132 ** Implementation [SharedFile]
00133 *****************************************************************************/
00134 
00135 SharedFile::SharedFile(const std::string &name, WriteMode mode) ecl_throw_decl(StandardException) :
00136         shared_instance(NULL)
00137 {
00138         ecl_try {
00139                 open(name,mode);
00140         } ecl_catch( StandardException &e ) {
00141                 ecl_throw(StandardException(LOC,e));
00142         }
00143 }
00144 
00145 SharedFile::~SharedFile() {
00146         ecl_try {
00147                 devices::SharedFileManager::DeRegisterSharedFile( shared_instance->file.filename() );
00148         } ecl_catch( StandardException &e ) {
00149                 // Never throw from a destructor!
00150                 // use some other mechanism!!!
00151                 // throw StandardException(LOC,e);
00152         }
00153 }
00154 
00155 bool SharedFile::open(const std::string &name, WriteMode mode) ecl_throw_decl(StandardException) {
00156         ecl_try {
00157                 shared_instance = devices::SharedFileManager::RegisterSharedFile(name,mode);
00158                 if ( shared_instance == NULL ) {
00159                         shared_instance->error_handler = OpenError;
00160                         return false;
00161                 } else {
00162                         shared_instance->error_handler = NoError;
00163                         return true;
00164                 }
00165         } ecl_catch ( StandardException &e ) {
00166                 shared_instance->error_handler = OpenError;
00167                 ecl_throw(StandardException(LOC,e));
00168         }
00169 }
00170 
00171 long SharedFile::write(const char &c) ecl_debug_throw_decl(StandardException) {
00172         long n = buffer.append(c);
00173         if ( buffer.full() ) {
00174                 if ( !flush() ) {
00175                         return -1;
00176                 }
00177         }
00178         return n;
00179 }
00180 
00181 long SharedFile::write(const char* s, unsigned long n) ecl_debug_throw_decl(StandardException) {
00182         unsigned int no_written = 0;
00183         while ( no_written < n ) {
00184                 no_written += buffer.append(s+no_written,n-no_written);
00185                 if ( buffer.full() ) {
00186                         if ( !flush() ) {
00187                                 return -1;
00188                         }
00189                 }
00190         }
00191         return n;
00192 }
00193 
00194 bool SharedFile::flush() ecl_debug_throw_decl(StandardException) {
00195         long written;
00196         ecl_debug_try {
00197                 written = shared_instance->file.write(buffer.c_ptr(), buffer.size() );
00198         } ecl_debug_catch(const StandardException &e) {
00199                 shared_instance->error_handler = shared_instance->file.error();
00200                 ecl_debug_throw(StandardException(LOC,e));
00201         }
00202         buffer.clear();
00203         // fallback for no exceptions
00204         shared_instance->error_handler = shared_instance->file.error();
00205         if ( written > 0 ) {
00206                 return true;
00207         } else {
00208                 return false;
00209         }
00210 }
00211 
00212 
00213 }; // namespace ecl


ecl_devices
Author(s): Daniel Stonier
autogenerated on Sun Oct 5 2014 23:35:57