[
  {
    "path": ".gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User-specific files\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\n[Rr]eleases/\nx64/\nx86/\nbuild/\nbld/\n[Bb]in/\n[Oo]bj/\n\n# Roslyn cache directories\n*.ide/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n#NUNIT\n*.VisualState.xml\nTestResult.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n*_i.c\n*_p.c\n*_i.h\n*.ilk\n*.meta\n*.obj\n*.pch\n*.pdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opensdf\n*.sdf\n*.cachefile\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n\n# TFS 2012 Local Workspace\n$tf/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# JustCode is a .NET coding addin-in\n.JustCode\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n# TODO: Comment the next line if you want to checkin your web deploy settings \n# but database connection strings (with potential passwords) will be unencrypted\n*.pubxml\n*.publishproj\n\n# NuGet Packages\n*.nupkg\n# The packages folder can be ignored because of Package Restore\n**/packages/*\n# except build/, which is used as an MSBuild target.\n!**/packages/build/\n# If using the old MSBuild-Integrated Package Restore, uncomment this:\n#!**/packages/repositories.config\n\n# Windows Azure Build Output\ncsx/\n*.build.csdef\n\n# Windows Store app package directory\nAppPackages/\n\n# Others\nsql/\n*.Cache\nClientBin/\n[Ss]tyle[Cc]op.*\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.pfx\n*.publishsettings\nnode_modules/\nbower_components/\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\n\n# SQL Server files\n*.mdf\n*.ldf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n\n# Microsoft Fakes\nFakesAssemblies/\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\r\n\r\nCopyright (c) 2014 https://github.com/kjerk\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE."
  },
  {
    "path": "README.md",
    "content": "sjisunzip\n=========\n\nThis is a pretty braindead command line utility that simply forces the encoding to the right values to extract a Shift JIS encoded zip file ('[Code page 932](http://en.wikipedia.org/wiki/Code_page_932)') on a western/ansi encoding system.\n\n[Download Here](https://github.com/kjerk/sjisunzip/releases)\n\n```\nUsage:\n  sjisunzip someFile.zip [toFolder]\n  sjisunzip [-r] someFile.zip\n    -r: Recode file to {filename}_utf8.zip\nExamples:\n  sjisunzip aFile.zip\n  sjisunzip aFile.zip MyNewFolder\n```\n\nYou can also just drop a zip file onto the program since that'll pass it as the first argument and the contents will be extracted in the same directory.\n\nIf you've ever received a zip file from a friend, or the wrong damn gnu mirror or whatever that passed through Japan then you've probably seen garbled filenames\n![example_1](https://cloud.githubusercontent.com/assets/2738686/5326938/37acc0de-7ce7-11e4-8259-06ef8b1f43a8.jpg)\n---\n\nWell this program forces the opened zip to the correct encoding then extracts the file to a more reasonable UTF encoding.\n![example_2](https://cloud.githubusercontent.com/assets/2738686/5326978/712d7e50-7ce9-11e4-8f18-c885afc51055.jpg)\n---\n\nYou can even just reencode the zip file to a less busted-ass one so you don't have this creeping horror issue in the future\n![example_3](https://cloud.githubusercontent.com/assets/2738686/5326937/37ab2878-7ce7-11e4-9655-61b92a2b680d.jpg)\n---\n\nThe filenames and paths should be untangled when done.\n![example_4](https://cloud.githubusercontent.com/assets/2738686/5326940/37af9d72-7ce7-11e4-8ee2-3a9d11c6e669.jpg)\n---\n\nBonus fact: When this type of transitive corruption occurs, the output characters are called [Mojibake](http://en.wikipedia.org/wiki/Mojibake). That's almost cute enough to not be awful anymore.\n"
  },
  {
    "path": "SjisUnzip/App.config",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<configuration>\r\n    <startup> \r\n        <supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.5\"/>\r\n    </startup>\r\n</configuration>\r\n"
  },
  {
    "path": "SjisUnzip/AppRunner.cs",
    "content": "﻿namespace SjisUnzip\r\n{\r\n\t/// <summary>\r\n\t/// Bootstrapper to get out of the static context.\r\n\t/// </summary>\r\n\tstatic class AppRunner\r\n\t{\r\n\t\tstatic void Main(string[] args)\r\n\t\t{\r\n\t\t\tvar mainApp = new SjisUnzipApp();\r\n\t\t\tmainApp.Main(args);\r\n\t\t} \r\n\t}\r\n}"
  },
  {
    "path": "SjisUnzip/ExtensionMethods.cs",
    "content": "﻿using System;\r\nusing System.Collections.Generic;\r\nusing System.Globalization;\r\nusing System.IO;\r\nusing System.Linq;\r\nusing System.Text;\r\nusing System.Threading.Tasks;\r\n\r\nnamespace SjisUnzip\r\n{\r\n\tpublic static class ExtensionMethods\r\n\t{\r\n\t\t//\r\n\t\t// System.String\r\n\t\t//\r\n\r\n\t\t/// <summary>\r\n\t\t/// Checks whether a string contains any characters outside the typical ascii range. 127 or higher.\r\n\t\t/// </summary>\r\n\t\t/// <param name=\"str\">A string dum dum.</param>\r\n\t\t/// <returns>Boolean flag</returns>\r\n\t\tpublic static bool ContainsNonAscii(this string str)\r\n\t\t{\r\n\t\t\t// http://www.asciitable.com/\r\n\t\t\treturn str.Any(t => t > 0x7E);\r\n\t\t}\r\n\r\n\t\t/// <summary>\r\n\t\t/// A function to do a raw reinterpretation of character encoding without using the .Convert() function.\r\n\t\t/// This allows accidentally transposed strings to have their encoding fixed by reversing the process.\r\n\t\t/// </summary>\r\n\t\t/// <param name=\"str\">The string being operated on.</param>\r\n\t\t/// <param name=\"from\">The source encoding the bytes will be extracted as.</param>\r\n\t\t/// <param name=\"to\">The destination encoding the bytes will be 'interpreted' as.</param>\r\n\t\t/// <returns>The reinterpreted string.</returns>\r\n\t\tpublic static string RawTranscode(this string str, Encoding from, Encoding to)\r\n\t\t{\r\n\t\t\tvar rawBytes = from.GetBytes(str);\r\n\t\t\treturn to.GetString(rawBytes);\r\n\t\t}\r\n\r\n\t\t/// <summary>\r\n\t\t/// A wrapper for the RawTranscode() function which passes the correct parameters for fixing Sjis mishaps.\r\n\t\t/// </summary>\r\n\t\t/// <see cref=\"RawTranscode\"/>\r\n\t\t/// <param name=\"str\">The garbled string.</param>\r\n\t\t/// <returns>A fixed unicode string.</returns>\r\n\t\tpublic static string DecodeMojibake(this string str)\r\n\t\t{\r\n\t\t\treturn str.RawTranscode(Encoding.Default, Encoding.GetEncoding(932));\r\n\t\t}\r\n\r\n\t\t/// <summary>\r\n\t\t/// Checks the contents of a string to see if any are within CJK and a few other unicode ranges.\r\n\t\t/// </summary>\r\n\t\t/// <remarks>\r\n\t\t/// See <a href=\"http://www.rikai.com/library/kanjitables/kanji_codes.unicode.shtml\">Reference Document</a> for ranges.\r\n\t\t/// </remarks>\r\n\t\t/// <param name=\"str\">Any string.</param>\r\n\t\t/// <returns>Boolean flag if any characters found.</returns>\r\n\t\tpublic static bool ContainsJapanese(this string str)\r\n\t\t{\r\n\t\t\treturn str.Any(c =>\r\n\t\t\t\t// Punctuation, Hiragana, Katakana\r\n\t\t\t\t(c > 0x3000 && c < 0x30ff) ||\r\n\t\t\t\t// Romaji and half-width kana\r\n\t\t\t\t(c > 0xff00 && c < 0xffef) ||\r\n\t\t\t\t// CJK Extension\r\n\t\t\t\t(c > 0x3400 && c < 0x4dbf) ||\r\n\t\t\t\t// CJK\r\n\t\t\t\t(c > 0x4e00 && c < 0x9fff)\r\n\t\t\t);\r\n\t\t}\r\n\r\n\t\t/// <summary>\r\n\t\t/// Convenience method calling Console.WriteLine. Looks cool too.\r\n\t\t/// </summary>\r\n\t\t/// <example>\r\n\t\t/// \"Hello World\".wl();\r\n\t\t/// </example>\r\n\t\tpublic static void wl(this string str)\r\n\t\t{\r\n\t\t\tConsole.WriteLine(str);\r\n\t\t}\r\n\r\n\t\t/// <summary>\r\n\t\t/// Convenience method for calling Console.WriteLine with params.\r\n\t\t/// </summary>\r\n\t\t/// <param name=\"str\">The input format string.</param>\r\n\t\t/// <param name=\"o\">Args for populating the format string.</param>\r\n\t\t/// <example>\r\n\t\t/// \"Elapsed time was {0} seconds.\".wl(timer.getSeconds());\r\n\t\t/// </example>\r\n\t\tpublic static void wl(this string str, params object[] o)\r\n\t\t{\r\n\t\t\tConsole.WriteLine(str, o);\r\n\t\t}\r\n\r\n\t\t//\r\n\t\t// System.IO.FileInfo\r\n\t\t//\r\n\r\n\t\t/// <summary>\r\n\t\t/// Renames a file while keeping it in the same directory. The typical MoveTo is considered absolute,\r\n\t\t/// whereas this is considered relative.\r\n\t\t/// </summary>\r\n\t\t/// <param name=\"fi\">The operating fileInfo.</param>\r\n\t\t/// <param name=\"newName\">A new filename.</param>\r\n\t\tpublic static void Rename(this FileInfo fi, string newName)\r\n\t\t{\r\n\t\t\tfi.MoveTo(Path.Combine(fi.Directory.FullName, newName));\r\n\t\t}\r\n\r\n\t\t/// <summary>\r\n\t\t/// Renames a file in place and keeps the original extension regardless of what the new name is.\r\n\t\t/// </summary>\r\n\t\t/// <param name=\"fi\">The operating fileInfo.</param>\r\n\t\t/// <param name=\"newName\">A new filename which will have the original extension appended onto.</param>\r\n\t\tpublic static void RenameKeepExt(this FileInfo fi, string newName)\r\n\t\t{\r\n\t\t\tfi.MoveTo(Path.Combine(fi.Directory.FullName, newName) + Path.GetExtension(fi.FullName));\r\n\t\t}\r\n\r\n\t\t//\r\n\t\t// System.IO.DirectoryInfo\r\n\t\t//\r\n\r\n\t\t/// <summary>\r\n\t\t/// Does an in-place rename of a directory. Path modifications will not work properly (e.g. ../myname).\r\n\t\t/// </summary>\r\n\t\t/// <param name=\"di\">The operating DirectoryInfo</param>\r\n\t\t/// <param name=\"newName\">A new name for the directory.</param>\r\n\t\tpublic static void Rename(this DirectoryInfo di, string newName)\r\n\t\t{\r\n\t\t\tdi.MoveTo(Path.Combine(di.Parent.FullName, newName));\r\n\t\t}\r\n\t}\r\n}\r\n"
  },
  {
    "path": "SjisUnzip/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\r\nusing System.Runtime.CompilerServices;\r\nusing System.Runtime.InteropServices;\r\n\r\n// General Information about an assembly is controlled through the following \r\n// set of attributes. Change these attribute values to modify the information\r\n// associated with an assembly.\r\n[assembly: AssemblyTitle(\"SjisUnzip\")]\r\n[assembly: AssemblyDescription(\"\")]\r\n[assembly: AssemblyConfiguration(\"\")]\r\n[assembly: AssemblyCompany(\"\")]\r\n[assembly: AssemblyProduct(\"SjisUnzip\")]\r\n[assembly: AssemblyCopyright(\"Copyright © 2014\")]\r\n[assembly: AssemblyTrademark(\"\")]\r\n[assembly: AssemblyCulture(\"\")]\r\n\r\n// Setting ComVisible to false makes the types in this assembly not visible \r\n// to COM components.  If you need to access a type in this assembly from \r\n// COM, set the ComVisible attribute to true on that type.\r\n[assembly: ComVisible(false)]\r\n\r\n// The following GUID is for the ID of the typelib if this project is exposed to COM\r\n[assembly: Guid(\"79ffa4e3-8a00-426a-8179-2b033731cb9e\")]\r\n\r\n// Version information for an assembly consists of the following four values:\r\n//\r\n//      Major Version\r\n//      Minor Version \r\n//      Build Number\r\n//      Revision\r\n//\r\n// You can specify all the values or you can default the Build and Revision Numbers \r\n// by using the '*' as shown below:\r\n// [assembly: AssemblyVersion(\"1.0.*\")]\r\n[assembly: AssemblyVersion(\"1.0.0.0\")]\r\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\r\n"
  },
  {
    "path": "SjisUnzip/SjisUnzip.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"12.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\r\n  <PropertyGroup>\r\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\r\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\r\n    <ProjectGuid>{1AAE9514-FA5C-44AD-86BF-B2F44466D6B8}</ProjectGuid>\r\n    <OutputType>Exe</OutputType>\r\n    <AppDesignerFolder>Properties</AppDesignerFolder>\r\n    <RootNamespace>SjisUnzip</RootNamespace>\r\n    <AssemblyName>sjisunzip</AssemblyName>\r\n    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>\r\n    <FileAlignment>512</FileAlignment>\r\n    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>\r\n    <TargetFrameworkProfile />\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\r\n    <PlatformTarget>AnyCPU</PlatformTarget>\r\n    <DebugSymbols>true</DebugSymbols>\r\n    <DebugType>full</DebugType>\r\n    <Optimize>false</Optimize>\r\n    <OutputPath>bin\\Debug\\</OutputPath>\r\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\r\n    <ErrorReport>prompt</ErrorReport>\r\n    <WarningLevel>4</WarningLevel>\r\n    <Prefer32Bit>false</Prefer32Bit>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\r\n    <PlatformTarget>AnyCPU</PlatformTarget>\r\n    <DebugType>pdbonly</DebugType>\r\n    <Optimize>true</Optimize>\r\n    <OutputPath>bin\\Release\\</OutputPath>\r\n    <DefineConstants>TRACE</DefineConstants>\r\n    <ErrorReport>prompt</ErrorReport>\r\n    <WarningLevel>4</WarningLevel>\r\n    <Prefer32Bit>false</Prefer32Bit>\r\n  </PropertyGroup>\r\n  <PropertyGroup>\r\n    <StartupObject>SjisUnzip.AppRunner</StartupObject>\r\n  </PropertyGroup>\r\n  <ItemGroup>\r\n    <Reference Include=\"System\" />\r\n    <Reference Include=\"System.Core\" />\r\n    <Reference Include=\"System.IO.Compression\" />\r\n    <Reference Include=\"System.IO.Compression.FileSystem\" />\r\n    <Reference Include=\"System.Xml.Linq\" />\r\n    <Reference Include=\"System.Data.DataSetExtensions\" />\r\n    <Reference Include=\"Microsoft.CSharp\" />\r\n    <Reference Include=\"System.Data\" />\r\n    <Reference Include=\"System.Xml\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Compile Include=\"AppRunner.cs\" />\r\n    <Compile Include=\"ExtensionMethods.cs\" />\r\n    <Compile Include=\"SjisUnzipApp.cs\" />\r\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"App.config\" />\r\n  </ItemGroup>\r\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\r\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \r\n       Other similar extension points exist, see Microsoft.Common.targets.\r\n  <Target Name=\"BeforeBuild\">\r\n  </Target>\r\n  <Target Name=\"AfterBuild\">\r\n  </Target>\r\n  -->\r\n</Project>"
  },
  {
    "path": "SjisUnzip/SjisUnzipApp.cs",
    "content": "﻿using System;\r\nusing System.Collections.Generic;\r\nusing System.Globalization;\r\nusing System.IO;\r\nusing System.Linq;\r\nusing System.Text;\r\nusing System.Threading.Tasks;\r\nusing System.IO.Compression;\r\n\r\nnamespace SjisUnzip\r\n{\r\n\tpublic class SjisUnzipApp\r\n\t{\r\n\t\tprivate readonly Encoding sjisEncoding = Encoding.GetEncoding(932);\r\n\r\n\t\tpublic void Main(string[] args)\r\n\t\t{\r\n\t\t\tvar recode = args.Any((s) => s.Equals(\"-r\"));\r\n\r\n\t\t\tif (recode && args.Length == 2)\r\n\t\t\t{\r\n\t\t\t\targs = args.Where((arg) => arg != \"-r\").ToArray();\r\n\t\t\t\tif (args.Length > 0 && File.Exists(args[0]))\r\n\t\t\t\t{\r\n\t\t\t\t\trecodeFile(args[0]);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\telse if (args.Length == 1 && Directory.Exists(args[0]))\r\n\t\t\t{\r\n\t\t\t\trecodeCorruptFilenames(args[0], true);\r\n\t\t\t}\r\n\t\t\telse if (args.Length == 1 && File.Exists(args[0]) && args[0].EndsWith(\".zip\", true, CultureInfo.CurrentCulture))\r\n\t\t\t{\r\n\t\t\t\textractSjisZip(args[0]);\r\n\t\t\t}\r\n\t\t\telse if (args.Length == 2 && File.Exists(args[0]) && args[0].EndsWith(\".zip\", true, CultureInfo.CurrentCulture))\r\n\t\t\t{\r\n\t\t\t\tvar folderPath = Path.GetDirectoryName(args[0]);\r\n\t\t\t\tvar newFolderPath = Path.Combine(folderPath, args[1]);\r\n\t\t\t\tDirectory.CreateDirectory(newFolderPath);\r\n\t\t\t\textractSjisZip(args[0], newFolderPath);\r\n\t\t\t}\r\n\t\t\telse\r\n\t\t\t{\r\n\t\t\t\tprintUsage();\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tstatic void printUsage()\r\n\t\t{\r\n\t\t\t\"Usage: sjisunzip someFile.zip [toFolder]\".wl();\r\n\t\t\t\"Usage: sjisunzip [-r] someFile.zip\".wl();\r\n\t\t\t\"    -r: Recode file to {filename}_utf8.zip\".wl();\r\n\t\t\t\"Usage: sjisunzip ./some_folder_with_corrupt_filenames\".wl();\r\n\t\t\t\"Examples:\".wl();\r\n\t\t\t\"    sjisunzip aFile.zip\".wl();\r\n\t\t\t\"    sjisunzip aFile.zip MyNewFolder\".wl();\r\n\t\t}\r\n\r\n\t\tprivate void extractSjisZip(string fileName, string toFolder = \"./\")\r\n\t\t{\r\n\t\t\t\"Writing to folder {0}...\".wl(toFolder);\r\n\r\n\t\t\tusing (var zipFile = new ZipArchive(new FileStream(fileName, FileMode.Open, FileAccess.Read), \r\n\t\t\t\tZipArchiveMode.Read, false, Encoding.GetEncoding(932)))\r\n\t\t\t{\r\n\t\t\t\tzipFile.ExtractToDirectory(toFolder);\r\n\t\t\t}\r\n\r\n\t\t\t\"Done.\".wl();\r\n\t\t}\r\n\r\n\t\tprivate void recodeFile(string srcFile)\r\n\t\t{\r\n\t\t\tvar zipFile = new ZipArchive(new FileStream(srcFile, FileMode.Open), ZipArchiveMode.Read, false, sjisEncoding);\r\n\t\t\tvar newFilePath = Path.Combine(Path.GetDirectoryName(srcFile), Path.GetFileNameWithoutExtension(srcFile) + \"_utf8.zip\");\r\n\r\n\t\t\tusing (var newZip = new ZipArchive(new FileStream(newFilePath, FileMode.CreateNew), ZipArchiveMode.Create, false, Encoding.UTF8))\r\n\t\t\t{\r\n\t\t\t\tforeach (var zipEntry in zipFile.Entries)\r\n\t\t\t\t{\r\n\t\t\t\t\tvar newFile = newZip.CreateEntry(zipEntry.FullName, CompressionLevel.Fastest);\r\n\r\n\t\t\t\t\tnewFile.LastWriteTime = zipEntry.LastWriteTime;\r\n\r\n\t\t\t\t\tusing (Stream newStream = newFile.Open(), oldStream = zipEntry.Open())\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\t\"Moved {0}\".wl(newFile.FullName);\r\n\t\t\t\t\t\toldStream.CopyTo(newStream);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t\"Finished recoding {0} entries.\".wl(zipFile.Entries.Count);\r\n        }\r\n\r\n\t\treadonly Func<char, bool> dirSeparatorComparator = c => c == Path.DirectorySeparatorChar;\r\n\r\n\t\tprivate void recodeCorruptFilenames(string directoryPath, bool recurse)\r\n\t\t{\r\n\t\t\tvar rootDir = new DirectoryInfo(directoryPath);\r\n\t\t\tvar dirs = rootDir.GetDirectories(\"*\", recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly).ToList();\r\n\t\t\tvar files = rootDir.GetFiles(\"*\", recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);\r\n\r\n\t\t\tfiles.Where(fi => fi.Name.ContainsNonAscii() && !fi.Name.ContainsJapanese())\r\n\t\t\t\t.ToList()\r\n\t\t\t\t.ForEach(\r\n\t\t\t\t\tfi => fi.Rename(fi.Name.DecodeMojibake())\r\n\t\t\t\t);\r\n\t\t\t\r\n\t\t\t// Sort reversed based on directory depth, rename deepest first and this won't rename a root before a leaf.\r\n\t\t\tdirs.Sort((d2, d1) => d1.FullName.Count(dirSeparatorComparator).CompareTo(d2.FullName.Count(dirSeparatorComparator)));\r\n\r\n\t\t\tdirs.Where(di => di.Name.ContainsNonAscii() && !di.Name.ContainsJapanese())\r\n\t\t\t\t.ToList()\r\n\t\t\t\t.ForEach(\r\n\t\t\t\t\tdi => di.Rename(di.Name.DecodeMojibake())\r\n\t\t\t\t);\r\n\r\n\t\t\tif (rootDir.Name.ContainsNonAscii() && !rootDir.Name.ContainsJapanese())\r\n\t\t\t{\r\n\t\t\t\trootDir.Rename(rootDir.Name.DecodeMojibake());\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}\r\n"
  },
  {
    "path": "SjisUnzip.sln",
    "content": "﻿\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio 2013\r\nVisualStudioVersion = 12.0.31101.0\r\nMinimumVisualStudioVersion = 10.0.40219.1\r\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"SjisUnzip\", \"SjisUnzip\\SjisUnzip.csproj\", \"{1AAE9514-FA5C-44AD-86BF-B2F44466D6B8}\"\r\nEndProject\r\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"SjisUnzipTests\", \"SjisUnzipTests\\SjisUnzipTests.csproj\", \"{0076D69F-56C1-4F2E-9ABE-0FB187824D37}\"\r\nEndProject\r\nGlobal\r\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\r\n\t\tDebug|Any CPU = Debug|Any CPU\r\n\t\tRelease|Any CPU = Release|Any CPU\r\n\tEndGlobalSection\r\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n\t\t{1AAE9514-FA5C-44AD-86BF-B2F44466D6B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{1AAE9514-FA5C-44AD-86BF-B2F44466D6B8}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{1AAE9514-FA5C-44AD-86BF-B2F44466D6B8}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{1AAE9514-FA5C-44AD-86BF-B2F44466D6B8}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{0076D69F-56C1-4F2E-9ABE-0FB187824D37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{0076D69F-56C1-4F2E-9ABE-0FB187824D37}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{0076D69F-56C1-4F2E-9ABE-0FB187824D37}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{0076D69F-56C1-4F2E-9ABE-0FB187824D37}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\tEndGlobalSection\r\n\tGlobalSection(SolutionProperties) = preSolution\r\n\t\tHideSolutionNode = FALSE\r\n\tEndGlobalSection\r\nEndGlobal\r\n"
  },
  {
    "path": "SjisUnzipTests/ExtensionTests.cs",
    "content": "﻿using System;\r\nusing System.Globalization;\r\nusing System.Text;\r\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\r\nusing SjisUnzip;\r\n\r\nnamespace SjisUnzipTests\r\n{\r\n\t[TestClass]\r\n\tpublic class ExtensionTests\r\n\t{\r\n\t\tprivate readonly Encoding sjisEncoding = Encoding.GetEncoding(932);\r\n\r\n\t\tprivate readonly string textGarbled = \"iƒeƒLƒXƒgƒtƒ@ƒCƒ‹j\"; //  \"（テキストファイル）\"\r\n\t\tprivate readonly string textCorrect = \"（テキストファイル）\"; // \"(TextFile)\"\r\n\t\tprivate readonly string textAscii = \"\\\"One bad programmer can easily create two new jobs a year.\\\" - David Parnas\";\r\n\r\n\t\t[TestMethod]\r\n\t\tpublic void TestContainsNonAscii()\r\n\t\t{\r\n\t\t\tvar res = textGarbled.ContainsNonAscii();\r\n\t\t\tAssert.IsTrue(res);\r\n\r\n\t\t\tres = textCorrect.ContainsNonAscii();\r\n\t\t\tAssert.IsTrue(res);\r\n\r\n\t\t\tres = textAscii.ContainsNonAscii();\r\n\t\t\tAssert.IsFalse(res);\r\n\t\t}\r\n\r\n\t\t[TestMethod]\r\n\t\tpublic void TestRawTranscode()\r\n\t\t{\r\n\t\t\tvar degarbled = textGarbled.RawTranscode(Encoding.Default, Encoding.GetEncoding(932));\r\n            Assert.AreEqual(textCorrect, degarbled, \"Degarbled text should be equivalent to the uncorrupted original.\");\r\n\r\n\t\t\tvar engarbled = textCorrect.RawTranscode(Encoding.GetEncoding(932), Encoding.Default);\r\n\t\t\tAssert.AreEqual(textGarbled, engarbled, \"Reversing the garbling process on correct text should match the example garbled version.\");\r\n\t\t}\r\n\r\n\t\t[TestMethod]\r\n\t\tpublic void TestDecodeMojibake()\r\n\t\t{\r\n\t\t\tvar degarbled = textGarbled.DecodeMojibake();\r\n\t\t\tAssert.AreEqual(textCorrect, degarbled, \"Degarbled text should be equivalent to the uncorrupted original.\");\r\n\t\t}\r\n\r\n\t\t[TestMethod]\r\n\t\tpublic void TestContainsJapanese()\r\n\t\t{\r\n\t\t\tvar res = textAscii.ContainsJapanese();\r\n\t\t\tAssert.IsFalse(res, \"Plain ascii strings should obviously not trigger true on this function.\");\r\n\r\n\t\t\tres = textGarbled.ContainsJapanese();\r\n\t\t\tAssert.IsFalse(res);\r\n\r\n\t\t\tres = textCorrect.ContainsJapanese();\r\n\t\t\tAssert.IsTrue(res);\r\n\t\t}\r\n\t}\r\n}\r\n"
  },
  {
    "path": "SjisUnzipTests/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\r\nusing System.Runtime.CompilerServices;\r\nusing System.Runtime.InteropServices;\r\n\r\n// General Information about an assembly is controlled through the following \r\n// set of attributes. Change these attribute values to modify the information\r\n// associated with an assembly.\r\n[assembly: AssemblyTitle(\"SjisUnzipTests\")]\r\n[assembly: AssemblyDescription(\"\")]\r\n[assembly: AssemblyConfiguration(\"\")]\r\n[assembly: AssemblyCompany(\"\")]\r\n[assembly: AssemblyProduct(\"SjisUnzipTests\")]\r\n[assembly: AssemblyCopyright(\"Copyright ©  2014\")]\r\n[assembly: AssemblyTrademark(\"\")]\r\n[assembly: AssemblyCulture(\"\")]\r\n\r\n// Setting ComVisible to false makes the types in this assembly not visible \r\n// to COM components.  If you need to access a type in this assembly from \r\n// COM, set the ComVisible attribute to true on that type.\r\n[assembly: ComVisible(false)]\r\n\r\n// The following GUID is for the ID of the typelib if this project is exposed to COM\r\n[assembly: Guid(\"bc5c23de-d2c0-4ce8-a73c-7844b3af0ff5\")]\r\n\r\n// Version information for an assembly consists of the following four values:\r\n//\r\n//      Major Version\r\n//      Minor Version \r\n//      Build Number\r\n//      Revision\r\n//\r\n// You can specify all the values or you can default the Build and Revision Numbers \r\n// by using the '*' as shown below:\r\n// [assembly: AssemblyVersion(\"1.0.*\")]\r\n[assembly: AssemblyVersion(\"1.0.0.0\")]\r\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\r\n"
  },
  {
    "path": "SjisUnzipTests/SjisUnzipAppTests.cs",
    "content": "﻿using Microsoft.VisualStudio.TestTools.UnitTesting;\r\nusing Moq;\r\nusing SjisUnzip;\r\n\r\nnamespace SjisUnzipTests\r\n{\r\n\t[TestClass]\r\n\tpublic class SjisUnzipAppTests\r\n\t{\r\n\t\t[Ignore]\r\n\t\t[TestMethod]\r\n\t\tpublic void TestRunWithFile()\r\n\t\t{\r\n\t\t\t// TODO: Refactor SjisUnzipApp to be more unit testable.\r\n\t\t\t// TODO: Try to not make a unit test just so you put a todo in it to shame yourself.\r\n\t\t}\r\n\t}\r\n}"
  },
  {
    "path": "SjisUnzipTests/SjisUnzipTests.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"12.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <PropertyGroup>\r\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\r\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\r\n    <ProjectGuid>{0076D69F-56C1-4F2E-9ABE-0FB187824D37}</ProjectGuid>\r\n    <OutputType>Library</OutputType>\r\n    <AppDesignerFolder>Properties</AppDesignerFolder>\r\n    <RootNamespace>SjisUnzipTests</RootNamespace>\r\n    <AssemblyName>SjisUnzipTests</AssemblyName>\r\n    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>\r\n    <FileAlignment>512</FileAlignment>\r\n    <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>\r\n    <VisualStudioVersion Condition=\"'$(VisualStudioVersion)' == ''\">10.0</VisualStudioVersion>\r\n    <VSToolsPath Condition=\"'$(VSToolsPath)' == ''\">$(MSBuildExtensionsPath32)\\Microsoft\\VisualStudio\\v$(VisualStudioVersion)</VSToolsPath>\r\n    <ReferencePath>$(ProgramFiles)\\Common Files\\microsoft shared\\VSTT\\$(VisualStudioVersion)\\UITestExtensionPackages</ReferencePath>\r\n    <IsCodedUITest>False</IsCodedUITest>\r\n    <TestProjectType>UnitTest</TestProjectType>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\r\n    <DebugSymbols>true</DebugSymbols>\r\n    <DebugType>full</DebugType>\r\n    <Optimize>false</Optimize>\r\n    <OutputPath>bin\\Debug\\</OutputPath>\r\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\r\n    <ErrorReport>prompt</ErrorReport>\r\n    <WarningLevel>4</WarningLevel>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\r\n    <DebugType>pdbonly</DebugType>\r\n    <Optimize>true</Optimize>\r\n    <OutputPath>bin\\Release\\</OutputPath>\r\n    <DefineConstants>TRACE</DefineConstants>\r\n    <ErrorReport>prompt</ErrorReport>\r\n    <WarningLevel>4</WarningLevel>\r\n  </PropertyGroup>\r\n  <ItemGroup>\r\n    <Reference Include=\"Moq\">\r\n      <HintPath>..\\packages\\Moq.4.2.1409.1722\\lib\\net40\\Moq.dll</HintPath>\r\n    </Reference>\r\n    <Reference Include=\"System\" />\r\n  </ItemGroup>\r\n  <Choose>\r\n    <When Condition=\"('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'\">\r\n      <ItemGroup>\r\n        <Reference Include=\"Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL\" />\r\n      </ItemGroup>\r\n    </When>\r\n    <Otherwise>\r\n      <ItemGroup>\r\n        <Reference Include=\"Microsoft.VisualStudio.QualityTools.UnitTestFramework\" />\r\n      </ItemGroup>\r\n    </Otherwise>\r\n  </Choose>\r\n  <ItemGroup>\r\n    <Compile Include=\"ExtensionTests.cs\" />\r\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\r\n    <Compile Include=\"SjisUnzipAppTests.cs\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\SjisUnzip\\SjisUnzip.csproj\">\r\n      <Project>{1aae9514-fa5c-44ad-86bf-b2f44466d6b8}</Project>\r\n      <Name>SjisUnzip</Name>\r\n    </ProjectReference>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"packages.config\" />\r\n  </ItemGroup>\r\n  <Choose>\r\n    <When Condition=\"'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'\">\r\n      <ItemGroup>\r\n        <Reference Include=\"Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL\">\r\n          <Private>False</Private>\r\n        </Reference>\r\n        <Reference Include=\"Microsoft.VisualStudio.TestTools.UITest.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL\">\r\n          <Private>False</Private>\r\n        </Reference>\r\n        <Reference Include=\"Microsoft.VisualStudio.TestTools.UITest.Extension, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL\">\r\n          <Private>False</Private>\r\n        </Reference>\r\n        <Reference Include=\"Microsoft.VisualStudio.TestTools.UITesting, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL\">\r\n          <Private>False</Private>\r\n        </Reference>\r\n      </ItemGroup>\r\n    </When>\r\n  </Choose>\r\n  <Import Project=\"$(VSToolsPath)\\TeamTest\\Microsoft.TestTools.targets\" Condition=\"Exists('$(VSToolsPath)\\TeamTest\\Microsoft.TestTools.targets')\" />\r\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\r\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \r\n       Other similar extension points exist, see Microsoft.Common.targets.\r\n  <Target Name=\"BeforeBuild\">\r\n  </Target>\r\n  <Target Name=\"AfterBuild\">\r\n  </Target>\r\n  -->\r\n</Project>"
  },
  {
    "path": "SjisUnzipTests/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<packages>\r\n  <package id=\"Moq\" version=\"4.2.1409.1722\" targetFramework=\"net45\" />\r\n</packages>"
  }
]