zoukankan      html  css  js  c++  java
  • 选择合适的数据类型

    WINCE6中SDBus驱动中有如下代码,用来从一段给定的内存中的指定位置取出指定的几位数据。

    就这样一个功能,使用了如此多的代码,我个人认为是由于使用了错误的数据类型从而使其变得很复杂

    // Shifts pbInput down by dwBitOffset.

    static

    VOID

    ShiftBytes(PBYTE pbInput, ULONG cbInput, DWORD dwBitOffset, PBYTE pbOutput)

    {

        PREFAST_DEBUGCHK(pbInput);

        PREFAST_DEBUGCHK(pbOutput);

     

        DWORD dwByteIndex = dwBitOffset / 8;

        dwBitOffset %= 8;

     

        DWORD dwRemainderShift = 8 - dwBitOffset;

     

        // Only copy 4 bytes max.

        DWORD dwEndIndex = min(dwByteIndex + sizeof(DWORD), cbInput);

        DWORD dwCurrOutputIndex = 0;

        while (dwByteIndex < dwEndIndex) {

            DEBUGCHK(dwCurrOutputIndex < sizeof(DWORD));

            DEBUGCHK(dwByteIndex < cbInput);

     

            pbOutput[dwCurrOutputIndex] = pbInput[dwByteIndex] >> dwBitOffset;

             ++dwByteIndex;

             if (dwByteIndex != cbInput) {

                BYTE bTemp = pbInput[dwByteIndex];

                bTemp <<= dwRemainderShift;

                pbOutput[dwCurrOutputIndex] |= bTemp;

            }

             ++dwCurrOutputIndex;

        }

    }

     

     

    ///////////////////////////////////////////////////////////////////////////////

    //  GetBitSlice - Get a bit slice from a stream of bytes

    //  Input:  pBuffer - buffer containing data stream

    //          cbBuffer - size of buffer in bytes

    //          dwBitOffset - bit offset from start of buffer

    //          ucBitCount - number of bits (less than or equal to 32)

    //  Output:

    //

    //  Return: returns a DWORD contain the bit slice shifted to fill the least significant bits

    //  Notes:  will raise an SEH exception if integer overflow occurs

    ///////////////////////////////////////////////////////////////////////////////

    DWORD CSDDevice::GetBitSlice(PUCHAR pBuffer, ULONG cbBuffer, DWORD dwBitOffset, UCHAR ucBitCount)

    {

        UCHAR rgbShifted[4] = { 0 };

     

        if (ucBitCount > 32) {

            DEBUG_CHECK(FALSE, (TEXT("GetBitSlice: invalid number of bits \n")));

            return 0;

        }

         typedef SafeInt<DWORD> SafeDW;

        // Exception will be raised on the next line if there is an overflow.

        if ( (SafeDW(dwBitOffset) + SafeDW(ucBitCount)) > (SafeDW(cbBuffer) * 8) ) {

            DEBUG_CHECK(FALSE, (TEXT("GetBitSlice: invalid bit offset given the number of bits \n")));

            return 0;

        }

     

        // Shift the pBuffer down by dwBitOffset bits.

        ShiftBytes(pBuffer, cbBuffer, dwBitOffset, rgbShifted);

     

        DWORD dwUsedBytes; // How many bytes have valid data.

     

        if (ucBitCount % 8 == 0) {

            // Return a byte multiple.

            dwUsedBytes = ucBitCount / 8;

        }

        else {

            // Clear the last used byte of upper bits.

            DWORD dwLastByteIndex = (ucBitCount - 1) / 8;

            DWORD dwRemainderShift = 8 - (ucBitCount % 8);

            rgbShifted[dwLastByteIndex] <<= dwRemainderShift;

            rgbShifted[dwLastByteIndex] >>= dwRemainderShift;

            dwUsedBytes = dwLastByteIndex + 1;

        }

     

        // Clear the unused bytes.

        if (dwUsedBytes != sizeof(rgbShifted)) {

            memset(rgbShifted + dwUsedBytes, 0, sizeof(rgbShifted) - dwUsedBytes);

        }

         DWORD dwRet;

        memcpy(&dwRet, rgbShifted, sizeof(dwRet));

     

        return dwRet;

    }

    以下是我自己为了实现相同功能而写的代码

    • WORD GetBitValue( PBYTE pBuf, DWORD dwBit, DWORD dwNum )
    • {
    •     DWORD dwByte=dwBit/8;
    •     DWORD dwBitinByte=dwBit & 0x7;
    •     if(dwBitinByte + dwNum >24 )
    •         return 0; //Not supported.
    •     else if(dwBitinByte + dwNum >16 )
    •         return (pBuf[dwByte]>>(dwBitinByte) ) |
    •                    (pBuf[dwByte+1]<<( 8- dwBitinByte) ) |
    •                   ( pBuf[dwByte+2] << (16-dwBitinByte) );
    •     else if(dwBitinByte + dwNum >8 )
    •         return (pBuf[dwByte]>>(dwBitinByte) ) |  (pBuf[dwByte+1]<<( 8- dwBitinByte) ) ;
    •     else
    •         return pBuf[dwByte]>>(dwBitinByte);
    • }

    当然我的代码有点缺陷:取出的数据高位没有清零,要做到这点是很容易的。

  • 相关阅读:
    JS使用 popstate 事件监听物理返回键
    JQ判断div是否隐藏
    SQL Server DATEDIFF() 函数
    取消a或input标签聚焦后出现虚线框
    C#定时任务
    C# 保留N位小数
    C#打印单据
    SQL语句创建函数
    SVN检出新项目
    解决jQuery的toggle()的自动触发问题
  • 原文地址:https://www.cnblogs.com/ceblog/p/1776951.html
Copyright © 2011-2022 走看看