Index: src/org/adblockplus/sbrowser/contentblocker/engine/Subscription.java |
=================================================================== |
--- a/src/org/adblockplus/sbrowser/contentblocker/engine/Subscription.java |
+++ b/src/org/adblockplus/sbrowser/contentblocker/engine/Subscription.java |
@@ -37,16 +37,17 @@ import java.util.HashMap; |
import java.util.HashSet; |
import java.util.List; |
import java.util.Locale; |
import java.util.Map; |
import java.util.Map.Entry; |
import java.util.zip.GZIPInputStream; |
import java.util.zip.GZIPOutputStream; |
+import android.text.TextUtils; |
import android.util.Log; |
/** |
* Simple subscription representation. |
*/ |
final class Subscription |
{ |
private static final String TAG = Subscription.class.getSimpleName(); |
@@ -78,17 +79,17 @@ final class Subscription |
private static final String[] ALLOWED_META_KEYS_ARRAY = |
{ |
"checksum", KEY_VERSION, KEY_TITLE, "last modified", "expires", "homepage", "licence" |
}; |
private final URL url; |
private final Type type; |
private final HashMap<String, String> meta = new HashMap<String, String>(); |
- private HashSet<String> filters = null; |
+ private final HashSet<String> filters = new HashSet<String>(); |
private boolean metaDataValid = true; |
private boolean filtersValid = true; |
static |
{ |
for (final String s : ALLOWED_META_KEYS_ARRAY) |
{ |
@@ -315,27 +316,27 @@ final class Subscription |
return "true".equals(this.getMeta(KEY_ENABLED)); |
} |
public void setEnabled(boolean enable) |
{ |
this.putMeta(KEY_ENABLED, Boolean.toString(enable)); |
} |
- public void getFilters(Collection<String> filters) |
+ public void copyFilters(Collection<String> filters) |
{ |
- if (this.filters != null) |
+ if (filters != null) |
{ |
filters.addAll(this.filters); |
} |
} |
public void clearFilters() |
{ |
- this.filters = null; |
+ this.filters.clear(); |
} |
/** |
* @return an internal management ID |
*/ |
public String getId() |
{ |
return getId(this); |
@@ -384,17 +385,17 @@ final class Subscription |
private static String createFilterHash(List<String> filters) throws IOException |
{ |
try |
{ |
final MessageDigest md5 = MessageDigest.getInstance("MD5"); |
Collections.sort(filters); |
for (final String filter : filters) |
{ |
- md5.update(filter.getBytes("UTF-8")); |
+ md5.update(filter.getBytes(Engine.CHARSET_UTF_8)); |
} |
return byteArrayToHexString(md5.digest()); |
} |
catch (final NoSuchAlgorithmException e) |
{ |
throw new IOException("MD5 is unavailable: " + e.getMessage(), e); |
} |
} |
@@ -421,109 +422,128 @@ final class Subscription |
} |
public void serializeFilters(final File filtersFile) throws IOException |
{ |
final DataOutputStream filtersOut = new DataOutputStream(new GZIPOutputStream( |
new BufferedOutputStream(new FileOutputStream(filtersFile)))); |
try |
{ |
- if (this.filters == null) |
- { |
- filtersOut.writeInt(0); |
- } |
- else |
+ filtersOut.writeInt(this.filters.size()); |
+ filtersOut.writeUTF(createFilterHash(new ArrayList<String>(this.filters))); |
+ for (final String s : this.filters) |
{ |
- filtersOut.writeInt(this.filters.size()); |
- filtersOut.writeUTF(createFilterHash(new ArrayList<String>(this.filters))); |
- for (final String s : this.filters) |
- { |
- filtersOut.writeUTF(s); |
- } |
+ final byte[] b = s.getBytes(Engine.CHARSET_UTF_8); |
+ filtersOut.writeInt(b.length); |
+ filtersOut.write(b); |
} |
} |
finally |
{ |
filtersOut.close(); |
} |
} |
public void serializeSubscription(final File metaFile, final File filtersFile) throws IOException |
{ |
this.serializeMetaData(metaFile); |
this.serializeFilters(filtersFile); |
} |
- public static Subscription deserializeSubscription(final File metaFile) throws IOException |
+ public static Subscription deserializeSubscription(final File metaFile) |
{ |
- final DataInputStream in = new DataInputStream(new GZIPInputStream(new BufferedInputStream( |
- new FileInputStream(metaFile)))); |
+ Subscription sub = null; |
+ DataInputStream in = null; |
try |
{ |
+ in = new DataInputStream(new GZIPInputStream(new BufferedInputStream( |
+ new FileInputStream(metaFile)))); |
final String urlString = in.readUTF(); |
- final Subscription sub = new Subscription(urlString.length() > 0 ? new URL(urlString) : null); |
+ sub = new Subscription(!TextUtils.isEmpty(urlString) ? new URL(urlString) : null); |
+ sub.metaDataValid = false; |
final int numMetaEntries = in.readInt(); |
for (int i = 0; i < numMetaEntries; i++) |
{ |
final String key = in.readUTF(); |
final String value = in.readUTF(); |
sub.meta.put(key, value); |
} |
sub.metaDataValid = createMetaDataHash(sub.meta).equals(sub.getMeta(KEY_META_HASH)); |
- return sub; |
+ } |
+ catch (Throwable t) |
+ { |
+ // We catch Throwable here in order to return whatever we could retrieve from the meta file |
} |
finally |
{ |
- in.close(); |
+ if (in != null) |
+ { |
+ try |
+ { |
+ in.close(); |
+ } |
+ catch (IOException e) |
+ { |
+ // Ignored |
+ } |
+ } |
} |
+ return sub; |
} |
- public void deserializeFilters(final File filtersFile) throws IOException |
+ public void deserializeFilters(final File filtersFile) |
{ |
- final DataInputStream in = new DataInputStream(new GZIPInputStream(new BufferedInputStream( |
- new FileInputStream(filtersFile)))); |
+ this.clearFilters(); |
+ this.filtersValid = false; |
+ DataInputStream in = null; |
try |
{ |
+ in = new DataInputStream(new GZIPInputStream(new BufferedInputStream( |
+ new FileInputStream(filtersFile)))); |
final int numFilters = in.readInt(); |
- if (numFilters == 0) |
- { |
- this.filters = null; |
- } |
- else |
+ final String filtersHash = in.readUTF(); |
+ for (int i = 0; i < numFilters; i++) |
{ |
- this.filters = new HashSet<String>(); |
- final String filtersHash = in.readUTF(); |
- for (int i = 0; i < numFilters; i++) |
- { |
- this.filters.add(in.readUTF()); |
- } |
- this.filtersValid = createFilterHash(new ArrayList<String>(this.filters)).equals( |
- filtersHash); |
- Log.d(TAG, "Filters valid: " + this.filtersValid); |
+ final int length = in.readInt(); |
+ final byte[] b = new byte[length]; |
+ in.readFully(b); |
+ this.filters.add(new String(b, Engine.CHARSET_UTF_8)); |
} |
+ this.filtersValid = createFilterHash(new ArrayList<String>(this.filters)).equals( |
+ filtersHash); |
+ Log.d(TAG, "Filters valid: " + this.filtersValid); |
+ } |
+ catch (Throwable t) |
+ { |
+ // We catch Throwable here in order to load whatever we could retrieve from the filters file |
} |
finally |
{ |
- in.close(); |
+ if (in != null) |
+ { |
+ try |
+ { |
+ in.close(); |
+ } |
+ catch (IOException e) |
+ { |
+ // Ignored |
+ } |
+ } |
} |
} |
/** |
* Adds the given string, which should be a single filter to this |
* subscription. |
* |
* @param input |
*/ |
public Subscription parseLine(String input) |
{ |
- if (this.filters == null) |
- { |
- this.filters = new HashSet<String>(); |
- } |
- |
final String line = input.trim(); |
if (!line.isEmpty()) |
{ |
if (line.startsWith("!")) |
{ |
// Meta data |
final int colon = line.indexOf(':'); |
if (colon > 2) |
@@ -616,17 +636,17 @@ final class Subscription |
this.meta.put(KEY_HTTP_LAST_MODIFIED, lastModified); |
} |
else |
{ |
this.meta.remove(KEY_HTTP_LAST_MODIFIED); |
} |
this.meta.put(KEY_DOWNLOAD_COUNT, Long.toString(this.getDownloadCount() + 1)); |
- this.filters = new HashSet<String>(); |
+ this.clearFilters(); |
this.parseText(text); |
} |
} |
} |
this.serializeMetaData(metaFile); |
if (filtersChanged) |
{ |