1 /* 2 * Copyright (C) 2015 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.tools.build.apkzlib.zip; 18 19 import com.google.common.base.MoreObjects; 20 import com.google.common.base.Preconditions; 21 import com.google.common.primitives.Ints; 22 import java.util.Comparator; 23 import javax.annotation.Nonnull; 24 import javax.annotation.Nullable; 25 26 /** 27 * Represents an entry in the {@link FileUseMap}. Each entry contains an interval of bytes. The 28 * end of the interval is exclusive. 29 * <p> 30 * Entries can either be free or used. Used entries <em>must</em> store an object. Free entries 31 * do not store anything. 32 * <p> 33 * File map entries are used to keep track of which parts of a file map are used and not. 34 * @param <T> the type of data stored 35 */ 36 class FileUseMapEntry<T> { 37 38 /** 39 * Comparator that compares entries by their start date. 40 */ 41 public static final Comparator<FileUseMapEntry<?>> COMPARE_BY_START = 42 (o1, o2) -> Ints.saturatedCast(o1.getStart() - o2.getStart()); 43 44 /** 45 * Comparator that compares entries by their size. 46 */ 47 public static final Comparator<FileUseMapEntry<?>> COMPARE_BY_SIZE = 48 (o1, o2) -> Ints.saturatedCast(o1.getSize() - o2.getSize()); 49 50 /** 51 * The first byte in the entry. 52 */ 53 private final long start; 54 55 /** 56 * The first byte no longer in the entry. 57 */ 58 private final long end; 59 60 /** 61 * The stored data. If {@code null} then this entry represents a free entry. 62 */ 63 @Nullable 64 private final T store; 65 66 /** 67 * Creates a new map entry. 68 * 69 * @param start the start of the entry 70 * @param end the end of the entry (first byte no longer in the entry) 71 * @param store the data to store in the entry or {@code null} if this is a free entry 72 */ FileUseMapEntry(long start, long end, @Nullable T store)73 private FileUseMapEntry(long start, long end, @Nullable T store) { 74 Preconditions.checkArgument(start >= 0, "start < 0"); 75 Preconditions.checkArgument(end > start, "end <= start"); 76 77 this.start = start; 78 this.end = end; 79 this.store = store; 80 } 81 82 /** 83 * Creates a new free entry. 84 * 85 * @param start the start of the entry 86 * @param end the end of the entry (first byte no longer in the entry) 87 * @return the entry 88 */ makeFree(long start, long end)89 public static FileUseMapEntry<Object> makeFree(long start, long end) { 90 return new FileUseMapEntry<>(start, end, null); 91 } 92 93 /** 94 * Creates a new used entry. 95 * 96 * @param start the start of the entry 97 * @param end the end of the entry (first byte no longer in the entry) 98 * @param store the data to store in the entry 99 * @param <T> the type of data to store in the entry 100 * @return the entry 101 */ makeUsed(long start, long end, @Nonnull T store)102 public static <T> FileUseMapEntry<T> makeUsed(long start, long end, @Nonnull T store) { 103 Preconditions.checkNotNull(store, "store == null"); 104 return new FileUseMapEntry<>(start, end, store); 105 } 106 107 /** 108 * Obtains the first byte in the entry. 109 * 110 * @return the first byte in the entry (if the same value as {@link #getEnd()} then the entry 111 * is empty and contains no data) 112 */ getStart()113 long getStart() { 114 return start; 115 } 116 117 /** 118 * Obtains the first byte no longer in the entry. 119 * 120 * @return the first byte no longer in the entry 121 */ getEnd()122 long getEnd() { 123 return end; 124 } 125 126 /** 127 * Obtains the size of the entry. 128 * 129 * @return the number of bytes contained in the entry 130 */ getSize()131 long getSize() { 132 return end - start; 133 } 134 135 /** 136 * Determines if this is a free entry. 137 * 138 * @return is this entry free? 139 */ isFree()140 boolean isFree() { 141 return store == null; 142 } 143 144 /** 145 * Obtains the data stored in the entry. 146 * 147 * @return the data stored or {@code null} if this entry is a free entry 148 */ 149 @Nullable getStore()150 T getStore() { 151 return store; 152 } 153 154 @Override toString()155 public String toString() { 156 return MoreObjects.toStringHelper(this) 157 .add("start", start) 158 .add("end", end) 159 .add("store", store) 160 .toString(); 161 } 162 } 163