зеркало из https://github.com/mozilla/pjs.git
move files over from src into linkable library
This commit is contained in:
Родитель
d47bfaa85a
Коммит
0def79c983
|
@ -0,0 +1 @@
|
|||
Makefile
|
|
@ -0,0 +1,60 @@
|
|||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
srcdir = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE=msgbaseutil
|
||||
LIBRARY_NAME=msgbaseutil
|
||||
|
||||
EXPORTS = \
|
||||
nsMsgGroupRecord.h \
|
||||
nsMsgLineBuffer.h \
|
||||
nsUInt32Array.h \
|
||||
nsNewsSet.h \
|
||||
nsMsgFolder.h \
|
||||
nsLocalFolderSummarySpec.h \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
nsMsgGroupRecord.cpp \
|
||||
nsMsgLineBuffer.cpp \
|
||||
nsMsgFolder.cpp \
|
||||
nsUInt32Array.cpp \
|
||||
nsNewsSet.cpp \
|
||||
nsLocalFolderSummarySpec.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(NSPR_LIBS) \
|
||||
-L$(DIST)/bin \
|
||||
-L$(DIST)/lib \
|
||||
-lraptorbase \
|
||||
-lxp \
|
||||
-lxpcom \
|
||||
-lrdfutil_s \
|
||||
$(NULL)
|
||||
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH=..\..\..
|
||||
IGNORE_MANIFEST=1
|
||||
|
||||
include <$(DEPTH)\config\config.mak>
|
||||
|
||||
LIBRARY_NAME=msgcoreutil
|
||||
MODULE= mailnewsutil
|
||||
REQUIRES=xpcom js nspr dom
|
||||
|
||||
DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN
|
||||
|
||||
CPPSRCS= \
|
||||
nsMsgGroupRecord.cpp \
|
||||
nsMsgLineBuffer.cpp \
|
||||
nsUInt32Array.cpp \
|
||||
nsNewsSet.cpp \
|
||||
nsMsgFolder.cpp \
|
||||
nsLocalFolderSummarySpec.cpp \
|
||||
$(NULL)
|
||||
|
||||
|
||||
|
||||
CPP_OBJS= \
|
||||
.\$(OBJDIR)\nsMsgGroupRecord.obj \
|
||||
.\$(OBJDIR)\nsMsgLineBuffer.obj \
|
||||
.\$(OBJDIR)\nsNewsSet.obj \
|
||||
.\$(OBJDIR)\nsMsgFolder.obj \
|
||||
.\$(OBJDIR)\nsLocalFolderSummarySpec.obj \
|
||||
$(NULL)
|
||||
|
||||
|
||||
EXPORTS= \
|
||||
nsMsgLineBuffer.h \
|
||||
nsMsgGroupRecord.h \
|
||||
nsNewsSet.h \
|
||||
nsMsgFolder.h \
|
||||
nsLocalFolderSummarySpec.h \
|
||||
$(NULL)
|
||||
|
||||
LINCS= \
|
||||
-I$(PUBLIC)\xpcom \
|
||||
-I$(PUBLIC)\mailnews \
|
||||
-I$(PUBLIC)\raptor \
|
||||
-I$(PUBLIC)\rdf \
|
||||
-I$(PUBLIC)\rdfutil \
|
||||
-I$(PUBLIC)\pref \
|
||||
-I$(PUBLIC)\js \
|
||||
-I$(PUBLIC)\netlib \
|
||||
-I$(PUBLIC)\dom \
|
||||
-I$(PUBLIC)\appcores \
|
||||
-I$(PUBLIC)\security \
|
||||
$(NULL)
|
||||
|
||||
LCFLAGS = \
|
||||
$(LCFLAGS) \
|
||||
$(DEFINES) \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
libs:: $(LIBRARY)
|
||||
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
|
||||
|
||||
clobber::
|
||||
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib
|
|
@ -0,0 +1,63 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsLocalFolderSummarySpec.h"
|
||||
#include "nsString.h"
|
||||
|
||||
nsLocalFolderSummarySpec::nsLocalFolderSummarySpec()
|
||||
{
|
||||
}
|
||||
|
||||
nsLocalFolderSummarySpec::nsLocalFolderSummarySpec(const char *folderPath)
|
||||
: nsFileSpec(folderPath)
|
||||
{
|
||||
CreateSummaryFileName();
|
||||
}
|
||||
|
||||
nsLocalFolderSummarySpec::nsLocalFolderSummarySpec(const nsFileSpec& inFolderPath)
|
||||
: nsFileSpec(inFolderPath)
|
||||
{
|
||||
CreateSummaryFileName();
|
||||
}
|
||||
|
||||
nsLocalFolderSummarySpec::nsLocalFolderSummarySpec(const nsFilePath &inFolderPath) : nsFileSpec(inFolderPath)
|
||||
{
|
||||
CreateSummaryFileName();
|
||||
}
|
||||
|
||||
void nsLocalFolderSummarySpec::SetFolderName(const char *folderPath)
|
||||
{
|
||||
*this = folderPath;
|
||||
}
|
||||
|
||||
void nsLocalFolderSummarySpec:: CreateSummaryFileName()
|
||||
{
|
||||
char *leafName = GetLeafName();
|
||||
|
||||
nsString fullLeafName(leafName);
|
||||
|
||||
// Append .msf (msg summary file) this is what windows will want.
|
||||
// Mac and Unix can decide for themselves.
|
||||
|
||||
fullLeafName += ".msf"; // message summary file
|
||||
char *cLeafName = fullLeafName.ToNewCString();
|
||||
SetLeafName(cLeafName);
|
||||
delete [] cLeafName; // ###use nsCString when it's available!@
|
||||
delete [] leafName;
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _nsLocalFolderSummarySpec_H
|
||||
#define _nsLocalFolderSummarySpec_H
|
||||
|
||||
#include "nsFileSpec.h"
|
||||
|
||||
// Class to name a summary file for a local mail folder,
|
||||
// given a full folder file spec. For windows, this just means tacking .msf on the end.
|
||||
// For Unix, it might mean something like putting a '.' on the front and .msgsummary on the end.
|
||||
// Note this class expects the invoking code to fully specify the folder path.
|
||||
// This class does NOT prepend the local folder directory, or put .sbd on the containing
|
||||
// directory names.
|
||||
class nsLocalFolderSummarySpec : public nsFileSpec
|
||||
{
|
||||
public:
|
||||
nsLocalFolderSummarySpec();
|
||||
nsLocalFolderSummarySpec(const char *folderPath);
|
||||
nsLocalFolderSummarySpec(const nsFileSpec& inFolderPath);
|
||||
nsLocalFolderSummarySpec(const nsFilePath &inFolderPath);
|
||||
void SetFolderName(const char *folderPath);
|
||||
|
||||
protected:
|
||||
void CreateSummaryFileName();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,315 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/********************************************************************************************************
|
||||
|
||||
Interface for representing Messenger folders.
|
||||
|
||||
*********************************************************************************************************/
|
||||
|
||||
#ifndef nsMsgFolder_h__
|
||||
#define nsMsgFolder_h__
|
||||
|
||||
#include "msgCore.h"
|
||||
#include "nsIMsgFolder.h" /* include the interface we are going to support */
|
||||
#include "nsRDFResource.h"
|
||||
#include "nsIRDFResourceFactory.h"
|
||||
#include "nsDBFolderInfo.h"
|
||||
#include "nsMsgDatabase.h"
|
||||
|
||||
/*
|
||||
* MsgFolder
|
||||
*/
|
||||
|
||||
class nsMsgFolder: public nsRDFResource, public nsIMsgFolder
|
||||
{
|
||||
public:
|
||||
nsMsgFolder(void);
|
||||
virtual ~nsMsgFolder(void);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsICollection methods:
|
||||
NS_IMETHOD_(PRUint32) Count(void) const;
|
||||
NS_IMETHOD AppendElement(nsISupports *aElement);
|
||||
NS_IMETHOD RemoveElement(nsISupports *aElement);
|
||||
NS_IMETHOD Enumerate(nsIEnumerator* *result);
|
||||
NS_IMETHOD Clear(void);
|
||||
|
||||
// nsIFolder methods:
|
||||
NS_IMETHOD GetURI(char* *name) { return nsRDFResource::GetValue((const char**)&name); }
|
||||
NS_IMETHOD GetName(char **name);
|
||||
NS_IMETHOD SetName(char *name);
|
||||
NS_IMETHOD GetChildNamed(const char *name, nsISupports* *result);
|
||||
NS_IMETHOD GetParent(nsIFolder* *parent);
|
||||
NS_IMETHOD GetSubFolders(nsIEnumerator* *result);
|
||||
NS_IMETHOD AddFolderListener(nsIFolderListener * listener);
|
||||
NS_IMETHOD RemoveFolderListener(nsIFolderListener * listener);
|
||||
|
||||
|
||||
// nsIMsgFolder methods:
|
||||
NS_IMETHOD AddUnique(nsISupports* element);
|
||||
NS_IMETHOD ReplaceElement(nsISupports* element, nsISupports* newElement);
|
||||
NS_IMETHOD GetVisibleSubFolders(nsIEnumerator* *result);
|
||||
NS_IMETHOD GetMessages(nsIEnumerator* *result);
|
||||
NS_IMETHOD GetPrettyName(char ** name);
|
||||
NS_IMETHOD SetPrettyName(char * name);
|
||||
#if 0
|
||||
static nsresult GetRoot(nsIMsgFolder* *result);
|
||||
#endif
|
||||
// Gets the URL that represents the given message. Returns a newly
|
||||
// created string that must be free'd using XP_FREE().
|
||||
// If the db is NULL, then returns a URL that represents the entire
|
||||
// folder as a whole.
|
||||
#ifdef HAVE_DB
|
||||
NS_IMETHOD BuildUrl(nsMsgDatabase *db, nsMsgKey key, char ** url);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MASTER
|
||||
NS_IMETHOD SetMaster(MSG_Master *master);
|
||||
#endif
|
||||
|
||||
#ifdef DOES_FOLDEROPERATIONS
|
||||
NS_IMETHOD StartAsyncCopyMessagesInto(MSG_FolderInfo *dstFolder,
|
||||
MSG_Pane* sourcePane,
|
||||
nsMsgDatabase *sourceDB,
|
||||
nsMsgKeyArray *srcArray,
|
||||
int32 srcCount,
|
||||
MWContext *currentContext,
|
||||
MSG_UrlQueue *urlQueue,
|
||||
PRBool deleteAfterCopy,
|
||||
nsMsgKey nextKey = nsMsgKey_None);
|
||||
|
||||
|
||||
NS_IMETHOD BeginCopyingMessages(MSG_FolderInfo *dstFolder,
|
||||
nsMsgDatabase *sourceDB,
|
||||
nsMsgKeyArray *srcArray,
|
||||
MSG_UrlQueue *urlQueue,
|
||||
int32 srcCount,
|
||||
MessageCopyInfo *copyInfo);
|
||||
|
||||
|
||||
NS_IMETHOD FinishCopyingMessages(MWContext *context,
|
||||
MSG_FolderInfo * srcFolder,
|
||||
MSG_FolderInfo *dstFolder,
|
||||
nsMsgDatabase *sourceDB,
|
||||
nsMsgKeyArray **ppSrcArray,
|
||||
int32 srcCount,
|
||||
msg_move_state *state);
|
||||
|
||||
|
||||
NS_IMETHOD CleanupCopyMessagesInto(MessageCopyInfo **info);
|
||||
|
||||
NS_IMETHOD SaveMessages(nsMsgKeyArray *, const char *fileName,
|
||||
MSG_Pane *pane, nsMsgDatabase *msgDB,
|
||||
int(*doneCB)(void *, int status) = NULL, void *state = NULL,
|
||||
PRBool addMozillaStatus = TRUE);
|
||||
#endif
|
||||
|
||||
NS_IMETHOD BuildFolderURL(char ** url);
|
||||
|
||||
|
||||
NS_IMETHOD GetPrettiestName(char ** name);
|
||||
|
||||
#ifdef HAVE_ADMINURL
|
||||
NS_IMETHOD GetAdminUrl(MWContext *context, MSG_AdminURLType type);
|
||||
NS_IMETHOD HaveAdminUrl(MSG_AdminURLType type, PRBool *hadAdminUrl);
|
||||
#endif
|
||||
|
||||
NS_IMETHOD GetDeleteIsMoveToTrash(PRBool *aIsDeleteIsMoveToTrash);
|
||||
NS_IMETHOD GetShowDeletedMessages(PRBool *aIsShowDeletedMessages);
|
||||
|
||||
NS_IMETHOD OnCloseFolder();
|
||||
NS_IMETHOD Delete();
|
||||
|
||||
NS_IMETHOD PropagateDelete(nsIMsgFolder **folder, PRBool deleteStorage);
|
||||
NS_IMETHOD RecursiveDelete(PRBool deleteStorage); // called by PropagateDelete
|
||||
|
||||
NS_IMETHOD CreateSubfolder(const char *leafNameFromuser, nsIMsgFolder** outFolder, PRUint32* outPos);
|
||||
|
||||
NS_IMETHOD Rename(const char *name);
|
||||
NS_IMETHOD Adopt(const nsIMsgFolder *srcFolder, PRUint32*);
|
||||
|
||||
NS_IMETHOD ContainsChildNamed(const char *name, PRBool *containsChild);
|
||||
NS_IMETHOD FindParentOf(nsIMsgFolder * aFolder, nsIMsgFolder ** aParent);
|
||||
NS_IMETHOD IsParentOf(nsIMsgFolder *, PRBool deep, PRBool *isParent);
|
||||
|
||||
NS_IMETHOD GenerateUniqueSubfolderName(const char *prefix, nsIMsgFolder *otherFolder,
|
||||
char **name);
|
||||
|
||||
NS_IMETHOD GetDepth(PRUint32 *depth);
|
||||
NS_IMETHOD SetDepth(PRUint32 depth);
|
||||
|
||||
// updates num messages and num unread - should be pure virtual
|
||||
// when I get around to implementing in all subclasses?
|
||||
NS_IMETHOD UpdateSummaryTotals();
|
||||
NS_IMETHOD SummaryChanged();
|
||||
NS_IMETHOD GetNumUnread(PRBool deep, PRUint32 *numUnread); // How many unread messages in this folder.
|
||||
NS_IMETHOD GetTotalMessages(PRBool deep, PRUint32 *totalMessages); // Total number of messages in this folder.
|
||||
|
||||
#ifdef HAVE_DB
|
||||
NS_IMETHOD GetTotalMessagesInDB(PRUint32 *totalMessages) const; // How many messages in database.
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PANE
|
||||
NS_IMETHOD MarkAllRead(MSG_Pane *pane, PRBool deep);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DB
|
||||
// These functions are used for tricking the front end into thinking that we have more
|
||||
// messages than are really in the DB. This is usually after and IMAP message copy where
|
||||
// we don't want to do an expensive select until the user actually opens that folder
|
||||
// These functions are called when MSG_Master::GetFolderLineById is populating a MSG_FolderLine
|
||||
// struct used by the FE
|
||||
int32 GetNumPendingUnread(PRBool deep = FALSE);
|
||||
int32 GetNumPendingTotalMessages(PRBool deep = FALSE);
|
||||
|
||||
void ChangeNumPendingUnread(int32 delta);
|
||||
void ChangeNumPendingTotalMessages(int32 delta);
|
||||
|
||||
|
||||
NS_IMETHOD SetFolderPrefFlags(PRUint32 flags);
|
||||
NS_IMETHOD GetFolderPrefFlags(PRUint32 *flags);
|
||||
NS_IMETHOD SetFolderCSID(PRInt16 csid);
|
||||
NS_IMETHOD GetFolderCSID(PRInt16 *csid);
|
||||
|
||||
|
||||
NS_IMETHOD SetLastMessageLoaded(nsMsgKey lastMessageLoaded);
|
||||
NS_IMETHOD GetLastMessageLoaded();
|
||||
#endif
|
||||
|
||||
NS_IMETHOD SetFlag(PRUint32 which);
|
||||
NS_IMETHOD ClearFlag(PRUint32 which);
|
||||
NS_IMETHOD GetFlag(PRUint32 flag, PRBool *_retval);
|
||||
|
||||
NS_IMETHOD ToggleFlag(PRUint32 which);
|
||||
NS_IMETHOD OnFlagChange(PRUint32 which);
|
||||
NS_IMETHOD GetFlags(PRUint32 *flags);
|
||||
|
||||
#ifdef HAVE_PANE
|
||||
NS_IMETHOD SetFlagInAllFolderPanes(PRUint32 which);
|
||||
#endif
|
||||
|
||||
NS_IMETHOD GetFoldersWithFlag(PRUint32 flags, nsIMsgFolder** result,
|
||||
PRUint32 resultsize, PRUint32 *numFolders);
|
||||
|
||||
NS_IMETHOD GetExpansionArray(nsISupportsArray *expansionArray);
|
||||
|
||||
#ifdef HAVE_NET
|
||||
NS_IMETHOD EscapeMessageId(const char *messageId, const char **escapeMessageID);
|
||||
#endif
|
||||
|
||||
NS_IMETHOD GetExpungedBytesCount(PRUint32 *count);
|
||||
|
||||
NS_IMETHOD GetDeletable(PRBool *deletable);
|
||||
NS_IMETHOD GetCanCreateChildren(PRBool *canCreateChildren);
|
||||
NS_IMETHOD GetCanBeRenamed(PRBool *canBeRenamed);
|
||||
NS_IMETHOD GetRequiresCleanup(PRBool *requiredCleanup);
|
||||
NS_IMETHOD ClearRequiresCleanup() ;
|
||||
#ifdef HAVE_PANE
|
||||
virtual PRBool CanBeInFolderPane();
|
||||
#endif
|
||||
|
||||
NS_IMETHOD GetKnowsSearchNntpExtension(PRBool *knowsExtension);
|
||||
NS_IMETHOD GetAllowsPosting(PRBool *allowsPosting);
|
||||
|
||||
NS_IMETHOD DisplayRecipients(PRBool *displayRecipients);
|
||||
|
||||
NS_IMETHOD ReadDBFolderInfo(PRBool force);
|
||||
|
||||
|
||||
#ifdef HAVE_SEMAPHORE
|
||||
nsresult AcquireSemaphore(void *semHolder);
|
||||
void ReleaseSemaphore(void *semHolder);
|
||||
PRBool TestSemaphore(void *semHolder);
|
||||
PRBool IsLocked() { return m_semaphoreHolder != NULL; }
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PANE
|
||||
MWContext *GetFolderPaneContext();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MASTER
|
||||
MSG_Master *GetMaster() {return m_master;}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CACHE
|
||||
virtual nsresult WriteToCache(XP_File);
|
||||
virtual nsresult ReadFromCache(char *);
|
||||
virtual PRBool IsCachable();
|
||||
void SkipCacheTokens(char **ppBuf, int numTokens);
|
||||
#endif
|
||||
|
||||
NS_IMETHOD GetRelativePathName(char **pathName);
|
||||
|
||||
|
||||
NS_IMETHOD GetSizeOnDisk(PRUint32 *size);
|
||||
|
||||
#ifdef HAVE_NET
|
||||
NS_IMETHOD ShouldPerformOperationOffline(PRBool *performOffline);
|
||||
#endif
|
||||
|
||||
#ifdef DOES_FOLDEROPERATIONS
|
||||
int DownloadToTempFileAndUpload(MessageCopyInfo *copyInfo, nsMsgKeyArray &keysToSave, MSG_FolderInfo *dstFolder, nsMsgDatabase *sourceDB);
|
||||
void UpdateMoveCopyStatus(MWContext *context, PRBool isMove, int32 curMsgCount, int32 totMessages);
|
||||
#endif
|
||||
|
||||
NS_IMETHOD RememberPassword(const char *password);
|
||||
NS_IMETHOD GetRememberedPassword(char ** password);
|
||||
NS_IMETHOD UserNeedsToAuthenticateForFolder(PRBool displayOnly, PRBool *needsAuthenticate);
|
||||
NS_IMETHOD GetUsersName(char **userName);
|
||||
NS_IMETHOD GetHostName(char **hostName);
|
||||
|
||||
virtual nsresult GetDBFolderInfoAndDB(nsDBFolderInfo **folderInfo, nsMsgDatabase **db) = 0;
|
||||
NS_IMETHOD DeleteMessage(nsIMessage *message) = 0;
|
||||
|
||||
|
||||
protected:
|
||||
nsString mName;
|
||||
PRUint32 mFlags;
|
||||
PRInt32 mNumUnreadMessages; /* count of unread messages (-1 means
|
||||
unknown; -2 means unknown but we already
|
||||
tried to find out.) */
|
||||
PRInt32 mNumTotalMessages; /* count of existing messages. */
|
||||
nsISupportsArray *mSubFolders;
|
||||
nsISupportsArray *mListeners;
|
||||
#ifdef HAVE_MASTER
|
||||
MSG_Master *mMaster;
|
||||
#endif
|
||||
|
||||
PRInt16 mCsid; // default csid for folder/newsgroup - maintained by fe.
|
||||
PRUint8 mDepth;
|
||||
PRInt32 mPrefFlags; // prefs like MSG_PREF_OFFLINE, MSG_PREF_ONE_PANE, etc
|
||||
#ifdef HAVE_SEMAPHORE
|
||||
void *mSemaphoreHolder; // set when the folder is being written to
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DB
|
||||
nsMsgKey m_lastMessageLoaded;
|
||||
#endif
|
||||
// These values are used for tricking the front end into thinking that we have more
|
||||
// messages than are really in the DB. This is usually after and IMAP message copy where
|
||||
// we don't want to do an expensive select until the user actually opens that folder
|
||||
PRUint32 mNumPendingUnreadMessages;
|
||||
PRUint32 mNumPendingTotalMessages;
|
||||
|
||||
PRBool mIsCachable;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,595 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "msgCore.h" // precompiled header...
|
||||
|
||||
#include "nsMsgGroupRecord.h"
|
||||
|
||||
#include "plstr.h"
|
||||
#include "prmem.h"
|
||||
#include "nsEscape.h"
|
||||
#include "nsCRT.h"
|
||||
|
||||
/* for the XP_TO_UPPER stuff */
|
||||
#include "xp_mcom.h"
|
||||
#include "net.h"
|
||||
|
||||
/* for linebreak, CR, LF, etc */
|
||||
#include "fe_proto.h"
|
||||
|
||||
extern "C" {
|
||||
extern int MK_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
const PRUint32 F_ISGROUP = 0x00000001;
|
||||
const PRUint32 F_EXPANDED = 0x00000002;
|
||||
const PRUint32 F_CATCONT = 0x00000004;
|
||||
const PRUint32 F_VIRTUAL = 0x00000008;
|
||||
const PRUint32 F_DIRTY = 0x00000010;
|
||||
const PRUint32 F_DESCENDENTSLOADED = 0x00000020;
|
||||
const PRUint32 F_HTMLOKGROUP = 0x00000040;
|
||||
const PRUint32 F_HTMLOKTREE = 0x00000080;
|
||||
const PRUint32 F_NEEDEXTRAINFO = 0x00000100;
|
||||
const PRUint32 F_DOESNOTEXIST = 0x00000200;
|
||||
const PRUint32 RUNTIMEFLAGS = // Flags to be sure *not* to write to disk.
|
||||
F_DIRTY | F_DESCENDENTSLOADED | F_EXPANDED;
|
||||
|
||||
|
||||
|
||||
int
|
||||
nsMsgGroupRecord::GroupNameCompare(const char* name1, const char* name2,
|
||||
char delimiter, PRBool caseInsensitive)
|
||||
{
|
||||
if (caseInsensitive)
|
||||
{
|
||||
while (*name1 && (nsCRT::ToUpper(*name1) == nsCRT::ToUpper(*name2))) {
|
||||
name1++;
|
||||
name2++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (*name1 && *name1 == *name2) {
|
||||
name1++;
|
||||
name2++;
|
||||
}
|
||||
}
|
||||
|
||||
if (*name1 && *name2) {
|
||||
if (*name1 == delimiter) return -1;
|
||||
if (*name2 == delimiter) return 1;
|
||||
}
|
||||
|
||||
if (caseInsensitive)
|
||||
return int(nsCRT::ToUpper(*name1)) - int(nsCRT::ToUpper(*name2));
|
||||
else
|
||||
return int(*name1) - int(*name2);
|
||||
}
|
||||
|
||||
|
||||
nsMsgGroupRecord*
|
||||
nsMsgGroupRecord::Create(nsMsgGroupRecord* parent, const char* partname,
|
||||
PRInt64 time, PRInt32 uniqueid, PRInt32 fileoffset)
|
||||
{
|
||||
nsMsgGroupRecord* result = new nsMsgGroupRecord(parent, partname,
|
||||
time, uniqueid, fileoffset);
|
||||
if (result && partname && !result->m_partname) {
|
||||
// We ran out of memory.
|
||||
delete result;
|
||||
result = NULL;
|
||||
}
|
||||
result->InitializeSibling();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
nsMsgGroupRecord::nsMsgGroupRecord(nsMsgGroupRecord* parent, const char* partname,
|
||||
PRInt64 time, PRInt32 uniqueid, PRInt32 fileoffset,
|
||||
char delimiter /* = '.' */)
|
||||
{
|
||||
int length;
|
||||
m_prettyname = NULL;
|
||||
m_parent = parent;
|
||||
m_children = NULL;
|
||||
m_sibling = NULL;
|
||||
m_flags = 0;
|
||||
m_partname = NULL;
|
||||
m_addtime = time;
|
||||
m_uniqueId = uniqueid;
|
||||
m_fileoffset = fileoffset;
|
||||
m_delimiter = delimiter;
|
||||
if (partname) {
|
||||
length = PL_strlen(partname);
|
||||
// PR_ASSERT(parent != NULL);
|
||||
m_partname = new char [length + 1];
|
||||
if (!m_partname) {
|
||||
m_parent = NULL;
|
||||
return;
|
||||
}
|
||||
PL_strcpy(m_partname, partname);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nsMsgGroupRecord::~nsMsgGroupRecord()
|
||||
{
|
||||
delete [] m_partname;
|
||||
m_partname = NULL;
|
||||
delete [] m_prettyname;
|
||||
m_prettyname = NULL;
|
||||
while (m_children) {
|
||||
delete m_children;
|
||||
}
|
||||
m_children = NULL;
|
||||
if (m_parent) {
|
||||
nsMsgGroupRecord** ptr;
|
||||
for (ptr = &(m_parent->m_children);
|
||||
*ptr;
|
||||
ptr = &((*ptr)->m_sibling)) {
|
||||
if (*ptr == this) {
|
||||
*ptr = m_sibling;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nsMsgGroupRecord::InitializeSibling()
|
||||
{
|
||||
if (m_parent) {
|
||||
PR_ASSERT(m_partname != NULL);
|
||||
nsMsgGroupRecord** ptr;
|
||||
for (ptr = &(m_parent->m_children) ; *ptr ; ptr = &((*ptr)->m_sibling)) {
|
||||
int comp = GroupNameCompare((*ptr)->m_partname, m_partname, m_delimiter, IsIMAPGroupRecord());
|
||||
PR_ASSERT(comp != 0);
|
||||
if (comp >= 0) break;
|
||||
}
|
||||
m_sibling = *ptr;
|
||||
*ptr = this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nsMsgGroupRecord*
|
||||
nsMsgGroupRecord::FindDescendant(const char* name)
|
||||
{
|
||||
if (!name || !*name) return this;
|
||||
char* ptr = PL_strchr(name, m_delimiter);
|
||||
if (ptr) *ptr = '\0';
|
||||
nsMsgGroupRecord* child;
|
||||
for (child = m_children ; child ; child = child->m_sibling) {
|
||||
if (PL_strcmp(child->m_partname, name) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ptr) {
|
||||
*ptr++ = m_delimiter;
|
||||
if (child) {
|
||||
return child->FindDescendant(ptr);
|
||||
}
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
||||
|
||||
nsMsgGroupRecord*
|
||||
nsMsgGroupRecord::GetSiblingOrAncestorSibling()
|
||||
{
|
||||
if (m_sibling) return m_sibling;
|
||||
if (m_parent) return m_parent->GetSiblingOrAncestorSibling();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nsMsgGroupRecord*
|
||||
nsMsgGroupRecord::GetNextAlphabetic()
|
||||
{
|
||||
nsMsgGroupRecord* result;
|
||||
if (m_children) result = m_children;
|
||||
else result = GetSiblingOrAncestorSibling();
|
||||
#ifdef DEBUG_slowAndParanoid
|
||||
if (result) {
|
||||
char* ptr1 = GetFullName();
|
||||
char* ptr2 = result->GetFullName();
|
||||
PR_ASSERT(GroupNameCompare(ptr1, ptr2) < 0);
|
||||
delete [] ptr1;
|
||||
delete [] ptr2;
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
nsMsgGroupRecord*
|
||||
nsMsgGroupRecord::GetNextAlphabeticNoCategories()
|
||||
{
|
||||
if (IsCategoryContainer()) {
|
||||
return GetSiblingOrAncestorSibling();
|
||||
} else {
|
||||
return GetNextAlphabetic();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char*
|
||||
nsMsgGroupRecord::GetFullName()
|
||||
{
|
||||
int length = 0;
|
||||
nsMsgGroupRecord* ptr;
|
||||
for (ptr = this ; ptr ; ptr = ptr->m_parent) {
|
||||
if (ptr->m_partname) length += PL_strlen(ptr->m_partname) + 1;
|
||||
}
|
||||
PR_ASSERT(length > 0);
|
||||
if (length <= 0) return NULL;
|
||||
char* result = new char [length];
|
||||
if (result) {
|
||||
SuckInName(result);
|
||||
PR_ASSERT(int(PL_strlen(result)) + 1 == length);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
char*
|
||||
nsMsgGroupRecord::SuckInName(char* ptr)
|
||||
{
|
||||
if (m_parent && m_parent->m_partname) {
|
||||
ptr = m_parent->SuckInName(ptr);
|
||||
*ptr++ = m_delimiter;
|
||||
}
|
||||
PL_strcpy(ptr, m_partname);
|
||||
return ptr + PL_strlen(ptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
nsMsgGroupRecord::SetPrettyName(const char* name)
|
||||
{
|
||||
if (name == NULL && m_prettyname == NULL) return 0;
|
||||
m_flags |= F_DIRTY;
|
||||
delete [] m_prettyname;
|
||||
m_prettyname = NULL;
|
||||
if (!name || !*name) {
|
||||
return 0;
|
||||
}
|
||||
int length = PL_strlen(name);
|
||||
m_prettyname = new char [length + 1];
|
||||
if (!m_prettyname) {
|
||||
return MK_OUT_OF_MEMORY;
|
||||
}
|
||||
PL_strcpy(m_prettyname, name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
nsMsgGroupRecord::IsCategory()
|
||||
{
|
||||
return GetCategoryContainer() != NULL;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsMsgGroupRecord::IsCategoryContainer()
|
||||
{
|
||||
return (m_flags & F_CATCONT) != 0;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsMsgGroupRecord::NeedsExtraInfo()
|
||||
{
|
||||
return (m_flags & F_NEEDEXTRAINFO) != 0;
|
||||
}
|
||||
|
||||
int
|
||||
nsMsgGroupRecord::SetNeedsExtraInfo(PRBool value)
|
||||
{
|
||||
return TweakFlag(F_NEEDEXTRAINFO, value);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
nsMsgGroupRecord::SetIsCategoryContainer(PRBool value)
|
||||
{
|
||||
// refuse to set a group to be a category container if it has a parent
|
||||
// that's a category container.
|
||||
if (! (value && GetCategoryContainer()))
|
||||
return TweakFlag(F_CATCONT, value);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
nsMsgGroupRecord*
|
||||
nsMsgGroupRecord::GetCategoryContainer()
|
||||
{
|
||||
if (IsCategoryContainer()) return NULL;
|
||||
for (nsMsgGroupRecord* ptr = m_parent ; ptr ; ptr = ptr->m_parent) {
|
||||
if (ptr->IsCategoryContainer()) return ptr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsMsgGroupRecord::IsVirtual(PRBool *retval)
|
||||
{
|
||||
*retval =( (m_flags & F_VIRTUAL) != 0);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMsgGroupRecord::SetIsVirtual(PRBool value)
|
||||
{
|
||||
TweakFlag(F_VIRTUAL, value);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
nsMsgGroupRecord::IsExpanded()
|
||||
{
|
||||
return (m_flags & F_EXPANDED) != 0;
|
||||
}
|
||||
|
||||
int
|
||||
nsMsgGroupRecord::SetIsExpanded(PRBool value)
|
||||
{
|
||||
return TweakFlag(F_EXPANDED, value);
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
nsMsgGroupRecord::IsHTMLOKGroup()
|
||||
{
|
||||
return (m_flags & F_HTMLOKGROUP) != 0;
|
||||
}
|
||||
|
||||
int
|
||||
nsMsgGroupRecord::SetIsHTMLOKGroup(PRBool value)
|
||||
{
|
||||
return TweakFlag(F_HTMLOKGROUP, value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
nsMsgGroupRecord::IsHTMLOKTree()
|
||||
{
|
||||
return (m_flags & F_HTMLOKTREE) != 0;
|
||||
}
|
||||
|
||||
int
|
||||
nsMsgGroupRecord::SetIsHTMLOKTree(PRBool value)
|
||||
{
|
||||
return TweakFlag(F_HTMLOKTREE, value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
nsMsgGroupRecord::IsGroup()
|
||||
{
|
||||
return (m_flags & F_ISGROUP) != 0;
|
||||
}
|
||||
|
||||
int
|
||||
nsMsgGroupRecord::SetIsGroup(PRBool value)
|
||||
{
|
||||
return TweakFlag(F_ISGROUP, value);
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
nsMsgGroupRecord::IsDescendentsLoaded()
|
||||
{
|
||||
return (m_flags & F_DESCENDENTSLOADED) != 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
nsMsgGroupRecord::SetIsDescendentsLoaded(PRBool value)
|
||||
{
|
||||
PR_ASSERT(value); // No reason we'd ever unset this.
|
||||
TweakFlag(F_DESCENDENTSLOADED, PR_TRUE);
|
||||
nsMsgGroupRecord* child;
|
||||
for (child = m_children ; child ; child = child->m_sibling) {
|
||||
child->SetIsDescendentsLoaded(value);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
PRBool nsMsgGroupRecord::DoesNotExistOnServer()
|
||||
{
|
||||
return (m_flags & F_DOESNOTEXIST) != 0;
|
||||
}
|
||||
|
||||
int nsMsgGroupRecord::SetDoesNotExistOnServer(PRBool value)
|
||||
{
|
||||
if (value) // turn off group flag if doesn't exist on server.
|
||||
TweakFlag(F_ISGROUP, PR_FALSE);
|
||||
return TweakFlag(F_DOESNOTEXIST, value);
|
||||
}
|
||||
|
||||
int
|
||||
nsMsgGroupRecord::TweakFlag(PRUint32 flagbit, PRBool value)
|
||||
{
|
||||
if (value) {
|
||||
if (!(m_flags & flagbit)) {
|
||||
m_flags |= flagbit;
|
||||
if (flagbit & ~RUNTIMEFLAGS)
|
||||
m_flags |= F_DIRTY;
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
if (m_flags & flagbit) {
|
||||
m_flags &= ~flagbit;
|
||||
if (flagbit & ~RUNTIMEFLAGS)
|
||||
m_flags |= F_DIRTY;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
PRInt32
|
||||
nsMsgGroupRecord::GetNumKids()
|
||||
{
|
||||
PRInt32 result = 0;
|
||||
nsMsgGroupRecord* child;
|
||||
for (child = m_children ; child ; child = child->m_sibling) {
|
||||
if (IsIMAPGroupRecord())
|
||||
result++;
|
||||
else
|
||||
if (child->m_flags & F_ISGROUP) result++;
|
||||
|
||||
if (!IsIMAPGroupRecord())
|
||||
result += child->GetNumKids();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
char*
|
||||
nsMsgGroupRecord::GetSaveString()
|
||||
{
|
||||
char* pretty = NULL;
|
||||
if (m_prettyname) {
|
||||
pretty = nsEscape(m_prettyname, url_XAlphas);
|
||||
if (!pretty) return NULL;
|
||||
}
|
||||
char* fullname = GetFullName();
|
||||
if (!fullname) return NULL;
|
||||
char* result = PR_smprintf("%s,%s,%lx,%lx,%lx" LINEBREAK,
|
||||
fullname, pretty ? pretty : "",
|
||||
(long) (m_flags & ~RUNTIMEFLAGS),
|
||||
(long) m_addtime,
|
||||
(long) m_uniqueId);
|
||||
delete [] fullname;
|
||||
if (pretty) PR_Free(pretty);
|
||||
m_flags &= ~F_DIRTY;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
nsMsgGroupRecord::IsDirty()
|
||||
{
|
||||
return (m_flags & F_DIRTY) != 0;
|
||||
}
|
||||
|
||||
|
||||
PRInt32
|
||||
nsMsgGroupRecord::GetDepth()
|
||||
{
|
||||
PRInt32 result = 0;
|
||||
nsMsgGroupRecord* tmp = m_parent;
|
||||
while (tmp) {
|
||||
tmp = tmp->m_parent;
|
||||
result++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
nsMsgGroupRecord*
|
||||
nsMsgGroupRecord::Create(nsMsgGroupRecord* parent, const char* saveline,
|
||||
PRInt32 savelinelength, PRInt32 fileoffset)
|
||||
{
|
||||
char* tmp;
|
||||
char* ptr;
|
||||
char* endptr;
|
||||
char* partname;
|
||||
char* prettyname;
|
||||
PRInt32 flags;
|
||||
PRInt32 addtime;
|
||||
PRInt32 uniqueid;
|
||||
nsMsgGroupRecord* result = NULL;
|
||||
|
||||
if (savelinelength < 0) savelinelength = PL_strlen(saveline);
|
||||
tmp = (char*) PR_Malloc(savelinelength + 1);
|
||||
if (!tmp) return NULL;
|
||||
PL_strncpy(tmp, saveline, savelinelength);
|
||||
tmp[savelinelength] = '\0';
|
||||
ptr = PL_strchr(tmp, ',');
|
||||
PR_ASSERT(ptr);
|
||||
if (!ptr) goto FAIL;
|
||||
*ptr++ = '\0';
|
||||
partname = PL_strrchr(tmp, '.');
|
||||
if (!partname) partname = tmp;
|
||||
else partname++;
|
||||
|
||||
#ifdef DEBUG_slowAndParanoid
|
||||
if (parent->m_partname) {
|
||||
char* parentname = parent->GetFullName();
|
||||
PR_ASSERT(partname > tmp && partname[-1] == '.');
|
||||
partname[-1] = '\0';
|
||||
PR_ASSERT(PL_strcmp(parentname, tmp) == 0);
|
||||
partname[-1] = '.';
|
||||
delete [] parentname;
|
||||
parentname = NULL;
|
||||
} else {
|
||||
PR_ASSERT(partname == tmp);
|
||||
}
|
||||
#endif
|
||||
|
||||
endptr = PL_strchr(ptr, ',');
|
||||
PR_ASSERT(endptr);
|
||||
if (!endptr) goto FAIL;
|
||||
*endptr++ = '\0';
|
||||
prettyname = nsUnescape(ptr);
|
||||
|
||||
ptr = endptr;
|
||||
endptr = PL_strchr(ptr, ',');
|
||||
PR_ASSERT(endptr);
|
||||
if (!endptr) goto FAIL;
|
||||
*endptr++ = '\0';
|
||||
flags = strtol(ptr, NULL, 16);
|
||||
|
||||
ptr = endptr;
|
||||
endptr = PL_strchr(ptr, ',');
|
||||
PR_ASSERT(endptr);
|
||||
if (!endptr) goto FAIL;
|
||||
*endptr++ = '\0';
|
||||
addtime = strtol(ptr, NULL, 16);
|
||||
|
||||
ptr = endptr;
|
||||
uniqueid = strtol(ptr, NULL, 16);
|
||||
|
||||
result = Create(parent, partname, addtime, uniqueid, fileoffset);
|
||||
if (result) {
|
||||
PRBool maybeCategoryContainer = flags & F_CATCONT;
|
||||
flags &= ~F_CATCONT;
|
||||
result->m_flags = flags;
|
||||
if (maybeCategoryContainer)
|
||||
result->SetIsCategoryContainer(PR_TRUE);
|
||||
if (prettyname && *prettyname) result->SetPrettyName(prettyname);
|
||||
}
|
||||
|
||||
FAIL:
|
||||
PR_Free(tmp);
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
// This class should only be used by the subscribe UI and by newshost.cpp.
|
||||
// And, well, a bit by the category code. Everyone else should use the stuff
|
||||
// in newshost.h.
|
||||
|
||||
#ifndef _nsMsgGroupRecord_h_
|
||||
#define _nsMsgGroupRecord_h__
|
||||
|
||||
#include "prtypes.h"
|
||||
#include "nsISupports.h"
|
||||
|
||||
class nsIMAPGroupRecord;
|
||||
|
||||
class nsMsgGroupRecord {
|
||||
public:
|
||||
static nsMsgGroupRecord* Create(nsMsgGroupRecord* parent,
|
||||
const char* partname,
|
||||
PRInt64 m_addtime,
|
||||
PRInt32 uniqueid,
|
||||
PRInt32 fileoffset);
|
||||
static nsMsgGroupRecord* Create(nsMsgGroupRecord* parent,
|
||||
const char* saveline,
|
||||
PRInt32 savelinelength,
|
||||
PRInt32 fileoffset);
|
||||
|
||||
|
||||
virtual void InitializeSibling();
|
||||
virtual PRBool IsIMAPGroupRecord() { return PR_FALSE; }
|
||||
virtual nsIMAPGroupRecord *GetIMAPGroupRecord() { return 0; }
|
||||
|
||||
// This is just like PL_strcmp(), except it works on news group names.
|
||||
// A container groupname is always less than any contained groups.
|
||||
// So, "netscape.devs-client-technical" > "netscape.devs.directory", even
|
||||
// though PL_strcmp says otherwise. (YICK!)
|
||||
static int GroupNameCompare(const char* name1,
|
||||
const char* name2,
|
||||
char delimiter = '.',
|
||||
PRBool caseInsensitive = PR_FALSE);
|
||||
|
||||
|
||||
virtual ~nsMsgGroupRecord();
|
||||
|
||||
nsMsgGroupRecord* FindDescendant(const char* name);
|
||||
|
||||
nsMsgGroupRecord* GetParent() {return m_parent;}
|
||||
nsMsgGroupRecord* GetChildren() {return m_children;}
|
||||
nsMsgGroupRecord* GetSibling() {return m_sibling;}
|
||||
nsMsgGroupRecord* GetSiblingOrAncestorSibling();
|
||||
nsMsgGroupRecord* GetNextAlphabetic();
|
||||
|
||||
nsMsgGroupRecord* GetNextAlphabeticNoCategories();
|
||||
|
||||
const char* GetPartName() {return m_partname;}
|
||||
|
||||
// The resulting string must be free'd using delete[].
|
||||
char* GetFullName();
|
||||
|
||||
const char* GetPrettyName() {return m_prettyname;}
|
||||
int SetPrettyName(const char* prettyname);
|
||||
|
||||
PRInt64 GetAddTime() {return m_addtime;}
|
||||
|
||||
virtual PRBool IsCategory();
|
||||
virtual PRBool IsCategoryContainer();
|
||||
virtual int SetIsCategoryContainer(PRBool value);
|
||||
|
||||
nsMsgGroupRecord* GetCategoryContainer();
|
||||
|
||||
// Get/Set whether this is a virtual newsgroup.
|
||||
nsresult IsVirtual(PRBool *retval);
|
||||
nsresult SetIsVirtual(PRBool value);
|
||||
|
||||
// Get/Set whether this is really a newsgroup (and not just a container
|
||||
// for newsgroups).
|
||||
virtual PRBool IsGroup();
|
||||
int SetIsGroup(PRBool value);
|
||||
|
||||
PRBool IsDescendentsLoaded();
|
||||
int SetIsDescendentsLoaded(PRBool value);
|
||||
|
||||
PRBool IsExpanded();
|
||||
int SetIsExpanded(PRBool value);
|
||||
|
||||
PRBool IsHTMLOKGroup();
|
||||
int SetIsHTMLOKGroup(PRBool value);
|
||||
|
||||
PRBool IsHTMLOKTree();
|
||||
int SetIsHTMLOKTree(PRBool value);
|
||||
|
||||
PRBool NeedsExtraInfo();
|
||||
int SetNeedsExtraInfo(PRBool value);
|
||||
|
||||
PRBool DoesNotExistOnServer();
|
||||
int SetDoesNotExistOnServer(PRBool value);
|
||||
|
||||
PRInt32 GetUniqueID() {return m_uniqueId;}
|
||||
|
||||
PRInt32 GetFileOffset() {return m_fileoffset;}
|
||||
int SetFileOffset(PRInt32 value) {m_fileoffset = value; return 0;}
|
||||
|
||||
// Get the number of descendents (not including ourself) that are
|
||||
// really newsgroups.
|
||||
PRInt32 GetNumKids();
|
||||
|
||||
// Gets the string that represents this group in the save file. The
|
||||
// resulting string must be free'd with PR_Free().
|
||||
char* GetSaveString();
|
||||
|
||||
PRBool IsDirty(); // Whether this record has had changes made
|
||||
// to it. Cleared by calls to GetSaveString().
|
||||
|
||||
PRInt32 GetDepth(); // Returns how deep in the heirarchy we are.
|
||||
// Basically, the number of dots in the full
|
||||
// newsgroup name, plus 1.
|
||||
virtual char GetHierarchySeparator() { return '.'; }
|
||||
|
||||
protected:
|
||||
nsMsgGroupRecord(nsMsgGroupRecord* parent,
|
||||
const char* partname,
|
||||
PRInt64 m_addtime,
|
||||
PRInt32 uniqueid,
|
||||
PRInt32 fileoffset,
|
||||
char delimiter = '.');
|
||||
int TweakFlag(PRUint32 flagbit, PRBool value);
|
||||
char* SuckInName(char* ptr);
|
||||
|
||||
char* m_partname;
|
||||
char* m_prettyname;
|
||||
nsMsgGroupRecord* m_parent;
|
||||
nsMsgGroupRecord* m_children;
|
||||
nsMsgGroupRecord* m_sibling;
|
||||
PRUint32 m_flags;
|
||||
PRInt64 m_addtime;
|
||||
PRInt32 m_uniqueId;
|
||||
PRInt32 m_fileoffset;
|
||||
char m_delimiter;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* _grec_h_ */
|
|
@ -0,0 +1,241 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "msgCore.h"
|
||||
#include "nsMsgLineBuffer.h"
|
||||
|
||||
nsByteArray::nsByteArray()
|
||||
{
|
||||
m_buffer = NULL;
|
||||
m_bufferSize = 0;
|
||||
m_bufferPos = 0;
|
||||
}
|
||||
|
||||
nsByteArray::~nsByteArray()
|
||||
{
|
||||
PR_FREEIF(m_buffer);
|
||||
}
|
||||
|
||||
nsresult nsByteArray::GrowBuffer(PRUint32 desired_size, PRUint32 quantum)
|
||||
{
|
||||
if (m_bufferSize < desired_size)
|
||||
{
|
||||
char *new_buf;
|
||||
PRUint32 increment = desired_size - m_bufferSize;
|
||||
if (increment < quantum) /* always grow by a minimum of N bytes */
|
||||
increment = quantum;
|
||||
|
||||
|
||||
new_buf = (m_buffer
|
||||
? (char *) PR_REALLOC (m_buffer, (m_bufferSize + increment))
|
||||
: (char *) PR_MALLOC (m_bufferSize + increment));
|
||||
if (! new_buf)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
m_buffer = new_buf;
|
||||
m_bufferSize += increment;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
nsresult nsByteArray::AppendString(const char *string)
|
||||
{
|
||||
PRUint32 strLength = (string) ? PL_strlen(string) : 0;
|
||||
return AppendBuffer(string, strLength);
|
||||
|
||||
}
|
||||
|
||||
nsresult nsByteArray::AppendBuffer(const char *buffer, PRUint32 length)
|
||||
{
|
||||
nsresult ret = NS_OK;
|
||||
if (m_bufferPos + length > m_bufferSize)
|
||||
ret = GrowBuffer(m_bufferPos + length, 1024);
|
||||
if (ret == NS_OK)
|
||||
{
|
||||
memcpy(m_buffer + m_bufferPos, buffer, length);
|
||||
m_bufferPos += length;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
nsMsgLineBuffer::nsMsgLineBuffer(nsMsgLineBufferHandler *handler, PRBool convertNewlinesP)
|
||||
{
|
||||
m_handler = handler;
|
||||
m_convertNewlinesP = convertNewlinesP;
|
||||
}
|
||||
|
||||
nsMsgLineBuffer::~nsMsgLineBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
PRInt32 nsMsgLineBuffer::BufferInput(const char *net_buffer, PRInt32 net_buffer_size)
|
||||
{
|
||||
int status = 0;
|
||||
if (m_bufferPos > 0 && m_buffer && m_buffer[m_bufferPos - 1] == CR &&
|
||||
net_buffer_size > 0 && net_buffer[0] != LF) {
|
||||
/* The last buffer ended with a CR. The new buffer does not start
|
||||
with a LF. This old buffer should be shipped out and discarded. */
|
||||
PR_ASSERT(m_bufferSize > m_bufferPos);
|
||||
if (m_bufferSize <= m_bufferPos) return -1;
|
||||
status = ConvertAndSendBuffer();
|
||||
if (status < 0)
|
||||
return status;
|
||||
m_bufferPos = 0;
|
||||
}
|
||||
while (net_buffer_size > 0)
|
||||
{
|
||||
const char *net_buffer_end = net_buffer + net_buffer_size;
|
||||
const char *newline = 0;
|
||||
const char *s;
|
||||
|
||||
|
||||
for (s = net_buffer; s < net_buffer_end; s++)
|
||||
{
|
||||
/* Move forward in the buffer until the first newline.
|
||||
Stop when we see CRLF, CR, or LF, or the end of the buffer.
|
||||
*But*, if we see a lone CR at the *very end* of the buffer,
|
||||
treat this as if we had reached the end of the buffer without
|
||||
seeing a line terminator. This is to catch the case of the
|
||||
buffers splitting a CRLF pair, as in "FOO\r\nBAR\r" "\nBAZ\r\n".
|
||||
*/
|
||||
if (*s == CR || *s == LF)
|
||||
{
|
||||
newline = s;
|
||||
if (newline[0] == CR)
|
||||
{
|
||||
if (s == net_buffer_end - 1)
|
||||
{
|
||||
/* CR at end - wait for the next character. */
|
||||
newline = 0;
|
||||
break;
|
||||
}
|
||||
else if (newline[1] == LF)
|
||||
/* CRLF seen; swallow both. */
|
||||
newline++;
|
||||
}
|
||||
newline++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure room in the net_buffer and append some or all of the current
|
||||
chunk of data to it. */
|
||||
{
|
||||
const char *end = (newline ? newline : net_buffer_end);
|
||||
PRUint32 desired_size = (end - net_buffer) + m_bufferPos + 1;
|
||||
|
||||
if (desired_size >= m_bufferSize)
|
||||
{
|
||||
status = GrowBuffer (desired_size, 1024);
|
||||
if (status < 0)
|
||||
return status;
|
||||
}
|
||||
memcpy (m_buffer + m_bufferPos, net_buffer, (end - net_buffer));
|
||||
m_bufferPos += (end - net_buffer);
|
||||
}
|
||||
|
||||
/* Now m_buffer contains either a complete line, or as complete
|
||||
a line as we have read so far.
|
||||
|
||||
If we have a line, process it, and then remove it from `m_buffer'.
|
||||
Then go around the loop again, until we drain the incoming data.
|
||||
*/
|
||||
if (!newline)
|
||||
return 0;
|
||||
|
||||
status = ConvertAndSendBuffer();
|
||||
if (status < 0) return status;
|
||||
|
||||
net_buffer_size -= (newline - net_buffer);
|
||||
net_buffer = newline;
|
||||
m_bufferPos = 0;
|
||||
}
|
||||
#ifdef DEBUG_bienvenu
|
||||
printf("returning from buffer input m_bufferPos = %ld\n", m_bufferPos);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
PRInt32 nsMsgLineBuffer::HandleLine(char *line, PRUint32 line_length)
|
||||
{
|
||||
NS_ASSERTION(FALSE, "must override this method if you don't provide a handler");
|
||||
return 0;
|
||||
}
|
||||
|
||||
PRInt32 nsMsgLineBuffer::ConvertAndSendBuffer()
|
||||
{
|
||||
/* Convert the line terminator to the native form.
|
||||
*/
|
||||
|
||||
char *buf = m_buffer;
|
||||
PRInt32 length = m_bufferPos;
|
||||
|
||||
char* newline;
|
||||
|
||||
PR_ASSERT(buf && length > 0);
|
||||
if (!buf || length <= 0)
|
||||
return -1;
|
||||
newline = buf + length;
|
||||
|
||||
PR_ASSERT(newline[-1] == CR || newline[-1] == LF);
|
||||
if (newline[-1] != CR && newline[-1] != LF)
|
||||
return -1;
|
||||
|
||||
if (!m_convertNewlinesP)
|
||||
{
|
||||
}
|
||||
#if (LINEBREAK_LEN == 1)
|
||||
else if ((newline - buf) >= 2 &&
|
||||
newline[-2] == CR &&
|
||||
newline[-1] == LF)
|
||||
{
|
||||
/* CRLF -> CR or LF */
|
||||
buf [length - 2] = LINEBREAK[0];
|
||||
length--;
|
||||
}
|
||||
else if (newline > buf + 1 &&
|
||||
newline[-1] != LINEBREAK[0])
|
||||
{
|
||||
/* CR -> LF or LF -> CR */
|
||||
buf [length - 1] = LINEBREAK[0];
|
||||
}
|
||||
#else
|
||||
else if (((newline - buf) >= 2 && newline[-2] != CR) ||
|
||||
((newline - buf) >= 1 && newline[-1] != LF))
|
||||
{
|
||||
/* LF -> CRLF or CR -> CRLF */
|
||||
length++;
|
||||
buf[length - 2] = LINEBREAK[0];
|
||||
buf[length - 1] = LINEBREAK[1];
|
||||
}
|
||||
#endif
|
||||
|
||||
return (m_handler) ? m_handler->HandleLine(buf, length) : HandleLine(buf, length);
|
||||
}
|
||||
|
||||
// If there's still some data (non CRLF terminated) flush it out
|
||||
PRInt32 nsMsgLineBuffer::FlushLastLine()
|
||||
{
|
||||
char *buf = m_buffer + m_bufferPos;
|
||||
PRInt32 length = m_bufferPos - 1;
|
||||
if (length > 0)
|
||||
return (m_handler) ? m_handler->HandleLine(buf, length) : HandleLine(buf, length);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
#ifndef _nsMsgLineBuffer_H
|
||||
#define _nsMsgLineBuffer_H
|
||||
|
||||
#include "msgCore.h" // precompiled header...
|
||||
|
||||
// I can't believe I have to have this stupid class, but I can't find
|
||||
// anything suitable (nsStrImpl might be, when its done). nsIByteBuffer
|
||||
// would do, if I had a stream for input, which I don't.
|
||||
|
||||
class nsByteArray
|
||||
{
|
||||
public:
|
||||
nsByteArray();
|
||||
virtual ~nsByteArray();
|
||||
PRUint32 GetSize() {return m_bufferSize;}
|
||||
nsresult GrowBuffer(PRUint32 desired_size, PRUint32 quantum = 1024);
|
||||
nsresult AppendString(const char *string);
|
||||
nsresult AppendBuffer(const char *buffer, PRUint32 length);
|
||||
void ResetWritePos() {m_bufferPos = 0;}
|
||||
char *GetBuffer() {return m_buffer;}
|
||||
protected:
|
||||
char *m_buffer;
|
||||
PRUint32 m_bufferSize;
|
||||
PRUint32 m_bufferPos; // write Pos in m_buffer - where the next byte should go.
|
||||
};
|
||||
|
||||
|
||||
class nsMsgLineBufferHandler : public nsByteArray
|
||||
{
|
||||
public:
|
||||
virtual PRInt32 HandleLine(char *line, PRUint32 line_length) = 0;
|
||||
};
|
||||
|
||||
class nsMsgLineBuffer : nsByteArray
|
||||
{
|
||||
public:
|
||||
nsMsgLineBuffer(nsMsgLineBufferHandler *handler, PRBool convertNewlinesP);
|
||||
|
||||
virtual ~nsMsgLineBuffer();
|
||||
PRInt32 BufferInput(const char *net_buffer, PRInt32 net_buffer_size);
|
||||
// Not sure why anyone cares, by NNTPHost seems to want to know the buf pos.
|
||||
PRUint32 GetBufferPos() {return m_bufferPos;}
|
||||
|
||||
virtual PRInt32 HandleLine(char *line, PRUint32 line_length);
|
||||
// flush last line, though it won't be CRLF terminated.
|
||||
virtual PRInt32 FlushLastLine();
|
||||
protected:
|
||||
nsMsgLineBuffer(PRBool convertNewlinesP);
|
||||
|
||||
PRInt32 ConvertAndSendBuffer();
|
||||
|
||||
nsMsgLineBufferHandler *m_handler;
|
||||
PRBool m_convertNewlinesP;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,112 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _nsNewsSet_H_
|
||||
#define _nsNewsSet_H_
|
||||
|
||||
// msg_NewsArtSet represents a set of articles. Typically, it is the set of
|
||||
// read articles from a .newsrc file, but it can be used for other purposes
|
||||
// too.
|
||||
|
||||
// If a MSG_NewsHost* is supplied to the creation routine, then that
|
||||
// MSG_NewsHost will be notified whwnever a change is made to set.
|
||||
|
||||
class MSG_NewsHost;
|
||||
|
||||
class nsNewsSet {
|
||||
public:
|
||||
// Creates an empty set.
|
||||
static nsNewsSet* Create(MSG_NewsHost* host = NULL);
|
||||
|
||||
// Creates a set from the list of numbers, as might be found in a
|
||||
// newsrc file.
|
||||
static nsNewsSet* Create(const char* str, MSG_NewsHost* host = NULL);
|
||||
~nsNewsSet();
|
||||
|
||||
// FirstNonMember() returns the lowest non-member of the set that is
|
||||
// greater than 0.
|
||||
PRInt32 FirstNonMember();
|
||||
|
||||
// Output() converts to a string representation suitable for writing to a
|
||||
// .newsrc file. (The result must be freed by the caller using delete[].)
|
||||
char* Output();
|
||||
|
||||
// IsMember() returns whether the given article is a member of this set.
|
||||
PRBool IsMember(PRInt32 art);
|
||||
|
||||
// Add() adds the given article to the set. (Returns 1 if a change was
|
||||
// made, 0 if it was already there, and negative on error.)
|
||||
int Add(PRInt32 art);
|
||||
|
||||
// Remove() removes the given article from the set.
|
||||
int Remove(PRInt32 art);
|
||||
|
||||
// AddRange() adds the (inclusive) given range of articles to the set.
|
||||
int AddRange(PRInt32 first, PRInt32 last);
|
||||
|
||||
// CountMissingInRange() takes an inclusive range of articles and returns
|
||||
// the number of articles in that range which are not in the set.
|
||||
PRInt32 CountMissingInRange(PRInt32 start, PRInt32 end);
|
||||
|
||||
// FirstMissingRange() takes an inclusive range and finds the first range
|
||||
// of articles that are not in the set. If none, return zeros.
|
||||
int FirstMissingRange(PRInt32 min, PRInt32 max, PRInt32* first, PRInt32* last);
|
||||
|
||||
|
||||
// LastMissingRange() takes an inclusive range and finds the last range
|
||||
// of articles that are not in the set. If none, return zeros.
|
||||
int LastMissingRange(PRInt32 min, PRInt32 max, PRInt32* first, PRInt32* last);
|
||||
|
||||
PRInt32 GetLastMember();
|
||||
PRInt32 GetFirstMember();
|
||||
void SetLastMember(PRInt32 highWaterMark);
|
||||
// For debugging only...
|
||||
PRInt32 getLength() {return m_length;}
|
||||
|
||||
#ifdef DEBUG
|
||||
static void RunTests();
|
||||
#endif
|
||||
|
||||
protected:
|
||||
nsNewsSet(MSG_NewsHost* host);
|
||||
nsNewsSet(const char*, MSG_NewsHost* host);
|
||||
PRBool Grow();
|
||||
PRBool Optimize();
|
||||
|
||||
#ifdef DEBUG
|
||||
static void test_decoder(const char*);
|
||||
static void test_adder();
|
||||
static void test_ranges();
|
||||
static void test_member(PRBool with_cache);
|
||||
#endif
|
||||
|
||||
PRInt32 *m_data; /* the numbers composing the `chunks' */
|
||||
PRInt32 m_data_size; /* size of that malloc'ed block */
|
||||
PRInt32 m_length; /* active area */
|
||||
|
||||
PRInt32 m_cached_value; /* a potential set member, or -1 if unset*/
|
||||
PRInt32 m_cached_value_index; /* the index into `data' at which a search
|
||||
to determine whether `cached_value' was
|
||||
a member of the set ended. */
|
||||
#ifdef NEWSRC_DOES_HOST_STUFF
|
||||
MSG_NewsHost* m_host;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#endif /* _nsNewsSet_H_ */
|
|
@ -0,0 +1,279 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "msgCore.h" // precompiled header...
|
||||
|
||||
#include "MailNewsTypes.h"
|
||||
#include "nsUInt32Array.h"
|
||||
#include "xp_qsort.h" // XXX we need to remove this dependency
|
||||
#include "xp.h" // XXX we need to remove this dependency..
|
||||
|
||||
|
||||
nsUInt32Array::nsUInt32Array()
|
||||
{
|
||||
m_nSize = 0;
|
||||
m_nMaxSize = 0;
|
||||
m_nGrowBy = 0;
|
||||
m_pData = NULL;
|
||||
}
|
||||
|
||||
nsUInt32Array::~nsUInt32Array()
|
||||
{
|
||||
SetSize(0);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PRUint32 nsUInt32Array::GetSize() const
|
||||
{
|
||||
return m_nSize;
|
||||
}
|
||||
|
||||
PRBool nsUInt32Array::SetSize(PRUint32 nSize, PRUint32 nGrowBy)
|
||||
{
|
||||
PR_ASSERT(nSize >= 0);
|
||||
|
||||
if (nGrowBy >= 0)
|
||||
m_nGrowBy = nGrowBy;
|
||||
|
||||
#ifdef MAX_ARR_ELEMS
|
||||
if (nSize > MAX_ARR_ELEMS);
|
||||
{
|
||||
PR_ASSERT(nSize <= MAX_ARR_ELEMS); // Will fail
|
||||
return PR_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (nSize == 0)
|
||||
{
|
||||
// Remove all elements
|
||||
PR_Free(m_pData);
|
||||
m_nSize = 0;
|
||||
m_nMaxSize = 0;
|
||||
m_pData = NULL;
|
||||
}
|
||||
else if (m_pData == NULL)
|
||||
{
|
||||
// Create a new array
|
||||
m_nMaxSize = MAX(8, nSize);
|
||||
m_pData = (PRUint32 *)PR_Calloc(1, m_nMaxSize * sizeof(PRUint32));
|
||||
if (m_pData)
|
||||
m_nSize = nSize;
|
||||
else
|
||||
m_nSize = m_nMaxSize = 0;
|
||||
}
|
||||
else if (nSize <= m_nMaxSize)
|
||||
{
|
||||
// The new size is within the current maximum size, make sure new
|
||||
// elements are to initialized to zero
|
||||
if (nSize > m_nSize)
|
||||
memset(&m_pData[m_nSize], 0, (nSize - m_nSize) * sizeof(PRUint32));
|
||||
|
||||
m_nSize = nSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The array needs to grow, figure out how much
|
||||
PRUint32 nMaxSize;
|
||||
nGrowBy = MAX(m_nGrowBy, MIN(1024, MAX(8, m_nSize / 8)));
|
||||
nMaxSize = MAX(nSize, m_nMaxSize + nGrowBy);
|
||||
#ifdef MAX_ARR_ELEMS
|
||||
nMaxSize = MIN(MAX_ARR_ELEMS, nMaxSize);
|
||||
#endif
|
||||
|
||||
PRUint32 *pNewData = (PRUint32 *)PR_Malloc(nMaxSize * sizeof(PRUint32));
|
||||
if (pNewData)
|
||||
{
|
||||
// Copy the data from the old array to the new one
|
||||
XP_MEMCPY(pNewData, m_pData, m_nSize * sizeof(PRUint32));
|
||||
|
||||
// Zero out the remaining elements
|
||||
memset(&pNewData[m_nSize], 0, (nSize - m_nSize) * sizeof(PRUint32));
|
||||
m_nSize = nSize;
|
||||
m_nMaxSize = nMaxSize;
|
||||
|
||||
// Free the old array
|
||||
PR_Free(m_pData);
|
||||
m_pData = pNewData;
|
||||
}
|
||||
}
|
||||
|
||||
return nSize == m_nSize;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PRUint32 &nsUInt32Array::ElementAt(PRUint32 nIndex)
|
||||
{
|
||||
PR_ASSERT(nIndex >= 0 && nIndex < m_nSize);
|
||||
return m_pData[nIndex];
|
||||
}
|
||||
|
||||
PRUint32 nsUInt32Array::GetAt(PRUint32 nIndex) const
|
||||
{
|
||||
PR_ASSERT(nIndex >= 0 && nIndex < m_nSize);
|
||||
return m_pData[nIndex];
|
||||
}
|
||||
|
||||
PRUint32 *nsUInt32Array::GetData()
|
||||
{
|
||||
return m_pData;
|
||||
}
|
||||
|
||||
void nsUInt32Array::SetAt(PRUint32 nIndex, PRUint32 newElement)
|
||||
{
|
||||
PR_ASSERT(nIndex >= 0 && nIndex < m_nSize);
|
||||
m_pData[nIndex] = newElement;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PRUint32 nsUInt32Array::Add(PRUint32 newElement)
|
||||
{
|
||||
PRUint32 nIndex = m_nSize;
|
||||
|
||||
#ifdef MAX_ARR_ELEMS
|
||||
if (nIndex >= MAX_ARR_ELEMS)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
SetAtGrow(nIndex, newElement);
|
||||
return nIndex;
|
||||
}
|
||||
|
||||
PRUint32 nsUInt32Array::Add(PRUint32 *elementPtr, PRUint32 numElements)
|
||||
{
|
||||
if (SetSize(m_nSize + numElements))
|
||||
XP_MEMCPY(m_pData + m_nSize, elementPtr, numElements * sizeof(PRUint32));
|
||||
|
||||
return m_nSize;
|
||||
}
|
||||
|
||||
PRUint32 *nsUInt32Array::CloneData()
|
||||
{
|
||||
PRUint32 *copyOfData = (PRUint32 *)PR_Malloc(m_nSize * sizeof(PRUint32));
|
||||
if (copyOfData)
|
||||
XP_MEMCPY(copyOfData, m_pData, m_nSize * sizeof(PRUint32));
|
||||
|
||||
return copyOfData;
|
||||
}
|
||||
|
||||
void nsUInt32Array::InsertAt(PRUint32 nIndex, PRUint32 newElement, PRUint32 nCount)
|
||||
{
|
||||
PR_ASSERT(nIndex >= 0);
|
||||
PR_ASSERT(nCount > 0);
|
||||
|
||||
if (nIndex >= m_nSize)
|
||||
{
|
||||
// If the new element is after the end of the array, grow the array
|
||||
SetSize(nIndex + nCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The element is being insert inside the array
|
||||
int nOldSize = m_nSize;
|
||||
SetSize(m_nSize + nCount);
|
||||
|
||||
// Move the data after the insertion point
|
||||
XP_MEMMOVE(&m_pData[nIndex + nCount], &m_pData[nIndex],
|
||||
(nOldSize - nIndex) * sizeof(PRUint32));
|
||||
}
|
||||
|
||||
// Insert the new elements
|
||||
PR_ASSERT(nIndex + nCount <= m_nSize);
|
||||
while (nCount--)
|
||||
m_pData[nIndex++] = newElement;
|
||||
}
|
||||
|
||||
void nsUInt32Array::InsertAt(PRUint32 nStartIndex, const nsUInt32Array *pNewArray)
|
||||
{
|
||||
PR_ASSERT(nStartIndex >= 0);
|
||||
PR_ASSERT(pNewArray != NULL);
|
||||
|
||||
if (pNewArray->GetSize() > 0)
|
||||
{
|
||||
InsertAt(nStartIndex, pNewArray->GetAt(0), pNewArray->GetSize());
|
||||
for (PRUint32 i = 1; i < pNewArray->GetSize(); i++)
|
||||
m_pData[nStartIndex + i] = pNewArray->GetAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
void nsUInt32Array::RemoveAll()
|
||||
{
|
||||
SetSize(0);
|
||||
}
|
||||
|
||||
void nsUInt32Array::RemoveAt(PRUint32 nIndex, PRUint32 nCount)
|
||||
{
|
||||
PR_ASSERT(nIndex >= 0);
|
||||
PR_ASSERT(nIndex + nCount <= m_nSize);
|
||||
|
||||
if (nCount > 0)
|
||||
{
|
||||
// Make sure not to overstep the end of the array
|
||||
int nMoveCount = m_nSize - (nIndex + nCount);
|
||||
if (nCount && nMoveCount)
|
||||
XP_MEMMOVE(&m_pData[nIndex], &m_pData[nIndex + nCount],
|
||||
nMoveCount * sizeof(PRUint32));
|
||||
|
||||
m_nSize -= nCount;
|
||||
}
|
||||
}
|
||||
|
||||
void nsUInt32Array::SetAtGrow(PRUint32 nIndex, PRUint32 newElement)
|
||||
{
|
||||
PR_ASSERT(nIndex >= 0);
|
||||
|
||||
if (nIndex >= m_nSize)
|
||||
SetSize(nIndex+1);
|
||||
m_pData[nIndex] = newElement;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void nsUInt32Array::CopyArray(nsUInt32Array *oldA)
|
||||
{
|
||||
CopyArray(*oldA);
|
||||
}
|
||||
|
||||
void nsUInt32Array::CopyArray(nsUInt32Array &oldA)
|
||||
{
|
||||
if (m_pData)
|
||||
PR_Free(m_pData);
|
||||
m_nSize = oldA.m_nSize;
|
||||
m_nMaxSize = oldA.m_nMaxSize;
|
||||
m_pData = (PRUint32 *)PR_Malloc(m_nSize * sizeof(PRUint32));
|
||||
if (m_pData)
|
||||
XP_MEMCPY(m_pData, oldA.m_pData, m_nSize * sizeof(PRUint32));
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int CompareDWord (const void *v1, const void *v2)
|
||||
{
|
||||
// QuickSort callback to compare array values
|
||||
PRUint32 i1 = *(PRUint32 *)v1;
|
||||
PRUint32 i2 = *(PRUint32 *)v2;
|
||||
return i1 - i2;
|
||||
}
|
||||
|
||||
void nsUInt32Array::QuickSort (int (*compare) (const void *elem1, const void *elem2))
|
||||
{
|
||||
if (m_nSize > 1)
|
||||
XP_QSORT (m_pData, m_nSize, sizeof(void*), compare ? compare : CompareDWord);
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
#ifndef _nsUInt32Array_H_
|
||||
#define _nsUInt32Array_H_
|
||||
|
||||
#include "nscore.h"
|
||||
#include "xp_core.h"
|
||||
#include "nsCRT.h"
|
||||
#include "prmem.h"
|
||||
|
||||
class nsUInt32Array
|
||||
{
|
||||
public:
|
||||
// Construction/destruction
|
||||
nsUInt32Array();
|
||||
~nsUInt32Array();
|
||||
|
||||
// State/attribute member functions
|
||||
PRUint32 GetSize() const;
|
||||
PRBool SetSize(PRUint32 nNewSize, PRUint32 nGrowBy = -1);
|
||||
|
||||
// Accessor member functions
|
||||
PRUint32 &ElementAt(PRUint32 nIndex);
|
||||
PRUint32 GetAt(PRUint32 nIndex) const;
|
||||
PRUint32 *GetData();
|
||||
void SetAt(PRUint32 nIndex, PRUint32 newElement);
|
||||
|
||||
// Insertion/deletion member functions
|
||||
PRUint32 Add(PRUint32 newElement);
|
||||
PRUint32 Add(PRUint32 *elementPtr, PRUint32 numElements);
|
||||
void InsertAt(PRUint32 nIndex, PRUint32 newElement, PRUint32 nCount = 1);
|
||||
void InsertAt(PRUint32 nStartIndex, const nsUInt32Array *pNewArray);
|
||||
void RemoveAll();
|
||||
void RemoveAt(PRUint32 nIndex, PRUint32 nCount = 1);
|
||||
void SetAtGrow(PRUint32 nIndex, PRUint32 newElement);
|
||||
|
||||
// Sorting member functions
|
||||
void QuickSort(int (*compare) (const void *elem1, const void *elem2) = NULL);
|
||||
|
||||
// Overloaded operators
|
||||
PRUint32 operator[](PRUint32 nIndex) const { return GetAt(nIndex); }
|
||||
PRUint32 &operator[](PRUint32 nIndex) { return ElementAt(nIndex); }
|
||||
|
||||
// Miscellaneous member functions
|
||||
PRUint32 *CloneData();
|
||||
void CopyArray(nsUInt32Array *oldA);
|
||||
void CopyArray(nsUInt32Array &oldA);
|
||||
|
||||
protected:
|
||||
// Member data
|
||||
PRUint32 m_nSize;
|
||||
PRUint32 m_nMaxSize;
|
||||
PRUint32 m_nGrowBy;
|
||||
PRUint32* m_pData;
|
||||
};
|
||||
|
||||
|
||||
#endif // _DWordArray_H_
|
Загрузка…
Ссылка в новой задаче