/* 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; version 2 of the License. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include #include 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(const char * value, int len){ const Uint32 valLen = (len + 3) / 4; if ((len % 4) == 0) return putWords((Uint32*)value, valLen); const Uint32 putLen= valLen - 1; if (!putWords((Uint32*)value, putLen)) return false; // Special handling of last bytes union { Uint32 lastWord; char lastBytes[4]; } tmp; tmp.lastWord =0 ; memcpy(tmp.lastBytes, value + putLen*4, len - putLen*4); return putWord(tmp.lastWord); } 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; return add(value, (int)strLen); } 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; return add((const char*)value, len); } 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 _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 _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() << ") : " << "\"" << "" << "\"" << 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 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