1cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal/* 2cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * Copyright (C) 2016 The Android Open Source Project 3cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * 4cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * Licensed under the Apache License, Version 2.0 (the "License"); 5cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * you may not use this file except in compliance with the License. 6cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * You may obtain a copy of the License at 7cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * 8cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * http://www.apache.org/licenses/LICENSE-2.0 9cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * 10cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * Unless required by applicable law or agreed to in writing, software 11cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * distributed under the License is distributed on an "AS IS" BASIS, 12cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * See the License for the specific language governing permissions and 14cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * limitations under the License. 15cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal */ 16cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal 17cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawalpackage com.android.server.wifi.util; 18cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal 19cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawalimport java.util.ArrayList; 20cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal 21cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal/** 22cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * A ring buffer where each element of the ring is itself a byte array. 23cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal */ 24cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawalpublic class ByteArrayRingBuffer { 25cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal private ArrayList<byte[]> mArrayList; 26ca0bac5826ab430d1b765b201a609f7bc38401eemukesh agrawal private int mMaxBytes; 27cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal private int mBytesUsed; 28cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal 29cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal /** 30cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * Creates a ring buffer that holds at most |maxBytes| of data. The overhead for each element 31cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * is not included in this limit. 32ca0bac5826ab430d1b765b201a609f7bc38401eemukesh agrawal * @param maxBytes upper bound on the amount of data to hold 33cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal */ 34cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal public ByteArrayRingBuffer(int maxBytes) { 35ca0bac5826ab430d1b765b201a609f7bc38401eemukesh agrawal if (maxBytes < 1) { 36ca0bac5826ab430d1b765b201a609f7bc38401eemukesh agrawal throw new IllegalArgumentException(); 37ca0bac5826ab430d1b765b201a609f7bc38401eemukesh agrawal } 38cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal mArrayList = new ArrayList<byte[]>(); 39cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal mMaxBytes = maxBytes; 40cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal mBytesUsed = 0; 41cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal } 42cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal 43cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal /** 44cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * Adds |newData| to the ring buffer. Removes existing entries to make room, if necessary. 45cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * Existing entries are removed in FIFO order. 46cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * <p><b>Note:</b> will fail if |newData| itself exceeds the size limit for this buffer. 47cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * Will first remove all existing entries in this case. (This guarantees that the ring buffer 48cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * always represents a contiguous sequence of data.) 49cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * @param newData data to be added to the ring 50cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * @return true if the data was added 51cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal */ 52cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal public boolean appendBuffer(byte[] newData) { 53ca0bac5826ab430d1b765b201a609f7bc38401eemukesh agrawal pruneToSize(mMaxBytes - newData.length); 54cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal if (mBytesUsed + newData.length > mMaxBytes) { 55cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal return false; 56cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal } 57cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal 58cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal mArrayList.add(newData); 59cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal mBytesUsed += newData.length; 60cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal return true; 61cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal } 62cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal 63cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal /** 64cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * Returns the |i|-th element of the ring. The element retains its position in the ring. 65cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * @param i 66cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * @return the requested element 67cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal */ 68cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal public byte[] getBuffer(int i) { 69cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal return mArrayList.get(i); 70cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal } 71cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal 72cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal /** 73cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * Returns the number of elements present in the ring. 74cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal * @return the number of elements present 75cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal */ 76cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal public int getNumBuffers() { 77cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal return mArrayList.size(); 78cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal } 79ca0bac5826ab430d1b765b201a609f7bc38401eemukesh agrawal 80ca0bac5826ab430d1b765b201a609f7bc38401eemukesh agrawal /** 81ca0bac5826ab430d1b765b201a609f7bc38401eemukesh agrawal * Resize the buffer, removing existing data if necessary. 82ca0bac5826ab430d1b765b201a609f7bc38401eemukesh agrawal * @param maxBytes upper bound on the amount of data to hold 83ca0bac5826ab430d1b765b201a609f7bc38401eemukesh agrawal */ 84ca0bac5826ab430d1b765b201a609f7bc38401eemukesh agrawal public void resize(int maxBytes) { 85ca0bac5826ab430d1b765b201a609f7bc38401eemukesh agrawal pruneToSize(maxBytes); 86ca0bac5826ab430d1b765b201a609f7bc38401eemukesh agrawal mMaxBytes = maxBytes; 87ca0bac5826ab430d1b765b201a609f7bc38401eemukesh agrawal } 88ca0bac5826ab430d1b765b201a609f7bc38401eemukesh agrawal 89ca0bac5826ab430d1b765b201a609f7bc38401eemukesh agrawal private void pruneToSize(int sizeBytes) { 90ca0bac5826ab430d1b765b201a609f7bc38401eemukesh agrawal int newBytesUsed = mBytesUsed; 91ca0bac5826ab430d1b765b201a609f7bc38401eemukesh agrawal int i = 0; 92ca0bac5826ab430d1b765b201a609f7bc38401eemukesh agrawal while (i < mArrayList.size() && newBytesUsed > sizeBytes) { 93ca0bac5826ab430d1b765b201a609f7bc38401eemukesh agrawal newBytesUsed -= mArrayList.get(i).length; 94ca0bac5826ab430d1b765b201a609f7bc38401eemukesh agrawal i++; 95ca0bac5826ab430d1b765b201a609f7bc38401eemukesh agrawal } 96ca0bac5826ab430d1b765b201a609f7bc38401eemukesh agrawal mArrayList.subList(0, i).clear(); 97ca0bac5826ab430d1b765b201a609f7bc38401eemukesh agrawal mBytesUsed = newBytesUsed; 98ca0bac5826ab430d1b765b201a609f7bc38401eemukesh agrawal } 99cc84bc6179db408b1e45168d43e10ba0ab089fcamukesh agrawal} 100