FileChannelImpl.java revision 2620ff9a08ce7fc6d66b60784b1eecd78eb001ba
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 19eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * Android Notice 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * In this class the address length was changed from long to int. 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This is due to performance optimizations for the device. 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Also this class was copied from a newer version of harmony. 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage org.apache.harmony.nio.internal; 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.Closeable; 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.FileDescriptor; 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.ByteBuffer; 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.MappedByteBuffer; 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.ClosedChannelException; 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.FileChannel; 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.FileLock; 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.NonWritableChannelException; 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.ReadableByteChannel; 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.WritableByteChannel; 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.platform.IFileSystem; 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.platform.Platform; 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.platform.PlatformAddress; 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.platform.PlatformAddressFactory; 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The file channel impl class is the bridge between the logical channels 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * described by the NIO channel framework, and the file system implementation 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * provided by the port layer. 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This class is non-API, but implements the API of the FileChannel interface. 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic abstract class FileChannelImpl extends FileChannel { 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Reference to the portable file system code. 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final IFileSystem fileSystem = Platform.getFileSystem(); 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final int ALLOC_GRANULARITY; 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static { 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ALLOC_GRANULARITY = fileSystem.getAllocGranularity(); 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IOException e) { 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new Error(e); 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Handle to the open file 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final int handle; 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // The object that will track all outstanding locks on this channel. 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final LockManager lockManager = new LockManager(); 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 73eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson private static class RepositioningLock {} 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final Object repositioningLock = new RepositioningLock(); 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final Object stream; 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Create a new file channel implementation class that wraps the given file 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * handle and operates in the specified mode. 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public FileChannelImpl(Object stream, int handle) { 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(); 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.handle = handle; 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.stream = stream; 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Helper method to throw an exception if the channel is already closed. 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Note that we don't bother to synchronize on this test since the file may 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * be closed by operations beyond our control anyways. 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected final void openCheck() throws ClosedChannelException { 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!isOpen()) { 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new ClosedChannelException(); 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (non-Javadoc) 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.nio.channels.spi.AbstractInterruptibleChannel#implCloseChannel() 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected void implCloseChannel() throws IOException { 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (stream instanceof Closeable) { 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ((Closeable) stream).close(); 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected FileLock basicLock(long position, long size, boolean shared, 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean wait) throws IOException { 11303c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (position < 0 || size < 0) { 11403c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IllegalArgumentException("Lock position and size must be non-negative"); 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 11603c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes int lockType = shared ? IFileSystem.SHARED_LOCK_TYPE : IFileSystem.EXCLUSIVE_LOCK_TYPE; 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project FileLock pendingLock = new FileLockImpl(this, position, size, shared); 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lockManager.addLock(pendingLock); 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (fileSystem.lock(handle, position, size, lockType, wait)) { 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return pendingLock; 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Lock acquisition failed 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lockManager.removeLock(pendingLock); 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Acquire a lock on the receiver, blocks if the lock cannot be obtained 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * immediately. 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.nio.channels.FileChannel#lock(long, long, boolean) 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final FileLock lock(long position, long size, boolean shared) 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException { 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project openCheck(); 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project FileLock resultLock = null; 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project { 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean completed = false; 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project begin(); 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project resultLock = basicLock(position, size, shared, true); 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project completed = true; 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project end(completed); 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return resultLock; 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Attempts to acquire the given lock, but does not block. If the lock 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cannot be acquired the method returns null. 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.nio.channels.FileChannel#tryLock(long, long, boolean) 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final FileLock tryLock(long position, long size, boolean shared) 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException { 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project openCheck(); 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return basicLock(position, size, shared, false); 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Non-API method to release a given lock on a file channel. Assumes that 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the lock will mark itself invalid after successful unlocking. 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project void release(FileLock lock) throws IOException { 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project openCheck(); 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project fileSystem.unlock(handle, lock.position(), lock.size()); 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lockManager.removeLock(lock); 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 174edc2dae4345ea305f092ade00419685d77c8eee9Elliott Hughes @Override public void force(boolean metadata) throws IOException { 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project openCheck(); 176edc2dae4345ea305f092ade00419685d77c8eee9Elliott Hughes fileSystem.fflush(handle, metadata); 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 179edc2dae4345ea305f092ade00419685d77c8eee9Elliott Hughes public abstract MappedByteBuffer map(MapMode mode, long position, long size) throws IOException; 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected final MappedByteBuffer mapImpl(int mapMode, long position, 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long size) throws IOException { 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (position + size > size()) { 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project fileSystem.truncate(handle, position + size); 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long alignment = position - position % ALLOC_GRANULARITY; 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int offset = (int) (position - alignment); 188eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson PlatformAddress address = PlatformAddressFactory.allocMap(handle, 189eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson alignment, size + offset, mapMode); 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project MappedByteBuffer buffer = null; 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buffer = MappedByteBufferFactory.getBuffer(address, mapMode, size, 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project offset); 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (Exception e) { 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IOException(e.getMessage()); 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return buffer; 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the current file position. 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public long position() throws IOException { 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project openCheck(); 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return fileSystem.seek(handle, 0L, IFileSystem.SEEK_CUR); 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Sets the file pointer. 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public FileChannel position(long newPosition) throws IOException { 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project openCheck(); 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (newPosition < 0) { 21403c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IllegalArgumentException("New position must be non-negative"); 215eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson } 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (repositioningLock) { 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project fileSystem.seek(handle, newPosition, IFileSystem.SEEK_SET); 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return this; 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int read(ByteBuffer buffer, long position) throws IOException { 2242620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes FileChannelImpl.checkWritable(buffer); 225eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson if (position < 0) { 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project openCheck(); 229eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson if (!buffer.hasRemaining()) { 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (repositioningLock) { 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int bytesRead = 0; 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long preReadPosition = position(); 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project position(position); 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project bytesRead = read(buffer); 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project position(preReadPosition); 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return bytesRead; 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int read(ByteBuffer buffer) throws IOException { 2462620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes FileChannelImpl.checkWritable(buffer); 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project openCheck(); 248eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson if (!buffer.hasRemaining()) { 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean completed = false; 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int bytesRead = 0; 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (repositioningLock) { 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (buffer.isDirect()) { 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project DirectBuffer directBuffer = (DirectBuffer) buffer; 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int address = directBuffer.getEffectiveAddress().toInt(); 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project begin(); 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 260eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * if (bytesRead <= EOF) dealt by read completed = false; 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project bytesRead = (int) fileSystem.readDirect(handle, address, 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buffer.position(), buffer.remaining()); 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project completed = true; 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project end(completed && bytesRead >= 0); 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project begin(); 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 272eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * if (bytesRead <= EOF) dealt by read completed = false; 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project bytesRead = (int) fileSystem.read(handle, buffer.array(), 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buffer.arrayOffset() + buffer.position(), buffer 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .remaining()); 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project completed = true; 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project end(completed && bytesRead >= 0); 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (bytesRead > 0) { 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buffer.position(buffer.position() + bytesRead); 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return bytesRead; 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 289d85168bd730e513cb0bd561030da3f7ea5044725Elliott Hughes public long read(ByteBuffer[] buffers, int offset, int length) throws IOException { 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (offset < 0 || length < 0 || offset + length > buffers.length) { 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IndexOutOfBoundsException(); 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project openCheck(); 2942620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes int count = FileChannelImpl.calculateTotalRemaining(buffers, offset, length, true); 295d85168bd730e513cb0bd561030da3f7ea5044725Elliott Hughes if (count == 0) { 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ByteBuffer[] directBuffers = new ByteBuffer[length]; 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int[] handles = new int[length]; 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int[] offsets = new int[length]; 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int[] lengths = new int[length]; 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < length; i++) { 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ByteBuffer buffer = buffers[i + offset]; 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!buffer.isDirect()) { 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buffer = ByteBuffer.allocateDirect(buffer.remaining()); 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project directBuffers[i] = buffer; 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project offsets[i] = 0; 308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project offsets[i] = buffer.position(); 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project handles[i] = ((DirectBuffer) buffer).getEffectiveAddress().toInt(); 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lengths[i] = buffer.remaining(); 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long bytesRead = 0; 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project { 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean completed = false; 317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project begin(); 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (repositioningLock) { 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project bytesRead = fileSystem.readv(handle, handles, offsets, 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lengths, length); 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project completed = true; 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 326eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * if (bytesRead < EOF) //dealt by readv? completed = false; 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project end(completed); 330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int end = offset + length; 333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long bytesRemaining = bytesRead; 334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = offset; i < end && bytesRemaining > 0; i++) { 335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (buffers[i].isDirect()) { 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (lengths[i] < bytesRemaining) { 337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int pos = buffers[i].limit(); 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buffers[i].position(pos); 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project bytesRemaining -= lengths[i]; 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int pos = (int) bytesRemaining; 342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buffers[i].position(pos); 343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ByteBuffer buf = directBuffers[i - offset]; 347eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson if (bytesRemaining < buf.remaining()) { 348eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson // this is the last step. 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int pos = buf.position(); 350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buffers[i].put(buf); 351eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson buffers[i].position(pos + (int) bytesRemaining); 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project bytesRemaining = 0; 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project bytesRemaining -= buf.remaining(); 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buffers[i].put(buf); 356eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson } 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return bytesRead; 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the current file size, as an integer number of bytes. 364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public long size() throws IOException { 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project openCheck(); 367a008cf079f1cb812ec42a4fcc941fe170cc9b40dElliott Hughes return fileSystem.length(handle); 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public long transferFrom(ReadableByteChannel src, long position, long count) 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException { 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project openCheck(); 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!src.isOpen()) { 374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new ClosedChannelException(); 375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 376eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson if (position < 0 || count < 0 || count > Integer.MAX_VALUE) { 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 379eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson if (position > size()) { 380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 382eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson 383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ByteBuffer buffer = null; 384eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (src instanceof FileChannel) { 387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project FileChannel fileSrc = (FileChannel) src; 388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long size = fileSrc.size(); 389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long filePosition = fileSrc.position(); 390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project count = Math.min(count, size - filePosition); 391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buffer = fileSrc.map(MapMode.READ_ONLY, filePosition, count); 392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project fileSrc.position(filePosition + count); 393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buffer = ByteBuffer.allocateDirect((int) count); 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project src.read(buffer); 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buffer.flip(); 397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return write(buffer, position); 399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // unmap the buffer 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (buffer != null) { 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // all children of FileChannelImpl currently returns 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // an instance of DirectBuffer from map() method 404eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson ((DirectBuffer) buffer).free(); 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public long transferTo(long position, long count, WritableByteChannel target) 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException { 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project openCheck(); 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!target.isOpen()) { 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new ClosedChannelException(); 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (target instanceof ReadOnlyFileChannel) { 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NonWritableChannelException(); 417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 418eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson if (position < 0 || count < 0) { 419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 421eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson 422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (count == 0 || position >= size()) { 423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ByteBuffer buffer = null; 426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project count = Math.min(count, size() - position); 427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (target instanceof SocketChannelImpl) { 428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // only socket can be transfered by system call 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return kernelTransfer(handle, ((SocketChannelImpl) target).getFD(), 430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project position, count); 431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 432eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buffer = map(MapMode.READ_ONLY, position, count); 435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return target.write(buffer); 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // unmap the buffer 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (buffer != null) { 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // all children of FileChannelImpl currently returns 440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // an instance of DirectBuffer from map() method 441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ((DirectBuffer) buffer).free(); 442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private long kernelTransfer(int l, FileDescriptor fd, long position, 447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long count) throws IOException { 448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean completed = false; 449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project begin(); 451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long ret = fileSystem.transfer(l, fd, position, count); 452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project completed = true; 453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return ret; 454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project end(completed); 456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public FileChannel truncate(long size) throws IOException { 460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project openCheck(); 461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (size < 0) { 462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (size < size()) { 465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (repositioningLock) { 466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long position = position(); 467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project fileSystem.truncate(handle, size); 468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * FIXME: currently the port library always modifies the 470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * position to given size. not sure it is a bug or intended 471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * behaviour, so I always reset the position to proper value as 472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Java Spec. 473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project position(position > size ? size : position); 475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return this; 478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (non-Javadoc) 482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.nio.channels.WritableByteChannel#write(java.nio.ByteBuffer) 484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int write(ByteBuffer buffer, long position) throws IOException { 487eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson if (null == buffer) { 488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 490eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson if (position < 0) { 491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project openCheck(); 494eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson if (!buffer.hasRemaining()) { 495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int bytesWritten = 0; 498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (repositioningLock) { 499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long preWritePosition = position(); 500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project position(position); 501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project bytesWritten = writeImpl(buffer); 503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project position(preWritePosition); 505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return bytesWritten; 508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int write(ByteBuffer buffer) throws IOException { 511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project openCheck(); 512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return writeImpl(buffer); 513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private int writeImpl(ByteBuffer buffer) throws IOException { 516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int bytesWritten; 517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean completed = false; 518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (repositioningLock) { 519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (buffer.isDirect()) { 520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project DirectBuffer directBuffer = (DirectBuffer) buffer; 521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int address = directBuffer.getEffectiveAddress().toInt(); 522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project begin(); 524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project bytesWritten = (int) fileSystem.writeDirect(handle, 525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project address, buffer.position(), buffer.remaining()); 526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project completed = true; 527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project end(completed); 529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project begin(); 533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project bytesWritten = (int) fileSystem.write(handle, buffer 534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .array(), buffer.arrayOffset() + buffer.position(), 535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buffer.remaining()); 536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project completed = true; 537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project end(completed); 539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (bytesWritten > 0) { 542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buffer.position(buffer.position() + bytesWritten); 543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return bytesWritten; 546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 5482620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes public long write(ByteBuffer[] buffers, int offset, int length) throws IOException { 549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (offset < 0 || length < 0 || (offset + length) > buffers.length) { 550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IndexOutOfBoundsException(); 551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project openCheck(); 5532620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes int count = FileChannelImpl.calculateTotalRemaining(buffers, offset, length, false); 554d85168bd730e513cb0bd561030da3f7ea5044725Elliott Hughes if (count == 0) { 555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int[] handles = new int[length]; 558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int[] offsets = new int[length]; 559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int[] lengths = new int[length]; 560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // BEGIN android-changed 561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // list of allocated direct ByteBuffers to prevent them from being GC-ed 562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project DirectBuffer[] allocatedBufs = new DirectBuffer[length]; 563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < length; i++) { 565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ByteBuffer buffer = buffers[i + offset]; 566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!buffer.isDirect()) { 567d85168bd730e513cb0bd561030da3f7ea5044725Elliott Hughes ByteBuffer directBuffer = ByteBuffer.allocateDirect(buffer.remaining()); 568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project directBuffer.put(buffer); 569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project directBuffer.flip(); 570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buffer = directBuffer; 571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project allocatedBufs[i] = (DirectBuffer) directBuffer; 572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project offsets[i] = 0; 573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project offsets[i] = buffer.position(); 575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project allocatedBufs[i] = null; 576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project handles[i] = ((DirectBuffer) buffer).getEffectiveAddress().toInt(); 578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lengths[i] = buffer.remaining(); 579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // END android-changed 581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long bytesWritten = 0; 583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean completed = false; 584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (repositioningLock) { 585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project begin(); 587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project bytesWritten = fileSystem.writev(handle, handles, offsets, 588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lengths, length); 589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project completed = true; 590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project end(completed); 592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // BEGIN android-added 593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // free temporary direct buffers 594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < length; ++i) { 595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (allocatedBufs[i] != null) { 596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project allocatedBufs[i].free(); 597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // END android-added 600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long bytesRemaining = bytesWritten; 604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = offset; i < length + offset; i++) { 605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (bytesRemaining > buffers[i].remaining()) { 606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int pos = buffers[i].limit(); 607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buffers[i].position(pos); 608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project bytesRemaining -= buffers[i].remaining(); 609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int pos = buffers[i].position() + (int) bytesRemaining; 611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buffers[i].position(pos); 612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return bytesWritten; 616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 617eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson 6182620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes static void checkWritable(ByteBuffer buffer) { 6192620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes if (buffer.isReadOnly()) { 6202620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes throw new IllegalArgumentException("read-only buffer"); 6212620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes } 6222620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes } 6232620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes 6242620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes /** 6252620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes * @param copyingIn true if we're copying data into the buffers (typically 6262620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes * because the caller is a file/network read operation), false if we're 6272620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes * copying data out of the buffers (for a file/network write operation). 6282620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes */ 6292620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes static int calculateTotalRemaining(ByteBuffer[] buffers, int offset, int length, boolean copyingIn) { 630d85168bd730e513cb0bd561030da3f7ea5044725Elliott Hughes int count = 0; 631d85168bd730e513cb0bd561030da3f7ea5044725Elliott Hughes for (int i = offset; i < offset + length; ++i) { 632d85168bd730e513cb0bd561030da3f7ea5044725Elliott Hughes count += buffers[i].remaining(); 6332620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes if (copyingIn) { 6342620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes checkWritable(buffers[i]); 6352620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes } 636d85168bd730e513cb0bd561030da3f7ea5044725Elliott Hughes } 637d85168bd730e513cb0bd561030da3f7ea5044725Elliott Hughes return count; 638d85168bd730e513cb0bd561030da3f7ea5044725Elliott Hughes } 639d85168bd730e513cb0bd561030da3f7ea5044725Elliott Hughes 640eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson public int getHandle() { 641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return handle; 642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 644