1d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen/**************************************************************** 2d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * Licensed to the Apache Software Foundation (ASF) under one * 3d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * or more contributor license agreements. See the NOTICE file * 4d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * distributed with this work for additional information * 5d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * regarding copyright ownership. The ASF licenses this file * 6d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * to you under the Apache License, Version 2.0 (the * 7d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * "License"); you may not use this file except in compliance * 8d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * with the License. You may obtain a copy of the License at * 9d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * * 10d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * http://www.apache.org/licenses/LICENSE-2.0 * 11d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * * 12d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * Unless required by applicable law or agreed to in writing, * 13d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * software distributed under the License is distributed on an * 14d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * 15d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * KIND, either express or implied. See the License for the * 16d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * specific language governing permissions and limitations * 17d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * under the License. * 18d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen ****************************************************************/ 19d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 20d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chenpackage org.apache.james.mime4j.decoder; 21d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 22d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chenimport java.util.Iterator; 23d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chenimport java.util.NoSuchElementException; 24d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 25d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen/** 26d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * UnboundedFifoByteBuffer is a very efficient buffer implementation. 27d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * According to performance testing, it exhibits a constant access time, but it 28d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * also outperforms ArrayList when used for the same purpose. 29d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * <p> 30d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * The removal order of an <code>UnboundedFifoByteBuffer</code> is based on the insertion 31d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * order; elements are removed in the same order in which they were added. 32d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * The iteration order is the same as the removal order. 33d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * <p> 34d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * The {@link #remove()} and {@link #get()} operations perform in constant time. 35d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * The {@link #add(Object)} operation performs in amortized constant time. All 36d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * other operations perform in linear time or worse. 37d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * <p> 38d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * Note that this implementation is not synchronized. The following can be 39d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * used to provide synchronized access to your <code>UnboundedFifoByteBuffer</code>: 40d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * <pre> 41d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * Buffer fifo = BufferUtils.synchronizedBuffer(new UnboundedFifoByteBuffer()); 42d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * </pre> 43d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * <p> 44d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * This buffer prevents null objects from being added. 45d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * 46d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * @since Commons Collections 3.0 (previously in main package v2.1) 47d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * @version $Revision: 1.1 $ $Date: 2004/08/24 06:52:02 $ 48d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * 49d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * 50d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * 51d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * 52d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * 53d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * 54d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen */ 55d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chenclass UnboundedFifoByteBuffer { 56d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 57d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen protected byte[] buffer; 58d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen protected int head; 59d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen protected int tail; 60d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 61d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen /** 62d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * Constructs an UnboundedFifoByteBuffer with the default number of elements. 63d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * It is exactly the same as performing the following: 64d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * 65d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * <pre> 66d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * new UnboundedFifoByteBuffer(32); 67d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * </pre> 68d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen */ 69d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen public UnboundedFifoByteBuffer() { 70d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen this(32); 71d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 72d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 73d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen /** 74d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * Constructs an UnboundedFifoByteBuffer with the specified number of elements. 75d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * The integer must be a positive integer. 76d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * 77d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * @param initialSize the initial size of the buffer 78d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * @throws IllegalArgumentException if the size is less than 1 79d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen */ 80d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen public UnboundedFifoByteBuffer(int initialSize) { 81d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen if (initialSize <= 0) { 82d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen throw new IllegalArgumentException("The size must be greater than 0"); 83d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 84d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen buffer = new byte[initialSize + 1]; 85d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen head = 0; 86d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen tail = 0; 87d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 88d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 89d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen /** 90d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * Returns the number of elements stored in the buffer. 91d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * 92d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * @return this buffer's size 93d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen */ 94d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen public int size() { 95d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen int size = 0; 96d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 97d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen if (tail < head) { 98d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen size = buffer.length - head + tail; 99d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } else { 100d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen size = tail - head; 101d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 102d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 103d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen return size; 104d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 105d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 106d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen /** 107d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * Returns true if this buffer is empty; false otherwise. 108d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * 109d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * @return true if this buffer is empty 110d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen */ 111d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen public boolean isEmpty() { 112d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen return (size() == 0); 113d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 114d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 115d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen /** 116d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * Adds the given element to this buffer. 117d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * 118d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * @param b the byte to add 119d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * @return true, always 120d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen */ 121d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen public boolean add(final byte b) { 122d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 123d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen if (size() + 1 >= buffer.length) { 124d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen byte[] tmp = new byte[((buffer.length - 1) * 2) + 1]; 125d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 126d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen int j = 0; 127d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen for (int i = head; i != tail;) { 128d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen tmp[j] = buffer[i]; 129d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen buffer[i] = 0; 130d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 131d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen j++; 132d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen i++; 133d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen if (i == buffer.length) { 134d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen i = 0; 135d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 136d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 137d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 138d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen buffer = tmp; 139d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen head = 0; 140d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen tail = j; 141d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 142d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 143d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen buffer[tail] = b; 144d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen tail++; 145d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen if (tail >= buffer.length) { 146d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen tail = 0; 147d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 148d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen return true; 149d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 150d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 151d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen /** 152d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * Returns the next object in the buffer. 153d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * 154d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * @return the next object in the buffer 155d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * @throws BufferUnderflowException if this buffer is empty 156d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen */ 157d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen public byte get() { 158d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen if (isEmpty()) { 159d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen throw new IllegalStateException("The buffer is already empty"); 160d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 161d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 162d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen return buffer[head]; 163d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 164d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 165d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen /** 166d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * Removes the next object from the buffer 167d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * 168d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * @return the removed object 169d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * @throws BufferUnderflowException if this buffer is empty 170d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen */ 171d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen public byte remove() { 172d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen if (isEmpty()) { 173d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen throw new IllegalStateException("The buffer is already empty"); 174d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 175d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 176d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen byte element = buffer[head]; 177d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 178d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen head++; 179d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen if (head >= buffer.length) { 180d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen head = 0; 181d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 182d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 183d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen return element; 184d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 185d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 186d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen /** 187d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * Increments the internal index. 188d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * 189d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * @param index the index to increment 190d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * @return the updated index 191d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen */ 192d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen private int increment(int index) { 193d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen index++; 194d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen if (index >= buffer.length) { 195d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen index = 0; 196d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 197d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen return index; 198d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 199d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 200d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen /** 201d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * Decrements the internal index. 202d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * 203d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * @param index the index to decrement 204d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * @return the updated index 205d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen */ 206d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen private int decrement(int index) { 207d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen index--; 208d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen if (index < 0) { 209d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen index = buffer.length - 1; 210d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 211d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen return index; 212d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 213d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 214d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen /** 215d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * Returns an iterator over this buffer's elements. 216d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * 217d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * @return an iterator over this buffer's elements 218d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen */ 219d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen public Iterator iterator() { 220d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen return new Iterator() { 221d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 222d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen private int index = head; 223d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen private int lastReturnedIndex = -1; 224d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 225d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen public boolean hasNext() { 226d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen return index != tail; 227d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 228d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 229d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 230d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen public Object next() { 231d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen if (!hasNext()) { 232d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen throw new NoSuchElementException(); 233d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 234d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen lastReturnedIndex = index; 235d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen index = increment(index); 236d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen return new Byte(buffer[lastReturnedIndex]); 237d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 238d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 239d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen public void remove() { 240d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen if (lastReturnedIndex == -1) { 241d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen throw new IllegalStateException(); 242d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 243d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 244d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen // First element can be removed quickly 245d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen if (lastReturnedIndex == head) { 246d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen UnboundedFifoByteBuffer.this.remove(); 247d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen lastReturnedIndex = -1; 248d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen return; 249d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 250d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 251d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen // Other elements require us to shift the subsequent elements 252d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen int i = lastReturnedIndex + 1; 253d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen while (i != tail) { 254d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen if (i >= buffer.length) { 255d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen buffer[i - 1] = buffer[0]; 256d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen i = 0; 257d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } else { 258d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen buffer[i - 1] = buffer[i]; 259d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen i++; 260d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 261d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 262d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 263d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen lastReturnedIndex = -1; 264d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen tail = decrement(tail); 265d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen buffer[tail] = 0; 266d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen index = decrement(index); 267d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 268d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 269d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen }; 270d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 271d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 272d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen}