/* * @(#) bytearr.h - Void and byte arrays class library header. * (c) 1998 Ivan Maidanski http://ivmai.chat.ru * Freeware class library source. All rights reserved. ** * Language: ISO/ANSI C++ * Tested with: Microsoft Visual C++ (R) v4.2, Watcom C++ 16/32 v11.0 * Last modified: 1998-09-06 23:25:00 GMT+04:00 */ // Library source file: bytearr.cpp // class TVoidArray; // class TByteArray; // ARRAYS_CHECK_INDEX #ifndef _BYTEARR_H_INCLUDED #define _BYTEARR_H_INCLUDED #ifndef __cplusplus #error This file is for use with C++ #endif // common macros declaration section (may be overriden) #ifndef ARRAYS_CHECK_INDEX // index checking enable/disable toggler #if defined(DEBUG) || defined(_DEBUG) #define ARRAYS_CHECK_INDEX 1 #else #define ARRAYS_CHECK_INDEX 0 #endif #endif // special compiler directives #ifdef _MSC_VER #pragma warning(disable: 4514) // "unreferenced inline function removed" #endif // classes declaration section class TVoidArray // resizable C-style void array { public: // constructors & destructor TVoidArray(); TVoidArray(unsigned InitSize); TVoidArray(const void *, unsigned InitSize); TVoidArray(const TVoidArray &); TVoidArray(const TVoidArray &, unsigned InitSize); ~TVoidArray(); public: // entier copiers & swapper TVoidArray &operator=(const TVoidArray &); TVoidArray &Copy(const TVoidArray &); TVoidArray &Copy(const TVoidArray &, unsigned CopySize); TVoidArray &Copy(const TVoidArray &, unsigned SrcOffset, unsigned CopySize); TVoidArray &Copy(const void *, unsigned CopySize); static void Swap(TVoidArray &, TVoidArray &); public: // data direct access operator const void *() const; const void *GetData() const; void *GetData(); public: // size manipulators unsigned Size(unsigned); unsigned Size() const; unsigned CalcNewSize(unsigned NewCount) const; static unsigned SizeAdd(unsigned, unsigned IncVal); static unsigned SizeMul(unsigned, unsigned MulVal); public: // block filler & copiers TVoidArray &SetAt(unsigned, char, unsigned RepCount=1); TVoidArray &CopyAt(unsigned, const TVoidArray &, unsigned CopySize); TVoidArray &CopyAt(unsigned, const TVoidArray &, unsigned SrcOffset, unsigned CopySize); TVoidArray &CopyAt(unsigned, const void *, unsigned CopySize); void *CopyAt(void *, unsigned SrcOffset, unsigned CopySize) const; public: // block swappers TVoidArray &SwapAt(unsigned OffsetA, unsigned OffsetB, unsigned SwapSize); TVoidArray &SwapAt(unsigned OffsetA, TVoidArray &ArrayB, unsigned OffsetB, unsigned SwapSize); TVoidArray &SwapAt(unsigned OffsetA, void *PDataB, unsigned SwapSize); public: // exceptions class TError {}; class TBadIndexError : public TError {}; class TOutOfMemoryError : public TError {}; private: // internal data fields void *Ptr; unsigned SizeVal; }; class TByteArray : public TVoidArray // resizable C-style byte array { public: // constructors & destructor TByteArray(); TByteArray(unsigned InitCount); TByteArray(unsigned char Byte, unsigned InitCount); TByteArray(const unsigned char *, unsigned InitCount); TByteArray(const TByteArray &); TByteArray(const TByteArray &, unsigned SrcIndex, unsigned InitCount); ~TByteArray(); public: // entier copiers & swapper TByteArray &operator=(const TByteArray &); TByteArray &Copy(const unsigned char *, unsigned CopyCount); TByteArray &Copy(const TByteArray &); TByteArray &Copy(const TByteArray &, unsigned SrcIndex, unsigned CopyCount); static void Swap(TByteArray &, TByteArray &); public: // data direct access const unsigned char *GetData() const; unsigned char *GetData(); public: // element count manipulators unsigned Count(unsigned); unsigned Count() const; void GrowAtIndex(unsigned, unsigned RegionSize=1); void RemoveAll(); int IsEmpty() const; public: // size manipulators unsigned Size(unsigned); unsigned Size() const; void FreeExtra(); public: // index validity checkers void CheckIndex(unsigned, unsigned CheckRange=1) const; unsigned IndexOf(const unsigned char &) const; public: // elements access (zero-based) unsigned char operator[](unsigned) const; unsigned char &operator[](unsigned); const unsigned char &ElementAt(unsigned) const; unsigned char &ElementAt(unsigned); unsigned char &ElementAtGrow(unsigned); unsigned char GetAt(unsigned) const; TByteArray &SetAt(unsigned, unsigned char Byte); TByteArray &SetAt(unsigned, unsigned char Byte, unsigned RepCount); TByteArray &SetAtGrow(unsigned, unsigned char Byte); TByteArray &SetAtGrow(unsigned, unsigned char Byte, unsigned RepCount); public: // elements access starting at end const unsigned char &ElementAtEnd(unsigned Offset=0) const; unsigned char &ElementAtEnd(unsigned Offset=0); unsigned char GetAtEnd(unsigned Offset=0) const; TByteArray &SetAtEnd(unsigned char Byte, unsigned Offset=0); public: // elements group copiers TByteArray &CopyAt(unsigned, const unsigned char *, unsigned CopyCount); TByteArray &CopyAt(unsigned, const TByteArray &, unsigned SrcIndex, unsigned CopyCount); unsigned char *CopyAt(unsigned char *, unsigned SrcIndex, unsigned CopyCount) const; public: // elements group swappers TByteArray &SwapAt(unsigned IndexA, unsigned IndexB, unsigned SwapCount); TByteArray &SwapAt(unsigned IndexA, TByteArray &ArrayB, unsigned IndexB, unsigned SwapCount); TByteArray &SwapAt(unsigned IndexA, unsigned char *PBytesB, unsigned SwapCount); TByteArray &SwapAt(unsigned IndexA, unsigned char &ByteB); TByteArray &ReverseAt(unsigned, unsigned RevCount); public: // array & elements concatenation TByteArray operator+(const TByteArray &) const; TByteArray &operator+=(const TByteArray &); TByteArray &Append(unsigned char Byte, unsigned RepCount=1); TByteArray &Append(const unsigned char *, unsigned CopyCount); TByteArray &Append(const TByteArray &); TByteArray &Append(const TByteArray &, unsigned SrcIndex, unsigned CopyCount); public: // array & elements insertion/extraction/removal TByteArray &InsertAt(unsigned, unsigned char Byte, unsigned RepCount=1); TByteArray &InsertAt(unsigned, const unsigned char *, unsigned CopyCount); TByteArray &InsertAt(unsigned, const TByteArray &); TByteArray &InsertAt(unsigned, const TByteArray &, unsigned SrcIndex, unsigned CopyCount); TByteArray &ExtractAt(unsigned, unsigned char &DestByte); unsigned char ExtractAt(unsigned); TByteArray &ExtractAt(unsigned, unsigned ExtrCount, unsigned char *PDestBytes); TByteArray &ExtractAt(unsigned, unsigned ExtrCount, TByteArray &DestArray); TByteArray &RemoveAt(unsigned, unsigned RemoveCount=1); TByteArray &RemoveAtEnd(unsigned RemoveCount=1); public: // elements stack-oriented access TByteArray &Push(unsigned char); TByteArray &Pop(unsigned char &); unsigned char Pop(); public: // elements reversed stack-oriented access TByteArray &ReversePush(unsigned char); TByteArray &ReversePop(unsigned char &); unsigned char ReversePop(); public: // elements queue-oriented access TByteArray &QueuePut(unsigned char); TByteArray &QueueGet(unsigned char &); unsigned char QueueGet(); public: // bitwise comparison int operator==(const TByteArray &) const; int operator!=(const TByteArray &) const; unsigned GetEqualLenAt(unsigned IndexA, const TByteArray &ArrayB, unsigned IndexB, unsigned CompareCount) const; unsigned GetEqualLenAt(unsigned IndexA, const unsigned char *PBytesB, unsigned CompareCount) const; public: // bitwise search unsigned FindAt(unsigned, unsigned char Byte) const; unsigned FindAt(unsigned, const TByteArray &) const; unsigned FindAt(unsigned, const TByteArray &, unsigned SrcIndex, unsigned SrcCount) const; unsigned FindAt(unsigned, const unsigned char *, unsigned SrcCount) const; public: // bitwise reversed search unsigned ReverseFindAt(unsigned, unsigned char Byte) const; unsigned ReverseFindAt(unsigned, const TByteArray &) const; unsigned ReverseFindAt(unsigned, const TByteArray &, unsigned SrcIndex, unsigned SrcCount) const; unsigned ReverseFindAt(unsigned, const unsigned char *, unsigned SrcCount) const; private: // internal data fields unsigned Cnt; }; // inline methods definition section inline TVoidArray::TVoidArray() : Ptr(0), SizeVal(0) { } inline TVoidArray::TVoidArray(unsigned InitSize) : Ptr(0), SizeVal(0) { Size(InitSize); } inline TVoidArray &TVoidArray::Copy(const TVoidArray &Array) { return operator=(Array); } inline TVoidArray &TVoidArray::Copy(const TVoidArray &Array, unsigned CopySize) { return Copy(Array,0,CopySize); } inline TVoidArray::operator const void *() const { return Ptr; } inline const void *TVoidArray::GetData() const { return Ptr; } inline void *TVoidArray::GetData() { return Ptr; } inline unsigned TVoidArray::Size() const { return SizeVal; } inline unsigned TVoidArray::SizeAdd(unsigned NewSize, unsigned IncVal) { if ((NewSize=NewSize+IncVal)1 && (~(unsigned)0)/MulValNewSize) throw TBadIndexError(); #endif return TVoidArray::Size(NewSize); } inline unsigned TByteArray::Size() const { return TVoidArray::Size(); } inline void TByteArray::FreeExtra() { TVoidArray::Size(Cnt); } inline void TByteArray::CheckIndex(unsigned Index, unsigned CheckRange) const { if (Index+CheckRangeCnt) throw TBadIndexError(); } inline unsigned char TByteArray::operator[](unsigned Index) const { return ElementAt(Index); } inline unsigned char &TByteArray::operator[](unsigned Index) { return ElementAt(Index); } inline const unsigned char &TByteArray::ElementAt(unsigned Index) const { #if ARRAYS_CHECK_INDEX if (Index>=Cnt) throw TBadIndexError(); #endif return *((const unsigned char *)TVoidArray::GetData()+Index); } inline unsigned char &TByteArray::ElementAt(unsigned Index) { #if ARRAYS_CHECK_INDEX if (Index>=Cnt) throw TBadIndexError(); #endif return *((unsigned char *)TVoidArray::GetData()+Index); } inline unsigned char &TByteArray::ElementAtGrow(unsigned Index) { GrowAtIndex(Index); return *((unsigned char *)TVoidArray::GetData()+Index); } inline unsigned char TByteArray::GetAt(unsigned Index) const { return ElementAt(Index); } inline TByteArray &TByteArray::SetAt(unsigned Index, unsigned char Byte) { ElementAt(Index)=Byte; return *this; } inline TByteArray &TByteArray::SetAt(unsigned Index, unsigned char Byte, unsigned RepCount) { #if ARRAYS_CHECK_INDEX if (Index+RepCount>Cnt) throw TBadIndexError(); #endif TVoidArray::SetAt(Index,(char)Byte,RepCount); return *this; } inline TByteArray &TByteArray::SetAtGrow(unsigned Index, unsigned char Byte) { ElementAtGrow(Index)=Byte; return *this; } inline TByteArray &TByteArray::SetAtGrow(unsigned Index, unsigned char Byte, unsigned RepCount) { GrowAtIndex(Index,RepCount); TVoidArray::SetAt(Index,(char)Byte,RepCount); return *this; } inline unsigned char TByteArray::GetAtEnd(unsigned Offset) const { return ElementAtEnd(Offset); } inline TByteArray &TByteArray::SetAtEnd(unsigned char Byte, unsigned Offset) { ElementAtEnd(Offset)=Byte; return *this; } inline TByteArray &TByteArray::CopyAt(unsigned Index, const unsigned char *PBytes, unsigned CopyCount) { #if ARRAYS_CHECK_INDEX if (Index+CopyCount>Cnt) throw TBadIndexError(); #endif TVoidArray::CopyAt(Index,(const void *)PBytes,CopyCount); return *this; } inline TByteArray &TByteArray::CopyAt(unsigned Index, const TByteArray &Array, unsigned SrcIndex, unsigned CopyCount) { #if ARRAYS_CHECK_INDEX if (Index+CopyCount>Cnt || SrcIndex+CopyCount>Array.Cnt) throw TBadIndexError(); #endif TVoidArray::CopyAt(Index,Array,SrcIndex,CopyCount); return *this; } inline unsigned char *TByteArray::CopyAt(unsigned char *PDestBytes, unsigned SrcIndex, unsigned CopyCount) const { #if ARRAYS_CHECK_INDEX if (SrcIndex+CopyCount>Cnt) throw TBadIndexError(); #endif TVoidArray::CopyAt((void *)PDestBytes,SrcIndex,CopyCount); return PDestBytes; } inline TByteArray &TByteArray::SwapAt(unsigned IndexA, unsigned IndexB, unsigned SwapCount) { #if ARRAYS_CHECK_INDEX if ((IndexA>IndexB? IndexA : IndexB)+SwapCount>Cnt) throw TBadIndexError(); #endif TVoidArray::SwapAt(IndexA,*this,IndexB,SwapCount); return *this; } inline TByteArray &TByteArray::SwapAt(unsigned IndexA, TByteArray &ArrayB, unsigned IndexB, unsigned SwapCount) { #if ARRAYS_CHECK_INDEX if (IndexA+SwapCount>Cnt || IndexB+SwapCount>ArrayB.Cnt) throw TBadIndexError(); #endif TVoidArray::SwapAt(IndexA,ArrayB,IndexB,SwapCount); return *this; } inline TByteArray &TByteArray::SwapAt(unsigned IndexA, unsigned char *PBytesB, unsigned SwapCount) { #if ARRAYS_CHECK_INDEX if (IndexA+SwapCount>Cnt) throw TBadIndexError(); #endif TVoidArray::SwapAt(IndexA,(void *)PBytesB,SwapCount); return *this; } inline TByteArray TByteArray::operator+(const TByteArray &Array) const { return TByteArray(*this).Append(Array,0,Array.Cnt); } inline TByteArray &TByteArray::operator+=(const TByteArray &Array) { return Append(Array,0,Array.Cnt); } inline TByteArray &TByteArray::Append(const TByteArray &Array) { return Append(Array,0,Array.Cnt); } inline TByteArray &TByteArray::InsertAt(unsigned Index, const TByteArray &Array) { return InsertAt(Index,Array,0,Array.Cnt); } inline unsigned char TByteArray::ExtractAt(unsigned Index) { unsigned char DestByte; ExtractAt(Index,DestByte); return DestByte; } inline TByteArray &TByteArray::RemoveAtEnd(unsigned RemoveCount) { #if ARRAYS_CHECK_INDEX if (RemoveCount>Cnt) throw TBadIndexError(); #endif TVoidArray::Size(CalcNewSize(Cnt-=RemoveCount)); return *this; } inline unsigned char TByteArray::Pop() { unsigned char DestByte; Pop(DestByte); return DestByte; } inline TByteArray &TByteArray::ReversePush(unsigned char Byte) { return InsertAt(0,Byte); } inline TByteArray &TByteArray::ReversePop(unsigned char &DestByte) { return ExtractAt(0,DestByte); } inline unsigned char TByteArray::ReversePop() { unsigned char DestByte; ReversePop(DestByte); return DestByte; } inline TByteArray &TByteArray::QueuePut(unsigned char Byte) { return Push(Byte); } inline TByteArray &TByteArray::QueueGet(unsigned char &DestByte) { return ReversePop(DestByte); } inline unsigned char TByteArray::QueueGet() { unsigned char DestByte; QueueGet(DestByte); return DestByte; } inline int TByteArray::operator==(const TByteArray &Array) const { return Cnt==Array.Cnt && GetEqualLenAt(0,Array,0,Cnt)==Cnt; } inline int TByteArray::operator!=(const TByteArray &Array) const { return Cnt!=Array.Cnt || GetEqualLenAt(0,Array,0,Cnt)!=Cnt; } inline unsigned TByteArray::FindAt(unsigned Index, const TByteArray &Array) const { return FindAt(Index,Array,0,Array.Cnt); } inline unsigned TByteArray::ReverseFindAt(unsigned Index, const TByteArray &Array) const { return ReverseFindAt(Index,Array,0,Array.Cnt); } #endif