1 /*
2  * Copyright (C) 2017 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 package com.android.dx.dex.file;
17 
18 import com.android.dx.rop.cst.CstCallSite;
19 import com.android.dx.util.AnnotatedOutput;
20 import com.android.dx.util.ByteArrayAnnotatedOutput;
21 
22 /**
23  * Representation of a call site in a DEX file.
24  */
25 public final class CallSiteItem extends OffsettedItem {
26 
27     /** {@code non-null;} the call site value */
28     private final CstCallSite value;
29 
30     /** {@code null-ok;} the encoded representation of the call site value */
31     private byte[] encodedForm;
32 
33     /**
34      * Constructs an instance.
35      *
36      * @param value {@code non-null;} the string value
37      */
CallSiteItem(CstCallSite value)38     public CallSiteItem(CstCallSite value) {
39         super(1, writeSize(value));
40 
41         this.value = value;
42     }
43 
44     /**
45      * Gets the write size for a given value.
46      *
47      * @param value {@code non-null;} the call site value
48      * @return {@code >= 2}; the write size, in bytes
49      */
writeSize(CstCallSite value)50     private static int writeSize(CstCallSite value) {
51         return -1;
52     }
53 
54     /** {@inheritDoc} */
55     @Override
place0(Section addedTo, int offset)56     protected void place0(Section addedTo, int offset) {
57         // Encode the data and note the size.
58 
59         ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput();
60         ValueEncoder encoder = new ValueEncoder(addedTo.getFile(), out);
61 
62         encoder.writeArray(value, true);
63         encodedForm = out.toByteArray();
64         setWriteSize(encodedForm.length);
65     }
66 
67     /** {@inheritDoc} */
68     @Override
toHuman()69     public String toHuman() {
70         return value.toHuman();
71     }
72 
73     /** {@inheritDoc} */
74     @Override
toString()75     public String toString() {
76         return value.toString();
77     }
78 
79     /** {@inheritDoc} */
80     @Override
writeTo0(DexFile file, AnnotatedOutput out)81     protected void writeTo0(DexFile file, AnnotatedOutput out) {
82         if (out.annotates()) {
83             out.annotate(0, offsetString() + " call site");
84             ValueEncoder encoder = new ValueEncoder(file, out);
85             encoder.writeArray(value, true);
86         } else {
87             out.write(encodedForm);
88         }
89     }
90 
91     /** {@inheritDoc} */
92     @Override
itemType()93     public ItemType itemType() {
94         // A call site is an encoded array with additional constraints
95         // on the element kinds. It is not listed separately in the
96         // DEX file's table of contents.
97         return ItemType.TYPE_ENCODED_ARRAY_ITEM;
98     }
99 
100     /** {@inheritDoc} */
101     @Override
addContents(DexFile file)102     public void addContents(DexFile file) {
103         ValueEncoder.addContents(file, value);
104     }
105 }
106