persistentstorage/dbms/pcdbms/udbms/UD_ROW.CPP
changeset 0 08ec8eefde2f
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "UD_STD.H"
       
    17 #include "D32Assert.h"
       
    18 #define UNUSED_VAR(a) a = a
       
    19 
       
    20 // Class TDbColumn
       
    21 
       
    22 EXPORT_C void TDbColumn::SetL(const TAny* aPtr,TInt aSize)
       
    23 	{
       
    24 	Mem::Copy(Row().SetColumnWidthL(iColumn,aSize),aPtr,aSize);
       
    25 	}
       
    26 
       
    27 EXPORT_C void TDbColumn::SetL(TUint32 aValue)
       
    28 	{
       
    29 	*(TUint32*)Row().SetColumnWidthL(iColumn,sizeof(aValue))=aValue;
       
    30 	}
       
    31 
       
    32 EXPORT_C void TDbColumn::SetL(TInt64 aValue)
       
    33 	{
       
    34 	*(TInt64*)Row().SetColumnWidthL(iColumn,sizeof(aValue))=aValue;
       
    35 	}
       
    36 
       
    37 EXPORT_C void TDbColumn::SetL(TReal32 aValue) __SOFTFP
       
    38 	{
       
    39 	*(TReal32*)Row().SetColumnWidthL(iColumn,sizeof(aValue))=aValue;
       
    40 	}
       
    41 
       
    42 EXPORT_C void TDbColumn::SetL(TReal64 aValue) __SOFTFP
       
    43 	{
       
    44 	*(TReal64*)Row().SetColumnWidthL(iColumn,sizeof(aValue))=aValue;
       
    45 	}
       
    46 
       
    47 EXPORT_C void TDbColumn::SetL(const TDesC8& aValue)
       
    48 	{
       
    49 	SetL(aValue.Ptr(),aValue.Length());
       
    50 	}
       
    51 
       
    52 EXPORT_C void TDbColumn::SetL(const TDesC16& aValue)
       
    53 	{
       
    54 	SetL(aValue.Ptr(),aValue.Length()<<1);
       
    55 	}
       
    56 
       
    57 EXPORT_C void TDbColumn::SetBlobL(TDbBlobId aBlobId,TInt aSize)
       
    58 	{
       
    59 	new(Row().SetColumnWidthL(iColumn,TDbBlob::RefSize())) TDbBlob(aBlobId,aSize);
       
    60 	}
       
    61 
       
    62 EXPORT_C void TDbColumn::SetBlobL(const TUint8* aData,TInt aSize)
       
    63 	{
       
    64 	new(Row().SetColumnWidthL(iColumn,TDbBlob::InlineSize(aSize))) TDbBlob(aData,aSize);
       
    65 	}
       
    66 
       
    67 EXPORT_C TDbBlob& TDbColumn::InitBlobL()
       
    68 	{
       
    69 	return *new(Row().SetColumnWidthL(iColumn,sizeof(TDbBlob))) TDbBlob;
       
    70 	}
       
    71 
       
    72 EXPORT_C void TDbColumn::CommitBlob(const TDbBlob& aBlob)
       
    73 	{
       
    74 #if defined(_DEBUG)
       
    75 	TDbColumnC colC(*this);
       
    76 	__ASSERT(&colC.Blob()==&aBlob);
       
    77 	__ASSERT(colC.Size()>=aBlob.CellSize());
       
    78 #endif
       
    79 	TRAPD(errCode, Row().SetColumnWidthL(iColumn,aBlob.Size() ? aBlob.CellSize() : 0));
       
    80     UNUSED_VAR(errCode);
       
    81 	}
       
    82 
       
    83 // The row buffer
       
    84 // Minimum data width is 4 bytes for strict alignment
       
    85 // No integral set members for small integers and extractors do the cast down from 4-byte integers
       
    86 
       
    87 EXPORT_C RDbRow::RDbRow()
       
    88 //
       
    89 // default to dynamic-owned empty row buffer
       
    90 //
       
    91 	:iFirst(0),iLast(0),iEnd(0),iCell(0),iColumn(TUint(EOwned))
       
    92 	{}
       
    93 
       
    94 EXPORT_C void RDbRow::Open(TAny* aBuf,TInt aSize,TInt aMaxSize)
       
    95 //
       
    96 // Use the provided row buffer
       
    97 //
       
    98 	{
       
    99 	iFirst=(TDbCell*)aBuf;
       
   100 	iEnd=PtrAdd(iFirst,aMaxSize);
       
   101 	iColumn=0;			// non-owned buffer
       
   102 	SetSize(aSize);
       
   103 	}
       
   104 
       
   105 EXPORT_C void RDbRow::CreateL(TInt aMaxSize)
       
   106 	{
       
   107 	__ASSERT(!iFirst && Owned());
       
   108 	GrowL(aMaxSize);
       
   109 	}
       
   110 
       
   111 void RDbRow::PushL()
       
   112 //
       
   113 // Dynamic reallocation requires that the buffer is pushed
       
   114 //
       
   115 	{
       
   116 	CleanupClosePushL(*this);
       
   117 	}
       
   118 
       
   119 EXPORT_C void RDbRow::Close()
       
   120 //
       
   121 // release the buffer if owned, and return to default constructed state
       
   122 //
       
   123 	{
       
   124 	if (Owned())
       
   125 		User::Free(iFirst);
       
   126 	iFirst=iLast=iEnd=iCell=0;
       
   127 	iColumn=TUint(EOwned);
       
   128 	}
       
   129 
       
   130 EXPORT_C void RDbRow::SetSize(TInt aSize)
       
   131 //
       
   132 // Set the current buffer size: assert that it is valid
       
   133 //
       
   134 	{
       
   135 	__ASSERT(PtrAdd(iFirst,aSize)<=iEnd);
       
   136 	iLast=PtrAdd(iFirst,aSize);
       
   137 	SetCache(iFirst,0);
       
   138 	}
       
   139 
       
   140 EXPORT_C void RDbRow::GrowL(TInt aMaxSize)
       
   141 //
       
   142 // Grow the buffer to at least aMaxSize, the buffer empty on return
       
   143 //
       
   144 	{
       
   145 	if (aMaxSize>MaxSize())
       
   146 		{
       
   147 		ReallocL(aMaxSize);
       
   148 		Reset();
       
   149 	//
       
   150 		__ASSERT(iFirst<=iEnd);
       
   151 		__ASSERT(iFirst<=iLast && iLast<=iEnd);
       
   152 		__ASSERT(iFirst<=iCell && iCell<=iLast);
       
   153 		}
       
   154 	}
       
   155 
       
   156 void RDbRow::ExtendL(TInt aAdjust)
       
   157 //
       
   158 // Adjust the buffer length by aAdjust, leave if no room, preserve contents and cache
       
   159 //
       
   160 	{
       
   161 	TDbCell* newLast=PtrAdd(iLast,aAdjust);
       
   162 	if (newLast>iEnd)
       
   163 		{
       
   164 		TInt move=ReallocL(Diff(iFirst,newLast));
       
   165 		iCell=PtrAdd(iCell,move);
       
   166 		newLast=PtrAdd(newLast,move);
       
   167 		}
       
   168 	iLast=newLast;
       
   169 // check invariant
       
   170 	__ASSERT(iFirst<=iEnd);
       
   171 	__ASSERT(iFirst<=iLast && iLast<=iEnd);
       
   172 	__ASSERT(iFirst<=iCell && iCell<=iLast);
       
   173 	}
       
   174 
       
   175 TInt RDbRow::ReallocL(TInt aMaxSize)
       
   176 //
       
   177 // Grow the buffer to aMaxSize, return the offset of buffer movement
       
   178 // leave iLast and cache untouched
       
   179 //
       
   180 	{
       
   181 	__ASSERT(aMaxSize>MaxSize());
       
   182 	if (!Owned())
       
   183 		__LEAVE(KErrTooBig);	// cannot reallocate if not owned
       
   184 //
       
   185 	aMaxSize+=EGranularity-1;
       
   186 	aMaxSize&=~(EGranularity-1);
       
   187 	TDbCell* buf=(TDbCell*)User::ReAllocL(iFirst,aMaxSize);
       
   188 	TInt move=Diff(iFirst,buf);
       
   189 	iFirst=buf;
       
   190 	iEnd=PtrAdd(buf,aMaxSize);
       
   191 	return move;
       
   192 	}
       
   193 
       
   194 TDbCell* RDbRow::Column(TInt aColIx) const
       
   195 //
       
   196 // aCol is now zero-based
       
   197 // Return a pointer to column aCol in the buffer
       
   198 // Return 0 if the column is past the end
       
   199 //
       
   200 	{
       
   201 	TInt ix=Column();
       
   202 	TDbCell* pC;
       
   203 	if (aColIx<ix)
       
   204 		{
       
   205 		ix=0;
       
   206 		pC=iFirst;
       
   207 		}
       
   208 	else
       
   209 		pC=iCell;
       
   210 	TDbCell* last=iLast;
       
   211 	for (;;)
       
   212 		{
       
   213 		if (pC>=last)
       
   214 			break;
       
   215 		if (ix>=aColIx)
       
   216 			break;
       
   217 		pC=pC->Next();
       
   218 		++ix;
       
   219 		}
       
   220 	CONST_CAST(RDbRow*,this)->SetCache(pC,ix);
       
   221 	return pC<last?pC:0;
       
   222 	}
       
   223 
       
   224 LOCAL_C const TDbCell* NullCell()
       
   225 	{
       
   226 	static TUint32 const NullCell[3]={0,0,0};	// 3 zero words represent any "Null" value
       
   227 //
       
   228 	return REINTERPRET_CAST(const TDbCell*,&NullCell[0]);
       
   229 	}
       
   230 
       
   231 EXPORT_C const TDbCell* RDbRow::ColCell(TDbColNo aColNo) const
       
   232 	{
       
   233 	__ASSERT(aColNo>0);
       
   234 	const TDbCell* cell=Column(aColNo-1);
       
   235 	return cell && cell->Length() ? cell : NullCell();
       
   236 	}
       
   237 
       
   238 EXPORT_C TAny* RDbRow::SetColumnWidthL(TDbColNo aColNo,TInt aWidth)
       
   239 // set the width for column aCol to Width
       
   240 // add extra NULL columns to buffer as required
       
   241 // return pointer to data for that column
       
   242 	{
       
   243 	__ASSERT(aColNo>0);
       
   244 	TDbCell* pC=Column(--aColNo);
       
   245 	if (pC==0)
       
   246 		{		// add extra NULL columns to buffer
       
   247 		if (aWidth==0)
       
   248 			return 0;	// setting to NULL, don't bother padding
       
   249 		TInt cFill=(aColNo-iColumn)*sizeof(TInt);
       
   250 		ExtendL(cFill+TDbCell::Size(aWidth));
       
   251 		pC=iCell;
       
   252 		Mem::FillZ(pC,cFill);
       
   253 		pC=PtrAdd(pC,cFill);		// set cache
       
   254 		SetCache(pC,aColNo);
       
   255 		}
       
   256 	else
       
   257 		{
       
   258 		TInt adjust=TDbCell::Size(aWidth)-pC->Size();	// how much to add
       
   259 		if (adjust!=0)
       
   260 			{
       
   261 			ExtendL(adjust);
       
   262 			pC=iCell;		// may have moved in extension
       
   263 			TDbCell* pNext=pC->Next();
       
   264 			TDbCell* pAdjust=PtrAdd(pNext,adjust);
       
   265 			Mem::Move(pAdjust,pNext,Diff(pAdjust,iLast));
       
   266 			}
       
   267 		}
       
   268 	pC->SetLength(aWidth);
       
   269 	return pC->Data();
       
   270 	}