Code Conversion

MTSkull

Centurion
Joined
Mar 25, 2003
Messages
151
Location
Boulder, Colorado
I was given a set of functions in c or c++ that I need to convert to C# if possible.

Background: I am automating a process that will take two hex formatted data files and merge them to create an aggregate memory map for a microprocessor. We have 30 to 40 active products and each has different firmware and initial data files, these files change on a regular basis and I don’t want to have to maintain the system. So I want to be able to create these files on the fly, so I can feed the updated file to the microprocessor programmer every time a batch of products is constructed. The manufacturer has several utilities to create the files but it is not easy to do with so many different products and changes to keep track of. I have the final files created by the process. I have completed the Binary Merge process and create the memory map files easily on the fly. The second part is a job text file that tells the preprogrammer what to do with the files. There are 2 CRCs that are generated and placed in job file. Here is where I am stuck. I can make an exact match for the mem map file but cannot generate an appropriate CRC. If I use my file and their program I get the correct CRC, so I know the Bin file generation is correct.

What I need Help with: The vendor for the preprogrammer sent me a C? or C++? File that generates the CRC. I need, either a way to translate their code to C#, or a way to drop their code in to a library file that I can link to.

In my program the bin file image is stored as a 1meg (1048576bytes) array. The vendors software looks like it takes a UInt32 pointer to the data array. Unfortunately the mem map is proprietary so I can not post it here. I do know the correct answer I am expecting and will post my attempts and the original source below.

Original code from vendor…
Code:
// Compute sumcheck on memory buffer of ULONGs by adding up the the buffer's data by 
// swapping the endian of each data element before adding it to the sum. 
// The WordWidth must be included since this method needs to know how the buffer is swapped (WORD or DWORD)
DWORD DoSumcheckSwappedWithWidth( DWORD* pBuf, DWORD nBytes, WORD nWordWidth, DWORD nBeginValue /* =0 */ )
{
            DWORD nUnits = nBytes / sizeof(ULONG) + ( nBytes % sizeof(ULONG) ? 1 : 0 );
            DWORD nSum = nBeginValue;

            while ( nUnits-- )
            {
                        // Perform a byte swap of the data when retrieving it from the buffer
                        nSum += SwapEndian(*pBuf++, nWordWidth);
            }

            return nSum;
}

inline DWORD SwapEndian(DWORD dwData, WORD nWordWidth = 0)
{
            DWORD dwResult;

    // Do normal 32 bit swap
    // Example:
    // Before: 01 02 03 04
    // After:  04 03 02 01
    if (nWordWidth != 16)
    {
                dwResult  = dwData >> 24;
                dwResult |= ((dwData & 0x00FF0000) >> 8);
                dwResult |= ((dwData & 0x0000FF00) << 8);
                dwResult |= ((dwData & 0x000000FF) << 24);
    }

    // Swap endian of a 32 bit value in a 16 bit fashion.
    // This will do a WORD swap of the upper and lower WORDs in a DWORD. This is useful for 
    // unswapping WORD swapped data when a 32 bit result is needed such as for calculating a 32 bit checksum
    // on a buffer of data that has been WORD swapped (and the unswapped checksum is desired).
    // Example:
    // Before: 01 02 03 04
    // After:  02 01 04 03
    else
    {
        dwResult  = SwapEndian( HIWORD(dwData) ) << 16;
        dwResult |= SwapEndian( LOWORD(dwData) );
    }

            return dwResult;
}

My C# translation attempt…
Code:
public UInt32 CalcCheckSum(UInt32* pBuf, UInt32 nBytes, UInt16 nUInt16Width, UInt32 nBeginValue/* =0 */)
        {
            UInt32 nUnits = nBytes / sizeof(UInt64);// +(nBytes % sizeof(UInt64) ? 1 : 0);
            if ((nBytes % sizeof(UInt64)) == 0)
                nUnits++;

            UInt32 Counter = 0;

            UInt32 nSum = nBeginValue;

            while (nUnits >= 0)
            {// Perform a byte swap of the data when retrieving it from the buffer
                nSum += SwapEndian(*pBuf++, nUInt16Width);
                nUnits--;
            }

            return nSum;
        }

        UInt32 SwapEndian(UInt32 dwData, UInt16 nUInt16Width) //=0)
        {
            UInt32 dwResult;

            // Do normal 32 bit swap
            // Example:
            // Before: 01 02 03 04
            // After:  04 03 02 01

            if (nUInt16Width != 16)
            {
                dwResult = dwData >> 24;
                dwResult |= ((dwData & 0x00FF0000) >> 8);
                dwResult |= ((dwData & 0x0000FF00) << 8);
                dwResult |= ((dwData & 0x000000FF) << 24);
            }
            // Swap endian of a 32 bit value in a 16 bit fashion.
            // This will do a UInt16 swap of the upper and lower UInt16s in a UInt32. This is useful for 
            // unswapping UInt16 swapped data when a 32 bit result is needed such as for calculating a 32 bit checksum
            // on a buffer of data that has been UInt16 swapped (and the unswapped checksum is desired).
            // Example:
            // Before: 01 02 03 04
            // After:  02 01 04 03
            else
            {
                dwResult = SwapEndian(HIUINT16(dwData), 0) << 16;
                dwResult |= SwapEndian(LOUINT16(dwData), 0);
            }

            return dwResult;

        }

	  //Not sure if these are right???
        UInt32 HIUINT16(UInt32 n)
        {
            return ((n)>>16);
        }
        UInt32 LOUINT16(UInt32 n)
        {
            return ((n)&0xFFFF);
        }

Sorry for only posting hard stuff. And thanks for the help.
MTS
 
I notice one difference: in the original loop,
Code:
            while ( [COLOR="Red"]nUnits--[/COLOR] )
            {
                        // Perform a byte swap of the data when retrieving it from the buffer
                        nSum += SwapEndian(*pBuf++, nWordWidth);
            }

            return nSum;
the loop terminates when nUnits = 0. In the C# code,
Code:
            while ([COLOR="Red"]nUnits >= 0[/COLOR])
            {// Perform a byte swap of the data when retrieving it from the buffer
                nUnits--;
                nSum += SwapEndian(*pBuf++, nUInt16Width);
            }

            return nSum;
the loop terminates when nUnits < 0, resulting in an extra iteration. Otherwise everything looks fine, but it's real easy to miss the small details when doing binary operations.
 
Back
Top