//----------------------------------------------------------------------- //----------------------------------------------------------------------- // file="MappingTable.cs" // Project: StgSharp // AuthorGroup: Nitload Space // Copyright (c) Nitload Space. All rights reserved. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the “Software”), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and // this permission notice shall be included in all copies // or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED “AS IS”, // WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, // ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // //----------------------------------------------------------------------- //----------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; namespace StgSharp.Data { public partial class HuffmanTree where T : struct { public Dictionary> BuildHuffmanDictionary() { Dictionary> ret = new Dictionary>(); TreeNode root = Root; HuffmanKey key = new HuffmanKey(); key = key.SetSide(KeySide.Right); InternalBuildDictionary(ret, root, key); return ret; } public void InternalBuildDictionary( Dictionary> dict, TreeNode node, HuffmanKey valueTemp ) { HuffmanKey nativeNode = new HuffmanKey(valueTemp.bitList); nativeNode.AddIndexLevel(); //检查左节点 if (node._left.Value == null) { //左节点不是叶子节点,继续搜索 InternalBuildDictionary( dict, node._left, nativeNode.SetSide(KeySide.Left)); } else { //左节点是叶子节点,添加值 dict.Add(node._left.Value.Value, nativeNode.SetSide(KeySide.Left)); } //检查右节点 if (node._right.Value == null) { //右节点不是叶子节点,继续搜索 InternalBuildDictionary( dict, node._right, nativeNode.SetSide(KeySide.Right)); } else { //右节点是叶子节点,添加值 dict.Add(node._right.Value.Value, nativeNode.SetSide(KeySide.Right)); } //这里检查自己是不是叶子节点 //但是上面已经检查过了,不需要被检查 } } public class HuffmanKey where T : struct { internal List bitList; internal BitArray code; public HuffmanKey() { bitList = new List(); bitList.Add(false); } public HuffmanKey(List former) { bitList = new List(former); } public bool IsSupported { get { return (typeof(T) == typeof(byte)) || (typeof(T) == typeof(uint)) || (typeof(T) == typeof(ushort)) || (typeof(T) == typeof(ulong)) || #if NET7_0_OR_GREATER typeof(T) == typeof(UInt128) || #endif (typeof(T) == typeof(M128)); } } public unsafe void AddIndexLevel() { bitList.Add(true); } public void Freeze() { if (code != null) { return; } bitList.RemoveAt(0); code = new BitArray(bitList.ToArray()); } public BitArray GetBitArray() { if (code == null) { List list = new List(bitList); list.RemoveAt(0); return new BitArray(list.ToArray()); } return code; } public unsafe byte[] GetBytes() { byte[] bytes = new byte[(bitList.Count / 8) + 1]; BitArray array = new BitArray(bitList.ToArray()); array.CopyTo(bytes, 0); return bytes; } public unsafe HuffmanKey SetSide(KeySide side) { HuffmanKey newKey = new HuffmanKey(bitList); newKey.bitList[newKey.bitList.Count - 1] = side == KeySide.Left; return newKey; } public override string ToString() { string str = string.Empty; foreach (var bit in bitList) { str += $"{bit} "; } return str; } } public enum KeySide { Left, Right } }