• Skip to content
  • Skip to link menu
KDE 4.4 API Reference
  • KDE API Reference
  • KDevelop Platform Libraries
  • Sitemap
  • Contact Us
 

language/duchain

indexedstring.cpp

00001 /***************************************************************************
00002    Copyright 2008 David Nolden <david.nolden.kdevelop@art-master.de>
00003 ***************************************************************************/
00004 
00005 /***************************************************************************
00006  *                                                                         *
00007  *   This program is free software; you can redistribute it and/or modify  *
00008  *   it under the terms of the GNU General Public License as published by  *
00009  *   the Free Software Foundation; either version 2 of the License, or     *
00010  *   (at your option) any later version.                                   *
00011  *                                                                         *
00012  ***************************************************************************/
00013 
00014 #include "indexedstring.h"
00015 #include "repositories/stringrepository.h"
00016 
00017 #include <kurl.h>
00018 #include "referencecounting.h"
00019 
00020 namespace KDevelop {
00021 namespace {
00022   
00023 struct IndexedStringData {
00024   unsigned short length;
00025   unsigned int refCount;
00026   unsigned int itemSize() const {
00027     return sizeof(IndexedStringData) + length;
00028   }
00029   unsigned int hash() const {
00030     IndexedString::RunningHash running;
00031     const char* str = ((const char*)this) + sizeof(IndexedStringData);
00032     for(int a = length-1; a >= 0; --a) {
00033       running.append(*str);
00034       ++str;
00035     }
00036     return running.hash;
00037     
00038   }
00039 };
00040 
00041 inline void increase(uint& val) {
00042   ++val;
00043 }
00044 
00045 inline void decrease(uint& val) {
00046   --val;
00047 }
00048 
00049 struct IndexedStringRepositoryItemRequest {
00050 
00051   //The text is supposed to be utf8 encoded
00052   IndexedStringRepositoryItemRequest(const char* text, unsigned int hash, unsigned short length) : m_hash(hash), m_length(length), m_text(text) {
00053   }
00054   
00055   enum {
00056     AverageSize = 10 //This should be the approximate average size of an Item
00057   };
00058 
00059   typedef unsigned int HashType;
00060   
00061   //Should return the hash-value associated with this request(For example the hash of a string)
00062   HashType hash() const {
00063     return m_hash;
00064   }
00065   
00066   //Should return the size of an item created with createItem
00067   size_t itemSize() const {
00068     return sizeof(IndexedStringData) + m_length;
00069   }
00070   //Should create an item where the information of the requested item is permanently stored. The pointer
00071   //@param item equals an allocated range with the size of itemSize().
00072   void createItem(IndexedStringData* item) const {
00073     item->length = m_length;
00074     item->refCount = 0;
00075     ++item;
00076     memcpy(item, m_text, m_length);
00077   }
00078   
00079   static void destroy(IndexedStringData* item, KDevelop::AbstractItemRepository&) {
00080     Q_UNUSED(item);
00081     //Nothing to do here (The object is not intelligent)
00082   }
00083 
00084   static bool persistent(const IndexedStringData* item) {
00085     return (bool)item->refCount;
00086   }
00087   
00088   //Should return whether the here requested item equals the given item
00089   bool equals(const IndexedStringData* item) const {
00090     return item->length == m_length && (memcmp(++item, m_text, m_length) == 0);
00091   }
00092   unsigned int m_hash;
00093   unsigned short m_length;
00094   const char* m_text;
00095 };
00096 
00097 typedef ItemRepository<IndexedStringData, IndexedStringRepositoryItemRequest, false, true> IndexedStringRepository;
00098 
00100 inline QString stringFromItem(const IndexedStringData* item) {
00101   const unsigned short* textPos = (unsigned short*)(item+1);
00102   return QString::fromUtf8((char*)textPos, item->length);
00103 }
00104 
00105 inline QByteArray arrayFromItem(const IndexedStringData* item) {
00106   const unsigned short* textPos = (unsigned short*)(item+1);
00107   return QByteArray((char*)textPos, item->length);
00108 }  
00109 }
00110 
00111 namespace {
00112   RepositoryManager< IndexedStringRepository >& getGlobalIndexedStringRepository(){
00113     static RepositoryManager< IndexedStringRepository > globalIndexedStringRepository("String Index");
00114     return globalIndexedStringRepository;
00115   }
00116 }
00117 
00118 IndexedString::IndexedString() : m_index(0) {
00119 }
00120 
00123 IndexedString::IndexedString( const char* str, unsigned short length, unsigned int hash ) {
00124   if(!length)
00125     m_index = 0;
00126   else if(length == 1)
00127     m_index = 0xffff0000 | str[0];
00128   else {
00129     QMutexLocker lock(getGlobalIndexedStringRepository()->mutex());
00130     
00131     m_index = getGlobalIndexedStringRepository()->index(IndexedStringRepositoryItemRequest(str, hash ? hash : hashString(str, length), length));
00132     
00133     if(shouldDoDUChainReferenceCounting(this))
00134       increase(getGlobalIndexedStringRepository()->dynamicItemFromIndexSimple(m_index)->refCount);
00135   }
00136 }
00137 
00138 IndexedString::IndexedString( char c ) {
00139   m_index = 0xffff0000 | c;
00140 }
00141 
00142 IndexedString::IndexedString( const KUrl& url ) {
00143   QByteArray array(url.pathOrUrl().toUtf8());
00144 
00145   const char* str = array.constData();
00146 
00147   int size = array.size();
00148 
00149   if(!size)
00150     m_index = 0;
00151   else if(size == 1)
00152     m_index = 0xffff0000 | str[0];
00153   else {
00154     QMutexLocker lock(getGlobalIndexedStringRepository()->mutex());
00155     m_index = getGlobalIndexedStringRepository()->index(IndexedStringRepositoryItemRequest(str, hashString(str, size), size));
00156     
00157     if(shouldDoDUChainReferenceCounting(this))
00158       increase(getGlobalIndexedStringRepository()->dynamicItemFromIndexSimple(m_index)->refCount);
00159   }
00160 }
00161 
00162 IndexedString::IndexedString( const QString& string ) {
00163   QByteArray array(string.toUtf8());
00164 
00165   const char* str = array.constData();
00166 
00167   int size = array.size();
00168 
00169   if(!size)
00170     m_index = 0;
00171   else if(size == 1)
00172     m_index = 0xffff0000 | str[0];
00173   else {
00174     QMutexLocker lock(getGlobalIndexedStringRepository()->mutex());
00175     m_index = getGlobalIndexedStringRepository()->index(IndexedStringRepositoryItemRequest(str, hashString(str, size), size));
00176 
00177     if(shouldDoDUChainReferenceCounting(this))
00178       increase(getGlobalIndexedStringRepository()->dynamicItemFromIndexSimple(m_index)->refCount);
00179   }
00180 }
00181 
00182 IndexedString::IndexedString( const char* str) {
00183   unsigned int length = strlen(str);
00184   if(!length)
00185     m_index = 0;
00186   else if(length == 1)
00187     m_index = 0xffff0000 | str[0];
00188   else {
00189     QMutexLocker lock(getGlobalIndexedStringRepository()->mutex());
00190     m_index = getGlobalIndexedStringRepository()->index(IndexedStringRepositoryItemRequest(str, hashString(str, length), length));
00191     
00192     if(shouldDoDUChainReferenceCounting(this))
00193       increase(getGlobalIndexedStringRepository()->dynamicItemFromIndexSimple(m_index)->refCount);
00194   }
00195 }
00196 
00197 IndexedString::IndexedString( const QByteArray& str) {
00198   unsigned int length = str.length();
00199   if(!length)
00200     m_index = 0;
00201   else if(length == 1)
00202     m_index = 0xffff0000 | str[0];
00203   else {
00204     QMutexLocker lock(getGlobalIndexedStringRepository()->mutex());
00205     m_index = getGlobalIndexedStringRepository()->index(IndexedStringRepositoryItemRequest(str, hashString(str, length), length));
00206     
00207     if(shouldDoDUChainReferenceCounting(this))
00208       increase(getGlobalIndexedStringRepository()->dynamicItemFromIndexSimple(m_index)->refCount);
00209   }
00210 }
00211 
00212 IndexedString::~IndexedString() {
00213   if(m_index && (m_index & 0xffff0000) != 0xffff0000) {
00214     if(shouldDoDUChainReferenceCounting(this)) {
00215       QMutexLocker lock(getGlobalIndexedStringRepository()->mutex());
00216     
00217       decrease(getGlobalIndexedStringRepository()->dynamicItemFromIndexSimple(m_index)->refCount);
00218     }
00219   }
00220 }
00221 
00222 IndexedString::IndexedString( const IndexedString& rhs ) : m_index(rhs.m_index) {
00223   if(m_index && (m_index & 0xffff0000) != 0xffff0000) {
00224     if(shouldDoDUChainReferenceCounting(this)) {
00225       QMutexLocker lock(getGlobalIndexedStringRepository()->mutex());
00226       increase(getGlobalIndexedStringRepository()->dynamicItemFromIndexSimple(m_index)->refCount);
00227     }
00228   }
00229 }
00230 
00231 IndexedString& IndexedString::operator=(const IndexedString& rhs) {
00232   if(m_index == rhs.m_index)
00233     return *this;
00234   if(m_index && (m_index & 0xffff0000) != 0xffff0000) {
00235     
00236     if(shouldDoDUChainReferenceCounting(this)) {
00237       QMutexLocker lock(getGlobalIndexedStringRepository()->mutex());
00238       decrease(getGlobalIndexedStringRepository()->dynamicItemFromIndexSimple(m_index)->refCount);
00239     }
00240   }
00241   
00242   m_index = rhs.m_index;
00243   
00244   if(m_index && (m_index & 0xffff0000) != 0xffff0000) {
00245     if(shouldDoDUChainReferenceCounting(this)) {
00246       QMutexLocker lock(getGlobalIndexedStringRepository()->mutex());
00247       increase(getGlobalIndexedStringRepository()->dynamicItemFromIndexSimple(m_index)->refCount);
00248     }
00249   }
00250   
00251   return *this;
00252 }
00253 
00254 
00255 KUrl IndexedString::toUrl() const {
00256   KUrl url( str() );
00257   return url;
00258 }
00259 
00260 QString IndexedString::str() const {
00261   if(!m_index)
00262     return QString();
00263   else if((m_index & 0xffff0000) == 0xffff0000)
00264     return QString(QChar((char)m_index & 0xff));
00265   else
00266     return stringFromItem(getGlobalIndexedStringRepository()->itemFromIndex(m_index));
00267 }
00268 
00269 int IndexedString::length() const {
00270   if(!m_index)
00271     return 0;
00272   else if((m_index & 0xffff0000) == 0xffff0000)
00273     return 1;
00274   else
00275     return getGlobalIndexedStringRepository()->itemFromIndex(m_index)->length;
00276 }
00277 
00278 QByteArray IndexedString::byteArray() const {
00279   if(!m_index)
00280     return QByteArray();
00281   else if((m_index & 0xffff0000) == 0xffff0000)
00282     return QString(QChar((char)m_index & 0xff)).toUtf8();
00283   else
00284     return arrayFromItem(getGlobalIndexedStringRepository()->itemFromIndex(m_index));
00285 }
00286 
00287 unsigned int IndexedString::hashString(const char* str, unsigned short length) {
00288   RunningHash running;
00289   for(int a = length-1; a >= 0; --a) {
00290     running.append(*str);
00291     ++str;
00292   }
00293   return running.hash;
00294 }
00295 
00296 
00297 }

language/duchain

Skip menu "language/duchain"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

KDevelop Platform Libraries

Skip menu "KDevelop Platform Libraries"
  • interfaces
  • language
  •   codegen
  •   duchain
  •   editor
  • outputview
  • project
  • shell
  • sublime
  • util
  • vcs
Generated for KDevelop Platform Libraries by doxygen 1.5.9-20090814
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal