wanggangzero.CSharpUtil.Bits.BitField
1.0.15
.NET 6.0
This package targets .NET 6.0. The package is compatible with this framework or higher.
.NET Standard 2.0
This package targets .NET Standard 2.0. The package is compatible with this framework or higher.
dotnet add package wanggangzero.CSharpUtil.Bits.BitField --version 1.0.15
NuGet\Install-Package wanggangzero.CSharpUtil.Bits.BitField -Version 1.0.15
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="wanggangzero.CSharpUtil.Bits.BitField" Version="1.0.15" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="wanggangzero.CSharpUtil.Bits.BitField" Version="1.0.15" />
<PackageReference Include="wanggangzero.CSharpUtil.Bits.BitField" />
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add wanggangzero.CSharpUtil.Bits.BitField --version 1.0.15
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: wanggangzero.CSharpUtil.Bits.BitField, 1.0.15"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package wanggangzero.CSharpUtil.Bits.BitField@1.0.15
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=wanggangzero.CSharpUtil.Bits.BitField&version=1.0.15
#tool nuget:?package=wanggangzero.CSharpUtil.Bits.BitField&version=1.0.15
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
ReadMe
A C# BitField library.
这是一个在 C# 中的位域操作库,在没有原生语法糖加持的情况下,已经是非常舒服的写法了。
作者封装了用于实现位域的各种位移,且,或操作,使得在 C# 中也能灵活操作内存中的任意一个 bit。
位域操作可能是个比较小众的使用场景,欢迎大家互通有无。
Examples:
0x00. Demo (示例)
ABT bT = new ABT() { EA = A.Eghit | A.Two, EB = B.Three, IsBitFields = true };
// 是的,支持枚举, 甚至其他unmanaged数据
// 比如自定义的struct也是支持的(但内存布局需要紧凑模式:[StructLayout(LayoutKind.Sequential, Pack = 1)])
[Flags]
enum A : byte
{
Zero = 0,
One = 1 << 0,
Two = 1 << 1,
Four = 1 << 2,
Eghit = 1 << 3,
}
enum B : byte
{
One = 1,
Two = 2,
Three = 3,
}
// sizeof(ABT) = 1
struct ABT
{
private byte data;
public byte Data() => data;
public static implicit operator byte(ABT self) => self.data;
public static explicit operator ABT(byte mData) => new() { data = mData };
public bool IsBitFields
{
get => data.BitField<bool>(0, 1);
set => data.SetBitField(value, 0, 1);
}
public A EA
{
get => data.BitField<A>(1, 4);
set => data.SetBitField(value, 1, 4);
}
public B EB
{
get => data.BitField<B>(5, 2);
set => data.SetBitField(value, 5, 2);
}
}
0x01. SnowFlake (分布式开发中的雪花ID算法)
class SnowFlake
{
static private long Ts() => DateTimeOffset.Now.ToUnixTimeMilliseconds(); // - 2015; if you like
public static SnowFlake NextId(int serialNum, int machineID)
=> new(sid: serialNum, mid: machineID);
private SnowFlake(int mid, int sid)
{
TimeStamp = Ts();
SerialNumber = sid;
MachineID = mid;
}
// 12位序列号
public int SerialNumber
{
get => m_data.BitField<int>(0, 12);
set => m_data.SetBitField(value, 0, 12);
}
// 41位时间戳
public long TimeStamp
{
get => m_data.BitField<long>(23, 41);
private set => m_data.SetBitField(value, 23, 41);
}
// 10位设备id
public int MachineID
{
get => m_data.BitField<int>(12, 10);
set => m_data.SetBitField(value, 12, 10);
}
// 内部数据用于存储实际bits
long m_data;
}
0x02. RGBA In Graphic and Images (图形图像中的RGBA)
// sizeof(RGB565) = 2, := we can control the layout same as mData
struct RGB565
{
public byte R
{
get => mData.BitField<byte>(0, 5);
set => mData.SetBitField(value, 0, 5);
}
public byte G
{
get => mData.BitField<byte>(5, 6);
set => mData.SetBitField(value, 5, 6);
}
public byte B
{
get => mData.BitField<byte>(11, 5);
set => mData.SetBitField(value, 11, 5);
}
public ushort mData;
}
// sizeof(RGB5551) = 2, := we can control the layout same as mData
struct RGBA5551
{
public byte R
{
get => mData.BitField<byte>(0, 5);
set => mData.SetBitField(value, 0, 5);
}
public byte G
{
get => mData.BitField<byte>(5, 5);
set => mData.SetBitField(value, 5, 5);
}
public byte B
{
get => mData.BitField<byte>(10, 5);
set => mData.SetBitField(value, 10, 5);
}
public byte A
{
get => mData.BitField<byte>(15, 1);
set => mData.SetBitField(value, 15, 1);
}
public ushort mData;
}
0x03. IPV6 Header (网络开发中的IPv6包头)
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | 版本 | 优先权 | 流 标 签 |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | 有效载荷长度 | 下一报头 | 跳限制 |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | |
// + +
// | |
// + 源 地 址 +
// | long |
// + +
// | |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | |
// + +
// | |
// + 目 的 地 址 +
// | long |
// + +
// | |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// sizeof(IPV6Head) = 8, := we can control the layout same as mData
// yes, I designed it on purpose. The memory layout is very clean.
// 所有例子我都是专门设计的, 内存布局十分干净, 可以方便的直接进行IO复制.
struct IPV6Head
{
public byte Version
{
get => mData.BitField<byte>(0, 4);
set => mData.SetBitfield(value, 0, 4);
}
public byte TrafficClass
{
get => mData.BitField<byte>(5, 8);
set => mData.SetBitField(value, 5, 8);
}
public int FlowLabel
{
get => mData.BitField<int>(12, 20);
set => mData.SetBitField(value, 12, 20);
}
public int PayloadLength
{
get => mData.BitField<int>(32, 16);
set => mData.SetBitField(value, 32, 16);
}
public byte NextHeader
{
get => mData.BitField<byte>(48, 8);
set => mData.SetBitField(value, 48, 8);
}
public byte HopLimit
{
get => mData.BitField<byte>(56, 8);
set => mData.SetBitField(value, 56, 8);
}
public ulong mData;
}
0x04 [BitFields] Attribute模拟定义一个位域struct (需要 lib version >=1.0.10 and .net >= 9.0)
// 它的内存布局也是设计为与BaseType一致, 可以直接内存读写.
// like: var s = (Some)BinaryReader.ReadInt32(xx); or Use UnSafe.Read<Some>(ptr);
// Its memory layout is also designed to be consistent with that of BaseType,
// allowing for direct read and write operations in memory.
[BitFields(EBitFieldBaseType.Int64)]
public partial struct Some
{
[BitOffset(0, 8)] //
public partial byte Age { get; set; }
[BitOffset(8, 1)]
public partial bool Sex { get; set; }
[BitOffset(16, 12)]
internal partial int Year { get; set; }
[BitOffset(31, 1)]
public partial bool Sign { get; internal set; }
//[BitOffset(31, 1)] // 这个是无效的
public static bool Ok { get; }
}
// then code generator will product code like this:
public partial struct Some
{
private Int64 data;
public partial Byte Age
{
get => data.BitField<Byte>(0, 8);
set => data.SetBitField<Byte>(value, 0, 8);
}
public partial Boolean Sex
{
get => data.BitField<Boolean>(8, 1);
set => data.SetBitField<Boolean>(value, 8, 1);
}
internal partial Int32 Year
{
get => data.BitField<Int32>(16, 12);
set => data.SetBitField<Int32>(value, 16, 12);
}
public partial Boolean Sign
{
get => data.BitField<Boolean>(31, 1);
internal set => data.SetBitField<Boolean>(value, 31, 1);
}
/// <summary>
/// 原型数据
/// </summary>
public Int64 Data() => data;
/// <summary>
/// 隐式转换为基础类型
/// </summary>
/// <param name="self"></param>
public static implicit operator Int64(Some self) => self.data;
/// <summary>
/// 从基础类型显式转换为当前类型
/// </summary>
/// <param name="mData"></param>
public static explicit operator Some(Int64 mData) => new() { data = mData };
/// <summary>
/// 序列化为字节数组
/// </summary>
/// <returns></returns>
public byte[] Bytes() => BytesUtil.Bytes(this);
/// <summary>
/// 序列化为网络序字节数组(大端序)
/// </summary>
/// <returns></returns>
public byte[] NetBytes()=> BytesUtil.NetBytes(this);
/// <summary>
/// 从字节数组反序列化数据结构
/// </summary>
/// <param name="bytes"></param>
/// <param name="ReadAsBigEndian">是否按网络序读取数据</param>
/// <returns></returns>
public static Some CastFrom(byte[] bytes, bool ReadAsBigEndian = false) => bytes.To<Some>(ReadAsBigEndian);
}
At last(写在最后): Personally, I think this code is ready to use, but anyone using it needs to test it carefully and at their own risk. 个人认为此代码已经可以使用, 但任何人使用它都需要自己进行谨慎测试并承担其风险.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.0
- wanggangzero.CSharpUtil.Bits.Dancing (>= 1.0.13)
-
net6.0
- wanggangzero.CSharpUtil.Bits.Dancing (>= 1.0.13)
-
net7.0
- wanggangzero.CSharpUtil.Bits.Dancing (>= 1.0.13)
-
net8.0
- wanggangzero.CSharpUtil.Bits.Dancing (>= 1.0.13)
-
net9.0
- wanggangzero.CSharpUtil.Bits.Dancing (>= 1.0.13)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
fix bugs.