localconnectivityservice/generichid/src/hiditem.cpp
branchRCL_3
changeset 39 4096754ee773
parent 38 3dcb815346df
child 40 52a167391590
equal deleted inserted replaced
38:3dcb815346df 39:4096754ee773
     1 /*
       
     2 * Copyright (c) 2004-2007 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:  Item implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // References:
       
    20 //
       
    21 // [1] USB Device Class Definition for Human Interface Devices (HID),
       
    22 //     Firmware Specification, Version 1.11, USB Implementers' Forum,
       
    23 //     June 2001
       
    24 //
       
    25 // ----------------------------------------------------------------------
       
    26 
       
    27 #include <e32std.h>
       
    28 
       
    29 #include "hiditem.h"
       
    30 #include "hidparser.h"
       
    31 
       
    32 const TInt KSizeMask        = 0x03;
       
    33 const TInt KTypeMask        = 0x03;
       
    34 const TInt KTypePosn        = 2;
       
    35 const TInt KTagMask         = 0x0F;
       
    36 const TInt KTagPosn         = 4;
       
    37 const TInt KLongItemId      = 0xfe;
       
    38 const TInt KMaxItemlength   = 4;
       
    39 const TInt KSizeThree       = 3;
       
    40 const TInt KSizeFour        = 4;
       
    41 const TInt KLongItemMin     = 3;
       
    42 
       
    43 
       
    44 // ======== MEMBER FUNCTIONS ========
       
    45 
       
    46 // ---------------------------------------------------------------------------
       
    47 // Constructor
       
    48 // ---------------------------------------------------------------------------
       
    49 //
       
    50 TItem::TItem(const TDesC8& aRawData)
       
    51     : iRawData(aRawData)
       
    52     {    
       
    53     if (aRawData.Length() < 1)
       
    54         {
       
    55         return;
       
    56         }
       
    57     TBool isShortItem = (aRawData[0] != KLongItemId);
       
    58 
       
    59     if (isShortItem)
       
    60         {
       
    61         //  +----+----+----+----+----+----+----+----+
       
    62         //  |        Tag        |   Type  |  Size   |    [data...]
       
    63         //  |    .    .    .    |    .    |    .    |
       
    64         //  +----+----+----+----+----+----+----+----+
       
    65         //    7    6    5    4    3    2    1     0
       
    66         //
       
    67         // A short item is followed by 0, 1, 2 or 4 bytes of data, as
       
    68         // specified in the size field. See [1], Section 6.2.2.2.        
       
    69         iSize = aRawData[0] & KSizeMask;
       
    70         if (iSize == KSizeThree)
       
    71             {
       
    72             iSize = KSizeFour;
       
    73             }        
       
    74         iType = static_cast<TItemType>((aRawData[0] >> KTypePosn) & KTypeMask);
       
    75         iTag = (aRawData[0] >> KTagPosn) & KTagMask;
       
    76         iDataOffset = 1;
       
    77         }
       
    78     else
       
    79         {
       
    80         //        Byte 0               Byte 1          Byte 2
       
    81         // +------+------+------+   +-----------+   +-----------+
       
    82         // | Tag  | Type | Size |   | Data size |   | Long item |   [data...]
       
    83         // | 1111 |  11  |  10  |   |  (0-255)  |   |    tag    |
       
    84         // +------+------+------+   +-----------+   +-----------+
       
    85         //   7654    32     10
       
    86         //
       
    87         // A long item is followed by 0-255 bytes of data, as specified
       
    88         // in the data size byte. See [1], Section 6.2.2.3.
       
    89 
       
    90         iType = EReserved;
       
    91 
       
    92         if (aRawData.Length() > KLongItemMin)
       
    93             {
       
    94             iSize = aRawData[1];
       
    95             iTag = aRawData[2];
       
    96             iDataOffset = KLongItemMin;
       
    97             }
       
    98         else
       
    99             {
       
   100             iSize = 0;
       
   101             iTag = 0;
       
   102             iDataOffset = 0;
       
   103             }
       
   104         }
       
   105 
       
   106 #ifdef DBG_ACTIVE
       
   107     for (TInt i=0; (i<aRawData.Length()) && (i<(iSize+iDataOffset)); ++i)
       
   108         {
       
   109         RDebug::Print(_L("aRawData[%d] = 0x%02x"), i, aRawData[i]);
       
   110         }
       
   111 #endif
       
   112     }
       
   113 
       
   114 // ---------------------------------------------------------------------------
       
   115 // DataSize()
       
   116 // ---------------------------------------------------------------------------
       
   117 //
       
   118 TInt TItem::DataSize() const
       
   119     {
       
   120     return iSize;
       
   121     }
       
   122 
       
   123 // ---------------------------------------------------------------------------
       
   124 // Tag()
       
   125 // ---------------------------------------------------------------------------
       
   126 //
       
   127 TInt TItem::Tag() const
       
   128     {
       
   129     return iTag;
       
   130     }
       
   131 
       
   132 // ---------------------------------------------------------------------------
       
   133 // Data()
       
   134 // ---------------------------------------------------------------------------
       
   135 //
       
   136 TUint32 TItem::Data() const
       
   137     {
       
   138     TInt size = DataSize();
       
   139 
       
   140     // Calling Data() makes no sense for long items that have a data
       
   141     // size over 4 bytes, as it only returns a TUint32:
       
   142     //
       
   143     if (size > KMaxItemlength)
       
   144         {
       
   145         size = KMaxItemlength;
       
   146         }
       
   147 
       
   148     // Ensure we don't overrun the source buffer:
       
   149     //
       
   150     if (size > (iRawData.Length() - 1))
       
   151         {
       
   152         size = iRawData.Length() - 1;
       
   153         }
       
   154 
       
   155     // Concatenate each byte into a TUint32.  Note that this function must
       
   156     // return zero if the data size is zero (see Parser.cpp, MainItemL()).
       
   157     //
       
   158     TUint32 tagData = 0;
       
   159     for (TInt i=0; i<size; ++i)
       
   160         {
       
   161         tagData |= (iRawData[1 + i] << (KSizeOfByte*i));
       
   162         }
       
   163 
       
   164     return tagData;
       
   165     }
       
   166 
       
   167 // ---------------------------------------------------------------------------
       
   168 // SignedData()
       
   169 // ---------------------------------------------------------------------------
       
   170 //
       
   171 TInt32 TItem::SignedData() const
       
   172     {
       
   173     TUint32 data = Data();
       
   174 
       
   175     // For 8 and 16 bit negative values, we need to
       
   176     // sign extend to 32-bits:
       
   177     //
       
   178     if ((DataSize() == 1) && (data & 0x80))
       
   179         {
       
   180         data |= 0xffffff00;
       
   181         }
       
   182     if ((DataSize() == 2) && (data & 0x8000))
       
   183         {
       
   184         data |= 0xffff0000;
       
   185         }
       
   186 
       
   187     // Note that this assumes that the machine uses 2s complement
       
   188     // representation internally.  All current Symbian devices do,
       
   189     // including ARM devices and the WINS emulator. This is almost
       
   190     // certain to remain the case in the future.
       
   191     //
       
   192     return static_cast<TInt32>(data);
       
   193     }
       
   194 
       
   195 // ---------------------------------------------------------------------------
       
   196 // Operator []
       
   197 // ---------------------------------------------------------------------------
       
   198 //
       
   199 TUint8 TItem::operator[](TInt aIndex) const
       
   200     {    
       
   201 
       
   202     TUint8 value = 0;
       
   203     if ((aIndex >= 0) && (aIndex < iSize))
       
   204         {
       
   205         value = iRawData[iDataOffset + aIndex];
       
   206         }
       
   207     return value;
       
   208     }
       
   209 
       
   210 // ---------------------------------------------------------------------------
       
   211 // Type()
       
   212 // ---------------------------------------------------------------------------
       
   213 //
       
   214 TItem::TItemType TItem::Type() const
       
   215     {
       
   216     return iType;
       
   217     }
       
   218 
       
   219 // ---------------------------------------------------------------------------
       
   220 // IsMain()
       
   221 // ---------------------------------------------------------------------------
       
   222 //
       
   223 TBool TItem::IsMain() const
       
   224     {
       
   225     return iType == TItem::EMain;
       
   226     }
       
   227 
       
   228 // ---------------------------------------------------------------------------
       
   229 // IsLocal()
       
   230 // ---------------------------------------------------------------------------
       
   231 //
       
   232 TBool TItem::IsLocal() const
       
   233     {
       
   234     return iType == TItem::ELocal;
       
   235     }
       
   236 
       
   237 // ---------------------------------------------------------------------------
       
   238 // IsGlobal()
       
   239 // ---------------------------------------------------------------------------
       
   240 //
       
   241 TBool TItem::IsGlobal() const
       
   242     {
       
   243     return iType == TItem::EGlobal;
       
   244     }
       
   245 
       
   246 // ---------------------------------------------------------------------------
       
   247 // IsLong()
       
   248 // ---------------------------------------------------------------------------
       
   249 //
       
   250 TBool TItem::IsLong() const
       
   251     {
       
   252     return iType == TItem::EReserved;
       
   253     }
       
   254 
       
   255 // ---------------------------------------------------------------------------
       
   256 // ItemSize()
       
   257 // ---------------------------------------------------------------------------
       
   258 //
       
   259 TInt TItem::ItemSize() const
       
   260     {
       
   261     return iSize + iDataOffset;
       
   262     }
       
   263