/* -*- mode: C++; tab-width: 4; c-basic-offset: 4; -*- */ /* AbiWord * Copyright (C) 2003 Francis James Franklin * Copyright (C) 2003 AbiSource, Inc. * * 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. */ #ifndef UT_INTSTRMAP_H #define UT_INTSTRMAP_H /* pre-emptive dismissal; ut_types.h is needed by just about everything, * so even if it's commented out in-file that's still a lot of work for * the preprocessor to do... */ #ifndef UT_TYPES_H #include "ut_types.h" #endif #include "ut_string_class.h" /* Four hash maps are defined here: * * 1. UT_IntStrMap * Maps integers to UTF-8 strings, e.g. map[1] == "one" * * 2. UT_NumberMap * Maps UTF-8 strings to integers, e.g. map["one"] == 1 * * 3. UT_GenericUTF8Hash * An alternative to UT_StringPtrMap (defined in ut_hash.h) but restricted to UTF-8 string keys; * one important difference is that UT_GenericUTF8Hash automatically free()s/deletes its contents. * Can't be instantiated, but isn't abstract. Designed for easy subclassing. * * NOTE: UT_GenericBase is declared in ut_string_class.h * * 4. UT_UTF8Hash * Useful subclass of UT_GenericUTF8Hash which maps UTF-8 strings to UTF-8 strings, e.g. map["one"] == "1" */ class ABI_EXPORT UT_IntStrMap { private: struct IntStr { UT_sint32 key; UT_UTF8String * value; }; public: UT_IntStrMap (); UT_IntStrMap (UT_uint32 increment); ~UT_IntStrMap (); void clear (); bool ins (UT_sint32 key, UT_UTF8String * value); // responsibility for value passes here bool ins (UT_sint32 key, const char * value); /* returns false if no such key-value */ bool del (UT_sint32 key); // value is deleted bool del (UT_sint32 key, UT_UTF8String *& value); // value is passed back inline const UT_UTF8String * operator[] (UT_sint32 key) { UT_uint32 index; return lookup (key, index) ? m_pair[index].value : 0; } private: bool lookup (UT_sint32 key, UT_uint32 & index); bool grow (); IntStr * m_pair; UT_uint32 m_pair_count; UT_uint32 m_pair_max; UT_uint32 m_index; UT_uint32 m_increment; public: inline bool pair (UT_uint32 index, UT_sint32 & key, const UT_UTF8String *& value) const { if (index >= m_pair_count) return false; key = m_pair[index].key; value = m_pair[index].value; return true; } UT_uint32 count () const { return m_pair_count; } }; class ABI_EXPORT UT_NumberMap { private: struct NumberStr { UT_UTF8String * key; UT_sint32 value; }; public: /* operator[] must return something, even if key not found, so what? * set default return value in constructor */ UT_NumberMap (UT_sint32 default_value = -1, UT_uint32 increment = 32); ~UT_NumberMap (); void clear (); bool ins (const UT_UTF8String & key, UT_sint32 value); /* returns false if no such key-value */ bool del (const char * key); inline UT_sint32 operator[] (const char * key) { UT_uint32 index; return lookup (key, index) ? m_pair[index].value : m_default_value; } inline UT_sint32 operator[] (const UT_UTF8String & key) { UT_uint32 index; return lookup (key, index) ? m_pair[index].value : m_default_value; } private: bool lookup (const char * key, UT_uint32 & index); bool lookup (const UT_UTF8String & key, UT_uint32 & index); bool lookup (const char * key, UT_uint32 key_length, UT_uint32 & index); bool grow (); NumberStr * m_pair; UT_uint32 m_pair_count; UT_uint32 m_pair_max; UT_uint32 m_index; UT_uint32 m_increment; UT_sint32 m_default_value; public: inline bool pair (UT_uint32 index, const UT_UTF8String *& key, UT_sint32 & value) const { if (index >= m_pair_count) return false; key = m_pair[index].key; value = m_pair[index].value; return true; } UT_uint32 count () const { return m_pair_count; } }; class ABI_EXPORT UT_GenericUTF8Hash { private: class ABI_EXPORT KeyValue { private: UT_UTF8String m_key; UT_GenericBase * m_value; public: KeyValue (const UT_UTF8String & key); ~KeyValue (); /* responsibility for value passes here */ void setValue (UT_GenericBase * value); /* and passes back here */ UT_GenericBase * getValue (); const UT_UTF8String & key () const { return m_key; } const UT_GenericBase * value () const { return m_value; } }; // disable these: UT_GenericUTF8Hash (const UT_GenericUTF8Hash & rhs); UT_GenericUTF8Hash & operator= (const UT_GenericUTF8Hash & rhs); protected: UT_GenericUTF8Hash (UT_uint32 increment); public: /* the destructor calls clear(false); * subclasses' destructors should call clear(true) if values need to be deleted */ virtual ~UT_GenericUTF8Hash (); inline UT_uint32 count () const { return m_pair_count; } protected: /* deletes all key/value pairs, but doesn't free() array of pointers */ void clear (bool delete_values); /* for easy sequential access of map members: */ virtual bool pair (UT_uint32 index, const UT_UTF8String *& key, const UT_GenericBase *& value) const; /* responsibility for value passes here */ virtual bool ins (const UT_UTF8String & key, UT_GenericBase * value); /* returns false if no such key-value */ virtual bool del (const char * key); virtual bool del (const UT_UTF8String & key); /* return value rather than deleting */ virtual bool del (const char * key, UT_GenericBase *& value); virtual bool del (const UT_UTF8String & key, UT_GenericBase *& value); virtual const UT_GenericBase * lookup (const char * key); virtual const UT_GenericBase * lookup (const UT_UTF8String & key); private: bool lookup (const char * key, UT_uint32 & index); bool lookup (const UT_UTF8String & key, UT_uint32 & index); bool lookup (const char * key, UT_uint32 key_length, UT_uint32 & index); bool grow (); KeyValue ** m_pair; UT_uint32 m_pair_count; UT_uint32 m_pair_max; UT_uint32 m_index; UT_uint32 m_increment; }; class ABI_EXPORT UT_UTF8Hash : public UT_GenericUTF8Hash { private: bool m_bStripEmptyValues; public: UT_UTF8Hash (bool bStripEmptyValues = false); ~UT_UTF8Hash (); inline void clear () { UT_GenericUTF8Hash::clear (true); } /* for easy sequential access of map members: */ bool pair (UT_uint32 index, const UT_UTF8String *& key, const UT_UTF8String *& value) const; /* responsibility for value passes here */ inline bool ins (const UT_UTF8String & key, UT_UTF8String * value) { return value ? UT_GenericUTF8Hash::ins (key, value) : false; } bool ins (const UT_UTF8String & key, const UT_UTF8String & value); bool ins (const char * key, const char * value); // make sure you provide valid UTF-8! bool ins (const char ** attrs); // attribute pairs with a 0 value are ignored void parse_properties (const char * properties); // insert key-value pairs from CSS-style string void parse_attributes (const char * attributes); // insert key-value pairs from attribute list /* returns false if no such key-value */ inline bool del (const char * key) { return UT_GenericUTF8Hash::del (key); } inline bool del (const UT_UTF8String & key) { return UT_GenericUTF8Hash::del (key); } /* return value rather than deleting */ bool del (const char * key, UT_UTF8String *& value); bool del (const UT_UTF8String & key, UT_UTF8String *& value); inline const UT_UTF8String * operator[] (const char * key) { return static_cast(UT_GenericUTF8Hash::lookup (key)); } inline const UT_UTF8String * operator[] (const UT_UTF8String & key) { return static_cast(UT_GenericUTF8Hash::lookup (key)); } }; ABI_EXPORT bool operator==(const UT_UTF8Hash & lhs, const UT_UTF8Hash & rhs); #endif /* ! UT_INTSTRMAP_H */