#include "LArray.h" #include "T2Archive.h" // unknown/assumed name -- not in T2DLL exports! class LDefaultComparator : public LComparator { public: virtual ~LDefaultComparator() {} virtual int Compare(const void* inItemOne, const void* inItemTwo, unsigned int inSizeOne, unsigned int inSizeTwo) const; virtual BOOL IsEqualTo(const void* inItemOne, const void* inItemTwo, unsigned int inSizeOne, unsigned int inSizeTwo) const; static LDefaultComparator* GetComparator(); protected: static LDefaultComparator* sDefaultComparator; }; LArray::LArray() { init(sizeof(void *), NULL, false); } LArray::LArray(int size, LComparator* comparator, BOOL keepSorted) { init(size, comparator, keepSorted); } void LArray::init(int size, LComparator* comparator, BOOL keepSorted) { mKeepSorted = keepSorted; mOwnsComparator = true; if (!comparator) { mComparator = LDefaultComparator::GetComparator(); mOwnsComparator = false; } else { mComparator = comparator; } mItemSize = size; mItemCount = 0; mExpandSize = 10; mBuffer = malloc(mExpandSize * mItemSize); } LArray::~LArray() { if (mComparator && mOwnsComparator) delete mComparator; free(mBuffer); } /*virtual*/ int LArray::GetCount() const { return mItemCount; } void LArray::Expand(int amount) { int threshold = mItemCount + amount; if (threshold > mExpandSize) { mExpandSize = threshold + 10; mBuffer = realloc(mBuffer, mExpandSize * mItemSize); } mItemCount += amount; } void LArray::AdjustAllocation(int amount) { if (amount > mExpandSize) { mExpandSize = amount + 10; mBuffer = realloc(mBuffer, mExpandSize * mItemSize); } } void LArray::SetKeepSorted(int keepSorted) { mKeepSorted = keepSorted; } /*virtual*/ void LArray::InsertItemsAt(int count, int where, const void* data) { if (!mKeepSorted) { if (where == 0) where = 1; int oldCount = mItemCount; Expand(count); memmove( (char *) mBuffer + mItemSize * (where - 1 + count), (char *) mBuffer + mItemSize * (where - 1), mItemSize * (oldCount - (where - 1)) ); if (data) { for (int i = 0; i < count; i++) { memcpy((char *) mBuffer + mItemSize * (where - 1 + i), data, mItemSize); } } } else { for (int i = 0; i < count; i++) { Add((const char *) data + i * mItemSize); } } } /*virtual*/ void LArray::RemoveItemsAt(int count, int where) { #line 94 _ASSERT(where > 0); if (where < (mItemCount + 1)) { memmove( (char *) mBuffer + mItemSize * (where - 1), (char *) mBuffer + mItemSize * (where - 1 + count), mItemSize * (mItemCount - (where - 1 + count)) ); } mItemCount -= count; } /*virtual*/ void LArray::Remove(const void* item) { int index = FetchIndexOf(item); if (index != 0) RemoveItemsAt(1, index); } /*virtual*/ int LArray::FetchIndexOf(const void* item) const { char *p = (char *) mBuffer; for (int i = 0; i < mItemCount; i++) { if (memcmp(p, item, mItemSize) == 0) return i + 1; p += mItemSize; } return 0; } /*virtual*/ BOOL LArray::FetchItemAt(int index, void* outItem) const { #line 123 _ASSERT(index > 0); if (index > mItemCount) return false; memcpy(outItem, (char *) mBuffer + mItemSize * (index - 1), mItemSize); return true; } /*virtual*/ void LArray::AssignItemsAt(int count, int where, void* data) { if (!mKeepSorted) { #line 134 _ASSERT(where > 0); if ((where - 1 + count) > mItemCount) Expand((where - 1 + count) - mItemCount); if (data) { for (int i = 0; i < count; i++) { memcpy((char *) mBuffer + mItemSize * (where - 1 + i), data, mItemSize); } } } else { if ((where - 1 + count) > mItemCount) Expand((where - 1 + count) - mItemCount); RemoveItemsAt(count, where); InsertItemsAt(count, where, data); } } /*virtual*/ void LArray::Add(const void* item) { if (!mKeepSorted) { Expand(1); memcpy((char *) mBuffer + mItemSize * (mItemCount - 1), item, mItemSize); } else { char *p = (char *) mBuffer; int i; for (i = 0; i < mItemCount; i++) { if (mComparator->Compare(item, p, mItemSize, mItemSize) < 0) { mKeepSorted = false; InsertItemsAt(1, i + 1, item); mKeepSorted = true; break; } p += mItemSize; } if (i == mItemCount) { mKeepSorted = false; Add(item); mKeepSorted = true; } } } void LArray::SetComparator(LComparator* comparator) { if (mComparator && mOwnsComparator) delete mComparator; mComparator = comparator; } /*virtual*/ void LArray::ReadAsWord(T2Archive& archive) { unsigned char flagValue; int itemSize; int itemCount; int handleSize; int n; archive >> itemSize; archive >> itemCount; archive >> n; archive >> n; archive >> flagValue; archive >> flagValue; archive >> handleSize; if (mItemCount > 0) RemoveItemsAt(mItemCount, 1); unsigned short theItem; unsigned int v; for (n = 0; n < itemCount; n++) { archive >> theItem; v = theItem; Add(&v); } for (; n < handleSize / itemSize; n++) { archive >> theItem; } } /*virtual*/ void LArray::WriteAsWord(T2Archive& archive) { int renameThisVarPleaseM = 2; archive << renameThisVarPleaseM; renameThisVarPleaseM = mItemCount; archive << renameThisVarPleaseM; int dataStored = renameThisVarPleaseM * 2; archive << dataStored; archive << dataStored; unsigned char flagValue = 0; archive << flagValue; flagValue = 0; archive << flagValue; int handleSize = mItemCount * 2; archive << handleSize; LArrayIterator iter(*this); unsigned int v; unsigned short item; while (iter.Next(&v)) { item = v; archive << item; } } /*virtual*/ void LArray::ReadAsDWord(T2Archive& archive) { DWORD code; archive >> code; #line 261 _ASSERT(code == 'Darr'); if (mItemCount > 0) RemoveItemsAt(mItemCount, 1); int itemCount; archive >> itemCount; unsigned int item; for (int i = 0; i < itemCount; i++) { archive >> item; Add(&item); } } /*virtual*/ void LArray::ReadAsChar(T2Archive& archive) { if (mItemCount > 0) RemoveItemsAt(mItemCount, 1); unsigned char v; int i; int itemSize; int itemCount; int dataStored; int dataAllocated; int handleSize; archive >> itemSize; archive >> itemCount; archive >> dataStored; archive >> dataAllocated; archive >> handleSize; for (i = 0; i < itemCount; i++) { archive >> v; Add(&v); } for (; i < handleSize; i++) { archive >> v; } } /*virtual*/ void LArray::WriteAsDWord(T2Archive& archive) { DWORD code = 'Darr'; archive << code; archive << mItemCount; LArrayIterator iter(*this); unsigned int item; while (iter.Next(&item)) { archive << item; } } /*virtual*/ void LArray::WriteAsChar(T2Archive& archive) { unsigned char v; int itemSize = 1; int handleSize = mItemCount; int dataAllocated = handleSize; int dataStored = dataAllocated; archive << itemSize; archive << mItemCount; archive << dataStored; archive << dataAllocated; archive << handleSize; LArrayIterator iter(*this); while (iter.Next(&v)) { archive << v; } } LArrayIterator::LArrayIterator(const LArray& array, int index) { mArray = &array; mNextIndex = index; } LArrayIterator::LArrayIterator(const LArrayIterator& iter) { mArray = iter.mArray; mNextIndex = iter.mNextIndex; } LArrayIterator::~LArrayIterator() { } void LArrayIterator::ResetTo(int index) { #line 366 _ASSERT(index == 0 || index == 1); mNextIndex = 1; } void LArrayIterator::Rewind() { mNextIndex = 1; } void LArrayIterator::Seek(const LArrayIterator& iter) { mArray = iter.mArray; mNextIndex = iter.mNextIndex; } BOOL LArrayIterator::Next(void* item) { if (mNextIndex > mArray->GetCount()) { mCurrentIndex = 0; return false; } else { mArray->FetchItemAt(mNextIndex, item); mCurrentIndex = mNextIndex; mNextIndex++; return true; } } BOOL LArrayIterator::Previous(void* item) { mCurrentIndex = mNextIndex; mNextIndex--; if (mNextIndex < 1) { mCurrentIndex = 0; return false; } else { mArray->FetchItemAt(mNextIndex, item); return true; } } LDefaultComparator* LDefaultComparator::sDefaultComparator; /*virtual*/ int LDefaultComparator::Compare(const void* inItemOne, const void* inItemTwo, unsigned int inSizeOne, unsigned int inSizeTwo) const { int result = memcmp(inItemOne, inItemTwo, (inSizeOne < inSizeTwo) ? inSizeOne : inSizeTwo); if (result == 0) result = inSizeOne - inSizeTwo; return result; } /*virtual*/ BOOL LDefaultComparator::IsEqualTo(const void* inItemOne, const void* inItemTwo, unsigned int inSizeOne, unsigned int inSizeTwo) const { if (inSizeOne != inSizeTwo) { return 0; } else { return memcmp(inItemOne, inItemTwo, inSizeOne) == 0; } } LDefaultComparator* LDefaultComparator::GetComparator() { if (!sDefaultComparator) sDefaultComparator = new LDefaultComparator; return sDefaultComparator; }