public byte ReadByte(long index, out bool isChanged) { long startIndex = 0; isChanged = false; BytePart bytePart = BytePartGetInfo(index, out startIndex); FileBytePart fileBytePart = bytePart as FileBytePart; MemoryBytePart memoryBytePart = bytePart as MemoryBytePart; if (fileBytePart != null) { if (_fileDataStream.Position != fileBytePart.FilePartIndex + index - startIndex) { _fileDataStream.Position = fileBytePart.FilePartIndex + index - startIndex; } return((byte)_fileDataStream.ReadByte()); } if (memoryBytePart != null) { isChanged = true; return(memoryBytePart.Bytes[index - startIndex]); } else { throw new ArgumentNullException("index", "FileByteData.ReadByte: The internal BytePartList is corrupt."); } }
public void DeleteBytes(long index, long length, bool track_Change = true) { long tempLength = length; Byte[] oldData = new Byte[length]; for (long l = 0; l < length; l++) { oldData[l] = ReadByte(l + index); } if (track_Change) { _undoList.Add(new UndoAction(oldData, index, mod_type.mod_delete)); } BytePart bytePart = BytePartGetInfo(index, out long startIndex); while ((tempLength > 0) && (bytePart != null)) { LinkedListNode <BytePart> bp = _bytePartList.Find(bytePart); BytePart nextBytePart = (bp.Next != null) ? bp.Next.Value : null; long byteCount = Math.Min(tempLength, bytePart.Length - (index - startIndex)); System.Diagnostics.Debug.Assert(byteCount > 0); bytePart.RemoveBytes(index - startIndex, byteCount, _bytePartList); if (bytePart.Length == 0) { _bytePartList.Remove(bytePart); if (_bytePartList.First == null) { _bytePartList.AddFirst(new MemoryBytePart(new byte[0])); } } tempLength -= byteCount; startIndex += bytePart.Length; bytePart = (tempLength > 0) ? nextBytePart : null; } Length -= length; OnDataLengthChanged(EventArgs.Empty); OnDataChanged(EventArgs.Empty); }
BytePart BytePartGetInfo(long index, out long startIndex) { BytePart bytePart = null; startIndex = 0; if (index < 0 || index > Length) { throw new ArgumentOutOfRangeException("index", "FileByteData.BytePartGetInfo: The parameter is outside the file limits."); } for (LinkedListNode <BytePart> bp = _bytePartList.First; bp != null; bp = bp.Next) { if ((startIndex <= index && startIndex + bp.Value.Length > index) || bp.Next == null) { bytePart = bp.Value as BytePart; break; } startIndex += bp.Value.Length; } return(bytePart); }
FileBytePart GetNextFileBytePart(BytePart bytePart, long index, out long nextIndex) { FileBytePart nextFileBytePart = null; nextIndex = index + bytePart.Length; LinkedListNode <BytePart> bp = _bytePartList.Find(bytePart); // run through the whole bytePart list from the current position + 1, to find the next FileBytePart for (LinkedListNode <BytePart> bp1 = bp.Next; bp1 != null; bp1 = bp1.Next) { FileBytePart fileBytePart = bp1.Value as FileBytePart; if (fileBytePart != null) { nextFileBytePart = fileBytePart; break; } nextIndex += bp1.Value.Length; } return(nextFileBytePart); }
public void InsertBytes(long index, byte[] value, bool track_Change = true) { if (track_Change) { _undoList.Add(new UndoAction(value, index, mod_type.mod_insert)); } BytePart bytePart = BytePartGetInfo(index, out long startIndex); FileBytePart fileBytePart = bytePart as FileBytePart; MemoryBytePart memoryBytePart = bytePart as MemoryBytePart; if (memoryBytePart != null) { memoryBytePart.InsertBytes(index - startIndex, value); Length += value.Length; OnDataLengthChanged(EventArgs.Empty); OnDataChanged(EventArgs.Empty); return; } LinkedListNode <BytePart> bp = _bytePartList.Find(bytePart); if (startIndex == index && bp.Previous != null) { MemoryBytePart prevMemoryBytePart = bp.Previous.Value as MemoryBytePart; if (prevMemoryBytePart != null) { prevMemoryBytePart.InsertBytes(prevMemoryBytePart.Length, value); Length += value.Length; OnDataLengthChanged(EventArgs.Empty); OnDataChanged(EventArgs.Empty); return; } } if (fileBytePart != null) { FileBytePart newPrevFileBytePart = null; FileBytePart newNextFileBytePart = null; if (index > startIndex) { newPrevFileBytePart = new FileBytePart(fileBytePart.FilePartIndex, index - startIndex); } if (index < startIndex + fileBytePart.Length) { newNextFileBytePart = new FileBytePart( fileBytePart.FilePartIndex + index - startIndex, fileBytePart.Length - (index - startIndex)); } BytePart newBP = new MemoryBytePart(value); _bytePartList.Find(bytePart).Value = newBP; bytePart = newBP; if (newPrevFileBytePart != null) { LinkedListNode <BytePart> bp1 = _bytePartList.Find(bytePart); _bytePartList.AddBefore(bp1, newPrevFileBytePart); } if (newNextFileBytePart != null) { LinkedListNode <BytePart> bp2 = _bytePartList.Find(bytePart); _bytePartList.AddAfter(bp2, newNextFileBytePart); } Length += value.Length; OnDataLengthChanged(EventArgs.Empty); OnDataChanged(EventArgs.Empty); } else { throw new ArgumentNullException("index", "FileByteData.InsertBytes: The internal BytePartList is corrupt."); } }
public void WriteByte(long index, byte value, bool track_Change = true) { long startIndex = 0; byte oldValue = ReadByte(index); if (track_Change) { _undoList.Add(new UndoAction(new byte[] { oldValue }, index, mod_type.mod_replace)); } BytePart bytePart = BytePartGetInfo(index, out startIndex); FileBytePart fileBytePart = bytePart as FileBytePart; MemoryBytePart memoryBytePart = bytePart as MemoryBytePart; if (memoryBytePart != null) { memoryBytePart.Bytes[index - startIndex] = value; OnDataChanged(EventArgs.Empty); return; } if (fileBytePart != null) { LinkedListNode <BytePart> bp = _bytePartList.Find(bytePart); if (index == startIndex && bp.Previous != null) { MemoryBytePart prevMemoryBytePart = bp.Previous.Value as MemoryBytePart; if (prevMemoryBytePart != null) { prevMemoryBytePart.AddByteToEnd(value); fileBytePart.RemoveBytesFromStart(1); if (fileBytePart.Length == 0) { _bytePartList.Remove(fileBytePart); } OnDataChanged(EventArgs.Empty); return; } } if (index == startIndex + fileBytePart.Length - 1 && bp.Next != null) { MemoryBytePart nextMemoryBytePart = bp.Next.Value as MemoryBytePart; if (nextMemoryBytePart != null) { nextMemoryBytePart.AddByteToStart(value); fileBytePart.RemoveBytesFromEnd(1); if (fileBytePart.Length == 0) { _bytePartList.Remove(fileBytePart); } OnDataChanged(EventArgs.Empty); return; } } FileBytePart newPrevFileBytePart = null; FileBytePart newNextFileBytePart = null; if (index > startIndex) { newPrevFileBytePart = new FileBytePart(fileBytePart.FilePartIndex, index - startIndex); } if (index < startIndex + fileBytePart.Length - 1) { newNextFileBytePart = new FileBytePart( fileBytePart.FilePartIndex + index - startIndex + 1, fileBytePart.Length - (index - startIndex + 1)); } BytePart newMemoryBP = new MemoryBytePart(value); _bytePartList.Find(bytePart).Value = newMemoryBP; bytePart = newMemoryBP; if (newPrevFileBytePart != null) { LinkedListNode <BytePart> bp1 = _bytePartList.Find(bytePart); _bytePartList.AddBefore(bp1, newPrevFileBytePart); } if (newNextFileBytePart != null) { LinkedListNode <BytePart> bp2 = _bytePartList.Find(bytePart); _bytePartList.AddAfter(bp2, newNextFileBytePart); } OnDataChanged(EventArgs.Empty); } else { throw new ArgumentNullException("index", "FileByteData.WriteByte: The internal BytePartList is corrupt."); } }