From 6713934813f01bbe3ce329a4001850820dd56ca6 Mon Sep 17 00:00:00 2001 From: pevillarreal Date: Mon, 11 May 2015 21:43:42 -0500 Subject: [PATCH] initial commit --- LocalTestRun.testrunconfig | 5 + PbvCompressor.Test/AuthoringTests.txt | 136 ++++++++++ PbvCompressor.Test/FileNameSelectorTest.cs | 94 +++++++ PbvCompressor.Test/PbvCompressor.Test.csproj | 73 ++++++ PbvCompressor.Test/PbvCompressorLZWTest.cs | 104 ++++++++ PbvCompressor.Test/Properties/AssemblyInfo.cs | 35 +++ .../Test References/PbvCompressor.accessor | 2 + PbvCompressor.gpState | 4 + PbvCompressor.sln | 36 +++ PbvCompressor.suo | Bin 0 -> 47104 bytes PbvCompressor.vsmdi | 6 + PbvCompressor/FileNameSelector.cs | 56 +++++ PbvCompressor/ICompressorAlgorithm.cs | 13 + PbvCompressor/PbvCompressor.csproj | 99 ++++++++ PbvCompressor/PbvCompressor.csproj.user | 15 ++ PbvCompressor/PbvCompressorLZW.cs | 235 ++++++++++++++++++ PbvCompressor/Program.cs | 70 ++++++ PbvCompressor/Properties/AssemblyInfo.cs | 38 +++ PbvCompressor1.vsmdi | 6 + 19 files changed, 1027 insertions(+) create mode 100644 LocalTestRun.testrunconfig create mode 100644 PbvCompressor.Test/AuthoringTests.txt create mode 100644 PbvCompressor.Test/FileNameSelectorTest.cs create mode 100644 PbvCompressor.Test/PbvCompressor.Test.csproj create mode 100644 PbvCompressor.Test/PbvCompressorLZWTest.cs create mode 100644 PbvCompressor.Test/Properties/AssemblyInfo.cs create mode 100644 PbvCompressor.Test/Test References/PbvCompressor.accessor create mode 100644 PbvCompressor.gpState create mode 100644 PbvCompressor.sln create mode 100644 PbvCompressor.suo create mode 100644 PbvCompressor.vsmdi create mode 100644 PbvCompressor/FileNameSelector.cs create mode 100644 PbvCompressor/ICompressorAlgorithm.cs create mode 100644 PbvCompressor/PbvCompressor.csproj create mode 100644 PbvCompressor/PbvCompressor.csproj.user create mode 100644 PbvCompressor/PbvCompressorLZW.cs create mode 100644 PbvCompressor/Program.cs create mode 100644 PbvCompressor/Properties/AssemblyInfo.cs create mode 100644 PbvCompressor1.vsmdi diff --git a/LocalTestRun.testrunconfig b/LocalTestRun.testrunconfig new file mode 100644 index 0000000..976c985 --- /dev/null +++ b/LocalTestRun.testrunconfig @@ -0,0 +1,5 @@ + + + This is a default test run configuration for a local test run. + + \ No newline at end of file diff --git a/PbvCompressor.Test/AuthoringTests.txt b/PbvCompressor.Test/AuthoringTests.txt new file mode 100644 index 0000000..c94b3cf --- /dev/null +++ b/PbvCompressor.Test/AuthoringTests.txt @@ -0,0 +1,136 @@ +========================================================================== + Visual Studio Team System: Overview of Authoring and Running Tests +========================================================================== + +This overview describes the features for authoring and running tests in +Visual Studio Team System and Visual Studio Team Edition for Software Testers. + +Opening Tests +------------- +To open a test, open a test project or a test metadata file (a file with +extension .vsmdi) that contains the definition of the test. You can find +test projects and metadata files in Solution Explorer. + +Viewing Tests +------------- +To see which tests are available to you, open the Test View window. Or, +if you have installed Team Edition for Software Testers, you can also open +the Test List Editor window to view tests. + +To open the Test View window, click the Test menu, point to Windows, and +then click Test View. To open the Test List Editor window (if you have +installed Team Edition for Software Testers), click Test, point to Windows, +and then click Test List Editor. + +Running Tests +------------- +You can run tests from the Test View window and the Test List Editor window. +See Viewing Tests to learn how to open these windows. To run one or more +tests displayed in the Test View window, first select the tests in that +window; to select multiple tests, hold either the Shift or CTRL key while +clicking tests. Then click the Run Tests button in the Test View window +toolbar. + +If you have installed Visual Studio Team Edition for Software Testers, you can +also use the Test List Editor window to run tests. To run tests in Test List Editor, +select the check box next to each test that you want to run. Then click the +Run Tests button in the Test List Editor window toolbar. + +Viewing Test Results +-------------------- +When you run a test or a series of tests, the results of the test run will be +shown in the Test Results window. Each individual test in the run is shown on +a separate line so that you can see its status. The window contains an +embedded status bar in the top half of the window that provides you with +summary details of the complete test run. + +To see more detailed results for a particular test result, double-click it in +the Test Results window. This opens a window that provides more information +about the particular test result, such as any specific error messages returned +by the test. + +Changing the way that tests are run +----------------------------------- +Each time you run one or more tests, a collection of settings is used to +determine how those tests are run. These settings are contained in a “test +run configuration” file. + +Here is a partial list of the changes you can make with a test run +configuration file: + + - Change the naming scheme for each test run. + - Change the test controller that the tests are run on so that you can run + tests remotely. + - Gather code coverage data for the code being tested so that you can see + which lines of code are covered by your tests. + - Enable and disable test deployment. + - Specify additional files to deploy before tests are run. + - Select a different host, ASP.NET, for running ASP.NET unit tests. + - Select a different host, the smart device test host, for running smart device unit tests. + - Set various properties for the test agents that run your tests. + - Run custom scripts at the start and end of each test run so that you can + set up the test environment exactly as required each time tests are run. + - Set time limits for tests and test runs. + - Set the browser mix and the number of times to repeat Web tests in the + test run. + +By default, a test run configuration file is created whenever you create a +new test project. You make changes to this file by double-clicking it in +Solution Explorer and then changing its settings. (Test run configuration +files have the extension .testrunconfig.) + +A solution can contain multiple test run configuration files. Only one of +those files, known as the “Active” test run configuration file, is used to +determine the settings that are currently used for test runs. You select +the active test run configuration by clicking Select Active Test Run +Configuration on the Test menu. + +------------------------------------------------------------------------------- + +Test Types +---------- +Using Visual Studio Team Edition for Software Testers, you can create a number +of different test types: + +Unit test: Use a unit test to create a programmatic test in C++, Visual C# or +Visual Basic that exercises source code. A unit test calls the methods of a +class, passing suitable parameters, and verifies that the returned value is +what you expect. +There are three specialized variants of unit tests: + - Data-driven unit tests are created when you configure a unit test to be + called repeatedly for each row of a data source. The data from each row + is used by the unit test as input data. + - ASP.NET unit tests are unit tests that exercise code in an ASP.NET Web + application. + - Smart device unit tests are unit tests that are deployed to a smart device + or emulator and then executed by the smart device test host. + +Web Test: Web tests consist of an ordered series of HTTP requests that you +record in a browser session using Microsoft Internet Explorer. You can have +the test report specific details about the pages or sites it requests, such +as whether a particular page contains a specified string. + +Load Test: You use a load test to encapsulate non-manual tests, such as +unit, Web, and generic tests, and then run them simultaneously by using +virtual users. Running these tests under load generates test results, +including performance and other counters, in tables and in graphs. + +Generic test: A generic test is an existing program wrapped to function as a +test in Visual Studio. The following are examples of tests or programs that +you can turn into generic tests: + - An existing test that uses process exit codes to communicate whether the + test passed or failed. 0 indicates passing and any other value indicates + a failure. + - A general program to obtain specific functionality during a test scenario. + - A test or program that uses a special XML file (called a “summary results + file”), to communicate detailed results. + +Manual test: The manual test type is used when the test tasks are to be +completed by a test engineer as opposed to an automated script. + +Ordered test: Use an ordered test to execute a set of tests in an order you +specify. + +------------------------------------------------------------------------------- + + diff --git a/PbvCompressor.Test/FileNameSelectorTest.cs b/PbvCompressor.Test/FileNameSelectorTest.cs new file mode 100644 index 0000000..d0613c8 --- /dev/null +++ b/PbvCompressor.Test/FileNameSelectorTest.cs @@ -0,0 +1,94 @@ +using PbvCompressor; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.IO; +using System; +namespace PbvCompressor.Test +{ + + + /// + ///This is a test class for FileNameSelectorTest and is intended + ///to contain all FileNameSelectorTest Unit Tests + /// + [TestClass()] + public class FileNameSelectorTest + { + + + private TestContext testContextInstance; + + /// + ///Gets or sets the test context which provides + ///information about and functionality for the current test run. + /// + public TestContext TestContext + { + get + { + return testContextInstance; + } + set + { + testContextInstance = value; + } + } + + #region Additional test attributes + // + //You can use the following additional attributes as you write your tests: + // + //Use ClassInitialize to run code before running the first test in the class + //[ClassInitialize()] + //public static void MyClassInitialize(TestContext testContext) + //{ + //} + // + //Use ClassCleanup to run code after all tests in a class have run + //[ClassCleanup()] + //public static void MyClassCleanup() + //{ + //} + // + //Use TestInitialize to run code before running each test + //[TestInitialize()] + //public void MyTestInitialize() + //{ + //} + // + //Use TestCleanup to run code after each test has run + //[TestCleanup()] + //public void MyTestCleanup() + //{ + //} + // + #endregion + + + + /// + ///A test for GetFileName + /// + [TestMethod()] + public void GetFileNameTest() //test selector + { + string pFileName = "testFilename"; + string expected = pFileName; + string actual; + actual = FileNameSelector.GetFileName(pFileName); + Assert.AreEqual(expected, actual); + + string pFileName2 = "testnName2"; + expected = pFileName2; + File.Create(pFileName); + StringReader sr = new StringReader("n" + Environment.NewLine + pFileName2 + Environment.NewLine); + Console.SetIn(sr); + actual = FileNameSelector.GetFileName(pFileName); + Assert.AreEqual(actual, expected); + + sr = new StringReader("y" + Environment.NewLine); + Console.SetIn(sr); + actual = FileNameSelector.GetFileName(pFileName); + Assert.AreEqual(actual, pFileName); + } + } +} diff --git a/PbvCompressor.Test/PbvCompressor.Test.csproj b/PbvCompressor.Test/PbvCompressor.Test.csproj new file mode 100644 index 0000000..3f7c839 --- /dev/null +++ b/PbvCompressor.Test/PbvCompressor.Test.csproj @@ -0,0 +1,73 @@ + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {01173E5A-1D21-4205-BC8A-9AAC10590367} + Library + Properties + PbvCompressor.Test + PbvCompressor.Test + v3.5 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + 3.5 + + + + 3.5 + + + + 3.5 + + + + + + + + + + + + + + + + {2A724694-2AD6-44B7-B63F-B0C46438DD4A} + PbvCompressor + + + + + \ No newline at end of file diff --git a/PbvCompressor.Test/PbvCompressorLZWTest.cs b/PbvCompressor.Test/PbvCompressorLZWTest.cs new file mode 100644 index 0000000..7042d85 --- /dev/null +++ b/PbvCompressor.Test/PbvCompressorLZWTest.cs @@ -0,0 +1,104 @@ +using PbvCompressor; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.IO; +namespace PbvCompressor.Test +{ + + + /// + ///This is a test class for PbvCompressorLZWTest and is intended + ///to contain all PbvCompressorLZWTest Unit Tests + /// + [TestClass()] + public class PbvCompressorLZWTest + { + + + private TestContext testContextInstance; + + /// + ///Gets or sets the test context which provides + ///information about and functionality for the current test run. + /// + public TestContext TestContext + { + get + { + return testContextInstance; + } + set + { + testContextInstance = value; + } + } + + #region Additional test attributes + // + //You can use the following additional attributes as you write your tests: + // + //Use ClassInitialize to run code before running the first test in the class + //[ClassInitialize()] + //public static void MyClassInitialize(TestContext testContext) + //{ + //} + // + //Use ClassCleanup to run code after all tests in a class have run + //[ClassCleanup()] + //public static void MyClassCleanup() + //{ + //} + // + //Use TestInitialize to run code before running each test + //[TestInitialize()] + //public void MyTestInitialize() + //{ + //} + // + //Use TestCleanup to run code after each test has run + //[TestCleanup()] + //public void MyTestCleanup() + //{ + //} + // + #endregion + + + /// + ///A test for Decompress + /// + [TestMethod()] + [DeploymentItem("PbvCompressor.exe")] + public void FullTest() //test compression and decompression + { + string line = "GEM8-GEU8,F,A,0,60303042,60303042,-0.14,1156AH8,F,B,0,60306043,60306043,90.51,106AH8,F,A,0,60306043,60306043,90.57,106AH8,F,B,0,60306092,60306092,90.52,106AM8,F,B,0,60306131,60306131,89.35,16AM8,F,A,0,60306131,60306131,89.5,3GEZ9-GEM0,F,B,0,60306436,60306436,0.415,175"; + string originalFileName = "originalTestFile"; + string outFileName = originalFileName + ".lzw"; + string inflatedName = originalFileName + ".inflated"; + StreamWriter writer = new StreamWriter(File.Create(originalFileName)); + writer.WriteLine(line); + writer.Close(); + + + PbvCompressorLZW_Accessor target = new PbvCompressorLZW_Accessor(); // TODO: Initialize to an appropriate value + string pInputFileName = originalFileName; + string pOutputFileName = outFileName; + bool expected = true; // TODO: Initialize to an appropriate value + bool actual; + + if (actual = ( target.Compress(originalFileName, outFileName) + && target.Decompress(outFileName, inflatedName))) + { + if (!File.Exists(pOutputFileName)) + actual = false; + else + { + StreamReader reader = new StreamReader(File.OpenRead(inflatedName)); + actual = line.Equals(reader.ReadToEnd().TrimEnd()); + reader.Close(); + } + } + + Assert.AreEqual(expected, actual); + } + } +} diff --git a/PbvCompressor.Test/Properties/AssemblyInfo.cs b/PbvCompressor.Test/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..b295a0f --- /dev/null +++ b/PbvCompressor.Test/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("PbvCompressor.Test")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("PbvCompressor.Test")] +[assembly: AssemblyCopyright("Copyright © 2011")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM componenets. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("6e6bbd73-0940-479b-bd8b-c6eaee9a43a3")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/PbvCompressor.Test/Test References/PbvCompressor.accessor b/PbvCompressor.Test/Test References/PbvCompressor.accessor new file mode 100644 index 0000000..d73f363 --- /dev/null +++ b/PbvCompressor.Test/Test References/PbvCompressor.accessor @@ -0,0 +1,2 @@ +PbvCompressor.exe +Desktop diff --git a/PbvCompressor.gpState b/PbvCompressor.gpState new file mode 100644 index 0000000..159ffa1 --- /dev/null +++ b/PbvCompressor.gpState @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/PbvCompressor.sln b/PbvCompressor.sln new file mode 100644 index 0000000..871ec6f --- /dev/null +++ b/PbvCompressor.sln @@ -0,0 +1,36 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PbvCompressor", "PbvCompressor\PbvCompressor.csproj", "{2A724694-2AD6-44B7-B63F-B0C46438DD4A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A819ED7C-7D8D-4718-A727-F5A10157D591}" + ProjectSection(SolutionItems) = preProject + LocalTestRun.testrunconfig = LocalTestRun.testrunconfig + PbvCompressor.vsmdi = PbvCompressor.vsmdi + PbvCompressor1.vsmdi = PbvCompressor1.vsmdi + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PbvCompressor.Test", "PbvCompressor.Test\PbvCompressor.Test.csproj", "{01173E5A-1D21-4205-BC8A-9AAC10590367}" +EndProject +Global + GlobalSection(TestCaseManagementSettings) = postSolution + CategoryFile = PbvCompressor1.vsmdi + EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2A724694-2AD6-44B7-B63F-B0C46438DD4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2A724694-2AD6-44B7-B63F-B0C46438DD4A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2A724694-2AD6-44B7-B63F-B0C46438DD4A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2A724694-2AD6-44B7-B63F-B0C46438DD4A}.Release|Any CPU.Build.0 = Release|Any CPU + {01173E5A-1D21-4205-BC8A-9AAC10590367}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {01173E5A-1D21-4205-BC8A-9AAC10590367}.Debug|Any CPU.Build.0 = Debug|Any CPU + {01173E5A-1D21-4205-BC8A-9AAC10590367}.Release|Any CPU.ActiveCfg = Release|Any CPU + {01173E5A-1D21-4205-BC8A-9AAC10590367}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/PbvCompressor.suo b/PbvCompressor.suo new file mode 100644 index 0000000000000000000000000000000000000000..11d8c9a347e0f152c96f1aaf5f4c7d5d9a835b41 GIT binary patch literal 47104 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 aR47a)ec9!IR_MV+Tz9{@Sj25k)c*(F_hGRB literal 0 HcmV?d00001 diff --git a/PbvCompressor.vsmdi b/PbvCompressor.vsmdi new file mode 100644 index 0000000..62bf9d3 --- /dev/null +++ b/PbvCompressor.vsmdi @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/PbvCompressor/FileNameSelector.cs b/PbvCompressor/FileNameSelector.cs new file mode 100644 index 0000000..b85eb47 --- /dev/null +++ b/PbvCompressor/FileNameSelector.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.IO; + +namespace PbvCompressor +{ + public class FileNameSelector + { + public static string GetFileName(string pFileName) + { + string newFileName = pFileName; + if (File.Exists(pFileName)) + { + Console.WriteLine(pFileName + " already exists. Overwrite it?"); + string response = PromptUserYNQ().ToLower(); + + if (response.Equals("n")) + newFileName = PromptUserFileName(); + else if (response.Equals("q")) + return null; + } + + return newFileName; + } + + private static string PromptUserYNQ() + { + Regex goodResponse = new Regex("[ynqYNQ]"); + string lineRead; + bool firstRun = true; + + do + { + if (!firstRun) + { + Console.WriteLine("Entered invalid option, try again..."); + } + + Console.WriteLine("[Y]es, [N]o, [Q]uit"); + lineRead = Console.ReadLine(); + firstRun = false; + } while (!goodResponse.IsMatch(lineRead)); + + return lineRead; + } + + private static string PromptUserFileName() + { + Console.WriteLine("Enter filename to use: "); + return Console.ReadLine(); + } + } +} diff --git a/PbvCompressor/ICompressorAlgorithm.cs b/PbvCompressor/ICompressorAlgorithm.cs new file mode 100644 index 0000000..0016526 --- /dev/null +++ b/PbvCompressor/ICompressorAlgorithm.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace PbvCompressor +{ + public interface ICompressorAlgorithm + { + bool Compress(string pIntputFileName, string pOutputFileName); + bool Decompress(string pIntputFileName, string pOutputFileName); + } +} diff --git a/PbvCompressor/PbvCompressor.csproj b/PbvCompressor/PbvCompressor.csproj new file mode 100644 index 0000000..f90d405 --- /dev/null +++ b/PbvCompressor/PbvCompressor.csproj @@ -0,0 +1,99 @@ + + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {2A724694-2AD6-44B7-B63F-B0C46438DD4A} + Exe + Properties + PbvCompressor + PbvCompressor + v3.5 + 512 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + + + + + + + + False + .NET Framework 2.0 %28x86%29 + false + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + true + + + False + Windows Installer 3.1 + true + + + + + \ No newline at end of file diff --git a/PbvCompressor/PbvCompressor.csproj.user b/PbvCompressor/PbvCompressor.csproj.user new file mode 100644 index 0000000..191b576 --- /dev/null +++ b/PbvCompressor/PbvCompressor.csproj.user @@ -0,0 +1,15 @@ + + + publish\ + + + + + + + + + en-US + false + + \ No newline at end of file diff --git a/PbvCompressor/PbvCompressorLZW.cs b/PbvCompressor/PbvCompressorLZW.cs new file mode 100644 index 0000000..4707b59 --- /dev/null +++ b/PbvCompressor/PbvCompressorLZW.cs @@ -0,0 +1,235 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.IO; + +namespace PbvCompressor +{ + //LZW Based Decompressor - basic algorithm used as described on Mark Nelson's website http://marknelson.us + class PbvCompressorLZW : ICompressorAlgorithm + { + private const int MAX_BITS = 14; //maimxum bits allowed to read + private const int HASH_BIT = MAX_BITS - 8; //hash bit to use with the hasing algorithm to find correct index + private const int MAX_VALUE = (1 << MAX_BITS) - 1; //max value allowed based on max bits + private const int MAX_CODE = MAX_VALUE - 1; //max code possible + private const int TABLE_SIZE = 18041; //must be bigger than the maximum allowed by maxbits and prime + + private int[] _iaCodeTable = new int[TABLE_SIZE]; //code table + private int[] _iaPrefixTable = new int[TABLE_SIZE]; //prefix table + private int[] _iaCharTable = new int[TABLE_SIZE]; //character table + + private ulong _iBitBuffer; //bit buffer to temporarily store bytes read from the files + private int _iBitCounter; //counter for knowing how many bits are in the bit buffer + + private void Initialize() //used to blank out bit buffer incase this class is called to comprss and decompress from the same instance + { + _iBitBuffer = 0; + _iBitCounter = 0; + } + + public bool Compress(string pInputFileName, string pOutputFileName) + { + BinaryReader reader = null; + BinaryWriter writer = null; + + try + { + Initialize(); + reader = new BinaryReader(File.OpenRead(pInputFileName), Encoding.ASCII); + writer = new BinaryWriter(File.Create(pOutputFileName), Encoding.ASCII); + int iNextCode = 256; + int iChar = 0, iString = 0, iIndex = 0; + + for (int i = 0; i < TABLE_SIZE; i++) //blank out table + _iaCodeTable[i] = -1; + + iString = reader.Read(); //get first code, will be 0-255 ascii char + + while((iChar = reader.Read()) != -1) //read until we reach end of file + { + iIndex = FindMatch(iString, iChar); //get correct index for prefix+char + + if (_iaCodeTable[iIndex] != -1) //set string if we have something at that index + iString = _iaCodeTable[iIndex]; + else //insert new entry + { + if (iNextCode <= MAX_CODE) //otherwise we insert into the tables + { + _iaCodeTable[iIndex] = iNextCode++; //insert and increment next code to use + _iaPrefixTable[iIndex] = iString; + _iaCharTable[iIndex] = (byte)iChar; + } + + WriteCode(writer, iString); //output the data in the string + iString = iChar; + } + } + + WriteCode(writer, iString); //output last code + WriteCode(writer, MAX_VALUE); //output end of buffer + WriteCode(writer, 0); //flush + } + catch(Exception ex) + { + Console.WriteLine(ex.StackTrace); + if (writer != null) + writer.Close(); + File.Delete(pOutputFileName); + return false; + } + finally + { + if (writer != null) + writer.Close(); + } + + return true; + } + + //hasing function, tries to find index of prefix+char, if not found returns -1 to signify space available + private int FindMatch(int pPrefix, int pChar) + { + int index = 0, offset = 0; + + index = (pChar << HASH_BIT) ^ pPrefix; + + offset = (index == 0) ? 1 : TABLE_SIZE - index; + + while (true) + { + if (_iaCodeTable[index] == -1) + return index; + + if (_iaPrefixTable[index] == pPrefix && _iaCharTable[index] == pChar) + return index; + + index -= offset; + if (index < 0) + index += TABLE_SIZE; + } + } + + private void WriteCode(BinaryWriter pWriter, int pCode) + { + _iBitBuffer |= (ulong)pCode << (32 - MAX_BITS - _iBitCounter); //make space and insert new code in buffer + _iBitCounter += MAX_BITS; //increment bit counter + + while (_iBitCounter >= 8) //write all the bytes we can + { + int temp = (byte)((_iBitBuffer >> 24) & 255); + pWriter.Write((byte)((_iBitBuffer >> 24) & 255)); //write byte from bit buffer + _iBitBuffer <<= 8; //remove written byte from buffer + _iBitCounter -= 8; //decrement counter + } + } + + public bool Decompress(string pInputFileName, string pOutputFileName) + { + BinaryReader reader = null; + BinaryWriter writer = null; + + try + { + Initialize(); + reader = new BinaryReader(File.OpenRead(pInputFileName), Encoding.ASCII); + writer = new BinaryWriter(File.Create(pOutputFileName), Encoding.ASCII); + int iNextCode = 256; + int iNewCode, iOldCode; + byte bChar; + int iCurrentCode, iCounter; + byte[] baDecodeStack = new byte[TABLE_SIZE]; + + iOldCode = ReadCode(reader); + bChar = (byte)iOldCode; + writer.Write((byte)iOldCode); //write first byte since it is plain ascii + + iNewCode = ReadCode(reader); + + while (iNewCode != MAX_VALUE) //read file all file + { + if (iNewCode >= iNextCode) + { //fix for prefix+chr+prefix+char+prefx special case + baDecodeStack[0] = bChar; + iCounter = 1; + iCurrentCode = iOldCode; + } + else + { + iCounter = 0; + iCurrentCode = iNewCode; + } + + while (iCurrentCode > 255) //decode string by cycling back through the prefixes + { + //lstDecodeStack.Add((byte)_iaCharTable[iCurrentCode]); + //iCurrentCode = _iaPrefixTable[iCurrentCode]; + baDecodeStack[iCounter] = (byte)_iaCharTable[iCurrentCode]; + ++iCounter; + if (iCounter >= MAX_CODE) + throw new Exception("oh crap"); + iCurrentCode = _iaPrefixTable[iCurrentCode]; + } + + baDecodeStack[iCounter] = (byte)iCurrentCode; + bChar = baDecodeStack[iCounter]; //set last char used + + while (iCounter >= 0) //write out decodestack + { + writer.Write(baDecodeStack[iCounter]); + --iCounter; + } + + if (iNextCode <= MAX_CODE) //insert into tables + { + _iaPrefixTable[iNextCode] = iOldCode; + _iaCharTable[iNextCode] = bChar; + ++iNextCode; + } + + iOldCode = iNewCode; + + //if (reader.PeekChar() != 0) + iNewCode = ReadCode(reader); + } + } + catch (System.IO.EndOfStreamException exEof) + { + writer.Close(); + } + catch (Exception ex) + { + Console.WriteLine(ex.StackTrace); + if (writer != null) + writer.Close(); + File.Delete(pOutputFileName); + return false; + } + finally + { + if (reader != null) + reader.Close(); + } + + return true; + } + + private int ReadCode(BinaryReader pReader) + { + uint iReturnVal; + + while (_iBitCounter <= 24) //fill up buffer + { + _iBitBuffer |= (ulong)pReader.ReadByte() << (24 - _iBitCounter); //insert byte into buffer + _iBitCounter += 8; //increment counter + } + + iReturnVal = (uint)_iBitBuffer >> (32 - MAX_BITS); //get last byte from buffer so we can return it + _iBitBuffer <<= MAX_BITS; //remove it from buffer + _iBitCounter -= MAX_BITS; //decrement bit counter + + int temp = (int)iReturnVal; + return temp; + } + } +} diff --git a/PbvCompressor/Program.cs b/PbvCompressor/Program.cs new file mode 100644 index 0000000..54fc993 --- /dev/null +++ b/PbvCompressor/Program.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace PbvCompressor +{ + public class PbvCompressor + { + private ICompressorAlgorithm _compressorAlgorithm; + + public ICompressorAlgorithm CompressorAlgorithm + { + // allows us to set the algorithm at runtime, also lets us set the algorithm dynamically if we creata factory class + set + { + _compressorAlgorithm = value; + } + } + + public PbvCompressor() + { + // setting this by default but we could create a facotry class to let us set the algorithm based on arguments passed to the main method + // IE. "Compress.exe zip -c blah.txt" would use the zip algorithm as opposed to the default one. + CompressorAlgorithm = new PbvCompressorLZW(); + } + + private void Start(string argument, string pInFile, string pOutFile) + { + string newOutFile = FileNameSelector.GetFileName(pOutFile); + + if (newOutFile == null) + { + Console.WriteLine("Exiting..."); + System.Environment.Exit(1); + } + + if (argument.Equals("-c")) + _compressorAlgorithm.Compress(pInFile, pOutFile); + else if (argument.Equals("-d")) + { + _compressorAlgorithm.Decompress(pInFile, pOutFile); + } + + return; + } + + static void Main(string[] args) + { + Regex validCommands = new Regex("-[cdCD]"); + PbvCompressor pc = null; + + if (args.Length != 3) + { + Console.WriteLine("Too many or too few arguments! Exiting."); + return; + } + else if (validCommands.IsMatch(args[0])) //if valid argments given proceed + { + pc = new PbvCompressor(); + pc.Start(args[0].ToLower(), args[1], args[2]); + } + else + Console.WriteLine("Invalid argument command given. Exiting."); + + return; + } + } +} \ No newline at end of file diff --git a/PbvCompressor/Properties/AssemblyInfo.cs b/PbvCompressor/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..f804495 --- /dev/null +++ b/PbvCompressor/Properties/AssemblyInfo.cs @@ -0,0 +1,38 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("PbvCompressor")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("PbvCompressor")] +[assembly: AssemblyCopyright("Copyright © 2011")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("a8d8bc2a-aec7-4475-92ca-fd40a50b7c89")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] + +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("PbvCompressor.UnitTest")] \ No newline at end of file diff --git a/PbvCompressor1.vsmdi b/PbvCompressor1.vsmdi new file mode 100644 index 0000000..62bf9d3 --- /dev/null +++ b/PbvCompressor1.vsmdi @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file