| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.ignite.internal.util.tostring; |
| |
| import java.util.Arrays; |
| |
| /** |
| * Basic string builder over circular buffer. |
| */ |
| public class CircularStringBuilder { |
| |
| /** Value */ |
| private final char value[]; |
| |
| /** Last written character idx (-1 if empty). */ |
| private int finishAt = -1; |
| |
| /** Value is full flag. */ |
| private boolean full; |
| |
| /** Number of skipped characters */ |
| private int skipped = 0; |
| |
| /** |
| * Creates an CircularStringBuilder of the specified capacity. |
| * |
| * @param capacity Capacity. |
| */ |
| CircularStringBuilder (int capacity) { |
| assert capacity > 0 : "Can't allocate CircularStringBuilder with capacity: " + capacity; |
| |
| value = new char[capacity]; |
| } |
| |
| /** |
| * Reset internal builder state |
| */ |
| public void reset() { |
| Arrays.fill(value,(char)0); |
| finishAt = -1; |
| full = false; |
| skipped = 0; |
| } |
| |
| /** |
| * Returns the length (character count). |
| * |
| * @return the length of the sequence of characters currently |
| * represented by this object |
| */ |
| public int length() { return full ? value.length : finishAt + 1; } |
| |
| /** |
| * Returns the current capacity. |
| * |
| * @return the current capacity |
| */ |
| public int capacity() { |
| return value.length; |
| } |
| |
| /** |
| * Appends the string representation of the {@code Object} argument. |
| * |
| * @param obj an {@code Object}. |
| * @return a reference to this object. |
| */ |
| public CircularStringBuilder append(Object obj) { |
| return append(String.valueOf(obj)); |
| } |
| |
| /** |
| * Appends the specified string to this character sequence. |
| * |
| * @param str a string. |
| * @return a reference to this object. |
| */ |
| public CircularStringBuilder append(String str) { |
| if (str == null) |
| return appendNull(); |
| |
| int objStrLen = str.length(); |
| |
| if (objStrLen >= value.length) { |
| // String bigger or equal to value length |
| str.getChars(objStrLen - value.length, objStrLen, value, 0); |
| |
| skipped += objStrLen - value.length + finishAt + 1; |
| |
| finishAt = value.length - 1; |
| |
| full = true; |
| } |
| else { |
| // String smaller then value length |
| if (value.length - finishAt - 1 < objStrLen) { |
| // String doesn't fit into remaining part of value array |
| int firstPart = value.length - finishAt - 1; |
| |
| if (firstPart > 0) |
| str.getChars(0, firstPart, value, finishAt + 1); |
| |
| str.getChars(firstPart, objStrLen, value, 0); |
| |
| skipped += full ? objStrLen : objStrLen - firstPart; |
| |
| finishAt = finishAt + objStrLen - value.length; |
| |
| full = true; |
| } |
| else { |
| // Whole string fin into remaining part of value array |
| str.getChars(0, objStrLen, value, finishAt + 1); |
| |
| skipped += full ? objStrLen : 0; |
| |
| finishAt += objStrLen; |
| } |
| } |
| |
| return this; |
| } |
| |
| /** |
| * Append StringBuffer |
| * |
| * @param sb StringBuffer to append. |
| * @return Reference to this object. |
| */ |
| public CircularStringBuilder append(StringBuffer sb) { |
| if (sb == null) |
| return appendNull(); |
| |
| int len = sb.length(); |
| |
| if (len < value.length) |
| append(sb.toString()); |
| else { |
| skipped += len - value.length; |
| |
| append(sb.substring(len - value.length)); |
| } |
| |
| return this; |
| } |
| |
| /** |
| * @return This builder. |
| */ |
| private CircularStringBuilder appendNull() { |
| append("null"); |
| |
| return this; |
| } |
| |
| /** |
| * @return Count of skipped elements. |
| */ |
| public int getSkipped() { return skipped; } |
| |
| /** {@inheritDoc} */ |
| @Override public String toString() { |
| // Create a copy, don't share the array |
| if (full) { |
| char strValue[] = new char[value.length]; |
| int firstPart = value.length - finishAt - 1; |
| |
| System.arraycopy(value, finishAt + 1, strValue, 0, firstPart); |
| System.arraycopy(value, 0, strValue, firstPart, value.length - firstPart); |
| |
| return new String(strValue, 0, strValue.length); |
| } |
| else |
| return new String(value, 0, finishAt + 1); |
| } |
| } |