SORU
18 AĞUSTOS 2008, PAZARTESİ


Bit alanları C#

Doldurmak için ihtiyacım olan bir yapısı var ve disk için (aslında birkaç) yazma.

Bir örnek:

byte-6    
bit0 - original_or_copy  
bit1 - copyright  
bit2 - data_alignment_indicator  
bit3 - PES_priority  
bit4-bit5 - PES_scrambling control.  
bit6-bit7 - reserved

C aşağıdaki gibi bir şey yapabilirim:

struct PESHeader  {
    unsigned reserved:2;
    unsigned scrambling_control:2;
    unsigned priority:1;
    unsigned data_alignment_indicator:1;
    unsigned copyright:1;
    unsigned original_or_copy:1;
};

C bunu yapmak için herhangi bir yolu var# bana bit yapı kaldırma nokta operatörünü kullanarak erişim sağlayacak?

Yapıların bir çift için, sadece bit bir erişimci işlevi sarılmış değişen yapabilirim.

Bu şekilde ele yapıların yükler var, kolay okuma ve yazma için daha hızlı bir şey arıyorum.

Teşekkürler Rob

CEVAP
18 AĞUSTOS 2008, PAZARTESİ


Muhtemelen bir şey öznitelikleri bit temel öğeler için uygun isnat yapıları dönüştürmek için bir dönüştürme class ' I kullanarak knock birlikte olurum. Gibi bir şey...

using System;

namespace BitfieldTest
{
    [global::System.AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
    sealed class BitfieldLengthAttribute : Attribute
    {
        uint length;

        public BitfieldLengthAttribute(uint length)
        {
            this.length = length;
        }

        public uint Length { get { return length; } }
    }

    static class PrimitiveConversion
    {
        public static long ToLong<T>(T t) where T : struct
        {
            long r = 0;
            int offset = 0;

            // For every field suitably attributed with a BitfieldLength
            foreach (System.Reflection.FieldInfo f in t.GetType().GetFields())
            {
                object[] attrs = f.GetCustomAttributes(typeof(BitfieldLengthAttribute), false);
                if (attrs.Length == 1)
                {
                    uint fieldLength  = ((BitfieldLengthAttribute)attrs[0]).Length;

                    // Calculate a bitmask of the desired length
                    long mask = 0;
                    for (int i = 0; i < fieldLength; i  )
                        mask |= 1 << i;

                    r |= ((UInt32)f.GetValue(t) & mask) << offset;

                    offset  = (int)fieldLength;
                }
            }

            return r;
        }
    }

    struct PESHeader
    {
        [BitfieldLength(2)]
        public uint reserved;
        [BitfieldLength(2)]
        public uint scrambling_control;
        [BitfieldLength(1)]
        public uint priority;
        [BitfieldLength(1)]
        public uint data_alignment_indicator;
        [BitfieldLength(1)]
        public uint copyright;
        [BitfieldLength(1)]
        public uint original_or_copy;
    };

    public class MainClass
    {
        public static void Main(string[] args)
        {
            PESHeader p = new PESHeader();

            p.reserved = 3;
            p.scrambling_control = 2;
            p.data_alignment_indicator = 1;

            long l = PrimitiveConversion.ToLong(p);


            for (int i = 63; i >= 0; i--)
            {
                Console.Write( ((l & (1l << i)) > 0) ? "1" : "0");
            }

            Console.WriteLine();

            return;
        }
    }
}

Beklenen üretir ...000101011. Tabii ki, daha fazla hata denetimi ve biraz aklım başımda bir yazma ihtiyacı var, ama kavram (sanırım) ses, yeniden kullanılabilir ve düzine ile kolayca muhafaza yapıları nakavt sağlar.

adamw

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • eurotuner

    eurotuner

    6 Mart 2006
  • Joseph Herscher

    Joseph Hersc

    14 Mart 2007
  • Majestic Casual

    Majestic Cas

    28 NİSAN 2012