gapcontent.java
来自「linux下建立JAVA虚拟机的源码KAFFE」· Java 代码 · 共 889 行 · 第 1/2 页
JAVA
889 行
throw new BadLocationException("len plus where cannot be greater" + " than the content length", len + where); // check if requested segment is contiguous if ((where < gapStart) && ((gapStart - where) < len)) { // requested segment is not contiguous -> copy the pieces together char[] copy = new char[len]; int lenFirst = gapStart - where; // the length of the first segment System.arraycopy(buffer, where, copy, 0, lenFirst); System.arraycopy(buffer, gapEnd, copy, lenFirst, len - lenFirst); txt.array = copy; txt.offset = 0; txt.count = len; } else { // requested segment is contiguous -> we can simply return the // actual content txt.array = buffer; if (where < gapStart) txt.offset = where; else txt.offset = where + (gapEnd - gapStart); txt.count = len; } } /** * Creates and returns a mark at the specified position. * * @param offset the position at which to create the mark * * @return the create Position object for the mark * * @throws BadLocationException if the offset is not a valid position in the * buffer */ public Position createPosition(final int offset) throws BadLocationException { if (offset < 0 || offset > length()) throw new BadLocationException("The offset was out of the bounds of this" + " buffer", offset); clearPositionReferences(); // We store the actual array index in the GapContentPosition. The real // offset is then calculated in the GapContentPosition. int mark = offset; if (offset >= gapStart) mark += gapEnd - gapStart; GapContentPosition pos = new GapContentPosition(mark); WeakReference r = new WeakReference(pos); // Add this into our list in a sorted fashion. int index = Collections.binarySearch(positions, r, new WeakPositionComparator()); if (index < 0) index = -(index + 1); positions.add(index, r); return pos; } /** * Enlarges the gap. This allocates a new bigger buffer array, copy the * segment before the gap as it is and the segment after the gap at the end * of the new buffer array. This does change the gapEnd mark but not the * gapStart mark. * * @param newSize the new size of the gap */ protected void shiftEnd(int newSize) { assert newSize > (gapEnd - gapStart) : "The new gap size must be greater " + "than the old gap size"; int delta = newSize - gapEnd + gapStart; // Update the marks after the gapEnd. adjustPositionsInRange(gapEnd, buffer.length - gapEnd, delta); // Copy the data around. char[] newBuf = (char[]) allocateArray(length() + newSize); System.arraycopy(buffer, 0, newBuf, 0, gapStart); System.arraycopy(buffer, gapEnd, newBuf, gapStart + newSize, buffer.length - gapEnd); gapEnd = gapStart + newSize; buffer = newBuf; } /** * Shifts the gap to the specified position. * * @param newGapStart the new start position of the gap */ protected void shiftGap(int newGapStart) { if (newGapStart == gapStart) return; int newGapEnd = newGapStart + gapEnd - gapStart; if (newGapStart < gapStart) { // Update the positions between newGapStart and (old) gapStart. The marks // must be shifted by (gapEnd - gapStart). adjustPositionsInRange(newGapStart, gapStart - newGapStart, gapEnd - gapStart); System.arraycopy(buffer, newGapStart, buffer, newGapEnd, gapStart - newGapStart); gapStart = newGapStart; gapEnd = newGapEnd; } else { // Update the positions between newGapEnd and (old) gapEnd. The marks // must be shifted by (gapEnd - gapStart). adjustPositionsInRange(gapEnd, newGapEnd - gapEnd, -(gapEnd - gapStart)); System.arraycopy(buffer, gapEnd, buffer, gapStart, newGapStart - gapStart); gapStart = newGapStart; gapEnd = newGapEnd; } if (gapStart == 0) resetMarksAtZero(); } /** * Shifts the gap start downwards. This does not affect the content of the * buffer. This only updates the gap start and all the marks that are between * the old gap start and the new gap start. They all are squeezed to the start * of the gap, because their location has been removed. * * @param newGapStart the new gap start */ protected void shiftGapStartDown(int newGapStart) { if (newGapStart == gapStart) return; assert newGapStart < gapStart : "The new gap start must be less than the " + "old gap start."; setPositionsInRange(newGapStart, gapStart - newGapStart, gapStart); gapStart = newGapStart; } /** * Shifts the gap end upwards. This does not affect the content of the * buffer. This only updates the gap end and all the marks that are between * the old gap end and the new end start. They all are squeezed to the end * of the gap, because their location has been removed. * * @param newGapEnd the new gap start */ protected void shiftGapEndUp(int newGapEnd) { if (newGapEnd == gapEnd) return; assert newGapEnd > gapEnd : "The new gap end must be greater than the " + "old gap end."; setPositionsInRange(gapEnd, newGapEnd - gapEnd, newGapEnd); gapEnd = newGapEnd; } /** * Returns the allocated buffer array. * * @return the allocated buffer array */ protected final Object getArray() { return buffer; } /** * Replaces a portion of the storage with the specified items. * * @param position the position at which to remove items * @param rmSize the number of items to remove * @param addItems the items to add at location * @param addSize the number of items to add */ protected void replace(int position, int rmSize, Object addItems, int addSize) { if (gapStart != position) shiftGap(position); // Remove content if (rmSize > 0) shiftGapEndUp(gapEnd + rmSize); // If gap is too small, enlarge the gap. if ((gapEnd - gapStart) <= addSize) shiftEnd((addSize - gapEnd + gapStart + 1) * 2 + gapEnd + DEFAULT_BUFSIZE); // Add new items to the buffer. if (addItems != null) { System.arraycopy(addItems, 0, buffer, gapStart, addSize); gapStart += addSize; } } /** * Returns the start index of the gap within the buffer array. * * @return the start index of the gap within the buffer array */ protected final int getGapStart() { return gapStart; } /** * Returns the end index of the gap within the buffer array. * * @return the end index of the gap within the buffer array */ protected final int getGapEnd() { return gapEnd; } /** * Returns all <code>Position</code>s that are in the range specified by * <code>offset</code> and </code>length</code> within the buffer array. * * @param v the vector to use; if <code>null</code>, a new Vector is allocated * @param offset the start offset of the range to search * @param length the length of the range to search * * @return the positions within the specified range */ protected Vector getPositionsInRange(Vector v, int offset, int length) { Vector res = v; if (res == null) res = new Vector(); else res.clear(); int endOffset = offset + length; int index1 = Collections.binarySearch(positions, new GapContentPosition(offset), new WeakPositionComparator()); if (index1 < 0) index1 = -(index1 + 1); // Search the first index with the specified offset. The binarySearch does // not necessarily find the first one. while (index1 > 0) { WeakReference r = (WeakReference) positions.get(index1 - 1); GapContentPosition p = (GapContentPosition) r.get(); if (p != null && p.mark == offset || p == null) index1--; else break; } for (ListIterator i = positions.listIterator(index1); i.hasNext();) { WeakReference r = (WeakReference) i.next(); GapContentPosition p = (GapContentPosition) r.get(); if (p == null) continue; if (p.mark > endOffset) break; if (p.mark >= offset && p.mark <= endOffset) res.add(p); } return res; } /** * Sets the mark of all <code>Position</code>s that are in the range * specified by <code>offset</code> and </code>length</code> within * the buffer array to <code>value</code> * * @param offset the start offset of the range to search * @param length the length of the range to search * @param value the new value for each mark */ private void setPositionsInRange(int offset, int length, int value) { int endOffset = offset + length; int index1 = Collections.binarySearch(positions, new GapContentPosition(offset), new WeakPositionComparator()); if (index1 < 0) index1 = -(index1 + 1); // Search the first index with the specified offset. The binarySearch does // not necessarily find the first one. while (index1 > 0) { WeakReference r = (WeakReference) positions.get(index1 - 1); GapContentPosition p = (GapContentPosition) r.get(); if (p != null && p.mark == offset || p == null) index1--; else break; } for (ListIterator i = positions.listIterator(index1); i.hasNext();) { WeakReference r = (WeakReference) i.next(); GapContentPosition p = (GapContentPosition) r.get(); if (p == null) continue; if (p.mark > endOffset) break; if (p.mark >= offset && p.mark <= endOffset) p.mark = value; } } /** * Adjusts the mark of all <code>Position</code>s that are in the range * specified by <code>offset</code> and </code>length</code> within * the buffer array by <code>increment</code> * * @param offset the start offset of the range to search * @param length the length of the range to search * @param incr the increment */ private void adjustPositionsInRange(int offset, int length, int incr) { int endOffset = offset + length; int index1 = Collections.binarySearch(positions, new GapContentPosition(offset), new WeakPositionComparator()); if (index1 < 0) index1 = -(index1 + 1); // Search the first index with the specified offset. The binarySearch does // not necessarily find the first one. while (index1 > 0) { WeakReference r = (WeakReference) positions.get(index1 - 1); GapContentPosition p = (GapContentPosition) r.get(); if (p != null && p.mark == offset || p == null) index1--; else break; } for (ListIterator i = positions.listIterator(index1); i.hasNext();) { WeakReference r = (WeakReference) i.next(); GapContentPosition p = (GapContentPosition) r.get(); if (p == null) continue; if (p.mark > endOffset) break; if (p.mark >= offset && p.mark <= endOffset) p.mark += incr; } } /** * Resets all <code>Position</code> that have an offset of <code>0</code>, * to also have an array index of <code>0</code>. This might be necessary * after a call to <code>shiftGap(0)</code>, since then the marks at offset * <code>0</code> get shifted to <code>gapEnd</code>. */ protected void resetMarksAtZero() { if (gapStart != 0) return; setPositionsInRange(gapEnd, 0, 0); } /** * @specnote This method is not very well specified and the positions vector * is implementation specific. The undo positions are managed * differently in this implementation, this method is only here * for binary compatibility. */ protected void updateUndoPositions(Vector positions, int offset, int length) { // We do nothing here. } /** * Outputs debugging info to System.err. It prints out the buffer array, * the gapStart is marked by a < sign, the gapEnd is marked by a > * sign and each position is marked by a # sign. */ private void dump() { System.err.println("GapContent debug information"); System.err.println("buffer length: " + buffer.length); System.err.println("gap start: " + gapStart); System.err.println("gap end: " + gapEnd); for (int i = 0; i < buffer.length; i++) { if (i == gapStart) System.err.print('<'); if (i == gapEnd) System.err.print('>'); if (!Character.isISOControl(buffer[i])) System.err.print(buffer[i]); else System.err.print('.'); } System.err.println(); } private void dumpPositions() { for (Iterator i = positions.iterator(); i.hasNext();) { WeakReference r = (WeakReference) i.next(); GapContentPosition pos = (GapContentPosition) r.get(); System.err.println("position at: " + pos.mark); } } /** * Clears all GC'ed references in the positions array. */ private void clearPositionReferences() { Iterator i = positions.iterator(); while (i.hasNext()) { WeakReference r = (WeakReference) i.next(); if (r.get() == null) i.remove(); } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?