13271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh/* 23271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh * Copyright (C) 2017 The Android Open Source Project 33271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh * 43271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh * Licensed under the Apache License, Version 2.0 (the "License"); 53271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh * you may not use this file except in compliance with the License. 63271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh * You may obtain a copy of the License at 73271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh * 83271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh * http://www.apache.org/licenses/LICENSE-2.0 93271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh * 103271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh * Unless required by applicable law or agreed to in writing, software 113271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh * distributed under the License is distributed on an "AS IS" BASIS, 123271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh * See the License for the specific language governing permissions and 143271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh * limitations under the License. 153271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh */ 163271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh 173271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsiehpackage android.util.apk; 183271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh 193271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsiehimport java.io.IOException; 203271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsiehimport java.nio.ByteBuffer; 21def64f26c32c0f1ddc72cd2b0d5c9f49338c558aVictor Hsiehimport java.security.DigestException; 223271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh 233271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh/** 243271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh * {@link DataSource} which provides data from a {@link ByteBuffer}. 253271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh */ 263271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsiehclass ByteBufferDataSource implements DataSource { 273271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh /** 283271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh * Underlying buffer. The data is stored between position 0 and the buffer's capacity. 293271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh * The buffer's position is 0 and limit is equal to capacity. 303271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh */ 313271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh private final ByteBuffer mBuf; 323271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh 333271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh ByteBufferDataSource(ByteBuffer buf) { 343271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh // Defensive copy, to avoid changes to mBuf being visible in buf, and to ensure position is 353271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh // 0 and limit == capacity. 363271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh mBuf = buf.slice(); 373271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh } 383271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh 393271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh @Override 403271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh public long size() { 413271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh return mBuf.capacity(); 423271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh } 433271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh 443271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh @Override 453271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh public void feedIntoDataDigester(DataDigester md, long offset, int size) 46def64f26c32c0f1ddc72cd2b0d5c9f49338c558aVictor Hsieh throws IOException, DigestException { 473271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh // There's no way to tell MessageDigest to read data from ByteBuffer from a position 483271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh // other than the buffer's current position. We thus need to change the buffer's 493271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh // position to match the requested offset. 503271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh // 513271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh // In the future, it may be necessary to compute digests of multiple regions in 523271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh // parallel. Given that digest computation is a slow operation, we enable multiple 533271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh // such requests to be fulfilled by this instance. This is achieved by serially 543271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh // creating a new ByteBuffer corresponding to the requested data range and then, 553271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh // potentially concurrently, feeding these buffers into MessageDigest instances. 563271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh ByteBuffer region; 573271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh synchronized (mBuf) { 583271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh mBuf.position(0); 593271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh mBuf.limit((int) offset + size); 603271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh mBuf.position((int) offset); 613271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh region = mBuf.slice(); 623271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh } 633271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh 643271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh md.consume(region); 653271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh } 663271d0452a4f26a6ff4fff42ed2ce5fb8b9ef07bVictor Hsieh} 67