Home | History | Annotate | Download | only in zip
      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      */
     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      */
     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      */
    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      */
    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      */
    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      */
    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      */
    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
    150     T getStore() {
    151         return store;
    152     }
    153 
    154     @Override
    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