• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdepim
  • Sitemap
  • Contact Us
 

knode

knarticlecollection.cpp

Go to the documentation of this file.
00001 /*
00002     KNode, the KDE newsreader
00003     Copyright (c) 1999-2005 the KNode authors.
00004     See file AUTHORS for details
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010     You should have received a copy of the GNU General Public License
00011     along with this program; if not, write to the Free Software Foundation,
00012     Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, US
00013 */
00014 
00015 #include <stdlib.h>
00016 
00017 #include <klocale.h>
00018 #include <kmessagebox.h>
00019 #include <kdebug.h>
00020 
00021 #include "knglobals.h"
00022 #include "knarticlecollection.h"
00023 #include "knarticle.h"
00024 
00025 #include <QByteArray>
00026 
00027 static const int sizeIncr=50;
00028 
00029 KNArticleVector::KNArticleVector(KNArticleVector *master, SortingType sorting)
00030   : m_aster(master), l_en(0), s_ize(0), l_ist(0), s_ortType(sorting)
00031 {
00032 }
00033 
00034 
00035 KNArticleVector::~KNArticleVector()
00036 {
00037   clear();
00038 }
00039 
00040 
00041 bool KNArticleVector::resize(int s)
00042 {
00043   KNArticle **bak=l_ist;
00044   int nSize;
00045 
00046   if(s==0)
00047     nSize=s_ize+sizeIncr;
00048   else
00049     nSize=((s/sizeIncr)+1)*sizeIncr;
00050 
00051   l_ist=(KNArticle**) realloc(l_ist, sizeof(KNArticle*)*nSize);
00052 
00053   if(!l_ist) {
00054     KMessageBox::error(knGlobals.topWidget, i18n("Memory allocation failed.\nYou should close this application now\nto avoid data loss."));
00055     l_ist=bak;
00056     return false;
00057   }
00058   else {
00059     s_ize=nSize;
00060     //kDebug(5003) <<"size :" << siz;
00061     return true;
00062   }
00063 
00064 }
00065 
00066 
00067 bool KNArticleVector::append(KNArticle *a, bool autoSort)
00068 {
00069   if( (l_en+1 > s_ize) && !resize()) // array too small => try to realloc
00070     return false; // allocation failed !!
00071 
00072   l_ist[l_en++]=a;
00073 
00074   if(autoSort) sort();
00075   return true;
00076 }
00077 
00078 
00079 void KNArticleVector::remove(int pos, bool autoDel, bool autoCompact)
00080 {
00081 
00082   if(pos < 0 || pos > l_en-1)
00083     return;
00084 
00085   if(autoDel)
00086     delete l_ist[pos];
00087 
00088   l_ist[pos]=0;
00089 
00090   if(autoCompact)
00091     compact();
00092 }
00093 
00094 
00095 void KNArticleVector::clear()
00096 {
00097   if(l_ist){
00098     if(m_aster==0)
00099       for(int i=0; i<l_en; i++) delete l_ist[i];
00100     free(l_ist);
00101   }
00102 
00103   l_ist=0; l_en=0; s_ize=0;
00104 }
00105 
00106 
00107 void KNArticleVector::compact()
00108 {
00109   int newLen, nullStart=0, nullCnt=0, ptrStart=0, ptrCnt=0;
00110 
00111   for(int idx=0; idx<l_en; idx++) {
00112     if(l_ist[idx]==0) {
00113       ptrStart=-1;
00114       ptrCnt=-1;
00115       nullStart=idx;
00116       nullCnt=1;
00117       for(int idx2=idx+1; idx2<l_en; idx2++) {
00118         if(l_ist[idx2]==0) nullCnt++;
00119         else {
00120           ptrStart=idx2;
00121           ptrCnt=1;
00122           break;
00123         }
00124       }
00125       if(ptrStart!=-1) {
00126         for(int idx2=ptrStart+1; idx2<l_en; idx2++) {
00127           if(l_ist[idx2]!=0) ptrCnt++;
00128           else break;
00129         }
00130         memmove(&(l_ist[nullStart]), &(l_ist[ptrStart]), ptrCnt*sizeof(KNArticle*));
00131         for(int idx2=nullStart+ptrCnt; idx2<nullStart+ptrCnt+nullCnt; idx2++)
00132           l_ist[idx2]=0;
00133         idx=nullStart+ptrCnt-1;
00134         }
00135       else break;
00136     }
00137   }
00138   newLen=0;
00139   while(l_ist[newLen]!=0) newLen++;
00140   l_en=newLen;
00141 }
00142 
00143 
00144 void KNArticleVector::syncWithMaster()
00145 {
00146   if(!m_aster) return;
00147 
00148   if(resize(m_aster->l_en)) {
00149     memcpy(l_ist, m_aster->l_ist, (m_aster->l_en) * sizeof(KNArticle*));
00150     l_en=m_aster->l_en;
00151     sort();
00152   }
00153 }
00154 
00155 
00156 void KNArticleVector::sort()
00157 {
00158   int (*cmp)(const void*,const void*) = 0;
00159 
00160   switch(s_ortType) {
00161     case STid:
00162       cmp=compareById;
00163     break;
00164     case STmsgId:
00165       cmp=compareByMsgId;
00166     break;
00167     default:
00168       cmp=0;
00169     break;
00170   }
00171 
00172   if(cmp) {
00173     //compact(); // remove null-pointers
00174     qsort(l_ist, l_en, sizeof(KNArticle*), cmp);
00175   }
00176 }
00177 
00178 
00179 int KNArticleVector::compareById(const void *p1, const void *p2)
00180 {
00181   KNArticle *a1, *a2;
00182   int rc=0, id1, id2;
00183 
00184   a1=*((KNArticle**)(p1));
00185   a2=*((KNArticle**)(p2));
00186 
00187   id1=a1->id(),
00188   id2=a2->id();
00189 
00190   if( id1 < id2 ) rc=-1;
00191   else if( id1 > id2 ) rc=1;
00192 
00193   return rc;
00194 }
00195 
00196 
00197 int KNArticleVector::compareByMsgId(const void *p1, const void *p2)
00198 {
00199   KNArticle *a1, *a2;
00200   QByteArray mid1, mid2;
00201 
00202   a1=*(KNArticle**)(p1);
00203   a2=*(KNArticle**)(p2);
00204 
00205   mid1=a1->messageID(true)->as7BitString(false);
00206   mid2=a2->messageID(true)->as7BitString(false);
00207 
00208   if(mid1.isNull()) mid1="";
00209   if(mid2.isNull()) mid2="";
00210 
00211   return strcmp( mid1.data(), mid2.data() );
00212 }
00213 
00214 
00215 KNArticle* KNArticleVector::bsearch(int id)
00216 {
00217   int idx=indexForId(id);
00218 
00219   return ( idx>-1 ? l_ist[idx] : 0 );
00220 }
00221 
00222 
00223 KNArticle* KNArticleVector::bsearch( const QByteArray &id )
00224 {
00225   int idx=indexForMsgId(id);
00226 
00227   return ( idx>-1 ? l_ist[idx] : 0 );
00228 }
00229 
00230 
00231 int KNArticleVector::indexForId(int id)
00232 {
00233   if(s_ortType!=STid) return -1;
00234 
00235   int start=0, end=l_en, mid=0, currentId=0;
00236   bool found=false;
00237   KNArticle *current=0;
00238 
00239   while(start!=end && !found) {
00240     mid=(start+end)/2;
00241     current=l_ist[mid];
00242     currentId=current->id();
00243 
00244     if(currentId==id)
00245       found=true;
00246     else if(currentId < id)
00247       start=mid+1;
00248     else
00249       end=mid;
00250   }
00251 
00252   if(found)
00253     return mid;
00254   else {
00255     kDebug(5003) << "id" << id << "not found";
00256     return -1;
00257   }
00258 }
00259 
00260 
00261 int KNArticleVector::indexForMsgId( const QByteArray &id )
00262 {
00263   if(s_ortType!=STmsgId) return -1;
00264 
00265   int start=0, end=l_en, mid=0;
00266   QByteArray currentMid;
00267   bool found=false;
00268   KNArticle *current=0;
00269   int cnt=0;
00270 
00271   while(start!=end && !found) {
00272     mid=(start+end)/2;
00273     current=l_ist[mid];
00274     currentMid=current->messageID(true)->as7BitString(false);
00275 
00276     if(currentMid==id)
00277       found=true;
00278     else if( currentMid < id )
00279       start=mid+1;
00280     else
00281       end=mid;
00282 
00283     cnt++;
00284   }
00285 
00286   if(found) {
00287     /*#ifndef NDEBUG
00288     qDebug("KNArticleVector::indexForMsgID() : msgID=%s found after %d compares", id.data(), cnt);
00289     #endif*/
00290     return mid;
00291   }
00292   else {
00293     /*#ifndef NDEBUG
00294     qDebug("knode: KNArticleVector::indexForMsgID() : msgID=%s not found", id.data());
00295     #endif*/
00296     return -1;
00297   }
00298 }
00299 
00300 
00301 
00302 
00303 // -------------------------------------------------------------------------------------------
00304 
00305 
00306 
00307 KNArticleCollection::KNArticleCollection(KNCollection *p)
00308   : KNCollection(p), l_astID(0), l_ockedArticles(0), n_otUnloadable(false)
00309 {
00310   a_rticles.setSortMode(KNArticleVector::STid);
00311   m_idIndex.setSortMode(KNArticleVector::STmsgId);
00312   m_idIndex.setMaster(&a_rticles);
00313 }
00314 
00315 
00316 
00317 KNArticleCollection::~KNArticleCollection()
00318 {
00319   clear();
00320 }
00321 
00322 
00323 
00324 bool KNArticleCollection::resize(int s)
00325 {
00326   return a_rticles.resize(s);
00327 }
00328 
00329 
00330 
00331 bool KNArticleCollection::append(KNArticle *a, bool autoSync)
00332 {
00333   if(a_rticles.append(a, false)) {
00334     if(a->id()==-1)
00335       a->setId(++l_astID);
00336     if(autoSync)
00337       syncSearchIndex();
00338     return true;
00339   }
00340   return false;
00341 
00342 }
00343 
00344 
00345 
00346 void KNArticleCollection::clear()
00347 {
00348   a_rticles.clear();
00349   m_idIndex.clear();
00350   l_astID=0;
00351 }
00352 
00353 
00354 
00355 void KNArticleCollection::compact()
00356 {
00357   a_rticles.compact();
00358   m_idIndex.clear();
00359 }
00360 
00361 
00362 KNArticle* KNArticleCollection::byId(int id)
00363 {
00364   return a_rticles.bsearch(id);
00365 }
00366 
00367 
00368 KNArticle* KNArticleCollection::byMessageId( const QByteArray &mid )
00369 {
00370   if(m_idIndex.isEmpty()) {
00371     m_idIndex.syncWithMaster();
00372     kDebug(5003) <<"KNArticleCollection::byMessageId() : created index";
00373   }
00374   return m_idIndex.bsearch(mid);
00375 }
00376 
00377 
00378 void KNArticleCollection::setLastID()
00379 {
00380   if(a_rticles.length()>0)
00381     l_astID=a_rticles.at(a_rticles.length()-1)->id();
00382   else
00383     l_astID=0;
00384 }
00385 
00386 
00387 void KNArticleCollection::syncSearchIndex()
00388 {
00389   m_idIndex.syncWithMaster();
00390 
00391   /*for(int i=0; i<m_idIndex.length(); i++) {
00392     kDebug(5003) << m_idIndex.at(i)->id() <<" ," << m_idIndex.at(i)->messageID()->as7BitString(false);
00393   } */
00394 }
00395 
00396 
00397 void KNArticleCollection::clearSearchIndex()
00398 {
00399   m_idIndex.clear();
00400 }

knode

Skip menu "knode"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

kdepim

Skip menu "kdepim"
  • akonadi
  •   clients
  •   kabc
  •   kcal
  •   kcm
  • akregator
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt
  • kdgantt1
  • kjots
  • kleopatra
  • kmail
  • kmobiletools
  • knode
  • knotes
  • kontact
  • kontactinterfaces
  • korganizer
  •   korgac
  • kpilot
  • ktimetracker
  •   doc
  • libkdepim
  • libkholidays
  • libkleo
  • libkpgp
  • maildir
Generated for kdepim by doxygen 1.5.4
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