--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/localconnectivityservice/generichid/src/hidreportbase.cpp Tue Aug 31 16:03:15 2010 +0300
@@ -0,0 +1,199 @@
+/*
+* Copyright (c) 2004-2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Report base class implementation
+*
+*/
+
+
+#include "hidfield.h"
+#include "hidtranslate.h"
+#include "hidinterfaces.h"
+
+const TUint KValueMask = 0xFFFFFFFF;
+const TUint KSignBitMask = 0x80000000;
+const TInt KThreeLSB = 7;
+const TInt KThreeLSBShift = 3;
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// GetIndexOfUsage()
+// ---------------------------------------------------------------------------
+//
+TBool TReportUtils::GetIndexOfUsage(const CField* aField,
+ TInt aUsageId, TInt& aUsageIndex)
+ {
+ TArray<TInt> usages(aField->UsageArray());
+
+ if ( usages.Count() > 0 )
+ {
+ // Find the usage in the array
+ for ( TInt i = 0; i < usages.Count(); i++ )
+ {
+ if ( usages[i] == aUsageId )
+ {
+ aUsageIndex = i;
+ return ETrue;
+ }
+ }
+ }
+ else
+ {
+ // The field includes all usages between the min and max
+ if ( aField->UsageMin() <= aUsageId && aUsageId <= aField->UsageMax() )
+ {
+ aUsageIndex = aUsageId - aField->UsageMin();
+ return ETrue;
+ }
+ }
+
+ return EFalse;
+ }
+
+// ---------------------------------------------------------------------------
+// UsageAtIndex()
+// ---------------------------------------------------------------------------
+//
+TInt TReportUtils::UsageAtIndex(const CField* aField, TInt aUsageIndex)
+ {
+ TInt usageId = 0;
+ TArray<TInt> usages(aField->UsageArray());
+
+ if ( usages.Count() > 0 )
+ {
+ if ( aUsageIndex < 0 )
+ {
+ // Null state for array control
+ }
+ else if ( aUsageIndex < usages.Count() )
+ {
+ // Get the usage ID from the set of possible usages
+ usageId = usages[aUsageIndex];
+ }
+ else
+ {
+ // If there aren't enough usages in the set, the last one repeats
+ usageId = usages[usages.Count() - 1];
+ }
+ }
+ else
+ {
+ // Get the usage ID from the range
+ if ( 0 <= aUsageIndex
+ && aUsageIndex <= (aField->UsageMax() - aField->UsageMin()) )
+ {
+ usageId = aField->UsageMin() + aUsageIndex;
+ }
+ }
+
+ return usageId;
+ }
+
+// ---------------------------------------------------------------------------
+// WriteData()
+// ---------------------------------------------------------------------------
+//
+TInt TReportUtils::WriteData(HBufC8& aData, const CField* aField,
+ TInt aIndex, TInt aValue)
+ {
+ if ( 0 <= aIndex && aIndex < aField->Count() )
+ {
+ // The offset in bits from the start of the report to the value
+ TInt offset = aField->Offset() + aIndex * aField->Size();
+
+ // How many bits in the least significant byte are not part of the value
+ TInt bitsToShift = offset & KThreeLSB;
+
+ TUint mask = KValueMask >> ((KSizeOfByte * sizeof(TInt)) - aField->Size());
+ mask <<= bitsToShift;
+ aValue <<= bitsToShift;
+
+ TPtr8 data = aData.Des();
+
+ // Write out the bytes, least significant first
+ for ( TInt i = offset >> KThreeLSBShift; mask && i < aData.Length(); i++ )
+ {
+ TUint8 maskByte = static_cast<TUint8>(mask);
+
+ // The extra cast is because MSVC6 thinks that or-ing 2
+ // TUint8s together gives an int.
+ data[i] = static_cast<TUint8>(
+ (static_cast<TUint8>(aValue) & maskByte)
+ | (aData[i] & ~maskByte));
+ mask >>= KSizeOfByte;
+ aValue >>= KSizeOfByte;
+ }
+
+ return KErrNone;
+ }
+
+ return KErrBadControlIndex;
+ }
+
+// ---------------------------------------------------------------------------
+// ReadData()
+// ---------------------------------------------------------------------------
+//
+TInt TReportUtils::ReadData(const TDesC8& aData, const CField* aField,
+ TInt aIndex, TInt& aValue)
+ {
+ if ( 0 <= aIndex && aIndex < aField->Count() )
+ {
+ // The offset in bits from the start of the report to the value
+ TInt offset = aField->Offset() + aIndex * aField->Size();
+
+ // How many bits in the least significant byte are not part of
+ // the value
+ TInt bitsToShift = offset & KThreeLSB;
+
+ // How many consecutive bytes we need to read to get the whole
+ // value. According to the HID spec, a value cannot span more
+ // than 4 bytes in a report
+ TInt bytesToRead = (bitsToShift + aField->Size() + KThreeLSB) / KSizeOfByte;
+
+ // Make sure we don't read past the end of the data
+ if ( (offset >> KThreeLSBShift) + bytesToRead > aData.Length() )
+ {
+ bytesToRead = aData.Length() - (offset >> KThreeLSBShift);
+ }
+
+ TInt value = 0;
+
+ // Read in the bytes, most significant first
+ for ( TInt i = bytesToRead - 1; i >= 0; i-- )
+ {
+ value = (value << KSizeOfByte) | aData[(offset >> KThreeLSBShift) + i];
+ }
+
+ value >>= bitsToShift;
+
+ // Make masks for the whole value and just the sign bit
+ TUint valueMask = KValueMask >> ((KSizeOfByte * sizeof(TInt)) - aField->Size());
+ TUint signMask = KSignBitMask >> ((KSizeOfByte * sizeof(TInt)) - aField->Size());
+
+ if ( aField->LogicalMin() < 0 && (value & signMask) )
+ {
+ // The value is negative, so the leading bits should be 1s
+ aValue = value | ~valueMask;
+ }
+ else
+ {
+ // The value is positive, so the leading bits should be 0s
+ aValue = value & valueMask;
+ }
+
+ return KErrNone;
+ }
+
+ return KErrBadControlIndex;
+ }