19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.content.res; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkeyimport android.os.Bundle; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcel; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ParcelFileDescriptor; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcelable; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2432559e191fd2580393d77161a32bcaeaa49fbe5dJeff Sharkeyimport java.io.Closeable; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileInputStream; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileOutputStream; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * File descriptor of an entry in the AssetManager. This provides your own 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * opened FileDescriptor that can be used to read the data, as well as the 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * offset and length of that entry's data in the file. 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3532559e191fd2580393d77161a32bcaeaa49fbe5dJeff Sharkeypublic class AssetFileDescriptor implements Parcelable, Closeable { 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Length used with {@link #AssetFileDescriptor(ParcelFileDescriptor, long, long)} 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and {@link #getDeclaredLength} when a length has not been declared. This means 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the data extends to the end of the file. 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final long UNKNOWN_LENGTH = -1; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ParcelFileDescriptor mFd; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final long mStartOffset; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final long mLength; 46c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey private final Bundle mExtras; 47c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create a new AssetFileDescriptor from the given values. 50c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey * 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param fd The underlying file descriptor. 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param startOffset The location within the file that the asset starts. 53c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey * This must be 0 if length is UNKNOWN_LENGTH. 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param length The number of bytes of the asset, or 55c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey * {@link #UNKNOWN_LENGTH} if it extends to the end of the file. 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AssetFileDescriptor(ParcelFileDescriptor fd, long startOffset, 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long length) { 59c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey this(fd, startOffset, length, null); 60c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey } 61c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey 62c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey /** 63c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey * Create a new AssetFileDescriptor from the given values. 64c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey * 65c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey * @param fd The underlying file descriptor. 66c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey * @param startOffset The location within the file that the asset starts. 67c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey * This must be 0 if length is UNKNOWN_LENGTH. 68c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey * @param length The number of bytes of the asset, or 69c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey * {@link #UNKNOWN_LENGTH} if it extends to the end of the file. 70c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey * @param extras additional details that can be used to interpret the 71c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey * underlying file descriptor. May be null. 72c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey */ 73c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey public AssetFileDescriptor(ParcelFileDescriptor fd, long startOffset, 74c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey long length, Bundle extras) { 75af67fc65bf113b028ff33e71cd6a45810018c273Jeff Brown if (fd == null) { 76af67fc65bf113b028ff33e71cd6a45810018c273Jeff Brown throw new IllegalArgumentException("fd must not be null"); 77af67fc65bf113b028ff33e71cd6a45810018c273Jeff Brown } 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (length < 0 && startOffset != 0) { 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException( 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "startOffset must be 0 when using UNKNOWN_LENGTH"); 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFd = fd; 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStartOffset = startOffset; 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLength = length; 85c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey mExtras = extras; 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 87c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The AssetFileDescriptor contains its own ParcelFileDescriptor, which 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in addition to the normal FileDescriptor object also allows you to close 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the descriptor when you are done with it. 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ParcelFileDescriptor getParcelFileDescriptor() { 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mFd; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the FileDescriptor that can be used to read the data in the 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * file. 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public FileDescriptor getFileDescriptor() { 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mFd.getFileDescriptor(); 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the byte offset where this asset entry's data starts. 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long getStartOffset() { 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStartOffset; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 111c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey 112c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey /** 113c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey * Returns any additional details that can be used to interpret the 114c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey * underlying file descriptor. May be null. 115c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey */ 116c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey public Bundle getExtras() { 117c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey return mExtras; 118c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey } 119c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the total number of bytes of this asset entry's data. May be 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #UNKNOWN_LENGTH} if the asset extends to the end of the file. 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the AssetFileDescriptor was constructed with {@link #UNKNOWN_LENGTH}, 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this will use {@link ParcelFileDescriptor#getStatSize() 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ParcelFileDescriptor.getStatSize()} to find the total size of the file, 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * returning that number if found or {@link #UNKNOWN_LENGTH} if it could 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * not be determined. 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getDeclaredLength() 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long getLength() { 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mLength >= 0) { 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mLength; 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long len = mFd.getStatSize(); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return len >= 0 ? len : UNKNOWN_LENGTH; 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the actual number of bytes that were declared when the 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * AssetFileDescriptor was constructed. Will be 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #UNKNOWN_LENGTH} if the length was not declared, meaning data 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should be read to the end of the file. 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getDeclaredLength() 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long getDeclaredLength() { 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mLength; 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Convenience for calling <code>getParcelFileDescriptor().close()</code>. 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15432559e191fd2580393d77161a32bcaeaa49fbe5dJeff Sharkey @Override 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void close() throws IOException { 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFd.close(); 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 158963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert 159963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert /** 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create and return a new auto-close input stream for this asset. This 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will either return a full asset {@link AutoCloseInputStream}, or 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * an underlying {@link ParcelFileDescriptor.AutoCloseInputStream 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ParcelFileDescriptor.AutoCloseInputStream} depending on whether the 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the object represents a complete file or sub-section of a file. You 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should only call this once for a particular asset. 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public FileInputStream createInputStream() throws IOException { 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mLength < 0) { 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new ParcelFileDescriptor.AutoCloseInputStream(mFd); 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new AutoCloseInputStream(this); 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create and return a new auto-close output stream for this asset. This 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will either return a full asset {@link AutoCloseOutputStream}, or 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * an underlying {@link ParcelFileDescriptor.AutoCloseOutputStream 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ParcelFileDescriptor.AutoCloseOutputStream} depending on whether the 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the object represents a complete file or sub-section of a file. You 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should only call this once for a particular asset. 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public FileOutputStream createOutputStream() throws IOException { 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mLength < 0) { 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new ParcelFileDescriptor.AutoCloseOutputStream(mFd); 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new AutoCloseOutputStream(this); 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "{AssetFileDescriptor: " + mFd 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " start=" + mStartOffset + " len=" + mLength + "}"; 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * An InputStream you can create on a ParcelFileDescriptor, which will 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * take care of calling {@link ParcelFileDescriptor#close 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ParcelFileDescritor.close()} for you when the stream is closed. 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static class AutoCloseInputStream 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project extends ParcelFileDescriptor.AutoCloseInputStream { 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mRemaining; 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AutoCloseInputStream(AssetFileDescriptor fd) throws IOException { 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(fd.getParcelFileDescriptor()); 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.skip(fd.getStartOffset()); 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRemaining = (int)fd.getLength(); 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int available() throws IOException { 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mRemaining >= 0 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ? (mRemaining < 0x7fffffff ? (int)mRemaining : 0x7fffffff) 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : super.available(); 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int read() throws IOException { 219212799338d7be336e73eb65de3dcd0338a705a11Bjorn Bringert byte[] buffer = new byte[1]; 220212799338d7be336e73eb65de3dcd0338a705a11Bjorn Bringert int result = read(buffer, 0, 1); 221212799338d7be336e73eb65de3dcd0338a705a11Bjorn Bringert return result == -1 ? -1 : buffer[0] & 0xff; 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int read(byte[] buffer, int offset, int count) throws IOException { 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRemaining >= 0) { 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRemaining == 0) return -1; 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (count > mRemaining) count = (int)mRemaining; 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int res = super.read(buffer, offset, count); 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (res >= 0) mRemaining -= res; 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return res; 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.read(buffer, offset, count); 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int read(byte[] buffer) throws IOException { 239212799338d7be336e73eb65de3dcd0338a705a11Bjorn Bringert return read(buffer, 0, buffer.length); 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long skip(long count) throws IOException { 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRemaining >= 0) { 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRemaining == 0) return -1; 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (count > mRemaining) count = mRemaining; 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long res = super.skip(count); 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (res >= 0) mRemaining -= res; 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return res; 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.skip(count); 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void mark(int readlimit) { 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRemaining >= 0) { 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Not supported. 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.mark(readlimit); 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean markSupported() { 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRemaining >= 0) { 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.markSupported(); 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public synchronized void reset() throws IOException { 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRemaining >= 0) { 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Not supported. 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.reset(); 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 281963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert 282963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert /** 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * An OutputStream you can create on a ParcelFileDescriptor, which will 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * take care of calling {@link ParcelFileDescriptor#close 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ParcelFileDescritor.close()} for you when the stream is closed. 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static class AutoCloseOutputStream 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project extends ParcelFileDescriptor.AutoCloseOutputStream { 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mRemaining; 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AutoCloseOutputStream(AssetFileDescriptor fd) throws IOException { 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(fd.getParcelFileDescriptor()); 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fd.getParcelFileDescriptor().seekTo(fd.getStartOffset()) < 0) { 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IOException("Unable to seek"); 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRemaining = (int)fd.getLength(); 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void write(byte[] buffer, int offset, int count) throws IOException { 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRemaining >= 0) { 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRemaining == 0) return; 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (count > mRemaining) count = (int)mRemaining; 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.write(buffer, offset, count); 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRemaining -= count; 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.write(buffer, offset, count); 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void write(byte[] buffer) throws IOException { 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRemaining >= 0) { 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRemaining == 0) return; 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int count = buffer.length; 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (count > mRemaining) count = (int)mRemaining; 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.write(buffer); 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRemaining -= count; 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.write(buffer); 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void write(int oneByte) throws IOException { 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRemaining >= 0) { 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRemaining == 0) return; 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.write(oneByte); 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRemaining--; 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.write(oneByte); 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 338c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Parcelable interface */ 340c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey @Override 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int describeContents() { 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mFd.describeContents(); 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 345c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey @Override 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void writeToParcel(Parcel out, int flags) { 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFd.writeToParcel(out, flags); 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.writeLong(mStartOffset); 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.writeLong(mLength); 350c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey if (mExtras != null) { 351c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey out.writeInt(1); 352c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey out.writeBundle(mExtras); 353c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey } else { 354c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey out.writeInt(0); 355c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey } 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor(Parcel src) { 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFd = ParcelFileDescriptor.CREATOR.createFromParcel(src); 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStartOffset = src.readLong(); 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLength = src.readLong(); 362c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey if (src.readInt() != 0) { 363c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey mExtras = src.readBundle(); 364c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey } else { 365c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey mExtras = null; 366c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey } 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 368c1c8f3f97d344a24bfddcb56a8be05e7e2fabe9eJeff Sharkey 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final Parcelable.Creator<AssetFileDescriptor> CREATOR 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = new Parcelable.Creator<AssetFileDescriptor>() { 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AssetFileDescriptor createFromParcel(Parcel in) { 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new AssetFileDescriptor(in); 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AssetFileDescriptor[] newArray(int size) { 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new AssetFileDescriptor[size]; 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 378963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 380