Public Member Functions | Private Member Functions | Private Attributes

ACE_Read_Buffer Class Reference

Efficiently reads an artibrarily large buffer from an input stream up to and including a termination character. Also performs search/replace on single occurrences a character in the buffer using the principles of Integrated Layer Processing. More...

#include <Read_Buffer.h>

Collaboration diagram for ACE_Read_Buffer:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 ACE_Read_Buffer (FILE *fp, bool close_on_delete=false, ACE_Allocator *=0)
 Read from a FILE *.
 ACE_Read_Buffer (ACE_HANDLE handle, bool close_on_delete=false, ACE_Allocator *=0)
 Read from an open HANDLE.
 ~ACE_Read_Buffer (void)
 Closes the FILE *.
char * read (int terminator=EOF, int search= '\n', int replace= '\0')
size_t replaced (void) const
 Returns the number of characters replaced during a read.
size_t size (void) const
ACE_Allocatoralloc (void) const
 Returns a pointer to its allocator.
void dump (void) const
 Dump the state of the object.

Private Member Functions

void operator= (const ACE_Read_Buffer &)
 ACE_Read_Buffer (const ACE_Read_Buffer &)
char * rec_read (int term, int search, int replace)
 Recursive helper method that does the work...

Private Attributes

size_t size_
 The total number of characters in the buffer.
size_t occurrences_
 The total number of characters replaced.
FILE * stream_
 The stream we are reading from.
bool const close_on_delete_
ACE_Allocatorallocator_
 Pointer to the allocator.

Detailed Description

Efficiently reads an artibrarily large buffer from an input stream up to and including a termination character. Also performs search/replace on single occurrences a character in the buffer using the principles of Integrated Layer Processing.

This implementation is optimized to do a single dynamic allocation and make only one copy of the data. It uses recursion and the run-time stack to accomplish this efficiently.

Definition at line 46 of file Read_Buffer.h.


Constructor & Destructor Documentation

ACE_Read_Buffer::ACE_Read_Buffer ( FILE *  fp,
bool  close_on_delete = false,
ACE_Allocator alloc = 0 
)

Read from a FILE *.

Definition at line 35 of file Read_Buffer.cpp.

  : 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 ();
}

ACE_Read_Buffer::ACE_Read_Buffer ( ACE_HANDLE  handle,
bool  close_on_delete = false,
ACE_Allocator alloc = 0 
)

Read from an open HANDLE.

Definition at line 48 of file Read_Buffer.cpp.

  : stream_ (ACE_OS::fdopen (handle, ACE_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 ();
}

ACE_Read_Buffer::~ACE_Read_Buffer ( void   ) 

Closes the FILE *.

Definition at line 62 of file Read_Buffer.cpp.

{
  ACE_TRACE ("ACE_Read_Buffer::~ACE_Read_Buffer");

  if (this->close_on_delete_)
    ACE_OS::fclose (this->stream_);
}

ACE_Read_Buffer::ACE_Read_Buffer ( const ACE_Read_Buffer  )  [private]

Member Function Documentation

ACE_Allocator * ACE_Read_Buffer::alloc ( void   )  const

Returns a pointer to its allocator.

Definition at line 26 of file Read_Buffer.inl.

{
  ACE_TRACE ("ACE_Read_Buffer::alloc");
  return this->allocator_;
}

void ACE_Read_Buffer::dump ( void   )  const

Dump the state of the object.

Definition at line 22 of file Read_Buffer.cpp.

{
#if defined (ACE_HAS_DUMP)
  ACE_TRACE ("ACE_Read_Buffer::dump");
  ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
  ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("size_ = %d"), this->size_));
  ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("\noccurrences_ = %d"), this->occurrences_));
  ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("\nstream_ = %x"), this->stream_));
  ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("\nallocator_ = %x"), this->allocator_));
  ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
#endif /* ACE_HAS_DUMP */
}

void ACE_Read_Buffer::operator= ( const ACE_Read_Buffer  )  [private]
char * ACE_Read_Buffer::read ( int  terminator = EOF,
int  search = '\n',
int  replace = '\0' 
)

Returns a pointer dynamically allocated with ACE_Allocator::malloc to data from the input stream up to (and including) the terminator. If search is >= 0 then all occurrences of the search value are substituted with the replace value. The last of the byte of data is a 0, so that strlen can be used on it. The caller is responsible for freeing the pointer returned from this method using the ACE_Allocator::free.

Definition at line 77 of file Read_Buffer.cpp.

{
  ACE_TRACE ("ACE_Read_Buffer::read");
  this->occurrences_ = 0;
  this->size_ = 0;
  return this->rec_read (term, search, replace);
}

char * ACE_Read_Buffer::rec_read ( int  term,
int  search,
int  replace 
) [private]

Recursive helper method that does the work...

Definition at line 97 of file Read_Buffer.cpp.

{
  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 = ACE_OS::getc (this->stream_);

      // Don't insert EOF into the buffer...
      if (c == EOF)
        {
          ACE_OS::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 = 0;

  // 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;
}

size_t ACE_Read_Buffer::replaced ( void   )  const

Returns the number of characters replaced during a read.

Definition at line 19 of file Read_Buffer.inl.

{
  ACE_TRACE ("ACE_Read_Buffer::replaced");
  return this->occurrences_;
}

size_t ACE_Read_Buffer::size ( void   )  const

Returns the size of the allocated buffer obtained during a read, not including the null terminator.

Definition at line 10 of file Read_Buffer.inl.

{
  ACE_TRACE ("ACE_Read_Buffer::size");
  return this->size_;
}


Member Data Documentation

Pointer to the allocator.

Definition at line 118 of file Read_Buffer.h.

bool const ACE_Read_Buffer::close_on_delete_ [private]

Keeps track of whether we should close the FILE in the destructor.

Definition at line 115 of file Read_Buffer.h.

The total number of characters replaced.

Definition at line 108 of file Read_Buffer.h.

size_t ACE_Read_Buffer::size_ [private]

The total number of characters in the buffer.

Definition at line 105 of file Read_Buffer.h.

FILE* ACE_Read_Buffer::stream_ [private]

The stream we are reading from.

Definition at line 111 of file Read_Buffer.h.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines