1ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey/* 2ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey * Copyright (C) 2014 The Android Open Source Project 3ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey * 4ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 5ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey * you may not use this file except in compliance with the License. 6ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey * You may obtain a copy of the License at 7ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey * 8ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 9ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey * 10ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey * Unless required by applicable law or agreed to in writing, software 11ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 12ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey * See the License for the specific language governing permissions and 14ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey * limitations under the License. 15ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey */ 16ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey 17ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkeypackage com.android.internal.util; 18ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey 19ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkeyimport libcore.io.Streams; 20ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey 21ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkeyimport java.io.IOException; 22ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkeyimport java.io.InputStream; 23ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey 24ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey/** 25ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey * Reads exact number of bytes from wrapped stream, returning EOF once those 26ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey * bytes have been read. 27ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey */ 28ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkeypublic class SizedInputStream extends InputStream { 29ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey private final InputStream mWrapped; 30ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey private long mLength; 31ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey 32ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey public SizedInputStream(InputStream wrapped, long length) { 33ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey mWrapped = wrapped; 34ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey mLength = length; 35ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey } 36ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey 37ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey @Override 38ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey public void close() throws IOException { 39ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey super.close(); 40ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey mWrapped.close(); 41ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey } 42ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey 43ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey @Override 44ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey public int read() throws IOException { 45ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey return Streams.readSingleByte(this); 46ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey } 47ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey 48ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey @Override 49ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException { 50ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey if (mLength <= 0) { 51ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey return -1; 52ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey } else if (byteCount > mLength) { 53ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey byteCount = (int) mLength; 54ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey } 55ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey 56ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey final int n = mWrapped.read(buffer, byteOffset, byteCount); 57ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey if (n == -1) { 58ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey if (mLength > 0) { 59ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey throw new IOException("Unexpected EOF; expected " + mLength + " more bytes"); 60ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey } 61ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey } else { 62ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey mLength -= n; 63ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey } 64ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey return n; 65ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey } 66ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey} 67