📄 charchunk.java
字号:
/* * ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 1999 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * * [Additional notices, if required by prior licensing conditions] * */ package org.apache.tomcat.util.buf;import java.text.*;import java.util.*;import java.io.Serializable;import java.io.IOException;/** * Utilities to manipluate char chunks. While String is * the easiest way to manipulate chars ( search, substrings, etc), * it is known to not be the most efficient solution - Strings are * designed as imutable and secure objects. * * @author dac@sun.com * @author James Todd [gonzo@sun.com] * @author Costin Manolache * @author Remy Maucherat */public final class CharChunk implements Cloneable, Serializable { // Input interface, used when the buffer is emptied. public static interface CharInputChannel { /** * Read new bytes ( usually the internal conversion buffer ). * The implementation is allowed to ignore the parameters, * and mutate the chunk if it wishes to implement its own buffering. */ public int realReadChars(char cbuf[], int off, int len) throws IOException; } /** * When we need more space we'll either * grow the buffer ( up to the limit ) or send it to a channel. */ public static interface CharOutputChannel { /** Send the bytes ( usually the internal conversion buffer ). * Expect 8k output if the buffer is full. */ public void realWriteChars(char cbuf[], int off, int len) throws IOException; } // -------------------- // char[] private char buff[]; private int start; private int end; private boolean isSet=false; // XXX private boolean isOutput=false; // -1: grow undefinitely // maximum amount to be cached private int limit=-1; private CharInputChannel in = null; private CharOutputChannel out = null; /** * Creates a new, uninitialized CharChunk object. */ public CharChunk() { } public CharChunk(int size) { allocate( size, -1 ); } // -------------------- public CharChunk getClone() { try { return (CharChunk)this.clone(); } catch( Exception ex) { return null; } } public boolean isNull() { if( end > 0 ) return false; return !isSet; //XXX } /** * Resets the message bytes to an uninitialized state. */ public void recycle() { // buff=null; isSet=false; // XXX start=0; end=0; } public void reset() { buff=null; } // -------------------- Setup -------------------- public void allocate( int initial, int limit ) { isOutput=true; if( buff==null || buff.length < initial ) { buff=new char[initial]; } this.limit=limit; start=0; end=0; isOutput=true; isSet=true; } public void setChars( char[] c, int off, int len ) { recycle(); isSet=true; buff=c; start=off; end=start + len; limit=end; } /** Maximum amount of data in this buffer. * * If -1 or not set, the buffer will grow undefinitely. * Can be smaller than the current buffer size ( which will not shrink ). * When the limit is reached, the buffer will be flushed ( if out is set ) * or throw exception. */ public void setLimit(int limit) { this.limit=limit; } public int getLimit() { return limit; } /** * When the buffer is empty, read the data from the input channel. */ public void setCharInputChannel(CharInputChannel in) { this.in = in; } /** When the buffer is full, write the data to the output channel. * Also used when large amount of data is appended. * * If not set, the buffer will grow to the limit. */ public void setCharOutputChannel(CharOutputChannel out) { this.out=out; } // compat public char[] getChars() { return getBuffer(); } public char[] getBuffer() { return buff; } /** * Returns the start offset of the bytes. * For output this is the end of the buffer. */ public int getStart() { return start; } public int getOffset() { return getStart(); } /** * Returns the start offset of the bytes. */ public void setOffset(int off) { start=off; } /** * Returns the length of the bytes. */ public int getLength() { return end-start; } public int getEnd() { return end; } public void setEnd( int i ) { end=i; } // -------------------- Adding data -------------------- public void append( char b ) throws IOException { makeSpace( 1 ); // couldn't make space if( limit >0 && end >= limit ) { flushBuffer(); } buff[end++]=b; } public void append( CharChunk src ) throws IOException { append( src.getBuffer(), src.getOffset(), src.getLength()); } /** Add data to the buffer */ public void append( char src[], int off, int len ) throws IOException { // will grow, up to limit makeSpace( len ); // if we don't have limit: makeSpace can grow as it wants if( limit < 0 ) { // assert: makeSpace made enough space System.arraycopy( src, off, buff, end, len ); end+=len; return; } // if we have limit and we're below if( len <= limit - end ) { // makeSpace will grow the buffer to the limit, // so we have space System.arraycopy( src, off, buff, end, len ); end+=len; return; } // need more space than we can afford, need to flush // buffer // the buffer is already at ( or bigger than ) limit // Optimization: // If len-avail < length ( i.e. after we fill the buffer with // what we can, the remaining will fit in the buffer ) we'll just // copy the first part, flush, then copy the second part - 1 write // and still have some space for more. We'll still have 2 writes, but // we write more on the first. if( len + end < 2 * limit ) { /* If the request length exceeds the size of the output buffer, flush the output buffer and then write the data directly. We can't avoid 2 writes, but we can write more on the second */ int avail=limit-end; System.arraycopy(src, off, buff, end, avail); end += avail; flushBuffer(); System.arraycopy(src, off+avail, buff, end, len - avail); end+= len - avail; } else { // len > buf.length + avail // long write - flush the buffer and write the rest // directly from source flushBuffer(); out.realWriteChars( src, off, len ); } } /** Add data to the buffer */ public void append( StringBuffer sb ) throws IOException { int len=sb.length(); // will grow, up to limit makeSpace( len );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -