Lately I got confronted with inserting and reading selections from a byte value using bit masks. I wrote the following class that makes it easier to deal with such operations for bytes. It can be extended for other types (short, int,..)
using System; using System.Collections.Generic; using System.Text; namespace Sandbox { public class ByteBitVector { private byte value; public byte Value { get { return this.value; } set { this.value = value; } } public ByteBitVector(byte value) { this.value = value; } public ByteBitVector() { this.value = 0x0000; } public void InsertSection(byte section, String mask) { this.checkMask(mask); Console.WriteLine("mask= " + mask); Console.WriteLine("this.getShift(mask)= " + this.getShift(mask)); Console.WriteLine("section= " + Convert.ToString(section,2)); this.value += (byte)(section << this.getShift(mask)); } public byte GetSection(String mask) { this.checkMask(mask); /* * String mask = "-xx----" * String maskAsBitStr = "0110000" * Byte maskAsByte = (byte) 0110000 = 0x30 */ String maskAsBitStr = String.Empty; maskAsBitStr = mask.Replace('-', '0'); maskAsBitStr = maskAsBitStr.Replace('x', '1'); byte maskAsByte = Convert.ToByte(maskAsBitStr, 2); return (byte)(((this.value) & maskAsByte) >> this.getShift(mask)); } private void checkMask(String mask) { if (8 != mask.Length) { throw new Exception("The mask length must be exactly 8!"); } foreach (char c in mask) { if ((c != '-') && (c != 'x')) { throw new Exception("Wrong format for mask! Accepted format: ---xx---"); } } } private byte getShift(String mask) { return (byte)((8-1) - mask.LastIndexOf('x')); } public void Main(String arg[]) { ByteBitVector v = new ByteBitVector(); String a_mask = "xx------"; String b_mask = "--xxxx--"; String c_mask = "------x-"; String d_mask = "-------x"; /* sections to insert and read */ byte a = 0x3; //00000011 byte b = 0XB; //00001011 byte c = 0x1; //00000001 byte d = 0x1; //00000001 /* inserting sections */ // v.Value = 0000 0000 v.InsertSection(a, a_mask); // v.Value = 1100 0000 v.InsertSection(b, b_mask); // v.Value = 1110 1100 v.InsertSection(c, c_mask); // v.Value = 1110 1110 v.InsertSection(d, d_mask); // v.Value = 1110 1111 /* reading sections */ Console.WriteLine("v.GetSection(a_mask) = " + Convert.ToString(v.GetSection(a_mask), 2)); //00000011 = a Console.WriteLine("v.GetSection(b_mask) = " + Convert.ToString(v.GetSection(b_mask), 2)); //00001011 = b Console.WriteLine("v.GetSection(c_mask) = " + Convert.ToString(v.GetSection(c_mask), 2)); //00000001 = c Console.WriteLine("v.GetSection(d_mask) = " + Convert.ToString(v.GetSection(d_mask), 2)); //00000001 = d } } }
Advertisements
Fan said
Hi great article enjoyed reading it
old – >public void Main(String arg[])
There is a bug line# 76 should be changed to
new -> public void Main(String[] arg)
What does intersection() do?
What does getShif() do?
vampo said
There is a problem with InsertSection method with this code.
this.value += (byte)(section << this.getShift(mask));
the operator must be bitwise OR (|=). otherwise if you call InsertSection twise it is messing up.