/// <summary> /// Finds the name of the closest symbol to an address /// </summary> /// <param name="address">The address</param> /// <param name="addressOffset">A pointer to where to store the offset from this symbol</param> /// <returns>The symbol name</returns> public static string FindSymbolName(void *address, void **addressOffset) { void *table = getSymbolTable(); // Before the first entry, there's an int stored for the amount of entries int entries = *(int *)table; int tableOffset = sizeof(int); // Find closest match int distance = 0x7FFFFFFF; string candidateName = null; void * candidateOffset = null; for (int i = 0; i < entries; i++) { // Get symbol info Symbol *sym = (Symbol *)((int)table + tableOffset); string symbolName = Util.CharPtrToString(&sym->Name); int size = sizeof(void *) + symbolName.Length + 1; // Distance from current symbol address to the address we search for int currentDistance = (int)address - (int)sym->Address; if (currentDistance < 0 || currentDistance > distance) { tableOffset += size; continue; } candidateName = symbolName; candidateOffset = (void *)currentDistance; distance = currentDistance; tableOffset += size; } *addressOffset = candidateOffset; return(candidateName); }
public override unsafe void CompressChunk(ReadOnlySpan <byte> chunk) { if (m_CompressOutput.IsEmpty) { return; } if (chunk.IsEmpty) { return; fixed(byte *pChunk = chunk) { m_CompressContext->inData = pChunk; m_CompressContext->inEnd = &pChunk[chunk.Length]; while (true) { Symbol *subcontext, symbol = null; byte value; ushort under = 0, total = 0, count = 0; ushort *parent = &m_CompressContext->predicted; if (m_CompressContext->inData >= m_CompressContext->inEnd) { break; } value = *m_CompressContext->inData++; for (subcontext = &m_CompressContext->symbols[m_CompressContext->predicted]; subcontext != m_CompressContext->root; subcontext = &m_CompressContext->symbols[subcontext->parent]) { m_CompressContext->Encode(subcontext, ref symbol, value, ref under, ref count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0); *parent = (ushort)(symbol - m_CompressContext->symbols); parent = &symbol->parent; total = subcontext->total; if (count > 0) { m_CompressContext->RangeCoderEncode((ushort)(subcontext->escapes + under), count, total); } else { if (subcontext->escapes > 0 && subcontext->escapes < total) { m_CompressContext->RangeCoderEncode(0, subcontext->escapes, total); } subcontext->escapes += ENET_SUBCONTEXT_ESCAPE_DELTA; subcontext->total += ENET_SUBCONTEXT_ESCAPE_DELTA; } subcontext->total += ENET_SUBCONTEXT_SYMBOL_DELTA; if (count > 0xFF - 2 * ENET_SUBCONTEXT_SYMBOL_DELTA || subcontext->total > ENET_RANGE_CODER_BOTTOM - 0x100) { m_CompressContext->Rescale(subcontext, 0); } if (count > 0) { goto nextInput; } } m_CompressContext->Encode(m_CompressContext->root, ref symbol, value, ref under, ref count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM); *parent = (ushort)(symbol - m_CompressContext->symbols); parent = &symbol->parent; total = m_CompressContext->root->total; m_CompressContext->RangeCoderEncode((ushort)(m_CompressContext->root->escapes + under), count, total); m_CompressContext->root->total += ENET_CONTEXT_SYMBOL_DELTA; if (count > 0xFF - 2 * ENET_CONTEXT_SYMBOL_DELTA + ENET_CONTEXT_SYMBOL_MINIMUM || m_CompressContext->root->total > ENET_RANGE_CODER_BOTTOM - 0x100) { m_CompressContext->Rescale(m_CompressContext->root, ENET_CONTEXT_SYMBOL_MINIMUM); } nextInput: if (m_CompressContext->order >= ENET_SUBCONTEXT_ORDER) { m_CompressContext->predicted = m_CompressContext->symbols[m_CompressContext->predicted].parent; } else { m_CompressContext->order++; } m_CompressContext->RangeCoderFreeSymbols(); } } }
/* Don't remove this, we may need it. */ /*static uint RangeCoderCompress(Symbol* context, byte* inBuffer, uint inBufferLen, byte* outData, uint outLimit) * { * if (context == null || inBuffer == null || outData == null) * throw new ENetCompressionException("Bad compressor arguments."); * * unchecked * { * Context ctx = new() * { * symbols = context, * outStart = outData, * outEnd = &outData[outLimit], * inData = inBuffer, * outData = outData, * inEnd = &inBuffer[inBufferLen], * low = 0, * range = (uint)~0, * root = null, * predicted = 0, * order = 0, * nextSymbol = 0, * }; * * ctx.Create(out ctx.root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM); * * while (true) * { * Symbol* subcontext, symbol = null; * byte value; * ushort under = 0, total = 0, count = 0; * ushort* parent = &ctx.predicted; * if (ctx.inData >= ctx.inEnd) * break; * * value = *ctx.inData++; * * for (subcontext = &ctx.symbols[ctx.predicted]; * subcontext != ctx.root; * subcontext = &ctx.symbols[subcontext->parent]) * { * ctx.Encode(subcontext, ref symbol, value, ref under, ref count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0); * * parent = (ushort)(symbol - ctx.symbols); * parent = &symbol->parent; * total = subcontext->total; * * if (count > 0) * { * ctx.RangeCoderEncode((ushort)(subcontext->escapes + under), count, total); * } * else * { * if (subcontext->escapes > 0 && subcontext->escapes < total) * ctx.RangeCoderEncode(0, subcontext->escapes, total); * subcontext->escapes += ENET_SUBCONTEXT_ESCAPE_DELTA; * subcontext->total += ENET_SUBCONTEXT_ESCAPE_DELTA; * } * subcontext->total += ENET_SUBCONTEXT_SYMBOL_DELTA; * if (count > 0xFF - 2 * ENET_SUBCONTEXT_SYMBOL_DELTA || subcontext->total > ENET_RANGE_CODER_BOTTOM - 0x100) * ctx.Rescale(subcontext, 0); * if (count > 0) goto nextInput; * } * * ctx.Encode(ctx.root, ref symbol, value, ref under, ref count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM); * parent = (ushort)(symbol - ctx.symbols); * parent = &symbol->parent; * total = ctx.root->total; * * ctx.RangeCoderEncode((ushort)(ctx.root->escapes + under), count, total); * ctx.root->total += ENET_CONTEXT_SYMBOL_DELTA; * if (count > 0xFF - 2 * ENET_CONTEXT_SYMBOL_DELTA + ENET_CONTEXT_SYMBOL_MINIMUM || ctx.root->total > ENET_RANGE_CODER_BOTTOM - 0x100) * ctx.Rescale(ctx.root, ENET_CONTEXT_SYMBOL_MINIMUM); * * nextInput: * if (ctx.order >= ENET_SUBCONTEXT_ORDER) * ctx.predicted = ctx.symbols[ctx.predicted].parent; * else * ctx.order++; * ctx.RangeCoderFreeSymbols(); * } * * ctx.RangeCoderFlush(); * * return (uint)(ctx.outData - ctx.outStart); * } * }*/ static uint RangeCoderDecompress(Symbol *context, byte *inData, uint inLimit, byte *outData, uint outLimit) { if (context == null || inLimit <= 0) throw new ENetCompressionException("Bad decompressor arguments."); }
public ENetRangeCoder() { m_Symbols = (Symbol *)Marshal.AllocHGlobal(sizeof(Symbol) * 4096); m_CompressContext = (Context *)Marshal.AllocHGlobal(sizeof(Context)); }