annotate src/lib/istream-crlf.c @ 23007:36e01285b5b8

lib: buffer - Improve header comment for buffer_insert() and buffer_delete().
author Stephan Bosch <stephan.bosch@dovecot.fi>
date Mon, 18 Mar 2019 00:52:37 +0100
parents cb108f786fb4
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
22713
cb108f786fb4 Updated copyright notices to include the year 2018.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
1 /* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */
6527
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "lib.h"
13529
cf77e448295c Renamed lib/*-internal.h files to lib/*-private.h for consistency.
Timo Sirainen <tss@iki.fi>
parents: 12782
diff changeset
4 #include "istream-private.h"
6527
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
5 #include "istream-crlf.h"
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
6
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
7 struct crlf_istream {
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
8 struct istream_private istream;
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
9
6722
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
10 unsigned int pending_cr:1;
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
11 unsigned int last_cr:1;
6527
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
12 };
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
13
6722
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
14 static int i_stream_crlf_read_common(struct crlf_istream *cstream)
6527
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
15 {
6722
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
16 struct istream_private *stream = &cstream->istream;
14629
c93ca5e46a8a Marked functions parameters that are allowed to be NULL. Some APIs were also changed.
Timo Sirainen <tss@iki.fi>
parents: 14133
diff changeset
17 size_t size, avail;
6527
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
18 ssize_t ret;
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
19
14683
9646f80ac3e9 Added i_stream_get_data_size(). Used it where possible.
Timo Sirainen <tss@iki.fi>
parents: 14629
diff changeset
20 size = i_stream_get_data_size(stream->parent);
6617
f33be4f9ba4d We called parent stream's read() too often, causing early EOFs.
Timo Sirainen <tss@iki.fi>
parents: 6563
diff changeset
21 if (size == 0) {
7030
1a89a1509e81 Use istream_private->parent pointer globally instead of each filter stream
Timo Sirainen <tss@iki.fi>
parents: 6725
diff changeset
22 ret = i_stream_read(stream->parent);
6544
Timo Sirainen <tss@iki.fi>
parents: 6527
diff changeset
23 if (ret <= 0 && (ret != -2 || stream->skip == 0)) {
Timo Sirainen <tss@iki.fi>
parents: 6527
diff changeset
24 stream->istream.stream_errno =
7030
1a89a1509e81 Use istream_private->parent pointer globally instead of each filter stream
Timo Sirainen <tss@iki.fi>
parents: 6725
diff changeset
25 stream->parent->stream_errno;
1a89a1509e81 Use istream_private->parent pointer globally instead of each filter stream
Timo Sirainen <tss@iki.fi>
parents: 6725
diff changeset
26 stream->istream.eof = stream->parent->eof;
6544
Timo Sirainen <tss@iki.fi>
parents: 6527
diff changeset
27 return ret;
Timo Sirainen <tss@iki.fi>
parents: 6527
diff changeset
28 }
14683
9646f80ac3e9 Added i_stream_get_data_size(). Used it where possible.
Timo Sirainen <tss@iki.fi>
parents: 14629
diff changeset
29 size = i_stream_get_data_size(stream->parent);
6721
9aab8ac958fb Minor optimization
Timo Sirainen <tss@iki.fi>
parents: 6697
diff changeset
30 i_assert(size != 0);
6527
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
31 }
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
32
14693
d7d1f24dde34 istreams: Renamed i_stream_get_buffer_space() to i_stream_try_alloc()
Timo Sirainen <tss@iki.fi>
parents: 14683
diff changeset
33 if (!i_stream_try_alloc(stream, size, &avail))
6558
4a1caf69ca14 Added i_stream_get_buffer_space() to remove code duplication.
Timo Sirainen <tss@iki.fi>
parents: 6552
diff changeset
34 return -2;
6722
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
35 return 1;
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
36 }
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
37
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
38 static ssize_t i_stream_crlf_read_crlf(struct istream_private *stream)
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
39 {
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
40 struct crlf_istream *cstream = (struct crlf_istream *)stream;
12054
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
41 const unsigned char *data, *ptr, *src, *src_end;
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
42 unsigned char *dest, *dest_end;
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
43 size_t size, copy_len;
6722
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
44 ssize_t ret;
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
45
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
46 ret = i_stream_crlf_read_common(cstream);
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
47 if (ret <= 0)
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
48 return ret;
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
49
12054
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
50 /* at least one byte was read */
7030
1a89a1509e81 Use istream_private->parent pointer globally instead of each filter stream
Timo Sirainen <tss@iki.fi>
parents: 6725
diff changeset
51 data = i_stream_get_data(stream->parent, &size);
6722
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
52
12054
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
53 dest = stream->w_buffer + stream->pos;
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
54 dest_end = stream->w_buffer + stream->buffer_size;
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
55 src = data;
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
56 src_end = data + size;
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
57
6722
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
58 /* @UNSAFE: add missing CRs */
12054
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
59 if (*src == '\n') {
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
60 if (!cstream->last_cr && dest < dest_end)
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
61 *dest++ = '\r';
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
62
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
63 if (dest < dest_end) {
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
64 *dest++ = '\n';
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
65 src++;
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
66 }
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
67 }
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
68
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
69 while (dest < dest_end) {
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
70 ptr = memchr(src, '\n', src_end - src);
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
71 if (ptr == NULL)
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
72 ptr = src_end;
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
73
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
74 /* copy data up to LF */
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
75 copy_len = ptr - src;
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
76 if (dest + copy_len > dest_end)
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
77 copy_len = dest_end - dest;
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
78
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
79 if (copy_len > 0) {
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
80 memcpy(dest, src, copy_len);
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
81
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
82 dest += copy_len;
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
83 src += copy_len;
6722
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
84 }
12054
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
85
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
86 i_assert(dest <= dest_end && src <= src_end);
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
87 if (dest == dest_end || src == src_end)
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
88 break;
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
89
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
90 /* add the CR if necessary and copy the LF.
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
91 (src >= data+1, because data[0]=='\n' was
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
92 handled before this loop) */
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
93 if (src[-1] != '\r')
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
94 *dest++ = '\r';
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
95
12113
2e1226259979 istream-crlf: Fixed assert-crash.
Timo Sirainen <tss@iki.fi>
parents: 12054
diff changeset
96 if (dest == dest_end)
2e1226259979 istream-crlf: Fixed assert-crash.
Timo Sirainen <tss@iki.fi>
parents: 12054
diff changeset
97 break;
12054
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
98
12113
2e1226259979 istream-crlf: Fixed assert-crash.
Timo Sirainen <tss@iki.fi>
parents: 12054
diff changeset
99 *dest++ = '\n';
2e1226259979 istream-crlf: Fixed assert-crash.
Timo Sirainen <tss@iki.fi>
parents: 12054
diff changeset
100 src++;
12054
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
101 i_assert(src == ptr + 1);
6722
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
102 }
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
103
12054
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
104 i_assert(dest != stream->w_buffer);
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
105 cstream->last_cr = dest[-1] == '\r';
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
106 i_stream_skip(stream->parent, src - data);
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
107
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
108 ret = (dest - stream->w_buffer) - stream->pos;
8196
40a07553606c Input streams: Improved error handling and added more asserts.
Timo Sirainen <tss@iki.fi>
parents: 7783
diff changeset
109 i_assert(ret > 0);
12054
5163d94d4272 istream-crlf optimization.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
110 stream->pos = dest - stream->w_buffer;
6722
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
111 return ret;
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
112 }
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
113
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
114 static ssize_t i_stream_crlf_read_lf(struct istream_private *stream)
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
115 {
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
116 struct crlf_istream *cstream = (struct crlf_istream *)stream;
17287
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
117 const unsigned char *data, *p;
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
118 size_t i, dest, size, max;
6722
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
119 ssize_t ret;
17287
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
120 bool pending_cr;
6722
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
121
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
122 ret = i_stream_crlf_read_common(cstream);
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
123 if (ret <= 0)
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
124 return ret;
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
125
7030
1a89a1509e81 Use istream_private->parent pointer globally instead of each filter stream
Timo Sirainen <tss@iki.fi>
parents: 6725
diff changeset
126 data = i_stream_get_data(stream->parent, &size);
6527
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
127
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
128 /* @UNSAFE */
17287
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
129 /* \r\n -> \n
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
130 \r<anything> -> \r<anything>
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
131 \r\r\n -> \r\n */
6527
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
132 dest = stream->pos;
17287
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
133 pending_cr = cstream->pending_cr;
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
134 for (i = 0; i < size && dest < stream->buffer_size; ) {
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
135 if (data[i] == '\r') {
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
136 if (pending_cr) {
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
137 /* \r\r */
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
138 stream->w_buffer[dest++] = '\r';
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
139 } else {
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
140 pending_cr = TRUE;
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
141 }
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
142 i++;
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
143 } else if (data[i] == '\n') {
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
144 /* [\r]\n */
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
145 pending_cr = FALSE;
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
146 stream->w_buffer[dest++] = '\n';
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
147 i++;
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
148 } else if (pending_cr) {
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
149 /* \r<anything> */
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
150 pending_cr = FALSE;
6527
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
151 stream->w_buffer[dest++] = '\r';
17287
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
152 } else {
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
153 /* copy everything until the next \r */
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
154 max = I_MIN(size - i, stream->buffer_size - dest);
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
155 p = memchr(data + i, '\r', max);
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
156 if (p != NULL)
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
157 max = p - (data+i);
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
158 memcpy(stream->w_buffer + dest, data + i, max);
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
159 dest += max;
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
160 i += max;
6527
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
161 }
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
162 }
17287
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
163 i_assert(i <= size);
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
164 i_assert(dest <= stream->buffer_size);
6722
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
165
17287
66620a924bfa istream-lf: Cleanup & performance improvement.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
166 cstream->pending_cr = pending_cr;
7030
1a89a1509e81 Use istream_private->parent pointer globally instead of each filter stream
Timo Sirainen <tss@iki.fi>
parents: 6725
diff changeset
167 i_stream_skip(stream->parent, i);
6552
Timo Sirainen <tss@iki.fi>
parents: 6544
diff changeset
168
Timo Sirainen <tss@iki.fi>
parents: 6544
diff changeset
169 ret = dest - stream->pos;
6563
d85bfe89f4b8 Don't assert-crash if underlying input stream read only a CR character.
Timo Sirainen <tss@iki.fi>
parents: 6559
diff changeset
170 if (ret == 0) {
6722
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
171 i_assert(cstream->pending_cr && size == 1);
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
172 return i_stream_crlf_read_lf(stream);
6563
d85bfe89f4b8 Don't assert-crash if underlying input stream read only a CR character.
Timo Sirainen <tss@iki.fi>
parents: 6559
diff changeset
173 }
8196
40a07553606c Input streams: Improved error handling and added more asserts.
Timo Sirainen <tss@iki.fi>
parents: 7783
diff changeset
174 i_assert(ret > 0);
6527
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
175 stream->pos = dest;
6552
Timo Sirainen <tss@iki.fi>
parents: 6544
diff changeset
176 return ret;
6527
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
177 }
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
178
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
179 static struct istream *
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
180 i_stream_create_crlf_full(struct istream *input, bool crlf)
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
181 {
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
182 struct crlf_istream *cstream;
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
183
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
184 cstream = i_new(struct crlf_istream, 1);
6559
15a9ce2cc0ab Always keep a usable value in stream->max_buffer_size.
Timo Sirainen <tss@iki.fi>
parents: 6558
diff changeset
185 cstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
6722
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
186 cstream->istream.read = crlf ? i_stream_crlf_read_crlf :
a9739ce5a7e4 Rewrote with separate CRLF/LF-only read functions. The code is much easier
Timo Sirainen <tss@iki.fi>
parents: 6721
diff changeset
187 i_stream_crlf_read_lf;
6527
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
188
9540
622509c562e8 Added struct istream.readable_fd, which is used to determine if sendfile() can be used.
Timo Sirainen <tss@iki.fi>
parents: 9522
diff changeset
189 cstream->istream.istream.readable_fd = FALSE;
6527
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
190 cstream->istream.istream.blocking = input->blocking;
7735
e063797bdcd5 Added support for seeking forwards in the stream. Also mark the stream as
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
191 cstream->istream.istream.seekable = FALSE;
7032
85cf52f0bc64 i_stream_create() now takes parent stream as parameter and internally sets
Timo Sirainen <tss@iki.fi>
parents: 7030
diff changeset
192 return i_stream_create(&cstream->istream, input,
85cf52f0bc64 i_stream_create() now takes parent stream as parameter and internally sets
Timo Sirainen <tss@iki.fi>
parents: 7030
diff changeset
193 i_stream_get_fd(input));
6527
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
194 }
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
195
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
196 struct istream *i_stream_create_crlf(struct istream *input)
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
197 {
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
198 return i_stream_create_crlf_full(input, TRUE);
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
199 }
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
200
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
201 struct istream *i_stream_create_lf(struct istream *input)
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
202 {
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
203 return i_stream_create_crlf_full(input, FALSE);
ba65c858b7dd Added input stream filters for reading linefeeds as CRLFs or LFs.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
204 }