コード例 #1
0
 /**
  * Prints out this text to the specified writer.
  *
  * @param writer the destination writer.
  */
 public void print(Writer writer) throws IOException {
   if (_data != null) { // Primitive
     writer.write(_data, 0, _count);
   } else { // Composite.
     _head.print(writer);
     _tail.print(writer);
   }
 }
コード例 #2
0
 /**
  * Compares this text against the specified object for equality. Returns <code>true</code> if the
  * specified object is a text having the same character sequence as this text. For generic
  * comparison with any character sequence the {@link #contentEquals(CharSequence)} should be used.
  *
  * @param obj the object to compare with or <code>null</code>.
  * @return <code>true</code> if that is a text with the same character sequence as this text;
  *     <code>false</code> otherwise.
  */
 public boolean equals(Object obj) {
   if (this == obj) return true;
   if (!(obj instanceof ImmutableText)) return false;
   final ImmutableText that = (ImmutableText) obj;
   if (this._count != that._count) return false;
   for (int i = 0; i < _count; ) {
     if (this.charAt(i) != that.charAt(i++)) return false;
   }
   return true;
 }
コード例 #3
0
 /**
  * Returns the index within this text of the first occurrence of the specified character,
  * searching backward and starting at the specified index.
  *
  * @param c the character to search for.
  * @param fromIndex the index to start the search backward from.
  * @return the index of the first occurrence of the character in this text that is less than or
  *     equal to <code>fromIndex</code>, or <code>-1</code> if the character does not occur.
  */
 public int lastIndexOf(char c, int fromIndex) {
   if (_data != null) { // Primitive.
     for (int i = Math.min(fromIndex, _count - 1); i >= 0; i--) {
       if (_data[i] == c) return i;
     }
     return -1;
   } else { // Composite.
     final int cesure = _head._count;
     if (fromIndex >= cesure) {
       final int tailIndex = _tail.lastIndexOf(c, fromIndex - cesure);
       if (tailIndex >= 0) return tailIndex + cesure; // Found in tail.
     }
     return _head.lastIndexOf(c, fromIndex);
   }
 }
コード例 #4
0
 /**
  * Copies the characters from this text into the destination character array.
  *
  * @param start the index of the first character to copy.
  * @param end the index after the last character to copy.
  * @param dest the destination array.
  * @param destPos the start offset in the destination array.
  * @throws IndexOutOfBoundsException if <code>(start < 0) || (end < 0) ||
  *         (start > end) || (end > this.length())</code>
  */
 public void getChars(int start, int end, @NotNull char[] dest, int destPos) {
   if (_data != null) { // Primitive.
     if ((start < 0) || (end > _count) || (start > end)) throw new IndexOutOfBoundsException();
     System.arraycopy(_data, start, dest, destPos, end - start);
   } else { // Composite.
     final int cesure = _head._count;
     if (end <= cesure) {
       _head.getChars(start, end, dest, destPos);
     } else if (start >= cesure) {
       _tail.getChars(start - cesure, end - cesure, dest, destPos);
     } else { // Overlaps head and tail.
       _head.getChars(start, cesure, dest, destPos);
       _tail.getChars(0, end - cesure, dest, destPos + cesure - start);
     }
   }
 }
コード例 #5
0
 /**
  * Returns the index within this text of the first occurrence of the specified character, starting
  * the search at the specified index.
  *
  * @param c the character to search for.
  * @param fromIndex the index to start the search from.
  * @return the index of the first occurrence of the character in this text that is greater than or
  *     equal to <code>fromIndex</code>, or <code>-1</code> if the character does not occur.
  */
 public int indexOf(char c, int fromIndex) {
   if (_data != null) { // Primitive.
     for (int i = Math.max(fromIndex, 0); i < _count; i++) {
       if (_data[i] == c) return i;
     }
     return -1;
   } else { // Composite.
     final int cesure = _head._count;
     if (fromIndex < cesure) {
       final int headIndex = _head.indexOf(c, fromIndex);
       if (headIndex >= 0) return headIndex; // Found in head.
     }
     final int tailIndex = _tail.indexOf(c, fromIndex - cesure);
     return (tailIndex >= 0) ? tailIndex + cesure : -1;
   }
 }
