示例#1
0
        public SegmentCollection GetRange(long pos1, long pos2)
        {
            long mapping1, mapping2;

            Util.List <Segment> .Node node1;
            Util.List <Segment> .Node node2;

            // Find the segments of the end points.
            // Search for the ending point first so that we won't
            // have to invalidate the cache later
            Segment s2 = FindSegment(pos2, out mapping2, out node2);
            Segment s1 = FindSegment(pos1, out mapping1, out node1);

            if (s1 == null || s2 == null)
            {
                return(null);
            }

            if (ReferenceEquals(node1, node2))
            {
                SegmentCollection scTemp = new SegmentCollection();
                Segment           seg    = new Segment(s1.Buffer, pos1 - mapping1 + s1.Start, pos2 - mapping1 + s1.Start);
                scTemp.Append(seg);
                return(scTemp);
            }

            // try to split the ending segment
            Segment sl = new Segment(s2.Buffer, s2.Start, pos2 - mapping2 + s2.Start);

            // try to split the starting segment
            Segment sf = new Segment(s1.Buffer, pos1 - mapping1 + s1.Start, s1.End);


            SegmentCollection sc = new SegmentCollection();

            // append the first segment
            sc.Append(sf);

            Util.List <Segment> .Node n = node1.next;

            // append to new and remove from old
            // all segments up to node2
            while (ReferenceEquals(n, node2) == false)
            {
                sc.Append(new Segment(n.data.Buffer, n.data.Start, n.data.End));
                n = n.next;
            }

            sc.Append(sl);

            return(sc);
        }
示例#2
0
        public override void Do()
        {
            if (seg == null)
            {
                return;
            }
            SegmentCollection tmp = new SegmentCollection();

            // use copy of segment seg to protect it from alterations
            tmp.Append(new Segment(seg.Buffer, seg.Start, seg.End));
            byteBuf.segCol.Insert(tmp, pos);
            byteBuf.size += seg.Size;
        }
示例#3
0
        ///<summary>
        /// Sets the file buffer and resets the segment collection
        ///</summary>
        private void LoadWithFile(string filename)
        {
            if (fileBuf == null)
            {
                fileBuf = new FileBuffer(filename, 0xffff);         // 64KB buffer
            }
            else
            {
                fileBuf.Load(filename);
            }

            Segment s = new Segment(fileBuf, 0, fileBuf.Size - 1);

            segCol = new SegmentCollection();
            segCol.Append(s);
            size = fileBuf.Size;

            SetupFSW();
        }
示例#4
0
        ///<summary>Delete a range from the collection</summary>
        public SegmentCollection DeleteRange(long pos1, long pos2)
        {
            long mapping1, mapping2;

            Util.List <Segment> .Node node1;
            Util.List <Segment> .Node node2;

            // Find the segments of the end points.
            // Search for the ending point first so that we won't
            // have to invalidate the cache later
            Segment s2 = FindSegment(pos2, out mapping2, out node2);
            Segment s1 = FindSegment(pos1, out mapping1, out node1);

            if (s1 == null || s2 == null)
            {
                return(null);
            }

            // ending segment == starting segment
            // needs special handling
            #region Special Handling if node1==node2
            if (ReferenceEquals(node1, node2))
            {
                bool remove_flag = false;

                // try to split segment at pos1
                Segment s_f = s1.SplitAt(pos1 - mapping1);
                // if we can't, this means that pos1 is
                // at the beginning of the segment
                if (s_f == null)
                {
                    s_f         = s1;
                    remove_flag = true;
                }

                // try to split s_f at pos2+1
                // s_l is the ending part of s1 that we
                // should keep
                Segment s_l = s_f.SplitAt(pos2 - pos1 + 1);

                // if we can't split, this means that pos2 is
                // at the end of the segment,
                // otherwise add s_l after node1 (which contains s1)
                if (s_l != null)
                {
                    list.InsertAfter(node1, s_l);
                }

                // if we should remove s1
                if (remove_flag)
                {
                    // try to set the cache
                    if (node1.next != null)
                    {
                        SetCache(node1.next, mapping1);
                    }
                    else if (node1.prev != null)
                    {
                        Segment s = node1.prev.data;
                        SetCache(node1.prev, mapping1 - s.Size);
                    }
                    else
                    {
                        InvalidateCache();
                    }

                    list.Remove(node1);
                }
                //else leave the cache set as is (node1, mapping1)

                SegmentCollection s_c = new SegmentCollection();
                s_c.Append(s_f);

                return(s_c);
            }
            #endregion
            // try to split the ending segment
            Segment sl = s2.SplitAt(pos2 - mapping2 + 1);

            // if we can't, this means that pos2 is the
            // at the end of the ending segment
            if (sl == null)
            {
                sl = s2;                // set the whole segment for removal
            }
            else
            {
                list.InsertAfter(node2, sl);
            }


            Util.List <Segment> .Node n = node1.next;

            // try to split the starting segment
            Segment sf = s1.SplitAt(pos1 - mapping1);

            // if we can't, this means that pos1 is
            // at the beginning of the starting segment
            if (sf == null)
            {
                sf = s1;
                // try to set the cache
                if (node1.prev != null)
                {
                    Segment s = node1.prev.data;
                    SetCache(node1.prev, mapping1 - s.Size);
                }
                else
                {
                    InvalidateCache();
                }

                list.Remove(node1);         // remove the whole segment
            }

            SegmentCollection sc = new SegmentCollection();

            // append the first segment
            sc.Append(sf);

            // append to new and remove from old
            // all segments up to node2
            while (ReferenceEquals(n, node2) == false)
            {
                sc.Append(n.data);
                Util.List <Segment> .Node p = n;
                n = n.next;
                // Remove() must be placed after n.next
                // because it sets n.next=null
                list.Remove(p);
            }
            // append and remove node2
            list.Remove(n);
            sc.Append(n.data);

            return(sc);
        }