diff -r 000000000000 -r 08ec8eefde2f persistentstorage/dbms/udbms/UD_ROW.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/persistentstorage/dbms/udbms/UD_ROW.CPP Fri Jan 22 11:06:30 2010 +0200 @@ -0,0 +1,270 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include "UD_STD.H" + +#define UNUSED_VAR(a) a = a + +// Class TDbColumn + +EXPORT_C void TDbColumn::SetL(const TAny* aPtr,TInt aSize) + { + Mem::Copy(Row().SetColumnWidthL(iColumn,aSize),aPtr,aSize); + } + +EXPORT_C void TDbColumn::SetL(TUint32 aValue) + { + *(TUint32*)Row().SetColumnWidthL(iColumn,sizeof(aValue))=aValue; + } + +EXPORT_C void TDbColumn::SetL(TInt64 aValue) + { + *(TInt64*)Row().SetColumnWidthL(iColumn,sizeof(aValue))=aValue; + } + +EXPORT_C void TDbColumn::SetL(TReal32 aValue) __SOFTFP + { + *(TReal32*)Row().SetColumnWidthL(iColumn,sizeof(aValue))=aValue; + } + +EXPORT_C void TDbColumn::SetL(TReal64 aValue) __SOFTFP + { + *(TReal64*)Row().SetColumnWidthL(iColumn,sizeof(aValue))=aValue; + } + +EXPORT_C void TDbColumn::SetL(const TDesC8& aValue) + { + SetL(aValue.Ptr(),aValue.Length()); + } + +EXPORT_C void TDbColumn::SetL(const TDesC16& aValue) + { + SetL(aValue.Ptr(),aValue.Length()<<1); + } + +EXPORT_C void TDbColumn::SetBlobL(TDbBlobId aBlobId,TInt aSize) + { + new(Row().SetColumnWidthL(iColumn,TDbBlob::RefSize())) TDbBlob(aBlobId,aSize); + } + +EXPORT_C void TDbColumn::SetBlobL(const TUint8* aData,TInt aSize) + { + new(Row().SetColumnWidthL(iColumn,TDbBlob::InlineSize(aSize))) TDbBlob(aData,aSize); + } + +EXPORT_C TDbBlob& TDbColumn::InitBlobL() + { + return *new(Row().SetColumnWidthL(iColumn,sizeof(TDbBlob))) TDbBlob; + } + +EXPORT_C void TDbColumn::CommitBlob(const TDbBlob& aBlob) + { +#if defined(_DEBUG) + TDbColumnC colC(*this); + __ASSERT(&colC.Blob()==&aBlob); + __ASSERT(colC.Size()>=aBlob.CellSize()); +#endif + TRAPD(errCode, Row().SetColumnWidthL(iColumn,aBlob.Size() ? aBlob.CellSize() : 0)); + UNUSED_VAR(errCode); + } + +// The row buffer +// Minimum data width is 4 bytes for strict alignment +// No integral set members for small integers and extractors do the cast down from 4-byte integers + +EXPORT_C RDbRow::RDbRow() +// +// default to dynamic-owned empty row buffer +// + :iFirst(0),iLast(0),iEnd(0),iCell(0),iColumn(TUint(EOwned)) + {} + +EXPORT_C void RDbRow::Open(TAny* aBuf,TInt aSize,TInt aMaxSize) +// +// Use the provided row buffer +// + { + iFirst=(TDbCell*)aBuf; + iEnd=PtrAdd(iFirst,aMaxSize); + iColumn=0; // non-owned buffer + SetSize(aSize); + } + +EXPORT_C void RDbRow::CreateL(TInt aMaxSize) + { + __ASSERT(!iFirst && Owned()); + GrowL(aMaxSize); + } + +void RDbRow::PushL() +// +// Dynamic reallocation requires that the buffer is pushed +// + { + CleanupClosePushL(*this); + } + +EXPORT_C void RDbRow::Close() +// +// release the buffer if owned, and return to default constructed state +// + { + if (Owned()) + User::Free(iFirst); + iFirst=iLast=iEnd=iCell=0; + iColumn=TUint(EOwned); + } + +EXPORT_C void RDbRow::SetSize(TInt aSize) +// +// Set the current buffer size: assert that it is valid +// + { + __ASSERT(PtrAdd(iFirst,aSize)<=iEnd); + iLast=PtrAdd(iFirst,aSize); + SetCache(iFirst,0); + } + +EXPORT_C void RDbRow::GrowL(TInt aMaxSize) +// +// Grow the buffer to at least aMaxSize, the buffer empty on return +// + { + if (aMaxSize>MaxSize()) + { + ReallocL(aMaxSize); + Reset(); + // + __ASSERT(iFirst<=iEnd); + __ASSERT(iFirst<=iLast && iLast<=iEnd); + __ASSERT(iFirst<=iCell && iCell<=iLast); + } + } + +void RDbRow::ExtendL(TInt aAdjust) +// +// Adjust the buffer length by aAdjust, leave if no room, preserve contents and cache +// + { + TDbCell* newLast=PtrAdd(iLast,aAdjust); + if (newLast>iEnd) + { + TInt move=ReallocL(Diff(iFirst,newLast)); + iCell=PtrAdd(iCell,move); + newLast=PtrAdd(newLast,move); + } + iLast=newLast; +// check invariant + __ASSERT(iFirst<=iEnd); + __ASSERT(iFirst<=iLast && iLast<=iEnd); + __ASSERT(iFirst<=iCell && iCell<=iLast); + } + +TInt RDbRow::ReallocL(TInt aMaxSize) +// +// Grow the buffer to aMaxSize, return the offset of buffer movement +// leave iLast and cache untouched +// + { + __ASSERT(aMaxSize>MaxSize()); + if (!Owned()) + __LEAVE(KErrTooBig); // cannot reallocate if not owned +// + aMaxSize+=EGranularity-1; + aMaxSize&=~(EGranularity-1); + TDbCell* buf=(TDbCell*)User::ReAllocL(iFirst,aMaxSize); + TInt move=Diff(iFirst,buf); + iFirst=buf; + iEnd=PtrAdd(buf,aMaxSize); + return move; + } + +TDbCell* RDbRow::Column(TInt aColIx) const +// +// aCol is now zero-based +// Return a pointer to column aCol in the buffer +// Return 0 if the column is past the end +// + { + TInt ix=Column(); + TDbCell* pC; + if (aColIx=last) + break; + if (ix>=aColIx) + break; + pC=pC->Next(); + ++ix; + } + CONST_CAST(RDbRow*,this)->SetCache(pC,ix); + return pC0); + const TDbCell* cell=Column(aColNo-1); + return cell && cell->Length() ? cell : NullCell(); + } + +EXPORT_C TAny* RDbRow::SetColumnWidthL(TDbColNo aColNo,TInt aWidth) +// set the width for column aCol to Width +// add extra NULL columns to buffer as required +// return pointer to data for that column + { + __ASSERT(aColNo>0); + TDbCell* pC=Column(--aColNo); + if (pC==0) + { // add extra NULL columns to buffer + if (aWidth==0) + return 0; // setting to NULL, don't bother padding + TInt cFill=(aColNo-iColumn)*sizeof(TInt); + ExtendL(cFill+TDbCell::Size(aWidth)); + pC=iCell; + Mem::FillZ(pC,cFill); + pC=PtrAdd(pC,cFill); // set cache + SetCache(pC,aColNo); + } + else + { + TInt adjust=TDbCell::Size(aWidth)-pC->Size(); // how much to add + if (adjust!=0) + { + ExtendL(adjust); + pC=iCell; // may have moved in extension + TDbCell* pNext=pC->Next(); + TDbCell* pAdjust=PtrAdd(pNext,adjust); + Mem::Move(pAdjust,pNext,Diff(pAdjust,iLast)); + } + } + pC->SetLength(aWidth); + return pC->Data(); + }