2014-05-18 9 views
0

정수 값을 바이트 배열 Byte[]으로 serialize하여 입력 값의 최상위 비트도 대상의 최상위 비트가되도록해야합니다 정렬. 또한 저장 위치에 대한 비트 단위 (바이트 단위가 아닌) 오프셋을 허용해야합니다.MSB 우선 비트 순서를 사용하는 경우 BitArray에서 비트 순서 유지

가 여기에 내가 정수를 쓰고있어 간단한 예제 (모두 MSByte - 첫째, MSbit - 일차) 바이트 경계에 정렬 : 여기

Byte[] buffer = new Byte[99]; 
Encode(buffer, 0, 0x1234); // Encode the value 0x1234 inside buffer at bit-offset 0. 
Assert.AreEqual(buffer[0], 0x12); // The integer value is stored most-significant-byte first 
Assert.AreEqual(buffer[1], 0x34); 

는 비슷한는하지만 에 의해 상쇄 1 비트 : 나는 현재 BitArray 인스턴스를 사용하고

Array.Initialize(buffer); // Reset the buffer's bytes to 0. 
Encode(buffer, 1, 0x0102); // Encode 0x0102 at bit-offset 1 
// In binary 0x0102 is 00000001 00000010, but the final buffer will be this: 00000000 10000001 00000000 
Assert.AreEqual(buffer[0], 0x00); // The first byte will be zero 
Assert.AreEqual(buffer[1], 0x81); // 10000001 == 0x81 
Assert.AreEqual(buffer[2], 0x00); 

그러나 BitArray는, 즉 바이트 내의 비트 순서를 반전시킵니다. bitArray[0]은 버퍼의 첫 번째 바이트의 최하위 비트 인 반면, 내 버퍼의 첫 번째 바이트의 최상위 비트가되어야합니다.

답변

0

이 문제를 해결할 수있는 유일한 방법은 대부분의 - 최소 중요 비트 순서를 보존하는 내 BitArray 클래스를 구현하는 것입니다.

대신 비트 값을 저장하기 위해 내부적으로 Boolean[]을 사용했기 때문에 내가기만당하는 느낌이 들었지만 성능은 만족 스럽습니다.

여기 내가 사용하는 논리는 다음과 같습니다

/// <summary>A bit-array that works with bytes in big-endian order (that is, this[0] == big-endian-bit of the first byte).</summary> 
public class BitArray2 : IEnumerable<Boolean> { 

    private Boolean[] _bits; 

    public BitArray2(Int32 byteCount, Boolean initialValue) { 

     this._bits = new Boolean[ byteCount * 8 ]; 
     for(int i=0;i<this._bits.Length;i++) { 
      this._bits[i] = initialValue; 
     } 
    } 

    public BitArray2(Byte[] copyFrom) { 

     this._bits = new Boolean[ copyFrom.Length * 8 ]; 

     for(int i=0;i<copyFrom.Length;i++) { 
      Byte b = copyFrom[i]; 

      this._bits[ (i*8) + 0 ] = (b & 0x80) == 0x80; 
      this._bits[ (i*8) + 1 ] = (b & 0x40) == 0x40; 
      this._bits[ (i*8) + 2 ] = (b & 0x20) == 0x20; 
      this._bits[ (i*8) + 3 ] = (b & 0x10) == 0x10; 
      this._bits[ (i*8) + 4 ] = (b & 0x08) == 0x08; 
      this._bits[ (i*8) + 5 ] = (b & 0x04) == 0x04; 
      this._bits[ (i*8) + 6 ] = (b & 0x02) == 0x02; 
      this._bits[ (i*8) + 7 ] = (b & 0x01) == 0x01; 
     } 
    } 

    public Boolean this[Int32 bitIndex] { 
     get { return this._bits[bitIndex]; } 
     set { this._bits[bitIndex] = value; } 
    } 

    public void CopyTo(Byte[] buffer) { 

     for(int i=0;i<_bits.Length;i+=8) { 

      Int32 destIndex = i/8; 

      Byte b = 0; 
      if(this._bits[ i + 0 ]) b |= 0x80; 
      if(this._bits[ i + 1 ]) b |= 0x40; 
      if(this._bits[ i + 2 ]) b |= 0x20; 
      if(this._bits[ i + 3 ]) b |= 0x10; 
      if(this._bits[ i + 4 ]) b |= 0x08; 
      if(this._bits[ i + 5 ]) b |= 0x04; 
      if(this._bits[ i + 6 ]) b |= 0x02; 
      if(this._bits[ i + 7 ]) b |= 0x01; 

      buffer[ destIndex ] = b; 
     } 
    } 

    public IEnumerator<Boolean> GetEnumerator() { 
     // See http://stackoverflow.com/questions/1272673/obtain-generic-enumerator-from-an-array 
     return ((IEnumerable<Boolean>)this._bits).GetEnumerator(); 
    } 
    IEnumerator IEnumerable.GetEnumerator() { 
     return this.GetEnumerator(); 
    } 
}