]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/numericbuilder.h
Add Numeric::ParamBuilder
[user/henk/code/inspircd.git] / include / numericbuilder.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2015-2016 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         template <unsigned int NumStaticParams, bool SendEmpty, typename Sink>
33         class GenericParamBuilder;
34
35         template <unsigned int NumStaticParams, bool SendEmpty = false>
36         class ParamBuilder;
37 }
38
39 class Numeric::WriteNumericSink
40 {
41         LocalUser* const user;
42
43  public:
44         WriteNumericSink(LocalUser* u)
45                 : user(u)
46         {
47         }
48
49         void operator()(Numeric& numeric) const
50         {
51                 user->WriteNumeric(numeric);
52         }
53 };
54
55 template <char Sep, bool SendEmpty, typename Sink>
56 class Numeric::GenericBuilder
57 {
58         Sink sink;
59         Numeric numeric;
60         const std::string::size_type max;
61
62         bool HasRoom(const std::string::size_type additional) const
63         {
64                 return (numeric.GetParams().back().size() + additional <= max);
65         }
66
67  public:
68         GenericBuilder(Sink s, unsigned int num, bool addparam = true, size_t additionalsize = 0)
69                 : sink(s)
70                 , numeric(num)
71                 , max(ServerInstance->Config->Limits.MaxLine - ServerInstance->Config->ServerName.size() - additionalsize - 10)
72         {
73                 if (addparam)
74                         numeric.push(std::string());
75         }
76
77         Numeric& GetNumeric() { return numeric; }
78
79         void Add(const std::string& entry)
80         {
81                 if (!HasRoom(entry.size()))
82                         Flush();
83                 numeric.GetParams().back().append(entry).push_back(Sep);
84         }
85
86         void Add(const std::string& entry1, const std::string& entry2)
87         {
88                 if (!HasRoom(entry1.size() + entry2.size()))
89                         Flush();
90                 numeric.GetParams().back().append(entry1).append(entry2).push_back(Sep);
91         }
92
93         void Flush()
94         {
95                 std::string& data = numeric.GetParams().back();
96                 if (IsEmpty())
97                 {
98                         if (!SendEmpty)
99                                 return;
100                 }
101                 else
102                 {
103                         data.erase(data.size()-1);
104                 }
105
106                 sink(numeric);
107                 data.clear();
108         }
109
110         bool IsEmpty() const { return (numeric.GetParams().back().empty()); }
111 };
112
113 template <char Sep, bool SendEmpty>
114 class Numeric::Builder : public GenericBuilder<Sep, SendEmpty, WriteNumericSink>
115 {
116  public:
117         Builder(LocalUser* user, unsigned int num, bool addparam = true, size_t additionalsize = 0)
118                 : ::Numeric::GenericBuilder<Sep, SendEmpty, WriteNumericSink>(WriteNumericSink(user), num, addparam, additionalsize + user->nick.size())
119         {
120         }
121 };
122
123 template <unsigned int NumStaticParams, bool SendEmpty, typename Sink>
124 class Numeric::GenericParamBuilder
125 {
126         Sink sink;
127         Numeric numeric;
128         std::string::size_type currlen;
129         std::string::size_type max;
130
131         bool HasRoom(const std::string::size_type additional) const
132         {
133                 return (currlen + additional <= max);
134         }
135
136  public:
137         GenericParamBuilder(Sink s, unsigned int num, size_t additionalsize)
138                 : sink(s)
139                 , numeric(num)
140                 , currlen(0)
141                 , max(ServerInstance->Config->Limits.MaxLine - ServerInstance->Config->ServerName.size() - additionalsize - 10)
142         {
143         }
144
145         void AddStatic(const std::string& entry)
146         {
147                 max -= (entry.length() + 1);
148                 numeric.GetParams().push_back(entry);
149         }
150
151         void Add(const std::string& entry)
152         {
153                 if (!HasRoom(entry.size()))
154                         Flush();
155
156                 currlen += entry.size() + 1;
157                 numeric.GetParams().push_back(entry);
158         }
159
160         void Flush()
161         {
162                 if ((!SendEmpty) && (IsEmpty()))
163                         return;
164
165                 sink(numeric);
166                 currlen = 0;
167                 numeric.GetParams().erase(numeric.GetParams().begin() + NumStaticParams, numeric.GetParams().end());
168         }
169
170         bool IsEmpty() const { return (numeric.GetParams().size() <= NumStaticParams); }
171 };
172
173 template <unsigned int NumStaticParams, bool SendEmpty>
174 class Numeric::ParamBuilder : public GenericParamBuilder<NumStaticParams, SendEmpty, WriteNumericSink>
175 {
176  public:
177         ParamBuilder(LocalUser* user, unsigned int num)
178                 : ::Numeric::GenericParamBuilder<NumStaticParams, SendEmpty, WriteNumericSink>(WriteNumericSink(user), num, user->nick.size())
179         {
180         }
181 };