コード例 #6
0
 /**
  * Returns a portion of this text.
  *
  * @param start the index of the first character inclusive.
  * @param end the index of the last character exclusive.
  * @return the sub-text starting at the specified start position and ending just before the
  *     specified end position.
  * @throws IndexOutOfBoundsException if <code>(start < 0) || (end < 0) ||
  *         (start > end) || (end > this.length())</code>
  */
 public ImmutableText subtext(int start, int end) {
   if (_data != null) { // Primitive.
     if ((start < 0) || (start > end) || (end > _count)) throw new IndexOutOfBoundsException();
     if ((start == 0) && (end == _count)) return this;
     if (start == end) return EMPTY;
     int length = end - start;
     char[] chars = new char[length];
     System.arraycopy(_data, start, chars, 0, length);
     return new ImmutableText(chars);
   } else { // Composite.
     final int cesure = _head._count;
     if (end <= cesure) return _head.subtext(start, end);
     if (start >= cesure) return _tail.subtext(start - cesure, end - cesure);
     if ((start == 0) && (end == _count)) return this;
     // Overlaps head and tail.
     return _head.subtext(start, cesure).concat(_tail.subtext(0, end - cesure));
   }
 }
コード例 #7
0
 private ImmutableText append(String str) { // Try to append, returns null if cannot.
   int length = str.length();
   if (_data == null) {
     ImmutableText merge = _tail.append(str);
     return merge != null ? new ImmutableText(_head, merge) : null;
   } else { // Primitive.
     if (_count + length > BLOCK_SIZE) return null; // Cannot merge.
     char[] chars = new char[_count + length];
     System.arraycopy(_data, 0, chars, 0, _count);
     str.getChars(0, length, chars, _count);
     return new ImmutableText(chars);
   }
 }
コード例 #8
0
  /**
   * Concatenates the specified text to the end of this text. This method is very fast (faster even
   * than <code>StringBuffer.append(String)</code>) and still returns a text instance with an
   * internal binary tree of minimal depth!
   *
   * @param that the text that is concatenated.
   * @return <code>this + that</code>
   */
  public ImmutableText concat(ImmutableText that) {
    if (that.length() == 0) {
      return this;
    }

    // All Text instances are maintained balanced:
    //   (head < tail * 2) & (tail < head * 2)

    final int length = this._count + that._count;
    if (length <= BLOCK_SIZE) { // Merges to primitive.
      char[] chars = new char[length];
      this.getChars(0, this._count, chars, 0);
      that.getChars(0, that._count, chars, this._count);
      return new ImmutableText(chars);
    } else { // Returns a composite.
      ImmutableText head = this;
      ImmutableText tail = that;

      if (((head._count << 1) < tail._count) && (tail._data == null)) { // tail is composite
        // head too small, returns (head + tail/2) + (tail/2)
        if (tail._head._count > tail._tail._count) {
          // Rotates to concatenate with smaller part.
          tail = tail.rightRotation();
        }
        head = head.concat(tail._head);
        tail = tail._tail;

      } else if (((tail._count << 1) < head._count) && (head._data == null)) { // head is composite.
        // tail too small, returns (head/2) + (head/2 concat tail)
        if (head._tail._count > head._head._count) {
          // Rotates to concatenate with smaller part.
          head = head.leftRotation();
        }
        tail = head._tail.concat(tail);
        head = head._head;
      }
      return new ImmutableText(head, tail);
    }
  }
コード例 #9
0
 private int getNbrOfLeaves() {
   return (_data == null) ? _head.getNbrOfLeaves() + _tail.getNbrOfLeaves() : 1;
 }
コード例 #10
0
 private int getNbrOfBranches() {
   return (_data == null) ? _head.getNbrOfBranches() + _tail.getNbrOfBranches() + 1 : 0;
 }
コード例 #11
0
 private int getDepth() {
   if (_data != null) // Primitive.
   return 0;
   return Math.max(_head.getDepth(), _tail.getDepth()) + 1;
 }