File indexing completed on 2024-05-05 04:38:10

0001 /*
0002     SPDX-FileCopyrightText: 2008 David Nolden <david.nolden.kdevelop@art-master.de>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #ifndef KDEVPLATFORM_STRINGREPOSITORY_H
0008 #define KDEVPLATFORM_STRINGREPOSITORY_H
0009 
0010 #include <QString>
0011 
0012 #include "itemrepository.h"
0013 #include "indexedstring.h"
0014 
0015 namespace Repositories {
0016 using namespace KDevelop;
0017 
0018 struct StringData
0019 {
0020     unsigned short length;
0021 
0022     StringData& operator=(const StringData& rhs) = delete;
0023 
0024     unsigned int itemSize() const
0025     {
0026         return sizeof(StringData) + length;
0027     }
0028     unsigned int hash() const
0029     {
0030         IndexedString::RunningHash running;
0031         const char* str = reinterpret_cast<const char*>(this) + sizeof(StringData);
0032         for (int a = length - 1; a >= 0; --a) {
0033             running.append(*str);
0034             ++str;
0035         }
0036 
0037         return running.hash;
0038     }
0039 };
0040 
0041 struct StringRepositoryItemRequest
0042 {
0043     //The text is supposed to be utf8 encoded
0044     StringRepositoryItemRequest(const char* text, unsigned int hash, unsigned short length) : m_hash(hash)
0045         , m_length(length)
0046         , m_text(text)
0047     {
0048     }
0049 
0050     enum {
0051         AverageSize = 10 //This should be the approximate average size of an Item
0052     };
0053 
0054     using HashType = unsigned int;
0055 
0056     //Should return the hash-value associated with this request(For example the hash of a string)
0057     HashType hash() const
0058     {
0059         return m_hash;
0060     }
0061 
0062     //Should return the size of an item created with createItem
0063     uint itemSize() const
0064     {
0065         return sizeof(StringData) + m_length;
0066     }
0067     //Should create an item where the information of the requested item is permanently stored. The pointer
0068     //@param item equals an allocated range with the size of itemSize().
0069     void createItem(StringData* item) const
0070     {
0071         item->length = m_length;
0072         void* itemText = reinterpret_cast<void*>(item + 1);
0073         memcpy(itemText, m_text, m_length);
0074     }
0075 
0076     static void destroy(StringData*, KDevelop::AbstractItemRepository&)
0077     {
0078     }
0079 
0080     static bool persistent(const StringData*)
0081     {
0082         //Reference-counting not supported in the normal string repository
0083         return true;
0084     }
0085 
0086     //Should return whether the here requested item equals the given item
0087     bool equals(const StringData* item) const
0088     {
0089         return item->length == m_length && (memcmp(++item, m_text, m_length) == 0);
0090     }
0091     unsigned int m_hash;
0092     unsigned short m_length;
0093     const char* m_text;
0094 };
0095 
0096 using StringRepository = ItemRepository<StringData, StringRepositoryItemRequest, false>;
0097 
0098 ///@param item must be valid(nonzero)
0099 inline QString stringFromItem(const StringData* item)
0100 {
0101     const unsigned short* textPos = ( unsigned short* )(item + 1);
0102     return QString::fromUtf8(reinterpret_cast<const char*>(textPos), item->length);
0103 }
0104 
0105 inline QByteArray arrayFromItem(const StringData* item)
0106 {
0107     const unsigned short* textPos = ( unsigned short* )(item + 1);
0108     return QByteArray(reinterpret_cast<const char*>(textPos), item->length);
0109 }
0110 }
0111 #endif