📄 contain.cxx
字号:
* * Revision 1.24 1994/08/21 23:43:02 robertj * Added object serialisation classes. * Changed parameter before variable argument list to NOT be a reference. * * Revision 1.23 1994/08/04 12:57:10 robertj * Rewrite of memory check code. * * Revision 1.22 1994/08/01 03:40:28 robertj * Fixed PString() constructor from integer * * Revision 1.21 1994/07/27 05:58:07 robertj * Synchronisation. * * Revision 1.20 1994/07/25 03:38:38 robertj * Added more memory tests. * * Revision 1.19 1994/07/17 10:46:06 robertj * Added number conversions to PString. * * Revision 1.18 1994/06/25 11:55:15 robertj * Unix version synchronisation. * * Revision 1.17 1994/04/20 12:17:44 robertj * assert changes * * Revision 1.16 1994/04/11 12:08:37 robertj * Fixed bug in memory leak hash table hash function, cant have negative numbers. * * Revision 1.15 1994/04/03 08:34:18 robertj * Added help and focus functionality. * * Revision 1.14 1994/04/01 14:01:11 robertj * Streams and stuff. * * Revision 1.13 1994/03/07 07:47:00 robertj * Major upgrade * * Revision 1.12 1994/01/15 03:14:22 robertj * Mac portability problems. * * Revision 1.11 1994/01/03 04:42:23 robertj * Mass changes to common container classes and interactors etc etc etc. * * Revision 1.10 1993/12/31 06:53:02 robertj * Made inlines optional for debugging purposes. * * Revision 1.9 1993/12/24 04:20:52 robertj * Mac CFront port. * * Revision 1.8 1993/12/16 00:51:46 robertj * Made some container functions const. * * Revision 1.7 1993/12/15 21:10:10 robertj * Fixed reference system used by container classes. * Plugged memory leaks in PList and PSortedList. * * Revision 1.6 1993/12/14 18:44:56 robertj * Added RemoveAll() function to collections. * Fixed bug in list processing when being destroyed (removes the item being * deleted from the list before deleting it). * Changed GetIndex() so does not assert if entry not in collection. * * Revision 1.5 1993/12/04 05:22:38 robertj * Added more string functions. * * Revision 1.4 1993/09/27 16:35:25 robertj * Fixed bugs in sorted list. * Fixed compatibility problem with sprintf return value (SVR4). * Change function for making string array to a constructor. * * Revision 1.3 1993/08/27 18:17:47 robertj * Fixed bugs in PAbstractSortedList (including some formatting). * * Revision 1.2 1993/08/21 01:50:33 robertj * Made Clone() function optional, default will assert if called. * * Revision 1.8 1993/08/01 14:05:27 robertj * Added const to ToLower() and ToUpper() in the PString class. * * Revision 1.7 1993/07/16 14:40:55 robertj * Added PString constructor for individual characters. * Added string to C style literal format. * * Revision 1.6 1993/07/15 05:02:57 robertj * Removed redundant word in PString enum for string types. * * Revision 1.5 1993/07/15 04:29:39 robertj * Added new constructor to convert from other string formats. * Fixed sprintf variable parameter list bug. * * Revision 1.4 1993/07/14 12:41:52 robertj * Fixed comment leader. * * Revision 1.3 1993/07/14 02:06:34 robertj * Fixed header comment for RCS. */#include <ptlib.h>#include <ctype.h>#ifdef __NUCLEUS_PLUS__extern "C" int vsprintf(char *, const char *, va_list);#endif#if P_REGEX#include <regex.h>#else#include "regex/regex.h"#endif#define regexpression ((regex_t *)expression)#if !P_USE_INLINES#include "ptlib/contain.inl"#endif#define new PNEW#undef __CLASS__#define __CLASS__ GetClass()///////////////////////////////////////////////////////////////////////////////PContainer::PContainer(PINDEX initialSize){ reference = new Reference(initialSize); PAssert(reference != NULL, POutOfMemory);}PContainer::PContainer(int, const PContainer * cont){ PAssert(cont != NULL, PInvalidParameter); PAssert2(cont->reference != NULL, cont->GetClass(), "Clone of deleted container");#if PCONTAINER_USES_CRITSEC PEnterAndLeave m(cont->reference->critSec);#endif reference = new Reference(*cont->reference); // create a new reference PAssert(reference != NULL, POutOfMemory);}PContainer::PContainer(const PContainer & cont){ PAssert2(cont.reference != NULL, cont.GetClass(), "Copy of deleted container");#if PCONTAINER_USES_CRITSEC PEnterAndLeave m(cont.reference->critSec);#endif ++cont.reference->count; reference = cont.reference; // copy the reference pointer}void PContainer::AssignContents(const PContainer & cont){#if PCONTAINER_USES_CRITSEC // make sure the critsecs are entered and left in the right order to avoid deadlock cont.reference->critSec.Enter(); reference->critSec.Enter();#endif PAssert2(cont.reference != NULL, cont.GetClass(), "Assign of deleted container"); if (reference == cont.reference) {#if PCONTAINER_USES_CRITSEC reference->critSec.Leave(); cont.reference->critSec.Leave();#endif return; } if (!IsUnique()) { --reference->count;#if PCONTAINER_USES_CRITSEC reference->critSec.Leave();#endif } else {#if PCONTAINER_USES_CRITSEC reference->critSec.Leave();#endif DestroyContents(); delete reference; reference = NULL; } ++cont.reference->count; reference = cont.reference;#if PCONTAINER_USES_CRITSEC cont.reference->critSec.Leave();#endif}void PContainer::Destruct(){ if (reference != NULL) {#if PCONTAINER_USES_CRITSEC Reference * ref = reference; ref->critSec.Enter();#endif --reference->count; if (reference->count > 0) { reference = NULL;#if PCONTAINER_USES_CRITSEC ref->critSec.Leave();#endif } else {#if PCONTAINER_USES_CRITSEC ref->critSec.Leave();#endif DestroyContents(); delete reference; reference = NULL; } }}BOOL PContainer::SetMinSize(PINDEX minSize){ PASSERTINDEX(minSize); if (minSize < 0) minSize = 0; if (minSize < GetSize()) minSize = GetSize(); return SetSize(minSize);}BOOL PContainer::MakeUnique(){#if PCONTAINER_USES_CRITSEC PEnterAndLeave m(reference->critSec);#endif if (IsUnique()) return TRUE; Reference * oldReference = reference; reference = new Reference(*reference); --oldReference->count; return FALSE;}///////////////////////////////////////////////////////////////////////////////PAbstractArray::PAbstractArray(PINDEX elementSizeInBytes, PINDEX initialSize) : PContainer(initialSize){ elementSize = elementSizeInBytes; PAssert(elementSize != 0, PInvalidParameter); if (GetSize() == 0) theArray = NULL; else { theArray = (char *)calloc(GetSize(), elementSize); PAssert(theArray != NULL, POutOfMemory); } allocatedDynamically = TRUE;}PAbstractArray::PAbstractArray(PINDEX elementSizeInBytes, const void *buffer, PINDEX bufferSizeInElements, BOOL dynamicAllocation) : PContainer(bufferSizeInElements){ elementSize = elementSizeInBytes; PAssert(elementSize != 0, PInvalidParameter); allocatedDynamically = dynamicAllocation; if (GetSize() == 0) theArray = NULL; else if (dynamicAllocation) { PINDEX sizebytes = elementSize*GetSize(); theArray = (char *)malloc(sizebytes); PAssert(theArray != NULL, POutOfMemory); memcpy(theArray, PAssertNULL(buffer), sizebytes); } else theArray = (char *)buffer;}void PAbstractArray::DestroyContents(){ if (theArray != NULL) { if (allocatedDynamically) free(theArray); theArray = NULL; }}void PAbstractArray::CopyContents(const PAbstractArray & array){ elementSize = array.elementSize; theArray = array.theArray; allocatedDynamically = array.allocatedDynamically;}void PAbstractArray::CloneContents(const PAbstractArray * array){ elementSize = array->elementSize; PINDEX sizebytes = elementSize*GetSize(); char * newArray = (char *)malloc(sizebytes); if (newArray == NULL) reference->size = 0; else memcpy(newArray, array->theArray, sizebytes); theArray = newArray; allocatedDynamically = TRUE;}void PAbstractArray::PrintOn(ostream & strm) const{ char separator = strm.fill(); int width = strm.width(); for (PINDEX i = 0; i < GetSize(); i++) { if (i > 0 && separator != '\0') strm << separator; strm.width(width); PrintElementOn(strm, i); } if (separator == '\n') strm << '\n';}void PAbstractArray::ReadFrom(istream & strm){ PINDEX i = 0; while (strm.good()) { ReadElementFrom(strm, i); if (!strm.fail()) i++; } SetSize(i);}PObject::Comparison PAbstractArray::Compare(const PObject & obj) const{ PAssert(PIsDescendant(&obj, PAbstractArray), PInvalidCast); const PAbstractArray & other = (const PAbstractArray &)obj; char * otherArray = other.theArray; if (theArray == otherArray) return EqualTo; if (elementSize < other.elementSize) return LessThan; if (elementSize > other.elementSize) return GreaterThan; PINDEX thisSize = GetSize(); PINDEX otherSize = other.GetSize(); if (thisSize < otherSize) return LessThan; if (thisSize > otherSize) return GreaterThan; if (thisSize == 0) return EqualTo; int retval = memcmp(theArray, otherArray, elementSize*thisSize); if (retval < 0) return LessThan; if (retval > 0) return GreaterThan; return EqualTo;}BOOL PAbstractArray::SetSize(PINDEX newSize){ return InternalSetSize(newSize, FALSE);}BOOL PAbstractArray::InternalSetSize(PINDEX newSize, BOOL force){ if (newSize < 0) newSize = 0; PINDEX newsizebytes = elementSize*newSize; PINDEX oldsizebytes = elementSize*GetSize(); if (!force && (newsizebytes == oldsizebytes)) return TRUE; char * newArray;#if PCONTAINER_USES_CRITSEC PEnterAndLeave m(reference->critSec);#endif if (!IsUnique()) { if (newsizebytes == 0) newArray = NULL; else { if ((newArray = (char *)malloc(newsizebytes)) == NULL) return FALSE; if (theArray != NULL) memcpy(newArray, theArray, PMIN(oldsizebytes, newsizebytes)); } --reference->count; reference = new Reference(newSize); } else { if (theArray != NULL) { if (newsizebytes == 0) { if (allocatedDynamically) free(theArray); newArray = NULL; } else if (allocatedDynamically) { if ((newArray = (char *)realloc(theArray, newsizebytes)) == NULL) return FALSE; } else { if ((newArray = (char *)malloc(newsizebytes)) == NULL) return FALSE; memcpy(newArray, theArray, PMIN(newsizebytes, oldsizebytes)); allocatedDynamically = TRUE; } } else if (newsizebytes != 0) { if ((newArray = (char *)malloc(newsizebytes)) == NULL) return FALSE; } else newArray = NULL; reference->size = newSize; } if (newsizebytes > oldsizebytes) memset(newArray+oldsizebytes, 0, newsizebytes-oldsizebytes); theArray = newArray; return TRUE;}void PAbstractArray::Attach(const void *buffer, PINDEX bufferSize){ if (allocatedDynamically && theArray != NULL) free(theArray);#if PCONTAINER_USES_CRITSEC PEnterAndLeave m(reference->critSec);#endif theArray = (char *)buffer; reference->size = bufferSize; allocatedDynamically = FALSE;}void * PAbstractArray::GetPointer(PINDEX minSize){ PAssert(SetMinSize(minSize), POutOfMemory); return theArray;}BOOL PAbstractArray::Concatenate(const PAbstractArray & array){ if (!allocatedDynamically || array.elementSize != elementSize) return FALSE; PINDEX oldLen = GetSize(); PINDEX addLen = array.GetSize(); if (!SetSize(oldLen + addLen)) return FALSE; memcpy(theArray+oldLen*elementSize, array.theArray, addLen*elementSize); return TRUE;}void PAbstractArray::PrintElementOn(ostream & /*stream*/, PINDEX /*index*/) const{}void PAbstractArray::ReadElementFrom(istream & /*stream*/, PINDEX /*index*/){}///////////////////////////////////////////////////////////////////////////////void PCharArray::PrintOn(ostream & strm) const{ PINDEX width = strm.width(); if (width > GetSize()) width -= GetSize(); else width = 0; BOOL left = (strm.flags()&ios::adjustfield) == ios::left; if (left)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -