persistentstorage/dbms/pcdbms/udbms/UD_ROW.CPP
changeset 0 08ec8eefde2f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/persistentstorage/dbms/pcdbms/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"
+#include "D32Assert.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<ix)
+		{
+		ix=0;
+		pC=iFirst;
+		}
+	else
+		pC=iCell;
+	TDbCell* last=iLast;
+	for (;;)
+		{
+		if (pC>=last)
+			break;
+		if (ix>=aColIx)
+			break;
+		pC=pC->Next();
+		++ix;
+		}
+	CONST_CAST(RDbRow*,this)->SetCache(pC,ix);
+	return pC<last?pC:0;
+	}
+
+LOCAL_C const TDbCell* NullCell()
+	{
+	static TUint32 const NullCell[3]={0,0,0};	// 3 zero words represent any "Null" value
+//
+	return REINTERPRET_CAST(const TDbCell*,&NullCell[0]);
+	}
+
+EXPORT_C const TDbCell* RDbRow::ColCell(TDbColNo aColNo) const
+	{
+	__ASSERT(aColNo>0);
+	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();
+	}