2 * Copyright (C) 2014, United States Government, as represented by the
3 * Administrator of the National Aeronautics and Space Administration.
6 * The Java Pathfinder core (jpf-core) platform is licensed under the
7 * Apache License, Version 2.0 (the "License"); you may not use this file except
8 * in compliance with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0.
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package gov.nasa.jpf.util;
20 import java.util.Iterator;
21 import java.util.NoSuchElementException;
24 * It is a dynamically growing, cyclic array buffer queue for bytes. It has
25 * the similar implementation as ArrayObjectQueue.
27 * Suitable buffer for storing data transmitted and received as a continuous
28 * stream of bytes, e.g. buffers for socket based communications
30 public class ArrayByteQueue implements ObjectQueue<Byte>, Cloneable {
32 static final int DEFAULT_CAPACITY = 256;
35 int first; // next index we will remove
36 int last; // last index we did add
40 class FIFOIterator implements Iterator<Byte> {
45 public boolean hasNext() {
46 return (remaining > 0);
52 throw new NoSuchElementException();
54 Byte e = buffer[next];
55 next = (next+1) % buffer.length;
62 public void remove() { // its a queue
63 throw new UnsupportedOperationException();
67 // just for debugging purposes
68 class StorageIterator implements Iterator<Byte> {
72 public boolean hasNext(){
73 return (next < buffer.length);
78 if (next == buffer.length){
79 throw new NoSuchElementException();
82 Byte e = buffer[next];
88 public void remove() { // its a queue
89 throw new UnsupportedOperationException();
93 public ArrayByteQueue (){
94 buffer = new byte[DEFAULT_CAPACITY];
97 public ArrayByteQueue (int initialCapacity){
98 buffer = new byte[initialCapacity];
101 protected void grow(){
102 byte[] newBuffer = new byte[buffer.length * 3 / 2];
105 System.arraycopy(buffer, first, newBuffer, 0, last - first +1);
106 } else if (first > last){
107 int nRight = buffer.length - first;
108 System.arraycopy(buffer, first, newBuffer, 0, nRight);
109 System.arraycopy(buffer, 0, newBuffer, nRight, last+1);
110 } else { // just 1 element
111 newBuffer[0] = buffer[first];
120 public boolean isEmpty() {
124 public int getCurrentCapacity(){
125 return buffer.length;
134 public boolean offer (Byte e){
139 public boolean add (Byte e){
140 if (size == 0){ // first element
146 int i = (last + 1) % buffer.length;
157 return true; // this is a dynamic queue, we never run out of space
167 first = (first+1) % buffer.length;
171 //buffer[i] = null; // avoid memory leaks
177 public Byte remove () throws NoSuchElementException {
179 throw new NoSuchElementException();
186 public Byte peek () {
190 return buffer[first];
195 public Iterator<Byte> iterator() {
196 return new FIFOIterator();
199 public Iterator<Byte> storageIterator(){
200 return new StorageIterator();
206 buffer = new byte[buffer.length]; // cheaper than iterating over the old one
212 * call Processor.process(e) on each queued object
214 * This method does not return before the queue is empty, which makes it
215 * suitable for graph traversal. It also avoids iterator objects, allows
216 * adding new objects while processing the queue, and enables to keep
217 * processing state in the processor
220 public void process (Processor<Byte> processor){
223 processor.process(e);
228 public Object clone() {
230 ArrayByteQueue clone = (ArrayByteQueue)super.clone();
231 clone.buffer = this.buffer.clone();
233 } catch (CloneNotSupportedException cnx) {
239 public String toString() {
240 Iterator<Byte> itr = iterator();
242 while(itr.hasNext()) {
243 if(result.length()>1) {
244 result = result + ", ";
249 result = result + "]";