/* * Copyright (C) 2010-2014 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 . */ 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 { public static final int EXTERNAL = 0; public static final int RANKINGS = 1; public static final int BLOCK_256 = 2; public static final int BLOCK_1K = 3; public static final int BLOCK_4K = 4; public static final int BLOCK_FILES = 5; public static final int BLOCK_ENTRIES = 6; public static final int BLOCK_EVICTED = 7; public static final String blockNames[] = new String[]{"EXTERNAL", "RANKINGS", "BLOCK_256", "BLOCK_1K", "BLOCK_4K", "BLOCK_FILES", "BLOCK_ENTRIES", "BLOCK_EVICTED"}; public static final int blockSizes[] = new int[]{0, 36, 256, 1024, 4096, 8, 104, 48}; public static final long kInitializedMask = 0x80000000L; public static final long kFileTypeMask = 0x70000000L; public static final int kFileTypeOffset = 28; public static final long kReservedBitsMask = 0x0c000000L; public static final long kNumBlocksMask = 0x03000000L; public static final int kNumBlocksOffset = 24; public static final long kFileSelectorMask = 0x00ff0000L; public static final int FileSelectorOffset = 16; public static final long kStartBlockMask = 0x0000FFFFL; public static final long kFileNameMask = 0x0FFFFFFFL; public boolean initialized; public int fileType; public int numBlocks; public int fileSelector; public int startBlock; public int fileName; public long val; public File rootPath; private final Map dataFiles; private final File externalFilesDir; public CacheAddr(InputStream is, File rootPath, Map 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; } }