#include "LArray.h" #include "T2Archive.h" // unknown/assumed name -- not in T2DLL exports! class LDefaultComparator : public LComparator { public: LDefaultComparator(); 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) { int itemSize; int count; int i; unsigned char zero; int totalSize; unsigned short item; archive >> itemSize; archive >> count; archive >> i; archive >> i; archive >> zero; archive >> zero; archive >> totalSize; if (mItemCount > 0) RemoveItemsAt(mItemCount, 1); for (i = 0; i < count; i++) { archive >> item; unsigned int v = item; Add(&v); } for (; i < totalSize / itemSize; i++) { archive >> item; } } /*virtual*/ void LArray::WriteAsWord(T2Archive& archive) { int boop = 2; archive << boop; boop = mItemCount; archive << boop; int byteCount = boop * 2; archive << byteCount; archive << byteCount; unsigned char zero = 0; archive << zero; zero = 0; archive << zero; int totalSize = mItemCount * 2; archive << totalSize; LArrayIterator iter(*this); unsigned int item; while (iter.Next(&item)) { unsigned short v = item; archive << v; } } /*virtual*/ void LArray::ReadAsDWord(T2Archive& archive) { unsigned long code; archive >> code; #line 261 _ASSERT(code == 'Darr'); if (mItemCount > 0) RemoveItemsAt(mItemCount, 1); int count; archive >> count; unsigned int item; for (int i = 0; i < count; i++) { archive >> item; Add(&item); } } /*virtual*/ void LArray::ReadAsChar(T2Archive& archive) { if (mItemCount > 0) RemoveItemsAt(mItemCount, 1); int i; int elemSize; int elemCount; int byteCount; int byteCount2; int totalSize; unsigned char buf; archive >> elemSize; archive >> elemCount; archive >> byteCount; archive >> byteCount2; archive >> totalSize; for (i = 0; i < elemCount; i++) { archive >> buf; Add(&buf); } for (; i < totalSize; i++) { archive >> buf; } } /*virtual*/ void LArray::WriteAsDWord(T2Archive& archive) { unsigned long code = 'Darr'; archive << code; archive << mItemCount; LArrayIterator iter(*this); unsigned int item; while (iter.Next(&item)) { archive << item; } } /*virtual*/ void LArray::WriteAsChar(T2Archive& archive) { int elemSize = 1; int byteCount = mItemCount; int byteCount2 = byteCount; int totalSize = byteCount; archive << elemSize; archive << mItemCount; archive << byteCount; archive << byteCount2; archive << totalSize; LArrayIterator iter(*this); unsigned char item; while (iter.Next(&item)) { archive << item; } } 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; } LDefaultComparator::LDefaultComparator() { } /*virtual*/ LDefaultComparator::~LDefaultComparator() { }