root/tls/ringbuf.hh

Revision 08f5bd75ad170e6b8177b93e98f40d0f8a51b9d2, 3.2 KB (checked in by Antti-Juhani Kaijanaho <antti-juhani@…>, 22 months ago)

[tls::session] Use ring buffers instead of dynamically growing buffers

This way enbuffering cannot throw bad_alloc.

Closes #69.

Signed-off-by: Antti-Juhani Kaijanaho <antti-juhani@…>

  • Property mode set to 100644
Line 
1/*  This file is part of Alue, the multiprotocol Internet discussion daemon
2
3    Copyright © 2010 Antti-Juhani Kaijanaho
4
5    Alue is free software: you can redistribute it and/or modify it
6    under the terms of the GNU General Public License as published by
7    the Free Software Foundation, either version 3 of the License, or
8    (at your option) any later version.
9
10    Alue is distributed in the hope that it will be useful, but
11    WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with Alue.  If not, see <http://www.gnu.org/licenses/>.
17
18 */
19
20#ifndef GUARD_TLS_RINGBUF_HH
21#define GUARD_TLS_RINGBUF_HH
22
23#include <boost/asio.hpp>
24#include <boost/noncopyable.hpp>
25#include <cstdlib>
26#include <cstring>
27#include <stdexcept>
28
29namespace tls
30{
31        class ringbuf : private boost::noncopyable
32        {
33                size_t rd, wr, n, N;
34                unsigned char *arr;
35
36                const unsigned char *rda1() const { return arr + rd; }
37                unsigned char *wra1()             { return arr + wr; }
38                const unsigned char *rda2() const { return arr + (rd < wr ? rd : 0); }
39                unsigned char *wra2()             { return arr + (wr < rd ? wr : 0); }
40                // rds1() and rds2() give meaningless answers if n == 0
41                // wrs1() and wrs2() give meaningless answers if n == N
42                size_t rds1() const { return rd >= wr ? N - rd : 0; }
43                size_t wrs1() const { return wr >= rd ? N - wr : 0; }
44                size_t rds2() const { return rd < wr ? wr - rd : wr; }
45                size_t wrs2() const { return wr < rd ? rd - wr : rd; }
46        public:
47                explicit ringbuf(size_t N)
48                        : rd(0)
49                        , wr(0)
50                        , n(0)
51                        , N(N)
52                        , arr((unsigned char*)std::malloc(N)) {
53                        if (arr == 0) throw std::bad_alloc();
54                }
55                ~ringbuf() { std::free(arr); }
56
57                bool empty() const { return n == 0; }
58                bool full() const { return n == N; }
59               
60                std::vector<boost::asio::mutable_buffer> write_area();
61                std::vector<boost::asio::const_buffer> read_area() const;
62                void read(size_t k) {
63                        BOOST_ASSERT(k <= n);
64                        n -= k;
65                        rd += k;
66                        rd %= N;
67                        BOOST_ASSERT((rd == wr) == (n == 0 || n == N));
68                        BOOST_ASSERT(n <= N);
69                }
70                void written(size_t k) {
71                        BOOST_ASSERT(n + k <= N);
72                        n += k;
73                        wr += k;
74                        wr %= N;
75                        BOOST_ASSERT((rd == wr) == (n == 0 || n == N));
76                        BOOST_ASSERT(n <= N);
77                }
78                size_t get(unsigned char *out, size_t k);
79                size_t put(const unsigned char *in, size_t k);
80        };
81}
82
83#endif /* GUARD_TLS_RINGBUF_HH */
Note: See TracBrowser for help on using the browser.