214 jio_snprintf(buf, buflen, UINTX_FORMAT, log->thread_id());
215 file->print_raw(buf);
216 file->print_raw_cr("'>");
217
218 size_t nr; // number read into buf from partial log
219 // Copy data up to the end of the last <event> element:
220 julong to_read = log->_file_end;
221 while (to_read > 0) {
222 if (to_read < (julong)buflen)
223 nr = (size_t)to_read;
224 else nr = buflen;
225 nr = read(partial_fd, buf, (int)nr);
226 if (nr <= 0) break;
227 to_read -= (julong)nr;
228 file->write(buf, nr);
229 }
230
231 // Copy any remaining data inside a quote:
232 bool saw_slop = false;
233 int end_cdata = 0; // state machine [0..2] watching for too many "]]"
234 while ((nr = read(partial_fd, buf, buflen)) > 0) {
235 if (!saw_slop) {
236 file->print_raw_cr("<fragment>");
237 file->print_raw_cr("<![CDATA[");
238 saw_slop = true;
239 }
240 // The rest of this loop amounts to a simple copy operation:
241 // { file->write(buf, nr); }
242 // However, it must sometimes output the buffer in parts,
243 // in case there is a CDATA quote embedded in the fragment.
244 const char* bufp; // pointer into buf
245 size_t nw; // number written in each pass of the following loop:
246 for (bufp = buf; nr > 0; nr -= nw, bufp += nw) {
247 // Write up to any problematic CDATA delimiter (usually all of nr).
248 for (nw = 0; nw < nr; nw++) {
249 // First, scan ahead into the buf, checking the state machine.
250 switch (bufp[nw]) {
251 case ']':
252 if (end_cdata < 2) end_cdata += 1; // saturating counter
253 continue; // keep scanning
254 case '>':
|
214 jio_snprintf(buf, buflen, UINTX_FORMAT, log->thread_id());
215 file->print_raw(buf);
216 file->print_raw_cr("'>");
217
218 size_t nr; // number read into buf from partial log
219 // Copy data up to the end of the last <event> element:
220 julong to_read = log->_file_end;
221 while (to_read > 0) {
222 if (to_read < (julong)buflen)
223 nr = (size_t)to_read;
224 else nr = buflen;
225 nr = read(partial_fd, buf, (int)nr);
226 if (nr <= 0) break;
227 to_read -= (julong)nr;
228 file->write(buf, nr);
229 }
230
231 // Copy any remaining data inside a quote:
232 bool saw_slop = false;
233 int end_cdata = 0; // state machine [0..2] watching for too many "]]"
234 while ((nr = read(partial_fd, buf, buflen-1)) > 0) {
235 buf[buflen-1] = '\0';
236 if (!saw_slop) {
237 file->print_raw_cr("<fragment>");
238 file->print_raw_cr("<![CDATA[");
239 saw_slop = true;
240 }
241 // The rest of this loop amounts to a simple copy operation:
242 // { file->write(buf, nr); }
243 // However, it must sometimes output the buffer in parts,
244 // in case there is a CDATA quote embedded in the fragment.
245 const char* bufp; // pointer into buf
246 size_t nw; // number written in each pass of the following loop:
247 for (bufp = buf; nr > 0; nr -= nw, bufp += nw) {
248 // Write up to any problematic CDATA delimiter (usually all of nr).
249 for (nw = 0; nw < nr; nw++) {
250 // First, scan ahead into the buf, checking the state machine.
251 switch (bufp[nw]) {
252 case ']':
253 if (end_cdata < 2) end_cdata += 1; // saturating counter
254 continue; // keep scanning
255 case '>':
|