Loading src/edu/bu/ec504/hw1p3/CharByCharCompressor.java +1 −2 Original line number Diff line number Diff line package edu.bu.ec504.hw1p3; import edu.bu.ec504.hw1p3.Compressor.Dictionary.Atom; import java.io.BufferedReader; import java.io.IOException; import java.util.ArrayList; Loading @@ -8,7 +7,7 @@ import java.util.ArrayList; /** * A simple implementation of the {@link Compressor} class. * This implementation ignores the dictionary entirely, and simply encodes each character of * the input as a trivial {@link Compressor.Dictionary.Atom}, indexed against the empty string. * the input as a trivial {@link Compressor.Atom}, indexed against the empty string. */ public class CharByCharCompressor extends Compressor { Loading src/edu/bu/ec504/hw1p3/Compressor.java +36 −25 Original line number Diff line number Diff line package edu.bu.ec504.hw1p3; import edu.bu.ec504.hw1p3.Compressor.Dictionary.Atom; import java.io.BufferedReader; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.List; public abstract class Compressor implements Serializable { // nested classes /** * A dictionary to be used in compression. */ static class Dictionary { /** * An immutable atom of compression that incorporates: * a. An integer representing an index into the dictionary {@link Dictionary#dict} * a. An integer representing an index into some dictionary. * b. A string that follows the dictionary word in a. */ static final class Atom implements Serializable { public Atom(int myIndex, String myNext) { index = myIndex; next = myNext; } public int getIndex() { return index; } public String getNext() { return next; } public Atom(int myIndex, String myNext) { index = myIndex; next = myNext; } private static final long serialVersionUID = 2L; // for serliazation private final int index; private final String next; public int getIndex() { return index; } Dictionary() { dict = new ArrayList<>(); public String getNext() { return next; } final ArrayList<String> dict; /** * Pretty print the atom. * @return A human-readable string representing this atom. */ @Override public String toString() { return "Atom{" + "index=" + index + ", next='" + next + '\'' + '}'; } private static final long serialVersionUID = 2L; // for serialization private final int index; private final String next; } /** * An encapsulation of a list of Atoms. */ public static class CompressedText implements Serializable { CompressedText(ArrayList<Atom> theData) { CompressedText(List<Atom> theData) { data=theData; } ArrayList<Atom> getList() { return data; } private ArrayList<Atom> data; private static final long serialVersionUID = 3L; // for serliazation List<Atom> getList() { return data; } private final List<Atom> data; private static final long serialVersionUID = 3L; // for serialization } Loading @@ -49,7 +61,6 @@ public abstract class Compressor implements Serializable { // CONSTRUCTORS Compressor() { } /** * Process additional plaintext from <code>in</code> and incorporates it into this compressed object. * @param in A BufferedReader linked to an input source. Loading @@ -61,10 +72,9 @@ public abstract class Compressor implements Serializable { * @return The uncompressed text corresponding to this object. */ final public String uncompress(CompressedText theCompressedText) { final ArrayList<String> dict = new ArrayList<>(); // a dictionary to be used in compression. dict.add(""); // starting point final ArrayList<String> dict = emptyDict; // a dictionary to be used in compression. StringBuilder result=new StringBuilder(""); StringBuilder result=new StringBuilder(); for (Atom anAtom: theCompressedText.getList()) { String nextStr=dict.get( anAtom.getIndex() ) + anAtom.getNext(); // the next String decoded from the theCompressedText result.append(nextStr); Loading @@ -75,5 +85,6 @@ public abstract class Compressor implements Serializable { // FIELDS private static final long serialVersionUID = 1L; // to allow serialization protected static final ArrayList<String> emptyDict = new ArrayList<>(Collections.singletonList("")); // contains just one string, the empty string } src/edu/bu/ec504/hw1p3/LineByLineCompressor.java 0 → 100644 +42 −0 Original line number Diff line number Diff line package edu.bu.ec504.hw1p3; import java.io.BufferedReader; import java.io.IOException; import java.util.ArrayList; /** * A slightly more complicated example of a compressor. */ public class LineByLineCompressor extends Compressor { /** * @inheritDoc */ @Override public CompressedText processPlainText(BufferedReader in) { ArrayList<String> dict = emptyDict; ArrayList<Atom> result = new ArrayList<>(); try { for (String line = in.readLine(); line!= null; line = in.readLine()) { // find a prefix in the dictionary Integer matchingLine=null; // the last line where a matching prefix was found for (int ii=0; ii<dict.size(); ii++) if (line.startsWith(dict.get(ii))) // i.e. dict[ii] is a prefix of line matchingLine=ii; if (matchingLine!=null) result.add(new Atom( matchingLine, // add the atom referencing the matching prefix line.substring(dict.get(matchingLine).length()) // followed by everything past the matching prefix )); else // no prefix found, just throw in the entire atom, referencing the empty string result.add( new Atom(0, line)); dict.add(line); // add to the dictionary; the entries have to match the uncompressor's inferred dictionary entries } } catch (IOException e) { e.printStackTrace(); } return new CompressedText(result); // encapsulate the result } } src/edu/bu/ec504/hw1p3/Tester.java +3 −15 Original line number Diff line number Diff line package edu.bu.ec504.hw1p3; import edu.bu.ec504.hw1p3.Compressor.CompressedText; import edu.bu.ec504.hw1p3.Compressor.Dictionary.Atom; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.PrintStream; import java.io.*; import java.net.URL; import java.nio.channels.Channels; import java.nio.channels.FileChannel; import java.nio.channels.ReadableByteChannel; import java.util.ArrayList; public class Tester { // CONSTANTS Loading @@ -25,7 +14,7 @@ public class Tester { // MAIN method public static void main(String[] args) { try { testResult result = testUrl(URLExample, new CharByCharCompressor()); // change this to myCompressor() to test your own compressor testResult result = testUrl(URLExample, new LineByLineCompressor()); // change this to myCompressor() to test your own compressor System.out.println("Statistics:" + "\n" + " Original size: " + result.originalSize + "\n" Loading Loading @@ -68,7 +57,6 @@ public class Tester { URL uu = new URL(inURL); ReadableByteChannel rbc = Channels.newChannel(uu.openStream()); FileOutputStream fos = new FileOutputStream(plainFile); FileChannel fcl = fos.getChannel(); fos.getChannel().transferFrom(rbc,0,Long.MAX_VALUE); // ... record the file size theFile = new File(plainFile); Loading Loading
src/edu/bu/ec504/hw1p3/CharByCharCompressor.java +1 −2 Original line number Diff line number Diff line package edu.bu.ec504.hw1p3; import edu.bu.ec504.hw1p3.Compressor.Dictionary.Atom; import java.io.BufferedReader; import java.io.IOException; import java.util.ArrayList; Loading @@ -8,7 +7,7 @@ import java.util.ArrayList; /** * A simple implementation of the {@link Compressor} class. * This implementation ignores the dictionary entirely, and simply encodes each character of * the input as a trivial {@link Compressor.Dictionary.Atom}, indexed against the empty string. * the input as a trivial {@link Compressor.Atom}, indexed against the empty string. */ public class CharByCharCompressor extends Compressor { Loading
src/edu/bu/ec504/hw1p3/Compressor.java +36 −25 Original line number Diff line number Diff line package edu.bu.ec504.hw1p3; import edu.bu.ec504.hw1p3.Compressor.Dictionary.Atom; import java.io.BufferedReader; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.List; public abstract class Compressor implements Serializable { // nested classes /** * A dictionary to be used in compression. */ static class Dictionary { /** * An immutable atom of compression that incorporates: * a. An integer representing an index into the dictionary {@link Dictionary#dict} * a. An integer representing an index into some dictionary. * b. A string that follows the dictionary word in a. */ static final class Atom implements Serializable { public Atom(int myIndex, String myNext) { index = myIndex; next = myNext; } public int getIndex() { return index; } public String getNext() { return next; } public Atom(int myIndex, String myNext) { index = myIndex; next = myNext; } private static final long serialVersionUID = 2L; // for serliazation private final int index; private final String next; public int getIndex() { return index; } Dictionary() { dict = new ArrayList<>(); public String getNext() { return next; } final ArrayList<String> dict; /** * Pretty print the atom. * @return A human-readable string representing this atom. */ @Override public String toString() { return "Atom{" + "index=" + index + ", next='" + next + '\'' + '}'; } private static final long serialVersionUID = 2L; // for serialization private final int index; private final String next; } /** * An encapsulation of a list of Atoms. */ public static class CompressedText implements Serializable { CompressedText(ArrayList<Atom> theData) { CompressedText(List<Atom> theData) { data=theData; } ArrayList<Atom> getList() { return data; } private ArrayList<Atom> data; private static final long serialVersionUID = 3L; // for serliazation List<Atom> getList() { return data; } private final List<Atom> data; private static final long serialVersionUID = 3L; // for serialization } Loading @@ -49,7 +61,6 @@ public abstract class Compressor implements Serializable { // CONSTRUCTORS Compressor() { } /** * Process additional plaintext from <code>in</code> and incorporates it into this compressed object. * @param in A BufferedReader linked to an input source. Loading @@ -61,10 +72,9 @@ public abstract class Compressor implements Serializable { * @return The uncompressed text corresponding to this object. */ final public String uncompress(CompressedText theCompressedText) { final ArrayList<String> dict = new ArrayList<>(); // a dictionary to be used in compression. dict.add(""); // starting point final ArrayList<String> dict = emptyDict; // a dictionary to be used in compression. StringBuilder result=new StringBuilder(""); StringBuilder result=new StringBuilder(); for (Atom anAtom: theCompressedText.getList()) { String nextStr=dict.get( anAtom.getIndex() ) + anAtom.getNext(); // the next String decoded from the theCompressedText result.append(nextStr); Loading @@ -75,5 +85,6 @@ public abstract class Compressor implements Serializable { // FIELDS private static final long serialVersionUID = 1L; // to allow serialization protected static final ArrayList<String> emptyDict = new ArrayList<>(Collections.singletonList("")); // contains just one string, the empty string }
src/edu/bu/ec504/hw1p3/LineByLineCompressor.java 0 → 100644 +42 −0 Original line number Diff line number Diff line package edu.bu.ec504.hw1p3; import java.io.BufferedReader; import java.io.IOException; import java.util.ArrayList; /** * A slightly more complicated example of a compressor. */ public class LineByLineCompressor extends Compressor { /** * @inheritDoc */ @Override public CompressedText processPlainText(BufferedReader in) { ArrayList<String> dict = emptyDict; ArrayList<Atom> result = new ArrayList<>(); try { for (String line = in.readLine(); line!= null; line = in.readLine()) { // find a prefix in the dictionary Integer matchingLine=null; // the last line where a matching prefix was found for (int ii=0; ii<dict.size(); ii++) if (line.startsWith(dict.get(ii))) // i.e. dict[ii] is a prefix of line matchingLine=ii; if (matchingLine!=null) result.add(new Atom( matchingLine, // add the atom referencing the matching prefix line.substring(dict.get(matchingLine).length()) // followed by everything past the matching prefix )); else // no prefix found, just throw in the entire atom, referencing the empty string result.add( new Atom(0, line)); dict.add(line); // add to the dictionary; the entries have to match the uncompressor's inferred dictionary entries } } catch (IOException e) { e.printStackTrace(); } return new CompressedText(result); // encapsulate the result } }
src/edu/bu/ec504/hw1p3/Tester.java +3 −15 Original line number Diff line number Diff line package edu.bu.ec504.hw1p3; import edu.bu.ec504.hw1p3.Compressor.CompressedText; import edu.bu.ec504.hw1p3.Compressor.Dictionary.Atom; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.PrintStream; import java.io.*; import java.net.URL; import java.nio.channels.Channels; import java.nio.channels.FileChannel; import java.nio.channels.ReadableByteChannel; import java.util.ArrayList; public class Tester { // CONSTANTS Loading @@ -25,7 +14,7 @@ public class Tester { // MAIN method public static void main(String[] args) { try { testResult result = testUrl(URLExample, new CharByCharCompressor()); // change this to myCompressor() to test your own compressor testResult result = testUrl(URLExample, new LineByLineCompressor()); // change this to myCompressor() to test your own compressor System.out.println("Statistics:" + "\n" + " Original size: " + result.originalSize + "\n" Loading Loading @@ -68,7 +57,6 @@ public class Tester { URL uu = new URL(inURL); ReadableByteChannel rbc = Channels.newChannel(uu.openStream()); FileOutputStream fos = new FileOutputStream(plainFile); FileChannel fcl = fos.getChannel(); fos.getChannel().transferFrom(rbc,0,Long.MAX_VALUE); // ... record the file size theFile = new File(plainFile); Loading