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 * https://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 }