Symbian
Symbian OS Library

FAQ-0813 How can I read from a socket into the middle of a descriptor?

[Index][spacer] [Previous] [Next]



 

Classification: C++ Category: Comms
Created: 09/02/2002 Modified: 09/11/2002
Number: FAQ-0813
Platform: Not Applicable

Question:
I'm reading packets of data from a socket into a buffer with consecutive reads. If the data in the buffer has not been processed before the next read, how can I append the packet to the data in the existing buffer without creating an extra buffer?

Answer:
You can, with a little effort, manufacture a TPtr descriptor to point to the position in the buffer where the last read ended, and pass that to the socket's read method. The code below shows how this might be done.

    // socket varables
    RSocket socket;
    TUint flags;
    TRequestStatus status;
    TSockXfrLength length; // not made use of below: a defect means it does not get set in RecvOneOrMore.
    ...
    // create an array of unsigned ints const TInt KMaxLength = 120;
    TBuf buf;
    TUint16* data = CONST_CAST(TUint16*, buf.Ptr());
    // create a TPtr descriptor arbitrarily pointing to the buffer
    TPtr ptr(data, 0, KMaxLength);
    TInt offset = 0;
    while (true)
    {
    // make the TPtr point to the right place in the buffer
    ptr.Set(&data[offset], 0, KMaxLength-offset);
    // now read the data into ptr, so appending it to buf
    socket.RecvOneOrMore(ptr, flags, status, length);
    User::WaitForRequest(status);
    if (status) break;
    offset += ptr.Length();
    }

    You must take care that buf.Length() will return zero: use the offset parameter to keep track on how much data is in your buffer. Also, if you are consuming the data on a separate thread, you will need to ensure the value of offset as well as data is shared between the threads and that you don't consume data beyond data[offset-1]. In practice, of course you would probably want to do this with active objects rather than using User::WaitForRequest(...) and processing the data on a separate thread. Checks should be made too that KMaxLength is not exceeded.