Home | History | Annotate | Download | only in reader
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package dex.reader;
     18 
     19 import java.io.BufferedInputStream;
     20 import java.io.ByteArrayOutputStream;
     21 import java.io.FileInputStream;
     22 import java.io.IOException;
     23 import java.nio.ByteBuffer;
     24 import java.nio.ByteOrder;
     25 
     26 public final class DexBuffer {
     27 
     28     private ByteBuffer b;
     29 
     30     public DexBuffer(String fileName) throws IOException {
     31 
     32         // FIXME channel? allocate fix size?
     33         FileInputStream fis = null;
     34         try {
     35             fis = new FileInputStream(fileName);
     36 
     37             BufferedInputStream bis = new BufferedInputStream(fis);
     38             ByteArrayOutputStream bos = new ByteArrayOutputStream();
     39             byte[] buf = new byte[1024];
     40             int len;
     41             while ((len = bis.read(buf)) > 0) {
     42                 bos.write(buf, 0, len);
     43             }
     44             byte[] bytes = bos.toByteArray();
     45             initialize(ByteBuffer.wrap(bytes));
     46         } finally {
     47             if (fis != null) {
     48                 fis.close();
     49             }
     50         }
     51     }
     52 
     53     public DexBuffer(byte[] bytes) {
     54         initialize(ByteBuffer.wrap(bytes));
     55     }
     56 
     57     private DexBuffer(ByteBuffer slice) {
     58         initialize(slice);
     59     }
     60 
     61     private void initialize(ByteBuffer buffer) {
     62         b = buffer.asReadOnlyBuffer();
     63         b.clear();
     64         b.order(ByteOrder.LITTLE_ENDIAN);
     65     }
     66 
     67     public void setPosition(int offset) {
     68         b.position(offset);
     69     }
     70 
     71     public void readBytes(byte[] dst) {
     72         b.get(dst, 0, dst.length);
     73     }
     74 
     75     /**
     76      * FIXME make endian dependent
     77      */
     78     public int readUleb128() {
     79         int endValue = 0;
     80         int value = 0;
     81         int nr = 0;
     82         do {
     83             value = (b.get() & 0xFF);
     84             endValue |= ((value & 0x7F) << 7 * nr);// cut away left most bit
     85             nr++;
     86         } while ((value & 0x80) != 0); // highest bit set?
     87         return endValue;
     88     }
     89 
     90     /**
     91      * pre 0 < nBytes <=4
     92      */
     93     public int readInt(int nBytes) {
     94         int endValue = 0;
     95         int tmp = 0;
     96         for (int i = 0; i < nBytes; i++) {
     97             tmp = b.get() & 0xFF;
     98             endValue |= (tmp << i * 8);
     99         }
    100         return endValue;
    101     }
    102 
    103     /**
    104      * pre 0 < nBytes <=1 FIXME: Sign extension
    105      */
    106     public short readShort(int nBytes) {
    107         short endValue = 0;
    108         int tmp = 0;
    109         for (int i = 0; i < nBytes; i++) {
    110             tmp = b.get() & 0xFF;
    111             endValue |= (tmp << i * 8);
    112         }
    113         return endValue;
    114     }
    115 
    116     /**
    117      * pre 0 < nBytes <=1
    118      */
    119     public char readChar(int nBytes) {
    120         char endValue = 0;
    121         int tmp = 0;
    122         for (int i = 0; i < nBytes; i++) {
    123             tmp = b.get() & 0xFF;
    124             endValue |= (tmp << i * 8);
    125         }
    126         return endValue;
    127     }
    128 
    129     /**
    130      * pre 0 < nBytes <=7 FIXME: Sign extension
    131      */
    132     public long readLong(int nBytes) {
    133         long endValue = 0;
    134         int tmp = 0;
    135         for (int i = 0; i < nBytes; i++) {
    136             tmp = b.get() & 0xFF;
    137             endValue |= (tmp << i * 8);
    138         }
    139         return endValue;
    140     }
    141 
    142     /**
    143      * pre 0 < nBytes <=4
    144      */
    145     public float readFloat(int nBytes) {
    146         int bits = readInt(nBytes);
    147         int bytesToMove = (4 - nBytes) * 8;
    148         bits <<= bytesToMove;
    149         return Float.intBitsToFloat(bits);
    150     }
    151 
    152     // returns int form current position
    153     public int readUInt() {
    154         int value = b.getInt();
    155         // assert value >= 0;
    156         return value;
    157     }
    158 
    159     public int readUShort() {
    160         return b.getShort() & 0xFFFF;
    161     }
    162 
    163     // returns byte form current position
    164     public byte readUByte() {
    165         return b.get();
    166     }
    167 
    168     public DexBuffer createCopy() {
    169         return new DexBuffer(b.duplicate());
    170     }
    171 
    172     public double readDouble(int nBytes) {
    173         long bits = readLong(nBytes);
    174         int bytesToMove = (8 - nBytes) * 8;
    175         bits <<= bytesToMove;
    176         return Double.longBitsToDouble(bits);
    177     }
    178 
    179     public void skip(int nBytes) {
    180         b.position(b.position() + nBytes);
    181     }
    182 }
    183