Flat_File_Persistence.cpp

Go to the documentation of this file.
00001 // $Id: Flat_File_Persistence.cpp 78858 2007-07-12 23:24:55Z sowayaa $
00002 
00003 //-----------------------------------------------------------------------------
00004 // Flat File class implementations
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   // We could check the mode for this file, but for now just check exists
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   // For now, three flags exist "r", "w",  and "c"
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_);  // even though flock_destroy closes the handle
00098                          // we still need to destroy the FILE*
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 /* ACE_HAS_WINCE */
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   //id
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   //kind
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    //ref
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; // Still set the global.counter (to 0)
00367     case EOF:
00368       this->setstate (eofbit);
00369       break; // Still set the global.counter (to 0)
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

Generated on Sun Jan 27 16:15:29 2008 for TAO_CosNaming by doxygen 1.3.6