Mercurial > dovecot > core-2.2
annotate src/lib/istream-limit.c @ 2983:c20a64efd608 HEAD
Added assert.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 16 Dec 2004 03:37:20 +0200 |
parents | 881e265febfa |
children | 904a268921af |
rev | line source |
---|---|
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
1 /* Copyright (C) 2003 Timo Sirainen */ |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
2 |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
3 #include "lib.h" |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
4 #include "istream-internal.h" |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
5 |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
6 struct limit_istream { |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
7 struct _istream istream; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
8 |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
9 struct istream *input; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
10 uoff_t v_start_offset, v_size; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
11 }; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
12 |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
13 static void _close(struct _iostream *stream __attr_unused__) |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
14 { |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
15 } |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
16 |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
17 static void _destroy(struct _iostream *stream) |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
18 { |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
19 struct limit_istream *lstream = (struct limit_istream *) stream; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
20 |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
21 /* get to same position in parent stream */ |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
22 i_stream_seek(lstream->input, lstream->v_start_offset + |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
23 lstream->istream.istream.v_offset); |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
24 i_stream_unref(lstream->input); |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
25 } |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
26 |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
27 static void _set_max_buffer_size(struct _iostream *stream, size_t max_size) |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
28 { |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
29 struct limit_istream *lstream = (struct limit_istream *) stream; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
30 |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
31 i_stream_set_max_buffer_size(lstream->input, max_size); |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
32 } |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
33 |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
34 static ssize_t _read(struct _istream *stream) |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
35 { |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
36 struct limit_istream *lstream = (struct limit_istream *) stream; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
37 uoff_t left; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
38 ssize_t ret; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
39 size_t pos; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
40 |
1874 | 41 if (stream->istream.v_offset + |
2441
b65224a24696
When we reach the limit, set eof = true
Timo Sirainen <tss@iki.fi>
parents:
2431
diff
changeset
|
42 (stream->pos - stream->skip) >= lstream->v_size) { |
b65224a24696
When we reach the limit, set eof = true
Timo Sirainen <tss@iki.fi>
parents:
2431
diff
changeset
|
43 stream->istream.eof = TRUE; |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
44 return -1; |
2441
b65224a24696
When we reach the limit, set eof = true
Timo Sirainen <tss@iki.fi>
parents:
2431
diff
changeset
|
45 } |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
46 |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
47 if (lstream->input->v_offset != |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
48 lstream->v_start_offset + stream->istream.v_offset) { |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
49 i_stream_seek(lstream->input, |
1874 | 50 lstream->v_start_offset + |
51 stream->istream.v_offset); | |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
52 } |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
53 |
2295
545c1d3ead54
Wrapper streams shouldn't try to read data if it's already buffered in main
Timo Sirainen <tss@iki.fi>
parents:
2166
diff
changeset
|
54 stream->buffer = i_stream_get_data(lstream->input, &pos); |
545c1d3ead54
Wrapper streams shouldn't try to read data if it's already buffered in main
Timo Sirainen <tss@iki.fi>
parents:
2166
diff
changeset
|
55 if (pos <= stream->pos) { |
2444 | 56 if ((ret = i_stream_read(lstream->input)) == -2) { |
2295
545c1d3ead54
Wrapper streams shouldn't try to read data if it's already buffered in main
Timo Sirainen <tss@iki.fi>
parents:
2166
diff
changeset
|
57 if (stream->skip == 0) |
545c1d3ead54
Wrapper streams shouldn't try to read data if it's already buffered in main
Timo Sirainen <tss@iki.fi>
parents:
2166
diff
changeset
|
58 return -2; |
545c1d3ead54
Wrapper streams shouldn't try to read data if it's already buffered in main
Timo Sirainen <tss@iki.fi>
parents:
2166
diff
changeset
|
59 } |
2431
8e9d8cb1e674
Removed istream.disconnected, it's too much of a special case and the only
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
60 stream->istream.eof = lstream->input->eof; |
2295
545c1d3ead54
Wrapper streams shouldn't try to read data if it's already buffered in main
Timo Sirainen <tss@iki.fi>
parents:
2166
diff
changeset
|
61 stream->buffer = i_stream_get_data(lstream->input, &pos); |
2444 | 62 } else { |
63 ret = 0; | |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
64 } |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
65 |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
66 stream->pos -= stream->skip; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
67 stream->skip = 0; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
68 |
2166 | 69 if (lstream->v_size != (uoff_t)-1) { |
70 left = lstream->v_size - stream->istream.v_offset; | |
71 if (pos > left) | |
72 pos = left; | |
73 } | |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
74 |
2444 | 75 ret = pos > stream->pos ? (ssize_t)(pos - stream->pos) : |
76 (ret == 0 ? 0 : -1); | |
1874 | 77 stream->pos = pos; |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
78 return ret; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
79 } |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
80 |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
81 static void _seek(struct _istream *stream, uoff_t v_offset) |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
82 { |
2983 | 83 struct limit_istream *lstream = (struct limit_istream *) stream; |
84 | |
85 i_assert(v_offset <= lstream->v_size); | |
86 | |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
87 stream->istream.stream_errno = 0; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
88 stream->istream.v_offset = v_offset; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
89 stream->skip = stream->pos = 0; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
90 } |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
91 |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
92 static uoff_t _get_size(struct _istream *stream) |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
93 { |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
94 struct limit_istream *lstream = (struct limit_istream *) stream; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
95 |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
96 return lstream->v_size != (uoff_t)-1 ? lstream->v_size : |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
97 i_stream_get_size(lstream->input); |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
98 } |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
99 |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
100 struct istream *i_stream_create_limit(pool_t pool, struct istream *input, |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
101 uoff_t v_start_offset, uoff_t v_size) |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
102 { |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
103 struct limit_istream *lstream; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
104 |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
105 i_stream_ref(input); |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
106 |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
107 lstream = p_new(pool, struct limit_istream, 1); |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
108 lstream->input = input; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
109 lstream->v_start_offset = v_start_offset; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
110 lstream->v_size = v_size; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
111 |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
112 lstream->istream.istream.v_offset = |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
113 input->v_offset < v_start_offset ? 0 : |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
114 input->v_offset - v_start_offset > v_size ? v_size : |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
115 input->v_offset - v_start_offset; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
116 |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
117 lstream->istream.iostream.close = _close; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
118 lstream->istream.iostream.destroy = _destroy; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
119 lstream->istream.iostream.set_max_buffer_size = _set_max_buffer_size; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
120 |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
121 lstream->istream.read = _read; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
122 lstream->istream.seek = _seek; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
123 lstream->istream.get_size = _get_size; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
124 |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
125 return _i_stream_create(&lstream->istream, pool, i_stream_get_fd(input), |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
126 input->real_stream->abs_start_offset + |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
127 v_start_offset); |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
128 } |