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); }
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; }
///<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(); }
///<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); }