summaryrefslogtreecommitdiff
path: root/ACE/ace/Read_Buffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/ace/Read_Buffer.cpp')
-rw-r--r--ACE/ace/Read_Buffer.cpp176
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