faststringbuffer.java
来自「java jdk 1.4的源码」· Java 代码 · 共 1,377 行 · 第 1/4 页
JAVA
1,377 行
m_array = new char[16][0]; m_array[0] = new char[m_chunkSize]; } /** * Directly set how much of the FastStringBuffer's storage is to be * considered part of its content. This is a fast but hazardous * operation. It is not protected against negative values, or values * greater than the amount of storage currently available... and even * if additional storage does exist, its contents are unpredictable. * The only safe use for our setLength() is to truncate the FastStringBuffer * to a shorter string. * * @param l New length. If l<0 or l>=getLength(), this operation will * not report an error but future operations will almost certainly fail. */ public final void setLength(int l) { m_lastChunk = l >>> m_chunkBits; if (m_lastChunk == 0 && m_innerFSB != null) { // Replace this FSB with the appropriate inner FSB, truncated m_innerFSB.setLength(l, this); } else { m_firstFree = l & m_chunkMask; // There's an edge case if l is an exact multiple of m_chunkBits, which risks leaving // us pointing at the start of a chunk which has not yet been allocated. Rather than // pay the cost of dealing with that in the append loops (more scattered and more // inner-loop), we correct it here by moving to the safe side of that // line -- as we would have left the indexes had we appended up to that point. if(m_firstFree==0 && m_lastChunk>0) { --m_lastChunk; m_firstFree=m_chunkSize; } } } /** * Subroutine for the public setLength() method. Deals with the fact * that truncation may require restoring one of the innerFSBs * * NEEDSDOC @param l * NEEDSDOC @param rootFSB */ private final void setLength(int l, FastStringBuffer rootFSB) { m_lastChunk = l >>> m_chunkBits; if (m_lastChunk == 0 && m_innerFSB != null) { m_innerFSB.setLength(l, rootFSB); } else { // Undo encapsulation -- pop the innerFSB data back up to root. // Inefficient, but attempts to keep the code simple. rootFSB.m_chunkBits = m_chunkBits; rootFSB.m_maxChunkBits = m_maxChunkBits; rootFSB.m_rebundleBits = m_rebundleBits; rootFSB.m_chunkSize = m_chunkSize; rootFSB.m_chunkMask = m_chunkMask; rootFSB.m_array = m_array; rootFSB.m_innerFSB = m_innerFSB; rootFSB.m_lastChunk = m_lastChunk; // Finally, truncate this sucker. rootFSB.m_firstFree = l & m_chunkMask; } } /** * Note that this operation has been somewhat deoptimized by the shift to a * chunked array, as there is no factory method to produce a String object * directly from an array of arrays and hence a double copy is needed. * By using ensureCapacity we hope to minimize the heap overhead of building * the intermediate StringBuffer. * <p> * (It really is a pity that Java didn't design String as a final subclass * of MutableString, rather than having StringBuffer be a separate hierarchy. * We'd avoid a <strong>lot</strong> of double-buffering.) * * @return the contents of the FastStringBuffer as a standard Java string. */ public final String toString() { int length = (m_lastChunk << m_chunkBits) + m_firstFree; return getString(new StringBuffer(length), 0, 0, length).toString(); } /** * Append a single character onto the FastStringBuffer, growing the * storage if necessary. * <p> * NOTE THAT after calling append(), previously obtained * references to m_array[][] may no longer be valid.... * though in fact they should be in this instance. * * @param value character to be appended. */ public final void append(char value) { char[] chunk; // We may have preallocated chunks. If so, all but last should // be at full size. boolean lastchunk = (m_lastChunk + 1 == m_array.length); if (m_firstFree < m_chunkSize) // Simplified test single-character-fits chunk = m_array[m_lastChunk]; else { // Extend array? int i = m_array.length; if (m_lastChunk + 1 == i) { char[][] newarray = new char[i + 16][]; System.arraycopy(m_array, 0, newarray, 0, i); m_array = newarray; } // Advance one chunk chunk = m_array[++m_lastChunk]; if (chunk == null) { // Hierarchical encapsulation if (m_lastChunk == 1 << m_rebundleBits && m_chunkBits < m_maxChunkBits) { // Should do all the work of both encapsulating // existing data and establishing new sizes/offsets m_innerFSB = new FastStringBuffer(this); } // Add a chunk. chunk = m_array[m_lastChunk] = new char[m_chunkSize]; } m_firstFree = 0; } // Space exists in the chunk. Append the character. chunk[m_firstFree++] = value; } /** * Append the contents of a String onto the FastStringBuffer, * growing the storage if necessary. * <p> * NOTE THAT after calling append(), previously obtained * references to m_array[] may no longer be valid. * * @param value String whose contents are to be appended. */ public final void append(String value) { if (value == null) return; int strlen = value.length(); if (0 == strlen) return; int copyfrom = 0; char[] chunk = m_array[m_lastChunk]; int available = m_chunkSize - m_firstFree; // Repeat while data remains to be copied while (strlen > 0) { // Copy what fits if (available > strlen) available = strlen; value.getChars(copyfrom, copyfrom + available, m_array[m_lastChunk], m_firstFree); strlen -= available; copyfrom += available; // If there's more left, allocate another chunk and continue if (strlen > 0) { // Extend array? int i = m_array.length; if (m_lastChunk + 1 == i) { char[][] newarray = new char[i + 16][]; System.arraycopy(m_array, 0, newarray, 0, i); m_array = newarray; } // Advance one chunk chunk = m_array[++m_lastChunk]; if (chunk == null) { // Hierarchical encapsulation if (m_lastChunk == 1 << m_rebundleBits && m_chunkBits < m_maxChunkBits) { // Should do all the work of both encapsulating // existing data and establishing new sizes/offsets m_innerFSB = new FastStringBuffer(this); } // Add a chunk. chunk = m_array[m_lastChunk] = new char[m_chunkSize]; } available = m_chunkSize; m_firstFree = 0; } } // Adjust the insert point in the last chunk, when we've reached it. m_firstFree += available; } /** * Append the contents of a StringBuffer onto the FastStringBuffer, * growing the storage if necessary. * <p> * NOTE THAT after calling append(), previously obtained * references to m_array[] may no longer be valid. * * @param value StringBuffer whose contents are to be appended. */ public final void append(StringBuffer value) { if (value == null) return; int strlen = value.length(); if (0 == strlen) return; int copyfrom = 0; char[] chunk = m_array[m_lastChunk]; int available = m_chunkSize - m_firstFree; // Repeat while data remains to be copied while (strlen > 0) { // Copy what fits if (available > strlen) available = strlen; value.getChars(copyfrom, copyfrom + available, m_array[m_lastChunk], m_firstFree); strlen -= available; copyfrom += available; // If there's more left, allocate another chunk and continue if (strlen > 0) { // Extend array? int i = m_array.length; if (m_lastChunk + 1 == i) { char[][] newarray = new char[i + 16][]; System.arraycopy(m_array, 0, newarray, 0, i); m_array = newarray; } // Advance one chunk chunk = m_array[++m_lastChunk]; if (chunk == null) { // Hierarchical encapsulation if (m_lastChunk == 1 << m_rebundleBits && m_chunkBits < m_maxChunkBits) { // Should do all the work of both encapsulating // existing data and establishing new sizes/offsets m_innerFSB = new FastStringBuffer(this); } // Add a chunk. chunk = m_array[m_lastChunk] = new char[m_chunkSize]; } available = m_chunkSize; m_firstFree = 0; } } // Adjust the insert point in the last chunk, when we've reached it. m_firstFree += available; } /** * Append part of the contents of a Character Array onto the * FastStringBuffer, growing the storage if necessary. * <p> * NOTE THAT after calling append(), previously obtained * references to m_array[] may no longer be valid. * * @param chars character array from which data is to be copied * @param start offset in chars of first character to be copied, * zero-based. * @param length number of characters to be copied */ public final void append(char[] chars, int start, int length) { int strlen = length; if (0 == strlen) return;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?