+++ /dev/null
-/*******************************************************************************\r
- * ============LICENSE_START====================================================\r
- * * org.onap.aaf\r
- * * ===========================================================================\r
- * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.\r
- * * ===========================================================================\r
- * * Licensed under the Apache License, Version 2.0 (the "License");\r
- * * you may not use this file except in compliance with the License.\r
- * * You may obtain a copy of the License at\r
- * * \r
- * * http://www.apache.org/licenses/LICENSE-2.0\r
- * * \r
- * * Unless required by applicable law or agreed to in writing, software\r
- * * distributed under the License is distributed on an "AS IS" BASIS,\r
- * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * * See the License for the specific language governing permissions and\r
- * * limitations under the License.\r
- * * ============LICENSE_END====================================================\r
- * *\r
- * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
- * *\r
- ******************************************************************************/\r
-package org.onap.aaf.cadi;\r
-\r
-import java.nio.ByteBuffer;\r
-import java.util.ArrayList;\r
-\r
-/**\r
- * Capacitor\r
- * \r
- * Storage mechanism for read data, specifically designed for InputStreams.\r
- * \r
- * The Standard BufferedInputStream requires a limit to be set for buffered reading, which is \r
- * impractical for reading SOAP headers, which can be quite large.\r
- *\r
- */\r
-public class Capacitor {\r
- private static final int DEFAULT_CHUNK = 256;\r
- private ArrayList<ByteBuffer> bbs = new ArrayList<ByteBuffer>();\r
- private ByteBuffer curr = null;\r
- private int idx;\r
- \r
- // Maintain a private RingBuffer for Memory, for efficiency\r
- private static ByteBuffer[] ring = new ByteBuffer[16];\r
- private static int start, end;\r
- \r
- \r
- public void put(byte b) {\r
- if(curr == null || curr.remaining()==0) { // ensure we have a "curr" buffer ready for data\r
- curr = ringGet();\r
- bbs.add(curr);\r
- }\r
- curr.put(b); \r
- }\r
-\r
- public int read() {\r
- if(curr!=null) { \r
- if(curr.remaining()>0) { // have a buffer, use it!\r
- return curr.get();\r
- } else if(idx<bbs.size()){ // Buffer not enough, get next one from array\r
- if(idx<bbs.size()) {\r
- curr=bbs.get(idx++);\r
- return curr.get();\r
- }\r
- }\r
- } // if no curr buffer, treat as end of stream\r
- return -1;\r
- }\r
- \r
- /**\r
- * read into an array like Streams\r
- * \r
- * @param array\r
- * @param offset\r
- * @param length\r
- * @return\r
- */\r
- public int read(byte[] array, int offset, int length) {\r
- if(curr==null)return -1;\r
- int len;\r
- int count=0;\r
- while(length>0) { // loop through while there's data needed\r
- if((len=curr.remaining())>length) { // if enough data in curr buffer, use this code\r
- curr.get(array,offset,length);\r
- count+=length;\r
- length=0;\r
- } else { // get data from curr, mark how much is needed to fulfil, and loop for next curr.\r
- curr.get(array,offset,len);\r
- count+=len;\r
- offset+=len;\r
- length-=len;\r
- if(idx<bbs.size()) {\r
- curr=bbs.get(idx++);\r
- } else {\r
- length=0; // stop, and return the count of how many we were able to load\r
- }\r
- }\r
- }\r
- return count;\r
- }\r
-\r
- /**\r
- * Put an array of data into Capacitor\r
- * \r
- * @param array\r
- * @param offset\r
- * @param length\r
- */\r
- public void put(byte[] array, int offset, int length) {\r
- if(curr == null || curr.remaining()==0) {\r
- curr = ringGet();\r
- bbs.add(curr);\r
- }\r
- \r
- int len;\r
- while(length>0) {\r
- if((len=curr.remaining())>length) {\r
- curr.put(array,offset,length);\r
- length=0;\r
- } else {\r
-// System.out.println(new String(array));\r
- curr.put(array,offset,len);\r
- length-=len;\r
- offset+=len;\r
- curr = ringGet();\r
- bbs.add(curr);\r
- }\r
- }\r
- }\r
- \r
- /**\r
- * Move state from Storage mode into Read mode, changing all internal buffers to read mode, etc\r
- */\r
- public void setForRead() {\r
- for(ByteBuffer bb : bbs) {\r
- bb.flip();\r
- }\r
- if(bbs.isEmpty()) {\r
- curr = null;\r
- idx = 0;\r
- } else {\r
- curr=bbs.get(0);\r
- idx=1;\r
- }\r
- }\r
- \r
- /**\r
- * reuse all the buffers\r
- */\r
- public void done() {\r
- for(ByteBuffer bb : bbs) {\r
- ringPut(bb);\r
- }\r
- bbs.clear();\r
- curr = null;\r
- }\r
- \r
- /**\r
- * Declare amount of data available to be read at once.\r
- * \r
- * @return\r
- */\r
- public int available() {\r
- int count = 0;\r
- for(ByteBuffer bb : bbs) {\r
- count+=bb.remaining();\r
- }\r
- return count;\r
- }\r
- \r
- /**\r
- * Returns how many are left that were not skipped\r
- * @param n\r
- * @return\r
- */\r
- public long skip(long n) {\r
- long skipped=0L;\r
- int skip;\r
- while(n>0) {\r
- if(n<(skip=curr.remaining())) {\r
- curr.position(curr.position()+(int)n);\r
- skipped+=skip;\r
- n=0;\r
- } else {\r
- curr.position(curr.limit());\r
- \r
- skipped-=skip;\r
- if(idx<bbs.size()) {\r
- curr=bbs.get(idx++);\r
- n-=skip;\r
- } else {\r
- n=0;\r
- }\r
- }\r
- }\r
- return skipped;\r
- }\r
- /**\r
- * Be able to re-read data that is stored that has already been re-read. This is not a standard Stream behavior, but can be useful\r
- * in a standalone mode.\r
- */\r
- public void reset() {\r
- for(ByteBuffer bb : bbs) {\r
- bb.position(0);\r
- }\r
- if(bbs.isEmpty()) {\r
- curr = null;\r
- idx = 0;\r
- } else {\r
- curr=bbs.get(0);\r
- idx=1;\r
- }\r
- }\r
-\r
- /*\r
- * Ring Functions. Reuse allocated memory \r
- */\r
- private ByteBuffer ringGet() {\r
- ByteBuffer bb = null;\r
- synchronized(ring) {\r
- bb=ring[start];\r
- ring[start]=null;\r
- if(bb!=null && ++start>15)start=0;\r
- }\r
- if(bb==null) {\r
- bb=ByteBuffer.allocate(DEFAULT_CHUNK);\r
- } else {\r
- bb.clear();// refresh reused buffer\r
- }\r
- return bb;\r
- }\r
- \r
- private void ringPut(ByteBuffer bb) {\r
- synchronized(ring) {\r
- ring[end]=bb; // if null or not, BB will just be Garbage collected\r
- if(++end>15)end=0;\r
- }\r
- }\r
-\r
-}\r