1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20 package org.apache.commons.compress.archivers.zip; 21 22 /** 23 * Circular byte buffer. 24 * 25 * @since 1.7 26 */ 27 final class CircularBuffer { 28 29 /** Size of the buffer */ 30 private final int size; 31 32 /** The buffer */ 33 private final byte[] buffer; 34 35 /** Index of the next data to be read from the buffer */ 36 private int readIndex; 37 38 /** Index of the next data written in the buffer */ 39 private int writeIndex; 40 41 CircularBuffer(final int size) { 42 this.size = size; 43 buffer = new byte[size]; 44 } 45 46 /** 47 * Tests whether a new byte can be read from the buffer. 48 * 49 * @return Whether a new byte can be read from the buffer. 50 */ 51 public boolean available() { 52 return readIndex != writeIndex; 53 } 54 55 /** 56 * Copies a previous interval in the buffer to the current position. 57 * 58 * @param distance the distance from the current write position 59 * @param length the number of bytes to copy 60 */ 61 public void copy(final int distance, final int length) { 62 final int pos1 = writeIndex - distance; 63 final int pos2 = pos1 + length; 64 for (int i = pos1; i < pos2; i++) { 65 buffer[writeIndex] = buffer[(i + size) % size]; 66 writeIndex = (writeIndex + 1) % size; 67 } 68 } 69 70 /** 71 * Reads a byte from the buffer. 72 * 73 * @return a byte from the buffer. 74 */ 75 public int get() { 76 if (available()) { 77 final int value = buffer[readIndex]; 78 readIndex = (readIndex + 1) % size; 79 return value & 0xFF; 80 } 81 return -1; 82 } 83 84 /** 85 * Puts a byte to the buffer. 86 * 87 * @param value the value to put. 88 */ 89 public void put(final int value) { 90 buffer[writeIndex] = (byte) value; 91 writeIndex = (writeIndex + 1) % size; 92 } 93 }