diff options
Diffstat (limited to 'ACE/ace/Read_Buffer.cpp')
-rw-r--r-- | ACE/ace/Read_Buffer.cpp | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/ACE/ace/Read_Buffer.cpp b/ACE/ace/Read_Buffer.cpp new file mode 100644 index 00000000000..9401048f148 --- /dev/null +++ b/ACE/ace/Read_Buffer.cpp @@ -0,0 +1,176 @@ +// $Id$ + +#include "ace/Read_Buffer.h" + +#include "ace/config-all.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Read_Buffer.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/Log_Msg.h" +#include "ace/Malloc_Base.h" +#include "ace/Service_Config.h" +#include "ace/OS_NS_stdio.h" + +ACE_RCSID(ace, Read_Buffer, "$Id$") + + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +void +ACE_Read_Buffer::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Read_Buffer::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("size_ = %d"), this->size_)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\noccurrences_ = %d"), this->occurrences_)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nstream_ = %x"), this->stream_)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nallocator_ = %x"), this->allocator_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_Read_Buffer::ACE_Read_Buffer (FILE *fp, + int close_on_delete, + ACE_Allocator *alloc) + : stream_ (fp), + close_on_delete_ (close_on_delete), + allocator_ (alloc) +{ + ACE_TRACE ("ACE_Read_Buffer::ACE_Read_Buffer"); + if (this->allocator_ == 0) + this->allocator_ = ACE_Allocator::instance (); +} + +#if !defined (ACE_HAS_WINCE) +ACE_Read_Buffer::ACE_Read_Buffer (ACE_HANDLE handle, + int close_on_delete, + ACE_Allocator *alloc) + : stream_ (ACE_OS::fdopen (handle, ACE_LIB_TEXT ("r"))), + close_on_delete_ (close_on_delete), + allocator_ (alloc) +{ + ACE_TRACE ("ACE_Read_Buffer::ACE_Read_Buffer"); + + if (this->allocator_ == 0) + this->allocator_ = ACE_Allocator::instance (); +} +#endif // ACE_HAS_WINCE + +ACE_Read_Buffer::~ACE_Read_Buffer (void) +{ + ACE_TRACE ("ACE_Read_Buffer::~ACE_Read_Buffer"); + + if (this->close_on_delete_) + ACE_OS::fclose (this->stream_); +} + +// Input: term the character to terminate on +// search the character to search for +// replace the character with which to replace search +// Output: a buffer containing the contents of stream +// Method: call the recursive helper function read_helper + +char * +ACE_Read_Buffer::read (int term, int search, int replace) +{ + ACE_TRACE ("ACE_Read_Buffer::read"); + this->occurrences_ = 0; + this->size_ = 0; + return this->rec_read (term, search, replace); +} + +// Input: term the termination character +// search the character to search for +// replace the character with which to replace search +// Purpose: read in a file to a buffer using only a single dynamic +// allocation. +// Method: read until the local buffer is full and then recurse. +// Must continue until the termination character is reached. +// Allocate the final buffer based on the number of local +// buffers read and as the recursive calls bottom out, +// copy them in reverse order into the allocated buffer. + +char * +ACE_Read_Buffer::rec_read (int term, int search, int replace) +{ + ACE_TRACE ("ACE_Read_Buffer::rec_read"); + // This is our temporary workspace. + char buf[BUFSIZ]; + + int c = EOF; + size_t slot = 0; + int done = 0; + + // Read in the file char by char + while (slot < BUFSIZ) + { + c = getc (this->stream_); + + // Don't insert EOF into the buffer... + if (c == EOF) + { + ungetc (c, this->stream_); + break; + } + else if (c == term) + done = 1; + + // Check for possible substitutions. + if (c == search) + { + this->occurrences_++; + + if (replace >= 0) + c = replace; + } + + buf[slot++] = (char) c; + + // Substitutions must be made before checking for termination. + if (done) + break; + } + + // Increment the number of bytes. + this->size_ += slot; + + // Don't bother going any farther if the total size is 0. + if (this->size_ == 0) + return 0; + + char *result; + + // Recurse, when the recursion bottoms out, allocate the result + // buffer. + if (done || c == EOF) + { + // Use the allocator to acquire the memory. The + 1 allows + // space for the null terminator. + result = (char *) this->allocator_->malloc (this->size_ + 1); + + if (result == 0) + { + errno = ENOMEM; + return 0; + } + result += this->size_; + + // Null terminate the buffer. + *result = '\0'; + } + else if ((result = this->rec_read (term, search, replace)) == 0) + return 0; + + // Copy buf into the appropriate location starting from end of + // buffer. Peter says this is confusing and that we should use + // memcpy() ;-) + for (size_t j = slot; j > 0; j--) + *--result = buf[j - 1]; + + return result; +} + +ACE_END_VERSIONED_NAMESPACE_DECL |