bluetoothengine/bthid/bthidserver/src/datasegmenter.cpp
changeset 0 f63038272f30
equal deleted inserted replaced
-1:000000000000 0:f63038272f30
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  This is the implementation of application class
       
    15  *
       
    16 */
       
    17 
       
    18 
       
    19 #include "datasegmenter.h"
       
    20 
       
    21 CDataSegmenter* CDataSegmenter::NewL()
       
    22     {
       
    23     CDataSegmenter* self = NewLC();
       
    24     CleanupStack::Pop(self);
       
    25     return self;
       
    26     }
       
    27 
       
    28 CDataSegmenter* CDataSegmenter::NewLC()
       
    29     {
       
    30     CDataSegmenter* self = new (ELeave) CDataSegmenter();
       
    31     CleanupStack::PushL(self);
       
    32     self->ConstructL();
       
    33     return self;
       
    34     }
       
    35 
       
    36 CDataSegmenter::CDataSegmenter()
       
    37     {
       
    38     // No work to do
       
    39     }
       
    40 
       
    41 CDataSegmenter::~CDataSegmenter()
       
    42     {
       
    43     delete iPayloadBuf;
       
    44 
       
    45     delete iPacket;
       
    46     }
       
    47 
       
    48 void CDataSegmenter::SegmentDataL(const TDesC8& aInitialHeader,
       
    49         const TDesC8& aPayload, TChar aAdditionalHeaderByte, TInt aMTU)
       
    50     {
       
    51     // Store the continuation packet header byte and MTU
       
    52     iAdditionalHeaderByte = aAdditionalHeaderByte;
       
    53     iMTU = aMTU;
       
    54 
       
    55     // Determine the payload that will go in the first packet
       
    56     TInt initialPayLoadSize = Min((iMTU - aInitialHeader.Length()),
       
    57             aPayload.Length());
       
    58 
       
    59     // The initial packet size
       
    60     TInt initialSize = aInitialHeader.Length() + initialPayLoadSize;
       
    61 
       
    62     TPtr8 dataPtr(0, 0);
       
    63     if (!iPacket)
       
    64         {
       
    65         // Allocate the packet buffer, if it doesn't exist
       
    66         iPacket = HBufC8::NewL(initialSize);
       
    67         dataPtr.Set(iPacket->Des());
       
    68         }
       
    69     else
       
    70         {
       
    71         // Ensure the existing buffer is large enough to hold the new data
       
    72         dataPtr.Set(iPacket->Des());
       
    73         if (dataPtr.MaxLength() < initialSize)
       
    74             {
       
    75             delete iPacket;
       
    76             iPacket = 0;
       
    77             iPacket = HBufC8::NewL(initialSize);
       
    78             dataPtr.Set(iPacket->Des());
       
    79             }
       
    80         }
       
    81 
       
    82     // Reset the packet buffer
       
    83     dataPtr.Zero();
       
    84     // Append the header and initial payload
       
    85     dataPtr.Append(aInitialHeader);
       
    86     dataPtr.Append(aPayload.Mid(0, initialPayLoadSize));
       
    87 
       
    88     // Reset the payload pointer to NULL
       
    89     iPayloadBufPtr.Set(TPtrC8(0, 0));
       
    90 
       
    91     // Determine the remaining payload
       
    92     TInt payloadRemaining = aPayload.Length() - initialPayLoadSize;
       
    93 
       
    94     // If there is some remaining payload, store it
       
    95     if (payloadRemaining > 0)
       
    96         {
       
    97         if (!iPayloadBuf)
       
    98             {
       
    99             // Allocate the payload buffer, if it doesn't exist
       
   100             iPayloadBuf = HBufC8::NewL(payloadRemaining);
       
   101             dataPtr.Set(iPayloadBuf->Des());
       
   102             }
       
   103         else
       
   104             {
       
   105             // Ensure the existing buffer is large enough to hold the new data
       
   106             dataPtr.Set(iPayloadBuf->Des());
       
   107             if (dataPtr.MaxLength() < payloadRemaining)
       
   108                 {
       
   109                 delete iPayloadBuf;
       
   110                 iPayloadBuf = 0;
       
   111                 iPayloadBuf = HBufC8::NewL(payloadRemaining);
       
   112                 dataPtr.Set(iPayloadBuf->Des());
       
   113                 }
       
   114             }
       
   115 
       
   116         // Reset the payload buffer
       
   117         dataPtr.Zero();
       
   118         // Copy the remaining payload
       
   119         dataPtr.Append(aPayload.Mid(initialPayLoadSize));
       
   120         // Initialise the payload pointer
       
   121         iPayloadBufPtr.Set(iPayloadBuf->Des());
       
   122         }
       
   123     }
       
   124 
       
   125 const HBufC8* CDataSegmenter::FirstPacketL() const
       
   126     {
       
   127     // Leave if no packet created.
       
   128     User::LeaveIfNull(iPacket);
       
   129 
       
   130     // Return the initial packet created
       
   131     return iPacket;
       
   132     }
       
   133 
       
   134 const HBufC8* CDataSegmenter::NextPacket()
       
   135     {
       
   136     HBufC8* result = iPacket;
       
   137     TPtr8 packetPtr = iPacket->Des();
       
   138 
       
   139     // If there is some payload left over
       
   140     if (iPayloadBufPtr.Length() > 0)
       
   141         {
       
   142         // Reset the packet buffer
       
   143         packetPtr.Zero();
       
   144 
       
   145         // Append the additional packet header
       
   146         packetPtr.Append(iAdditionalHeaderByte);
       
   147 
       
   148         // Determine how much payload to copy, minimum of what's left and what
       
   149         // can fit in the packet
       
   150         TInt dataToCopy = Min((iMTU - 1), iPayloadBufPtr.Length());
       
   151 
       
   152         // Copy payload into the packet buffer
       
   153         packetPtr.Append(iPayloadBufPtr.Mid(0, dataToCopy));
       
   154 
       
   155         // Update the payload pointer
       
   156         iPayloadBufPtr.Set(iPayloadBufPtr.Mid(dataToCopy));
       
   157         }
       
   158     else if (packetPtr.Length() == iMTU)
       
   159         {
       
   160         // No payload left, but last packet was full, so we must send
       
   161         // an additional packet with just the header
       
   162         packetPtr.Zero();
       
   163         packetPtr.Append(iAdditionalHeaderByte);
       
   164         }
       
   165     else
       
   166         {
       
   167         // No more packets
       
   168         result = 0;
       
   169         }
       
   170 
       
   171     return result;
       
   172     }
       
   173 
       
   174 void CDataSegmenter::Reset()
       
   175     {
       
   176     // If a packet has been allocated, then reset the data
       
   177     if (iPacket)
       
   178         {
       
   179         TPtr8 packetPtr = iPacket->Des();
       
   180         packetPtr.Zero();
       
   181         }
       
   182 
       
   183     // Reset the payload pointer to NULL
       
   184     iPayloadBufPtr.Set(TPtrC8(0, 0));
       
   185     }
       
   186 
       
   187 void CDataSegmenter::ConstructL()
       
   188     {
       
   189     // No work to do
       
   190     }
       
   191