1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.conscrypt; 19 20 import java.nio.ByteBuffer; 21 22 /** 23 * This class provides the DataStream functionality 24 * implemented over the array of ByteBuffer instances. 25 * Among with the data chunks read functionality 26 * it provides the info about amount of consumed data. 27 * The source ByteBuffer objects can be replaced by other. 28 * So one instance of this wrapper can be reused for several 29 * data sources. 30 */ 31 public class SSLEngineDataStream implements DataStream { 32 33 private ByteBuffer[] srcs; 34 private int offset; 35 private int limit; 36 37 private int available; 38 private int consumed; 39 40 protected SSLEngineDataStream() {} 41 42 protected void setSourceBuffers(ByteBuffer[] srcs, int offset, int length) { 43 this.srcs = srcs; 44 this.offset = offset; 45 this.limit = offset+length; 46 this.consumed = 0; 47 this.available = 0; 48 for (int i=offset; i<limit; i++) { 49 if (srcs[i] == null) { 50 throw new IllegalStateException( 51 "Some of the input parameters are null"); 52 } 53 available += srcs[i].remaining(); 54 } 55 } 56 57 public int available() { 58 return available; 59 } 60 61 public boolean hasData() { 62 return available > 0; 63 } 64 65 public byte[] getData(int length) { 66 // TODO: optimization work: 67 // use ByteBuffer.get(byte[],int,int) 68 // and ByteBuffer.hasArray() methods 69 int len = (length < available) ? length : available; 70 available -= len; 71 consumed += len; 72 byte[] res = new byte[len]; 73 int pos = 0; 74 loop: 75 for (; offset<limit; offset++) { 76 while (srcs[offset].hasRemaining()) { 77 res[pos++] = srcs[offset].get(); 78 len --; 79 if (len == 0) { 80 break loop; 81 } 82 } 83 } 84 return res; 85 } 86 87 protected int consumed() { 88 return consumed; 89 } 90 } 91 92