localconnectivityservice/generichid/src/hidreportbase.cpp
branchRCL_3
changeset 19 0aa8cc770c8a
equal deleted inserted replaced
18:453dfc402455 19:0aa8cc770c8a
       
     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:  Report base class implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "hidfield.h"
       
    20 #include "hidtranslate.h"
       
    21 #include "hidinterfaces.h"
       
    22 
       
    23 const TUint KValueMask      = 0xFFFFFFFF;
       
    24 const TUint KSignBitMask    = 0x80000000;
       
    25 const TInt  KThreeLSB       = 7;
       
    26 const TInt  KThreeLSBShift  = 3;
       
    27 // ======== MEMBER FUNCTIONS ========
       
    28 
       
    29 // ---------------------------------------------------------------------------
       
    30 // GetIndexOfUsage()
       
    31 // ---------------------------------------------------------------------------
       
    32 //
       
    33 TBool TReportUtils::GetIndexOfUsage(const CField* aField,
       
    34     TInt aUsageId, TInt& aUsageIndex)
       
    35     {
       
    36     TArray<TInt> usages(aField->UsageArray());
       
    37 
       
    38     if ( usages.Count() > 0 )
       
    39         {
       
    40         // Find the usage in the array
       
    41         for ( TInt i = 0; i < usages.Count(); i++ )
       
    42             {
       
    43             if ( usages[i] == aUsageId )
       
    44                 {
       
    45                 aUsageIndex = i;
       
    46                 return ETrue;
       
    47                 }
       
    48             }
       
    49         }
       
    50     else
       
    51         {
       
    52         // The field includes all usages between the min and max
       
    53         if ( aField->UsageMin() <= aUsageId && aUsageId <= aField->UsageMax() )
       
    54             {
       
    55             aUsageIndex = aUsageId - aField->UsageMin();
       
    56             return ETrue;
       
    57             }
       
    58         }
       
    59 
       
    60     return EFalse;
       
    61     }
       
    62 
       
    63 // ---------------------------------------------------------------------------
       
    64 // UsageAtIndex()
       
    65 // ---------------------------------------------------------------------------
       
    66 //
       
    67 TInt TReportUtils::UsageAtIndex(const CField* aField, TInt aUsageIndex)
       
    68     {
       
    69     TInt usageId = 0;
       
    70     TArray<TInt> usages(aField->UsageArray());
       
    71 
       
    72     if ( usages.Count() > 0 )
       
    73         {
       
    74         if ( aUsageIndex < 0 )
       
    75             {
       
    76             // Null state for array control
       
    77             }
       
    78         else if ( aUsageIndex < usages.Count() )
       
    79             {
       
    80             // Get the usage ID from the set of possible usages
       
    81             usageId = usages[aUsageIndex];
       
    82             }
       
    83         else
       
    84             {
       
    85             // If there aren't enough usages in the set, the last one repeats
       
    86             usageId = usages[usages.Count() - 1];
       
    87             }
       
    88         }
       
    89     else
       
    90         {
       
    91         // Get the usage ID from the range
       
    92         if ( 0 <= aUsageIndex
       
    93                 && aUsageIndex <= (aField->UsageMax() - aField->UsageMin()) )
       
    94             {
       
    95             usageId = aField->UsageMin() + aUsageIndex;
       
    96             }
       
    97         }
       
    98 
       
    99     return usageId;
       
   100     }
       
   101 
       
   102 // ---------------------------------------------------------------------------
       
   103 // WriteData()
       
   104 // ---------------------------------------------------------------------------
       
   105 //
       
   106 TInt TReportUtils::WriteData(HBufC8& aData, const CField* aField,
       
   107     TInt aIndex, TInt aValue)
       
   108     {
       
   109     if ( 0 <= aIndex && aIndex < aField->Count() )
       
   110         {
       
   111         // The offset in bits from the start of the report to the value
       
   112         TInt offset = aField->Offset() + aIndex * aField->Size();
       
   113 
       
   114         // How many bits in the least significant byte are not part of the value
       
   115         TInt bitsToShift = offset & KThreeLSB;
       
   116 
       
   117         TUint mask = KValueMask >> ((KSizeOfByte * sizeof(TInt)) - aField->Size());
       
   118         mask <<= bitsToShift;
       
   119         aValue <<= bitsToShift;
       
   120 
       
   121         TPtr8 data = aData.Des();
       
   122 
       
   123         // Write out the bytes, least significant first
       
   124         for ( TInt i = offset >> KThreeLSBShift; mask && i < aData.Length(); i++ )
       
   125             {
       
   126             TUint8 maskByte = static_cast<TUint8>(mask);
       
   127 
       
   128             // The extra cast is because MSVC6 thinks that or-ing 2
       
   129             // TUint8s together gives an int.
       
   130             data[i] = static_cast<TUint8>(
       
   131                 (static_cast<TUint8>(aValue) & maskByte)
       
   132                 | (aData[i] & ~maskByte));
       
   133             mask >>= KSizeOfByte;
       
   134             aValue >>= KSizeOfByte;
       
   135             }
       
   136 
       
   137         return KErrNone;
       
   138         }
       
   139 
       
   140     return KErrBadControlIndex;
       
   141     }
       
   142 
       
   143 // ---------------------------------------------------------------------------
       
   144 // ReadData()
       
   145 // ---------------------------------------------------------------------------
       
   146 //
       
   147 TInt TReportUtils::ReadData(const TDesC8& aData, const CField* aField,
       
   148     TInt aIndex, TInt& aValue)
       
   149     {
       
   150     if ( 0 <= aIndex && aIndex < aField->Count() )
       
   151         {
       
   152         // The offset in bits from the start of the report to the value
       
   153         TInt offset = aField->Offset() + aIndex * aField->Size();
       
   154 
       
   155         // How many bits in the least significant byte are not part of
       
   156         // the value
       
   157         TInt bitsToShift = offset & KThreeLSB;
       
   158 
       
   159         // How many consecutive bytes we need to read to get the whole
       
   160         // value. According to the HID spec, a value cannot span more
       
   161         // than 4 bytes in a report
       
   162         TInt bytesToRead = (bitsToShift + aField->Size() + KThreeLSB) / KSizeOfByte;
       
   163 
       
   164         // Make sure we don't read past the end of the data
       
   165         if ( (offset >> KThreeLSBShift) + bytesToRead > aData.Length() )
       
   166             {
       
   167             bytesToRead = aData.Length() - (offset >> KThreeLSBShift);
       
   168             }
       
   169 
       
   170         TInt value = 0;
       
   171 
       
   172         // Read in the bytes, most significant first
       
   173         for ( TInt i = bytesToRead - 1; i >= 0; i-- )
       
   174             {
       
   175             value = (value << KSizeOfByte) | aData[(offset >> KThreeLSBShift) + i];
       
   176             }
       
   177 
       
   178         value >>= bitsToShift;
       
   179 
       
   180         // Make masks for the whole value and just the sign bit
       
   181         TUint valueMask = KValueMask >> ((KSizeOfByte * sizeof(TInt)) - aField->Size());
       
   182         TUint signMask = KSignBitMask >> ((KSizeOfByte * sizeof(TInt)) - aField->Size());
       
   183 
       
   184         if ( aField->LogicalMin() < 0 && (value & signMask) )
       
   185             {
       
   186             // The value is negative, so the leading bits should be 1s
       
   187             aValue = value | ~valueMask;
       
   188             }
       
   189         else
       
   190             {
       
   191             // The value is positive, so the leading bits should be 0s
       
   192             aValue = value & valueMask;
       
   193             }
       
   194 
       
   195         return KErrNone;
       
   196         }
       
   197 
       
   198     return KErrBadControlIndex;
       
   199     }