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 
17 package com.android.dx.dex.file;
18 
19 import com.android.dex.SizeOf;
20 import com.android.dx.rop.cst.CstString;
21 import com.android.dx.util.AnnotatedOutput;
22 import com.android.dx.util.Hex;
23 
24 /**
25  * Representation of a string inside a Dalvik file.
26  */
27 public 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      */
StringIdItem(CstString value)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
equals(Object other)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
hashCode()62     public int hashCode() {
63         return value.hashCode();
64     }
65 
66     /** {@inheritDoc} */
67     @Override
compareTo(Object other)68     public int compareTo(Object other) {
69         StringIdItem otherString = (StringIdItem) other;
70         return value.compareTo(otherString.value);
71     }
72 
73     /** {@inheritDoc} */
74     @Override
itemType()75     public ItemType itemType() {
76         return ItemType.TYPE_STRING_ID_ITEM;
77     }
78 
79     /** {@inheritDoc} */
80     @Override
writeSize()81     public int writeSize() {
82         return SizeOf.STRING_ID_ITEM;
83     }
84 
85     /** {@inheritDoc} */
86     @Override
addContents(DexFile file)87     public void addContents(DexFile file) {
88         if (data == null) {
89             // The string data hasn't yet been added, so add it.
90             MixedItemSection stringData = file.getStringData();
91             data = new StringDataItem(value);
92             stringData.add(data);
93         }
94     }
95 
96     /** {@inheritDoc} */
97     @Override
writeTo(DexFile file, AnnotatedOutput out)98     public void writeTo(DexFile file, AnnotatedOutput out) {
99         int dataOff = data.getAbsoluteOffset();
100 
101         if (out.annotates()) {
102             out.annotate(0, indexString() + ' ' + value.toQuoted(100));
103             out.annotate(4, "  string_data_off: " + Hex.u4(dataOff));
104         }
105 
106         out.writeInt(dataOff);
107     }
108 
109     /**
110      * Gets the string value.
111      *
112      * @return {@code non-null;} the value
113      */
getValue()114     public CstString getValue() {
115         return value;
116     }
117 
118     /**
119      * Gets the associated data object for this instance, if known.
120      *
121      * @return {@code null-ok;} the associated data object or {@code null}
122      * if not yet known
123      */
getData()124     public StringDataItem getData() {
125         return data;
126     }
127 }
128