/* * Copyright (C) 2010-2016 JPEXS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.jpexs.browsers.cache.chrome; import com.jpexs.browsers.cache.RafInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.util.Map; /** * * @author JPEXS */ public class CacheAddr { private static final int EXTERNAL = 0; private static final int RANKINGS = 1; private static final int BLOCK_256 = 2; private static final int BLOCK_1K = 3; private static final int BLOCK_4K = 4; private static final int BLOCK_FILES = 5; private static final int BLOCK_ENTRIES = 6; private static final int BLOCK_EVICTED = 7; private static final String[] blockNames = new String[]{"EXTERNAL", "RANKINGS", "BLOCK_256", "BLOCK_1K", "BLOCK_4K", "BLOCK_FILES", "BLOCK_ENTRIES", "BLOCK_EVICTED"}; private static final int[] blockSizes = new int[]{0, 36, 256, 1024, 4096, 8, 104, 48}; private static final long kInitializedMask = 0x80000000L; private static final long kFileTypeMask = 0x70000000L; private static final int kFileTypeOffset = 28; private static final long kReservedBitsMask = 0x0c000000L; private static final long kNumBlocksMask = 0x03000000L; private static final int kNumBlocksOffset = 24; private static final long kFileSelectorMask = 0x00ff0000L; private static final int FileSelectorOffset = 16; private static final long kStartBlockMask = 0x0000FFFFL; private static final long kFileNameMask = 0x0FFFFFFFL; private final boolean initialized; private final int fileType; private int numBlocks; private int fileSelector; private int startBlock; private int fileName; private final long val; private final File rootPath; private final Map<Integer, RandomAccessFile> dataFiles; private final File externalFilesDir; public CacheAddr(InputStream is, File rootPath, Map<Integer, RandomAccessFile> dataFiles, File externalFilesDir) throws IOException { this.dataFiles = dataFiles; this.rootPath = rootPath; this.externalFilesDir = externalFilesDir; IndexInputStream iis = new IndexInputStream(is); val = iis.readUInt32(); initialized = (val & kInitializedMask) == kInitializedMask; fileType = (int) ((val & kFileTypeMask) >> kFileTypeOffset); if (fileType == EXTERNAL) { fileName = (int) (val & kFileNameMask); } else { numBlocks = (int) ((val & kNumBlocksMask) >> kNumBlocksOffset); fileSelector = (int) ((val & kFileSelectorMask) >> FileSelectorOffset); startBlock = (int) (val & kStartBlockMask); } } @Override public String toString() { String ft = blockNames[fileType]; if (fileType == EXTERNAL) { return ft + ":" + fileName; } if (!initialized) { return "uninitialized"; } return ft + ": numBlocks " + numBlocks + " fileSelector " + fileSelector + " startBlock " + startBlock; } public InputStream getInputStream() throws IOException { if (!initialized) { return null; } switch (fileType) { case EXTERNAL: String fileNameStr = Long.toHexString(fileName); while (fileNameStr.length() < 6) { fileNameStr = "0" + fileNameStr; } fileNameStr = "f_" + fileNameStr; return new RafInputStream(new RandomAccessFile(new File(externalFilesDir, fileNameStr), "r")); case BLOCK_1K: case BLOCK_256: case BLOCK_4K: RandomAccessFile raf; if (dataFiles.containsKey(fileSelector)) { raf = dataFiles.get(fileSelector); } else { raf = new RandomAccessFile(rootPath + "\\data_" + fileSelector, "r"); dataFiles.put(fileSelector, raf); } raf.seek(BlockFileHeader.kBlockHeaderSize + startBlock * blockSizes[fileType]); return new RafInputStream(raf); } return null; } }