(file) Return to Buffer.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

Diff for /pegasus/src/Pegasus/Common/Buffer.cpp between version 1.3.2.1 and 1.13

version 1.3.2.1, 2006/02/10 16:09:33 version 1.13, 2007/12/10 14:11:29
Line 29 
Line 29 
 // //
 //============================================================================== //==============================================================================
 // //
 // Author: Michael E. Brasher (mike-brasher@austin.rr.com -- Inova Europe)  
 //  
 //%///////////////////////////////////////////////////////////////////////////// //%/////////////////////////////////////////////////////////////////////////////
  
 #include <cstring> #include <cstring>
 #include "Buffer.h" #include "Buffer.h"
   #include "Pegasus/Common/InternalException.h"
  
 PEGASUS_NAMESPACE_BEGIN PEGASUS_NAMESPACE_BEGIN
  
 BufferRep Buffer::_empty_rep = { 0, 0, {0} };  //
   // Note: _empty_rep is the only BufferRep object that may have a zero capacity.
 static const size_t MIN_CAPACITY = 2048;  // So "_rep->cap == 0" implies "_rep == _empty_rep". But some platforms produce
   // more than one instance of _empty_rep (strangely). Therefore, it is safer to
   // use the former test rather than the latter.
   //
   BufferRep Buffer::_empty_rep =
   {
       0, /* size */
       0, /* cap (zero implies it is the _empty_rep) */
       {0} /* data[0] */
   };
  
 static Uint32 _next_pow_2(Uint32 x)  static Uint32 _next_pow_2(Uint32 x, Uint32 minCap)
 { {
     if (x < MIN_CAPACITY)      // Check for potential overflow in x.
         return MIN_CAPACITY;      PEGASUS_CHECK_CAPACITY_OVERFLOW(x);
   
       if (x < minCap)
           return minCap;
  
     x--;     x--;
     x |= (x >> 1);     x |= (x >> 1);
Line 58 
Line 69 
     return x;     return x;
 } }
  
 static inline BufferRep* _allocate(size_t cap)  static inline BufferRep* _allocate(Uint32 cap, Uint32 minCap)
 { {
     BufferRep* rep = (BufferRep*)malloc(sizeof(BufferRep) + cap);      if (cap < minCap)
           cap = minCap;
   
       // Allocate an extra byte for null-termination performed by getData().
       BufferRep* rep = (BufferRep*)malloc(sizeof(BufferRep) + cap + 1);
   
       if (!rep)
       {
           throw PEGASUS_STD(bad_alloc)();
       }
     rep->cap = cap;     rep->cap = cap;
     return rep;     return rep;
 } }
  
 static inline BufferRep* _reallocate(BufferRep* rep, size_t cap)  static inline BufferRep* _reallocate(BufferRep* rep, Uint32 cap)
   {
       // Allocate an extra byte for null-termination performed by getData().
       rep = (BufferRep*)realloc(rep, sizeof(BufferRep) + cap + 1);
   
       if (!rep)
 { {
     rep = (BufferRep*)realloc(rep, sizeof(BufferRep) + cap);          throw PEGASUS_STD(bad_alloc)();
       }
     rep->cap = cap;     rep->cap = cap;
     return rep;     return rep;
 } }
  
 Buffer::Buffer(const Buffer& x) Buffer::Buffer(const Buffer& x)
 { {
     _rep = _allocate(x._rep->cap);      _rep = _allocate(x._rep->cap, x._minCap);
     memcpy(_rep->data, x._rep->data, x._rep->size);     memcpy(_rep->data, x._rep->data, x._rep->size);
     _rep->size = x._rep->size;     _rep->size = x._rep->size;
       _minCap=x._minCap;
 } }
  
 Buffer::Buffer(const char* data, size_t size)  Buffer::Buffer(const char* data, Uint32 size, Uint32 minCap): _minCap(minCap)
 { {
     _rep = _allocate(size);      _rep = _allocate(size, _minCap);
     _rep->size = size;     _rep->size = size;
     memcpy(_rep->data, data, size);     memcpy(_rep->data, data, size);
 } }
