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 + -
显示快捷键?