//----------------------------------------------------------------------------- KMMessage* KMFolder::readMsg(int idx) { KMMessage* msg; unsigned long msgSize; QString msgText; KMMsgInfo* mi = (KMMsgInfo*)mMsgList[idx]; assert(mi!=NULL && !mi->isMessage()); assert(mStream != NULL); msgSize = mi->msgSize(); msgText.resize(msgSize+2); fseek(mStream, mi->folderOffset(), SEEK_SET); fread(msgText.data(), msgSize, 1, mStream); msgText[msgSize] = '\0'; msg = new KMMessage(*mi); msg->fromString(msgText); mMsgList.set(idx,msg); return msg; }
//----------------------------------------------------------------------------- void KMFolder::readIndex(void) { char line[MAX_LINE]; KMMsgInfo* mi; assert(mIndexStream != NULL); rewind(mIndexStream); mMsgList.clear(); if (!readIndexHeader()) return; mDirty = FALSE; mHeaderOffset = ftell(mIndexStream); mMsgList.clear(); while (!feof(mIndexStream)) { fgets(line, MAX_LINE, mIndexStream); if (feof(mIndexStream)) break; mi = new KMMsgInfo(this); mi->fromIndexString(line); if (mi->status() == KMMsgStatusDeleted) { delete mi; // skip messages that are marked as deleted mDirty = TRUE; needsCompact = true; //We have deleted messages - needs to be compacted continue; } #ifdef OBSOLETE else if (mi->status() == KMMsgStatusNew) { mi->setStatus(KMMsgStatusUnread); mi->setDirty(FALSE); } #endif mMsgList.append(mi); } }
//----------------------------------------------------------------------------- int KMFolder::createIndexFromContents(void) { char line[MAX_LINE]; char status[8], xstatus[8]; QString subjStr, dateStr, fromStr, toStr, xmarkStr, *lastStr=NULL; QString whoFieldName; unsigned long offs, size, pos; bool atEof = FALSE; bool inHeader = TRUE; KMMsgInfo* mi; QString msgStr(256); QRegExp regexp(MSG_SEPERATOR_REGEX); int i, num, numStatus, whoFieldLen; short needStatus; assert(mStream != NULL); rewind(mStream); mMsgList.clear(); num = -1; numStatus= 11; offs = 0; size = 0; dateStr = ""; fromStr = ""; toStr = ""; subjStr = ""; *status = '\0'; *xstatus = '\0'; xmarkStr = ""; needStatus = 3; whoFieldName = QString(whoField()) + ':'; //unused (sven) whoFieldLen = whoFieldName.length(); //unused (sven) //debug("***whoField: %s (%d)", // (const char*)whoFieldName, whoFieldLen); while (!atEof) { pos = ftell(mStream); if (!fgets(line, MAX_LINE, mStream)) atEof = TRUE; if (atEof || (strncmp(line,MSG_SEPERATOR_START, msgSepLen)==0 && regexp.match(line) >= 0)) { size = pos - offs; pos = ftell(mStream); if (num >= 0) { if (numStatus <= 0) { msgStr.sprintf(i18n("Creating index file: %d messages done"), num); emit statusMsg(msgStr); numStatus = 10; } if (size > 0) { mi = new KMMsgInfo(this); mi->init(subjStr, fromStr, toStr, 0, KMMsgStatusNew, xmarkStr, offs, size); mi->setStatus(status,xstatus); mi->setDate(dateStr); mi->setDirty(FALSE); mMsgList.append(mi); *status = '\0'; *xstatus = '\0'; needStatus = 3; xmarkStr = ""; dateStr = ""; fromStr = ""; subjStr = ""; } else num--,numStatus++; } offs = ftell(mStream); num++; numStatus--; inHeader = TRUE; continue; } // Is this a long header line? if (inHeader && (line[0]=='\t' || line[0]==' ')) { i = 0; while (line [i]=='\t' || line [i]==' ') i++; if (line [i] < ' ' && line [i]>0) inHeader = FALSE; else if (lastStr) *lastStr += line + i; } else lastStr = NULL; if (inHeader && (line [0]=='\n' || line [0]=='\r')) inHeader = FALSE; if (!inHeader) continue; if ((needStatus & 1) && strncasecmp(line, "Status:", 7) == 0 && isblank(line[7])) { for(i=0; i<4 && line[i+8] > ' '; i++) status[i] = line[i+8]; status[i] = '\0'; needStatus &= ~1; } else if ((needStatus & 2) && strncasecmp(line, "X-Status:", 9)==0 && isblank(line[9])) { for(i=0; i<4 && line[i+10] > ' '; i++) xstatus[i] = line[i+10]; xstatus[i] = '\0'; needStatus &= ~2; } else if (strncasecmp(line,"X-KMail-Mark:",13)==0 && isblank(line[13])) xmarkStr = QString(line+14).copy(); else if (strncasecmp(line,"Date:",5)==0 && isblank(line[5])) { dateStr = QString(line+6).copy(); lastStr = &dateStr; } else if (strncasecmp(line,"From:", 5)==0 && isblank(line[5])) { fromStr = QString(line+6).copy(); lastStr = &fromStr; } else if (strncasecmp(line,"To:", 3)==0 && isblank(line[3])) { toStr = QString(line+4).copy(); lastStr = &toStr; } else if (strncasecmp(line,"Subject:",8)==0 && isblank(line[8])) { subjStr = QString(line+9).copy(); lastStr = &subjStr; } } if (mAutoCreateIndex) { emit statusMsg(i18n("Writing index file")); writeIndex(); } else mHeaderOffset = 0; return 0; }
bool KMFolderIndex::readIndex() { qint32 len; KMMsgInfo* mi; assert(mIndexStream != 0); rewind(mIndexStream); clearIndex(); int version; setDirty( false ); if (!readIndexHeader(&version)) return false; mUnreadMsgs = 0; mTotalMsgs = 0; mHeaderOffset = KDE_ftell(mIndexStream); clearIndex(); while (!feof(mIndexStream)) { mi = 0; if(version >= 1505) { if(!fread(&len, sizeof(len), 1, mIndexStream)) break; if (mIndexSwapByteOrder) len = kmail_swap_32(len); off_t offs = KDE_ftell(mIndexStream); if(KDE_fseek(mIndexStream, len, SEEK_CUR)) break; mi = new KMMsgInfo(folder(), offs, len); } else { QByteArray line( MAX_LINE, '\0' ); fgets(line.data(), MAX_LINE, mIndexStream); if (feof(mIndexStream)) break; if (*line.data() == '\0') { fclose(mIndexStream); //kDebug( KMKernel::storageDebug() ) << "fclose(mIndexStream = " << mIndexStream << ")"; mIndexStream = 0; clearIndex(); return false; } mi = new KMMsgInfo(folder()); mi->compat_fromOldIndexString(line, mConvertToUtf8); } if(!mi) break; if (mi->status().isDeleted()) { delete mi; // skip messages that are marked as deleted setDirty( true ); needsCompact = true; //We have deleted messages - needs to be compacted continue; } #ifdef OBSOLETE else if (mi->isNew()) { mi->setStatus(KMMsgStatusUnread); mi->setDirty(false); } #endif if ((mi->status().isNew()) || (mi->status().isUnread()) || (folder() == kmkernel->outboxFolder())) { ++mUnreadMsgs; if (mUnreadMsgs == 0) ++mUnreadMsgs; } mMsgList.append(mi, false); } if( version < 1505) { mConvertToUtf8 = false; setDirty( true ); writeIndex(); } mTotalMsgs = mMsgList.count(); return true; }