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


ecl_devices
Author(s): Daniel Stonier (d.stonier@gmail.com)
autogenerated on Thu Jan 2 2014 11:12:50