1 /*
2    Copyright (C) 2003-2008 MySQL AB, 2008 Sun Microsystems, Inc.
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 SIMPLE_PROPERTIES_HPP
27 #define SIMPLE_PROPERTIES_HPP
28 
29 #include <ndb_global.h>
30 #include <NdbOut.hpp>
31 
32 /**
33  * @class SimpleProperties
34  * @brief Key-value-pair container.  Actully a list of named elements.
35  *
36  * SimpleProperties:
37  * - The keys are Uint16
38  * - The values are either Uint32 or null terminated c-strings
39  *
40  * @note  Keys may be repeated.
41  *
42  * Examples of things that can be stored in a SimpleProperties object:
43  * - Lists like: ((1, "foo"), (2, "bar"), (3, 32), (2, "baz"))
44  */
45 class SimpleProperties {
46 public:
47   /**
48    * Value types
49    */
50    enum ValueType {
51     Uint32Value  = 0,
52     StringValue  = 1,
53     BinaryValue  = 2,
54     InvalidValue = 3
55    };
56 
57   /**
58    * Struct for defining mapping to be used with unpack
59    */
60   struct SP2StructMapping {
61     Uint16 Key;
62     Uint32 Offset;
63     ValueType Type;
64     Uint32 minValue;
65     Uint32 maxValue;
66     Uint32 Length_Offset; // Offset used for looking up length of
67                           // data if Type = BinaryValue
68   };
69 
70   /**
71    * UnpackStatus - Value returned from unpack
72    */
73   enum UnpackStatus {
74     Eof = 0,            // Success, end of SimpleProperties object reached
75     Break = 1,          // Success
76     TypeMismatch = 2,
77     ValueTooLow = 3,
78     ValueTooHigh = 4,
79     UnknownKey = 5,
80     OutOfMemory = 6     // Only used when packing
81   };
82 
83   /**
84    * Unpack
85    */
86   class Reader;
87   static UnpackStatus unpack(class Reader & it,
88 			     void * dst,
89 			     const SP2StructMapping[], Uint32 mapSz,
90 			     bool ignoreMinMax,
91 			     bool ignoreUnknownKeys);
92 
93   class Writer;
94   static UnpackStatus pack(class Writer &,
95 			   const void * src,
96 			   const SP2StructMapping[], Uint32 mapSz,
97 			   bool ignoreMinMax);
98 
99   /**
100    * Reader class
101    */
102   class Reader {
103   public:
~Reader()104     virtual ~Reader() {}
105 
106     /**
107      * Move to first element
108      *   Return true if element exist
109      */
110     bool first();
111 
112     /**
113      * Move to next element
114      *   Return true if element exist
115      */
116     bool next();
117 
118     /**
119      * Is this valid
120      */
121     bool valid() const;
122 
123     /**
124      * Get key
125      *  Note only valid is valid() == true
126      */
127     Uint16 getKey() const;
128 
129     /**
130      * Get value length in bytes - (including terminating 0 for strings)
131      *  Note only valid is valid() == true
132      */
133     Uint16 getValueLen() const;
134 
135     /**
136      * Get value type
137      *  Note only valid is valid() == true
138      */
139     ValueType getValueType() const;
140 
141     /**
142      * Get value
143      *  Note only valid is valid() == true
144      */
145     Uint32 getUint32() const;
146     char * getString(char * dst) const;
147 
148     /**
149      * Print the complete simple properties (for debugging)
150      */
151     void printAll(NdbOut& ndbout);
152 
153   private:
154     bool readValue();
155 
156     Uint16 m_key;
157     Uint16 m_itemLen;
158     union {
159       Uint32 m_ui32_value;
160       Uint32 m_strLen; // Including 0-byte in words
161     };
162     ValueType m_type;
163   protected:
164     Reader();
165     virtual void reset() = 0;
166 
167     virtual bool step(Uint32 len) = 0;
168     virtual bool getWord(Uint32 * dst) = 0;
169     virtual bool peekWord(Uint32 * dst) const = 0;
170     virtual bool peekWords(Uint32 * dst, Uint32 len) const = 0;
171   };
172 
173   /**
174    * Writer class
175    */
176   class Writer {
177   public:
Writer()178     Writer() {}
179 
180     bool first();
181     bool add(Uint16 key, Uint32 value);
182     bool add(Uint16 key, const char * value);
183     bool add(Uint16 key, const void* value, int len);
184   protected:
~Writer()185     virtual ~Writer() {}
186     virtual bool reset() = 0;
187     virtual bool putWord(Uint32 val) = 0;
188     virtual bool putWords(const Uint32 * src, Uint32 len) = 0;
189   private:
190     bool add(const char* value, int len);
191   };
192 };
193 
194 /**
195  * Reader for linear memory
196  */
197 class SimplePropertiesLinearReader : public SimpleProperties::Reader {
198 public:
199   SimplePropertiesLinearReader(const Uint32 * src, Uint32 len);
~SimplePropertiesLinearReader()200   virtual ~SimplePropertiesLinearReader() {}
201 
202   virtual void reset();
203   virtual bool step(Uint32 len);
204   virtual bool getWord(Uint32 * dst);
205   virtual bool peekWord(Uint32 * dst) const ;
206   virtual bool peekWords(Uint32 * dst, Uint32 len) const;
207 private:
208   Uint32 m_len;
209   Uint32 m_pos;
210   const Uint32 * m_src;
211 };
212 
213 /**
214  * Writer for linear memory
215  */
216 class LinearWriter : public SimpleProperties::Writer {
217 public:
218   LinearWriter(Uint32 * src, Uint32 len);
~LinearWriter()219   virtual ~LinearWriter() {}
220 
221   virtual bool reset();
222   virtual bool putWord(Uint32 val);
223   virtual bool putWords(const Uint32 * src, Uint32 len);
224   Uint32 getWordsUsed() const;
225 private:
226   Uint32 m_len;
227   Uint32 m_pos;
228   Uint32 * m_src;
229 };
230 
231 /**
232  * Writer for UtilBuffer
233  */
234 class UtilBufferWriter : public SimpleProperties::Writer {
235 public:
236   UtilBufferWriter(class UtilBuffer & buf);
~UtilBufferWriter()237   virtual ~UtilBufferWriter() {}
238 
239   virtual bool reset();
240   virtual bool putWord(Uint32 val);
241   virtual bool putWords(const Uint32 * src, Uint32 len);
242   Uint32 getWordsUsed() const;
243 private:
244   class UtilBuffer & m_buf;
245 };
246 
247 /**
248  * Reader for long signal section memory
249  *
250  *
251  * Implemented in kernel/vm/SimplePropertiesSection.cpp
252  */
253 class SimplePropertiesSectionReader : public SimpleProperties::Reader {
254 public:
255   SimplePropertiesSectionReader(struct SegmentedSectionPtr &,
256 				class SectionSegmentPool &);
~SimplePropertiesSectionReader()257   virtual ~SimplePropertiesSectionReader() {}
258 
259   virtual void reset();
260   virtual bool step(Uint32 len);
261   virtual bool getWord(Uint32 * dst);
262   virtual bool peekWord(Uint32 * dst) const ;
263   virtual bool peekWords(Uint32 * dst, Uint32 len) const;
264   Uint32 getSize() const;
265   bool getWords(Uint32 * dst, Uint32 len);
266 
267 private:
268   Uint32 m_pos;
269   Uint32 m_len;
270   class SectionSegmentPool & m_pool;
271   struct SectionSegment * m_head;
272   struct SectionSegment * m_currentSegment;
273 };
274 
275 inline
getSize() const276 Uint32 SimplePropertiesSectionReader::getSize() const
277 {
278   return m_len;
279 }
280 
281 /**
282  * Writer for long signal section memory
283  *
284  *
285  * Implemented in kernel/vm/SimplePropertiesSection.cpp
286  */
287 class SimplePropertiesSectionWriter : public SimpleProperties::Writer {
288 public:
289   SimplePropertiesSectionWriter(class SimulatedBlock & block);
290   virtual ~SimplePropertiesSectionWriter();
291 
292   virtual bool reset();
293   virtual bool putWord(Uint32 val);
294   virtual bool putWords(const Uint32 * src, Uint32 len);
295   Uint32 getWordsUsed() const;
296 
297   /**
298    * This "unlinks" the writer from the memory
299    */
300   void getPtr(struct SegmentedSectionPtr & dst);
301 
302 private:
303   void release();
304 
305   Int32 m_pos;
306   Uint32 m_sz;
307 
308   class SectionSegmentPool & m_pool;
309   class SimulatedBlock & m_block;
310   struct SectionSegment * m_head;
311   Uint32 m_prevPtrI; // Prev to m_currentSegment
312   struct SectionSegment * m_currentSegment;
313 };
314 
315 #endif
316