1/*
2 * Copyright (C) 2014 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
17package dexfuzz.rawdex;
18
19import dexfuzz.Log;
20
21import java.io.IOException;
22
23public class EncodedMethod implements RawDexObject {
24  public int methodIdxDiff;
25  public int accessFlags;
26  public Offset codeOff;
27
28  @Override
29  public void read(DexRandomAccessFile file) throws IOException {
30    methodIdxDiff = file.readUleb128();
31    accessFlags = file.readUleb128();
32    codeOff = file.getOffsetTracker().getNewOffset(file.readUleb128());
33    if (isNative()) {
34      Log.errorAndQuit("Sorry, DEX files with native methods are not supported yet.");
35    }
36  }
37
38  @Override
39  public void write(DexRandomAccessFile file) throws IOException {
40    file.writeUleb128(methodIdxDiff);
41    file.writeUleb128(accessFlags);
42    file.getOffsetTracker().tryToWriteOffset(codeOff, file, true /* ULEB128 */);
43  }
44
45  @Override
46  public void incrementIndex(IndexUpdateKind kind, int insertedIdx) {
47    // Do nothing.
48    // NB: our idx_diff is handled in ClassDataItem...
49  }
50
51  public boolean isStatic() {
52    return ((accessFlags & Flag.ACC_STATIC.getValue()) != 0);
53  }
54
55  public boolean isNative() {
56    return ((accessFlags & Flag.ACC_NATIVE.getValue()) != 0);
57  }
58
59  /**
60   * Set/unset the static flag for this EncodedMethod.
61   */
62  public void setStatic(boolean turnOn) {
63    if (turnOn) {
64      accessFlags |= Flag.ACC_STATIC.getValue();
65    } else {
66      accessFlags &= ~(Flag.ACC_STATIC.getValue());
67    }
68  }
69
70  private static enum Flag {
71    ACC_PUBLIC(0x1),
72    ACC_PRIVATE(0x2),
73    ACC_PROTECTED(0x4),
74    ACC_STATIC(0x8),
75    ACC_FINAL(0x10),
76    ACC_SYNCHRONIZED(0x20),
77    ACC_VARARGS(0x80),
78    ACC_NATIVE(0x100),
79    ACC_ABSTRACT(0x400),
80    ACC_STRICT(0x800),
81    ACC_SYNTHETIC(0x1000),
82    ACC_ENUM(0x4000),
83    ACC_CONSTRUCTOR(0x10000);
84
85    private int value;
86
87    private Flag(int value) {
88      this.value = value;
89    }
90
91    public int getValue() {
92      return value;
93    }
94  }
95}
96