RSqlBufFlat Class Reference

class RSqlBufFlat

RSqlBufFlat class manages a flat memory buffer with fixed elements count. Each element (or field) of the flat buffer has a type and variable length data and is accessible using an index. The data may be NULL. The RSqlBufFlat objects are used for sending/receiving data between client dlls and servers, because once the buffer filled, a pointer to the flat buffer data can be used to send the whole buffer in a single IPC call, which is more effective than using a stream like transfer.

RSqlBufFlat public functions are not very convenient for storing/retrieving values based on the column type and there are two additional classes which may be used instead of working with the flat buffer directly: TSqlBufRIterator and TSqlBufWIterator.

The physical structure of the flat buffer is: --------------------------- | SysData | Header | Data | ---------------------------
  • "SysData" has fixed length and contains fields with about the buffer used size, elements count, header size;

  • "Header" has fixed length, which depends of the number of elements and contains cells, one per element. Each cell contains information about: element type, element data length, the start position of the element data in the flat buffer, "present"/"not present" flag. "Not present" means that no memory is reserved for the element data, but the buffer "knows" what is the element type and element data length; (In the current design there is no "Present"/"Not present flag". If the data position is 0, that indicates the element is "Not present"). See RSqlBufFlat::TCell comments for details.

  • "Data" Is the dynamic part of the buffer which may grow during the operations with the flat buffer (setting element data);

"Present"/"Not present" attribute has a key role in the large data transfers between the client and the server. In order to optimize memory usage, usually the client specifies what can be the max field size. The server knows that and when it fills a particular flat buffer, which has to be sent to the client, it puts in the flat buffer only the pieces of data whose size is less than the specified "large data" size. Any data piece whose size is larger will be set as "Not present" in the flat buffer. The "Not present" field will have all the attributes, like type and size, but won't have any data or any allocated flat buffer memory. So the client, when it receives the flat buffer, will know the field type and size and if it wants to get the field data, will have to make an additional call to the server.

Note that the fields in the buffer are 8-byte aligned.

Typical examples how the buffer can be used:

Case 1 - a dll client wants to receive from the server a flat buffer data.

RSqlBufFlat bufFlat;
bufFlat.SetCount(N);								//N is the field count
....
bufFlat.Reset();									//Clears the content of the buffer without shrinking it.
ipcArgs.Set(0, bufFlat.MaxSize());					//Tell the server what is the flat buffer max size
ipcArgs.Set(1, &bufFlat.BufPtr());
TInt rc = session.SendReceive(funcNum, ipcArgs);
if(rc > KSqlClientBufOverflowCode)
	{												//the client buffer is not big enough and has to be resized
	rc = bufFlat.ReAlloc(err - KSqlClientBufOverflowCode);
	if(rc != KErrNone)
		{
		return rc;
		}
	ipcArgs.Set(0, bufFlat.MaxSize());
	ipcArgs.Set(1, &bufFlat.BufPtr());
	rc = session.SendReceive(funcNum, ipcArgs);
	}

Case 2 - a dll client wants to send to the server a flat buffer data.

RSqlBufFlat bufFlat;
bufFlat.SetCount(N);								//N is the field count
....
TPtrC8 ptr(bufFlat.BufDes());
TInt err = session.SendReceive(funcNum, TIpcArgs(ptr.Length(), &ptr));
Case 3 - the server wants to return to the client a flat buffer data.
RSqlBufFlat bufFlat;
bufFlat.SetCount(N);								//N is the field count
....
TInt maxCliBufSize = msg.Int0();					//The max size of the client buffer
if(maxCliBufSize < bufFlat.Size())
	{
	return bufFlat.Size() + KSqlClientBufOverflowCode;//Tell the client that its buffer is too small
	}
msg.WriteL(1, bufFlat.BufDes());
Case 4 - the server wants to receive from the client a flat buffer data.
RSqlBufFlat bufFlat;
bufFlat.SetCount(N);								//N is the field count
....
TInt cliBufFlatLen = aMessage.Int0();
TInt err = bufFlat.ReAlloc(cliBufFlatLen);			//Reallocate memory for the flat buffer
if(err != KErrNone)
	{
	return err;
	}
msg.ReadL(1, bufFlat.BufPtr());
Case 5 - the server (or the client) wants to fill the flat buffer with some data.
RSqlBufFlat bufFlat;
bufFlat.SetCount(N);								//N is the field count
....
TInt err = flatBuf.SetCount(M);						//If the field count has to be changed to M
if(err != KErrNone)
	{
	return err;
	}
//use the TSqlBufWIterator iterator to fill the buffer

TSqlBufRIterator TSqlBufWIterator RSqlBufFlat::TCell RSqlBufFlat::TBufFlat

Nested Classes and Structures

