📄 contain.cxx
字号:
* Added flag for PStringArray constructor to create caseless strings.
* Fixed bug in arrays when size set to zero.
*
* Revision 1.41 1995/06/04 12:39:59 robertj
* Made char * array all const in PStringArray constructor.
*
* Revision 1.40 1995/04/25 11:29:38 robertj
* Fixed Borland compiler warnings.
*
* Revision 1.39 1995/04/02 09:27:27 robertj
* Added "balloon" help.
*
* Revision 1.38 1995/03/12 04:46:02 robertj
* Fixed use of PCaselessString as dictionary key.
*
* Revision 1.37 1995/01/15 04:56:28 robertj
* Fixed PStringStream for correct pointer calculations in output.
*
* Revision 1.36 1995/01/10 11:44:13 robertj
* Removed PString parameter in stdarg function for GNU C++ compatibility.
*
* Revision 1.35 1995/01/09 12:32:56 robertj
* Removed unnecesary return value from I/O functions.
* Changed function names due to Mac port.
*
* Revision 1.34 1995/01/04 10:57:08 robertj
* Changed for HPUX and GNU2.6.x
*
* Revision 1.33 1995/01/03 09:39:08 robertj
* Put standard malloc style memory allocation etc into memory check system.
*
* Revision 1.32 1994/12/13 11:50:56 robertj
* Added MakeUnique() function to all container classes.
*
* Revision 1.31 1994/12/12 13:13:17 robertj
* Fixed bugs in PString mods just made.
*
* Revision 1.30 1994/12/12 10:16:27 robertj
* Restructuring and documentation of container classes.
* Renaming of some macros for declaring container classes.
* Added some extra functionality to PString.
* Added start to 2 byte characters in PString.
* Fixed incorrect overrides in PCaselessString.
*
* Revision 1.29 1994/12/05 11:19:36 robertj
* Moved SetMinSize from PAbstractArray to PContainer.
*
* Revision 1.28 1994/11/28 12:37:29 robertj
* Added dummy parameter to container classes.
*
* Revision 1.27 1994/10/30 11:50:44 robertj
* Split into Object classes and Container classes.
* Changed mechanism for doing notification callback functions.
*
* Revision 1.26 1994/10/23 03:43:07 robertj
* Changed PBaseArray so can have zero elements in it.
* Added Printf style constructor to PString.
*
* Revision 1.25 1994/09/25 10:49:44 robertj
* Added empty functions for serialisation.
*
* 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 (--reference->count > 0) {
#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
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -