Bug 250811 replace nsUint8Array with nsTARray<PRUint8> r+sr=bienvenu

git-svn-id: svn://10.0.0.236/trunk@242371 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
neil%parkwaycc.co.uk
2008-01-04 20:35:51 +00:00
parent 7166bacc91
commit edb7044a5d
11 changed files with 44 additions and 414 deletions

View File

@@ -2032,7 +2032,7 @@ NS_IMETHODIMP nsMsgDBView::Close()
m_keys.RemoveAll();
// be consistent
m_flags.RemoveAll();
m_levels.RemoveAll();
m_levels.Clear();
// clear these out since they no longer apply if we're switching a folder
nsMemory::Free(mJunkIndices);
@@ -2682,7 +2682,7 @@ nsresult nsMsgDBView::RemoveByIndex(nsMsgViewIndex index)
return NS_MSG_INVALID_DBVIEW_INDEX;
m_keys.RemoveAt(index);
m_flags.RemoveAt(index);
m_levels.RemoveAt(index);
m_levels.RemoveElementAt(index);
// the call to NoteChange() has to happen after we remove the key
// as NoteChange() will call RowCountChanged() which will call our GetRowCount()
@@ -3158,14 +3158,14 @@ nsresult nsMsgDBView::ReverseThreads()
{
nsUInt32Array newFlagArray;
nsMsgKeyArray newKeyArray;
nsUint8Array newLevelArray;
nsTArray<PRUint8> newLevelArray;
PRInt32 sourceIndex, destIndex;
PRInt32 viewSize = GetSize();
newKeyArray.SetSize(m_keys.GetSize());
newFlagArray.SetSize(m_flags.GetSize());
newLevelArray.SetSize(m_levels.GetSize());
newLevelArray.SetLength(m_levels.Length());
for (sourceIndex = 0, destIndex = viewSize - 1; sourceIndex < viewSize;)
{
@@ -3191,7 +3191,7 @@ nsresult nsMsgDBView::ReverseThreads()
{
newKeyArray.SetAt(destIndex, m_keys.GetAt(endThread));
newFlagArray.SetAt(destIndex, m_flags.GetAt(endThread));
newLevelArray.SetAt(destIndex, m_levels.GetAt(endThread));
newLevelArray[destIndex] = m_levels[endThread];
endThread--;
destIndex--;
}
@@ -3202,7 +3202,7 @@ nsresult nsMsgDBView::ReverseThreads()
// arrays' data ptrs, so they won't be freed when the arrays are deleted.
m_keys.CopyArray(newKeyArray);
m_flags.CopyArray(newFlagArray);
m_levels.CopyArray(newLevelArray);
m_levels.SwapElements(newLevelArray);
return NS_OK;
}
@@ -4149,7 +4149,7 @@ nsMsgViewIndex nsMsgDBView::ThreadIndexOfMsg(nsMsgKey msgKey,
threadIndex++;
numChildren++;
}
while ((int32) threadIndex < m_levels.GetSize() && m_levels[threadIndex] != 0);
while (threadIndex < m_levels.Length() && m_levels[threadIndex] != 0);
*pThreadCount = numChildren;
}
}
@@ -4251,7 +4251,7 @@ PRInt32 nsMsgDBView::CountExpandedThread(nsMsgViewIndex index)
threadIndex++;
numInThread++;
}
while ((PRInt32) threadIndex < m_levels.GetSize() && m_levels[threadIndex] != 0);
while (threadIndex < m_levels.Length() && m_levels[threadIndex] != 0);
return numInThread;
}
@@ -4437,7 +4437,7 @@ nsresult nsMsgDBView::ExpandByIndex(nsMsgViewIndex index, PRUint32 *pNumExpanded
if (m_viewFlags & nsMsgViewFlagsType::kUnreadOnly)
{
if (flags & MSG_FLAG_READ)
m_levels.Add(0); // keep top level hdr in thread, even though read.
m_levels.AppendElement(0); // keep top level hdr in thread, even though read.
rv = ListUnreadIdsInThread(pThread, index, &numExpanded);
}
else
@@ -4499,8 +4499,8 @@ nsresult nsMsgDBView::CollapseByIndex(nsMsgViewIndex index, PRUint32 *pNumCollap
{
m_keys.RemoveAt(index + 1);
m_flags.RemoveAt(index + 1);
m_levels.RemoveAt(index + 1);
}
m_levels.RemoveElementsAt(index + 1, threadCount);
if (pNumCollapsed != nsnull)
*pNumCollapsed = numRemoved;
NoteEndChange(index + 1, -numRemoved, nsMsgViewNotificationCode::insertOrDelete);
@@ -4710,7 +4710,7 @@ nsresult nsMsgDBView::AddHdr(nsIMsgDBHdr *msgHdr)
{
PRUint32 flags = 0;
#ifdef DEBUG_bienvenu
NS_ASSERTION((int) m_keys.GetSize() == m_flags.GetSize() && (int) m_keys.GetSize() == m_levels.GetSize(), "view arrays out of sync!");
NS_ASSERTION((int) m_keys.GetSize() == m_flags.GetSize() && (int) m_keys.GetSize() == m_levels.Length(), "view arrays out of sync!");
#endif
if (!GetShowingIgnored())
@@ -4745,7 +4745,7 @@ nsresult nsMsgDBView::AddHdr(nsIMsgDBHdr *msgHdr)
{
m_keys.Add(msgKey);
m_flags.Add(flags);
m_levels.Add(levelToAdd);
m_levels.AppendElement(levelToAdd);
// the call to NoteChange() has to happen after we add the key
// as NoteChange() will call RowCountChanged() which will call our GetRowCount()
@@ -4755,7 +4755,7 @@ nsresult nsMsgDBView::AddHdr(nsIMsgDBHdr *msgHdr)
{
m_keys.InsertAt(0, msgKey);
m_flags.InsertAt(0, flags);
m_levels.InsertAt(0, levelToAdd);
m_levels.InsertElementAt(0, levelToAdd);
// the call to NoteChange() has to happen after we insert the key
// as NoteChange() will call RowCountChanged() which will call our GetRowCount()
@@ -4768,7 +4768,7 @@ nsresult nsMsgDBView::AddHdr(nsIMsgDBHdr *msgHdr)
m_keys.InsertAt(insertIndex, msgKey);
m_flags.InsertAt(insertIndex, flags);
PRInt32 level = 0;
m_levels.InsertAt(insertIndex, level);
m_levels.InsertElementAt(insertIndex, level);
// the call to NoteChange() has to happen after we add the key
// as NoteChange() will call RowCountChanged() which will call our GetRowCount()
@@ -4840,7 +4840,7 @@ nsresult nsMsgDBView::ListIdsInThreadOrder(nsIMsgThread *threadHdr, nsMsgKey par
// ### TODO - how about hasChildren flag?
m_flags.SetAt(*viewIndex, msgFlags & ~MSG_VIEW_FLAGS);
// ### TODO this is going to be tricky - might use enumerators
m_levels.SetAt(*viewIndex, level);
m_levels[*viewIndex] = level;
// turn off thread or elided bit if they got turned on (maybe from new only view?)
msgHdr->AndFlags(~(MSG_VIEW_FLAG_ISTHREAD | MSG_FLAG_ELIDED), &newFlags);
(*pNumListed)++;
@@ -4865,7 +4865,7 @@ nsresult nsMsgDBView::ListIdsInThread(nsIMsgThread *threadHdr, nsMsgViewIndex st
numChildren--; // account for the existing thread root
m_keys.InsertAt(viewIndex, 0, numChildren);
m_flags.InsertAt(viewIndex, 0, numChildren);
m_levels.InsertAt(viewIndex, 1, numChildren); // default unthreaded level
m_levels.InsertElementsAt(viewIndex, numChildren, 1); // default unthreaded level
// ### need to rework this when we implemented threading in group views.
if (m_viewFlags & nsMsgViewFlagsType::kThreadedDisplay && ! (m_viewFlags & nsMsgViewFlagsType::kGroupBySort))
@@ -4903,7 +4903,7 @@ nsresult nsMsgDBView::ListIdsInThread(nsIMsgThread *threadHdr, nsMsgViewIndex st
NS_NOTREACHED("thread corrupt in db");
m_keys.RemoveAt(viewIndex, numChildren - *pNumListed);
m_flags.RemoveAt(viewIndex, numChildren - *pNumListed);
m_levels.RemoveAt(viewIndex, numChildren - *pNumListed);
m_levels.RemoveElementsAt(viewIndex, numChildren - *pNumListed);
// if we've listed fewer messages than are in the thread, then the db
// is corrupt, and we should invalidate it.
// we'll use this rv to indicate there's something wrong with the db
@@ -4989,7 +4989,7 @@ nsresult nsMsgDBView::ListUnreadIdsInThread(nsIMsgThread *threadHdr, nsMsgViewIn
m_keys.InsertAt(viewIndex, msgKey);
m_flags.InsertAt(viewIndex, msgFlags);
levelToAdd = FindLevelInThread(msgHdr, startOfThreadViewIndex, viewIndex);
m_levels.InsertAt(viewIndex, levelToAdd);
m_levels.InsertElementAt(viewIndex, levelToAdd);
viewIndex++;
(*pNumListed)++;
}
@@ -5073,7 +5073,7 @@ NS_IMETHODIMP nsMsgDBView::OnAnnouncerGoingAway(nsIDBChangeAnnouncer *instigator
m_keys.RemoveAll();
// be consistent
m_flags.RemoveAll();
m_levels.RemoveAll();
m_levels.Clear();
// tell the tree all the rows have gone away
if (mTree)
@@ -6332,7 +6332,7 @@ nsresult nsMsgDBView::CopyDBView(nsMsgDBView *aNewMsgDBView, nsIMessenger *aMess
aNewMsgDBView->mHeaderParser = mHeaderParser;
aNewMsgDBView->mDeleteModel = mDeleteModel;
aNewMsgDBView->m_flags.CopyArray(m_flags);
aNewMsgDBView->m_levels.CopyArray(m_levels);
aNewMsgDBView->m_levels = m_levels;
aNewMsgDBView->m_keys.CopyArray(m_keys);
return NS_OK;

View File

@@ -48,7 +48,6 @@
#include "nsIMsgHdr.h"
#include "nsMsgLineBuffer.h" // for nsByteArray
#include "nsMsgKeyArray.h"
#include "nsUint8Array.h"
#include "nsIDBChangeListener.h"
#include "nsITreeView.h"
#include "nsITreeBoxObject.h"
@@ -349,7 +348,7 @@ protected:
void ClearHdrCache();
nsMsgKeyArray m_keys;
nsUInt32Array m_flags;
nsUint8Array m_levels;
nsTArray<PRUint8> m_levels;
nsMsgImapDeleteModel mDeleteModel;
// cache the most recently asked for header and corresponding msgKey.

View File

@@ -327,7 +327,7 @@ nsMsgGroupThread *nsMsgGroupView::AddHdrToThread(nsIMsgDBHdr *msgHdr, PRBool *pN
insertIndex = m_keys.GetSize();
m_keys.InsertAt(insertIndex, msgKey);
m_flags.InsertAt(insertIndex, msgFlags | MSG_VIEW_FLAG_ISTHREAD | MSG_FLAG_ELIDED);
m_levels.InsertAt(insertIndex, 0, 1);
m_levels.InsertElementAt(insertIndex, 0);
// if grouped by date, insert dummy header for "age"
if (GroupViewUsesDummyRow())
{
@@ -435,7 +435,7 @@ nsresult nsMsgGroupView::HandleDayChange()
m_keys.RemoveAll();
// be consistent
m_flags.RemoveAll();
m_levels.RemoveAll();
m_levels.Clear();
// this needs to happen after we remove all the keys, since RowCountChanged() will call our GetRowCount()
if (mTree)
@@ -517,12 +517,11 @@ nsresult nsMsgGroupView::OnNewHeader(nsIMsgDBHdr *newHdr, nsMsgKey aParentKey, P
m_flags.InsertAt(threadIndex + msgIndexInThread, msgFlags);
if (msgIndexInThread > 0)
{
m_levels.InsertAt(threadIndex + msgIndexInThread, 1);
m_levels.InsertElementAt(threadIndex + msgIndexInThread, 1);
}
else // insert new header at level 0, and bump old level 0 to 1
{
m_levels.InsertAt(threadIndex, 0, 1);
m_levels.SetAt(threadIndex + 1, 1);
m_levels.InsertElementAt(threadIndex + 1, 1);
}
}
// the call to NoteChange() has to happen after we add the key

View File

@@ -306,7 +306,7 @@ nsMsgQuickSearchDBView::OnNewSearch()
PRInt32 oldSize = GetSize();
m_keys.RemoveAll();
m_levels.RemoveAll();
m_levels.Clear();
m_flags.RemoveAll();
m_hdrHits.Clear();
// this needs to happen after we remove all the keys, since RowCountChanged() will call our GetRowCount()
@@ -453,7 +453,7 @@ nsresult nsMsgQuickSearchDBView::SortThreads(nsMsgViewSortTypeValue sortType, ns
threadRootIds.CopyArray(m_keys);
}
m_keys.RemoveAll();
m_levels.RemoveAll();
m_levels.Clear();
m_flags.RemoveAll();
// now we've build up the list of thread ids - need to build the view
// from that. So for each thread id, we need to list the messages in the thread.
@@ -477,7 +477,7 @@ nsresult nsMsgQuickSearchDBView::SortThreads(nsMsgViewSortTypeValue sortType, ns
rootFlags |= MSG_VIEW_FLAG_ISTHREAD;
m_keys.Add(rootKey);
m_flags.Add(rootFlags);
m_levels.Add(0);
m_levels.AppendElement(0);
nsMsgViewIndex startOfThreadViewIndex = m_keys.GetSize() - 1;
PRUint32 numListed;
@@ -526,7 +526,7 @@ nsresult nsMsgQuickSearchDBView::ListIdsInThread(nsIMsgThread *threadHdr, nsMsg
m_flags.SetAt(startOfThreadViewIndex, rootFlags);
}
levelToAdd = FindLevelInThread(msgHdr, startOfThreadViewIndex, viewIndex);
m_levels.InsertAt(viewIndex, levelToAdd);
m_levels.InsertElementAt(viewIndex, levelToAdd);
viewIndex++;
(*pNumListed)++;
}

View File

@@ -192,7 +192,7 @@ nsresult nsMsgSearchDBView::AddHdrFromFolder(nsIMsgDBHdr *msgHdr, nsISupports *f
{
msgHdr->GetFlags(&msgFlags);
m_keys.Add(msgKey);
m_levels.Add(0);
m_levels.AppendElement(0);
m_flags.Add(msgFlags);
// this needs to be called after we add the key, since RowCountChanged() will call our GetRowCount()
@@ -252,7 +252,7 @@ nsMsgSearchDBView::OnNewSearch()
m_folders->Clear();
m_keys.RemoveAll();
m_levels.RemoveAll();
m_levels.Clear();
m_flags.RemoveAll();
// needs to happen after we remove the keys, since RowCountChanged() will call our GetRowCount()

View File

@@ -127,10 +127,10 @@ nsresult nsMsgThreadedDBView::InitThreadedView(PRInt32 *pCount)
m_keys.RemoveAll();
m_flags.RemoveAll();
m_levels.RemoveAll();
m_levels.Clear();
m_prevKeys.RemoveAll();
m_prevFlags.RemoveAll();
m_prevLevels.RemoveAll();
m_prevLevels.Clear();
m_havePrevView = PR_FALSE;
nsresult getSortrv = NS_OK; // ### TODO m_db->GetSortInfo(&sortType, &sortOrder);
@@ -188,7 +188,7 @@ nsresult nsMsgThreadedDBView::SortThreads(nsMsgViewSortTypeValue sortType, nsMsg
}
m_keys.SetSize(numThreads);
m_flags.SetSize(numThreads);
m_levels.SetSize(numThreads);
m_levels.SetLength(numThreads);
//m_viewFlags &= ~nsMsgViewFlagsType::kThreadedDisplay;
m_sortType = nsMsgViewSortType::byNone; // sort from scratch
nsMsgDBView::Sort(sortType, sortOrder);
@@ -240,7 +240,7 @@ nsresult nsMsgThreadedDBView::AddKeys(nsMsgKey *pKeys, PRInt32 *pFlags, const ch
// Allocate enough space first to avoid memory allocation/deallocation.
m_keys.AllocateSpace(numKeysToAdd+m_keys.GetSize());
m_flags.AllocateSpace(numKeysToAdd+m_flags.GetSize());
m_levels.AllocateSpace(numKeysToAdd+m_levels.GetSize());
m_levels.SetCapacity(m_levels.Length() + numKeysToAdd);
for (PRInt32 i = 0; i < numKeysToAdd; i++)
{
PRInt32 threadFlag = pFlags[i];
@@ -257,7 +257,7 @@ nsresult nsMsgThreadedDBView::AddKeys(nsMsgKey *pKeys, PRInt32 *pFlags, const ch
flag |= MSG_VIEW_FLAG_ISTHREAD;
m_keys.Add(pKeys[i]);
m_flags.Add(flag);
m_levels.Add(pLevels[i]);
m_levels.AppendElement(pLevels[i]);
numAdded++;
// we expand as we build the view, which allows us to insert at the end of the key array,
// instead of the middle, and is much faster.
@@ -311,8 +311,7 @@ NS_IMETHODIMP nsMsgThreadedDBView::Sort(nsMsgViewSortTypeValue sortType, nsMsgVi
m_keys.InsertAt(0, &m_prevKeys);
m_flags.RemoveAll();
m_flags.InsertAt(0, &m_prevFlags);
m_levels.RemoveAll();
m_levels.InsertAt(0, &m_prevLevels);
m_levels = m_prevLevels;
m_sortValid = PR_TRUE;
// the sort may have changed the number of rows
@@ -357,8 +356,7 @@ NS_IMETHODIMP nsMsgThreadedDBView::Sort(nsMsgViewSortTypeValue sortType, nsMsgVi
m_prevKeys.InsertAt(0, &m_keys);
m_prevFlags.RemoveAll();
m_prevFlags.InsertAt(0, &m_flags);
m_prevLevels.RemoveAll();
m_prevLevels.InsertAt(0, &m_levels);
m_prevLevels = m_levels;
// do this before we sort, so that we'll use the cheap method
// of expanding.
m_viewFlags &= ~(nsMsgViewFlagsType::kThreadedDisplay | nsMsgViewFlagsType::kGroupBySort);
@@ -542,7 +540,7 @@ void nsMsgThreadedDBView::OnHeaderAddedOrDeleted()
void nsMsgThreadedDBView::ClearPrevIdArray()
{
m_prevKeys.RemoveAll();
m_prevLevels.RemoveAll();
m_prevLevels.Clear();
m_prevFlags.RemoveAll();
m_havePrevView = PR_FALSE;
}
@@ -630,7 +628,7 @@ nsresult nsMsgThreadedDBView::OnNewHeader(nsIMsgDBHdr *newHdr, nsMsgKey aParentK
}
m_keys.InsertAt(insertIndex, newKey);
m_flags.InsertAt(insertIndex, newFlags, 1);
m_levels.InsertAt(insertIndex, level);
m_levels.InsertElementAt(insertIndex, level);
// the call to NoteChange() has to happen after we add the key
// as NoteChange() will call RowCountChanged() which will call our GetRowCount()
@@ -770,7 +768,7 @@ nsresult nsMsgThreadedDBView::RemoveByIndex(nsMsgViewIndex index)
if (numThreadChildren > 1)
flag |= MSG_VIEW_FLAG_ISTHREAD | MSG_VIEW_FLAG_HASCHILDREN;
m_flags.SetAtGrow(index, flag);
m_levels.SetAtGrow(index, 0);
m_levels[index] = 0;
}
}
}

View File

@@ -79,7 +79,7 @@ protected:
PRBool m_havePrevView;
nsMsgKeyArray m_prevKeys; //this is used for caching non-threaded view.
nsUInt32Array m_prevFlags;
nsUint8Array m_prevLevels;
nsTArray<PRUint8> m_prevLevels;
nsCOMPtr <nsISimpleEnumerator> m_threadEnumerator;
};

View File

@@ -163,7 +163,7 @@ nsresult nsMsgXFVirtualFolderDBView::InsertHdrFromFolder(nsIMsgDBHdr *msgHdr, ns
m_keys.InsertAt(insertIndex, msgKey);
m_flags.InsertAt(insertIndex, msgFlags);
m_folders->InsertElementAt(folder, insertIndex);
m_levels.InsertAt((PRInt32) insertIndex, (PRUint8) 0);
m_levels.InsertElementAt(insertIndex, 0);
// the call to NoteChange() has to happen after we add the key
// as NoteChange() will call RowCountChanged() which will call our GetRowCount()
@@ -322,7 +322,7 @@ nsMsgXFVirtualFolderDBView::OnNewSearch()
m_folders->Clear();
m_keys.RemoveAll();
m_levels.RemoveAll();
m_levels.Clear();
m_flags.RemoveAll();
// needs to happen after we remove the keys, since RowCountChanged() will call our GetRowCount()

View File

@@ -94,7 +94,6 @@ REQUIRES = xpcom \
CPPSRCS = \
nsMsgLineBuffer.cpp \
nsMsgDBFolder.cpp \
nsUint8Array.cpp \
nsUInt32Array.cpp \
nsMsgKeySet.cpp \
nsMsgKeyArray.cpp \
@@ -112,7 +111,6 @@ CPPSRCS = \
EXPORTS = \
nsMsgLineBuffer.h \
nsUint8Array.h \
nsUInt32Array.h \
nsMsgKeySet.h \
nsMsgKeyArray.h \

View File

@@ -1,263 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "msgCore.h"
#include "nsUint8Array.h"
nsUint8Array::nsUint8Array()
{
m_pData = nsnull;
m_nSize = m_nMaxSize = m_nGrowBy = 0;
}
nsUint8Array::~nsUint8Array()
{
PR_Free(m_pData);
}
void nsUint8Array::SetSize(PRInt32 nNewSize, PRInt32 nGrowBy)
{
// AssertValid(this);
NS_ASSERTION(nNewSize >= 0, "can't set size to negative value");
if (nGrowBy != -1)
m_nGrowBy = nGrowBy; // set new size
if (nNewSize == 0)
{
// shrink to nothing
PR_Free(m_pData);
m_pData = nsnull;
m_nSize = m_nMaxSize = 0;
}
else if (m_pData == nsnull)
{
// create one with exact size
m_pData = (PRUint8*)PR_Malloc(nNewSize * sizeof(PRUint8));
memset(m_pData, 0, nNewSize * sizeof(PRUint8)); // zero fill
m_nSize = m_nMaxSize = nNewSize;
}
else if (nNewSize <= m_nMaxSize)
{
// it fits
if (nNewSize > m_nSize)
{
// initialize the new elements
memset(&m_pData[m_nSize], 0, (nNewSize-m_nSize) * sizeof(PRUint8));
}
m_nSize = nNewSize;
}
else
{
// otherwise, grow array
PRInt32 nGrowBy = m_nGrowBy;
if (nGrowBy == 0)
{
nGrowBy = PR_MIN(1024, PR_MAX(4, m_nSize / 8));
}
PRInt32 nNewMax;
if (nNewSize < m_nMaxSize + nGrowBy)
nNewMax = m_nMaxSize + nGrowBy; // granularity
else
nNewMax = nNewSize; // no slush
NS_ASSERTION(nNewMax >= m_nMaxSize, "no wraparound"); // no wrap around
PRUint8* pNewData = (PRUint8*)PR_Malloc(nNewMax * sizeof(PRUint8));
// copy new data from old
memcpy(pNewData, m_pData, m_nSize * sizeof(PRUint8));
NS_ASSERTION(nNewSize > m_nSize, "did't grow size");
memset(&pNewData[m_nSize], 0, (nNewSize-m_nSize) * sizeof(PRUint8));
PR_Free(m_pData);
m_pData = pNewData;
m_nSize = nNewSize;
m_nMaxSize = nNewMax;
}
}
void nsUint8Array::FreeExtra()
{
if (m_nSize != m_nMaxSize)
{
// shrink to desired size
PRUint8* pNewData = nsnull;
if (m_nSize != 0)
{
pNewData = (PRUint8*)PR_Malloc(m_nSize * sizeof(PRUint8));
// copy new data from old
memcpy(pNewData, m_pData, m_nSize * sizeof(PRUint8));
}
// get rid of old stuff (note: no destructors called)
PR_Free(m_pData);
m_pData = pNewData;
m_nMaxSize = m_nSize;
}
}
void nsUint8Array::CopyArray(nsUint8Array &aSrcArray)
{
PR_FREEIF(m_pData);
m_nSize = aSrcArray.m_nSize;
m_nMaxSize = aSrcArray.m_nSize;
m_pData = (PRUint8*)PR_Malloc(m_nSize * sizeof(PRUint8));
if (m_pData)
memcpy(m_pData, aSrcArray.m_pData, m_nSize * sizeof(PRUint8));
}
/////////////////////////////////////////////////////////////////////////////
void nsUint8Array::SetAtGrow(PRInt32 nIndex, PRUint8 newElement)
{
NS_ASSERTION(nIndex >= 0, "can't insert at negative index");
if (nIndex >= m_nSize)
SetSize(nIndex+1);
m_pData[nIndex] = newElement;
}
nsresult nsUint8Array::InsertAt(PRInt32 nIndex, PRUint8 newElement, PRInt32 nCount)
{
NS_ASSERTION(nIndex >= 0, "can't insert at negative index");
NS_ASSERTION(nCount > 0, "have to insert something"); // zero or negative size not allowed
if (nIndex >= m_nSize)
{
// adding after the end of the array
SetSize(nIndex + nCount); // grow so nIndex is valid
}
else
{
// inserting in the middle of the array
PRInt32 nOldSize = m_nSize;
SetSize(m_nSize + nCount); // grow it to new size
// shift old data up to fill gap
memmove(&m_pData[nIndex+nCount], &m_pData[nIndex],
(nOldSize-nIndex) * sizeof(PRUint8));
// re-init slots we copied from
memset(&m_pData[nIndex], 0, nCount * sizeof(PRUint8));
}
// insert new value in the gap
NS_ASSERTION(nIndex + nCount <= m_nSize, "overflow");
while (nCount--)
m_pData[nIndex++] = newElement;
return NS_OK;
}
void nsUint8Array::RemoveAt(PRInt32 nIndex, PRInt32 nCount)
{
if (nIndex < 0 || nCount < 0 || nIndex + nCount > m_nSize)
{
NS_ASSERTION(PR_FALSE, "bad remove index or count");
return;
}
// just remove a range
PRInt32 nMoveCount = m_nSize - (nIndex + nCount);
NS_ASSERTION(nMoveCount >= 0, "can't remove nothing");
if (nMoveCount >= 0)
memmove(&m_pData[nIndex], &m_pData[nIndex + nCount],
nMoveCount * sizeof(PRUint8));
m_nSize -= nCount;
}
nsresult nsUint8Array::InsertAt(PRInt32 nStartIndex, nsUint8Array* pNewArray)
{
NS_ENSURE_ARG(pNewArray);
NS_ASSERTION(nStartIndex >= 0, "start index must be positive");
if (pNewArray->GetSize() > 0)
{
InsertAt(nStartIndex, pNewArray->GetAt(0), pNewArray->GetSize());
for (PRInt32 i = 0; i < pNewArray->GetSize(); i++)
SetAt(nStartIndex + i, pNewArray->GetAt(i));
}
return NS_OK;
}
PRInt32 nsUint8Array::GetSize() const
{ return m_nSize; }
PRInt32 nsUint8Array::GetUpperBound() const
{ return m_nSize-1; }
void nsUint8Array::RemoveAll()
{ SetSize(0); }
PRUint8 nsUint8Array::GetAt(PRInt32 nIndex) const
{ NS_ASSERTION(nIndex >= 0 && nIndex < m_nSize, "out of bounds");
return m_pData[nIndex]; }
void nsUint8Array::SetAt(PRInt32 nIndex, PRUint8 newElement)
{ NS_ASSERTION(nIndex >= 0 && nIndex < m_nSize, "out of bounds");
m_pData[nIndex] = newElement; }
PRUint8& nsUint8Array::ElementAt(PRInt32 nIndex)
{ NS_ASSERTION(nIndex >= 0 && nIndex < m_nSize, "out of bounds");
return m_pData[nIndex]; }
PRInt32 nsUint8Array::Add(PRUint8 newElement)
{ PRInt32 nIndex = m_nSize;
SetAtGrow(nIndex, newElement);
return nIndex; }
PRUint8 nsUint8Array::operator[](PRInt32 nIndex) const
{ return GetAt(nIndex); }
PRUint8& nsUint8Array::operator[](PRInt32 nIndex)
{ return ElementAt(nIndex); }
/////////////////////////////////////////////////////////////////////////////
// Diagnostics
#ifdef _DEBUG
void nsUint8Array::AssertValid() const
{
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////

View File

@@ -1,101 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corp.
* Portions created by the Initial Developer are Copyright (C) 1995
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef _nsUint8Array_H_
#define _nsUint8Array_H_
#include "nscore.h"
#include "prmem.h"
#include "msgCore.h"
class NS_MSG_BASE nsUint8Array
{
public:
// Construction
nsUint8Array();
// Attributes
PRInt32 GetSize() const;
PRInt32 GetUpperBound() const;
void SetSize(PRInt32 nNewSize, PRInt32 nGrowBy = -1);
void AllocateSpace(PRUint32 nNewSize) { if (nNewSize == 0) return; PRInt32 saveSize = m_nSize; SetSize(nNewSize); m_nSize = saveSize;}
// Operations
// Clean up
void FreeExtra();
void RemoveAll();
// Accessing elements
PRUint8 GetAt(PRInt32 nIndex) const;
void SetAt(PRInt32 nIndex, PRUint8 newElement);
PRUint8& ElementAt(PRInt32 nIndex);
// Potentially growing the array
void SetAtGrow(PRInt32 nIndex, PRUint8 newElement);
PRInt32 Add(PRUint8 newElement);
// overloaded operator helpers
PRUint8 operator[](PRInt32 nIndex) const;
PRUint8& operator[](PRInt32 nIndex);
// Operations that move elements around
nsresult InsertAt(PRInt32 nIndex, PRUint8 newElement, PRInt32 nCount = 1);
void RemoveAt(PRInt32 nIndex, PRInt32 nCount = 1);
nsresult InsertAt(PRInt32 nStartIndex, nsUint8Array* pNewArray);
void CopyArray(nsUint8Array &aSrcArray);
// use carefully!
PRUint8* GetArray(void) {return((PRUint8*)m_pData);} // only valid until another function called on the array (like GetBuffer() in CString)
// Implementation
protected:
PRUint8* m_pData; // the actual array of data
PRInt32 m_nSize; // # of elements (upperBound - 1)
PRInt32 m_nMaxSize; // max allocated
PRInt32 m_nGrowBy; // grow amount
public:
~nsUint8Array();
#ifdef _DEBUG
void AssertValid() const;
#endif
};
#endif