Home | History | Annotate | Download | only in build
      1 /*
      2  * Copyright (C) 2008 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 util.build;
     18 
     19 import dasm.DAsm;
     20 import dasm.DasmError;
     21 import dasm.Utils;
     22 
     23 import java.io.BufferedReader;
     24 import java.io.Closeable;
     25 import java.io.File;
     26 import java.io.FileInputStream;
     27 import java.io.FileOutputStream;
     28 import java.io.FileWriter;
     29 import java.io.IOException;
     30 import java.io.InputStreamReader;
     31 import java.io.Reader;
     32 
     33 class DasmBuildStep extends BuildStep {
     34 
     35 
     36     boolean generate_linenum = false;
     37 
     38     DasmBuildStep(BuildFile inputFile, BuildFile outputFile) {
     39         super(inputFile, outputFile);
     40 
     41     }
     42 
     43     @Override
     44     boolean build() {
     45         if (super.build()) {
     46             return assemble(inputFile.fileName);
     47         }
     48         return false;
     49     }
     50 
     51     private static Reader createReader(String fname) throws IOException {
     52         FileInputStream fs = new FileInputStream(fname);
     53         InputStreamReader ir;
     54         ir = new InputStreamReader(fs);
     55         return new BufferedReader(ir);
     56     }
     57 
     58     private boolean assemble(File file) {
     59         DAsm dAsm = new DAsm();
     60         String fname = file.getAbsolutePath();
     61 
     62         // read and parse .d file
     63         Reader inp = null;
     64         try {
     65             inp = createReader(fname);
     66             dAsm.readD(inp, new File(fname).getName(), generate_linenum);
     67             close(inp);
     68         } catch(DasmError e) {
     69             if(BuildDalvikSuite.DEBUG)
     70                 e.printStackTrace();
     71             System.err.println("DASM Error: " + e.getMessage());
     72         } catch(Exception e) {
     73              if(BuildDalvikSuite.DEBUG)
     74                  e.printStackTrace();
     75              System.err.println("Exception <" + e.getClass().getName() + ">" + e.getMessage() +
     76                          " while reading and parsing " + fname);
     77              return false;
     78 
     79         }
     80         finally {
     81             close(inp);
     82         }
     83 
     84         if(dAsm.errorCount() > 0) {
     85             System.err.println("Found " + dAsm.errorCount() + " errors " +
     86                     " while reading and parsing " + fname);
     87                 return false;
     88         }
     89 
     90         String class_path[] = Utils.getClassFieldFromString(dAsm.getClassName());
     91         String class_name = class_path[1];
     92 
     93         // determine where to place .dex file
     94         String dest_dir = outputFile.folder.getAbsolutePath();
     95         if (class_path[0] != null) {
     96             String class_dir = class_path[0].replaceAll("/|\\.", Character.toString(File.separatorChar));
     97             if (dest_dir != null) {
     98                 dest_dir = dest_dir + File.separator + class_dir;
     99             } else {
    100                 dest_dir = class_dir;
    101             }
    102         }
    103 
    104         File out_file = null;
    105 
    106         if (dest_dir == null) {
    107             out_file = new File(class_name + ".dex");
    108         } else {
    109             out_file = new File(dest_dir, class_name + ".dex");
    110 
    111             // check that dest_dir exists
    112             File dest = new File(dest_dir);
    113             if (!dest.exists()) {
    114                 dest.mkdirs();
    115             }
    116 
    117             if (!dest.isDirectory()) {
    118                 System.err.println("Cannot create directory " + dest_dir);
    119                 return false;
    120             }
    121         }
    122 
    123         // write output
    124         FileOutputStream outp = null;
    125 
    126         try {
    127             outp = new FileOutputStream(out_file);
    128             dAsm.write(outp, null);
    129         } catch(Exception e) {
    130                 if(BuildDalvikSuite.DEBUG)
    131                 e.printStackTrace();
    132                 System.err.println("Exception <" + e.getClass().getName() + ">" + e.getMessage() +
    133                         " while writing " + out_file.getPath());
    134 
    135                 close(outp);
    136 
    137                 out_file.delete();
    138 
    139                 return false;
    140        }
    141        finally {
    142            close(outp);
    143        }
    144 
    145        return true;
    146     }
    147 
    148     private static void close(Closeable c) {
    149         if(c == null)
    150             return;
    151         try {
    152             c.close();
    153         } catch(IOException e) {
    154 
    155         }
    156     }
    157 
    158     @Override
    159     public boolean equals(Object obj) {
    160         if (super.equals(obj)) {
    161             DasmBuildStep other = (DasmBuildStep) obj;
    162 
    163             return inputFile.equals(other.inputFile)
    164                     && generate_linenum == other.generate_linenum
    165                     && outputFile.equals(other.outputFile);
    166         }
    167         return false;
    168     }
    169 
    170     @Override
    171     public int hashCode() {
    172         return inputFile.hashCode() ^ outputFile.hashCode()
    173                 ^ (generate_linenum ? 31 : 37);
    174     }
    175 }
    176