부품 설계도
[C#]Bit_Builder 전체 코드
밤말팅
2020. 11. 15. 20:22
[C#] Int를 비트단위로 저장해주는 클래스
안녕하십니까 밤말팅입니다. 블로그를 열고 첫 포스팅인데요, 앞으로 게임 개발에 도움이 될 여러 가지 클래스를 구상하고 제작하는 대로 포스팅 할 예정입니다. 내용이 괜찮다고 생각하시면
game-part-factory.tistory.com
이 글은 위에서 설명하는 클래스의 전체 코드입니다!
내용이 궁금하시면 해당 포스팅을 참고해주시면 감사드리겠습니다~
public enum Bit_Type
{
FLOAT,
BOOL
}
public class Bit_Builder
{
private Bit_Type[] containTypeArray;
private byte[] containByteArray;
private int[] locationBitArray;
public int Length { get { return containTypeArray.Length; } }
public object this[int targetIndex]
{
get
{
if(targetIndex > containTypeArray.Length)
{
return null;
};
if (containTypeArray[targetIndex] == Bit_Type.BOOL)
{
return GetBool(targetIndex);
}
else if (containTypeArray[targetIndex] == Bit_Type.FLOAT)
{
return BitConverter.ToSingle(GetByte(targetIndex), 0);
}
else
{
return BitConverter.ToInt32(GetByte(targetIndex), 0);
};
}
set
{
if(targetIndex > containTypeArray.Length)
{
return;
};
if (containTypeArray[targetIndex] == Bit_Type.BOOL)
{
SetBool(targetIndex, (bool)value);
}
else
{
Type valueType = value.GetType();
byte[] wantByte = new byte[0];
if (valueType == typeof(float))
{
wantByte = BitConverter.GetBytes((float)value);
}
else
{
wantByte = BitConverter.GetBytes((int)value);
};
if(wantByte.Length > 0)
{
SetByte(targetIndex, wantByte);
};
};
}
}
public Bit_Builder(Bit_Type[] wantTypes)
{
int bitLength = 0;
containTypeArray = wantTypes;
locationBitArray = new int[wantTypes.Length];
for (int i = 0; i < containTypeArray.Length; ++i)
{
if (containTypeArray[i] > (Bit_Type)32)
{
containTypeArray[i] = (Bit_Type)32;
};
locationBitArray[i] = bitLength;
bitLength += TypeLength(containTypeArray[i]);
};
containByteArray = new byte[(int)Math.Ceiling(bitLength / 8.0d)];
}
private static int TypeLength(Bit_Type wantType)
{
if(wantType == Bit_Type.FLOAT)
{
return 32;
}
else
{
return (int)wantType;
};
}
private void SetBool(int targetIndex, bool value)
{
int bitLocation = locationBitArray[targetIndex] % 8;
int byteLocation = locationBitArray[targetIndex] >> 3;
if (value)
{
containByteArray[byteLocation] |= (byte)(0x80 >> bitLocation);
}
else
{
containByteArray[byteLocation] &= (byte)~(0x80 >> bitLocation);
};
}
private bool GetBool(int targetIndex)
{
int bitLocation = locationBitArray[targetIndex] % 8;
byte targetByte = containByteArray[locationBitArray[targetIndex] >> 3];
return (targetByte & (0x80 >> bitLocation)) > 0;
}
private void SetByte(int targetIndex, byte[] wantByte)
{
int bitLocation = locationBitArray[targetIndex] % 8;
int byteLocation = locationBitArray[targetIndex] >> 3;
int bitEnd = bitLocation + TypeLength(containTypeArray[targetIndex]);
int byteEnd = (locationBitArray[targetIndex] + TypeLength(containTypeArray[targetIndex])) >> 3;
int wholeByte = TypeLength(containTypeArray[targetIndex]) >> 3;
int leftBit = TypeLength(containTypeArray[targetIndex]) % 8;
int lastBit = leftBit + bitLocation;
if (byteEnd > containByteArray.Length)
{
return;
};
if (1 < TypeLength(containTypeArray[targetIndex]) && TypeLength(containTypeArray[targetIndex]) < 8)
{
if (bitEnd < 9)
{
int bitMask = (0xff >> bitLocation) ^ (0xff >> bitEnd);
containByteArray[byteLocation] &= (byte)~bitMask;
containByteArray[byteLocation] |= (byte)(bitMask & (wantByte[0] << (8 - bitEnd)));
return;
}
else
{
int bitMask = (0xff >> bitLocation);
containByteArray[byteLocation] &= (byte)~bitMask;
containByteArray[byteLocation] |= (byte)(bitMask & wantByte[0]);
bitMask = ~(0xff >> (bitEnd - 8));
containByteArray[byteLocation + 1] &= (byte)~bitMask;
containByteArray[byteLocation + 1] |= (byte)(bitMask & (wantByte[0] << (8 - TypeLength(containTypeArray[targetIndex]))));
};
}
else
{
if (bitLocation == 0)
{
for (int i = 0; i < wholeByte; ++i)
{
containByteArray[byteLocation + i] = wantByte[i];
};
if(leftBit > 0)
{
containByteArray[byteLocation + wholeByte] &= (byte)~(0xff >> bitEnd % 8);
containByteArray[byteLocation + wholeByte] |= (byte)(wantByte[wholeByte] << (8 - leftBit));
};
return;
}
else
{
int bitMask = 0xFF >> bitLocation;
byte firstByte = (byte)(wantByte[0] & bitMask);
byte lastByte = (byte)(wantByte[0] & ~bitMask);
for (int i = 1; i < wholeByte; ++i)
{
containByteArray[byteLocation + i] = wantByte[i];
};
containByteArray[byteLocation] &= (byte)~bitMask;
containByteArray[byteLocation] |= firstByte;
containByteArray[byteLocation + wholeByte] &= (byte)bitMask;
containByteArray[byteLocation + wholeByte] |= lastByte;
if(wholeByte < 4)
{
if (lastBit > 8)
{
containByteArray[byteLocation + wholeByte] &= (byte)~bitMask;
containByteArray[byteLocation + wholeByte] |= (byte)(wantByte[wholeByte] & bitMask);
bitMask = ~(0xff >> lastBit % 8);
containByteArray[byteLocation + wholeByte + 1] &= (byte)~bitMask;
containByteArray[byteLocation + wholeByte + 1] |= (byte)((wantByte[wholeByte] << (8 - leftBit)) & bitMask);
}
else if (leftBit > 0)
{
bitMask = ~(~bitMask | (0xff >> bitLocation + leftBit));
containByteArray[byteLocation + wholeByte] &= (byte)~bitMask;
containByteArray[byteLocation + wholeByte] |= (byte)((wantByte[wholeByte] << (8 - lastBit)) & bitMask);
};
};
return;
};
};
}
private byte[] GetByte(int targetIndex)
{
int bitLocation = locationBitArray[targetIndex] % 8;
int byteLocation = locationBitArray[targetIndex] >> 3;
int bitEnd = bitLocation + TypeLength(containTypeArray[targetIndex]);
int byteEnd = (locationBitArray[targetIndex] + TypeLength(containTypeArray[targetIndex])) >> 3;
int wholeByte = TypeLength(containTypeArray[targetIndex]) >> 3;
int leftBit = TypeLength(containTypeArray[targetIndex]) % 8;
int lastBit = leftBit + bitLocation;
byte[] result = new byte[4];
if (byteEnd > containByteArray.Length)
{
return result;
};
if (1 < TypeLength(containTypeArray[targetIndex]) && TypeLength(containTypeArray[targetIndex]) < 8)
{
if (bitEnd < 9)
{
int bitMask = (0xff >> bitLocation) ^ (0xff >> bitEnd);
result[0] = (byte)((containByteArray[byteLocation] & bitMask) >> (8 - bitEnd));
}
else
{
int bitMask = (0xff >> bitLocation);
result[0] = (byte)(containByteArray[byteLocation] & bitMask);
bitMask = ~(0xff >> (bitEnd - 8));
result[0] |= (byte)((containByteArray[byteLocation + 1] & bitMask) >> (8 - TypeLength(containTypeArray[targetIndex])));
};
}
else
{
if (bitLocation == 0)
{
for (int i = 0; i < wholeByte; ++i)
{
result[i] = containByteArray[byteLocation + i];
};
if (leftBit > 0)
{
result[wholeByte] = (byte)(containByteArray[byteLocation + wholeByte] & ~(0xff >> bitEnd % 8));
result[wholeByte] = (byte)(result[wholeByte] >> (8 - leftBit));
};
}
else
{
int bitMask = 0xFF >> bitLocation;
result[0] = (byte)(containByteArray[byteLocation] & bitMask);
result[0] |= (byte)(containByteArray[byteLocation + wholeByte] & ~bitMask);
for (int i = 1; i < wholeByte; ++i)
{
result[i] = containByteArray[byteLocation + i];
};
if(wholeByte != 4)
{
if (lastBit > 8)
{
result[wholeByte] = (byte)(containByteArray[byteLocation + wholeByte] & bitMask);
bitMask = ~(0xff >> lastBit % 8);
result[wholeByte] |= (byte)((containByteArray[byteLocation + wholeByte + 1] & bitMask) >> (8 - leftBit));
}
else if(leftBit > 0)
{
bitMask = ~(~bitMask | (0xff >> bitLocation + leftBit));
result[wholeByte] = (byte)((containByteArray[byteLocation + wholeByte] & bitMask) >> (8 - lastBit));
};
};
};
};
if(TypeLength(containTypeArray[targetIndex]) % 8 == 0)
{
if (wholeByte <= result.Length && (result[wholeByte - 1] & (0x80)) > 0)
{
for (int i = 3; i>=wholeByte; --i)
{
result[i] = 0xff;
};
};
}
else
{
if (wholeByte < result.Length && (result[wholeByte] & (0x01 << leftBit - 1)) > 0)
{
for (int i = 3; i > wholeByte; --i)
{
result[i] = 0xff;
};
result[wholeByte] |= (byte)(0xff << leftBit);
};
};
return result;
}
public bool SetByteArray(byte[] wantArray)
{
if (wantArray.Length == containByteArray.Length)
{
containByteArray = wantArray;
return true;
}
else
{
return false;
};
}
public byte[] GetByteArray()
{
return containByteArray;
}
}