mardi 20 novembre 2018

How could I simplify this long chain of conditional statements?

I have the following enum

[Flags]
internal enum DataSectionFlags : uint
{
    TypeReg = 0x0,
    TypeDsect = 0x01,
    TypeNoLoad = 0x02,
    TypeGroup = 0x04,
    TypeNoPadded = 0x08,
    TypeCopy = 0x010,

    ContentCode = 0x020,
    ContentInitializedData = 0x040,
    ContentUninitializedData = 0x080,

    LinkOther = 0x0100,
    LinkInfo = 0x0200,

    TypeOver = 0x0400,

    LinkRemove = 0x0800,
    LinkComDat = 0x01000,

    NoDeferSpecExceptions = 0x04000,

    RelativeGP = 0x08000,

    MemPurgeable = 0x020000,

    Memory16Bit = 0x020000,
    MemoryLocked = 0x040000,
    MemoryPreload = 0x080000,

    Align1Bytes = 0x0100000,
    Align2Bytes = 0x0200000,
    Align4Bytes = 0x0300000,
    Align8Bytes = 0x0400000,
    Align16Bytes = 0x0500000,
    Align32Bytes = 0x0600000,
    Align64Bytes = 0x0700000,
    Align128Bytes = 0x0800000,
    Align256Bytes = 0x0900000,
    Align512Bytes = 0x0A00000,
    Align1024Bytes = 0x0B00000,
    Align2048Bytes = 0x0C00000,
    Align4096Bytes = 0x0D00000,
    Align8192Bytes = 0x0E00000,

    LinkExtendedRelocationOverflow = 0x01000000,

    MemoryDiscardable = 0x02000000,
    MemoryNotCached = 0x04000000,
    MemoryNotPaged = 0x08000000,
    MemoryShared = 0x10000000,
    MemoryExecute = 0x20000000,
    MemoryRead = 0x40000000,
    MemoryWrite = 0x80000000
}

I am casting a uint variable with this enum like so

var testVariable = (DataSectionFlags) 1610612768;

I have a method that processes the above variable like this

private static uint GetSectionProtection(DataSectionFlags characteristics)
{
    uint result = 0;

    if (characteristics.HasFlag(DataSectionFlags.MemoryNotCached))
    {
        // PageNoCache

        result |= 0x200;
    }

    if (characteristics.HasFlag(DataSectionFlags.MemoryExecute))
    {
        if (characteristics.HasFlag(DataSectionFlags.MemoryRead))
        {
            if (characteristics.HasFlag(DataSectionFlags.MemoryWrite))
            {
                // PageExecuteReadWrite

                result |= 0x40;
            }

            else
            { 
                // PageExecuteRead

                result |= 0x20;
            }

        }

        else if (characteristics.HasFlag(DataSectionFlags.MemoryWrite))
        {
            // PageExecuteWriteCopy

            result |= 0x80;
        }

        else
        {
            // PageExecute

            result |= 0x10;
        }
    }

    else if (characteristics.HasFlag(DataSectionFlags.MemoryRead))
    {
        if (characteristics.HasFlag(DataSectionFlags.MemoryWrite))
        {
            // PageReadWrite

            result |= 0x04;
        }

        else
        {
            // PageReadOnly

            result |= 0x02;
        }               
    }

    else if (characteristics.HasFlag(DataSectionFlags.MemoryWrite))
    {
        // PageWriteCopy

        result |= 0x08;
    }

    else
    {
        // PageNoAccess

        result |= 0x01;
    }

    return result;
}

I'm attempting to simplify the long chain of conditional statements inside this method but am having trouble doing so.

What would be the simplest way to write the conditional statements inside the method whilst still maintaining their functionality?

Aucun commentaire:

Enregistrer un commentaire