MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SimpleProperties.cpp
1 /*
2  Copyright (C) 2003-2006 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 as published by
7  the Free Software Foundation; version 2 of the License.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 #include <ndb_global.h>
20 #include <SimpleProperties.hpp>
21 #include <NdbOut.hpp>
22 #include <NdbTCP.h>
23 #include <UtilBuffer.hpp>
24 
25 bool
26 SimpleProperties::Writer::first(){
27  return reset();
28 }
29 
30 bool
31 SimpleProperties::Writer::add(Uint16 key, Uint32 value){
32  Uint32 head = Uint32Value;
33  head <<= 16;
34  head += key;
35  if(!putWord(htonl(head)))
36  return false;
37 
38  return putWord(htonl(value));
39 }
40 
41 bool
42 SimpleProperties::Writer::add(const char * value, int len){
43  const Uint32 valLen = (len + 3) / 4;
44 
45  if ((len % 4) == 0)
46  return putWords((Uint32*)value, valLen);
47 
48  const Uint32 putLen= valLen - 1;
49  if (!putWords((Uint32*)value, putLen))
50  return false;
51 
52  // Special handling of last bytes
53  union {
54  Uint32 lastWord;
55  char lastBytes[4];
56  } tmp;
57  tmp.lastWord =0 ;
58  memcpy(tmp.lastBytes,
59  value + putLen*4,
60  len - putLen*4);
61  return putWord(tmp.lastWord);
62 }
63 
64 bool
65 SimpleProperties::Writer::add(Uint16 key, const char * value){
66  Uint32 head = StringValue;
67  head <<= 16;
68  head += key;
69  if(!putWord(htonl(head)))
70  return false;
71  Uint32 strLen = Uint32(strlen(value) + 1); // Including NULL-byte
72  if(!putWord(htonl(strLen)))
73  return false;
74 
75  return add(value, (int)strLen);
76 
77 }
78 
79 bool
80 SimpleProperties::Writer::add(Uint16 key, const void* value, int len){
81  Uint32 head = BinaryValue;
82  head <<= 16;
83  head += key;
84  if(!putWord(htonl(head)))
85  return false;
86  if(!putWord(htonl(len)))
87  return false;
88 
89  return add((const char*)value, len);
90 }
91 
92 SimpleProperties::Reader::Reader(){
93  m_itemLen = 0;
94 }
95 
96 bool
98  reset();
99  m_itemLen = 0;
100  return readValue();
101 }
102 
103 bool
105  return readValue();
106 }
107 
108 bool
110  return m_type != InvalidValue;
111 }
112 
113 Uint16
115  return m_key;
116 }
117 
118 Uint16
120  switch(m_type){
121  case Uint32Value:
122  return 4;
123  case StringValue:
124  case BinaryValue:
125  return m_strLen;
126  case InvalidValue:
127  return 0;
128  }
129  return 0;
130 }
131 
134  return m_type;
135 }
136 
137 Uint32
139  return m_ui32_value;
140 }
141 
142 char *
143 SimpleProperties::Reader::getString(char * dst) const {
144  if(peekWords((Uint32*)dst, m_itemLen))
145  return dst;
146  return 0;
147 }
148 
149 bool
150 SimpleProperties::Reader::readValue(){
151  if(!step(m_itemLen)){
152  m_type = InvalidValue;
153  return false;
154  }
155 
156  Uint32 tmp;
157  if(!getWord(&tmp)){
158  m_type = InvalidValue;
159  return false;
160  }
161 
162  tmp = ntohl(tmp);
163  m_key = tmp & 0xFFFF;
164  m_type = (SimpleProperties::ValueType)(tmp >> 16);
165  switch(m_type){
166  case Uint32Value:
167  m_itemLen = 1;
168  if(!peekWord(&m_ui32_value))
169  return false;
170  m_ui32_value = ntohl(m_ui32_value);
171  return true;
172  case StringValue:
173  case BinaryValue:
174  if(!getWord(&tmp))
175  return false;
176  m_strLen = ntohl(tmp);
177  m_itemLen = (m_strLen + 3)/4;
178  return true;
179  default:
180  m_itemLen = 0;
181  m_type = InvalidValue;
182  return false;
183  }
184 }
185 
187 SimpleProperties::unpack(Reader & it, void * dst,
188  const SP2StructMapping _map[], Uint32 mapSz,
189  bool ignoreMinMax,
190  bool ignoreUnknownKeys){
191  do {
192  if(!it.valid())
193  break;
194 
195  bool found = false;
196  Uint16 key = it.getKey();
197  for(Uint32 i = 0; i<mapSz; i++){
198  if(key == _map[i].Key){
199  found = true;
200  if(_map[i].Type == InvalidValue)
201  return Break;
202  if(_map[i].Type != it.getValueType())
203  return TypeMismatch;
204 
205  char * _dst = (char *)dst;
206  _dst += _map[i].Offset;
207 
208  switch(it.getValueType()){
209  case Uint32Value:{
210  const Uint32 val = it.getUint32();
211  if(!ignoreMinMax){
212  if(val < _map[i].minValue)
213  return ValueTooLow;
214  if(val > _map[i].maxValue)
215  return ValueTooHigh;
216  }
217  * ((Uint32 *)_dst) = val;
218  break;
219  }
220  case BinaryValue:
221  case StringValue:{
222  unsigned len = it.getValueLen();
223  if(len < _map[i].minValue)
224  return ValueTooLow;
225  if(len > _map[i].maxValue)
226  return ValueTooHigh;
227  it.getString(_dst);
228  break;
229  }
230  default:
231  abort();
232  }
233  break;
234  }
235  }
236  if(!found && !ignoreUnknownKeys)
237  return UnknownKey;
238  } while(it.next());
239 
240  return Eof;
241 }
242 
244 SimpleProperties::pack(Writer & it, const void * __src,
245  const SP2StructMapping _map[], Uint32 mapSz,
246  bool ignoreMinMax){
247 
248  const char * _src = (const char *)__src;
249 
250  for(Uint32 i = 0; i<mapSz; i++){
251  bool ok = false;
252  const char * src = _src + _map[i].Offset;
253  switch(_map[i].Type){
254  case SimpleProperties::InvalidValue:
255  ok = true;
256  break;
257  case SimpleProperties::Uint32Value:{
258  Uint32 val = * ((Uint32*)src);
259  if(!ignoreMinMax){
260  if(val < _map[i].minValue)
261  return ValueTooLow;
262  if(val > _map[i].maxValue)
263  return ValueTooHigh;
264  }
265  ok = it.add(_map[i].Key, val);
266  }
267  break;
268  case SimpleProperties::BinaryValue:{
269  const char * src_len = _src + _map[i].Length_Offset;
270  Uint32 len = *((Uint32*)src_len);
271  if(!ignoreMinMax){
272  if(len > _map[i].maxValue)
273  return ValueTooHigh;
274  }
275  ok = it.add(_map[i].Key, src, len);
276  break;
277  }
278  case SimpleProperties::StringValue:
279  if(!ignoreMinMax){
280  size_t len = strlen(src);
281  if(len > _map[i].maxValue)
282  return ValueTooHigh;
283  }
284  ok = it.add(_map[i].Key, src);
285  break;
286  }
287  if(!ok)
288  return OutOfMemory;
289  }
290 
291  return Eof;
292 }
293 
294 void
296  char tmp[1024];
297  for(first(); valid(); next()){
298  switch(getValueType()){
299  case SimpleProperties::Uint32Value:
300  ndbout << "Key: " << getKey()
301  << " value(" << getValueLen() << ") : "
302  << getUint32() << endl;
303  break;
304  case SimpleProperties::BinaryValue:
305  case SimpleProperties::StringValue:
306  if(getValueLen() < 1024){
307  getString(tmp);
308  ndbout << "Key: " << getKey()
309  << " value(" << getValueLen() << ") : "
310  << "\"" << tmp << "\"" << endl;
311  } else {
312  ndbout << "Key: " << getKey()
313  << " value(" << getValueLen() << ") : "
314  << "\"" << "<TOO LONG>" << "\"" << endl;
315 
316  }
317  break;
318  default:
319  ndbout << "Unknown type for key: " << getKey()
320  << " type: " << (Uint32)getValueType() << endl;
321  }
322  }
323 }
324 
325 SimplePropertiesLinearReader::SimplePropertiesLinearReader
326 (const Uint32 * src, Uint32 len){
327  m_src = src;
328  m_len = len;
329  m_pos = 0;
330  first();
331 }
332 
333 void
334 SimplePropertiesLinearReader::reset() {
335  m_pos = 0;
336 }
337 
338 bool
339 SimplePropertiesLinearReader::step(Uint32 len){
340  m_pos += len;
341  return m_pos < m_len;
342 }
343 
344 bool
345 SimplePropertiesLinearReader::getWord(Uint32 * dst) {
346  if(m_pos<m_len){
347  * dst = m_src[m_pos++];
348  return true;
349  }
350  return false;
351 }
352 
353 bool
354 SimplePropertiesLinearReader::peekWord(Uint32 * dst) const {
355  if(m_pos<m_len){
356  * dst = m_src[m_pos];
357  return true;
358  }
359  return false;
360 }
361 
362 bool
363 SimplePropertiesLinearReader::peekWords(Uint32 * dst, Uint32 len) const {
364  if(m_pos + len <= m_len){
365  memcpy(dst, &m_src[m_pos], 4 * len);
366  return true;
367  }
368  return false;
369 }
370 
371 LinearWriter::LinearWriter(Uint32 * src, Uint32 len){
372  m_src = src;
373  m_len = len;
374  reset();
375 }
376 
377 bool LinearWriter::reset() { m_pos = 0; return m_len > 0;}
378 
379 bool
380 LinearWriter::putWord(Uint32 val){
381  if(m_pos < m_len){
382  m_src[m_pos++] = val;
383  return true;
384  }
385  return false;
386 }
387 
388 bool
389 LinearWriter::putWords(const Uint32 * src, Uint32 len){
390  if(m_pos + len <= m_len){
391  memcpy(&m_src[m_pos], src, 4 * len);
392  m_pos += len;
393  return true;
394  }
395  return false;
396 }
397 
398 Uint32
399 LinearWriter::getWordsUsed() const { return m_pos;}
400 
401 UtilBufferWriter::UtilBufferWriter(UtilBuffer & b)
402  : m_buf(b)
403 {
404  reset();
405 }
406 
407 bool UtilBufferWriter::reset() { m_buf.clear(); return true;}
408 
409 bool
410 UtilBufferWriter::putWord(Uint32 val){
411  return (m_buf.append(&val, 4) == 0);
412 }
413 
414 bool
415 UtilBufferWriter::putWords(const Uint32 * src, Uint32 len){
416  return (m_buf.append(src, 4 * len) == 0);
417 }
418 
419 
420 Uint32
421 UtilBufferWriter::getWordsUsed() const { return m_buf.length() / 4;}
422 
423 #if 0
424 LinearPagesReader::LinearPagesReader(const Uint32 * base,
425  Uint32 pageSize,
426  Uint32 headerSize,
427  Uint32 noOfPages,
428  Uint32 len){
429  m_base = base;
430  m_pageSz = pageSize;
431  m_noOfPages = noOfPages;
432  m_pageHeaderSz = headerSize;
433  m_len = len;
434  reset();
435 }
436 
437 void
438 LinearPagesReader::reset() { m_pos = 0;}
439 
440 bool
441 LinearPagesReader::step(Uint32 len){
442  m_pos += len;
443  return m_pos < m_len;
444 }
445 
446 bool
447 LinearPagesReader::getWord(Uint32 * dst) {
448  if(m_pos<m_len){
449  * dst = m_base[getPos(m_pos++)];
450  return true;
451  }
452  return false;
453 }
454 
455 bool
456 LinearPagesReader::peekWord(Uint32 * dst) const {
457  if(m_pos<m_len){
458  * dst = m_base[getPos(m_pos)];
459  return true;
460  }
461  return false;
462 }
463 
464 bool
465 LinearPagesReader::peekWords(Uint32 * dst, Uint32 len) const {
466  if(m_pos + len <= m_len){
467  for(Uint32 i = 0; i<len; i++)
468  * (dst + i) = m_base[getPos(m_pos + i)];
469  return true;
470  }
471  return false;
472 }
473 
474 Uint32
475 LinearPagesReader::getPos(Uint32 pos) const {
476  const Uint32 sz = (m_pageSz - m_pageHeaderSz);
477  Uint32 no = pos / sz;
478  Uint32 in = pos % sz;
479  return no * m_pageSz + m_pageHeaderSz + in;
480 }
481 
482 LinearPagesWriter::LinearPagesWriter(Uint32 * base,
483  Uint32 pageSize,
484  Uint32 noOfPages,
485  Uint32 headerSize){
486  m_base = base;
487  m_pageSz = pageSize;
488  m_noOfPages = noOfPages;
489  m_pageHeaderSz = headerSize;
490  m_len = noOfPages * (pageSize - headerSize);
491  reset();
492 }
493 
494 bool
495 LinearPagesWriter::putWord(Uint32 val){
496  if(m_pos < m_len){
497  m_base[getPos(m_pos++)] = val;
498  return true;
499  }
500  return false;
501 }
502 
503 bool
504 LinearPagesWriter::putWords(const Uint32 * src, Uint32 len){
505  if(m_pos + len <= m_len){
506  for(Uint32 i = 0; i<len; i++)
507  m_base[getPos(m_pos++)] = src[i];
508  return true;
509  }
510  return false;
511 }
512 
513 #if 0
514 Uint32
515 LinearPagesWriter::getWordsUsed() const {
516  return getPos(m_pos);
517 }
518 #endif
519 
520 Uint32
521 LinearPagesWriter::getPagesUsed() const {
522  return m_pos / (m_pageSz - m_pageHeaderSz);
523 }
524 
525 Uint32
526 LinearPagesWriter::getPos(Uint32 pos) const {
527  const Uint32 sz = (m_pageSz - m_pageHeaderSz);
528  Uint32 no = pos / sz;
529  Uint32 in = pos % sz;
530  return no * m_pageSz + m_pageHeaderSz + in;
531 }
532 #endif