📄 collect.cxx
字号:
/*
* collect.cxx
*
* Container Classes
*
* Portable Windows Library
*
* Copyright (c) 1993-1998 Equivalence Pty. Ltd.
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (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 Portable Windows Library.
*
* The Initial Developer of the Original Code is Equivalence Pty. Ltd.
*
* Portions are Copyright (C) 1993 Free Software Foundation, Inc.
* All Rights Reserved.
*
* Contributor(s): ______________________________________.
*
* $Revision: 19435 $
* $Author: csoutheren $
* $Date: 2008-02-09 06:38:27 +0000 (Sat, 09 Feb 2008) $
*/
#include <ptlib.h>
#ifndef _WIN32_WCE
#define new PNEW
#undef __CLASS__
#define __CLASS__ GetClass()
#endif
///////////////////////////////////////////////////////////////////////////////
void PCollection::PrintOn(ostream &strm) const
{
char separator = strm.fill();
int width = strm.width();
for (PINDEX i = 0; i < GetSize(); i++) {
if (i > 0 && separator != ' ')
strm << separator;
PObject * obj = GetAt(i);
if (obj != NULL) {
if (separator != ' ')
strm.width(width);
strm << *obj;
}
}
if (separator == '\n')
strm << '\n';
}
void PCollection::RemoveAll()
{
while (GetSize() > 0)
RemoveAt(0);
}
///////////////////////////////////////////////////////////////////////////////
void PArrayObjects::CopyContents(const PArrayObjects & array)
{
theArray = array.theArray;
}
void PArrayObjects::DestroyContents()
{
if (reference->deleteObjects && theArray != NULL) {
for (PINDEX i = 0; i < theArray->GetSize(); i++) {
if ((*theArray)[i] != NULL)
delete (*theArray)[i];
}
}
delete theArray;
theArray = NULL;
}
void PArrayObjects::RemoveAll()
{
SetSize(0);
}
void PArrayObjects::CloneContents(const PArrayObjects * array)
{
PBaseArray<PObject *> & oldArray = *array->theArray;
theArray = new PBaseArray<PObject *>(oldArray.GetSize());
for (PINDEX i = 0; i < GetSize(); i++) {
PObject * ptr = oldArray[i];
if (ptr != NULL)
SetAt(i, ptr->Clone());
}
}
PObject::Comparison PArrayObjects::Compare(const PObject & obj) const
{
PAssert(PIsDescendant(&obj, PArrayObjects), PInvalidCast);
const PArrayObjects & other = (const PArrayObjects &)obj;
PINDEX i;
for (i = 0; i < GetSize(); i++) {
if (i >= other.GetSize() || *(*theArray)[i] < *(*other.theArray)[i])
return LessThan;
if (*(*theArray)[i] > *(*other.theArray)[i])
return GreaterThan;
}
return i < other.GetSize() ? GreaterThan : EqualTo;
}
PINDEX PArrayObjects::GetSize() const
{
return theArray->GetSize();
}
PBoolean PArrayObjects::SetSize(PINDEX newSize)
{
PINDEX sz = theArray->GetSize();
if (reference->deleteObjects && sz > 0) {
for (PINDEX i = sz; i > newSize; i--) {
PObject * obj = theArray->GetAt(i-1);
if (obj != NULL)
delete obj;
}
}
return theArray->SetSize(newSize);
}
PINDEX PArrayObjects::Append(PObject * obj)
{
PINDEX where = GetSize();
SetAt(where, obj);
return where;
}
PINDEX PArrayObjects::Insert(const PObject & before, PObject * obj)
{
PINDEX where = GetObjectsIndex(&before);
InsertAt(where, obj);
return where;
}
PBoolean PArrayObjects::Remove(const PObject * obj)
{
PINDEX i = GetObjectsIndex(obj);
if (i == P_MAX_INDEX)
return PFalse;
RemoveAt(i);
return PTrue;
}
PObject * PArrayObjects::GetAt(PINDEX index) const
{
return (*theArray)[index];
}
PBoolean PArrayObjects::SetAt(PINDEX index, PObject * obj)
{
if (!theArray->SetMinSize(index+1))
return PFalse;
PObject * oldObj = theArray->GetAt(index);
if (oldObj != NULL && reference->deleteObjects)
delete oldObj;
(*theArray)[index] = obj;
return PTrue;
}
PINDEX PArrayObjects::InsertAt(PINDEX index, PObject * obj)
{
for (PINDEX i = GetSize(); i > index; i--)
(*theArray)[i] = (*theArray)[i-1];
(*theArray)[index] = obj;
return index;
}
PObject * PArrayObjects::RemoveAt(PINDEX index)
{
PObject * obj = (*theArray)[index];
PINDEX size = GetSize()-1;
PINDEX i;
for (i = index; i < size; i++)
(*theArray)[i] = (*theArray)[i+1];
(*theArray)[i] = NULL;
SetSize(size);
if (obj != NULL && reference->deleteObjects) {
delete obj;
obj = NULL;
}
return obj;
}
PINDEX PArrayObjects::GetObjectsIndex(const PObject * obj) const
{
for (PINDEX i = 0; i < GetSize(); i++) {
if ((*theArray)[i] == obj)
return i;
}
return P_MAX_INDEX;
}
PINDEX PArrayObjects::GetValuesIndex(const PObject & obj) const
{
for (PINDEX i = 0; i < GetSize(); i++) {
PObject * elmt = (*theArray)[i];
if (elmt != NULL && *elmt == obj)
return i;
}
return P_MAX_INDEX;
}
///////////////////////////////////////////////////////////////////////////////
void PAbstractList::DestroyContents()
{
RemoveAll();
delete info;
info = NULL;
}
void PAbstractList::CopyContents(const PAbstractList & list)
{
info = list.info;
}
void PAbstractList::CloneContents(const PAbstractList * list)
{
Element * element = list->info->head;
info = new PListInfo;
PAssert(info != NULL, POutOfMemory);
while (element != NULL) {
Element * newElement = new Element(element->data->Clone());
if (info->head == NULL)
info->head = info->tail = newElement;
else {
newElement->prev = info->tail;
info->tail->next = newElement;
info->tail = newElement;
}
element = element->next;
}
}
PObject::Comparison PAbstractList::Compare(const PObject & obj) const
{
PAssert(PIsDescendant(&obj, PAbstractList), PInvalidCast);
Element * elmt1 = info->head;
Element * elmt2 = ((const PAbstractList &)obj).info->head;
while (elmt1 != NULL && elmt2 != NULL) {
if (elmt1 == NULL)
return LessThan;
if (elmt2 == NULL)
return GreaterThan;
if (*elmt1->data < *elmt2->data)
return LessThan;
if (*elmt1->data > *elmt2->data)
return GreaterThan;
elmt1 = elmt1->next;
elmt2 = elmt2->next;
}
return EqualTo;
}
PBoolean PAbstractList::SetSize(PINDEX)
{
return PTrue;
}
PINDEX PAbstractList::Append(PObject * obj)
{
if (PAssertNULL(obj) == NULL)
return P_MAX_INDEX;
Element * element = new Element(obj);
if (info->tail != NULL)
info->tail->next = element;
element->prev = info->tail;
element->next = NULL;
if (info->head == NULL)
info->head = element;
info->tail = element;
PINDEX lastIndex = GetSize();
reference->size++;
return lastIndex;
}
PINDEX PAbstractList::Insert(const PObject & before, PObject * obj)
{
if (PAssertNULL(obj) == NULL)
return P_MAX_INDEX;
PINDEX where = GetObjectsIndex(&before);
InsertAt(where, obj);
return where;
}
PINDEX PAbstractList::InsertAt(PINDEX index, PObject * obj)
{
if (PAssertNULL(obj) == NULL)
return P_MAX_INDEX;
if (index >= GetSize())
return Append(obj);
Element * lastElement;
PAssert(SetCurrent(index, lastElement), PInvalidArrayIndex);
Element * newElement = new Element(obj);
if (lastElement->prev != NULL)
lastElement->prev->next = newElement;
else
info->head = newElement;
newElement->prev = lastElement->prev;
newElement->next = lastElement;
lastElement->prev = newElement;
reference->size++;
return index;
}
PBoolean PAbstractList::Remove(const PObject * obj)
{
if (info == NULL){
PAssertAlways("info is null");
return false;
}
Element * elmt = info->head;
while (elmt != NULL) {
if (elmt->data == obj) {
RemoveElement(elmt);
return true;
}
elmt = elmt->next;
}
return false;
}
PObject * PAbstractList::RemoveAt(PINDEX index)
{
if (info == NULL){
PAssertAlways("info is null");
return NULL;
}
Element * elmt;
if (!SetCurrent(index, elmt)) {
PAssertAlways(PInvalidArrayIndex);
return NULL;
}
return RemoveElement(elmt);
}
PObject * PAbstractList::RemoveElement(PListElement * elmt)
{
if (elmt == NULL){
PAssertAlways("elmt is null");
return NULL;
}
if (elmt->prev != NULL)
elmt->prev->next = elmt->next;
else {
info->head = elmt->next;
if (info->head != NULL)
info->head->prev = NULL;
}
if (elmt->next != NULL)
elmt->next->prev = elmt->prev;
else {
info->tail = elmt->prev;
if (info->tail != NULL)
info->tail->next = NULL;
}
if((reference == NULL) || (reference->size == 0)){
PAssertAlways("reference is null or reference->size == 0");
return NULL;
}
reference->size--;
PObject * obj = elmt->data;
if (obj != NULL && reference->deleteObjects) {
delete obj;
obj = NULL;
}
delete elmt;
return obj;
}
PObject * PAbstractList::GetAt(PINDEX index) const
{
Element * lastElement;
return SetCurrent(index, lastElement) ? lastElement->data : (PObject *)NULL;
}
PBoolean PAbstractList::SetAt(PINDEX index, PObject * val)
{
Element * lastElement;
if (!SetCurrent(index, lastElement))
return PFalse;
lastElement->data = val;
return PTrue;
}
PBoolean PAbstractList::ReplaceAt(PINDEX index, PObject * val)
{
Element * lastElement;
if (!SetCurrent(index, lastElement))
return PFalse;
if (lastElement->data != NULL && reference->deleteObjects) {
delete lastElement->data;
}
lastElement->data = val;
return PTrue;
}
PINDEX PAbstractList::GetObjectsIndex(const PObject * obj) const
{
PINDEX index = 0;
Element * element = info->head;
while (element != NULL) {
if (element->data == obj)
return index;
element = element->next;
index++;
}
return P_MAX_INDEX;
}
PINDEX PAbstractList::GetValuesIndex(const PObject & obj) const
{
PINDEX index = 0;
Element * element = info->head;
while (element != NULL) {
if (*element->data == obj)
return index;
element = element->next;
index++;
}
return P_MAX_INDEX;
}
PBoolean PAbstractList::SetCurrent(PINDEX index, Element * & lastElement) const
{
if (index >= GetSize())
return PFalse;
PINDEX lastIndex;
if (index < GetSize()/2) {
lastIndex = 0;
lastElement = info->head;
}
else {
lastIndex = GetSize()-1;
lastElement = info->tail;
}
while (lastIndex < index) {
lastElement = lastElement->next;
++lastIndex;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -