]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * Copyright (C) 1996-2018 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_CLASS_INIT(ESISegment); | |
17 | ||
18 | void | |
19 | ESISegmentFreeList (ESISegment::Pointer &head) | |
20 | { | |
21 | while (head.getRaw()) { | |
22 | ESISegment::Pointer temp = head; | |
23 | head = head->next; | |
24 | temp->next = NULL; | |
25 | } | |
26 | } | |
27 | ||
28 | size_t | |
29 | ESISegment::space() const | |
30 | { | |
31 | assert (len <= sizeof(buf)); | |
32 | return sizeof (buf) - len; | |
33 | } | |
34 | ||
35 | void | |
36 | ESISegment::adsorbList (ESISegment::Pointer from) | |
37 | { | |
38 | assert (next.getRaw() == NULL); | |
39 | assert (from.getRaw() != NULL); | |
40 | /* prevent worst case */ | |
41 | assert (!(len == 0 && from->len == space() )); | |
42 | Pointer copyFrom = from; | |
43 | ||
44 | while (copyFrom.getRaw() && space() >= copyFrom->len) { | |
45 | assert (append (copyFrom) == copyFrom->len); | |
46 | copyFrom = copyFrom->next; | |
47 | } | |
48 | ||
49 | next = copyFrom; | |
50 | } | |
51 | ||
52 | void | |
53 | ESISegment::ListTransfer (ESISegment::Pointer &from, ESISegment::Pointer &to) | |
54 | { | |
55 | if (!to.getRaw()) { | |
56 | to = from; | |
57 | from = NULL; | |
58 | return; | |
59 | } | |
60 | ||
61 | ESISegment::Pointer temp = to->tail(); | |
62 | temp->adsorbList (from); | |
63 | from = NULL; | |
64 | } | |
65 | ||
66 | size_t | |
67 | ESISegment::listLength() const | |
68 | { | |
69 | size_t result = 0; | |
70 | ESISegment const* temp = this; | |
71 | ||
72 | while (temp) { | |
73 | result += temp->len; | |
74 | temp = temp->next.getRaw(); | |
75 | } | |
76 | ||
77 | return result; | |
78 | } | |
79 | ||
80 | char * | |
81 | ESISegment::listToChar() const | |
82 | { | |
83 | size_t length = listLength(); | |
84 | char *rv = (char *)xmalloc (length + 1); | |
85 | assert (rv); | |
86 | rv [length] = '\0'; | |
87 | ||
88 | ESISegment::Pointer temp = this; | |
89 | size_t pos = 0; | |
90 | ||
91 | while (temp.getRaw()) { | |
92 | memcpy(&rv[pos], temp->buf, temp->len); | |
93 | pos += temp->len; | |
94 | temp = temp->next; | |
95 | } | |
96 | ||
97 | return rv; | |
98 | } | |
99 | ||
100 | void | |
101 | ESISegment::listAppend (char const *s, size_t length) | |
102 | { | |
103 | assert (next.getRaw() == NULL); | |
104 | ESISegment::Pointer output = this; | |
105 | /* copy the string to output */ | |
106 | size_t pos=0; | |
107 | ||
108 | while (pos < length) { | |
109 | if (output->space() == 0) { | |
110 | assert (output->next.getRaw() == NULL); | |
111 | output->next = new ESISegment; | |
112 | output = output->next; | |
113 | } | |
114 | ||
115 | pos += output->append(s + pos, length - pos); | |
116 | } | |
117 | } | |
118 | ||
119 | void | |
120 | ESISegment::ListAppend (ESISegment::Pointer &head, char const *s, size_t len) | |
121 | { | |
122 | if (!head.getRaw()) | |
123 | head = new ESISegment; | |
124 | ||
125 | head->tail()->listAppend (s, len); | |
126 | } | |
127 | ||
128 | /* XXX: if needed, make this iterative */ | |
129 | ESISegment::Pointer | |
130 | ESISegment::cloneList () const | |
131 | { | |
132 | ESISegment::Pointer result = new ESISegment (*this); | |
133 | result->next = next.getRaw() ? next->cloneList() : NULL; | |
134 | return result; | |
135 | } | |
136 | ||
137 | size_t | |
138 | ESISegment::append(char const *appendBuffer, size_t appendLength) | |
139 | { | |
140 | size_t toCopy = min(appendLength, space()); | |
141 | memcpy(&buf[len], appendBuffer, toCopy); | |
142 | len += toCopy; | |
143 | return toCopy; | |
144 | } | |
145 | ||
146 | size_t | |
147 | ESISegment::append(ESISegment::Pointer from) | |
148 | { | |
149 | return append (from->buf, from->len); | |
150 | } | |
151 | ||
152 | ESISegment const * | |
153 | ESISegment::tail() const | |
154 | { | |
155 | ESISegment const *result = this; | |
156 | ||
157 | while (result->next.getRaw()) | |
158 | result = result->next.getRaw(); | |
159 | ||
160 | return result; | |
161 | } | |
162 | ||
163 | ESISegment * | |
164 | ESISegment::tail() | |
165 | { | |
166 | ESISegment::Pointer result = this; | |
167 | ||
168 | while (result->next.getRaw()) | |
169 | result = result->next; | |
170 | ||
171 | return result.getRaw(); | |
172 | } | |
173 | ||
174 | ESISegment::ESISegment(ESISegment const &old) : len (0), next(NULL) | |
175 | { | |
176 | append (old.buf, old.len); | |
177 | } | |
178 | ||
179 | void | |
180 | ESISegment::dumpToLog() const | |
181 | { | |
182 | ESISegment::Pointer temp = this; | |
183 | ||
184 | while (temp.getRaw()) { | |
185 | temp->dumpOne(); | |
186 | temp = temp->next; | |
187 | } | |
188 | } | |
189 | ||
190 | void | |
191 | ESISegment::dumpOne() const | |
192 | { | |
193 | String temp; | |
194 | temp.limitInit(buf, len); | |
195 | debugs(86, 9, "ESISegment::dumpOne: \"" << temp << "\""); | |
196 | } | |
197 |