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.dexgen.dex.file;
18 
19 import com.android.dexgen.rop.cst.CstUtf8;
20 import com.android.dexgen.util.AnnotatedOutput;
21 import com.android.dexgen.util.ByteArray;
22 import com.android.dexgen.util.Hex;
23 import com.android.dexgen.util.Leb128Utils;
24 
25 /**
26  * Representation of string data for a particular string, in a Dalvik file.
27  */
28 public final class StringDataItem extends OffsettedItem {
29     /** {@code non-null;} the string value */
30     private final CstUtf8 value;
31 
32     /**
33      * Constructs an instance.
34      *
35      * @param value {@code non-null;} the string value
36      */
StringDataItem(CstUtf8 value)37     public StringDataItem(CstUtf8 value) {
38         super(1, writeSize(value));
39 
40         this.value = value;
41     }
42 
43     /**
44      * Gets the write size for a given value.
45      *
46      * @param value {@code non-null;} the string value
47      * @return {@code >= 2}; the write size, in bytes
48      */
writeSize(CstUtf8 value)49     private static int writeSize(CstUtf8 value) {
50         int utf16Size = value.getUtf16Size();
51 
52         // The +1 is for the '\0' termination byte.
53         return Leb128Utils.unsignedLeb128Size(utf16Size)
54             + value.getUtf8Size() + 1;
55     }
56 
57     /** {@inheritDoc} */
58     @Override
itemType()59     public ItemType itemType() {
60         return ItemType.TYPE_STRING_DATA_ITEM;
61     }
62 
63     /** {@inheritDoc} */
64     @Override
addContents(DexFile file)65     public void addContents(DexFile file) {
66         // Nothing to do here.
67     }
68 
69     /** {@inheritDoc} */
70     @Override
writeTo0(DexFile file, AnnotatedOutput out)71     public void writeTo0(DexFile file, AnnotatedOutput out) {
72         ByteArray bytes = value.getBytes();
73         int utf16Size = value.getUtf16Size();
74 
75         if (out.annotates()) {
76             out.annotate(Leb128Utils.unsignedLeb128Size(utf16Size),
77                     "utf16_size: " + Hex.u4(utf16Size));
78             out.annotate(bytes.size() + 1, value.toQuoted());
79         }
80 
81         out.writeUnsignedLeb128(utf16Size);
82         out.write(bytes);
83         out.writeByte(0);
84     }
85 
86     /** {@inheritDoc} */
87     @Override
toHuman()88     public String toHuman() {
89         return value.toQuoted();
90     }
91 
92     /** {@inheritDoc} */
93     @Override
compareTo0(OffsettedItem other)94     protected int compareTo0(OffsettedItem other) {
95         StringDataItem otherData = (StringDataItem) other;
96 
97         return value.compareTo(otherData.value);
98     }
99 }
100