annotate src/lib/ostream-escaped.c @ 22955:812e5c961328

fts: Indexing virtual mailbox didn't always index the last mails
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Thu, 03 May 2018 18:33:00 +0300
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) 2016-2018 Dovecot authors, see the included COPYING file */
19735
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
2
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
3 #include "lib.h"
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
4 #include "str.h"
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
5 #include "ostream.h"
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
6 #include "ostream-private.h"
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
7 #include "ostream-escaped.h"
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
8
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
9 struct escaped_ostream {
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
10 struct ostream_private ostream;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
11 ostream_escaped_escape_formatter_t format;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
12
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
13 string_t *buf;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
14 bool flushed;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
15 };
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
16
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
17 static ssize_t
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
18 o_stream_escaped_send_outbuf(struct escaped_ostream *estream)
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
19 {
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
20 ssize_t ret;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
21
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
22 if (estream->flushed)
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
23 return 1; /* nothing to send */
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
24 ret = o_stream_send(estream->ostream.parent, str_data(estream->buf), str_len(estream->buf));
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
25 if (ret < 0) {
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
26 o_stream_copy_error_from_parent(&estream->ostream);
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
27 return -1;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
28 }
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
29 if ((size_t)ret != str_len(estream->buf)) {
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
30 /* move data */
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
31 str_delete(estream->buf, 0, ret);
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
32 return 0;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
33 }
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
34 str_truncate(estream->buf, 0);
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
35 estream->flushed = TRUE;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
36 return 1;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
37 }
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
38
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
39 static ssize_t
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
40 o_stream_escaped_send_chunk(struct escaped_ostream *estream,
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
41 const unsigned char *data, size_t len)
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
42 {
20266
bd22ff741f5d lib: ostream-escaped: Fixed setting offset
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19735
diff changeset
43 size_t i, max_buffer_size;
19735
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
44 ssize_t ret;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
45
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
46 max_buffer_size = I_MIN(o_stream_get_max_buffer_size(estream->ostream.parent),
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
47 estream->ostream.max_buffer_size);
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
48 if (max_buffer_size > IO_BLOCK_SIZE) {
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
49 /* avoid using up too much memory in case of large buffers */
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
50 max_buffer_size = IO_BLOCK_SIZE;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
51 }
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
52
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
53 for (i = 0; i < len; i++) {
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
54 if (str_len(estream->buf) + 2 > max_buffer_size) { /* escaping takes at least two bytes */
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
55 ret = o_stream_escaped_send_outbuf(estream);
20266
bd22ff741f5d lib: ostream-escaped: Fixed setting offset
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19735
diff changeset
56 if (ret < 0) {
bd22ff741f5d lib: ostream-escaped: Fixed setting offset
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19735
diff changeset
57 estream->ostream.ostream.offset += i;
19735
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
58 return ret;
20266
bd22ff741f5d lib: ostream-escaped: Fixed setting offset
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19735
diff changeset
59 }
19735
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
60 if (ret == 0)
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
61 break;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
62 }
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
63 estream->format(estream->buf, data[i]);
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
64 estream->flushed = FALSE;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
65 }
20266
bd22ff741f5d lib: ostream-escaped: Fixed setting offset
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19735
diff changeset
66 estream->ostream.ostream.offset += i;
19735
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
67 return i;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
68 }
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
69
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
70 static ssize_t
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
71 o_stream_escaped_sendv(struct ostream_private *stream,
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
72 const struct const_iovec *iov, unsigned int iov_count)
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
73 {
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
74 struct escaped_ostream *estream = (struct escaped_ostream *)stream;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
75 unsigned int iov_cur;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
76 ssize_t ret, bytes = 0;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
77
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
78 for (iov_cur = 0; iov_cur < iov_count; iov_cur++) {
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
79 ret = o_stream_escaped_send_chunk(estream,
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
80 iov[iov_cur].iov_base, iov[iov_cur].iov_len);
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
81 if (ret < 0)
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
82 return ret;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
83 bytes += ret;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
84 if ((size_t)ret != iov[iov_cur].iov_len)
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
85 break;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
86 }
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
87 if (o_stream_escaped_send_outbuf(estream) < 0)
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
88 return -1;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
89 return bytes;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
90 }
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
91
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
92 static int
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
93 o_stream_escaped_flush(struct ostream_private *stream)
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
94 {
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
95 struct escaped_ostream *estream = (struct escaped_ostream *)stream;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
96 int ret;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
97
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
98 if ((ret = o_stream_escaped_send_outbuf(estream)) <= 0)
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
99 return ret;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
100 if ((ret = o_stream_flush(stream->parent)) < 0)
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
101 o_stream_copy_error_from_parent(stream);
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
102 return ret;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
103 }
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
104
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
105 static void o_stream_escaped_destroy(struct iostream_private *stream)
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
106 {
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
107 struct escaped_ostream *estream = (struct escaped_ostream *)stream;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
108
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
109 str_free(&estream->buf);
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
110 o_stream_unref(&estream->ostream.parent);
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
111 }
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
112
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
113 void ostream_escaped_hex_format(string_t *dest, unsigned char chr)
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
114 {
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
115 str_printfa(dest, "%02x", chr);
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
116 }
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
117
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
118 struct ostream *
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
119 o_stream_create_escaped(struct ostream *output,
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
120 ostream_escaped_escape_formatter_t format)
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
121 {
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
122 struct escaped_ostream *estream;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
123
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
124 estream = i_new(struct escaped_ostream, 1);
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
125 estream->ostream.sendv = o_stream_escaped_sendv;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
126 estream->ostream.flush = o_stream_escaped_flush;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
127 estream->ostream.max_buffer_size = o_stream_get_max_buffer_size(output);
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
128 estream->ostream.iostream.destroy = o_stream_escaped_destroy;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
129 estream->buf = str_new(default_pool, 512);
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
130 estream->format = format;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
131 estream->flushed = FALSE;
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
132
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
133 return o_stream_create(&estream->ostream, output, o_stream_get_fd(output));
a3872143befd lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
134 }