trunk contents moved to root

This commit is contained in:
Jindra Petřík
2014-05-10 20:50:57 +02:00
parent 1b851e66a8
commit 199a4d0c2b
2296 changed files with 0 additions and 0 deletions
@@ -0,0 +1,51 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.jpexs.browsers.cache.firefox;
import java.io.IOException;
import java.io.InputStream;
/**
*
* @author JPEXS
*/
public class CacheInputStream extends InputStream {
private final InputStream is;
@Override
public int available() throws IOException {
return is.available();
}
public CacheInputStream(InputStream is) {
this.is = is;
}
@Override
public int read() throws IOException {
return is.read();
}
public long readInt32() throws IOException {
return (read() << 24) + (read() << 16) + (read() << 8) + read();
}
public int readInt16() throws IOException {
return (read() << 8) + read();
}
}
+72
View File
@@ -0,0 +1,72 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.jpexs.browsers.cache.firefox;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
* @author JPEXS
*/
public class CacheMap {
public long version;
public long datasize;
public long entryCount;
public long dirtyFlag;
public long recordCount;
public long evictionRank[];
public long bucketUsage[];
public List<MapBucket> mapBuckets;
public CacheMap(File file) throws IOException {
File cacheDir = file.getParentFile();
CacheInputStream cis = new CacheInputStream(new FileInputStream(file));
version = cis.readInt32();
datasize = cis.readInt32();
entryCount = cis.readInt32();
dirtyFlag = cis.readInt32();
recordCount = cis.readInt32();
evictionRank = new long[32];
for (int i = 0; i < evictionRank.length; i++) {
evictionRank[i] = cis.readInt32();
}
bucketUsage = new long[32];
for (int i = 0; i < bucketUsage.length; i++) {
bucketUsage[i] = cis.readInt32();
}
mapBuckets = new ArrayList<>();
Map<Integer, RandomAccessFile> cacheFiles = new HashMap<>();
for (int i = 1; i <= 3; i++) {
cacheFiles.put(i, new RandomAccessFile(new File(cacheDir, "_CACHE_00" + i + "_"), "r"));
}
while (cis.available() > 0) {
MapBucket mb = new MapBucket(cis, cacheDir, cacheFiles);
if (mb.hash == 0) {
continue;
}
mapBuckets.add(mb);
}
}
}
+161
View File
@@ -0,0 +1,161 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.jpexs.browsers.cache.firefox;
import com.jpexs.browsers.cache.CacheEntry;
import com.jpexs.browsers.cache.CacheImplementation;
import java.io.File;
import java.io.IOException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author JPEXS
*/
public class FirefoxCache implements CacheImplementation {
private static FirefoxCache instance;
private FirefoxCache() {
}
public static FirefoxCache getInstance() {
if (instance == null) {
instance = new FirefoxCache();
}
return instance;
}
private boolean loaded = false;
private CacheMap map;
@Override
public void refresh() {
File dir = getCacheDirectory();
if (dir == null) {
return;
}
File cacheMapFile = new File(dir, "_CACHE_MAP_");
try {
map = new CacheMap(cacheMapFile);
} catch (IOException ex) {
Logger.getLogger(FirefoxCache.class.getName()).log(Level.SEVERE, null, ex);
}
loaded = true;
}
@Override
public List<CacheEntry> getEntries() {
if (!loaded) {
refresh();
}
if (map == null) {
return null;
}
List<CacheEntry> ret = new ArrayList<>();
ret.addAll(map.mapBuckets);
return ret;
}
private enum OSId {
WINDOWS, OSX, UNIX
}
private static OSId getOSId() {
PrivilegedAction<String> doGetOSName = new PrivilegedAction<String>() {
@Override
public String run() {
return System.getProperty("os.name");
}
};
OSId id = OSId.UNIX;
String osName = AccessController.doPrivileged(doGetOSName);
if (osName != null) {
if (osName.toLowerCase().startsWith("mac os x")) {
id = OSId.OSX;
} else if (osName.contains("Windows")) {
id = OSId.WINDOWS;
}
}
return id;
}
public static File getProfileDirectory() {
File profilesDir = getProfilesDirectory();
if (profilesDir == null) {
return null;
}
File profiles[] = profilesDir.listFiles();
File profileDir = null;
for (File f : profiles) {
if (f.isDirectory()) {
if (f.getName().matches("[a-z0-9]+\\.default")) {
profileDir = f;
break;
}
}
}
return profileDir;
}
public static File getCacheDirectory() {
File profileDir = getProfileDirectory();
File cacheDir = null;
if (profileDir != null) {
cacheDir = new File(profileDir, "Cache");
}
if (cacheDir == null) {
return null;
}
if (!cacheDir.exists()) {
return null;
}
return cacheDir;
}
public static File getProfilesDirectory() {
String userHome = null;
File profilesDir = null;
try {
userHome = System.getProperty("user.home");
} catch (SecurityException ignore) {
}
if (userHome != null) {
OSId osId = getOSId();
if (osId == OSId.WINDOWS) {
profilesDir = new File(userHome + "\\AppData\\Local\\Mozilla\\Firefox\\Profiles");
if (!profilesDir.exists()) {
profilesDir = new File(userHome + "\\Local Settings\\Application Data\\Mozilla\\Firefox\\Profiles");
}
} else if (osId == OSId.OSX) {
profilesDir = new File(userHome + "/Library/Caches/Firefox/Profiles");
} else {
profilesDir = new File(userHome + "/.mozilla/firefox");
}
}
if ((profilesDir == null) || !profilesDir.exists()) {
return null;
}
return profilesDir;
}
}
@@ -0,0 +1,28 @@
/*
* Copyright (C) 2010-2014 etrik
*
* 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.firefox;
/**
*
* @author petrik
*/
public class IncompatibleVersionException extends Exception {
public IncompatibleVersionException(int version) {
super("Incompatible version: " + version);
}
}
+116
View File
@@ -0,0 +1,116 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.jpexs.browsers.cache.firefox;
import com.jpexs.browsers.cache.RafInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.util.Map;
/**
*
* @author JPEXS
*/
public class Location {
public int locationSelector;
public int extraBlocks;
public long blockNumber;
public int fileGeneration;
public int fileSize;
public boolean isMetadata;
public long hash;
private final File rootDir;
public static final long eReservedMask = 0x4C000000L;
public static final long eLocationSelectorMask = 0x30000000L;
public static final int eLocationSelectorOffset = 28;
public static final long eExtraBlocksMask = 0x03000000L;
public static final int eExtraBlocksOffset = 24;
public static final long eBlockNumberMask = 0x00FFFFFFL;
public static final long eFileGenerationMask = 0x000000FFL;
public static final long eFileSizeMask = 0x00FFFF00L;
public static final int eFileSizeOffset = 8;
public static final long eFileReservedMask = 0x4F000000L;
public static int size_shift(int idx) {
return (2 * ((idx) - 1));
}
public static int bitmapSizeForIndex(int idx) {
return ((idx > 0) ? (131072 >> size_shift(idx)) : 0);
}
public static int blockSizeForIndex(int idx) {
return ((idx > 0) ? (256 << size_shift(idx)) : 0);
}
/*
#define BLOCK_SIZE_FOR_INDEX(idx) ((idx) ? (256 << SIZE_SHIFT(idx)) : 0)
#define BITMAP_SIZE_FOR_INDEX(idx) ((idx) ? (131072 >> SIZE_SHIFT(idx)) : 0)
*/
private final Map<Integer, RandomAccessFile> dataFiles;
public InputStream getInputStream() throws IOException {
String fileName = getFileName();
if (locationSelector > 0) {
RandomAccessFile raf = dataFiles.get(locationSelector);
raf.seek(bitmapSizeForIndex(locationSelector) / 8 + blockSizeForIndex(locationSelector) * blockNumber);
return new RafInputStream(raf);
}
return new FileInputStream(new File(rootDir, fileName));
}
public Location(long val, boolean isMetadata, long hash, File rootDir, Map<Integer, RandomAccessFile> dataFiles) {
this.hash = hash;
this.dataFiles = dataFiles;
this.rootDir = rootDir;
this.isMetadata = isMetadata;
locationSelector = (int) ((val & eLocationSelectorMask) >> eLocationSelectorOffset);
if (locationSelector > 0) {
extraBlocks = (int) ((val & eExtraBlocksMask) >> eExtraBlocksOffset);
blockNumber = (int) (val & eBlockNumberMask);
} else {
fileSize = (int) ((val & eFileSizeMask) >> eFileSizeOffset);
fileGeneration = (int) (val & eFileGenerationMask);
}
}
public String getFileName() {
if (locationSelector > 0) {
return "_CACHE_00" + locationSelector + "_";
}
String hashHex = Long.toHexString(hash & 0xffffffffL).toUpperCase();
while (hashHex.length() < 8) {
hashHex = "0" + hashHex;
}
String genHex = Integer.toHexString(fileGeneration);
while (genHex.length() < 2) {
genHex = "0" + genHex;
}
return hashHex.charAt(0) + File.separator + hashHex.substring(1, 1 + 2) + File.separator + hashHex.substring(3) + (isMetadata ? "m" : "d") + genHex;
}
@Override
public String toString() {
if (locationSelector > 0) {
return getFileName() + " block " + blockNumber + " extraBlocks " + extraBlocks;
}
return getFileName();
}
}
+129
View File
@@ -0,0 +1,129 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.jpexs.browsers.cache.firefox;
import com.jpexs.browsers.cache.CacheEntry;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author JPEXS
*/
public class MapBucket extends CacheEntry {
public long hash;
public long enviction;
public Location dataLocation;
public Location metadataLocation;
private MetaData metadata;
public MapBucket(InputStream is, File rootDir, Map<Integer, RandomAccessFile> dataFiles) throws IOException {
CacheInputStream cis = new CacheInputStream(is);
hash = cis.readInt32();
enviction = cis.readInt32();
dataLocation = new Location(cis.readInt32(), false, hash, rootDir, dataFiles);
metadataLocation = new Location(cis.readInt32(), true, hash, rootDir, dataFiles);
}
public InputStream getMetaDataStream() throws IOException {
return metadataLocation.getInputStream();
}
public MetaData getMetaData() {
if (metadata == null) {
try {
metadata = new MetaData(getMetaDataStream());
} catch (IncompatibleVersionException ie) {
} catch (IOException ex) {
Logger.getLogger(MapBucket.class.getName()).log(Level.SEVERE, null, ex);
}
}
return metadata;
}
@Override
public String getRequestURL() {
String req = null;
MetaData m = getMetaData();
if (m == null) {
return null;
}
req = m.request;
if (req == null) {
return null;
}
if (req.startsWith("HTTP:")) {
req = req.substring("HTTP:".length());
}
return req;
}
@Override
public Map<String, String> getResponseHeaders() {
MetaData m = getMetaData();
if (m == null) {
return null;
}
String responseHead = m.response.get("response-head");
if (responseHead == null) {
return null;
}
String headers[] = responseHead.split("\r\n");
Map<String, String> ret = new HashMap<>();
for (int h = 1; h < headers.length; h++) {
String hs = headers[h];
if (hs.contains(":")) {
String hp[] = hs.split(":");
ret.put(hp[0].trim(), hp[1].trim());
}
}
return ret;
}
@Override
public String getStatusLine() {
MetaData m = getMetaData();
if (m == null) {
return null;
}
String responseHead = m.response.get("response-head");
String headers[] = responseHead.split("\r\n");
return headers[0];
}
@Override
public String getRequestMethod() {
return "GET"; //No POST caching in Firefox
}
@Override
public InputStream getResponseRawDataStream() {
try {
return dataLocation.getInputStream();
} catch (IOException ex) {
Logger.getLogger(MapBucket.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
}
+79
View File
@@ -0,0 +1,79 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.jpexs.browsers.cache.firefox;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
/**
*
* @author JPEXS
*/
public class MetaData {
public int majorVersion;
public int minorVersion;
public long location;
public long fetchCount;
public long firstFetchTime;
public long lastFetchTime;
public long expireTime;
public long dataSize;
public long requestSize;
public long infoSize;
public String request;
public Map<String, String> response;
public MetaData(InputStream is) throws IOException, IncompatibleVersionException {
CacheInputStream cis = new CacheInputStream(is);
majorVersion = cis.readInt16();
if (majorVersion != 1) {
throw new IncompatibleVersionException(majorVersion);
}
minorVersion = cis.readInt16();
location = cis.readInt32();
fetchCount = cis.readInt32();
firstFetchTime = cis.readInt32();
lastFetchTime = cis.readInt32();
expireTime = cis.readInt32();
dataSize = cis.readInt32();
requestSize = cis.readInt32();
infoSize = cis.readInt32();
byte req[] = new byte[(int) requestSize];
cis.read(req);
request = new String(req, 0, (int) requestSize - 1/*Ends with char 0*/);
byte res[] = new byte[(int) infoSize];
cis.read(res);
String responseStr = new String(res);
int nulpos;
boolean inKey = true;
String key = null;
response = new HashMap<>();
while ((nulpos = responseStr.indexOf(0)) > 0) {
String v = responseStr.substring(0, nulpos);
responseStr = responseStr.substring(nulpos + 1);
if (inKey) {
key = v;
} else {
response.put(key, v);
}
inKey = !inKey;
}
}
}