Java tutorial
/* * Copyright 1999-2010 University of Chicago * * 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.globus.gsi.gssapi; import java.io.InputStream; import java.io.IOException; import java.util.LinkedList; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Used as token-oriented input stream needed for SSL library I/O abstraction. */ public class TokenInputStream extends InputStream { private static Log logger = LogFactory.getLog(TokenInputStream.class.getName()); private LinkedList tokens; // list of buffers private byte[] buff; // current buffer private int index; // position within current buffer private boolean closed; public TokenInputStream() { this.tokens = new LinkedList(); this.index = 0; this.closed = false; } // main function public void putToken(byte[] buf, int off, int len) { if (buf == null || len <= 0) { return; } if (logger.isDebugEnabled()) { logger.debug("put token: " + len); } byte[] localBuf = buf; if (off != 0) { localBuf = new byte[len]; System.arraycopy(buf, off, localBuf, 0, len); } synchronized (this) { if (this.buff == null || this.buff != null && this.buff.length == this.index) { this.buff = localBuf; this.index = 0; } else { this.tokens.add(localBuf); } notify(); } } public int read(byte[] data) throws IOException { return read(data, 0, data.length); } public int read(byte[] data, int off, int len) throws IOException { if (logger.isDebugEnabled()) { logger.debug("read byte array: " + len); } if (!checkData()) { return -1; } int size = Math.min(len, buff.length - index); System.arraycopy(buff, index, data, off, size); index += size; return size; } public int read() throws IOException { logger.debug("read byte"); if (!checkData()) { return -1; } return buff[index++] & 0xff; } protected synchronized boolean checkData() { try { while (!hasData()) { wait(); if (closed) { return false; } } } catch (Exception e) { return false; } return true; } protected boolean hasData() { if (this.buff == null) { return false; } if (this.buff.length == this.index) { if (tokens.isEmpty()) { return false; } else { this.buff = (byte[]) tokens.removeFirst(); this.index = 0; return true; } } return true; } public int available() throws IOException { if (!hasData()) { return 0; } else { return buff.length - index; } } public void close() throws IOException { logger.debug("close() called"); synchronized (this) { this.closed = true; notify(); } } public String toString() { return tokens.toString() + " " + index + " " + buff.length; } }