Washi1337 / AvaloniaHex

A hex editor control for Avalonia.
MIT License
78 stars 7 forks source link

Removing/inserting bytes to a hex editor #10

Open kb-1000 opened 1 week ago

kb-1000 commented 1 week ago

CanRemove and RemoveBytes exist, but appear to be unused.

kb-1000 commented 1 week ago

Inserting also seems to behave quite weirdly in general - so currently more or less everything but viewing and editing existing bytes appears to be broken. Unfortunately there's also no builtin resizable IBinaryDocument, though currently there wouldn't be much of a point anyways. I created my own using a List<byte>, could PR it if this gets fixed. This screenshot shows some (but not all) of the weirdness, created by repeatedly typing A in varying locations: image It only really lets you edit one of the two half-bytes in insert mode. It also doesn't let you place the caret behind the last half-byte, so you can't append bytes.

DynamicBinaryDocument

```cs public class DynamicBinaryDocument : IBinaryDocument { private readonly List _data; public event EventHandler? Changed; public DynamicBinaryDocument(byte[] data) { _data = [..data]; _validRanges = new BitRangeUnion([new BitRange(0UL, Length)]); } public ulong Length => (ulong)_data.Count; public bool IsReadOnly => false; public bool CanInsert => true; public bool CanRemove => true; private readonly BitRangeUnion _validRanges; public IReadOnlyBitRangeUnion ValidRanges => _validRanges; public void ReadBytes(ulong offset, Span buffer) { CollectionsMarshal.AsSpan(_data).Slice((int)offset, buffer.Length).CopyTo(buffer); } public void WriteBytes(ulong offset, ReadOnlySpan buffer) { buffer.CopyTo(CollectionsMarshal.AsSpan(_data).Slice((int)offset, buffer.Length)); OnChanged(new BinaryDocumentChange(BinaryDocumentChangeType.Modify, new BitRange(offset, offset + (ulong) buffer.Length))); } public void InsertBytes(ulong offset, ReadOnlySpan buffer) { _data.InsertRange((int)offset, buffer); _validRanges.Add(new BitRange(Length - (ulong)buffer.Length, Length)); OnChanged(new BinaryDocumentChange(BinaryDocumentChangeType.Insert, new BitRange(offset, offset + (ulong) buffer.Length))); } public void RemoveBytes(ulong offset, ulong length) { _data.RemoveRange((int)offset, (int)length); _validRanges.Remove(new BitRange(Length, Length + length)); OnChanged(new BinaryDocumentChange(BinaryDocumentChangeType.Insert, new BitRange(offset, offset + length))); } protected virtual void OnChanged(BinaryDocumentChange e) { Changed?.Invoke(this, e); } } ```

Washi1337 commented 1 week ago

This is correct. Currently the control only fully supports viewing and editing existing bytes. This is also one of the reasons there is no dynamically resizable binary document implementation yet. The interface methods are currently there as a WIP / future work.

Ideally, for a dynamically resizable document we should not use List<byte>, as this would result in insert and remove becoming O(n) operations, which is really bad for large documents of several 100s of megabytes to gigabytes.