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