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.SizeOf;
20import com.android.dx.rop.cst.CstString;
21import com.android.dx.util.AnnotatedOutput;
22import com.android.dx.util.Hex;
23
24/**
25 * Representation of a string inside a Dalvik file.
26 */
27public final class StringIdItem
28        extends IndexedItem implements Comparable {
29    /** {@code non-null;} the string value */
30    private final CstString value;
31
32    /** {@code null-ok;} associated string data object, if known */
33    private StringDataItem data;
34
35    /**
36     * Constructs an instance.
37     *
38     * @param value {@code non-null;} the string value
39     */
40    public StringIdItem(CstString value) {
41        if (value == null) {
42            throw new NullPointerException("value == null");
43        }
44
45        this.value = value;
46        this.data = null;
47    }
48
49    /** {@inheritDoc} */
50    @Override
51    public boolean equals(Object other) {
52        if (!(other instanceof StringIdItem)) {
53            return false;
54        }
55
56        StringIdItem otherString = (StringIdItem) other;
57        return value.equals(otherString.value);
58    }
59
60    /** {@inheritDoc} */
61    @Override
62    public int hashCode() {
63        return value.hashCode();
64    }
65
66    /** {@inheritDoc} */
67    public int compareTo(Object other) {
68        StringIdItem otherString = (StringIdItem) other;
69        return value.compareTo(otherString.value);
70    }
71
72    /** {@inheritDoc} */
73    @Override
74    public ItemType itemType() {
75        return ItemType.TYPE_STRING_ID_ITEM;
76    }
77
78    /** {@inheritDoc} */
79    @Override
80    public int writeSize() {
81        return SizeOf.STRING_ID_ITEM;
82    }
83
84    /** {@inheritDoc} */
85    @Override
86    public void addContents(DexFile file) {
87        if (data == null) {
88            // The string data hasn't yet been added, so add it.
89            MixedItemSection stringData = file.getStringData();
90            data = new StringDataItem(value);
91            stringData.add(data);
92        }
93    }
94
95    /** {@inheritDoc} */
96    @Override
97    public void writeTo(DexFile file, AnnotatedOutput out) {
98        int dataOff = data.getAbsoluteOffset();
99
100        if (out.annotates()) {
101            out.annotate(0, indexString() + ' ' + value.toQuoted(100));
102            out.annotate(4, "  string_data_off: " + Hex.u4(dataOff));
103        }
104
105        out.writeInt(dataOff);
106    }
107
108    /**
109     * Gets the string value.
110     *
111     * @return {@code non-null;} the value
112     */
113    public CstString getValue() {
114        return value;
115    }
116
117    /**
118     * Gets the associated data object for this instance, if known.
119     *
120     * @return {@code null-ok;} the associated data object or {@code null}
121     * if not yet known
122     */
123    public StringDataItem getData() {
124        return data;
125    }
126}
127