/* * ParseBuffer.java February 2001 * * Copyright (C) 2001, Niall Gallagher <niallg@users.sf.net> * * Licensed 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.simpleframework.util.parse; /** * This is primarily used to replace the <code>StringBuffer</code> class, as a * way for the <code>Parser</code> to store the char's for a specific region * within the parse data that constitutes a desired value. The methods are not * synchronized so it enables the <code>char</code>'s to be taken quicker than * the <code>StringBuffer</code> class. * * @author Niall Gallagher */ public class ParseBuffer { /** * This is used to quicken <code>toString</code>. */ protected String cache; /** * The <code>char</code>'s this buffer accumulated. */ protected char[] buf; /** * This is the number of <code>char</code>'s stored. */ protected int count; /** * Constructor for <code>ParseBuffer</code>. The default * <code>ParseBuffer</code> stores 16 <code>char</code>'s before a * <code>resize</code> is needed to accommodate extra characters. */ public ParseBuffer() { this(16); } /** * This creates a <code>ParseBuffer</code> with a specific default size. The * buffer will be created the with the length specified. The * <code>ParseBuffer</code> can grow to accommodate a collection of * <code>char</code>'s larger the the size specified. * * @param size * initial size of this <code>ParseBuffer</code> */ public ParseBuffer(int size) { this.buf = new char[size]; } /** * This will add a <code>char</code> to the end of the buffer. The buffer * will not overflow with repeated uses of the <code>append</code>, it uses * an <code>ensureCapacity</code> method which will allow the buffer to * dynamically grow in size to accommodate more <code>char</code>'s. * * @param c * the <code>char</code> to be appended */ public void append(char c) { this.ensureCapacity(this.count + 1); this.buf[this.count++] = c; } /** * This will add a <code>String</code> to the end of the buffer. The buffer * will not overflow with repeated uses of the <code>append</code>, it uses * an <code>ensureCapacity</code> method which will allow the buffer to * dynamically grow in size to accommodate large <code>String</code> * objects. * * @param text * the <code>String</code> to be appended to this */ public void append(String text) { this.ensureCapacity(this.count + text.length()); text.getChars(0, text.length(), this.buf, this.count); this.count += text.length(); } /** * This will reset the buffer in such a way that the buffer is cleared of * all contents and then has the given string appended. This is used when a * value is to be set into the buffer value. See the * <code>append(String)</code> method for reference. * * @param text * this is the text that is to be appended to this */ public void reset(String text) { this.clear(); this.append(text); } /** * This will add a <code>ParseBuffer</code> to the end of this. The buffer * will not overflow with repeated uses of the <code>append</code>, it uses * an <code>ensureCapacity</code> method which will allow the buffer to * dynamically grow in size to accommodate large <code>ParseBuffer</code> * objects. * * @param text * the <code>ParseBuffer</code> to be appended */ public void append(ParseBuffer text) { this.append(text.buf, 0, text.count); } /** * This will reset the buffer in such a way that the buffer is cleared of * all contents and then has the given string appended. This is used when a * value is to be set into the buffer value. See the * <code>append(ParseBuffer)</code> method for reference. * * @param text * this is the text that is to be appended to this */ public void reset(ParseBuffer text) { this.clear(); this.append(text); } /** * This will add a <code>char</code> to the end of the buffer. The buffer * will not overflow with repeated uses of the <code>append</code>, it uses * an <code>ensureCapacity</code> method which will allow the buffer to * dynamically grow in size to accommodate large <code>char</code> arrays. * * @param c * the <code>char</code> array to be appended to this * @param off * the read offset for the array * @param len * the number of <code>char</code>'s to add */ public void append(char[] c, int off, int len) { this.ensureCapacity(this.count + len); System.arraycopy(c, off, this.buf, this.count, len); this.count += len; } /** * This will add a <code>String</code> to the end of the buffer. The buffer * will not overflow with repeated uses of the <code>append</code>, it uses * an <code>ensureCapacity</code> method which will allow the buffer to * dynamically grow in size to accommodate large <code>String</code> * objects. * * @param str * the <code>String</code> to be appended to this * @param off * the read offset for the <code>String</code> * @param len * the number of <code>char</code>'s to add */ public void append(String str, int off, int len) { this.ensureCapacity(this.count + len); str.getChars(off, len, this.buf, this.count); this.count += len; } /** * This will add a <code>ParseBuffer</code> to the end of this. The buffer * will not overflow with repeated uses of the <code>append</code>, it uses * an <code>ensureCapacity</code> method which will allow the buffer to * dynamically grow in size to accommodate large <code>ParseBuffer</code> * objects. * * @param text * the <code>ParseBuffer</code> to be appended * @param off * the read offset for the <code>ParseBuffer</code> * @param len * the number of <code>char</code>'s to add */ public void append(ParseBuffer text, int off, int len) { this.append(text.buf, off, len); } /** * This ensure that there is enough space in the buffer to allow for more * <code>char</code>'s to be added. If the buffer is already larger than min * then the buffer will not be expanded at all. * * @param min * the minimum size needed */ protected void ensureCapacity(int min) { if (this.buf.length < min) { int size = this.buf.length * 2; int max = Math.max(min, size); char[] temp = new char[max]; System.arraycopy(this.buf, 0, temp, 0, this.count); this.buf = temp; } } /** * This will empty the <code>ParseBuffer</code> so that the * <code>toString</code> parameter will return <code>null</code>. This is * used so that the same <code>ParseBuffer</code> can be recycled for * different tokens. */ public void clear() { this.cache = null; this.count = 0; } /** * This will return the number of bytes that have been appended to the * <code>ParseBuffer</code>. This will return zero after the clear method * has been invoked. * * @return the number of <code>char</code>'s within the buffer */ public int length() { return this.count; } /** * This will return the characters that have been appended to the * <code>ParseBuffer</code> as a <code>String</code> object. If the * <code>String</code> object has been created before then a cached * <code>String</code> object will be returned. This method will return * <code>null</code> after clear is invoked. * * @return the <code>char</code>'s appended as a <code>String</code> */ @Override public String toString() { if (this.count <= 0) return null; if (this.cache != null) return this.cache; this.cache = new String(this.buf, 0, this.count); return this.cache; } }