/* Copyright (C) 2004-2006 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 St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __CONFIG_VALUES_HPP #define __CONFIG_VALUES_HPP #include #include class ConfigValues { friend class ConfigValuesFactory; ConfigValues(Uint32 sz, Uint32 data); public: ~ConfigValues(); enum ValueType { InvalidType = 0, IntType = 1, StringType = 2, SectionType = 3, Int64Type = 4 }; struct Entry { Uint32 m_key; ValueType m_type; union { Uint32 m_int; Uint64 m_int64; const char * m_string; }; }; class ConstIterator { friend class ConfigValuesFactory; const ConfigValues & m_cfg; public: Uint32 m_currentSection; ConstIterator(const ConfigValues&c) : m_cfg(c) { m_currentSection = 0;} bool openSection(Uint32 key, Uint32 no); bool closeSection(); bool get(Uint32 key, Entry *) const; bool get(Uint32 key, Uint32 * value) const; bool get(Uint32 key, Uint64 * value) const; bool get(Uint32 key, const char ** value) const; bool getTypeOf(Uint32 key, ValueType * type) const; Uint32 get(Uint32 key, Uint32 notFound) const; Uint64 get64(Uint32 key, Uint64 notFound) const; const char * get(Uint32 key, const char * notFound) const; ValueType getTypeOf(Uint32 key) const; }; class Iterator : public ConstIterator { ConfigValues & m_cfg; public: Iterator(ConfigValues&c) : ConstIterator(c), m_cfg(c) {} Iterator(ConfigValues&c, const ConstIterator& i):ConstIterator(c),m_cfg(c){ m_currentSection = i.m_currentSection; } bool set(Uint32 key, Uint32 value); bool set(Uint32 key, Uint64 value); bool set(Uint32 key, const char * value); }; Uint32 getPackedSize() const; // get size in bytes needed to pack Uint32 pack(UtilBuffer&) const; Uint32 pack(void * dst, Uint32 len) const;// pack into dst(of len %d); private: friend class Iterator; friend class ConstIterator; bool getByPos(Uint32 pos, Entry *) const; Uint64 * get64(Uint32 index) const; char ** getString(Uint32 index) const; Uint32 m_size; Uint32 m_dataSize; Uint32 m_stringCount; Uint32 m_int64Count; Uint32 m_values[1]; void * m_data[1]; }; class ConfigValuesFactory { Uint32 m_currentSection; public: Uint32 m_sectionCounter; Uint32 m_freeKeys; Uint32 m_freeData; public: ConfigValuesFactory(Uint32 keys = 50, Uint32 data = 10); // Initial ConfigValuesFactory(ConfigValues * m_cfg); // ~ConfigValuesFactory(); ConfigValues * m_cfg; ConfigValues * getConfigValues(); bool openSection(Uint32 key, Uint32 no); bool put(const ConfigValues::Entry & ); bool put(Uint32 key, Uint32 value); bool put64(Uint32 key, Uint64 value); bool put(Uint32 key, const char * value); bool closeSection(); void expand(Uint32 freeKeys, Uint32 freeData); void shrink(); bool unpack(const UtilBuffer&); bool unpack(const void * src, Uint32 len); static ConfigValues * extractCurrentSection(const ConfigValues::ConstIterator &); private: static ConfigValues * create(Uint32 keys, Uint32 data); void put(const ConfigValues & src); }; inline bool ConfigValues::ConstIterator::get(Uint32 key, Uint32 * value) const { Entry tmp; if(get(key, &tmp) && tmp.m_type == IntType){ * value = tmp.m_int; return true; } return false; } inline bool ConfigValues::ConstIterator::get(Uint32 key, Uint64 * value) const { Entry tmp; if(get(key, &tmp) && tmp.m_type == Int64Type){ * value = tmp.m_int64; return true; } return false; } inline bool ConfigValues::ConstIterator::get(Uint32 key, const char ** value) const { Entry tmp; if(get(key, &tmp) && tmp.m_type == StringType){ * value = tmp.m_string; return true; } return false; } inline bool ConfigValues::ConstIterator::getTypeOf(Uint32 key, ValueType * type) const{ Entry tmp; if(get(key, &tmp)){ * type = tmp.m_type; return true; } return false; } inline Uint32 ConfigValues::ConstIterator::get(Uint32 key, Uint32 notFound) const { Entry tmp; if(get(key, &tmp) && tmp.m_type == IntType){ return tmp.m_int; } return notFound; } inline Uint64 ConfigValues::ConstIterator::get64(Uint32 key, Uint64 notFound) const { Entry tmp; if(get(key, &tmp) && tmp.m_type == Int64Type){ return tmp.m_int64; } return notFound; } inline const char * ConfigValues::ConstIterator::get(Uint32 key, const char * notFound) const { Entry tmp; if(get(key, &tmp) && tmp.m_type == StringType){ return tmp.m_string; } return notFound; } inline ConfigValues::ValueType ConfigValues::ConstIterator::getTypeOf(Uint32 key) const{ Entry tmp; if(get(key, &tmp)){ return tmp.m_type; } return ConfigValues::InvalidType; } inline bool ConfigValuesFactory::put(Uint32 key, Uint32 val){ ConfigValues::Entry tmp; tmp.m_key = key; tmp.m_type = ConfigValues::IntType; tmp.m_int = val; return put(tmp); } inline bool ConfigValuesFactory::put64(Uint32 key, Uint64 val){ ConfigValues::Entry tmp; tmp.m_key = key; tmp.m_type = ConfigValues::Int64Type; tmp.m_int64 = val; return put(tmp); } inline bool ConfigValuesFactory::put(Uint32 key, const char * val){ ConfigValues::Entry tmp; tmp.m_key = key; tmp.m_type = ConfigValues::StringType; tmp.m_string = val; return put(tmp); } inline Uint32 ConfigValues::pack(UtilBuffer& buf) const { Uint32 len = getPackedSize(); void * tmp = buf.append(len); if(tmp == 0){ return 0; } return pack(tmp, len); } inline bool ConfigValuesFactory::unpack(const UtilBuffer& buf){ return unpack(buf.get_data(), buf.length()); } #endif