HeaderItem.java revision 333201833d506a3accdeac6ceb7caba8d4b95797
1/*
2 * Copyright (C) 2007 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 com.android.dx.dex.file;
18
19import com.android.dx.dex.DexFormat;
20import com.android.dx.dex.SizeOf;
21import com.android.dx.rop.cst.CstString;
22import com.android.dx.util.AnnotatedOutput;
23import com.android.dx.util.Hex;
24
25/**
26 * File header section of a {@code .dex} file.
27 */
28public final class HeaderItem extends IndexedItem {
29    /**
30     * Constructs an instance.
31     */
32    public HeaderItem() {
33        // This space intentionally left blank.
34    }
35
36    /** {@inheritDoc} */
37    @Override
38    public ItemType itemType() {
39        return ItemType.TYPE_HEADER_ITEM;
40    }
41
42    /** {@inheritDoc} */
43    @Override
44    public int writeSize() {
45        return SizeOf.HEADER_ITEM;
46    }
47
48    /** {@inheritDoc} */
49    @Override
50    public void addContents(DexFile file) {
51        // Nothing to do here.
52    }
53
54    /** {@inheritDoc} */
55    @Override
56    public void writeTo(DexFile file, AnnotatedOutput out) {
57        int mapOff = file.getMap().getFileOffset();
58        Section firstDataSection = file.getFirstDataSection();
59        Section lastDataSection = file.getLastDataSection();
60        int dataOff = firstDataSection.getFileOffset();
61        int dataSize = lastDataSection.getFileOffset() +
62            lastDataSection.writeSize() - dataOff;
63
64        if (out.annotates()) {
65            out.annotate(8, "magic: " + new CstString(DexFormat.MAGIC).toQuoted());
66            out.annotate(4, "checksum");
67            out.annotate(20, "signature");
68            out.annotate(4, "file_size:       " +
69                         Hex.u4(file.getFileSize()));
70            out.annotate(4, "header_size:     " + Hex.u4(SizeOf.HEADER_ITEM));
71            out.annotate(4, "endian_tag:      " + Hex.u4(DexFormat.ENDIAN_TAG));
72            out.annotate(4, "link_size:       0");
73            out.annotate(4, "link_off:        0");
74            out.annotate(4, "map_off:         " + Hex.u4(mapOff));
75        }
76
77        // Write the magic number.
78        for (int i = 0; i < 8; i++) {
79            out.writeByte(DexFormat.MAGIC.charAt(i));
80        }
81
82        // Leave space for the checksum and signature.
83        out.writeZeroes(24);
84
85        out.writeInt(file.getFileSize());
86        out.writeInt(SizeOf.HEADER_ITEM);
87        out.writeInt(DexFormat.ENDIAN_TAG);
88
89        /*
90         * Write zeroes for the link size and data, as the output
91         * isn't a staticly linked file.
92         */
93        out.writeZeroes(8);
94
95        out.writeInt(mapOff);
96
97        // Write out each section's respective header part.
98        file.getStringIds().writeHeaderPart(out);
99        file.getTypeIds().writeHeaderPart(out);
100        file.getProtoIds().writeHeaderPart(out);
101        file.getFieldIds().writeHeaderPart(out);
102        file.getMethodIds().writeHeaderPart(out);
103        file.getClassDefs().writeHeaderPart(out);
104
105        if (out.annotates()) {
106            out.annotate(4, "data_size:       " + Hex.u4(dataSize));
107            out.annotate(4, "data_off:        " + Hex.u4(dataOff));
108        }
109
110        out.writeInt(dataSize);
111        out.writeInt(dataOff);
112    }
113}
114