/// <summary> /// Writes the table out to the provided delegates. This is primarily for validation purposes of the algorithm. /// Functions are called based on the order nodes are encountered in the tree. /// The first value written is the number of unique symbols. /// Internal nodes write two values, the left child index and the right child index. /// </summary> public void WriteTable(WriteSymbolDelegate <TSymbolType> symbolWriter, WriteUInt32Delegate valueWriter, WriteNotYetTransmittedDelegate notYetTransmittedWriter) { valueWriter((uint)_map.Count); for (uint i = 0; i < _entries.Length; ++i) { if (_entries[i].IsLeaf) { if (_entries[i].Symbol.IsValid) { symbolWriter(_entries[i].Symbol.Symbol); } else { notYetTransmittedWriter(); } } else { valueWriter(_entries[i].LeftChild); valueWriter(_entries[i].RightChild); // Technically unneeded, but consistent with static implementation. } } }
/// <summary> /// Writes the Huffman tree for future decoding use. /// </summary> public void WriteTable(WriteSymbolDelegate <TSymbolType> symbolWriter, WriteUInt32Delegate valueWriter) { valueWriter(SymbolCount); for (uint i = 0; i < SymbolCount; ++i) { symbolWriter(_entries[i].Symbol); } for (var i = SymbolCount; i < _entries.Length; ++i) { valueWriter(_entries[i].ChildIndex[0]); valueWriter(_entries[i].ChildIndex[1]); } }
/// <summary> /// Writes the code for <paramref name="symbol" />. If the symbol was not previously encountered, /// the bit sequence to mark a symbol literal is written to <paramref name="bitWriter" /> /// and the symbol through <paramref name="symbolWriter" />. /// </summary> public void WriteCode(TSymbolType symbol, WriteBitDelegate bitWriter, WriteSymbolDelegate <TSymbolType> symbolWriter) { var nytSeen = false; if (HasSymbol(symbol)) { WriteCodeInternal(symbol, bitWriter); } else { WriteCodeInternal(SymbolSpace.NotYetTransmitted, bitWriter); UpdateSymbolInternal(SymbolSpace.NotYetTransmitted, GetTweak(symbol, true)); symbolWriter(symbol); nytSeen = true; } UpdateSymbolInternal(symbol, 1); if (!nytSeen) { UpdateSymbolInternal(SymbolSpace.NotYetTransmitted, GetTweak(symbol, false)); } }