shared_file.cpp
Go to the documentation of this file.
1 
8 /*****************************************************************************
9 ** Cross Platform Functionality
10 *****************************************************************************/
11 // Only because there is only ofile_pos support so far.
12 
13 #include <ecl/config/ecl.hpp>
14 
15 /*****************************************************************************
16 ** Includes
17 *****************************************************************************/
18 
19 #include <iostream>
20 #include <map>
21 #include <string>
22 #include <ecl/errors/handlers.hpp>
25 #include "../../include/ecl/devices/shared_file.hpp"
26 
27 /*****************************************************************************
28 ** Namespaces
29 *****************************************************************************/
30 
31 namespace ecl {
32 namespace devices {
33 
34 /****************************************************************************
35 ** Using
36 *****************************************************************************/
37 
38 using std::string;
39 using ecl::WriteMode;
40 using ecl::CloseError;
42 using ecl::Mutex;
43 
44 /*****************************************************************************
45 ** Implementation [SharedFileCommon]
46 *****************************************************************************/
47 
48 SharedFileCommon::SharedFileCommon(const std::string &name, ecl::WriteMode mode) :
49  count(1),
50  error_handler(NoError)
51 {
52  ecl_try {
53  if ( !file.open(name,mode) ) {
54  error_handler = file.error();
55  }
56  } ecl_catch( StandardException &e ) {
57  error_handler = file.error();
58  ecl_throw(StandardException(LOC,e));
59  }
60 }
61 
62 /*****************************************************************************
63 ** Static Variable Initialisation [SharedFileManager]
64 *****************************************************************************/
65 
66 Mutex SharedFileManager::mutex;
67 std::map<string,SharedFileCommon*> SharedFileManager::opened_files;
68 
69 /*****************************************************************************
70 ** Implementation [SharedFileManager]
71 *****************************************************************************/
72 
73 SharedFileCommon* SharedFileManager::RegisterSharedFile(const std::string& name, ecl::WriteMode mode) {
74 
75  mutex.lock();
76  std::map<std::string,SharedFileCommon*>::iterator iter = opened_files.find(name);
77  SharedFileCommon* shared_instance;
78  if ( iter != opened_files.end() ) {
79  /******************************************
80  ** File exists - do not open
81  *******************************************/
82  iter->second->count += 1;
83  shared_instance = iter->second;
84  } else {
85  /******************************************
86  ** File does not exist - open it
87  *******************************************/
88  ecl_try {
89  shared_instance = new SharedFileCommon(name,mode);
90  opened_files.insert(std::pair<string,SharedFileCommon*>(name,shared_instance));
91  } ecl_catch ( StandardException &e ) {
92  shared_instance = NULL;
94  }
95  }
96  mutex.unlock();
97  return shared_instance;
98 }
104 bool SharedFileManager::DeRegisterSharedFile(const std::string& name) {
105 
106  mutex.lock();
107  std::map<std::string,SharedFileCommon*>::iterator iter = opened_files.find(name);
108 
109  if ( iter == opened_files.end() ) {
110  ecl_throw(StandardException(LOC,CloseError,"The specified shared object file could not be closed - was not found."));
111  return false;
112  }
113  if ( iter->second->count == 1 ) {
114  delete iter->second;
115  opened_files.erase(iter);
116  } else {
117  iter->second->count -= 1;
118  }
119  mutex.unlock();
120  return true;
121 }
122 
123 }; // namespace Interfaces
124 
125 /*****************************************************************************
126 ** Using
127 *****************************************************************************/
128 
129 using std::string;
130 
131 /*****************************************************************************
132 ** Implementation [SharedFile]
133 *****************************************************************************/
134 
135 SharedFile::SharedFile(const std::string &name, WriteMode mode) :
136  shared_instance(NULL)
137 {
138  ecl_try {
139  open(name,mode);
140  } ecl_catch( StandardException &e ) {
142  }
143 }
144 
146  ecl_try {
147  devices::SharedFileManager::DeRegisterSharedFile( shared_instance->file.filename() );
148  } ecl_catch( StandardException &e ) {
149  // Never throw from a destructor!
150  // use some other mechanism!!!
151  // throw StandardException(LOC,e);
152  }
153 }
154 
155 bool SharedFile::open(const std::string &name, WriteMode mode) {
156  ecl_try {
157  shared_instance = devices::SharedFileManager::RegisterSharedFile(name,mode);
158  if ( shared_instance == NULL ) {
159  shared_instance->error_handler = OpenError;
160  return false;
161  } else {
162  shared_instance->error_handler = NoError;
163  return true;
164  }
165  } ecl_catch ( StandardException &e ) {
166  shared_instance->error_handler = OpenError;
167  ecl_throw(StandardException(LOC,e));
168  }
169 }
170 
171 long SharedFile::write(const char &c) {
172  long n = buffer.append(c);
173  if ( buffer.full() ) {
174  if ( !flush() ) {
175  return -1;
176  }
177  }
178  return n;
179 }
180 
181 long SharedFile::write(const char* s, unsigned long n) {
182  unsigned int no_written = 0;
183  while ( no_written < n ) {
184  no_written += buffer.append(s+no_written,n-no_written);
185  if ( buffer.full() ) {
186  if ( !flush() ) {
187  return -1;
188  }
189  }
190  }
191  return n;
192 }
193 
194 bool SharedFile::flush() {
195  long written;
196  ecl_debug_try {
197  written = shared_instance->file.write(buffer.c_ptr(), buffer.size() );
198  } ecl_debug_catch(const StandardException &e) {
199  shared_instance->error_handler = shared_instance->file.error();
201  }
202  buffer.clear();
203  // fallback for no exceptions
204  shared_instance->error_handler = shared_instance->file.error();
205  if ( written > 0 ) {
206  return true;
207  } else {
208  return false;
209  }
210 }
211 
212 
213 }; // namespace ecl
ecl::OpenError
OpenError
ecl::WriteMode
WriteMode
Write mode for devices.
Definition: modes.hpp:41
ecl_try
#define ecl_try
ecl::SharedFile::write
long write(const char &c)
Write a character to the buffer.
Definition: shared_file.cpp:177
ecl::devices::SharedFileCommon::SharedFileCommon
SharedFileCommon()
Definition: shared_file.hpp:80
ecl::devices::SharedFileCommon
Interface distributed to all members of a shared output file.
Definition: shared_file.hpp:74
ecl_debug_try
#define ecl_debug_try
ecl::devices::SharedFileCommon::error_handler
Error error_handler
Definition: shared_file.hpp:99
ecl::devices::SharedFileCommon::count
unsigned int count
Definition: shared_file.hpp:96
ecl::StandardException
ecl::NoError
NoError
ecl::devices::SharedFileManager::RegisterSharedFile
static SharedFileCommon * RegisterSharedFile(const std::string &name, ecl::WriteMode mode=New)
Definition: shared_file.cpp:85
ecl_debug_catch
#define ecl_debug_catch(exception)
mutex
ecl::Mutex mutex
handlers.hpp
standard_exception.hpp
ecl_catch
#define ecl_catch(exception)
ecl_throw
#define ecl_throw(exception)
ecl::CloseError
CloseError
ecl::SharedFile::open
bool open()
Status flag indicating if the file is open/closed.
Definition: shared_file.hpp:198
ecl::SharedFile::~SharedFile
virtual ~SharedFile()
Automatic cleaner for shared files.
Definition: shared_file.cpp:151
ecl::devices::SharedFileCommon::file
OFile file
Definition: shared_file.hpp:98
ecl::devices::SharedFileManager::DeRegisterSharedFile
static bool DeRegisterSharedFile(const std::string &name)
Definition: shared_file.cpp:116
ecl::SharedFile::flush
bool flush()
Flush the internal buffer.
Definition: shared_file.cpp:200
macros.hpp
ecl
Embedded control libraries.
ecl_debug_throw
#define ecl_debug_throw(exception)


ecl_devices
Author(s): Daniel Stonier
autogenerated on Wed Mar 2 2022 00:16:45