1 /* 2 * Copyright (C) 2020 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.storage.block.read; 18 19 import com.android.storage.util.Visitor; 20 21 import java.util.Arrays; 22 import java.util.Objects; 23 24 /** 25 * Information about a block from a block file's header. There is one {@link BlockInfo} for every 26 * (logical) block in the file, though the associated block's data can be zero length, in which case 27 * the {@link #getBlockStartByteOffset()} will be set but the block itself will occupy no bytes in 28 * the file. 29 */ 30 public final class BlockInfo { 31 32 private final int mId; 33 34 private final int mType; 35 36 private final long mBlockStartByteOffset; 37 38 private final long mBlockSizeBytes; 39 40 private final byte[] mExtraBytes; 41 42 /** 43 * Creates an instance using the supplied information. {@code extraBytes} can be {@code null}. 44 */ BlockInfo(int id, int type, long blockStartByteOffset, long blockSizeBytes, byte[] extraBytes)45 public BlockInfo(int id, int type, long blockStartByteOffset, long blockSizeBytes, 46 byte[] extraBytes) { 47 mId = id; 48 mType = type; 49 mBlockStartByteOffset = blockStartByteOffset; 50 mBlockSizeBytes = blockSizeBytes; 51 mExtraBytes = extraBytes; 52 } 53 54 /** Returns the block's ID. */ getId()55 public int getId() { 56 return mId; 57 } 58 59 /** Returns the block's type ID. */ getType()60 public int getType() { 61 return mType; 62 } 63 64 /** Returns the "extra" (domain specific) bytes. */ getExtraBytes()65 public byte[] getExtraBytes() { 66 return mExtraBytes; 67 } 68 69 /** Returns the location of the block in the file. */ getBlockStartByteOffset()70 public long getBlockStartByteOffset() { 71 return mBlockStartByteOffset; 72 } 73 74 /** 75 * The block's size in the file. It may be zero to indicate an empty block. When >= 0 it 76 * includes the length of the block's header. 77 */ getBlockSizeBytes()78 public long getBlockSizeBytes() { 79 return mBlockSizeBytes; 80 } 81 82 @Override equals(Object o)83 public boolean equals(Object o) { 84 if (this == o) { 85 return true; 86 } 87 if (o == null || getClass() != o.getClass()) { 88 return false; 89 } 90 BlockInfo blockInfo = (BlockInfo) o; 91 return mId == blockInfo.mId 92 && mType == blockInfo.mType 93 && mBlockStartByteOffset == blockInfo.mBlockStartByteOffset 94 && mBlockSizeBytes == blockInfo.mBlockSizeBytes 95 && Arrays.equals(mExtraBytes, blockInfo.mExtraBytes); 96 } 97 98 @Override hashCode()99 public int hashCode() { 100 int result = Objects.hash(mId, mType, mBlockStartByteOffset, mBlockSizeBytes); 101 result = 31 * result + Arrays.hashCode(mExtraBytes); 102 return result; 103 } 104 105 @Override toString()106 public String toString() { 107 return "BlockInfo{" 108 + "mId=" + mId + "(" + Integer.toHexString(mId) + ")" 109 + ", mType=" + mType 110 + ", mBlockStartByteOffset=" + mBlockStartByteOffset 111 + ", mBlockSizeBytes=" + mBlockSizeBytes 112 + ", mExtraBytes=" + Arrays.toString(mExtraBytes) 113 + '}'; 114 } 115 116 /** A {@link Visitor} for the {@link BlockInfo}. See {@link #visit} */ 117 public interface BlockInfoVisitor extends Visitor { 118 119 /** Called after {@link #begin()} with the BlockInfo. */ visit(BlockInfo blockInfo)120 void visit(BlockInfo blockInfo) throws VisitException; 121 } 122 123 /** 124 * Issues callbacks to the supplied {@link BlockInfoVisitor} containing information from 125 * the block info. 126 */ visit(BlockInfoVisitor blockInfoVisitor)127 public void visit(BlockInfoVisitor blockInfoVisitor) throws Visitor.VisitException { 128 try { 129 blockInfoVisitor.begin(); 130 blockInfoVisitor.visit(this); 131 } finally { 132 blockInfoVisitor.end(); 133 } 134 } 135 } 136