$search
00001 00009 /***************************************************************************** 00010 ** Cross Platform Functionality 00011 *****************************************************************************/ 00012 00013 #include <ecl/config/ecl.hpp> 00014 #if defined(ECL_IS_POSIX) 00015 00016 /***************************************************************************** 00017 ** Includes 00018 *****************************************************************************/ 00019 00020 #include "../../include/ecl/devices/ofile_pos.hpp" 00021 #include "../../include/ecl/devices/detail/error_handler_pos.hpp" 00022 #include <iostream> 00023 #include <ecl/exceptions/macros.hpp> 00024 00025 /***************************************************************************** 00026 ** Namespaces 00027 *****************************************************************************/ 00028 00029 namespace ecl { 00030 00031 /***************************************************************************** 00032 ** Implementation [OFile] 00033 *****************************************************************************/ 00034 00035 OFile::OFile() : 00036 file(NULL), 00037 error_handler(NoError) 00038 {} 00039 00040 OFile::OFile(const std::string &file_name, const WriteMode &write_mode) ecl_throw_decl(StandardException) : 00041 file(NULL), 00042 error_handler(NoError) 00043 { 00044 ecl_try { 00045 open(file_name,write_mode); 00046 } ecl_catch( StandardException &e ) { 00047 ecl_throw(StandardException(LOC,e)); 00048 } 00049 } 00050 00051 OFile::~OFile() { 00052 if ( open() ) { 00053 // This flushes and closes the file descriptor. 00054 if ( fclose(file) != 0 ) { 00055 // implement some mechanism if ever needed, but no 00056 // exceptions allowed in destructors, just have to assume the best. 00057 } 00058 file = NULL; 00059 } 00060 } 00061 /***************************************************************************** 00062 ** Implementation [OFile][open/close] 00063 *****************************************************************************/ 00064 00065 bool OFile::open(const std::string &file_name, const WriteMode &write_mode) ecl_throw_decl(StandardException) { 00066 name = file_name; 00067 switch(write_mode) { 00068 case(New) : { 00069 file_descriptor = ::open(name.c_str(), O_WRONLY|O_CREAT, S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH); 00070 if ( file_descriptor == -1 ) { 00071 ecl_throw(devices::open_exception(LOC,file_name)); 00072 error_handler = devices::open_error(); 00073 return false; 00074 } 00075 file = fdopen(file_descriptor,"w"); 00076 break; 00077 } 00078 case(Append) : { 00079 file_descriptor = ::open(name.c_str(),O_WRONLY|O_APPEND|O_CREAT, S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH); 00080 if ( file_descriptor == -1 ) { 00081 ecl_throw(devices::open_exception(LOC,file_name)); 00082 error_handler = devices::open_error(); 00083 return false; 00084 } 00085 file = fdopen(file_descriptor,"a"); 00086 break; 00087 } 00088 default : break; 00089 } 00090 if ( file == NULL ) { 00091 ecl_throw(devices::open_exception(LOC,file_name)); 00092 error_handler = devices::open_error(); 00093 return false; 00094 } 00095 error_handler = NoError; 00096 return true; 00097 } 00098 00099 bool OFile::close() ecl_throw_decl(StandardException) { 00100 if ( open() ) { 00101 // This flushes and closes the file descriptor. 00102 if ( fclose(file) != 0 ) { 00103 ecl_throw(devices::close_exception(LOC,name)); 00104 error_handler = devices::close_error(); 00105 return false; 00106 } 00107 file = NULL; 00108 } 00109 error_handler = NoError; 00110 return true; 00111 } 00112 /***************************************************************************** 00113 ** Implementation [OFile][write] 00114 *****************************************************************************/ 00115 00116 long OFile::write(const char &c) ecl_debug_throw_decl(StandardException) 00117 { 00118 if ( !open() ) { 00119 ecl_debug_throw(StandardException(LOC, OpenError, std::string("File ") + name + std::string(" is not open for writing."))); 00120 error_handler = OpenError; 00121 return -1; 00122 } 00123 size_t written = fwrite(&c,1,1,file); 00124 if ( written <= 0 ) { 00125 ecl_debug_throw(StandardException(LOC, WriteError, std::string("Could not write to ") + name + std::string("."))); 00126 error_handler = WriteError; 00127 return -1; 00128 } 00129 error_handler = NoError; 00130 // fwrite returns the number of 'items' written, not bytes! 00131 return written; 00132 } 00133 00134 long OFile::write(const char* s, unsigned long n) ecl_debug_throw_decl(StandardException) 00135 { 00136 if ( !open() ) { 00137 ecl_debug_throw(StandardException(LOC, OpenError, std::string("File ") + name + std::string(" is not open for writing."))); 00138 error_handler = OpenError; 00139 return -1; 00140 } 00141 size_t written = fwrite(s,n,1,file); 00142 if ( written <= 0 ) { 00143 ecl_debug_throw(StandardException(LOC, WriteError, std::string("Could not write to ") + name + std::string("."))); 00144 error_handler = WriteError; 00145 return -1; 00146 } 00147 error_handler = NoError; 00148 // fwrite returns the number of 'items' written, not bytes! 00149 return n*written; 00150 } 00151 00152 bool OFile::flush() ecl_debug_throw_decl(StandardException) { 00153 // This flushes userland buffers to the kernel buffers...not sure why, 00154 // but you can still read the file in real time, so its good enough and 00155 // thus better than a more expensive fsync here. 00156 int result = fflush(file); 00157 if ( result != 0 ) { 00158 ecl_debug_throw ( StandardException(LOC, UnknownError, std::string("Could not fflush ") + name + std::string("."))); 00159 error_handler = UnknownError; 00160 return false; 00161 } 00162 error_handler = NoError; 00163 return true; 00164 } 00165 00166 }; // namespace ecl 00167 00168 #endif /* ECL_IS_POSIX */