예제 #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 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);
        }
예제 #3
0
        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);
        }
예제 #4
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);
        }
예제 #5
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.");
            }
        }
예제 #6
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.");
            }
        }