00001
00002
00003
00004
00005
00006 #include "orbsvcs/Naming/Flat_File_Persistence.h"
00007
00008 #include "ace/Log_Msg.h"
00009 #include "ace/Numeric_Limits.h"
00010 #include "ace/Auto_Ptr.h"
00011 #include "ace/OS_NS_sys_stat.h"
00012 #include "ace/OS_NS_unistd.h"
00013 #include "ace/OS_NS_fcntl.h"
00014
00015 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00016
00017 TAO_NS_FlatFileStream::TAO_NS_FlatFileStream (const ACE_CString & file,
00018 const char * mode)
00019 : fl_ (0)
00020 {
00021 ACE_TRACE("TAO_NS_FlatFileStream");
00022 file_ = file;
00023 mode_ = mode;
00024 }
00025
00026 TAO_NS_FlatFileStream::~TAO_NS_FlatFileStream ()
00027 {
00028 ACE_TRACE("~TAO_NS_FlatFileStream");
00029 if ( fl_ != 0 )
00030 this->close();
00031 }
00032
00033 void
00034 TAO_NS_FlatFileStream::remove ()
00035 {
00036 ACE_TRACE("remove");
00037 ACE_OS::unlink(ACE_TEXT_CHAR_TO_TCHAR(file_.c_str()));
00038 }
00039
00040 int
00041 TAO_NS_FlatFileStream::exists ()
00042 {
00043 ACE_TRACE("exists");
00044
00045 return ! ACE_OS::access(file_.c_str(), F_OK);
00046 }
00047
00048 int
00049 TAO_NS_FlatFileStream::open()
00050 {
00051 ACE_TRACE("open");
00052
00053 int flags = 0;
00054 const char *fdmode = 0;
00055 if( ACE_OS::strchr(mode_.c_str(), 'r') )
00056 if( ACE_OS::strchr(mode_.c_str(), 'w') )
00057 flags = O_RDWR, fdmode = "r+";
00058 else
00059 flags = O_RDONLY, fdmode = "r";
00060 else
00061 flags = O_WRONLY, fdmode = "w";
00062 if( ACE_OS::strchr(mode_.c_str(), 'c') )
00063 flags |= O_CREAT;
00064 #ifndef ACE_WIN32
00065 if( ACE_OS::flock_init (&filelock_, flags, ACE_TEXT_CHAR_TO_TCHAR(file_.c_str()), 0666) != 0 )
00066 ACE_ERROR_RETURN ((LM_ERROR,
00067 "Cannot open file %s for mode %s: (%d) %s\n",
00068 file_.c_str(), mode_.c_str(),
00069 errno, ACE_OS::strerror(errno)),
00070 -1);
00071 #else
00072 if( (filelock_.handle_= ACE_OS::open (ACE_TEXT_CHAR_TO_TCHAR(file_.c_str()), flags, 0)) == ACE_INVALID_HANDLE )
00073 ACE_ERROR_RETURN ((LM_ERROR,
00074 "Cannot open file %s for mode %s: (%d) %s\n",
00075 file_.c_str(), mode_.c_str(),
00076 errno, ACE_OS::strerror(errno)),
00077 -1);
00078 #endif
00079 this->fl_ = ACE_OS::fdopen(filelock_.handle_, ACE_TEXT_CHAR_TO_TCHAR(fdmode));
00080 if (this->fl_ == 0)
00081 ACE_ERROR_RETURN ((LM_ERROR,
00082 "Cannot fdopen file %s for mode %s: (%d) %s\n",
00083 file_.c_str(), mode_.c_str(),
00084 errno, ACE_OS::strerror(errno)),
00085 -1);
00086 return 0;
00087 }
00088
00089 int
00090 TAO_NS_FlatFileStream::close()
00091 {
00092 ACE_TRACE("close");
00093 ACE_OS::fflush(fl_);
00094 #ifndef ACE_WIN32
00095 ACE_OS::flock_destroy (&filelock_, 0);
00096 #endif
00097 ACE_OS::fclose (fl_);
00098
00099
00100 fl_ = 0;
00101 return 0;
00102 }
00103
00104 int
00105 TAO_NS_FlatFileStream::flock (int whence, int start, int len)
00106 {
00107 ACE_TRACE("flock");
00108 #if defined (ACE_WIN32)
00109 ACE_UNUSED_ARG (whence);
00110 ACE_UNUSED_ARG (start);
00111 ACE_UNUSED_ARG (len);
00112 #else
00113 if( ACE_OS::strcmp(mode_.c_str(), "r") == 0 )
00114 ACE_OS::flock_rdlock(&filelock_, whence, start, len);
00115 else
00116 ACE_OS::flock_wrlock(&filelock_, whence, start, len);
00117 #endif
00118 return 0;
00119 }
00120
00121 int
00122 TAO_NS_FlatFileStream::funlock (int whence, int start, int len)
00123 {
00124 ACE_TRACE("funlock");
00125 #if defined (ACE_WIN32)
00126 ACE_UNUSED_ARG (whence);
00127 ACE_UNUSED_ARG (start);
00128 ACE_UNUSED_ARG (len);
00129 #else
00130 ACE_OS::flock_unlock(&filelock_, whence, start, len);
00131 #endif
00132 return 0;
00133 }
00134
00135 time_t
00136 TAO_NS_FlatFileStream::last_changed(void)
00137 {
00138 ACE_TRACE("TAO_NS_FlatFileStream::last_changed");
00139 ACE_stat st;
00140 ACE_OS::fstat(filelock_.handle_, &st);
00141 #if !defined (ACE_HAS_WINCE)
00142 return st.st_mtime;
00143 #else
00144 return st.st_mtime.sec ();
00145 #endif
00146 }
00147
00148 TAO_Storable_Base &
00149 TAO_NS_FlatFileStream::operator <<(
00150 const TAO_NS_Persistence_Header &header)
00151 {
00152 ACE_TRACE("TAO_NS_FlatFileStream::operator <<");
00153 ACE_OS::rewind(this->fl_);
00154 ACE_OS::fprintf(this->fl_, "%d\n%d\n", header.size(), header.destroyed());
00155 ACE_OS::fflush(this->fl_);
00156
00157 return *this;
00158 }
00159
00160 TAO_Storable_Base &
00161 TAO_NS_FlatFileStream::operator >>(
00162 TAO_NS_Persistence_Header &header)
00163 {
00164 ACE_TRACE("TAO_NS_FlatFileStream::operator >>");
00165 unsigned int size;
00166 int destroyed;
00167
00168 ACE_OS::rewind(this->fl_);
00169 switch (fscanf(fl_, "%u\n", &size))
00170 {
00171 case 0:
00172 this->setstate (badbit);
00173 return *this;
00174 case EOF:
00175 this->setstate (eofbit);
00176 return *this;
00177 }
00178 header.size(size);
00179
00180 switch (fscanf(fl_, "%d\n", &destroyed))
00181 {
00182 case 0:
00183 this->setstate (badbit);
00184 return *this;
00185 case EOF:
00186 this->setstate (eofbit);
00187 return *this;
00188 }
00189 header.destroyed(destroyed);
00190
00191 return *this;
00192
00193 }
00194
00195 TAO_Storable_Base &
00196 TAO_NS_FlatFileStream::operator <<(
00197 const TAO_NS_Persistence_Record &record)
00198 {
00199 ACE_TRACE("TAO_NS_FlatFileStream::operator <<");
00200 TAO_NS_Persistence_Record::Record_Type type = record.type();
00201 ACE_OS::fprintf(this->fl_, "%d\n", type);
00202
00203 ACE_CString id = record.id();
00204 ACE_OS::fprintf(this->fl_, ACE_SIZE_T_FORMAT_SPECIFIER ACE_TEXT("\n%s\n"),
00205 id.length(), id.c_str());
00206
00207 ACE_CString kind = record.kind();
00208 ACE_OS::fprintf(this->fl_, ACE_SIZE_T_FORMAT_SPECIFIER ACE_TEXT ("\n%s\n"),
00209 kind.length(), kind.c_str());
00210
00211 ACE_CString ref = record.ref();
00212 ACE_OS::fprintf(this->fl_, ACE_SIZE_T_FORMAT_SPECIFIER ACE_TEXT ("\n%s\n"),
00213 ref.length(), ref.c_str());
00214
00215 ACE_OS::fflush(this->fl_);
00216
00217 return *this;
00218 }
00219
00220 TAO_Storable_Base &
00221 TAO_NS_FlatFileStream::operator >>(TAO_NS_Persistence_Record &record)
00222 {
00223 ACE_TRACE("TAO_NS_FlatFileStream::operator >>");
00224
00225 int temp_type_in;
00226 switch (fscanf(fl_, "%d\n", &temp_type_in))
00227 {
00228 case 0:
00229 this->setstate (badbit);
00230 return *this;
00231 case EOF:
00232 this->setstate (eofbit);
00233 return *this;
00234 }
00235 TAO_NS_Persistence_Record::Record_Type type =
00236 (TAO_NS_Persistence_Record::Record_Type) temp_type_in;
00237 record.type (type);
00238
00239 int bufSize = 0;
00240 ACE_CString::size_type const max_buf_len =
00241 ACE_Numeric_Limits<ACE_CString::size_type>::max ();
00242
00243
00244 switch (fscanf(fl_, "%d\n", &bufSize))
00245 {
00246 case 0:
00247 this->setstate (badbit);
00248 return *this;
00249 case EOF:
00250 this->setstate (eofbit);
00251 return *this;
00252 }
00253
00254 if (bufSize < 0
00255 || static_cast<ACE_CString::size_type> (bufSize) >= max_buf_len)
00256 {
00257 this->setstate (badbit);
00258 return *this;
00259 }
00260 {
00261 ACE_Auto_Basic_Array_Ptr<char> the_id (new char[bufSize + 1]);
00262 the_id[0] = '\0';
00263 if (ACE_OS::fgets (ACE_TEXT_CHAR_TO_TCHAR (the_id.get ()),
00264 bufSize + 1,
00265 fl_) == 0
00266 && bufSize != 0)
00267 {
00268 this->setstate (badbit);
00269 return *this;
00270 }
00271 record.id (ACE_CString (the_id.get (), 0, false));
00272 }
00273
00274
00275 switch (fscanf(fl_, "%d\n", &bufSize))
00276 {
00277 case 0:
00278 this->setstate (badbit);
00279 return *this;
00280 case EOF:
00281 this->setstate (eofbit);
00282 return *this;
00283 }
00284
00285 if (bufSize < 0
00286 || static_cast<ACE_CString::size_type> (bufSize) >= max_buf_len)
00287 {
00288 this->setstate (badbit);
00289 return *this;
00290 }
00291
00292 {
00293 ACE_Auto_Basic_Array_Ptr<char> the_kind (new char[bufSize + 1]);
00294 the_kind[0] = '\0';
00295 if (ACE_OS::fgets (ACE_TEXT_CHAR_TO_TCHAR (the_kind.get ()),
00296 bufSize + 1,
00297 fl_) == 0
00298 && bufSize != 0)
00299 {
00300 this->setstate (badbit);
00301 return *this;
00302 }
00303 record.kind (ACE_CString (the_kind.get (), 0, false));
00304 }
00305
00306
00307 switch (fscanf(fl_, "%d\n", &bufSize))
00308 {
00309 case 0:
00310 this->setstate (badbit);
00311 return *this;
00312 case EOF:
00313 this->setstate (eofbit);
00314 return *this;
00315 }
00316
00317 if (bufSize < 0
00318 || static_cast<ACE_CString::size_type> (bufSize) >= max_buf_len)
00319 {
00320 this->setstate (badbit);
00321 return *this;
00322 }
00323
00324 {
00325 ACE_Auto_Basic_Array_Ptr<char> the_ref (new char[bufSize + 1]);
00326 the_ref[0] = '\0';
00327 if (ACE_OS::fgets (ACE_TEXT_CHAR_TO_TCHAR (the_ref.get ()),
00328 bufSize + 1,
00329 fl_) == 0
00330 && bufSize != 0)
00331 {
00332 this->setstate (badbit);
00333 return *this;
00334 }
00335 record.ref (ACE_CString (the_ref.get (), 0, false));
00336 }
00337
00338 return *this;
00339
00340 }
00341
00342 TAO_Storable_Base &
00343 TAO_NS_FlatFileStream::operator <<(
00344 const TAO_NS_Persistence_Global &global)
00345 {
00346 ACE_TRACE("TAO_NS_FlatFileStream::operator <<");
00347 ACE_OS::rewind(this->fl_);
00348 ACE_OS::fprintf(this->fl_, "%d\n", global.counter());
00349 ACE_OS::fflush(this->fl_);
00350
00351 return *this;
00352 }
00353
00354 TAO_Storable_Base &
00355 TAO_NS_FlatFileStream::operator >>(
00356 TAO_NS_Persistence_Global &global)
00357 {
00358 ACE_TRACE("TAO_NS_FlatFileStream::operator >>");
00359 unsigned int counter = 0;
00360
00361 ACE_OS::rewind(this->fl_);
00362 switch (fscanf(fl_, "%u\n", &counter))
00363 {
00364 case 0:
00365 this->setstate (badbit);
00366 break;
00367 case EOF:
00368 this->setstate (eofbit);
00369 break;
00370 }
00371 global.counter(counter);
00372
00373 return *this;
00374 }
00375
00376
00377 TAO_Storable_Base *
00378 TAO_NS_FlatFileFactory::create_stream (const ACE_CString & file,
00379 const ACE_TCHAR * mode)
00380 {
00381 ACE_TRACE("TAO_NS_FlatFileFactory::create_stream");
00382 TAO_Storable_Base *stream = 0;
00383
00384 ACE_NEW_RETURN (stream,
00385 TAO_NS_FlatFileStream(file, ACE_TEXT_ALWAYS_CHAR (mode)),
00386 0);
00387 return stream;
00388 }
00389
00390 TAO_END_VERSIONED_NAMESPACE_DECL