📄 chxflatarray.cpp
字号:
/* ***** BEGIN LICENSE BLOCK ***** * Source last modified: $Id: CHXFlatArray.cpp,v 1.4.2.3 2004/07/09 01:49:47 hubbe Exp $ * * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved. * * The contents of this file, and the files included with this file, * are subject to the current version of the RealNetworks Public * Source License (the "RPSL") available at * http://www.helixcommunity.org/content/rpsl unless you have licensed * the file under the current version of the RealNetworks Community * Source License (the "RCSL") available at * http://www.helixcommunity.org/content/rcsl, in which case the RCSL * will apply. You may also obtain the license terms directly from * RealNetworks. You may not use this file except in compliance with * the RPSL or, if you have a valid RCSL with RealNetworks applicable * to this file, the RCSL. Please see the applicable RPSL or RCSL for * the rights, obligations and limitations governing use of the * contents of the file. * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL") in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your version of * this file only under the terms of the GPL, and not to allow others * to use your version of this file under the terms of either the RPSL * or RCSL, indicate your decision by deleting the provisions above * and replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient may * use your version of this file under the terms of any one of the * RPSL, the RCSL or the GPL. * * This file is part of the Helix DNA Technology. RealNetworks is the * developer of the Original Code and owns the copyrights in the * portions it created. * * This file, and the files included with this file, is distributed * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET * ENJOYMENT OR NON-INFRINGEMENT. * * Technology Compatibility Kit Test Suite(s) Location: * http://www.helixcommunity.org/content/tck * * Contributor(s): * * ***** END LICENSE BLOCK ***** */#include "CHXFlatArray.h"#include "CHXClientDebug.h"#include "hlxclib/stdlib.h"#include "hlxclib/memory.h"CHXFlatArray::CHXFlatArray(UINT32 recordSize) : mRecordSize(recordSize) , mCount(0) , mpData(NULL) , mDataSize(0){ CHXASSERT(mRecordSize < 0x10000L); // we're probably being instantiated badly if this happens CHXASSERT(mRecordSize > 0);}CHXFlatArray::CHXFlatArray(UINT32 recordSize, const void* firstItemPtr) : mRecordSize(recordSize) , mCount(0) , mpData(NULL) , mDataSize(0){ SetToDataAt(firstItemPtr, recordSize);}CHXFlatArray::CHXFlatArray(const CHXFlatArray& sourceArray){ mpData = NULL; mDataSize = 0; *this = sourceArray;}CHXFlatArray& CHXFlatArray::operator=(const CHXFlatArray& sourceArray){ // do nothing if we're copying ourselves if (this == &sourceArray) return *this; mRecordSize = sourceArray.mRecordSize; if (InternalReplaceAllData(sourceArray.mpData, sourceArray.mDataSize)) { mCount = sourceArray.mCount; } else { mCount = 0; } return *this;}CHXFlatArray& CHXFlatArray::operator+=(const CHXFlatArray& array2){ CHXASSERT(mRecordSize == array2.mRecordSize || mRecordSize == 0); if (mRecordSize == array2.mRecordSize || mRecordSize == 0) { if (mCount == 0 || mpData == NULL) { *this = array2; } else { if (InternalAppendData(array2.mpData, array2.mDataSize)) { mCount += array2.mCount; } } } return *this;}CHXFlatArray::~CHXFlatArray(){ if (mpData) { free(mpData); mDataSize = 0; }}UINT32 CHXFlatArray::CopyDataTo(void *pOutBuff, UINT32 buffSize) const{ UINT32 bytesToCopy; bytesToCopy = mDataSize; if (bytesToCopy > buffSize) { bytesToCopy = buffSize; } if (mpData && bytesToCopy) { memcpy(pOutBuff, mpData, bytesToCopy); } return bytesToCopy;}bool CHXFlatArray::SetToDataAt(const void *pBuff, UINT32 buffSize){ if(mRecordSize <= 0) return false; if(buffSize % mRecordSize != 0) return false; if (InternalReplaceAllData(pBuff, buffSize)) { mCount = buffSize / mRecordSize; return true; } else { mCount = 0; return false; }}bool CHXFlatArray::SetAt(UINT32 recordNum, const void *itemPtr){ if(mRecordSize <= 0) return false; // forgot to set record size for array UINT32 newRecordCount = recordNum + 1; if (newRecordCount > mCount) { // allocate more slots for records UINT32 oldSize, newSize; newSize = mRecordSize * newRecordCount; oldSize = mRecordSize * mCount; CHXASSERT(oldSize == mDataSize); if (!InternalAppendData(NULL, newSize - oldSize)) return false; // zero out the new slots memset(oldSize + mpData, 0, newSize - oldSize); mCount = newRecordCount; } if (itemPtr != NULL) { memcpy((recordNum * mRecordSize) + mpData, itemPtr, mRecordSize); } return true;}bool CHXFlatArray::GetAt(UINT32 recordNum, void *outItemPtr) const{ if(mRecordSize <= 0) return false; // forgot to set record size for array if(recordNum >= mCount) return false; UINT8* recordPtr = mpData + (mRecordSize * recordNum); if (outItemPtr) { memcpy(outItemPtr, recordPtr, mRecordSize); } return true;}bool CHXFlatArray::InsertBefore(UINT32 recordNum, const void *itemPtr){ // parameter should be between 0 and mCount (since mCount is 1 greater than the max valid index) if(recordNum > mCount) return false; UINT32 recordOffset = mRecordSize * recordNum; if (InternalInsertData(recordOffset, itemPtr, mRecordSize)) { mCount++; return true; } return false;}bool CHXFlatArray::Remove(UINT32 recordNum){ // parameter should be between 0 and mCount (since mCount is 1 greater than the max valid index) if(recordNum >= mCount) return false; // move all records down UINT32 recordDataOffset = mRecordSize * recordNum; if (InternalDeleteData(recordDataOffset, mRecordSize)) { mCount--; return true; } return false;}void CHXFlatArray::RemoveAll(){ InternalDeleteAllData(); mCount = 0;}bool CHXFlatArray::SetCount(UINT32 numRecords){ if(mRecordSize <= 0) return false; // forgot to set record size for array if (numRecords == mCount) return true; // if we need to lengthen the array, use SetAt if (numRecords > mCount) return SetAt(numRecords - 1, NULL); // shorten the array if (InternalTruncateData((mCount - numRecords) * mRecordSize)) { mCount = numRecords; return true; } return false;}bool CHXFlatArray::FindRecord(const void *matchPtr, AreElementsEqualProcPtr AreElementsEqual, UINT32 startAtRecordNum, UINT32 *outFoundRecordNum, void *outFoundRecordPtr) const{ UINT32 idx; for (idx = startAtRecordNum; idx < mCount; idx++) { UINT8* recordPtr = mpData + (mRecordSize * idx); if (AreElementsEqual(recordPtr, matchPtr)) { if (outFoundRecordNum) { *outFoundRecordNum = idx; } if (outFoundRecordPtr) { memcpy(outFoundRecordPtr, recordPtr, mRecordSize); } return true; } } return false;}bool CHXFlatArray::DiffRecords(AreElementsEqualProcPtr AreElementsEqual, const CHXFlatArray& recordDataToSubtract){ if(mRecordSize <= 0 || mRecordSize != recordDataToSubtract.mRecordSize) return false; for (int idx = mCount - 1; idx >= 0; idx--) { UINT8* recordPtr = mpData + (mRecordSize * idx); if (recordDataToSubtract.HasRecord(recordPtr, AreElementsEqual)) { Remove(idx); } } return true;}bool CHXFlatArray::SectRecords(AreElementsEqualProcPtr AreElementsEqual, const CHXFlatArray& recordDataToIntersect){ if(mRecordSize <= 0 || mRecordSize != recordDataToIntersect.mRecordSize) return false; for (int idx = mCount - 1; idx >= 0; idx--) { UINT8* recordPtr = mpData + (mRecordSize * idx); if (!recordDataToIntersect.HasRecord(recordPtr, AreElementsEqual)) { Remove(idx); } } return true;}// the internal routines that follow do not adjust record counts at all; routines that// call these should manage recordsbool CHXFlatArray::InternalReplaceAllData(const void *pReplacementData, UINT32 replacementDataSize){ // get rid of old data if (mpData) { free(mpData); mpData = NULL; mDataSize = 0; } if (!replacementDataSize) return true; mpData = (UINT8*)malloc(replacementDataSize); if (!mpData) return false; // copy the data into a new allocation mDataSize = replacementDataSize; memcpy(mpData, pReplacementData, mDataSize); return true;}bool CHXFlatArray::InternalInsertData(UINT32 insertBeforeOffset, const void *pInsertData, UINT32 insertDataSize){ // insertBeforeOffset is 0-based; max legal value is mDataSize, which inserts at end of all // data (though it's easier to use InternalAppendData for that) // // It is valid for pInsertData to be NULL, meaning don't initialize the inserted data space if(insertBeforeOffset > mDataSize) return false; if (insertDataSize == 0) return true; UINT8* pNewData = (UINT8*)malloc(mDataSize + insertDataSize); CHXASSERT(pNewData != NULL); if (!pNewData ) return false; if (mpData != NULL && insertBeforeOffset > 0) { memcpy(pNewData, mpData, insertBeforeOffset); } if (pInsertData) { memcpy(pNewData + insertBeforeOffset, pInsertData, insertDataSize); } if (mpData != NULL && insertBeforeOffset < mDataSize) { memcpy(pNewData + insertBeforeOffset + insertDataSize, mpData + insertBeforeOffset, mDataSize - insertBeforeOffset); } if (mpData) free(mpData); mpData = pNewData; mDataSize += insertDataSize; return true;}bool CHXFlatArray::InternalDeleteData(UINT32 deleteAtOffset, UINT32 deleteDataSize){ // deleteAtOffset is 0-based; max legal value is mDataSize - 1 if (mDataSize == 0 && deleteDataSize == 0) return true; if(deleteAtOffset > (mDataSize - 1)) return false; if((deleteAtOffset + deleteDataSize) > mDataSize) return false; if (deleteDataSize == mDataSize) { CHXASSERT(deleteAtOffset == 0); free(mpData); mpData = NULL; mDataSize = 0; return true; } else if (deleteDataSize > 0) { UINT8* pNewData = (UINT8*)malloc(mDataSize - deleteDataSize); CHXASSERT(pNewData != NULL); if (pNewData && mpData != NULL) { if (deleteAtOffset > 0) { memcpy(pNewData, mpData, deleteAtOffset); } if (deleteAtOffset < mDataSize - 1) { memcpy(pNewData + deleteAtOffset, mpData + deleteAtOffset + deleteDataSize, mDataSize - (deleteAtOffset + deleteDataSize)); } free(mpData); mpData = pNewData; mDataSize -= deleteDataSize; return true; } } return false;}//// The remaining routines are independent of data storage method//bool CHXFlatArray::SetRecordSize(UINT32 recordSize){ CHXASSERT(mRecordSize == 0 || mRecordSize == recordSize); mRecordSize = recordSize; RemoveAll(); return true;}bool CHXFlatArray::Push(const void *itemPtr){ return SetAt(mCount, itemPtr);}bool CHXFlatArray::Pop(void *itemPtr){ if (GetAt(mCount - 1, itemPtr)) { (void) Remove(mCount - 1); return true; } return false;}bool CHXFlatArray::Enqueue(const void *itemPtr){ return SetAt(mCount, itemPtr);}bool CHXFlatArray::Dequeue(void *itemPtr){ if (GetAt(0, itemPtr)) { (void) Remove(0); return true; } return false;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -