This repository was archived by the owner on May 8, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBitHelper.cs
More file actions
126 lines (100 loc) · 3.69 KB
/
Copy pathBitHelper.cs
File metadata and controls
126 lines (100 loc) · 3.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
using System;
namespace BitHelper
{
public class GreaterThanMaximumException : Exception
{
public GreaterThanMaximumException(byte max) : base($"The value cannot be greater than {max}!") { }
}
public class ByteOverflowException : Exception
{
public ByteOverflowException() : base("An attempt was made to add more bits than a byte can hold.") {}
}
// A byte cannot be separated into more than 8 bits.
public class NotEnoughBitsException : Exception {}
public class MissingArgumentException : ArgumentException {}
public enum StorageType : byte
{
Bit = 1,
Crumb = 2,
Tribit = 3,
Nibble = 4,
Pentad = 5,
Hexad = 6,
Heptad = 7,
Byte = 8
}
static class StorageServices
{
static internal StorageType Combine(this StorageType a, StorageType b)
{
if ((byte)a + (byte)b > (byte)StorageType.Byte)
throw new ByteOverflowException();
return (StorageType)((byte)a + (byte)b);
}
static public byte[] ToByteArray(this StorageUnit[] storageUnits)
{
var result = new byte[storageUnits.Length];
for (int index = 0; index < storageUnits.Length; ++index)
result[index] = storageUnits[index].Value;
return result;
}
}
public class StorageUnit
{
private byte value;
public StorageType Type { get; private set; }
public byte MaxValue => (byte)(Math.Pow(2, (double)Type) - 1);
/***************************\
* Maximum Value = 2ᵀʸᵖᵉ - 1 *
\***************************/
public byte Value
{
get => value;
set
{
if (value > MaxValue) throw new GreaterThanMaximumException(MaxValue);
this.value = value;
}
}
public StorageUnit(byte value, StorageType type)
{
Type = type;
if (value > MaxValue) throw new GreaterThanMaximumException(MaxValue);
this.value = value;
}
public override string ToString() => Convert.ToString(value, 2);
public StorageUnit Combine(params StorageUnit[] storageUnits)
{
var type = Type;
var val = value;
foreach (var unit in storageUnits)
{
val |= (byte)(unit.value << (byte)unit.Type);
type = type.Combine(unit.Type);
}
return new StorageUnit(val, type);
}
static public StorageUnit[] Separate(byte value, params StorageType[] storageTypes)
{
// validation loop to make sure the method isn't trying to split more data than available.
byte count = 0;
for (int index = 0; index < storageTypes.Length; ++index)
{
count += (byte)storageTypes[index];
if (count > 8) throw new NotEnoughBitsException();
}
// Validation check to make sure the method isn't missing any data.
if (count != 8) throw new MissingArgumentException();
var storageUnits = new StorageUnit[storageTypes.Length];
byte lastValue = 0;
for (int index = 0; index < storageUnits.Length; ++index)
{
byte newValue = (byte)(value << lastValue),
currentValue = (byte)(newValue >> (byte)(8 - (byte)storageTypes[index]));
storageUnits[index] = new StorageUnit(currentValue, storageTypes[index]);
lastValue += (byte)storageTypes[index];
}
return storageUnits;
}
}
}