summaryrefslogtreecommitdiff
path: root/storage/ndb/src/common/util/SimpleProperties.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'storage/ndb/src/common/util/SimpleProperties.cpp')
-rw-r--r--storage/ndb/src/common/util/SimpleProperties.cpp507
1 files changed, 507 insertions, 0 deletions
diff --git a/storage/ndb/src/common/util/SimpleProperties.cpp b/storage/ndb/src/common/util/SimpleProperties.cpp
new file mode 100644
index 00000000000..00c440fcb4e
--- /dev/null
+++ b/storage/ndb/src/common/util/SimpleProperties.cpp
@@ -0,0 +1,507 @@
+/* Copyright (C) 2003 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <ndb_global.h>
+#include <SimpleProperties.hpp>
+#include <NdbOut.hpp>
+#include <NdbTCP.h>
+#include <UtilBuffer.hpp>
+
+bool
+SimpleProperties::Writer::first(){
+ return reset();
+}
+
+bool
+SimpleProperties::Writer::add(Uint16 key, Uint32 value){
+ Uint32 head = Uint32Value;
+ head <<= 16;
+ head += key;
+ if(!putWord(htonl(head)))
+ return false;
+
+ return putWord(htonl(value));
+}
+
+bool
+SimpleProperties::Writer::add(Uint16 key, const char * value){
+ Uint32 head = StringValue;
+ head <<= 16;
+ head += key;
+ if(!putWord(htonl(head)))
+ return false;
+ Uint32 strLen = strlen(value) + 1; // Including NULL-byte
+ if(!putWord(htonl(strLen)))
+ return false;
+
+ const Uint32 valLen = (strLen + 3) / 4;
+ return putWords((Uint32*)value, valLen);
+}
+
+bool
+SimpleProperties::Writer::add(Uint16 key, const void* value, int len){
+ Uint32 head = BinaryValue;
+ head <<= 16;
+ head += key;
+ if(!putWord(htonl(head)))
+ return false;
+ if(!putWord(htonl(len)))
+ return false;
+
+ const Uint32 valLen = (len + 3) / 4;
+ return putWords((Uint32*)value, valLen);
+}
+
+SimpleProperties::Reader::Reader(){
+ m_itemLen = 0;
+}
+
+bool
+SimpleProperties::Reader::first(){
+ reset();
+ m_itemLen = 0;
+ return readValue();
+}
+
+bool
+SimpleProperties::Reader::next(){
+ return readValue();
+}
+
+bool
+SimpleProperties::Reader::valid() const {
+ return m_type != InvalidValue;
+}
+
+Uint16
+SimpleProperties::Reader::getKey() const{
+ return m_key;
+}
+
+Uint16
+SimpleProperties::Reader::getValueLen() const {
+ switch(m_type){
+ case Uint32Value:
+ return 4;
+ case StringValue:
+ case BinaryValue:
+ return m_strLen;
+ case InvalidValue:
+ return 0;
+ }
+ return 0;
+}
+
+SimpleProperties::ValueType
+SimpleProperties::Reader::getValueType() const {
+ return m_type;
+}
+
+Uint32
+SimpleProperties::Reader::getUint32() const {
+ return m_ui32_value;
+}
+
+char *
+SimpleProperties::Reader::getString(char * dst) const {
+ if(peekWords((Uint32*)dst, m_itemLen))
+ return dst;
+ return 0;
+}
+
+bool
+SimpleProperties::Reader::readValue(){
+ if(!step(m_itemLen)){
+ m_type = InvalidValue;
+ return false;
+ }
+
+ Uint32 tmp;
+ if(!getWord(&tmp)){
+ m_type = InvalidValue;
+ return false;
+ }
+
+ tmp = ntohl(tmp);
+ m_key = tmp & 0xFFFF;
+ m_type = (SimpleProperties::ValueType)(tmp >> 16);
+ switch(m_type){
+ case Uint32Value:
+ m_itemLen = 1;
+ if(!peekWord(&m_ui32_value))
+ return false;
+ m_ui32_value = ntohl(m_ui32_value);
+ return true;
+ case StringValue:
+ case BinaryValue:
+ if(!getWord(&tmp))
+ return false;
+ m_strLen = ntohl(tmp);
+ m_itemLen = (m_strLen + 3)/4;
+ return true;
+ default:
+ m_itemLen = 0;
+ m_type = InvalidValue;
+ return false;
+ }
+}
+
+SimpleProperties::UnpackStatus
+SimpleProperties::unpack(Reader & it, void * dst,
+ const SP2StructMapping _map[], Uint32 mapSz,
+ bool ignoreMinMax,
+ bool ignoreUnknownKeys){
+ do {
+ if(!it.valid())
+ break;
+
+ bool found = false;
+ Uint16 key = it.getKey();
+ for(Uint32 i = 0; i<mapSz; i++){
+ if(key == _map[i].Key){
+ found = true;
+ if(_map[i].Type == InvalidValue)
+ return Break;
+ if(_map[i].Type != it.getValueType())
+ return TypeMismatch;
+
+ char * _dst = (char *)dst;
+ _dst += _map[i].Offset;
+
+ switch(it.getValueType()){
+ case Uint32Value:{
+ const Uint32 val = it.getUint32();
+ if(!ignoreMinMax){
+ if(val < _map[i].minValue)
+ return ValueTooLow;
+ if(val > _map[i].maxValue)
+ return ValueTooHigh;
+ }
+ * ((Uint32 *)_dst) = val;
+ break;
+ }
+ case BinaryValue:
+ case StringValue:{
+ unsigned len = it.getValueLen();
+ if(len < _map[i].minValue)
+ return ValueTooLow;
+ if(len > _map[i].maxValue)
+ return ValueTooHigh;
+ it.getString(_dst);
+ break;
+ }
+ default:
+ abort();
+ }
+ break;
+ }
+ }
+ if(!found && !ignoreUnknownKeys)
+ return UnknownKey;
+ } while(it.next());
+
+ return Eof;
+}
+
+SimpleProperties::UnpackStatus
+SimpleProperties::pack(Writer & it, const void * __src,
+ const SP2StructMapping _map[], Uint32 mapSz,
+ bool ignoreMinMax){
+
+ const char * _src = (const char *)__src;
+
+ for(Uint32 i = 0; i<mapSz; i++){
+ bool ok = false;
+ const char * src = _src + _map[i].Offset;
+ switch(_map[i].Type){
+ case SimpleProperties::InvalidValue:
+ ok = true;
+ break;
+ case SimpleProperties::Uint32Value:{
+ Uint32 val = * ((Uint32*)src);
+ if(!ignoreMinMax){
+ if(val < _map[i].minValue)
+ return ValueTooLow;
+ if(val > _map[i].maxValue)
+ return ValueTooHigh;
+ }
+ ok = it.add(_map[i].Key, val);
+ }
+ break;
+ case SimpleProperties::BinaryValue:{
+ const char * src_len = _src + _map[i].Length_Offset;
+ Uint32 len = *((Uint32*)src_len);
+ if(!ignoreMinMax){
+ if(len == _map[i].maxValue)
+ return ValueTooHigh;
+ }
+ ok = it.add(_map[i].Key, src, len);
+ break;
+ }
+ case SimpleProperties::StringValue:
+ if(!ignoreMinMax){
+ size_t len = strlen(src);
+ if(len == _map[i].maxValue)
+ return ValueTooHigh;
+ }
+ ok = it.add(_map[i].Key, src);
+ break;
+ }
+ if(!ok)
+ return OutOfMemory;
+ }
+
+ return Eof;
+}
+
+void
+SimpleProperties::Reader::printAll(NdbOut& ndbout){
+ char tmp[1024];
+ for(first(); valid(); next()){
+ switch(getValueType()){
+ case SimpleProperties::Uint32Value:
+ ndbout << "Key: " << getKey()
+ << " value(" << getValueLen() << ") : "
+ << getUint32() << endl;
+ break;
+ case SimpleProperties::BinaryValue:
+ case SimpleProperties::StringValue:
+ if(getValueLen() < 1024){
+ getString(tmp);
+ ndbout << "Key: " << getKey()
+ << " value(" << getValueLen() << ") : "
+ << "\"" << tmp << "\"" << endl;
+ } else {
+ ndbout << "Key: " << getKey()
+ << " value(" << getValueLen() << ") : "
+ << "\"" << "<TOO LONG>" << "\"" << endl;
+
+ }
+ break;
+ default:
+ ndbout << "Unknown type for key: " << getKey()
+ << " type: " << (Uint32)getValueType() << endl;
+ }
+ }
+}
+
+SimplePropertiesLinearReader::SimplePropertiesLinearReader
+(const Uint32 * src, Uint32 len){
+ m_src = src;
+ m_len = len;
+ m_pos = 0;
+ first();
+}
+
+void
+SimplePropertiesLinearReader::reset() {
+ m_pos = 0;
+}
+
+bool
+SimplePropertiesLinearReader::step(Uint32 len){
+ m_pos += len;
+ return m_pos < m_len;
+}
+
+bool
+SimplePropertiesLinearReader::getWord(Uint32 * dst) {
+ if(m_pos<m_len){
+ * dst = m_src[m_pos++];
+ return true;
+ }
+ return false;
+}
+
+bool
+SimplePropertiesLinearReader::peekWord(Uint32 * dst) const {
+ if(m_pos<m_len){
+ * dst = m_src[m_pos];
+ return true;
+ }
+ return false;
+}
+
+bool
+SimplePropertiesLinearReader::peekWords(Uint32 * dst, Uint32 len) const {
+ if(m_pos + len <= m_len){
+ memcpy(dst, &m_src[m_pos], 4 * len);
+ return true;
+ }
+ return false;
+}
+
+LinearWriter::LinearWriter(Uint32 * src, Uint32 len){
+ m_src = src;
+ m_len = len;
+ reset();
+}
+
+bool LinearWriter::reset() { m_pos = 0; return m_len > 0;}
+
+bool
+LinearWriter::putWord(Uint32 val){
+ if(m_pos < m_len){
+ m_src[m_pos++] = val;
+ return true;
+ }
+ return false;
+}
+
+bool
+LinearWriter::putWords(const Uint32 * src, Uint32 len){
+ if(m_pos + len <= m_len){
+ memcpy(&m_src[m_pos], src, 4 * len);
+ m_pos += len;
+ return true;
+ }
+ return false;
+}
+
+Uint32
+LinearWriter::getWordsUsed() const { return m_pos;}
+
+UtilBufferWriter::UtilBufferWriter(UtilBuffer & b)
+ : m_buf(b)
+{
+ reset();
+}
+
+bool UtilBufferWriter::reset() { m_buf.clear(); return true;}
+
+bool
+UtilBufferWriter::putWord(Uint32 val){
+ return (m_buf.append(&val, 4) == 0);
+}
+
+bool
+UtilBufferWriter::putWords(const Uint32 * src, Uint32 len){
+ return (m_buf.append(src, 4 * len) == 0);
+}
+
+Uint32
+UtilBufferWriter::getWordsUsed() const { return m_buf.length() / 4;}
+
+#if 0
+LinearPagesReader::LinearPagesReader(const Uint32 * base,
+ Uint32 pageSize,
+ Uint32 headerSize,
+ Uint32 noOfPages,
+ Uint32 len){
+ m_base = base;
+ m_pageSz = pageSize;
+ m_noOfPages = noOfPages;
+ m_pageHeaderSz = headerSize;
+ m_len = len;
+ reset();
+}
+
+void
+LinearPagesReader::reset() { m_pos = 0;}
+
+bool
+LinearPagesReader::step(Uint32 len){
+ m_pos += len;
+ return m_pos < m_len;
+}
+
+bool
+LinearPagesReader::getWord(Uint32 * dst) {
+ if(m_pos<m_len){
+ * dst = m_base[getPos(m_pos++)];
+ return true;
+ }
+ return false;
+}
+
+bool
+LinearPagesReader::peekWord(Uint32 * dst) const {
+ if(m_pos<m_len){
+ * dst = m_base[getPos(m_pos)];
+ return true;
+ }
+ return false;
+}
+
+bool
+LinearPagesReader::peekWords(Uint32 * dst, Uint32 len) const {
+ if(m_pos + len <= m_len){
+ for(Uint32 i = 0; i<len; i++)
+ * (dst + i) = m_base[getPos(m_pos + i)];
+ return true;
+ }
+ return false;
+}
+
+Uint32
+LinearPagesReader::getPos(Uint32 pos) const {
+ const Uint32 sz = (m_pageSz - m_pageHeaderSz);
+ Uint32 no = pos / sz;
+ Uint32 in = pos % sz;
+ return no * m_pageSz + m_pageHeaderSz + in;
+}
+
+LinearPagesWriter::LinearPagesWriter(Uint32 * base,
+ Uint32 pageSize,
+ Uint32 noOfPages,
+ Uint32 headerSize){
+ m_base = base;
+ m_pageSz = pageSize;
+ m_noOfPages = noOfPages;
+ m_pageHeaderSz = headerSize;
+ m_len = noOfPages * (pageSize - headerSize);
+ reset();
+}
+
+bool
+LinearPagesWriter::putWord(Uint32 val){
+ if(m_pos < m_len){
+ m_base[getPos(m_pos++)] = val;
+ return true;
+ }
+ return false;
+}
+
+bool
+LinearPagesWriter::putWords(const Uint32 * src, Uint32 len){
+ if(m_pos + len <= m_len){
+ for(Uint32 i = 0; i<len; i++)
+ m_base[getPos(m_pos++)] = src[i];
+ return true;
+ }
+ return false;
+}
+
+#if 0
+Uint32
+LinearPagesWriter::getWordsUsed() const {
+ return getPos(m_pos);
+}
+#endif
+
+Uint32
+LinearPagesWriter::getPagesUsed() const {
+ return m_pos / (m_pageSz - m_pageHeaderSz);
+}
+
+Uint32
+LinearPagesWriter::getPos(Uint32 pos) const {
+ const Uint32 sz = (m_pageSz - m_pageHeaderSz);
+ Uint32 no = pos / sz;
+ Uint32 in = pos % sz;
+ return no * m_pageSz + m_pageHeaderSz + in;
+}
+#endif