/* * StreamBufferList.java - Maintain a list of StreamBuffer objects. * * Copyright (c) 1996 Chuck McManis, All Rights Reserved. * * Permission to use, copy, modify, and distribute this software * and its documentation for NON-COMMERCIAL purposes and without * fee is hereby granted provided that this copyright notice * appears in all copies. * * CHUCK MCMANIS MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE * SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. CHUCK MCMANIS * SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT * OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. */ package util.comm; /** * This class is private to the util.comm package and maintains a list * of StreamBuffer objects for its client. Both the DataChannelInputStream * and the DataChannelOutputStram classes use these lists to keep active * and free lists of stream buffers. */ class StreamBufferList { StreamBuffer buf; StreamBufferList next; private StreamBufferList lastValid; private StreamBufferList lastInChain; public StreamBufferList(StreamBuffer z) { buf = z; next = null; } public StreamBufferList() { buf = null; next = null; lastValid = null; lastInChain = null; } synchronized StreamBuffer getBuffer() { // if the list is empty then return null. if (next == null) return null; StreamBuffer result = next.buf; next.buf = null; // clear it out. /* * Case 1: There is only one valid buffer. */ if (lastValid == next) { lastValid = null; return result; } /* * Case 2: There is more than one valid buffer in the chain. */ lastInChain.next = next; lastInChain = next; next = next.next; lastInChain.next = null; return result; } synchronized void putBuffer(StreamBuffer z) { // Case 0: The list is empty. if (next == null) { next = new StreamBufferList(z); lastValid = next; lastInChain = next; return; } // Case 1: The list is non-empty, but there is a left over list item. if (lastValid == null) { lastValid = next; next.buf = z; return; } // case 1b. if (lastValid.next != null) { lastValid.next.buf = z; lastValid = lastValid.next; return; } // Case 2: grow the list. lastValid.next = new StreamBufferList(z); lastInChain = lastValid.next; lastValid = lastValid.next; } /** * Return the total number of bytes queued in this streambuffer list. */ public synchronized int avail() { int total = 0; for (StreamBufferList q = next; (q != null) && (q.buf != null); q = q.next) total += q.buf.avail(); return total; } }