]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/other/radius/reader.h
3bc1f9e674db1029268e104c49e18e08f8d19d30
[stg.git] / projects / stargazer / plugins / other / radius / reader.h
1 /*
2  *    This program is free software; you can redistribute it and/or modify
3  *    it under the terms of the GNU General Public License as published by
4  *    the Free Software Foundation; either version 2 of the License, or
5  *    (at your option) any later version.
6  *
7  *    This program is distributed in the hope that it will be useful,
8  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *    GNU General Public License for more details.
11  *
12  *    You should have received a copy of the GNU General Public License
13  *    along with this program; if not, write to the Free Software
14  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15  */
16
17 /*
18  *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
19  */
20
21 #ifndef __STG_SGCONFIG_READER_H__
22 #define __STG_SGCONFIG_READER_H__
23
24 #include <string>
25 #include <vector>
26 #include <utility>
27
28 namespace STG
29 {
30
31 struct BaseReader
32 {
33     virtual ~BaseReader() {}
34
35     virtual ssize_t read(TransportProto& proto) = 0;
36     virtual bool done() const = 0;
37 };
38
39 template <typename T>
40 class Reader : public BaseReader
41 {
42     public:
43         Reader(size_t size = sizeof(T)) : m_size(size), m_done(0) {}
44
45         virtual ssize_t read(TransportProto& proto)
46         {
47             char* pos = static_cast<void*>(&m_dest);
48             pos += m_done;
49             ssize_t res = proto.read(pos, m_size - m_done);
50             if (res < 0)
51                 return res;
52             if (res == 0) {
53                 m_done = m_size;
54                 return 0;
55             }
56             m_done += res;
57             return res;
58         }
59
60         virtual bool done() const { return m_done == m_size; }
61
62         T get() const { return ntoh(m_dest); }
63
64     private:
65         T m_dest;
66         size_t m_size;
67         size_t m_done;
68
69 };
70
71 template <>
72 class Reader<std::vector<Reader*> > : public BaseReader
73 {
74     public:
75         Reader(const std::vector<Reader*>& readers) : m_size(readers.size()), m_done(0) {}
76
77         virtual ssize_t read(TransportProto& proto)
78         {
79             if (m_size == 0)
80                 return 0;
81             size_t res = m_dest[m_done]->read(proto);
82             if (res < 0)
83                 return res;
84             if (res == 0) {
85                 m_done = m_size;
86                 return 0;
87             }
88             if (m_dest[m_done].done())
89                 ++m_dest;
90             return res;
91         }
92
93         virtual bool done() const { return m_done == m_size; }
94
95         const T& get() const { return m_dest; }
96
97     private:
98         T m_dest;
99         size_t m_size;
100         size_t m_done;
101
102 };
103
104 template <>
105 class Reader<std::vector<char> > : public BaseReader
106 {
107     public:
108         Reader(size_t size ) : m_dest(size), m_size(size), m_done(0) {}
109
110         virtual ssize_t read(TransportProto& proto)
111         {
112             char* pos = static_cast<void*>(m_dest.data());
113             pos += m_done;
114             ssize_t res = proto.read(pos, m_size - m_done);
115             if (res < 0)
116                 return res;
117             if (res == 0) {
118                 m_done = m_size;
119                 return 0;
120             }
121             m_done += res;
122             return res;
123         }
124
125         virtual bool done() const { return m_done == m_size; }
126
127         const std::vector<char>& get() const { return m_dest; }
128
129     private:
130         std::vector<char> m_dest;
131         size_t m_size;
132         size_t m_done;
133
134 };
135
136 template <>
137 class Reader<std::string>
138 {
139     public:
140         Reader() : m_dest(Reader<std::string>::initDest()) {}
141
142         virtual ssize_t read(TransportProto& proto)
143         {
144             if (m_size == 0)
145                 return 0;
146             size_t res = m_dest[m_done]->read(proto);
147             if (res < 0)
148                 return res;
149             if (res == 0) {
150                 m_done = m_size;
151                 return 0;
152             }
153             if (m_dest[m_done].done())
154                 ++m_dest;
155             return res;
156         }
157
158         virtual bool done() const { return m_done == m_size; }
159
160         const T& get() const { return m_dest; }
161
162     private:
163         T m_dest;
164         size_t m_size;
165         size_t m_done;
166 };
167
168 } // namespace STG
169
170 #endif