1 /*
2  * Copyright 2012, Google Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *     * Neither the name of Google Inc. nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 package org.jf.dexlib2.immutable.value;
33 
34 import com.google.common.base.Preconditions;
35 import com.google.common.collect.ImmutableList;
36 import org.jf.dexlib2.ValueType;
37 import org.jf.dexlib2.iface.value.*;
38 import org.jf.util.ExceptionWithContext;
39 import org.jf.util.ImmutableConverter;
40 
41 import javax.annotation.Nonnull;
42 import javax.annotation.Nullable;
43 
44 public class ImmutableEncodedValueFactory {
45     @Nonnull
of(@onnull EncodedValue encodedValue)46     public static ImmutableEncodedValue of(@Nonnull EncodedValue encodedValue) {
47         switch (encodedValue.getValueType()) {
48             case ValueType.BYTE:
49                 return ImmutableByteEncodedValue.of((ByteEncodedValue)encodedValue);
50             case ValueType.SHORT:
51                 return ImmutableShortEncodedValue.of((ShortEncodedValue)encodedValue);
52             case ValueType.CHAR:
53                 return ImmutableCharEncodedValue.of((CharEncodedValue)encodedValue);
54             case ValueType.INT:
55                 return ImmutableIntEncodedValue.of((IntEncodedValue)encodedValue);
56             case ValueType.LONG:
57                 return ImmutableLongEncodedValue.of((LongEncodedValue)encodedValue);
58             case ValueType.FLOAT:
59                 return ImmutableFloatEncodedValue.of((FloatEncodedValue)encodedValue);
60             case ValueType.DOUBLE:
61                 return ImmutableDoubleEncodedValue.of((DoubleEncodedValue)encodedValue);
62             case ValueType.STRING:
63                 return ImmutableStringEncodedValue.of((StringEncodedValue)encodedValue);
64             case ValueType.TYPE:
65                 return ImmutableTypeEncodedValue.of((TypeEncodedValue)encodedValue);
66             case ValueType.FIELD:
67                 return ImmutableFieldEncodedValue.of((FieldEncodedValue)encodedValue);
68             case ValueType.METHOD:
69                 return ImmutableMethodEncodedValue.of((MethodEncodedValue)encodedValue);
70             case ValueType.ENUM:
71                 return ImmutableEnumEncodedValue.of((EnumEncodedValue)encodedValue);
72             case ValueType.ARRAY:
73                 return ImmutableArrayEncodedValue.of((ArrayEncodedValue)encodedValue);
74             case ValueType.ANNOTATION:
75                 return ImmutableAnnotationEncodedValue.of((AnnotationEncodedValue)encodedValue);
76             case ValueType.NULL:
77                 return ImmutableNullEncodedValue.INSTANCE;
78             case ValueType.BOOLEAN:
79                 return ImmutableBooleanEncodedValue.of((BooleanEncodedValue)encodedValue);
80             default:
81                 Preconditions.checkArgument(false);
82                 return null;
83         }
84     }
85 
86     @Nonnull
defaultValueForType(String type)87     public static EncodedValue defaultValueForType(String type) {
88         switch (type.charAt(0)) {
89             case 'Z':
90                 return ImmutableBooleanEncodedValue.FALSE_VALUE;
91             case 'B':
92                 return new ImmutableByteEncodedValue((byte)0);
93             case 'S':
94                 return new ImmutableShortEncodedValue((short)0);
95             case 'C':
96                 return new ImmutableCharEncodedValue((char)0);
97             case 'I':
98                 return new ImmutableIntEncodedValue(0);
99             case 'J':
100                 return new ImmutableLongEncodedValue(0);
101             case 'F':
102                 return new ImmutableFloatEncodedValue(0);
103             case 'D':
104                 return new ImmutableDoubleEncodedValue(0);
105             case 'L':
106             case '[':
107                 return ImmutableNullEncodedValue.INSTANCE;
108             default:
109                 throw new ExceptionWithContext("Unrecognized type: %s", type);
110         }
111     }
112 
113     @Nullable
ofNullable(@ullable EncodedValue encodedValue)114     public static ImmutableEncodedValue ofNullable(@Nullable EncodedValue encodedValue) {
115         if (encodedValue == null) {
116             return null;
117         }
118         return of(encodedValue);
119     }
120 
121     @Nonnull
immutableListOf(@ullable Iterable<? extends EncodedValue> list)122     public static ImmutableList<ImmutableEncodedValue> immutableListOf
123             (@Nullable Iterable<? extends EncodedValue> list) {
124         return CONVERTER.toList(list);
125     }
126 
127     private static final ImmutableConverter<ImmutableEncodedValue, EncodedValue> CONVERTER =
128             new ImmutableConverter<ImmutableEncodedValue, EncodedValue>() {
129                 @Override
130                 protected boolean isImmutable(@Nonnull EncodedValue item) {
131                     return item instanceof ImmutableEncodedValue;
132                 }
133 
134                 @Nonnull
135                 @Override
136                 protected ImmutableEncodedValue makeImmutable(@Nonnull EncodedValue item) {
137                     return of(item);
138                 }
139             };
140 }
141