00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifndef _ARRAY_H_
00035 #define _ARRAY_H_
00036
00037 #ifdef P_USE_PRAGMA
00038 #pragma interface
00039 #endif
00040
00041 #include <ptlib/contain.h>
00042
00044
00045
00067 class PAbstractArray : public PContainer
00068 {
00069 PCONTAINERINFO(PAbstractArray, PContainer);
00070
00071 public:
00083 PAbstractArray(
00084 PINDEX elementSizeInBytes,
00085
00086 PINDEX initialSize = 0
00087 );
00088
00106 PAbstractArray(
00107 PINDEX elementSizeInBytes,
00108
00109 const void *buffer,
00110 PINDEX bufferSizeInElements,
00111 PBoolean dynamicAllocation
00112 );
00114
00123 virtual void PrintOn(
00124 ostream &strm
00125 ) const;
00126
00133 virtual void ReadFrom(
00134 istream &strm
00135 );
00136
00157 virtual Comparison Compare(
00158 const PObject & obj
00159 ) const;
00161
00172 virtual PBoolean SetSize(
00173 PINDEX newSize
00174 );
00176
00187 void Attach(
00188 const void *buffer,
00189 PINDEX bufferSize
00190 );
00191
00205 void * GetPointer(
00206 PINDEX minSize = 1
00207 );
00208
00221 PBoolean Concatenate(
00222 const PAbstractArray & array
00223 );
00225
00226 protected:
00227 PBoolean InternalSetSize(PINDEX newSize, PBoolean force);
00228
00229 virtual void PrintElementOn(
00230 ostream & stream,
00231 PINDEX index
00232 ) const;
00233 virtual void ReadElementFrom(
00234 istream & stream,
00235 PINDEX index
00236 );
00237
00239 PINDEX elementSize;
00240
00242 char * theArray;
00243
00245 PBoolean allocatedDynamically;
00246
00247 friend class PArrayObjects;
00248 };
00249
00250
00252
00253
00254 #ifdef PHAS_TEMPLATES
00255
00275 template <class T> class PBaseArray : public PAbstractArray
00276 {
00277 PCLASSINFO(PBaseArray, PAbstractArray);
00278
00279 public:
00287 PBaseArray(
00288 PINDEX initialSize = 0
00289 ) : PAbstractArray(sizeof(T), initialSize) { }
00290
00293 PBaseArray(
00294 T const * buffer,
00295 PINDEX length,
00296 PBoolean dynamic = PTrue
00297 ) : PAbstractArray(sizeof(T), buffer, length, dynamic) { }
00299
00304 virtual PObject * Clone() const
00305 {
00306 return PNEW PBaseArray<T>(*this, GetSize());
00307 }
00309
00318 PBoolean SetAt(
00319 PINDEX index,
00320 T val
00321 ) {
00322 return SetMinSize(index+1) && val==(((T *)theArray)[index] = val);
00323 }
00324
00331 T GetAt(
00332 PINDEX index
00333 ) const {
00334 PASSERTINDEX(index);
00335 return index < GetSize() ? ((T *)theArray)[index] : (T)0;
00336 }
00337
00346 void Attach(
00347 const T * buffer,
00348 PINDEX bufferSize
00349 ) {
00350 PAbstractArray::Attach(buffer, bufferSize);
00351 }
00352
00366 T * GetPointer(
00367 PINDEX minSize = 0
00368 ) {
00369 return (T *)PAbstractArray::GetPointer(minSize);
00370 }
00372
00384 T operator[](
00385 PINDEX index
00386 ) const {
00387 return GetAt(index);
00388 }
00389
00400 T & operator[](
00401 PINDEX index
00402 ) {
00403 PASSERTINDEX(index);
00404 PAssert(SetMinSize(index+1), POutOfMemory);
00405 return ((T *)theArray)[index];
00406 }
00407
00421 operator T const *() const {
00422 return (T const *)theArray;
00423 }
00424
00436 PBoolean Concatenate(
00437 const PBaseArray & array
00438 ) {
00439 return PAbstractArray::Concatenate(array);
00440 }
00442
00443 protected:
00444 virtual void PrintElementOn(
00445 ostream & stream,
00446 PINDEX index
00447 ) const {
00448 stream << GetAt(index);
00449 }
00450 };
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460 #define PBASEARRAY(cls, T) typedef PBaseArray<T> cls
00461
00474 #define PDECLARE_BASEARRAY(cls, T) \
00475 PDECLARE_CLASS(cls, PBaseArray<T>) \
00476 cls(PINDEX initialSize = 0) \
00477 : PBaseArray<T>(initialSize) { } \
00478 cls(T const * buffer, PINDEX length, PBoolean dynamic = PTrue) \
00479 : PBaseArray<T>(buffer, length, dynamic) { } \
00480 virtual PObject * Clone() const \
00481 { return PNEW cls(*this, GetSize()); } \
00482
00483
00502 template <class T> class PScalarArray : public PBaseArray<T>
00503 {
00504 public:
00512 PScalarArray(
00513 PINDEX initialSize = 0
00514 ) : PBaseArray<T>(initialSize) { }
00515
00518 PScalarArray(
00519 T const * buffer,
00520 PINDEX length,
00521 PBoolean dynamic = PTrue
00522 ) : PBaseArray<T>(buffer, length, dynamic) { }
00524
00525 protected:
00526 virtual void ReadElementFrom(
00527 istream & stream,
00528 PINDEX index
00529 ) {
00530 T t;
00531 stream >> t;
00532 if (!stream.fail())
00533 SetAt(index, t);
00534 }
00535 };
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546 #define PSCALAR_ARRAY(cls, T) typedef PScalarArray<T> cls
00547
00548 #else // PHAS_TEMPLATES
00549
00550 #define PBASEARRAY(cls, T) \
00551 typedef T P_##cls##_Base_Type; \
00552 class cls : public PAbstractArray { \
00553 PCLASSINFO(cls, PAbstractArray) \
00554 public: \
00555 inline cls(PINDEX initialSize = 0) \
00556 : PAbstractArray(sizeof(P_##cls##_Base_Type), initialSize) { } \
00557 inline cls(P_##cls##_Base_Type const * buffer, PINDEX length, PBoolean dynamic = PTrue) \
00558 : PAbstractArray(sizeof(P_##cls##_Base_Type), buffer, length, dynamic) { } \
00559 virtual PObject * Clone() const \
00560 { return PNEW cls(*this, GetSize()); } \
00561 inline PBoolean SetAt(PINDEX index, P_##cls##_Base_Type val) \
00562 { return SetMinSize(index+1) && \
00563 val==(((P_##cls##_Base_Type *)theArray)[index] = val); } \
00564 inline P_##cls##_Base_Type GetAt(PINDEX index) const \
00565 { PASSERTINDEX(index); return index < GetSize() ? \
00566 ((P_##cls##_Base_Type*)theArray)[index] : (P_##cls##_Base_Type)0; } \
00567 inline P_##cls##_Base_Type operator[](PINDEX index) const \
00568 { PASSERTINDEX(index); return GetAt(index); } \
00569 inline P_##cls##_Base_Type & operator[](PINDEX index) \
00570 { PASSERTINDEX(index); PAssert(SetMinSize(index+1), POutOfMemory); \
00571 return ((P_##cls##_Base_Type *)theArray)[index]; } \
00572 inline void Attach(const P_##cls##_Base_Type * buffer, PINDEX bufferSize) \
00573 { PAbstractArray::Attach(buffer, bufferSize); } \
00574 inline P_##cls##_Base_Type * GetPointer(PINDEX minSize = 0) \
00575 { return (P_##cls##_Base_Type *)PAbstractArray::GetPointer(minSize); } \
00576 inline operator P_##cls##_Base_Type const *() const \
00577 { return (P_##cls##_Base_Type const *)theArray; } \
00578 inline PBoolean Concatenate(cls const & array) \
00579 { return PAbstractArray::Concatenate(array); } \
00580 }
00581
00582 #define PDECLARE_BASEARRAY(cls, T) \
00583 PBASEARRAY(cls##_PTemplate, T); \
00584 PDECLARE_CLASS(cls, cls##_PTemplate) \
00585 cls(PINDEX initialSize = 0) \
00586 : cls##_PTemplate(initialSize) { } \
00587 cls(T const * buffer, PINDEX length, PBoolean dynamic = PTrue) \
00588 : cls##_PTemplate(buffer, length, dynamic) { } \
00589 virtual PObject * Clone() const \
00590 { return PNEW cls(*this, GetSize()); } \
00591
00592 #define PSCALAR_ARRAY(cls, T) PBASEARRAY(cls, T)
00593
00594 #endif // PHAS_TEMPLATES
00595
00596
00598 #ifdef DOC_PLUS_PLUS
00599 class PCharArray : public PBaseArray {
00600 public:
00606 PCharArray(
00607 PINDEX initialSize = 0
00608 );
00609
00612 PCharArray(
00613 char const * buffer,
00614 PINDEX length,
00615 PBoolean dynamic = PTrue
00616 );
00618 #endif
00619 PDECLARE_BASEARRAY(PCharArray, char);
00620 public:
00623
00624 virtual void PrintOn(
00625 ostream & strm
00626 ) const;
00628 virtual void ReadFrom(
00629 istream &strm
00630 );
00632 };
00633
00635 #ifdef DOC_PLUS_PLUS
00636 class PShortArray : public PBaseArray {
00637 public:
00643 PShortArray(
00644 PINDEX initialSize = 0
00645 );
00646
00649 PShortArray(
00650 short const * buffer,
00651 PINDEX length,
00652 PBoolean dynamic = PTrue
00653 );
00655 };
00656 #endif
00657 PSCALAR_ARRAY(PShortArray, short);
00658
00659
00661 #ifdef DOC_PLUS_PLUS
00662 class PIntArray : public PBaseArray {
00663 public:
00669 PIntArray(
00670 PINDEX initialSize = 0
00671 );
00672
00675 PIntArray(
00676 int const * buffer,
00677 PINDEX length,
00678 PBoolean dynamic = PTrue
00679 );
00681 };
00682 #endif
00683 PSCALAR_ARRAY(PIntArray, int);
00684
00685
00687 #ifdef DOC_PLUS_PLUS
00688 class PLongArray : public PBaseArray {
00689 public:
00695 PLongArray(
00696 PINDEX initialSize = 0
00697 );
00698
00701 PLongArray(
00702 long const * buffer,
00703 PINDEX length,
00704 PBoolean dynamic = PTrue
00705 );
00707 };
00708 #endif
00709 PSCALAR_ARRAY(PLongArray, long);
00710
00711
00713 #ifdef DOC_PLUS_PLUS
00714 class PBYTEArray : public PBaseArray {
00715 public:
00721 PBYTEArray(
00722 PINDEX initialSize = 0
00723 );
00724
00727 PBYTEArray(
00728 BYTE const * buffer,
00729 PINDEX length,
00730 PBoolean dynamic = PTrue
00731 );
00733 };
00734 #endif
00735 PDECLARE_BASEARRAY(PBYTEArray, BYTE);
00736 public:
00739
00740 virtual void PrintOn(
00741 ostream & strm
00742 ) const;
00744 virtual void ReadFrom(
00745 istream &strm
00746 );
00748 };
00749
00750
00752 #ifdef DOC_PLUS_PLUS
00753 class PWORDArray : public PBaseArray {
00754 public:
00760 PWORDArray(
00761 PINDEX initialSize = 0
00762 );
00763
00766 PWORDArray(
00767 WORD const * buffer,
00768 PINDEX length,
00769 PBoolean dynamic = PTrue
00770 );
00772 };
00773 #endif
00774 PSCALAR_ARRAY(PWORDArray, WORD);
00775
00776
00778 #ifdef DOC_PLUS_PLUS
00779 class PUnsignedArray : public PBaseArray {
00780 public:
00786 PUnsignedArray(
00787 PINDEX initialSize = 0
00788 );
00789
00792 PUnsignedArray(
00793 unsigned const * buffer,
00794 PINDEX length,
00795 PBoolean dynamic = PTrue
00796 );
00798 };
00799 #endif
00800 PSCALAR_ARRAY(PUnsignedArray, unsigned);
00801
00802
00804 #ifdef DOC_PLUS_PLUS
00805 class PDWORDArray : public PBaseArray {
00806 public:
00812 PDWORDArray(
00813 PINDEX initialSize = 0
00814 );
00815
00818 PDWORDArray(
00819 DWORD const * buffer,
00820 PINDEX length,
00821 PBoolean dynamic = PTrue
00822 );
00824 #endif
00825 PSCALAR_ARRAY(PDWORDArray, DWORD);
00826
00827
00829
00830
00852 class PArrayObjects : public PCollection
00853 {
00854 PCONTAINERINFO(PArrayObjects, PCollection);
00855
00856 public:
00865 PINLINE PArrayObjects(
00866 PINDEX initialSize = 0
00867 );
00869
00902 virtual Comparison Compare(
00903 const PObject & obj
00904 ) const;
00906
00909
00910 virtual PINDEX GetSize() const;
00911
00920 virtual PBoolean SetSize(
00921 PINDEX newSize
00922 );
00924
00933 virtual PINDEX Append(
00934 PObject * obj
00935 );
00936
00952 virtual PINDEX Insert(
00953 const PObject & before,
00954 PObject * obj
00955 );
00956
00967 virtual PINDEX InsertAt(
00968 PINDEX index,
00969 PObject * obj
00970 );
00971
00980 virtual PBoolean Remove(
00981 const PObject * obj
00982 );
00983
00995 virtual PObject * RemoveAt(
00996 PINDEX index
00997 );
00998
01006 virtual PBoolean SetAt(
01007 PINDEX index,
01008 PObject * val
01009 );
01010
01017 virtual PObject * GetAt(
01018 PINDEX index
01019 ) const;
01020
01028 virtual PINDEX GetObjectsIndex(
01029 const PObject * obj
01030 ) const;
01031
01041 virtual PINDEX GetValuesIndex(
01042 const PObject & obj
01043 ) const;
01044
01051 virtual void RemoveAll();
01053
01054 protected:
01055 PBASEARRAY(ObjPtrArray, PObject *);
01056
01057 PBaseArray<PObject *> * theArray;
01058 };
01059
01060
01061 #ifdef PHAS_TEMPLATES
01062
01069 template <class T> class PArray : public PArrayObjects
01070 {
01071 PCLASSINFO(PArray, PArrayObjects);
01072
01073 public:
01082 PArray(
01083 PINDEX initialSize = 0
01084 ) : PArrayObjects(initialSize) { }
01086
01092 virtual PObject * Clone() const
01093 { return PNEW PArray(0, this); }
01095
01105 T & operator[](
01106 PINDEX index
01107 ) const {
01108 PObject * obj = GetAt(index);
01109 PAssert(obj != NULL, PInvalidArrayElement);
01110 return (T &)*obj;
01111 }
01113
01114 protected:
01115 PArray(int dummy, const PArray * c) : PArrayObjects(dummy, c) { }
01116 };
01117
01118
01130 #define PARRAY(cls, T) typedef PArray<T> cls
01131
01132
01145 #define PDECLARE_ARRAY(cls, T) \
01146 PARRAY(cls##_PTemplate, T); \
01147 PDECLARE_CLASS(cls, cls##_PTemplate) \
01148 protected: \
01149 inline cls(int dummy, const cls * c) \
01150 : cls##_PTemplate(dummy, c) { } \
01151 public: \
01152 inline cls(PINDEX initialSize = 0) \
01153 : cls##_PTemplate(initialSize) { } \
01154 virtual PObject * Clone() const \
01155 { return PNEW cls(0, this); } \
01156
01157 #else // PHAS_TEMPLATES
01158
01159
01160 #define PARRAY(cls, T) \
01161 class cls : public PArrayObjects { \
01162 PCLASSINFO(cls, PArrayObjects); \
01163 protected: \
01164 inline cls(int dummy, const cls * c) \
01165 : PArrayObjects(dummy, c) { } \
01166 public: \
01167 inline cls(PINDEX initialSize = 0) \
01168 : PArrayObjects(initialSize) { } \
01169 virtual PObject * Clone() const \
01170 { return PNEW cls(0, this); } \
01171 inline T & operator[](PINDEX index) const\
01172 { PObject * obj = GetAt(index); \
01173 PAssert(obj != NULL, PInvalidArrayElement); \
01174 \
01175 return (T &)*obj; } \
01176 }
01177
01178 #define PDECLARE_ARRAY(cls, T) \
01179 PARRAY(cls##_PTemplate, T); \
01180 PDECLARE_CLASS(cls, cls##_PTemplate) \
01181 protected: \
01182 inline cls(int dummy, const cls * c) \
01183 : cls##_PTemplate(dummy, c) { } \
01184 public: \
01185 inline cls(PINDEX initialSize = 0) \
01186 : cls##_PTemplate(initialSize) { } \
01187 virtual PObject * Clone() const \
01188 { return PNEW cls(0, this); } \
01189
01190 #endif // PHAS_TEMPLATES
01191
01192
01195 class PBitArray : public PBYTEArray
01196 {
01197 PCLASSINFO(PBitArray, PBYTEArray);
01198
01199 public:
01204 PBitArray(
01205 PINDEX initialSize = 0
01206 );
01207
01210 PBitArray(
01211 const void * buffer,
01212 PINDEX length,
01213 PBoolean dynamic = PTrue
01214 );
01216
01221 virtual PObject * Clone() const;
01223
01232 virtual PINDEX GetSize() const;
01233
01242 virtual PBoolean SetSize(
01243 PINDEX newSize
01244 );
01245
01252 PBoolean SetAt(
01253 PINDEX index,
01254 PBoolean val
01255 );
01256
01263 PBoolean GetAt(
01264 PINDEX index
01265 ) const;
01266
01275 void Attach(
01276 const void * buffer,
01277 PINDEX bufferSize
01278 );
01279
01293 BYTE * GetPointer(
01294 PINDEX minSize = 0
01295 );
01297
01309 PBoolean operator[](
01310 PINDEX index
01311 ) const { return GetAt(index); }
01312
01318 PBitArray & operator+=(
01319 PINDEX index
01320 ) { SetAt(index, PTrue); return *this; }
01321
01327 PBitArray & operator-=(
01328 PINDEX index
01329 ) { SetAt(index, PFalse); return *this; }
01330
01342 PBoolean Concatenate(
01343 const PBitArray & array
01344 );
01346 };
01347
01348
01349 #endif
01350