]> git.ipfire.org Git - thirdparty/squid.git/blob - src/esi/Segment.cc
merge from trunk r12441
[thirdparty/squid.git] / src / esi / Segment.cc
1
2 /*
3 * DEBUG: section 86 ESI processing
4 * AUTHOR: Robert Collins
5 *
6 * SQUID Web Proxy Cache http://www.squid-cache.org/
7 * ----------------------------------------------------------
8 *
9 * Squid is the result of efforts by numerous individuals from
10 * the Internet community; see the CONTRIBUTORS file for full
11 * details. Many organizations have provided support for Squid's
12 * development; see the SPONSORS file for full details. Squid is
13 * Copyrighted (C) 2001 by the Regents of the University of
14 * California; see the COPYRIGHT file for full details. Squid
15 * incorporates software developed and/or copyrighted by other
16 * sources; see the CREDITS file for full details.
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
31 *
32 */
33
34 #include "squid.h"
35 #include "Debug.h"
36 #include "esi/Segment.h"
37 #include "SquidString.h"
38
39 CBDATA_TYPE(ESISegment);
40
41 /* ESISegment */
42 void
43 ESISegmentFreeList (ESISegment::Pointer &head)
44 {
45 while (head.getRaw()) {
46 ESISegment::Pointer temp = head;
47 head = head->next;
48 temp->next = NULL;
49 }
50 }
51
52 size_t
53 ESISegment::space() const
54 {
55 assert (len <= sizeof(buf));
56 return sizeof (buf) - len;
57 }
58
59 void
60 ESISegment::adsorbList (ESISegment::Pointer from)
61 {
62 assert (next.getRaw() == NULL);
63 assert (from.getRaw() != NULL);
64 /* prevent worst case */
65 assert (!(len == 0 && from->len == space() ));
66 Pointer copyFrom = from;
67
68 while (copyFrom.getRaw() && space() >= copyFrom->len) {
69 assert (append (copyFrom) == copyFrom->len);
70 copyFrom = copyFrom->next;
71 }
72
73 next = copyFrom;
74 }
75
76 void
77 ESISegment::ListTransfer (ESISegment::Pointer &from, ESISegment::Pointer &to)
78 {
79 if (!to.getRaw()) {
80 to = from;
81 from = NULL;
82 return;
83 }
84
85 ESISegment::Pointer temp = to->tail();
86 temp->adsorbList (from);
87 from = NULL;
88 }
89
90 size_t
91 ESISegment::listLength() const
92 {
93 size_t result = 0;
94 ESISegment const* temp = this;
95
96 while (temp) {
97 result += temp->len;
98 temp = temp->next.getRaw();
99 }
100
101 return result;
102 }
103
104 char *
105 ESISegment::listToChar() const
106 {
107 size_t length = listLength();
108 char *rv = (char *)xmalloc (length + 1);
109 assert (rv);
110 rv [length] = '\0';
111
112 ESISegment::Pointer temp = this;
113 size_t pos = 0;
114
115 while (temp.getRaw()) {
116 memcpy(&rv[pos], temp->buf, temp->len);
117 pos += temp->len;
118 temp = temp->next;
119 }
120
121 return rv;
122 }
123
124 void
125 ESISegment::listAppend (char const *s, size_t length)
126 {
127 assert (next.getRaw() == NULL);
128 ESISegment::Pointer output = this;
129 /* copy the string to output */
130 size_t pos=0;
131
132 while (pos < length) {
133 if (output->space() == 0) {
134 assert (output->next.getRaw() == NULL);
135 output->next = new ESISegment;
136 output = output->next;
137 }
138
139 pos += output->append(s + pos, length - pos);
140 }
141 }
142
143 void
144 ESISegment::ListAppend (ESISegment::Pointer &head, char const *s, size_t len)
145 {
146 if (!head.getRaw())
147 head = new ESISegment;
148
149 head->tail()->listAppend (s, len);
150 }
151
152 void *
153 ESISegment::operator new(size_t byteCount)
154 {
155 assert (byteCount == sizeof (ESISegment));
156 void *rv;
157 CBDATA_INIT_TYPE(ESISegment);
158 rv = (void *)cbdataAlloc (ESISegment);
159 return rv;
160 }
161
162 void
163 ESISegment::operator delete (void *address)
164 {
165 cbdataFree (address);
166 }
167
168 /* XXX: if needed, make this iterative */
169 ESISegment::Pointer
170 ESISegment::cloneList () const
171 {
172 ESISegment::Pointer result = new ESISegment (*this);
173 result->next = next.getRaw() ? next->cloneList() : NULL;
174 return result;
175 }
176
177 size_t
178 ESISegment::append(char const *appendBuffer, size_t appendLength)
179 {
180 size_t toCopy = min(appendLength, space());
181 memcpy(&buf[len], appendBuffer, toCopy);
182 len += toCopy;
183 return toCopy;
184 }
185
186 size_t
187 ESISegment::append(ESISegment::Pointer from)
188 {
189 return append (from->buf, from->len);
190 }
191
192 ESISegment const *
193 ESISegment::tail() const
194 {
195 ESISegment const *result = this;
196
197 while (result->next.getRaw())
198 result = result->next.getRaw();
199
200 return result;
201 }
202
203 ESISegment *
204 ESISegment::tail()
205 {
206 ESISegment::Pointer result = this;
207
208 while (result->next.getRaw())
209 result = result->next;
210
211 return result.getRaw();
212 }
213
214 ESISegment::ESISegment() : len(0), next(NULL)
215 {}
216
217 ESISegment::ESISegment(ESISegment const &old) : len (0), next(NULL)
218 {
219 append (old.buf, old.len);
220 }
221
222 void
223 ESISegment::dumpToLog() const
224 {
225 ESISegment::Pointer temp = this;
226
227 while (temp.getRaw()) {
228 temp->dumpOne();
229 temp = temp->next;
230 }
231 }
232
233 void
234 ESISegment::dumpOne() const
235 {
236 String temp;
237 temp.limitInit(buf, len);
238 debugs(86, 9, "ESISegment::dumpOne: \"" << temp << "\"");
239 }