Пример #1
0
        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.");
            }
        }
Пример #2
0
        public bool IsChanged()
        {
            if (ReadOnly)
            {
                return(false);
            }

            if (Length != _fileDataStream.Length)
            {
                return(true);
            }

            long index = 0;

            for (LinkedListNode <BytePart> bp = _bytePartList.First; bp != null; bp = bp.Next)
            {
                FileBytePart fileBytePart = bp.Value as FileBytePart;

                if (fileBytePart == null || fileBytePart.FilePartIndex != index)
                {
                    return(true);
                }

                index += fileBytePart.Length;
            }

            return(index != _fileDataStream.Length);
        }
Пример #3
0
        public void CommitChanges()
        {
            if (ReadOnly)
            {
                throw new OperationCanceledException("FileByteData.CommitChanges: The data cannot be saved when the file is in read only mode.");
            }

            if (Length > _fileDataStream.Length)
            {
                _fileDataStream.SetLength(Length);
            }

            long index = 0;

            // run through the whole bytePart list
            for (LinkedListNode <BytePart> bp = _bytePartList.First; bp != null; bp = bp.Next)
            {
                // try to convert it to a FileBytePart
                FileBytePart fileBytePart = bp.Value as FileBytePart;

                // if  it's a FileBytePart and the orig file position is different, move the FileBytePart to the new (expected) position
                if (fileBytePart != null && fileBytePart.FilePartIndex != index)
                {
                    RearrangeFileBytePart(fileBytePart, index);
                }

                // increment the index to the next expected BytePart position for file - and memory parts
                index += bp.Value.Length;
            }

            index = 0;

            // run through the whole bytePart list again, now look at the memory parts
            for (LinkedListNode <BytePart> bp = _bytePartList.First; bp != null; bp = bp.Next)
            {
                // try to convert it to a MemoryBytePart
                MemoryBytePart memoryBytePart = bp.Value as MemoryBytePart;

                // if it's a MemoryBytePart
                if (memoryBytePart != null)
                {
                    _fileDataStream.Position = index;

                    // write the MemoryBytePart into the stream
                    for (int memoryIndex = 0; memoryIndex < memoryBytePart.Length; memoryIndex += BLOCK_SIZE)
                    {
                        _fileDataStream.Write(memoryBytePart.Bytes, memoryIndex, (int)Math.Min(BLOCK_SIZE, memoryBytePart.Length - memoryIndex));
                    }
                }

                // increment the index to the next expected BytePart position for file - and memory parts
                index += bp.Value.Length;
            }

            _fileDataStream.Flush();

            InitFileByteData();
        }
Пример #4
0
        void RearrangeFileBytePart(FileBytePart bytePart, long index)
        {
            long nextIndex = 0;

            byte[] buffer = new byte[BLOCK_SIZE];

            FileBytePart nextFileBlock = GetNextFileBytePart(bytePart, index, out nextIndex);

            if (nextFileBlock != null && index + bytePart.Length > nextFileBlock.FilePartIndex)
            {
                RearrangeFileBytePart(nextFileBlock, nextIndex);
            }

            if (bytePart.FilePartIndex > index)
            {
                Array.Clear(buffer, 0, buffer.Length);

                for (long relIndex = 0; relIndex < bytePart.Length; relIndex += buffer.Length)
                {
                    int bytesToRead = (int)Math.Min(buffer.Length, bytePart.Length - relIndex);
                    _fileDataStream.Position = bytePart.FilePartIndex + relIndex;
                    _fileDataStream.Read(buffer, 0, bytesToRead);
                    _fileDataStream.Position = index + relIndex;
                    _fileDataStream.Write(buffer, 0, bytesToRead);
                }
            }
            else
            {
                Array.Clear(buffer, 0, buffer.Length);

                for (long relIndex = 0; relIndex < bytePart.Length; relIndex += buffer.Length)
                {
                    int  bytesToRead = (int)Math.Min(buffer.Length, bytePart.Length - relIndex);
                    long readOffset  = bytePart.FilePartIndex + bytePart.Length - relIndex - bytesToRead;
                    _fileDataStream.Position = readOffset;
                    _fileDataStream.Read(buffer, 0, bytesToRead);

                    long writeOffset = index + bytePart.Length - relIndex - bytesToRead;
                    _fileDataStream.Position = writeOffset;
                    _fileDataStream.Write(buffer, 0, bytesToRead);
                }
            }

            bytePart.SetFilePartIndex(index);
        }
Пример #5
0
        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);
        }
Пример #6
0
        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.");
            }
        }
Пример #7
0
        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.");
            }
        }