2362N/A * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/A * or visit www.oracle.com if you need additional information or have any 0N/A * An implementation of the AbstractDocument.Content interface 0N/A * implemented using a gapped buffer similar to that used by emacs. 0N/A * The underlying storage is a array of unicode characters with 0N/A * a gap somewhere. The gap is moved to the location of changes 0N/A * to take advantage of common behavior where most changes are 0N/A * in the same location. Changes that occur at a gap boundary are 0N/A * generally cheap and moving the gap is generally cheaper than 0N/A * moving the array contents directly to accomodate the change. 0N/A * The positions tracking change are also generally cheap to 0N/A * maintain. The Position implementations (marks) store the array 0N/A * index and can easily calculate the sequential position from 0N/A * the current gap location. Changes only require update to the 0N/A * the marks between the old and new gap boundaries when the gap 0N/A * is moved, so generally updating the marks is pretty cheap. 0N/A * The marks are stored sorted so they can be located quickly 0N/A * with a binary search. This increases the cost of adding a 0N/A * mark, and decreases the cost of keeping the mark updated. 0N/A * @author Timothy Prinzing 0N/A * Creates a new GapContent object. Initial size defaults to 10. 0N/A * Creates a new GapContent object, with the initial 0N/A * size specified. The initial size will not be allowed 0N/A * to go below 2, to give room for the implied break and 0N/A * @param initialLength the initial size 0N/A * Allocate an array to store items of the type 0N/A * appropriate (which is determined by the subclass). 0N/A * Get the length of the allocated array. 0N/A // --- AbstractDocument.Content methods ------------------------- 0N/A * Returns the length of the content. 0N/A * @return the length >= 1 0N/A * @see AbstractDocument.Content#length 0N/A * Inserts a string into the content. 0N/A * @param where the starting position >= 0, < length() 0N/A * @param str the non-null string to insert 0N/A * @return an UndoableEdit object for undoing 0N/A * @exception BadLocationException if the specified position is invalid 0N/A * @see AbstractDocument.Content#insertString 0N/A * Removes part of the content. 0N/A * @param where the starting position >= 0, where + nitems < length() 0N/A * @param nitems the number of characters to remove >= 0 0N/A * @return an UndoableEdit object for undoing 0N/A * @exception BadLocationException if the specified position is invalid 0N/A * @see AbstractDocument.Content#remove 0N/A * Retrieves a portion of the content. 0N/A * @param where the starting position >= 0 0N/A * @param len the length to retrieve >= 0 0N/A * @return a string representing the content 0N/A * @exception BadLocationException if the specified position is invalid 0N/A * @see AbstractDocument.Content#getString 0N/A * Retrieves a portion of the content. If the desired content spans 0N/A * the gap, we copy the content. If the desired content does not 0N/A * span the gap, the actual store is returned to avoid the copy since 0N/A * @param where the starting position >= 0, where + len <= length() 0N/A * @param len the number of characters to retrieve >= 0 0N/A * @param chars the Segment object to return the characters in 0N/A * @exception BadLocationException if the specified position is invalid 0N/A * @see AbstractDocument.Content#getChars 0N/A // partial return allowed, return amount before the gap 0N/A // partial return not allowed, must copy 0N/A * Creates a position within the content that will 0N/A * track change as the content is mutated. 0N/A * @param offset the offset to track >= 0 0N/A * @return the position 0N/A * @exception BadLocationException if the specified position is invalid 0N/A //position references the correct StickyPostition 0N/A * Holds the data for a mark... separately from 0N/A * the real mark so that the real mark (Position 0N/A * that the caller of createPosition holds) can be 0N/A * collected if there are no more references to 0N/A * it. The update table holds only a reference 0N/A * Fetch the location in the contiguous sequence 0N/A * being modeled. The index in the gap array 0N/A * is held by the mark, so it is adjusted according 0N/A * to it's relationship to the gap. 0N/A // --- variables -------------------------------------- 0N/A private static final char[]
empty =
new char[
0];
0N/A * Record used for searching for the place to 0N/A * start updating mark indexs when the gap 0N/A * boundaries are moved. 0N/A * The number of unused mark entries 0N/A // --- gap management ------------------------------- 0N/A * Make the gap bigger, moving any necessary data and updating 0N/A * the appropriate marks 0N/A * Overridden to make growth policy less agressive for large 0N/A * Move the start of the gap to a new location, 0N/A * without changing the size of the gap. This 0N/A * moves the data in the array and updates the 0N/A * marks accordingly. 0N/A // shift gap in the character array 0N/A // Move gap up, move data and marks down. 0N/A // Move gap down, move data and marks up. 0N/A * Resets all the marks that have an offset of 0 to have an index of 0N/A * Adjust the gap end downward. This doesn't move 0N/A * any data, but it does update any marks affected 0N/A * by the boundary change. All marks from the old 0N/A * gap start down to the new gap start are squeezed 0N/A * to the end of the gap (their location has been 0N/A // Push aside all marks from oldGapStart down to newGapStart. 0N/A // no more marks to adjust 0N/A // shift the gap in the character array 0N/A * Adjust the gap end upward. This doesn't move 0N/A * any data, but it does update any marks affected 0N/A * by the boundary change. All marks from the old 0N/A * gap end up to the new gap end are squeezed 0N/A * to the end of the gap (their location has been 0N/A // shift the gap in the character array 0N/A * Compares two marks. 0N/A * @param o1 the first object 0N/A * @param o2 the second object 0N/A * @return < 0 if o1 < o2, 0 if the same, > 0 if o1 > o2 0N/A * Finds the index to start mark adjustments given 0N/A * some search index. 0N/A // return the first in the series 0N/A // (ie. there may be duplicates). 0N/A * Finds the index of where to insert a new mark. 0N/A * @param o the mark to insert 0N/A // didn't find it, but we indicate the index of where it would belong. 0N/A * Remove all unused marks out of the sorted collection 0N/A for (
int i =
0; i < n; i++) {
0N/A * Allocate an array to store items of the type 0N/A * appropriate (which is determined by the subclass). 0N/A * Get the length of the allocated array 0N/A * Returns the number of marks currently held 0N/A * Inserts a mark into the vector 0N/A * Add a mark to the end 0N/A * Fetches the mark at the given index 0N/A * Replaces the elements in the specified range with the passed 0N/A * in objects. This will NOT adjust the gap. The passed in indices 0N/A * do not account for the gap, they are the same as would be used 0N/A * int <code>elementAt</code>. 0N/A // Completely passed gap 0N/A // --- serialization ------------------------------------- 0N/A // --- undo support -------------------------------------- 0N/A * Returns a Vector containing instances of UndoPosRef for the 0N/A * Positions in the range 0N/A * <code>offset</code> to <code>offset</code> + <code>length</code>. 0N/A * If <code>v</code> is not null the matching Positions are placed in 0N/A * there. The vector with the resulting Positions are returned. 0N/A * @param v the Vector to use, with a new one created on null 0N/A * @param offset the starting offset >= 0 0N/A * @param length the length >= 0 0N/A * @return the set of instances 0N/A // Find the index of the marks. 0N/A // findMarkAdjustIndex start at 1! 0N/A * Resets the location for all the UndoPosRef instances 0N/A * in <code>positions</code>. 0N/A * This is meant for internal usage, and is generally not of interest 0N/A * @param positions the UndoPosRef instances to reset 0N/A // Find the indexs of the end points. 0N/A // Reset the location of the refenences. 0N/A // We have to resort the marks in the range startIndex to endIndex. 0N/A // We can take advantage of the fact that it will be in 0N/A // increasing order, accept there will be a bunch of MarkData's with 0N/A // the index g1 (or 0 if offset == 0) interspersed throughout. 0N/A // If the offset is 0, the positions won't have incremented, 0N/A // have to do the reverse thing. 0N/A // Find the elements in startIndex whose index is 0 0N/A * Used to hold a reference to a Mark that is being reset as the 0N/A * result of removing from the content. 0N/A * Resets the location of the Position to the offset when the 0N/A * receiver was instantiated. 0N/A * @param endOffset end location of inserted string. 0N/A * @param g1 resulting end of gap. 0N/A /** Previous Offset of rec. */ 0N/A /** Mark to reset offset. */ 0N/A }
// End of GapContent.UndoPosRef 0N/A * UnoableEdit created for inserts. 0N/A // Get the Positions in the range being removed. 0N/A // Update the Positions that were in the range removed. 0N/A /** Where string was inserted. */ 0N/A /** Length of string inserted. */ 0N/A /** The string that was inserted. This will only be valid after an 0N/A /** An array of instances of UndoPosRef for the Positions in the 0N/A * range that was removed, valid after undo. */ 0N/A }
// GapContent.InsertUndo 0N/A * UndoableEdit created for removes. 0N/A // Update the Positions that were in the range removed. 0N/A // Get the Positions in the range being removed. 0N/A /** Where the string was removed from. */ 0N/A /** Length of string removed. */ 0N/A /** The string that was removed. This is valid when redo is valid. */ 0N/A /** An array of instances of UndoPosRef for the Positions in the 0N/A * range that was removed, valid before undo. */ 0N/A }
// GapContent.RemoveUndo