Public Member Functions
RSqlBufFlat()
const TDesC8 &BufDes()
TPtr8 &BufPtr()
voidClose()
TInt Count()
TInt MaxSize()
TInt ReAlloc(TInt)
voidReset()
voidResetAndMinimize()
TInt SetCount(TInt)
TInt SetField(TInt, TInt, const void *, TInt)
TInt Size()
Private Member Functions
TInt Available()
voidDoInit()
TInt DoReAlloc(TInt)
voidDoSet(TInt, TInt, const void *, TInt)
const TCell *Header()
TCell *Header()
voidInvariant()
TInt Reserve(TInt)
TInt SysDataSize()
Public Member Enumerations
enumanonymous { EWidthType = 3, EWidthLen = 29 }
enumanonymous { EMaxType = 1 << EWidthType, EMaxLength = 1 << EWidthLen }
Private Attributes
TBufFlat *iBuf
TPtr8 iBufPtr
TPtrC8 iBufPtrC
TInt iMaxSize

Constructor & Destructor Documentation

RSqlBufFlat()

RSqlBufFlat()

Sets the flat buffer pointer to NULL

Member Functions Documentation

Available()

TInt Available()const [private, inline]

BufDes()

const TDesC8 &BufDes()const [inline]

This function returns a const reference to a descriptor object pointing to the internal buffer. BufDes() guarantees to return a const descriptor, whose lifetime is the same as the flat buffer lifetime. (useful when making asynchronous IPC calls)

BufPtr()

TPtr8 &BufPtr()[inline]

This function returns a modifiable reference to a descriptor object pointing to the internal buffer. BufPtr() guarantees to return a modifiable descriptor, whose lifetime is the same as the flat buffer lifetime. (useful when making asynchronous IPC calls)

Close()

voidClose()

Closes the flat bufer and frees the allocated memory.

Count()

TInt Count()const [inline]

DoInit()

voidDoInit()[private]
Initialzies the flat buffer header. All field set:
  • invalid type;

  • zero length;

  • "Not present";

DoReAlloc(TInt)

TInt DoReAlloc(TIntaSize)[private]

Reallocates the amount of the occupied by the flat buffer memory (only in case the requested size is bigger than the buffer size or the buffer does not exist). The operation preserves the content of the flat buffer.

Parameters

TInt aSizeDesired flat buffer size in bytes.

DoSet(TInt, TInt, const void *, TInt)

voidDoSet(TIntaIndex,
TIntaType,
const void *aData,
TIntaDataLength
)[private]

Initialzes a flat buffer field. A memory for the field data has to be allocated before the call.

Parameters

TInt aIndexField index
TInt aTypeField type
const void * aDataField data, may be NULL
TInt aDataLengthField data length, may be 0

Header()

const TCell *Header()const [private, inline]

Header()

TCell *Header()[private, inline]

Invariant()

voidInvariant()const [private]

MaxSize()

TInt MaxSize()const [inline]

ReAlloc(TInt)

TInt ReAlloc(TIntaSize)

Reallocates the amount of the occupied by the flat buffer memory. The operation preserves the content of the flat buffer. Note: if the new size is less or equal to the max size of the buffer, no memory will be allocated.

Parameters

TInt aSizeDesired flat buffer size in bytes

Reserve(TInt)

TInt Reserve(TIntaLength)[private]

Makes sure that the flat buffer has enough free space for a block of data with "aLength" length. The function may reallocated the buffer if there is not enough space.

Parameters

TInt aLengthThe requested free memory length.

Reset()

voidReset()

Cleans up the flat buffer content but does not free the occupied memory. The count of elements is preserved.

All elements set to have:
  • invalid type;

  • zero length;

  • zero data position;

The element count is preserved.

ResetAndMinimize()

voidResetAndMinimize()

Cleans up the flat buffer content and frees the occupied memory if the memory is above KBufLimit. The count of elements is preserved.

If the buffer size is bigger than KBufLimit, the buffer will be reallocated and the buffer content - not preserved.

If the buffer size is less or equal to KBufLimit, no memory will be reallocated and the buffer preserves its content.

It is guaranteed that the reallocated buffer will have the same address in the heap as the original one.

SetCount(TInt)

TInt SetCount(TIntaCount)

"Resource acquisiton" method. Sets the elements count of a new or already existing flat buffer.

The occupied memory won't be freed (in case of buffer resizing). The buffer content is not preserved (in case of buffer resizing).

All elements set to have:
  • invalid type;

  • zero length;

  • zero data position;

Parameters

TInt aCountDesired flat buffer elements count

SetField(TInt, TInt, const void *, TInt)

TInt SetField(TIntaIndex,
TIntaType,
const void *aData,
TIntaDataLength
)

Sets the content of a field.

Parameters

TInt aIndexField index
TInt aTypeField type
const void * aDataField data, may be NULL
TInt aDataLengthField data length, may be 0

Size()

TInt Size()const [inline]

SysDataSize()

TInt SysDataSize()const [private, inline]

Member Enumerations Documentation

Enum anonymous

Enumerators

EWidthType = 3
EWidthLen = 29

Enum anonymous

Enumerators

EMaxType = 1 << EWidthType
EMaxLength = 1 << EWidthLen

Member Data Documentation

TBufFlat * iBuf

TBufFlat *iBuf[private]

TPtr8 iBufPtr

TPtr8 iBufPtr[private]

TPtrC8 iBufPtrC

TPtrC8 iBufPtrC[private]

TInt iMaxSize

TInt iMaxSize[private]