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

  1 martin 1.14 //%LICENSE////////////////////////////////////////////////////////////////
  2 martin 1.15 //
  3 martin 1.14 // Licensed to The Open Group (TOG) under one or more contributor license
  4             // agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
  5             // this work for additional information regarding copyright ownership.
  6             // Each contributor licenses this file to you under the OpenPegasus Open
  7             // Source License; you may not use this file except in compliance with the
  8             // License.
  9 martin 1.15 //
 10 martin 1.14 // Permission is hereby granted, free of charge, to any person obtaining a
 11             // copy of this software and associated documentation files (the "Software"),
 12             // to deal in the Software without restriction, including without limitation
 13             // the rights to use, copy, modify, merge, publish, distribute, sublicense,
 14             // and/or sell copies of the Software, and to permit persons to whom the
 15             // Software is furnished to do so, subject to the following conditions:
 16 martin 1.15 //
 17 martin 1.14 // The above copyright notice and this permission notice shall be included
 18             // in all copies or substantial portions of the Software.
 19 martin 1.15 //
 20 martin 1.14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 21 martin 1.15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 22 martin 1.14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 23             // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 24             // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 25             // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 26             // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 27 martin 1.15 //
 28 martin 1.14 //////////////////////////////////////////////////////////////////////////
 29 mike   1.2  //
 30             //%/////////////////////////////////////////////////////////////////////////////
 31             
 32             #include <cstring>
 33             #include "Buffer.h"
 34 kumpf  1.5  #include "Pegasus/Common/InternalException.h"
 35 dl.meetei 1.17 #include "Pegasus/Common/Pegasus_inl.h"
 36 mike      1.2  
 37                PEGASUS_NAMESPACE_BEGIN
 38                
 39 gs.keenan 1.7  //
 40                // Note: _empty_rep is the only BufferRep object that may have a zero capacity.
 41                // So "_rep->cap == 0" implies "_rep == _empty_rep". But some platforms produce
 42 kumpf     1.10 // more than one instance of _empty_rep (strangely). Therefore, it is safer to
 43 gs.keenan 1.7  // use the former test rather than the latter.
 44                //
 45 kumpf     1.10 BufferRep Buffer::_empty_rep =
 46                {
 47 gs.keenan 1.7      0, /* size */
 48                    0, /* cap (zero implies it is the _empty_rep) */
 49                    {0} /* data[0] */
 50                };
 51 mike      1.2  
 52 marek     1.13 static Uint32 _next_pow_2(Uint32 x, Uint32 minCap)
 53 mike      1.2  {
 54 dave.sudlik 1.6      // Check for potential overflow in x.
 55                      PEGASUS_CHECK_CAPACITY_OVERFLOW(x);
 56                  
 57 marek       1.13     if (x < minCap)
 58                          return minCap;
 59 mike        1.2  
 60                      x--;
 61                      x |= (x >> 1);
 62                      x |= (x >> 2);
 63                      x |= (x >> 4);
 64                      x |= (x >> 8);
 65                      x |= (x >> 16);
 66                      x++;
 67                  
 68                      return x;
 69                  }
 70                  
 71 marek       1.13 static inline BufferRep* _allocate(Uint32 cap, Uint32 minCap)
 72 mike        1.2  {
 73 marek       1.13     if (cap < minCap)
 74                          cap = minCap;
 75 gs.keenan   1.7  
 76                      // Allocate an extra byte for null-termination performed by getData().
 77                      BufferRep* rep = (BufferRep*)malloc(sizeof(BufferRep) + cap + 1);
 78                  
 79 kumpf       1.5      if (!rep)
 80                      {
 81                          throw PEGASUS_STD(bad_alloc)();
 82                      }
 83 mike        1.2      rep->cap = cap;
 84                      return rep;
 85                  }
 86                  
 87 kumpf       1.12 static inline BufferRep* _reallocate(BufferRep* rep, Uint32 cap)
 88 mike        1.2  {
 89 gs.keenan   1.7      // Allocate an extra byte for null-termination performed by getData().
 90 dl.meetei   1.18     rep = (BufferRep*)peg_inln_realloc(rep, sizeof(BufferRep) + cap + 1);
 91 gs.keenan   1.7  
 92 mike        1.2      rep->cap = cap;
 93                      return rep;
 94                  }
 95                  
 96                  Buffer::Buffer(const Buffer& x)
 97                  {
 98 marek       1.13     _rep = _allocate(x._rep->cap, x._minCap);
 99 mike        1.2      memcpy(_rep->data, x._rep->data, x._rep->size);
100                      _rep->size = x._rep->size;
101 marek       1.13     _minCap=x._minCap;
102 mike        1.2  }
103                  
104 marek       1.13 Buffer::Buffer(const char* data, Uint32 size, Uint32 minCap): _minCap(minCap)
105 mike        1.2  {
106 marek       1.13     _rep = _allocate(size, _minCap);
107 mike        1.2      _rep->size = size;
108                      memcpy(_rep->data, data, size);
109                  }
110                  
111                  Buffer& Buffer::operator=(const Buffer& x)
112                  {
113                      if (&x != this)
114                      {
115 kumpf       1.10         if (x._rep->size > _rep->cap)
116                          {
117                              if (_rep->cap != 0)
118                                  free(_rep);
119 mike        1.2  
120 marek       1.13             _rep = _allocate(x._rep->cap, x._minCap);
121 kumpf       1.10         }
122 mike        1.2  
123 kumpf       1.10         memcpy(_rep->data, x._rep->data, x._rep->size);
124                          _rep->size = x._rep->size;
125 marek       1.13         _minCap = x._minCap;
126 mike        1.2      }
127                      return *this;
128                  }
129                  
130 kumpf       1.12 void Buffer::_reserve_aux(Uint32 cap)
131 mike        1.2  {
132 gs.keenan   1.7      if (_rep->cap == 0)
133 mike        1.2      {
134 marek       1.13         _rep = _allocate(cap, _minCap);
135 kumpf       1.10         _rep->size = 0;
136 mike        1.2      }
137                      else
138 marek       1.13         _rep = _reallocate(_rep, _next_pow_2(cap, _minCap));
139 mike        1.2  }
140                  
141                  void Buffer::_append_char_aux()
142                  {
143 gs.keenan   1.7      if (_rep->cap == 0)
144 mike        1.2      {
145 marek       1.13         _rep = _allocate(_minCap, _minCap);
146 kumpf       1.10         _rep->size = 0;
147 mike        1.2      }
148                      else
149 dave.sudlik 1.6      {
150                          // Check for potential overflow.
151                          PEGASUS_CHECK_CAPACITY_OVERFLOW(_rep->cap);
152 marek       1.13         _rep = _reallocate(_rep, _rep->cap ? (2 * _rep->cap) : _minCap);
153 dave.sudlik 1.6      }
154 mike        1.2  }
155                  
156 kumpf       1.12 void Buffer::insert(Uint32 pos, const char* data, Uint32 size)
157 mike        1.2  {
158                      if (pos > _rep->size)
159 kumpf       1.10         return;
160 mike        1.2  
161 kumpf       1.12     Uint32 cap = _rep->size + size;
162                      Uint32 rem = _rep->size - pos;
163 mike        1.2  
164                      if (cap > _rep->cap)
165                      {
166 marek       1.13         BufferRep* rep = _allocate(cap, _minCap);
167 kumpf       1.10         rep->size = cap;
168 mike        1.2  
169 kumpf       1.10         memcpy(rep->data, _rep->data, pos);
170                          memcpy(rep->data + pos, data, size);
171                          memcpy(rep->data + pos + size, _rep->data + pos, rem);
172 mike        1.2  
173 kumpf       1.10         if (_rep->cap != 0)
174                              free(_rep);
175 mike        1.2  
176 kumpf       1.10         _rep = rep;
177 mike        1.2      }
178                      else
179                      {
180                          memmove(_rep->data + pos + size, _rep->data + pos, rem);
181 kumpf       1.10         memcpy(_rep->data + pos, data, size);
182                          _rep->size += size;
183 mike        1.2      }
184                  }
185                  
186 marek       1.16 void Buffer::insertWithOverlay(
187                      Uint32 pos,
188                      const char* data,
189                      Uint32 size,
190                      Uint32 overlay)
191                  {
192                      if (pos > _rep->size)
193                          return;
194                  
195                      Uint32 rem = _rep->size - pos;
196                  
197                      memmove(_rep->data + pos + size - overlay, _rep->data + pos, rem);
198                      memcpy(_rep->data + pos, data, size);
199                  
200                      _rep->size += (size-overlay);
201                  }
202                  
203 kumpf       1.12 void Buffer::remove(Uint32 pos, Uint32 size)
204 mike        1.2  {
205                      if (pos + size > _rep->size)
206 kumpf       1.10         return;
207 mike        1.2  
208 kumpf       1.12     Uint32 rem = _rep->size - (pos + size);
209 mike        1.2  
210                      if (rem)
211 kumpf       1.10         memmove(_rep->data + pos, _rep->data + pos + size, rem);
212 mike        1.2  
213                      _rep->size -= size;
214                  }
215                  
216                  PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2