Line 92 
Line 119 
     {     {
         if (x._rep->size > _rep->cap)         if (x._rep->size > _rep->cap)
         {         {
             if (_rep != &_empty_rep)              if (_rep->cap != 0)
                 free(_rep);                 free(_rep);
  
             _rep = _allocate(x._rep->cap);              _rep = _allocate(x._rep->cap, x._minCap);
         }         }
  
         memcpy(_rep->data, x._rep->data, x._rep->size);         memcpy(_rep->data, x._rep->data, x._rep->size);
         _rep->size = x._rep->size;         _rep->size = x._rep->size;
           _minCap = x._minCap;
     }     }
     return *this;     return *this;
 } }
  
 void Buffer::_reserve_aux(size_t cap)  void Buffer::_reserve_aux(Uint32 cap)
 { {
     if (_rep == &_empty_rep)      if (_rep->cap == 0)
     {     {
         _rep = _allocate(cap);          _rep = _allocate(cap, _minCap);
         _rep->size = 0;         _rep->size = 0;
     }     }
     else     else
         _rep = _reallocate(_rep, _next_pow_2(cap));          _rep = _reallocate(_rep, _next_pow_2(cap, _minCap));
 } }
  
 void Buffer::_append_char_aux() void Buffer::_append_char_aux()
 { {
     if (_rep == &_empty_rep)      if (_rep->cap == 0)
     {     {
         _rep = _allocate(MIN_CAPACITY);          _rep = _allocate(_minCap, _minCap);
         _rep->size = 0;         _rep->size = 0;
     }     }
     else     else
         _rep = _reallocate(_rep, _rep->cap ? (2 * _rep->cap) : MIN_CAPACITY);      {
           // Check for potential overflow.
           PEGASUS_CHECK_CAPACITY_OVERFLOW(_rep->cap);
           _rep = _reallocate(_rep, _rep->cap ? (2 * _rep->cap) : _minCap);
       }
 } }
  
 void Buffer::insert(size_t pos, const char* data, size_t size)  void Buffer::insert(Uint32 pos, const char* data, Uint32 size)
 { {
     if (pos > _rep->size)     if (pos > _rep->size)
         return;         return;
  
     size_t cap = _rep->size + size;      Uint32 cap = _rep->size + size;
     size_t rem = _rep->size - pos;      Uint32 rem = _rep->size - pos;
  
     if (cap > _rep->cap)     if (cap > _rep->cap)
     {     {
         BufferRep* rep = _allocate(cap);          BufferRep* rep = _allocate(cap, _minCap);
         rep->size = cap;         rep->size = cap;
  
         memcpy(rep->data, _rep->data, pos);         memcpy(rep->data, _rep->data, pos);
         memcpy(rep->data + pos, data, size);         memcpy(rep->data + pos, data, size);
         memcpy(rep->data + pos + size, _rep->data + pos, rem);         memcpy(rep->data + pos + size, _rep->data + pos, rem);
  
         if (_rep != &_empty_rep)          if (_rep->cap != 0)
             free(_rep);             free(_rep);
  
         _rep = rep;         _rep = rep;
Line 156 
Line 188 
     }     }
 } }
  
 void Buffer::remove(size_t pos, size_t size)  void Buffer::remove(Uint32 pos, Uint32 size)
 { {
     if (pos + size > _rep->size)     if (pos + size > _rep->size)
         return;         return;
  
     size_t rem = _rep->size - (pos + size);      Uint32 rem = _rep->size - (pos + size);
  
     if (rem)     if (rem)
         memmove(_rep->data + pos, _rep->data + pos + size, rem);         memmove(_rep->data + pos, _rep->data + pos + size, rem);


Legend:
Removed from v.1.3.2.1  
changed lines
  Added in v.1.13

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2