]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/numericbuilder.h
Fix build errors on CentOS 6 and OpenBSD.
[user/henk/code/inspircd.git] / include / numericbuilder.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2015 Attila Molnar <attilamolnar@hush.com>
5  *
6  * This file is part of InspIRCd.  InspIRCd is free software: you can
7  * redistribute it and/or modify it under the terms of the GNU General Public
8  * License as published by the Free Software Foundation, version 2.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
13  * details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19
20 #pragma once
21
22 namespace Numeric
23 {
24         class WriteNumericSink;
25
26         template <char Sep, bool SendEmpty, typename Sink>
27         class GenericBuilder;
28
29         template <char Sep = ',', bool SendEmpty = false>
30         class Builder;
31 }
32
33 class Numeric::WriteNumericSink
34 {
35         LocalUser* const user;
36
37  public:
38         WriteNumericSink(LocalUser* u)
39                 : user(u)
40         {
41         }
42
43         void operator()(unsigned int numeric, const std::string& params) const
44         {
45                 user->WriteNumeric(numeric, params);
46         }
47 };
48
49 template <char Sep, bool SendEmpty, typename Sink>
50 class Numeric::GenericBuilder
51 {
52         Sink sink;
53         std::string data;
54         const unsigned int numeric;
55         const std::string::size_type max;
56         std::string::size_type beginpos;
57
58         bool HasRoom(const std::string::size_type additional) const
59         {
60                 return (data.size() + additional <= max);
61         }
62
63  public:
64         GenericBuilder(Sink s, unsigned int num, bool addparam = true, size_t additionalsize = 0)
65                 : sink(s)
66                 , numeric(num)
67                 , max(ServerInstance->Config->Limits.MaxLine - ServerInstance->Config->ServerName.size() - additionalsize - 9)
68         {
69                 if (addparam)
70                         data.push_back(':');
71                 SaveBeginPos();
72         }
73
74         std::string& GetNumeric() { return data; }
75
76         void Add(const std::string& entry)
77         {
78                 if (!HasRoom(entry.size()))
79                         Flush();
80                 data.append(entry).push_back(Sep);
81         }
82
83         void Add(const std::string& entry1, const std::string& entry2)
84         {
85                 if (!HasRoom(entry1.size() + entry2.size()))
86                         Flush();
87                 data.append(entry1).append(entry2).push_back(Sep);
88         }
89
90         void Flush()
91         {
92                 if (IsEmpty())
93                 {
94                         if (!SendEmpty)
95                                 return;
96                 }
97                 else
98                 {
99                         data.erase(data.size()-1);
100                 }
101
102                 sink(numeric, data);
103                 if (data.size() > beginpos)
104                         data.erase(beginpos);
105         }
106
107         bool IsEmpty() const { return (data.size() == beginpos); }
108         void SaveBeginPos() { beginpos = data.size(); }
109 };
110
111 template <char Sep, bool SendEmpty>
112 class Numeric::Builder : public GenericBuilder<Sep, SendEmpty, WriteNumericSink>
113 {
114  public:
115         Builder(LocalUser* user, unsigned int num, bool addparam = true, size_t additionalsize = 0)
116                 : Numeric::GenericBuilder<Sep, SendEmpty, WriteNumericSink>(WriteNumericSink(user), num, addparam, additionalsize + user->nick.size())
117         {
118         }
119 };