14ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver/* 21bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * Copyright 2013, Google Inc. 34ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver * All rights reserved. 44ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver * 54ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver * Redistribution and use in source and binary forms, with or without 64ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver * modification, are permitted provided that the following conditions are 74ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver * met: 84ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver * 94ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver * * Redistributions of source code must retain the above copyright 104ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver * notice, this list of conditions and the following disclaimer. 114ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver * * Redistributions in binary form must reproduce the above 124ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver * copyright notice, this list of conditions and the following disclaimer 134ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver * in the documentation and/or other materials provided with the 144ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver * distribution. 154ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver * * Neither the name of Google Inc. nor the names of its 164ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver * contributors may be used to endorse or promote products derived from 174ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver * this software without specific prior written permission. 184ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver * 194ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 204ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 214ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 224ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 234ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 244ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 254ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 264ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 274ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 284ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 294ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 304ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver */ 314ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver 321bf6f2324541df184689fdb2c0d8188af5221784Ben Gruverpackage org.jf.dexlib2.writer.pool; 334ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver 341bf6f2324541df184689fdb2c0d8188af5221784Ben Gruverimport com.google.common.collect.ImmutableList; 3508d90ec360b43c9febe9638089b1a3815cc62111Ben Gruverimport org.jf.dexlib2.writer.DexWriter; 361bf6f2324541df184689fdb2c0d8188af5221784Ben Gruverimport org.jf.dexlib2.writer.TypeListSection; 3708d90ec360b43c9febe9638089b1a3815cc62111Ben Gruverimport org.jf.dexlib2.writer.pool.TypeListPool.Key; 384ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver 394ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruverimport javax.annotation.Nonnull; 4008d90ec360b43c9febe9638089b1a3815cc62111Ben Gruverimport javax.annotation.Nullable; 411bf6f2324541df184689fdb2c0d8188af5221784Ben Gruverimport java.util.Collection; 421bf6f2324541df184689fdb2c0d8188af5221784Ben Gruverimport java.util.Iterator; 434ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver 441bf6f2324541df184689fdb2c0d8188af5221784Ben Gruverpublic class TypeListPool extends BaseNullableOffsetPool<Key<? extends Collection<? extends CharSequence>>> 451bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver implements TypeListSection<CharSequence, Key<? extends Collection<? extends CharSequence>>> { 461bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver @Nonnull private final TypePool typePool; 474ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver 481bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver public TypeListPool(@Nonnull TypePool typePool) { 491bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver this.typePool = typePool; 504ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver } 514ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver 524ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver public void intern(@Nonnull Collection<? extends CharSequence> types) { 5308d90ec360b43c9febe9638089b1a3815cc62111Ben Gruver if (types.size() > 0) { 5408d90ec360b43c9febe9638089b1a3815cc62111Ben Gruver Key<? extends Collection<? extends CharSequence>> key = new Key<Collection<? extends CharSequence>>(types); 5508d90ec360b43c9febe9638089b1a3815cc62111Ben Gruver Integer prev = internedItems.put(key, 0); 5608d90ec360b43c9febe9638089b1a3815cc62111Ben Gruver if (prev == null) { 5708d90ec360b43c9febe9638089b1a3815cc62111Ben Gruver for (CharSequence type: types) { 5808d90ec360b43c9febe9638089b1a3815cc62111Ben Gruver typePool.intern(type); 5908d90ec360b43c9febe9638089b1a3815cc62111Ben Gruver } 604ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver } 614ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver } 624ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver } 634ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver 641bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver @Nonnull @Override 651bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver public Collection<? extends CharSequence> getTypes(Key<? extends Collection<? extends CharSequence>> typesKey) { 661bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver if (typesKey == null) { 671bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver return ImmutableList.of(); 684ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver } 691bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver return typesKey.types; 704ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver } 714ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver 7208d90ec360b43c9febe9638089b1a3815cc62111Ben Gruver @Override public int getNullableItemOffset(@Nullable Key<? extends Collection<? extends CharSequence>> key) { 7308d90ec360b43c9febe9638089b1a3815cc62111Ben Gruver if (key == null || key.types.size() == 0) { 7408d90ec360b43c9febe9638089b1a3815cc62111Ben Gruver return DexWriter.NO_OFFSET; 7508d90ec360b43c9febe9638089b1a3815cc62111Ben Gruver } else { 7608d90ec360b43c9febe9638089b1a3815cc62111Ben Gruver return super.getNullableItemOffset(key); 7708d90ec360b43c9febe9638089b1a3815cc62111Ben Gruver } 7808d90ec360b43c9febe9638089b1a3815cc62111Ben Gruver } 7908d90ec360b43c9febe9638089b1a3815cc62111Ben Gruver 801bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver public static class Key<TypeCollection extends Collection<? extends CharSequence>> 811bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver implements Comparable<Key<? extends Collection<? extends CharSequence>>> { 821bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver @Nonnull TypeCollection types; 83085cfce948928c19fff95c4bf93ab5ed430991aeIzzat Bahadirov 841bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver public Key(@Nonnull TypeCollection types) { 854ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver this.types = types; 864ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver } 874ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver 884ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver @Override 894ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver public int hashCode() { 904ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver int hashCode = 1; 914ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver for (CharSequence type: types) { 924ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver hashCode = hashCode*31 + type.toString().hashCode(); 934ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver } 944ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver return hashCode; 954ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver } 964ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver 974ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver @Override 984ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver public boolean equals(Object o) { 994ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver if (o instanceof Key) { 1001bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver Key<? extends Collection<? extends CharSequence>> other = 1011bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver (Key<? extends Collection<? extends CharSequence>>)o; 1024ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver if (types.size() != other.types.size()) { 1034ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver return false; 1044ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver } 1054ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver Iterator<? extends CharSequence> otherTypes = other.types.iterator(); 1064ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver for (CharSequence type: types) { 1074ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver if (!type.toString().equals(otherTypes.next().toString())) { 1084ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver return false; 1094ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver } 1104ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver } 1114ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver return true; 1124ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver } 1134ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver return false; 1144ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver } 1154ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver 1164ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver @Override 1174ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver public String toString() { 1184ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver StringBuilder sb = new StringBuilder(); 1194ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver for (CharSequence type: types) { 1204ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver sb.append(type.toString()); 1214ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver } 1224ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver return sb.toString(); 1234ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver } 1244ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver 1254ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver @Override 1261bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver public int compareTo(Key<? extends Collection<? extends CharSequence>> o) { 1274ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver Iterator<? extends CharSequence> other = o.types.iterator(); 1284ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver for (CharSequence type: types) { 1294ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver if (!other.hasNext()) { 1304ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver return 1; 1314ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver } 1324ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver int comparison = type.toString().compareTo(other.next().toString()); 1334ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver if (comparison != 0) { 1344ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver return comparison; 1354ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver } 1364ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver } 1374ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver if (other.hasNext()) { 1384ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver return -1; 1394ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver } 1404ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver return 0; 1414ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver } 1424ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver } 1434ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver} 144