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.
|
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
39 PEGASUS_NAMESPACE_BEGIN
40
41 BufferRep Buffer::_empty_rep = { 0, 0, {0} };
42
|
44 mike 1.2
45 static Uint32 _next_pow_2(Uint32 x)
46 {
47 if (x < MIN_CAPACITY)
48 return MIN_CAPACITY;
49
50 x--;
51 x |= (x >> 1);
52 x |= (x >> 2);
53 x |= (x >> 4);
54 x |= (x >> 8);
55 x |= (x >> 16);
56 x++;
57
58 return x;
59 }
60
61 static inline BufferRep* _allocate(size_t cap)
62 {
63 BufferRep* rep = (BufferRep*)malloc(sizeof(BufferRep) + cap);
64 rep->cap = cap;
65 mike 1.2 return rep;
66 }
67
68 static inline BufferRep* _reallocate(BufferRep* rep, size_t cap)
69 {
70 rep = (BufferRep*)realloc(rep, sizeof(BufferRep) + cap);
71 rep->cap = cap;
72 return rep;
73 }
74
75 Buffer::Buffer(const Buffer& x)
76 {
77 _rep = _allocate(x._rep->cap);
78 memcpy(_rep->data, x._rep->data, x._rep->size);
79 _rep->size = x._rep->size;
80 }
81
82 Buffer::Buffer(const char* data, size_t size)
83 {
84 _rep = _allocate(size);
85 _rep->size = size;
86 mike 1.2 memcpy(_rep->data, data, size);
87 }
88
89 Buffer& Buffer::operator=(const Buffer& x)
90 {
91 if (&x != this)
92 {
93 if (x._rep->size > _rep->cap)
94 {
95 if (_rep != &_empty_rep)
96 free(_rep);
97
98 _rep = _allocate(x._rep->cap);
99 }
100
101 memcpy(_rep->data, x._rep->data, x._rep->size);
102 _rep->size = x._rep->size;
103 }
104 return *this;
105 }
106
107 mike 1.2 void Buffer::_reserve_aux(size_t cap)
108 {
109 if (_rep == &_empty_rep)
110 {
111 _rep = _allocate(cap);
112 _rep->size = 0;
113 }
114 else
115 _rep = _reallocate(_rep, _next_pow_2(cap));
116 }
117
118 void Buffer::_append_char_aux()
119 {
120 if (_rep == &_empty_rep)
121 {
122 _rep = _allocate(MIN_CAPACITY);
123 _rep->size = 0;
124 }
125 else
126 _rep = _reallocate(_rep, _rep->cap ? (2 * _rep->cap) : MIN_CAPACITY);
127 }
128 mike 1.2
129 void Buffer::insert(size_t pos, const char* data, size_t size)
130 {
131 if (pos > _rep->size)
132 return;
133
134 size_t cap = _rep->size + size;
135 size_t rem = _rep->size - pos;
136
137 if (cap > _rep->cap)
138 {
139 BufferRep* rep = _allocate(cap);
140 rep->size = cap;
141
142 memcpy(rep->data, _rep->data, pos);
143 memcpy(rep->data + pos, data, size);
144 memcpy(rep->data + pos + size, _rep->data + pos, rem);
145
146 if (_rep != &_empty_rep)
147 free(_rep);
148
149 mike 1.2 _rep = rep;
150 }
151 else
152 {
153 memmove(_rep->data + pos + size, _rep->data + pos, rem);
154 memcpy(_rep->data + pos, data, size);
155 _rep->size += size;
156 }
157 }
158
159 void Buffer::remove(size_t pos, size_t size)
160 {
161 if (pos + size > _rep->size)
162 return;
163
164 size_t rem = _rep->size - (pos + size);
165
166 if (rem)
167 memmove(_rep->data + pos, _rep->data + pos + size, rem);
168
169 _rep->size -= size;
170 mike 1.2 }
171
172 PEGASUS_NAMESPACE_END
|