| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.apksig.internal.util; |
| |
| import com.android.apksig.util.DataSink; |
| |
| import java.io.IOException; |
| import java.io.RandomAccessFile; |
| import java.nio.ByteBuffer; |
| import java.nio.channels.FileChannel; |
| |
| /** |
| * {@link DataSink} which outputs received data into the associated file, sequentially. |
| */ |
| public class RandomAccessFileDataSink implements DataSink { |
| |
| private final RandomAccessFile mFile; |
| private final FileChannel mFileChannel; |
| private long mPosition; |
| |
| /** |
| * Constructs a new {@code RandomAccessFileDataSink} which stores output starting from the |
| * beginning of the provided file. |
| */ |
| public RandomAccessFileDataSink(RandomAccessFile file) { |
| this(file, 0); |
| } |
| |
| /** |
| * Constructs a new {@code RandomAccessFileDataSink} which stores output starting from the |
| * specified position of the provided file. |
| */ |
| public RandomAccessFileDataSink(RandomAccessFile file, long startPosition) { |
| if (file == null) { |
| throw new NullPointerException("file == null"); |
| } |
| if (startPosition < 0) { |
| throw new IllegalArgumentException("startPosition: " + startPosition); |
| } |
| mFile = file; |
| mFileChannel = file.getChannel(); |
| mPosition = startPosition; |
| } |
| |
| @Override |
| public void consume(byte[] buf, int offset, int length) throws IOException { |
| if (length == 0) { |
| return; |
| } |
| |
| synchronized (mFile) { |
| mFile.seek(mPosition); |
| mFile.write(buf, offset, length); |
| mPosition += length; |
| } |
| } |
| |
| @Override |
| public void consume(ByteBuffer buf) throws IOException { |
| int length = buf.remaining(); |
| if (length == 0) { |
| return; |
| } |
| |
| synchronized (mFile) { |
| mFile.seek(mPosition); |
| while (buf.hasRemaining()) { |
| mFileChannel.write(buf); |
| } |
| mPosition += length; |
| } |
| } |
| } |