Go to the documentation of this file.00001
00008
00009
00010
00011
00012
00013 #include <ecl/config/ecl.hpp>
00014 #if defined(ECL_IS_POSIX)
00015
00016
00017
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
00030
00031
00032 namespace ecl {
00033 namespace devices {
00034
00035
00036
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
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
00065
00066
00067 Mutex SharedFileManager::mutex;
00068 std::map<string,SharedFileCommon*> SharedFileManager::opened_files;
00069
00070
00071
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
00082
00083 iter->second->count += 1;
00084 shared_instance = iter->second;
00085 } else {
00086
00087
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 };
00125
00126
00127
00128
00129
00130 using std::string;
00131
00132
00133
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
00151
00152
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
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 };
00215
00216 #endif