1 /*
2    Copyright (C) 2004-2006 MySQL AB
3     All rights reserved. Use is subject to license terms.
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License, version 2.0,
7    as published by the Free Software Foundation.
8 
9    This program is also distributed with certain software (including
10    but not limited to OpenSSL) that is licensed under separate terms,
11    as designated in a particular file or component or in included license
12    documentation.  The authors of MySQL hereby grant you an additional
13    permission to link the program and your derivative works with the
14    separately licensed software that they have included with MySQL.
15 
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License, version 2.0, for more details.
20 
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
24 */
25 
26 #ifndef __CONFIG_VALUES_HPP
27 #define __CONFIG_VALUES_HPP
28 
29 #include <ndb_types.h>
30 #include <UtilBuffer.hpp>
31 
32 class ConfigValues {
33   friend class ConfigValuesFactory;
34   ConfigValues(Uint32 sz, Uint32 data);
35 
36 public:
37   ~ConfigValues();
38 
39   enum ValueType {
40     InvalidType = 0,
41     IntType     = 1,
42     StringType  = 2,
43     SectionType = 3,
44     Int64Type   = 4
45   };
46 
47   struct Entry {
48     Uint32 m_key;
49     ValueType m_type;
50     union {
51       Uint32 m_int;
52       Uint64 m_int64;
53       const char * m_string;
54     };
55   };
56 
57   class ConstIterator {
58     friend class ConfigValuesFactory;
59     const ConfigValues & m_cfg;
60   public:
61     Uint32 m_currentSection;
ConstIterator(const ConfigValues & c)62     ConstIterator(const ConfigValues&c) : m_cfg(c) { m_currentSection = 0;}
63 
64     bool openSection(Uint32 key, Uint32 no);
65     bool closeSection();
66 
67     bool get(Uint32 key, Entry *) const;
68 
69     bool get(Uint32 key, Uint32 * value) const;
70     bool get(Uint32 key, Uint64 * value) const;
71     bool get(Uint32 key, const char ** value) const;
72     bool getTypeOf(Uint32 key, ValueType * type) const;
73 
74     Uint32 get(Uint32 key, Uint32 notFound) const;
75     Uint64 get64(Uint32 key, Uint64 notFound) const;
76     const char * get(Uint32 key, const char * notFound) const;
77     ValueType getTypeOf(Uint32 key) const;
78   };
79 
80   class Iterator : public ConstIterator {
81     ConfigValues & m_cfg;
82   public:
Iterator(ConfigValues & c)83     Iterator(ConfigValues&c) : ConstIterator(c), m_cfg(c) {}
Iterator(ConfigValues & c,const ConstIterator & i)84     Iterator(ConfigValues&c, const ConstIterator& i):ConstIterator(c),m_cfg(c){
85       m_currentSection = i.m_currentSection;
86     }
87 
88     bool set(Uint32 key, Uint32 value);
89     bool set(Uint32 key, Uint64 value);
90     bool set(Uint32 key, const char * value);
91   };
92 
93   Uint32 getPackedSize() const; // get size in bytes needed to pack
94   Uint32 pack(UtilBuffer&) const;
95   Uint32 pack(void * dst, Uint32 len) const;// pack into dst(of len %d);
96 
97 private:
98   friend class Iterator;
99   friend class ConstIterator;
100 
101   bool getByPos(Uint32 pos, Entry *) const;
102   Uint64 * get64(Uint32 index) const;
103   char ** getString(Uint32 index) const;
104 
105   Uint32 m_size;
106   Uint32 m_dataSize;
107   Uint32 m_stringCount;
108   Uint32 m_int64Count;
109 
110   Uint32 m_values[1];
111   void * m_data[1];
112 };
113 
114 class ConfigValuesFactory {
115   Uint32 m_currentSection;
116 public:
117   Uint32 m_sectionCounter;
118   Uint32 m_freeKeys;
119   Uint32 m_freeData;
120 
121 public:
122   ConfigValuesFactory(Uint32 keys = 50, Uint32 data = 10); // Initial
123   ConfigValuesFactory(ConfigValues * m_cfg);        //
124   ~ConfigValuesFactory();
125 
126   ConfigValues * m_cfg;
127   ConfigValues * getConfigValues();
128 
129   bool openSection(Uint32 key, Uint32 no);
130   bool put(const ConfigValues::Entry & );
131   bool put(Uint32 key, Uint32 value);
132   bool put64(Uint32 key, Uint64 value);
133   bool put(Uint32 key, const char * value);
134   bool closeSection();
135 
136   void expand(Uint32 freeKeys, Uint32 freeData);
137   void shrink();
138 
139   bool unpack(const UtilBuffer&);
140   bool unpack(const void * src, Uint32 len);
141 
142   static ConfigValues * extractCurrentSection(const ConfigValues::ConstIterator &);
143 
144 private:
145   static ConfigValues * create(Uint32 keys, Uint32 data);
146   void put(const ConfigValues & src);
147 };
148 
149 inline
150 bool
get(Uint32 key,Uint32 * value) const151 ConfigValues::ConstIterator::get(Uint32 key, Uint32 * value) const {
152   Entry tmp;
153   if(get(key, &tmp) && tmp.m_type == IntType){
154     * value = tmp.m_int;
155     return true;
156   }
157   return false;
158 }
159 
160 inline
161 bool
get(Uint32 key,Uint64 * value) const162 ConfigValues::ConstIterator::get(Uint32 key, Uint64 * value) const {
163   Entry tmp;
164   if(get(key, &tmp) && tmp.m_type == Int64Type){
165     * value = tmp.m_int64;
166     return true;
167   }
168   return false;
169 }
170 
171 inline
172 bool
get(Uint32 key,const char ** value) const173 ConfigValues::ConstIterator::get(Uint32 key, const char ** value) const {
174   Entry tmp;
175   if(get(key, &tmp) && tmp.m_type == StringType){
176     * value = tmp.m_string;
177     return true;
178   }
179   return false;
180 }
181 
182 inline
183 bool
getTypeOf(Uint32 key,ValueType * type) const184 ConfigValues::ConstIterator::getTypeOf(Uint32 key, ValueType * type) const{
185   Entry tmp;
186   if(get(key, &tmp)){
187     * type = tmp.m_type;
188     return true;
189   }
190   return false;
191 }
192 
193 inline
194 Uint32
get(Uint32 key,Uint32 notFound) const195 ConfigValues::ConstIterator::get(Uint32 key, Uint32 notFound) const {
196   Entry tmp;
197   if(get(key, &tmp) && tmp.m_type == IntType){
198     return tmp.m_int;
199   }
200   return notFound;
201 }
202 
203 inline
204 Uint64
get64(Uint32 key,Uint64 notFound) const205 ConfigValues::ConstIterator::get64(Uint32 key, Uint64 notFound) const {
206   Entry tmp;
207   if(get(key, &tmp) && tmp.m_type == Int64Type){
208     return tmp.m_int64;
209   }
210   return notFound;
211 }
212 
213 inline
214 const char *
get(Uint32 key,const char * notFound) const215 ConfigValues::ConstIterator::get(Uint32 key, const char * notFound) const {
216   Entry tmp;
217   if(get(key, &tmp) && tmp.m_type == StringType){
218     return tmp.m_string;
219   }
220   return notFound;
221 }
222 
223 inline
224 ConfigValues::ValueType
getTypeOf(Uint32 key) const225 ConfigValues::ConstIterator::getTypeOf(Uint32 key) const{
226   Entry tmp;
227   if(get(key, &tmp)){
228     return tmp.m_type;
229   }
230   return ConfigValues::InvalidType;
231 }
232 
233 inline
234 bool
put(Uint32 key,Uint32 val)235 ConfigValuesFactory::put(Uint32 key, Uint32 val){
236   ConfigValues::Entry tmp;
237   tmp.m_key = key;
238   tmp.m_type = ConfigValues::IntType;
239   tmp.m_int = val;
240   return put(tmp);
241 }
242 
243 inline
244 bool
put64(Uint32 key,Uint64 val)245 ConfigValuesFactory::put64(Uint32 key, Uint64 val){
246   ConfigValues::Entry tmp;
247   tmp.m_key = key;
248   tmp.m_type = ConfigValues::Int64Type;
249   tmp.m_int64 = val;
250   return put(tmp);
251 }
252 
253 inline
254 bool
put(Uint32 key,const char * val)255 ConfigValuesFactory::put(Uint32 key, const char * val){
256   ConfigValues::Entry tmp;
257   tmp.m_key = key;
258   tmp.m_type = ConfigValues::StringType;
259   tmp.m_string = val;
260   return put(tmp);
261 }
262 
263 inline
264 Uint32
pack(UtilBuffer & buf) const265 ConfigValues::pack(UtilBuffer& buf) const {
266   Uint32 len = getPackedSize();
267   void * tmp = buf.append(len);
268   if(tmp == 0){
269     return 0;
270   }
271   return pack(tmp, len);
272 }
273 
274 inline
275 bool
unpack(const UtilBuffer & buf)276 ConfigValuesFactory::unpack(const UtilBuffer& buf){
277   return unpack(buf.get_data(), buf.length());
278 }
279 
280 #endif
281