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 import javax.net.ssl.SSLException; 22 23 /** 24 * This class is used to retrieve the application data 25 * arrived for the SSLEngine. 26 */ 27 public class SSLEngineAppData implements Appendable { 28 29 /** 30 * Buffer containing received application data. 31 */ 32 byte[] buffer; 33 34 /** 35 * Constructor 36 */ 37 protected SSLEngineAppData() {} 38 39 /** 40 * Stores received data. The source data is not cloned, 41 * just the array reference is remembered into the buffer field. 42 */ 43 public void append(byte[] src) { 44 if (buffer != null) { 45 throw new AlertException( 46 AlertProtocol.INTERNAL_ERROR, 47 new SSLException("Attempt to override the data")); 48 } 49 buffer = src; 50 } 51 52 /** 53 * Places the data from the buffer into the array of destination 54 * ByteBuffer objects. 55 */ 56 protected int placeTo(ByteBuffer[] dsts, int offset, int length) { 57 if (buffer == null) { 58 return 0; 59 } 60 int pos = 0; 61 int len = buffer.length; 62 int rem; 63 // write data to the buffers 64 for (int i=offset; i<offset+length; i++) { 65 rem = dsts[i].remaining(); 66 // TODO: optimization work - use hasArray, array(), arraycopy 67 if (len - pos < rem) { 68 // can fully write remaining data into buffer 69 dsts[i].put(buffer, pos, len - pos); 70 pos = len; 71 // data was written, exit 72 break; 73 } 74 // write chunk of data 75 dsts[i].put(buffer, pos, rem); 76 pos += rem; 77 } 78 if (pos != len) { 79 // The data did not feet into the buffers, 80 // it should not happen, because the destination buffers 81 // had been checked for the space before record unwrapping. 82 // But if it so, we should allert about internal error. 83 throw new AlertException( 84 AlertProtocol.INTERNAL_ERROR, 85 new SSLException( 86 "The received application data could not be fully written" 87 + "into the destination buffers")); 88 } 89 buffer = null; 90 return len; 91 } 92 } 93 94