Read_Buffer.cpp

Go to the documentation of this file.
00001 // $Id: Read_Buffer.cpp 80826 2008-03-04 14:51:23Z wotte $
00002 
00003 #include "ace/Read_Buffer.h"
00004 
00005 #include "ace/config-all.h"
00006 
00007 #if !defined (__ACE_INLINE__)
00008 #include "ace/Read_Buffer.inl"
00009 #endif /* __ACE_INLINE__ */
00010 
00011 #include "ace/Log_Msg.h"
00012 #include "ace/Malloc_Base.h"
00013 #include "ace/Service_Config.h"
00014 #include "ace/OS_NS_stdio.h"
00015 
00016 ACE_RCSID(ace, Read_Buffer, "$Id: Read_Buffer.cpp 80826 2008-03-04 14:51:23Z wotte $")
00017 
00018 
00019 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00020 
00021 void
00022 ACE_Read_Buffer::dump (void) const
00023 {
00024 #if defined (ACE_HAS_DUMP)
00025   ACE_TRACE ("ACE_Read_Buffer::dump");
00026   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00027   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("size_ = %d"), this->size_));
00028   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("\noccurrences_ = %d"), this->occurrences_));
00029   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("\nstream_ = %x"), this->stream_));
00030   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("\nallocator_ = %x"), this->allocator_));
00031   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00032 #endif /* ACE_HAS_DUMP */
00033 }
00034 
00035 ACE_Read_Buffer::ACE_Read_Buffer (FILE *fp,
00036                                   bool close_on_delete,
00037                                   ACE_Allocator *alloc)
00038   : stream_ (fp),
00039     close_on_delete_ (close_on_delete),
00040     allocator_ (alloc)
00041 {
00042   ACE_TRACE ("ACE_Read_Buffer::ACE_Read_Buffer");
00043   if (this->allocator_ == 0)
00044     this->allocator_ = ACE_Allocator::instance ();
00045 }
00046 
00047 #if !defined (ACE_HAS_WINCE)
00048 ACE_Read_Buffer::ACE_Read_Buffer (ACE_HANDLE handle,
00049                                   bool close_on_delete,
00050                                   ACE_Allocator *alloc)
00051   : stream_ (ACE_OS::fdopen (handle, ACE_TEXT ("r"))),
00052     close_on_delete_ (close_on_delete),
00053     allocator_ (alloc)
00054 {
00055   ACE_TRACE ("ACE_Read_Buffer::ACE_Read_Buffer");
00056 
00057   if (this->allocator_ == 0)
00058     this->allocator_ = ACE_Allocator::instance ();
00059 }
00060 #endif  // ACE_HAS_WINCE
00061 
00062 ACE_Read_Buffer::~ACE_Read_Buffer (void)
00063 {
00064   ACE_TRACE ("ACE_Read_Buffer::~ACE_Read_Buffer");
00065 
00066   if (this->close_on_delete_)
00067     ACE_OS::fclose (this->stream_);
00068 }
00069 
00070 // Input: term        the character to terminate on
00071 //        search      the character to search for
00072 //        replace     the character with which to replace search
00073 // Output: a buffer containing the contents of stream
00074 // Method: call the recursive helper function read_helper
00075 
00076 char *
00077 ACE_Read_Buffer::read (int term, int search, int replace)
00078 {
00079   ACE_TRACE ("ACE_Read_Buffer::read");
00080   this->occurrences_ = 0;
00081   this->size_ = 0;
00082   return this->rec_read (term, search, replace);
00083 }
00084 
00085 // Input: term       the termination character
00086 //        search     the character to search for
00087 //        replace    the character with which to replace search
00088 // Purpose: read in a file to a buffer using only a single dynamic
00089 //          allocation.
00090 // Method: read until the local buffer is full and then recurse.
00091 //         Must continue until the termination character is reached.
00092 //         Allocate the final buffer based on the number of local
00093 //         buffers read and as the recursive calls bottom out,
00094 //         copy them in reverse order into the allocated buffer.
00095 
00096 char *
00097 ACE_Read_Buffer::rec_read (int term, int search, int replace)
00098 {
00099   ACE_TRACE ("ACE_Read_Buffer::rec_read");
00100   // This is our temporary workspace.
00101   char buf[BUFSIZ];
00102 
00103   int c = EOF;
00104   size_t slot = 0;
00105   int done = 0;
00106 
00107   // Read in the file char by char
00108   while (slot < BUFSIZ)
00109     {
00110       c = ACE_OS::getc (this->stream_);
00111 
00112       // Don't insert EOF into the buffer...
00113       if (c == EOF)
00114         {
00115           ACE_OS::ungetc (c, this->stream_);
00116           break;
00117         }
00118       else if (c == term)
00119         done = 1;
00120 
00121       // Check for possible substitutions.
00122       if (c == search)
00123         {
00124           ++this->occurrences_;
00125 
00126           if (replace >= 0)
00127             c = replace;
00128         }
00129 
00130       buf[slot++] = (char) c;
00131 
00132       // Substitutions must be made before checking for termination.
00133       if (done)
00134         break;
00135     }
00136 
00137   // Increment the number of bytes.
00138   this->size_ += slot;
00139 
00140   // Don't bother going any farther if the total size is 0.
00141   if (this->size_ == 0)
00142     return 0;
00143 
00144   char *result = 0;
00145 
00146   // Recurse, when the recursion bottoms out, allocate the result
00147   // buffer.
00148   if (done || c == EOF)
00149     {
00150       // Use the allocator to acquire the memory.  The + 1 allows
00151       // space for the null terminator.
00152       result = (char *) this->allocator_->malloc (this->size_ + 1);
00153 
00154       if (result == 0)
00155         {
00156           errno = ENOMEM;
00157           return 0;
00158         }
00159       result += this->size_;
00160 
00161       // Null terminate the buffer.
00162       *result = '\0';
00163     }
00164   else if ((result = this->rec_read (term, search, replace)) == 0)
00165     return 0;
00166 
00167   // Copy buf into the appropriate location starting from end of
00168   // buffer.  Peter says this is confusing and that we should use
00169   // memcpy() ;-)
00170   for (size_t j = slot; j > 0; j--)
00171     *--result = buf[j - 1];
00172 
00173   return result;
00174 }
00175 
00176 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:18:42 2010 for ACE by  doxygen 1.4.7