1 karl 1.4 //%2006////////////////////////////////////////////////////////////////////////
|
2 mike 1.2 //
3 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
6 // IBM Corp.; EMC Corporation, The Open Group.
7 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
9 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.4 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 mike 1.2 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
18 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
20 //
21 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
24 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 // Author: Michael E. Brasher (mike-brasher@austin.rr.com -- Inova Europe)
33 //
34 mike 1.2 //%/////////////////////////////////////////////////////////////////////////////
35
36 #include <cstring>
37 #include "Buffer.h"
|
38 kumpf 1.4.2.1 #include "Pegasus/Common/InternalException.h"
|
39 mike 1.2
40 PEGASUS_NAMESPACE_BEGIN
41
42 BufferRep Buffer::_empty_rep = { 0, 0, {0} };
43
|
44 mike 1.3 static const size_t MIN_CAPACITY = 2048;
|
45 mike 1.2
46 static Uint32 _next_pow_2(Uint32 x)
47 {
|
48 dave.sudlik 1.4.2.2 // Check for potential overflow in x.
49 PEGASUS_CHECK_CAPACITY_OVERFLOW(x);
50
|
51 mike 1.2 if (x < MIN_CAPACITY)
52 return MIN_CAPACITY;
53
54 x--;
55 x |= (x >> 1);
56 x |= (x >> 2);
57 x |= (x >> 4);
58 x |= (x >> 8);
59 x |= (x >> 16);
60 x++;
61
62 return x;
63 }
64
65 static inline BufferRep* _allocate(size_t cap)
66 {
67 BufferRep* rep = (BufferRep*)malloc(sizeof(BufferRep) + cap);
|
68 kumpf 1.4.2.1 if (!rep)
69 {
70 throw PEGASUS_STD(bad_alloc)();
71 }
|
72 mike 1.2 rep->cap = cap;
73 return rep;
74 }
75
76 static inline BufferRep* _reallocate(BufferRep* rep, size_t cap)
77 {
78 rep = (BufferRep*)realloc(rep, sizeof(BufferRep) + cap);
|
79 kumpf 1.4.2.1 if (!rep)
80 {
81 throw PEGASUS_STD(bad_alloc)();
82 }
|
83 mike 1.2 rep->cap = cap;
84 return rep;
85 }
86
87 Buffer::Buffer(const Buffer& x)
88 {
89 _rep = _allocate(x._rep->cap);
90 memcpy(_rep->data, x._rep->data, x._rep->size);
91 _rep->size = x._rep->size;
92 }
93
94 Buffer::Buffer(const char* data, size_t size)
95 {
96 _rep = _allocate(size);
97 _rep->size = size;
98 memcpy(_rep->data, data, size);
99 }
100
101 Buffer& Buffer::operator=(const Buffer& x)
102 {
103 if (&x != this)
104 mike 1.2 {
105 if (x._rep->size > _rep->cap)
106 {
107 if (_rep != &_empty_rep)
108 free(_rep);
109
110 _rep = _allocate(x._rep->cap);
111 }
112
113 memcpy(_rep->data, x._rep->data, x._rep->size);
114 _rep->size = x._rep->size;
115 }
116 return *this;
117 }
118
119 void Buffer::_reserve_aux(size_t cap)
120 {
121 if (_rep == &_empty_rep)
122 {
123 _rep = _allocate(cap);
124 _rep->size = 0;
125 mike 1.2 }
126 else
127 _rep = _reallocate(_rep, _next_pow_2(cap));
128 }
129
130 void Buffer::_append_char_aux()
131 {
132 if (_rep == &_empty_rep)
133 {
134 _rep = _allocate(MIN_CAPACITY);
135 _rep->size = 0;
136 }
137 else
|
138 dave.sudlik 1.4.2.2 {
139 // Check for potential overflow.
140 PEGASUS_CHECK_CAPACITY_OVERFLOW(_rep->cap);
141 _rep = _reallocate(_rep, _rep->cap ? (2 * _rep->cap) : MIN_CAPACITY);
142 }
|
143 mike 1.2 }
144
145 void Buffer::insert(size_t pos, const char* data, size_t size)
146 {
147 if (pos > _rep->size)
148 return;
149
150 size_t cap = _rep->size + size;
151 size_t rem = _rep->size - pos;
152
153 if (cap > _rep->cap)
154 {
155 BufferRep* rep = _allocate(cap);
156 rep->size = cap;
157
158 memcpy(rep->data, _rep->data, pos);
159 memcpy(rep->data + pos, data, size);
160 memcpy(rep->data + pos + size, _rep->data + pos, rem);
161
162 if (_rep != &_empty_rep)
163 free(_rep);
164 mike 1.2
165 _rep = rep;
166 }
167 else
168 {
169 memmove(_rep->data + pos + size, _rep->data + pos, rem);
170 memcpy(_rep->data + pos, data, size);
171 _rep->size += size;
172 }
173 }
174
175 void Buffer::remove(size_t pos, size_t size)
176 {
177 if (pos + size > _rep->size)
178 return;
179
180 size_t rem = _rep->size - (pos + size);
181
182 if (rem)
183 memmove(_rep->data + pos, _rep->data + pos + size, rem);
184
185 mike 1.2 _rep->size -= size;
186 }
187
188 PEGASUS_NAMESPACE_END
|