]> git.ipfire.org Git - thirdparty/squid.git/blob - src/esi/Segment.cc
Merged from trunk
[thirdparty/squid.git] / src / esi / Segment.cc
1 /*
2 * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9 /* DEBUG: section 86 ESI processing */
10
11 #include "squid.h"
12 #include "Debug.h"
13 #include "esi/Segment.h"
14 #include "SquidString.h"
15
16 CBDATA_TYPE(ESISegment);
17
18 /* ESISegment */
19 void
20 ESISegmentFreeList (ESISegment::Pointer &head)
21 {
22 while (head.getRaw()) {
23 ESISegment::Pointer temp = head;
24 head = head->next;
25 temp->next = NULL;
26 }
27 }
28
29 size_t
30 ESISegment::space() const
31 {
32 assert (len <= sizeof(buf));
33 return sizeof (buf) - len;
34 }
35
36 void
37 ESISegment::adsorbList (ESISegment::Pointer from)
38 {
39 assert (next.getRaw() == NULL);
40 assert (from.getRaw() != NULL);
41 /* prevent worst case */
42 assert (!(len == 0 && from->len == space() ));
43 Pointer copyFrom = from;
44
45 while (copyFrom.getRaw() && space() >= copyFrom->len) {
46 assert (append (copyFrom) == copyFrom->len);
47 copyFrom = copyFrom->next;
48 }
49
50 next = copyFrom;
51 }
52
53 void
54 ESISegment::ListTransfer (ESISegment::Pointer &from, ESISegment::Pointer &to)
55 {
56 if (!to.getRaw()) {
57 to = from;
58 from = NULL;
59 return;
60 }
61
62 ESISegment::Pointer temp = to->tail();
63 temp->adsorbList (from);
64 from = NULL;
65 }
66
67 size_t
68 ESISegment::listLength() const
69 {
70 size_t result = 0;
71 ESISegment const* temp = this;
72
73 while (temp) {
74 result += temp->len;
75 temp = temp->next.getRaw();
76 }
77
78 return result;
79 }
80
81 char *
82 ESISegment::listToChar() const
83 {
84 size_t length = listLength();
85 char *rv = (char *)xmalloc (length + 1);
86 assert (rv);
87 rv [length] = '\0';
88
89 ESISegment::Pointer temp = this;
90 size_t pos = 0;
91
92 while (temp.getRaw()) {
93 memcpy(&rv[pos], temp->buf, temp->len);
94 pos += temp->len;
95 temp = temp->next;
96 }
97
98 return rv;
99 }
100
101 void
102 ESISegment::listAppend (char const *s, size_t length)
103 {
104 assert (next.getRaw() == NULL);
105 ESISegment::Pointer output = this;
106 /* copy the string to output */
107 size_t pos=0;
108
109 while (pos < length) {
110 if (output->space() == 0) {
111 assert (output->next.getRaw() == NULL);
112 output->next = new ESISegment;
113 output = output->next;
114 }
115
116 pos += output->append(s + pos, length - pos);
117 }
118 }
119
120 void
121 ESISegment::ListAppend (ESISegment::Pointer &head, char const *s, size_t len)
122 {
123 if (!head.getRaw())
124 head = new ESISegment;
125
126 head->tail()->listAppend (s, len);
127 }
128
129 void *
130 ESISegment::operator new(size_t byteCount)
131 {
132 assert (byteCount == sizeof (ESISegment));
133 void *rv;
134 CBDATA_INIT_TYPE(ESISegment);
135 rv = (void *)cbdataAlloc (ESISegment);
136 return rv;
137 }
138
139 void
140 ESISegment::operator delete (void *address)
141 {
142 cbdataFree (address);
143 }
144
145 /* XXX: if needed, make this iterative */
146 ESISegment::Pointer
147 ESISegment::cloneList () const
148 {
149 ESISegment::Pointer result = new ESISegment (*this);
150 result->next = next.getRaw() ? next->cloneList() : NULL;
151 return result;
152 }
153
154 size_t
155 ESISegment::append(char const *appendBuffer, size_t appendLength)
156 {
157 size_t toCopy = min(appendLength, space());
158 memcpy(&buf[len], appendBuffer, toCopy);
159 len += toCopy;
160 return toCopy;
161 }
162
163 size_t
164 ESISegment::append(ESISegment::Pointer from)
165 {
166 return append (from->buf, from->len);
167 }
168
169 ESISegment const *
170 ESISegment::tail() const
171 {
172 ESISegment const *result = this;
173
174 while (result->next.getRaw())
175 result = result->next.getRaw();
176
177 return result;
178 }
179
180 ESISegment *
181 ESISegment::tail()
182 {
183 ESISegment::Pointer result = this;
184
185 while (result->next.getRaw())
186 result = result->next;
187
188 return result.getRaw();
189 }
190
191 ESISegment::ESISegment() : len(0), next(NULL)
192 {}
193
194 ESISegment::ESISegment(ESISegment const &old) : len (0), next(NULL)
195 {
196 append (old.buf, old.len);
197 }
198
199 void
200 ESISegment::dumpToLog() const
201 {
202 ESISegment::Pointer temp = this;
203
204 while (temp.getRaw()) {
205 temp->dumpOne();
206 temp = temp->next;
207 }
208 }
209
210 void
211 ESISegment::dumpOne() const
212 {
213 String temp;
214 temp.limitInit(buf, len);
215 debugs(86, 9, "ESISegment::dumpOne: \"" << temp << "\"");
216 }
217