SimpleProperties.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:10k
源码类别:

MySQL数据库

开发平台:

Visual C++

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