[
  {
    "path": ".gitignore",
    "content": ".classpath\n.project\n.settings/\ntarget/\n"
  },
  {
    "path": "license.txt",
    "content": " ******    *****   ******   UnRAR - free utility for RAR archives\n **   **  **   **  **   **  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n ******   *******  ******    License for use and distribution of\n **   **  **   **  **   **   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n **   **  **   **  **   **         FREE portable version\n                                   ~~~~~~~~~~~~~~~~~~~~~\n\n      The source code of UnRAR utility is freeware. This means:\n\n   1. All copyrights to RAR and the utility UnRAR are exclusively\n      owned by the author - Alexander Roshal.\n\n   2. The UnRAR sources may be used in any software to handle RAR\n      archives without limitations free of charge, but cannot be used\n      to re-create the RAR compression algorithm, which is proprietary.\n      Distribution of modified UnRAR sources in separate form or as a\n      part of other software is permitted, provided that it is clearly\n      stated in the documentation and source comments that the code may\n      not be used to develop a RAR (WinRAR) compatible archiver.\n\n   3. The UnRAR utility may be freely distributed. It is allowed\n      to distribute UnRAR inside of other software packages.\n\n   4. THE RAR ARCHIVER AND THE UnRAR UTILITY ARE DISTRIBUTED \"AS IS\".\n      NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED.  YOU USE AT \n      YOUR OWN RISK. THE AUTHOR WILL NOT BE LIABLE FOR DATA LOSS, \n      DAMAGES, LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING\n      OR MISUSING THIS SOFTWARE.\n\n   5. Installing and using the UnRAR utility signifies acceptance of\n      these terms and conditions of the license.\n\n   6. If you don't agree with terms of the license you must remove\n      UnRAR files from your storage devices and cease to use the\n      utility.\n\n      Thank you for your interest in RAR and UnRAR.\n\n\n                                            Alexander L. Roshal"
  },
  {
    "path": "testutil/.gitignore",
    "content": ".classpath\n.project\nbin/\n.checkstyle\n"
  },
  {
    "path": "testutil/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n\txmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\txsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<groupId>com.github.junrar</groupId>\n\t<artifactId>junrar-testutil</artifactId>\n\t<packaging>jar</packaging>\n\t<version>0.1</version>\n\t<name>java-unrar-testutil</name>\n\t<url>http://maven.apache.org</url>\n\t<developers>\n\t\t<developer>\n\t\t\t<id>edmund_wagner</id>\n\t\t\t<name>Edmund Wagner</name>\n\t\t\t<email>edmund_wagner@users.sourceforge.net</email>\n\t\t\t<roles>\n\t\t\t\t<role></role>\n\t\t\t</roles>\n\t\t</developer>\n\t</developers>\n\t<build>\n\t\t<plugins>\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t<artifactId>maven-jar-plugin</artifactId>\n\t\t\t\t<version>2.2</version>\n\t\t\t\t<configuration>\n\t\t\t\t\t<archive>\n\t\t\t\t\t\t<manifest>\n\t\t\t\t\t\t\t<mainClass>\n\t\t\t\t\t\t\t\tde.innosystec.unrar.testutil.JUnRarTestUtil\n\t\t\t\t\t\t\t</mainClass>\n\t\t\t\t\t\t\t<packageName>\n\t\t\t\t\t\t\t\tde.innosystec.unrar.testutil\n\t\t\t\t\t\t\t</packageName>\n\t\t\t\t\t\t\t<addClasspath>true</addClasspath>\n\t\t\t\t\t\t\t<addExtensions />\n\t\t\t\t\t\t\t<classpathPrefix />\n\t\t\t\t\t\t</manifest>\n\t\t\t\t\t\t<manifestEntries>\n\t\t\t\t\t\t\t<mode>development</mode>\n\t\t\t\t\t\t\t<url>${pom.url}</url>\n\t\t\t\t\t\t</manifestEntries>\n\t\t\t\t\t\t<manifestFile>\n\t\t\t\t\t\t\tsrc/main/resources/META-INF/MANIFEST.MF\n\t\t\t\t\t\t</manifestFile>\n\t\t\t\t\t</archive>\n\t\t\t\t</configuration>\n\t\t\t</plugin>\n\t\t</plugins>\n\t</build>\n\t<dependencies>\n\t\t<dependency>\n\t\t\t<groupId>junit</groupId>\n\t\t\t<artifactId>junit</artifactId>\n\t\t\t<version>3.8.1</version>\n\t\t\t<scope>test</scope>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>com.github.junrar</groupId>\n\t\t\t<artifactId>junrar</artifactId>\n\t\t\t<version>0.6-SNAPSHOT</version>\n\t\t</dependency>\n\t</dependencies>\n</project>\n"
  },
  {
    "path": "testutil/src/main/java/com/github/junrar/testutil/ExtractArchive.java",
    "content": "package com.github.junrar.testutil;\n\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.OutputStream;\n\nimport org.apache.commons.logging.Log;\nimport org.apache.commons.logging.LogFactory;\n\nimport com.github.junrar.Archive;\nimport com.github.junrar.exception.RarException;\nimport com.github.junrar.rarfile.FileHeader;\n\n/**\n * extract an archive to the given location\n * \n * @author edmund wagner\n * \n */\npublic class ExtractArchive {\n\n    private static Log logger = LogFactory.getLog(ExtractArchive.class\n\t    .getName());\n\n    public static void extractArchive(String archive, String destination) {\n\tif (archive == null || destination == null) {\n\t    throw new RuntimeException(\"archive and destination must me set\");\n\t}\n\tFile arch = new File(archive);\n\tif (!arch.exists()) {\n\t    throw new RuntimeException(\"the archive does not exit: \" + archive);\n\t}\n\tFile dest = new File(destination);\n\tif (!dest.exists() || !dest.isDirectory()) {\n\t    throw new RuntimeException(\n\t\t    \"the destination must exist and point to a directory: \"\n\t\t\t    + destination);\n\t}\n\textractArchive(arch, dest);\n    }\n\n    public static void main(String[] args) {\n\tif (args.length == 2) {\n\t    extractArchive(args[0], args[1]);\n\t} else {\n\t    System.out\n\t\t    .println(\"usage: java -jar extractArchive.jar <thearchive> <the destination directory>\");\n\t}\n    }\n\n    public static void extractArchive(File archive, File destination) {\n\tArchive arch = null;\n\ttry {\n\t    arch = new Archive(archive);\n\t} catch (RarException e) {\n\t    logger.error(e);\n\t} catch (IOException e1) {\n\t    logger.error(e1);\n\t}\n\tif (arch != null) {\n\t    if (arch.isEncrypted()) {\n\t\tlogger.warn(\"archive is encrypted cannot extreact\");\n\t\treturn;\n\t    }\n\t    FileHeader fh = null;\n\t    while (true) {\n\t\tfh = arch.nextFileHeader();\n\t\tif (fh == null) {\n\t\t    break;\n\t\t}\n\t\tif (fh.isEncrypted()) {\n\t\t    logger.warn(\"file is encrypted cannot extract: \"\n\t\t\t    + fh.getFileNameString());\n\t\t    continue;\n\t\t}\n\t\tlogger.info(\"extracting: \" + fh.getFileNameString());\n\t\ttry {\n\t\t    if (fh.isDirectory()) {\n\t\t\tcreateDirectory(fh, destination);\n\t\t    } else {\n\t\t\tFile f = createFile(fh, destination);\n\t\t\tOutputStream stream = new FileOutputStream(f);\n\t\t\tarch.extractFile(fh, stream);\n\t\t\tstream.close();\n\t\t    }\n\t\t} catch (IOException e) {\n\t\t    logger.error(\"error extracting the file\", e);\n\t\t} catch (RarException e) {\n\t\t    logger.error(\"error extraction the file\", e);\n\t\t}\n\t    }\n\t}\n    }\n\n    private static File createFile(FileHeader fh, File destination) {\n\tFile f = null;\n\tString name = null;\n\tif (fh.isFileHeader() && fh.isUnicode()) {\n\t    name = fh.getFileNameW();\n\t} else {\n\t    name = fh.getFileNameString();\n\t}\n\tf = new File(destination, name);\n\tif (!f.exists()) {\n\t    try {\n\t\tf = makeFile(destination, name);\n\t    } catch (IOException e) {\n\t\tlogger.error(\"error creating the new file: \" + f.getName(), e);\n\t    }\n\t}\n\treturn f;\n    }\n\n    private static File makeFile(File destination, String name)\n\t    throws IOException {\n\tString[] dirs = name.split(\"\\\\\\\\\");\n\tif (dirs == null) {\n\t    return null;\n\t}\n\tString path = \"\";\n\tint size = dirs.length;\n\tif (size == 1) {\n\t    return new File(destination, name);\n\t} else if (size > 1) {\n\t    for (int i = 0; i < dirs.length - 1; i++) {\n\t\tpath = path + File.separator + dirs[i];\n\t\tnew File(destination, path).mkdir();\n\t    }\n\t    path = path + File.separator + dirs[dirs.length - 1];\n\t    File f = new File(destination, path);\n\t    f.createNewFile();\n\t    return f;\n\t} else {\n\t    return null;\n\t}\n    }\n\n    private static void createDirectory(FileHeader fh, File destination) {\n\tFile f = null;\n\tif (fh.isDirectory() && fh.isUnicode()) {\n\t    f = new File(destination, fh.getFileNameW());\n\t    if (!f.exists()) {\n\t\tmakeDirectory(destination, fh.getFileNameW());\n\t    }\n\t} else if (fh.isDirectory() && !fh.isUnicode()) {\n\t    f = new File(destination, fh.getFileNameString());\n\t    if (!f.exists()) {\n\t\tmakeDirectory(destination, fh.getFileNameString());\n\t    }\n\t}\n    }\n\n    private static void makeDirectory(File destination, String fileName) {\n\tString[] dirs = fileName.split(\"\\\\\\\\\");\n\tif (dirs == null) {\n\t    return;\n\t}\n\tString path = \"\";\n\tfor (String dir : dirs) {\n\t    path = path + File.separator + dir;\n\t    new File(destination, path).mkdir();\n\t}\n\n    }\n}\n"
  },
  {
    "path": "testutil/src/main/java/com/github/junrar/testutil/JUnRarTestUtil.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: EW\r\n * Creation date: 26.09.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n *\r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.testutil;\r\n\r\nimport java.io.ByteArrayOutputStream;\r\nimport java.io.File;\r\nimport java.io.IOException;\r\nimport java.util.ArrayList;\r\nimport java.util.Date;\r\nimport java.util.List;\r\n\r\nimport org.apache.commons.logging.Log;\r\nimport org.apache.commons.logging.LogFactory;\r\n\r\nimport com.github.junrar.Archive;\r\nimport com.github.junrar.exception.RarException;\r\nimport com.github.junrar.exception.RarException.RarExceptionType;\r\nimport com.github.junrar.io.ReadOnlyAccessFile;\r\nimport com.github.junrar.rarfile.FileHeader;\r\n\r\n/**\r\n * DOCUMENT ME\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class JUnRarTestUtil\r\n{\r\n\tprivate static Log logger = LogFactory.getLog(JUnRarTestUtil.class.getName());\r\n\t/**\r\n\t * @param args\r\n\t */\r\n\tprivate static List<String> successfulFiles = new ArrayList<String>();\r\n\t\r\n\tprivate static List<String> errorFiles = new ArrayList<String>();\r\n\t\r\n\tprivate static List<String> unsupportedFiles = new ArrayList<String>();\r\n\t\r\n\tpublic static void main(String[] args)\r\n\t{\r\n\t\tif(args.length!=1){\r\n\t\t\tSystem.out.println(\"JUnRar TestUtil\\n usage: java -jar unrar-test.jar <directory with test files>\");\r\n\t\t\treturn;\r\n\t\t}else{\r\n\t\t\tFile file = new File(args[0]);\r\n\t\t\tif(file.exists()){\r\n\t\t\t\tif(file.isDirectory()){\r\n\t\t\t\t\trecurseDirectory(file);\r\n\t\t\t\t}else{\r\n\t\t\t\t\ttestFile(file);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tprintSummary();\r\n\r\n\t}\r\n\r\n\tprivate static void printSummary()\r\n\t{\r\n\t\tSystem.out.println(\"\\n\\n\\nSuccessfully tested archives:\\n\");\r\n\t\tfor(String sf:successfulFiles){\r\n\t\t\tSystem.out.println(sf);\r\n\t\t}\r\n\t\tSystem.out.println(\"\");\r\n\t\tSystem.out.println(\"Unsupported archives:\\n\");\r\n\t\tfor(String uf: unsupportedFiles){\r\n\t\t\tSystem.out.println(uf);\r\n\t\t}\r\n\t\tSystem.out.println(\"\");\r\n\t\tSystem.out.println(\"Failed archives:\");\r\n\t\tfor(String ff: errorFiles){\r\n\t\t\tSystem.out.println(ff);\r\n\t\t}\r\n\t\tSystem.out.println(\"\");\r\n\t\tSystem.out.println(\"\\n\\n\\nSummary\\n\");\r\n\t\tSystem.out.println(\"tested:\\t\\t\"+(successfulFiles.size()+unsupportedFiles.size()+errorFiles.size()));\r\n\t\tSystem.out.println(\"successful:\\t\"+successfulFiles.size());\r\n\t\tSystem.out.println(\"unsupported:\\t\"+unsupportedFiles.size());\r\n\t\tSystem.out.println(\"failed:\\t\\t\"+errorFiles.size());\r\n\t}\r\n\r\n\tprivate static void testFile(File file)\r\n\t{\r\n\t\tif(file==null || !file.exists()){\r\n\t\t\tlogger.error(\"error file \" +file + \" does not exist\");\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tlogger.info(\">>>>>> testing archive: \"+file);\r\n\t\tString s = file.toString();\r\n\t\ts = s.substring(s.length()-3);\r\n\t\tif(s.equalsIgnoreCase(\"rar\")){\r\n\t\t\tSystem.out.println(file.toString());\r\n\t\t\tReadOnlyAccessFile readFile = null;\r\n\t\t\ttry {\r\n//\t\t\t\treadFile = new ReadOnlyAccessFile(file);\r\n\t\t\t\tArchive arc = null;\r\n\t\t\t\ttry {\r\n\t\t\t\t\tarc = new Archive(file);\r\n\t\t\t\t} catch (RarException e) {\r\n\t\t\t\t\tlogger.error(\"archive consturctor error\",e);\r\n\t\t\t\t\terrorFiles.add(file.toString());\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tif(arc != null){\r\n\t\t\t\t\tif(arc.isEncrypted()){\r\n\t\t\t\t\t\tlogger.warn(\"archive is encrypted cannot extreact\");\r\n\t\t\t\t\t\tunsupportedFiles.add(file.toString());\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tList<FileHeader> files = arc.getFileHeaders();\r\n\t\t\t\t\tfor(FileHeader fh : files)\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tif(fh.isEncrypted()){\r\n\t\t\t\t\t\t\tlogger.warn(\"file is encrypted cannot extract: \"+fh.getFileNameString());\r\n\t\t\t\t\t\t\tunsupportedFiles.add(file.toString());\r\n\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tlogger.info(\"extracting file: \"+fh.getFileNameString());\r\n\t\t\t\t\t\tif(fh.isFileHeader() && fh.isUnicode()){\r\n\t\t\t\t\t\t\tlogger.info(\"unicode name: \"+fh.getFileNameW());\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tlogger.info(\"start: \"+new Date());\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\tByteArrayOutputStream os = new ByteArrayOutputStream();\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\ttry {\r\n\t\t\t\t\t\t\tarc.extractFile(fh, os);\r\n\t\t\t\t\t\t} catch (RarException e) {\r\n\t\t\t\t\t\t\tif(e.getType().equals(RarExceptionType.notImplementedYet)){\r\n\t\t\t\t\t\t\t\tlogger.error(\"error extracting unsupported file: \"+fh.getFileNameString(),e);\r\n\t\t\t\t\t\t\t\tunsupportedFiles.add(file.toString());\r\n\t\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tlogger.error(\"error extracting file: \"+fh.getFileNameString(),e);\r\n\t\t\t\t\t\t\terrorFiles.add(file.toString());\r\n\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t}finally{\r\n\t\t\t\t\t\t\tos.close();\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\tlogger.info(\"end: \"+new Date());\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tlogger.info(\"successfully tested archive: \"+file);\r\n\t\t\t\tsuccessfulFiles.add(file.toString());\r\n\t\t\t} catch (Exception e) {\r\n\t\t\t\tlogger.error(\"file: \"+file+ \" extraction error - does the file exist?\"+e );\r\n\t\t\t\terrorFiles.add(file.toString());\r\n\t\t\t} finally{\r\n\t\t\t\tif(readFile!=null){\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\treadFile.close();\r\n\t\t\t\t\t} catch (IOException e) {\r\n\t\t\t\t\t\te.printStackTrace();\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t\r\n\t\t}\r\n\t}\r\n\t\r\n\tprivate static void recurseDirectory(File file)\r\n\t{\r\n\t\tif(file==null||!file.exists()){\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif(file.isDirectory()){\r\n\t\t\tFile[] files = file.listFiles();\r\n\t\t\tif(files == null){\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tfor(File f: files){\r\n\t\t\t\trecurseDirectory(f);\r\n\t\t\t\tf = null;\r\n\t\t\t}\r\n\t\t}else{\r\n\t\t\ttestFile(file);\r\n\t\t\tfile=null;\r\n\t\t}\r\n\t\t\r\n\t}\r\n\r\n\t\r\n\r\n}\r\n"
  },
  {
    "path": "testutil/src/main/resources/META-INF/MANIFEST.MF",
    "content": ""
  },
  {
    "path": "unrar/.gitignore",
    "content": ".classpath\n.project\n\n"
  },
  {
    "path": "unrar/generate-testdata.sh",
    "content": "\nmode=$1\nadstepping=$2\nt1stepping=$3\nt2stepping=$4\nindir=$5\noutdir=$6\npar1=1\npar2=1\npath=$PWD\n\n\nfunction start {\ncase \"$1\" in\n\ta|d)\n\t\t.\n\t\t\twhile [ $par1 -le 31 ]\n\t\t\tdo\n\t\t\trar a -ep1 -mc$par1$1+ $path/$outdir/$i/$i-mc$par1$1+.rar $path/$indir/$i\n\t\t\tlet par1+=adstepping\n\t\t\tdone\n\t\tpar1=1\n\t;;\n\tt)\n\t\t\tlet par1=2\n\t\t\twhile [ $par1 -le 63 ]\n\t\t\tdo\n\t\t\t\twhile [ $par2 -le 128 ]\n\t\t\t\tdo\n\t\t\t\t\trar a -ep1 -mc$par1:$par2$1+ $path/$outdir/$i/$i-mc$par1.$par2$1+.rar $path/$indir/$i\n\t\t\t\t\tlet par2+=$t2stepping\n\t\t\t\tdone\n\t\t\tlet par1+=$t1stepping\n\t\t\tlet par2=1\n\t\t\tdone\n\t\tpar1=1\n\t;;\n\tc|e|i)\n\n\t\t\trar a -ep1 -mc$1+ $path/$outdir/$i/$i-mc$1+.rar $path/$indir/$i\n\t\t\tpar1=1\n\t;;\n\tn)\n\n\t\t\trar a -ep1 -mca- -mcd- -mct- -mcc- -mce- -mci-  $path/$outdir/$i/$i-n.rar $path/$indir/$i\n\t;;\n\tesac\n}\n\n\nif [ \"$mode\" != \"\" ] && [ \"$adstepping\" != \"\" ]  &&[ \"$t1stepping\" != \"\" ] && [ \"$t2stepping\" != \"\" ] && [ \"$indir\" != \"\" ] && [ \"$outdir\" != \"\" ];\nthen\n\t# create output dir\n\tmkdir -m 0777 $outdir\n\n\tcd $indir\n\n\tfor i in $(ls *)\n\tdo\n\t\tmkdir -m 0777 $path/$outdir/$i\n\t\tif [ \"$1\" == \"all\" ];then\n\t\t\tstart a\n\t\t\tstart d\n\t\t\tstart c\n\t\t\tstart e\n\t\t\tstart i\n\t\t\tstart t\n\t\t\tstart n\n\t\telse\n\t\t\tstart \"$mode\"\n\t\tfi\n\tdone\nelse\n\t\n\techo \"usage: ./generate-testdata.sh [ a | d | c  | e | i | t | n | all ] [ adstepping ] [ t1stepping]  [ t2stepping]  [ indir ] [ outdir ]\"\n\techo .......................................\n\texit 0\nfi\n\n\n\n"
  },
  {
    "path": "unrar/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<groupId>com.github.beothorn</groupId>\n\t<artifactId>junrar</artifactId>\n\t<packaging>jar</packaging>\n\t<version>0.7-SNAPSHOT</version>\n\t<name>Java UnRar</name>\n\t<description>rar decompression library in plain java</description>\n\t<url>https://github.com/edmund-wagner/junrar</url>\n\n\t<properties>\n\t\t<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n\t\t<maven.compiler.source>1.6</maven.compiler.source>\n\t\t<maven.compiler.target>1.6</maven.compiler.target>\n\t</properties>\n\n\t<licenses>\n\t\t<license>\n\t\t\t<name>UnRar License</name>\n\t\t\t<url>https://raw.github.com/edmund-wagner/junrar/master/license.txt</url>\n\t\t\t<distribution>repo</distribution>\n\t\t</license>\n\t</licenses>\n\n\t<scm>\n\t\t<connection>scm:git:git@github.com:edmund-wagner/junrar.git</connection>\n\t\t<developerConnection>scm:git:git@github.com:edmund-wagner/junrar.git</developerConnection>\n\t\t<url>git@github.com:edmund-wagner/junrar.git</url>\n\t</scm>\n\n\t<developers>\n\t\t<developer>\n\t\t\t<id>edmund_wagner</id>\n\t\t\t<name>Edmund Wagner</name>\n\t\t</developer>\n\t</developers>\n\n\t<dependencies>\n\t\t<dependency>\n\t\t\t<groupId>junit</groupId>\n\t\t\t<artifactId>junit</artifactId>\n\t\t\t<version>3.8.1</version>\n\t\t\t<type>jar</type>\n\t\t\t<scope>test</scope>\n\t\t\t<optional>false</optional>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>commons-logging</groupId>\n\t\t\t<artifactId>commons-logging-api</artifactId>\n\t\t\t<version>1.1</version>\n\t\t\t<type>jar</type>\n\t\t\t<optional>false</optional>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.apache.commons</groupId>\n\t\t\t<artifactId>commons-vfs2</artifactId>\n\t\t\t<version>2.0</version>\n\t\t\t<optional>true</optional>\n\t\t</dependency>\n\t</dependencies>\n\t\n\t<build>\n\t\t<plugins>\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t<artifactId>maven-release-plugin</artifactId>\n\t\t\t\t<version>2.2.1</version>\n\t\t\t</plugin>\n\t\t</plugins>\n\t</build>\n\n\t<profiles>\n\t\t<profile>\n\t\t\t<id>sign</id>\n\t\t\t<build>\n\t\t\t\t<plugins>\n\t\t\t\t\t<plugin>\n\t\t\t\t\t\t<groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t\t\t<artifactId>maven-compiler-plugin</artifactId>\n\t\t\t\t\t\t<version>2.3.2</version>\n\t\t\t\t\t\t<configuration>\n\t\t\t\t\t\t\t<source>${maven.compiler.source}</source>\n\t\t\t\t\t\t\t<target>${maven.compiler.source}</target>\n\t\t\t\t\t\t\t<encoding>${project.build.sourceEncoding}</encoding>\n\t\t\t\t\t\t</configuration>\n\t\t\t\t\t</plugin>\n\t\t\t\t\t<plugin>\n\t\t\t\t\t\t<groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t\t\t<artifactId>maven-gpg-plugin</artifactId>\n\t\t\t\t\t\t<executions>\n\t\t\t\t\t\t\t<execution>\n\t\t\t\t\t\t\t\t<id>sign-artifacts</id>\n\t\t\t\t\t\t\t\t<phase>verify</phase>\n\t\t\t\t\t\t\t\t<goals>\n\t\t\t\t\t\t\t\t\t<goal>sign</goal>\n\t\t\t\t\t\t\t\t</goals>\n\t\t\t\t\t\t\t</execution>\n\t\t\t\t\t\t</executions>\n\t\t\t\t\t</plugin>\n\t\t\t\t</plugins>\n\t\t\t</build>\n\t\t</profile>\n\t</profiles>\n\t\n\t<parent>\n\t\t<groupId>org.sonatype.oss</groupId>\n\t\t<artifactId>oss-parent</artifactId>\n\t\t<version>7</version>\n\t</parent>\n</project>\n"
  },
  {
    "path": "unrar/readme.md",
    "content": "unrar\r\n=====\r\n\r\nAdds support to read a rar from a given InputStream.\r\n\r\nAdditional dependencies\r\n-----------------------\r\n* ij: http://rsbweb.nih.gov/ij/"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/Archive.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 22.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n *\r\n * the unrar licence applies to all junrar source and binary distributions\r\n * you are not allowed to use this source to re-create the RAR compression\r\n * algorithm\r\n *\r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\"\r\n */\r\npackage com.github.junrar;\r\n\r\nimport java.io.Closeable;\r\nimport java.io.File;\r\nimport java.io.IOException;\r\nimport java.io.InputStream;\r\nimport java.io.OutputStream;\r\nimport java.io.PipedInputStream;\r\nimport java.io.PipedOutputStream;\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\nimport java.util.logging.Level;\r\nimport java.util.logging.Logger;\r\n\r\nimport com.github.junrar.exception.RarException;\r\nimport com.github.junrar.exception.RarException.RarExceptionType;\r\nimport com.github.junrar.impl.FileVolumeManager;\r\nimport com.github.junrar.io.IReadOnlyAccess;\r\nimport com.github.junrar.rarfile.AVHeader;\r\nimport com.github.junrar.rarfile.BaseBlock;\r\nimport com.github.junrar.rarfile.BlockHeader;\r\nimport com.github.junrar.rarfile.CommentHeader;\r\nimport com.github.junrar.rarfile.EAHeader;\r\nimport com.github.junrar.rarfile.EndArcHeader;\r\nimport com.github.junrar.rarfile.FileHeader;\r\nimport com.github.junrar.rarfile.MacInfoHeader;\r\nimport com.github.junrar.rarfile.MainHeader;\r\nimport com.github.junrar.rarfile.MarkHeader;\r\nimport com.github.junrar.rarfile.ProtectHeader;\r\nimport com.github.junrar.rarfile.SignHeader;\r\nimport com.github.junrar.rarfile.SubBlockHeader;\r\nimport com.github.junrar.rarfile.UnixOwnersHeader;\r\nimport com.github.junrar.rarfile.UnrarHeadertype;\r\nimport com.github.junrar.unpack.ComprDataIO;\r\nimport com.github.junrar.unpack.Unpack;\r\n\r\n\r\n/**\r\n * The Main Rar Class; represents a rar Archive\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class Archive implements Closeable {\r\n\tprivate static Logger logger = Logger.getLogger(Archive.class.getName());\r\n\r\n\tprivate IReadOnlyAccess rof;\r\n\r\n\tprivate final UnrarCallback unrarCallback;\r\n\r\n\tprivate final ComprDataIO dataIO;\r\n\r\n\tprivate final List<BaseBlock> headers = new ArrayList<BaseBlock>();\r\n\r\n\tprivate MarkHeader markHead = null;\r\n\r\n\tprivate MainHeader newMhd = null;\r\n\r\n\tprivate Unpack unpack;\r\n\r\n\tprivate int currentHeaderIndex;\r\n\r\n\t/** Size of packed data in current file. */\r\n\tprivate long totalPackedSize = 0L;\r\n\r\n\t/** Number of bytes of compressed data read from current file. */\r\n\tprivate long totalPackedRead = 0L;\r\n\r\n\tprivate VolumeManager volumeManager;\r\n\tprivate Volume volume;\r\n\r\n\tpublic Archive(VolumeManager volumeManager) throws RarException,\r\n\t\t\tIOException {\r\n\t\tthis(volumeManager, null);\r\n\t}\r\n\r\n\t/**\r\n\t * create a new archive object using the given {@link VolumeManager}\r\n\t * \r\n\t * @param volumeManager\r\n\t *            the the {@link VolumeManager} that will provide volume stream\r\n\t *            data\r\n\t * @throws RarException\r\n\t */\r\n\tpublic Archive(VolumeManager volumeManager, UnrarCallback unrarCallback)\r\n\t\t\tthrows RarException, IOException {\r\n\t\tthis.volumeManager = volumeManager;\r\n\t\tthis.unrarCallback = unrarCallback;\r\n\r\n\t\tsetVolume(this.volumeManager.nextArchive(this, null));\r\n\t\tdataIO = new ComprDataIO(this);\r\n\t}\r\n\r\n\tpublic Archive(File firstVolume) throws RarException, IOException {\r\n\t\tthis(new FileVolumeManager(firstVolume), null);\r\n\t}\r\n\r\n\tpublic Archive(File firstVolume, UnrarCallback unrarCallback)\r\n\t\t\tthrows RarException, IOException {\r\n\t\tthis(new FileVolumeManager(firstVolume), unrarCallback);\r\n\t}\r\n\r\n\t// public File getFile() {\r\n\t// return file;\r\n\t// }\r\n\t//\r\n\t// void setFile(File file) throws IOException {\r\n\t// this.file = file;\r\n\t// setFile(new ReadOnlyAccessFile(file), file.length());\r\n\t// }\r\n\r\n\tprivate void setFile(IReadOnlyAccess file, long length) throws IOException {\r\n\t\ttotalPackedSize = 0L;\r\n\t\ttotalPackedRead = 0L;\r\n\t\tclose();\r\n\t\trof = file;\r\n\t\ttry {\r\n\t\t\treadHeaders(length);\r\n\t\t} catch (Exception e) {\r\n\t\t\tlogger.log(Level.WARNING,\r\n\t\t\t\t\t\"exception in archive constructor maybe file is encrypted \"\r\n\t\t\t\t\t\t\t+ \"or currupt\", e);\r\n\t\t\t// ignore exceptions to allow exraction of working files in\r\n\t\t\t// corrupt archive\r\n\t\t}\r\n\t\t// Calculate size of packed data\r\n\t\tfor (BaseBlock block : headers) {\r\n\t\t\tif (block.getHeaderType() == UnrarHeadertype.FileHeader) {\r\n\t\t\t\ttotalPackedSize += ((FileHeader) block).getFullPackSize();\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (unrarCallback != null) {\r\n\t\t\tunrarCallback.volumeProgressChanged(totalPackedRead,\r\n\t\t\t\t\ttotalPackedSize);\r\n\t\t}\r\n\t}\r\n\r\n\tpublic void bytesReadRead(int count) {\r\n\t\tif (count > 0) {\r\n\t\t\ttotalPackedRead += count;\r\n\t\t\tif (unrarCallback != null) {\r\n\t\t\t\tunrarCallback.volumeProgressChanged(totalPackedRead,\r\n\t\t\t\t\t\ttotalPackedSize);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tpublic IReadOnlyAccess getRof() {\r\n\t\treturn rof;\r\n\t}\r\n\r\n\t/**\r\n\t * @return returns all file headers of the archive\r\n\t */\r\n\tpublic List<FileHeader> getFileHeaders() {\r\n\t\tList<FileHeader> list = new ArrayList<FileHeader>();\r\n\t\tfor (BaseBlock block : headers) {\r\n\t\t\tif (block.getHeaderType().equals(UnrarHeadertype.FileHeader)) {\r\n\t\t\t\tlist.add((FileHeader) block);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn list;\r\n\t}\r\n\r\n\tpublic FileHeader nextFileHeader() {\r\n\t\tint n = headers.size();\r\n\t\twhile (currentHeaderIndex < n) {\r\n\t\t\tBaseBlock block = headers.get(currentHeaderIndex++);\r\n\t\t\tif (block.getHeaderType() == UnrarHeadertype.FileHeader) {\r\n\t\t\t\treturn (FileHeader) block;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn null;\r\n\t}\r\n\r\n\tpublic UnrarCallback getUnrarCallback() {\r\n\t\treturn unrarCallback;\r\n\t}\r\n\r\n\t/**\r\n\t * \r\n\t * @return whether the archive is encrypted\r\n\t */\r\n\tpublic boolean isEncrypted() {\r\n\t\tif (newMhd != null) {\r\n\t\t\treturn newMhd.isEncrypted();\r\n\t\t} else {\r\n\t\t\tthrow new NullPointerException(\"mainheader is null\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Read the headers of the archive\r\n\t * \r\n\t * @param fileLength\r\n\t *            Length of file.\r\n\t * @throws RarException\r\n\t */\r\n\tprivate void readHeaders(long fileLength) throws IOException, RarException {\r\n\t\tmarkHead = null;\r\n\t\tnewMhd = null;\r\n\t\theaders.clear();\r\n\t\tcurrentHeaderIndex = 0;\r\n\t\tint toRead = 0;\r\n\r\n\t\twhile (true) {\r\n\t\t\tint size = 0;\r\n\t\t\tlong newpos = 0;\r\n\t\t\tbyte[] baseBlockBuffer = new byte[BaseBlock.BaseBlockSize];\r\n\r\n\t\t\tlong position = rof.getPosition();\r\n\r\n\t\t\t// Weird, but is trying to read beyond the end of the file\r\n\t\t\tif (position >= fileLength) {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\r\n\t\t\t// logger.info(\"\\n--------reading header--------\");\r\n\t\t\tsize = rof.readFully(baseBlockBuffer, BaseBlock.BaseBlockSize);\r\n\t\t\tif (size == 0) {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tBaseBlock block = new BaseBlock(baseBlockBuffer);\r\n\r\n\t\t\tblock.setPositionInFile(position);\r\n\r\n\t\t\tswitch (block.getHeaderType()) {\r\n\r\n\t\t\tcase MarkHeader:\r\n\t\t\t\tmarkHead = new MarkHeader(block);\r\n\t\t\t\tif (!markHead.isSignature()) {\r\n\t\t\t\t\tthrow new RarException(\r\n\t\t\t\t\t\t\tRarException.RarExceptionType.badRarArchive);\r\n\t\t\t\t}\r\n\t\t\t\theaders.add(markHead);\r\n\t\t\t\t// markHead.print();\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase MainHeader:\r\n\t\t\t\ttoRead = block.hasEncryptVersion() ? MainHeader.mainHeaderSizeWithEnc\r\n\t\t\t\t\t\t: MainHeader.mainHeaderSize;\r\n\t\t\t\tbyte[] mainbuff = new byte[toRead];\r\n\t\t\t\trof.readFully(mainbuff, toRead);\r\n\t\t\t\tMainHeader mainhead = new MainHeader(block, mainbuff);\r\n\t\t\t\theaders.add(mainhead);\r\n\t\t\t\tthis.newMhd = mainhead;\r\n\t\t\t\tif (newMhd.isEncrypted()) {\r\n\t\t\t\t\tthrow new RarException(\r\n\t\t\t\t\t\t\tRarExceptionType.rarEncryptedException);\r\n\t\t\t\t}\r\n\t\t\t\t// mainhead.print();\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase SignHeader:\r\n\t\t\t\ttoRead = SignHeader.signHeaderSize;\r\n\t\t\t\tbyte[] signBuff = new byte[toRead];\r\n\t\t\t\trof.readFully(signBuff, toRead);\r\n\t\t\t\tSignHeader signHead = new SignHeader(block, signBuff);\r\n\t\t\t\theaders.add(signHead);\r\n\t\t\t\t// logger.info(\"HeaderType: SignHeader\");\r\n\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase AvHeader:\r\n\t\t\t\ttoRead = AVHeader.avHeaderSize;\r\n\t\t\t\tbyte[] avBuff = new byte[toRead];\r\n\t\t\t\trof.readFully(avBuff, toRead);\r\n\t\t\t\tAVHeader avHead = new AVHeader(block, avBuff);\r\n\t\t\t\theaders.add(avHead);\r\n\t\t\t\t// logger.info(\"headertype: AVHeader\");\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase CommHeader:\r\n\t\t\t\ttoRead = CommentHeader.commentHeaderSize;\r\n\t\t\t\tbyte[] commBuff = new byte[toRead];\r\n\t\t\t\trof.readFully(commBuff, toRead);\r\n\t\t\t\tCommentHeader commHead = new CommentHeader(block, commBuff);\r\n\t\t\t\theaders.add(commHead);\r\n\t\t\t\t// logger.info(\"method: \"+commHead.getUnpMethod()+\"; 0x\"+\r\n\t\t\t\t// Integer.toHexString(commHead.getUnpMethod()));\r\n\t\t\t\tnewpos = commHead.getPositionInFile()\r\n\t\t\t\t\t\t+ commHead.getHeaderSize();\r\n\t\t\t\trof.setPosition(newpos);\r\n\r\n\t\t\t\tbreak;\r\n\t\t\tcase EndArcHeader:\r\n\r\n\t\t\t\ttoRead = 0;\r\n\t\t\t\tif (block.hasArchiveDataCRC()) {\r\n\t\t\t\t\ttoRead += EndArcHeader.endArcArchiveDataCrcSize;\r\n\t\t\t\t}\r\n\t\t\t\tif (block.hasVolumeNumber()) {\r\n\t\t\t\t\ttoRead += EndArcHeader.endArcVolumeNumberSize;\r\n\t\t\t\t}\r\n\t\t\t\tEndArcHeader endArcHead;\r\n\t\t\t\tif (toRead > 0) {\r\n\t\t\t\t\tbyte[] endArchBuff = new byte[toRead];\r\n\t\t\t\t\trof.readFully(endArchBuff, toRead);\r\n\t\t\t\t\tendArcHead = new EndArcHeader(block, endArchBuff);\r\n\t\t\t\t\t// logger.info(\"HeaderType: endarch\\ndatacrc:\"+\r\n\t\t\t\t\t// endArcHead.getArchiveDataCRC());\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// logger.info(\"HeaderType: endarch - no Data\");\r\n\t\t\t\t\tendArcHead = new EndArcHeader(block, null);\r\n\t\t\t\t}\r\n\t\t\t\theaders.add(endArcHead);\r\n\t\t\t\t// logger.info(\"\\n--------end header--------\");\r\n\t\t\t\treturn;\r\n\r\n\t\t\tdefault:\r\n\t\t\t\tbyte[] blockHeaderBuffer = new byte[BlockHeader.blockHeaderSize];\r\n\t\t\t\trof.readFully(blockHeaderBuffer, BlockHeader.blockHeaderSize);\r\n\t\t\t\tBlockHeader blockHead = new BlockHeader(block,\r\n\t\t\t\t\t\tblockHeaderBuffer);\r\n\r\n\t\t\t\tswitch (blockHead.getHeaderType()) {\r\n\t\t\t\tcase NewSubHeader:\r\n\t\t\t\tcase FileHeader:\r\n\t\t\t\t\ttoRead = blockHead.getHeaderSize()\r\n\t\t\t\t\t\t\t- BlockHeader.BaseBlockSize\r\n\t\t\t\t\t\t\t- BlockHeader.blockHeaderSize;\r\n\t\t\t\t\tbyte[] fileHeaderBuffer = new byte[toRead];\r\n\t\t\t\t\trof.readFully(fileHeaderBuffer, toRead);\r\n\r\n\t\t\t\t\tFileHeader fh = new FileHeader(blockHead, fileHeaderBuffer);\r\n\t\t\t\t\theaders.add(fh);\r\n\t\t\t\t\tnewpos = fh.getPositionInFile() + fh.getHeaderSize()\r\n\t\t\t\t\t\t\t+ fh.getFullPackSize();\r\n\t\t\t\t\trof.setPosition(newpos);\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase ProtectHeader:\r\n\t\t\t\t\ttoRead = blockHead.getHeaderSize()\r\n\t\t\t\t\t\t\t- BlockHeader.BaseBlockSize\r\n\t\t\t\t\t\t\t- BlockHeader.blockHeaderSize;\r\n\t\t\t\t\tbyte[] protectHeaderBuffer = new byte[toRead];\r\n\t\t\t\t\trof.readFully(protectHeaderBuffer, toRead);\r\n\t\t\t\t\tProtectHeader ph = new ProtectHeader(blockHead,\r\n\t\t\t\t\t\t\tprotectHeaderBuffer);\r\n\r\n\t\t\t\t\tnewpos = ph.getPositionInFile() + ph.getHeaderSize()\r\n\t\t\t\t\t\t\t+ ph.getDataSize();\r\n\t\t\t\t\trof.setPosition(newpos);\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase SubHeader: {\r\n\t\t\t\t\tbyte[] subHeadbuffer = new byte[SubBlockHeader.SubBlockHeaderSize];\r\n\t\t\t\t\trof.readFully(subHeadbuffer,\r\n\t\t\t\t\t\t\tSubBlockHeader.SubBlockHeaderSize);\r\n\t\t\t\t\tSubBlockHeader subHead = new SubBlockHeader(blockHead,\r\n\t\t\t\t\t\t\tsubHeadbuffer);\r\n\t\t\t\t\tsubHead.print();\r\n\t\t\t\t\tswitch (subHead.getSubType()) {\r\n\t\t\t\t\tcase MAC_HEAD: {\r\n\t\t\t\t\t\tbyte[] macHeaderbuffer = new byte[MacInfoHeader.MacInfoHeaderSize];\r\n\t\t\t\t\t\trof.readFully(macHeaderbuffer,\r\n\t\t\t\t\t\t\t\tMacInfoHeader.MacInfoHeaderSize);\r\n\t\t\t\t\t\tMacInfoHeader macHeader = new MacInfoHeader(subHead,\r\n\t\t\t\t\t\t\t\tmacHeaderbuffer);\r\n\t\t\t\t\t\tmacHeader.print();\r\n\t\t\t\t\t\theaders.add(macHeader);\r\n\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// TODO implement other subheaders\r\n\t\t\t\t\tcase BEEA_HEAD:\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase EA_HEAD: {\r\n\t\t\t\t\t\tbyte[] eaHeaderBuffer = new byte[EAHeader.EAHeaderSize];\r\n\t\t\t\t\t\trof.readFully(eaHeaderBuffer, EAHeader.EAHeaderSize);\r\n\t\t\t\t\t\tEAHeader eaHeader = new EAHeader(subHead,\r\n\t\t\t\t\t\t\t\teaHeaderBuffer);\r\n\t\t\t\t\t\teaHeader.print();\r\n\t\t\t\t\t\theaders.add(eaHeader);\r\n\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tcase NTACL_HEAD:\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase STREAM_HEAD:\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase UO_HEAD:\r\n\t\t\t\t\t\ttoRead = subHead.getHeaderSize();\r\n\t\t\t\t\t\ttoRead -= BaseBlock.BaseBlockSize;\r\n\t\t\t\t\t\ttoRead -= BlockHeader.blockHeaderSize;\r\n\t\t\t\t\t\ttoRead -= SubBlockHeader.SubBlockHeaderSize;\r\n\t\t\t\t\t\tbyte[] uoHeaderBuffer = new byte[toRead];\r\n\t\t\t\t\t\trof.readFully(uoHeaderBuffer, toRead);\r\n\t\t\t\t\t\tUnixOwnersHeader uoHeader = new UnixOwnersHeader(\r\n\t\t\t\t\t\t\t\tsubHead, uoHeaderBuffer);\r\n\t\t\t\t\t\tuoHeader.print();\r\n\t\t\t\t\t\theaders.add(uoHeader);\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tdefault:\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t\tdefault:\r\n\t\t\t\t\tlogger.warning(\"Unknown Header\");\r\n\t\t\t\t\tthrow new RarException(RarExceptionType.notRarArchive);\r\n\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// logger.info(\"\\n--------end header--------\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Extract the file specified by the given header and write it to the\r\n\t * supplied output stream\r\n\t * \r\n\t * @param header\r\n\t *            the header to be extracted\r\n\t * @param os\r\n\t *            the outputstream\r\n\t * @throws RarException\r\n\t */\r\n\tpublic void extractFile(FileHeader hd, OutputStream os) throws RarException {\r\n\t\tif (!headers.contains(hd)) {\r\n\t\t\tthrow new RarException(RarExceptionType.headerNotInArchive);\r\n\t\t}\r\n\t\ttry {\r\n\t\t\tdoExtractFile(hd, os);\r\n\t\t} catch (Exception e) {\r\n\t\t\tif (e instanceof RarException) {\r\n\t\t\t\tthrow (RarException) e;\r\n\t\t\t} else {\r\n\t\t\t\tthrow new RarException(e);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns an {@link InputStream} that will allow to read the file and\r\n\t * stream it. Please note that this method will create a new Thread and an a\r\n\t * pair of Pipe streams.\r\n\t * \r\n\t * @param header\r\n\t *            the header to be extracted\r\n\t * @throws RarException\r\n\t * @throws IOException\r\n\t *             if any IO error occur\r\n\t */\r\n\tpublic InputStream getInputStream(final FileHeader hd) throws RarException,\r\n\t\t\tIOException {\r\n\t\tfinal PipedInputStream in = new PipedInputStream(32 * 1024);\r\n\t\tfinal PipedOutputStream out = new PipedOutputStream(in);\r\n\r\n\t\t// creates a new thread that will write data to the pipe. Data will be\r\n\t\t// available in another InputStream, connected to the OutputStream.\r\n\t\tnew Thread(new Runnable() {\r\n\t\t\tpublic void run() {\r\n\t\t\t\ttry {\r\n\t\t\t\t\textractFile(hd, out);\r\n\t\t\t\t} catch (RarException e) {\r\n\t\t\t\t} finally {\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tout.close();\r\n\t\t\t\t\t} catch (IOException e) {\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}).start();\r\n\r\n\t\treturn in;\r\n\t}\r\n\r\n\tprivate void doExtractFile(FileHeader hd, OutputStream os)\r\n\t\t\tthrows RarException, IOException {\r\n\t\tdataIO.init(os);\r\n\t\tdataIO.init(hd);\r\n\t\tdataIO.setUnpFileCRC(this.isOldFormat() ? 0 : 0xffFFffFF);\r\n\t\tif (unpack == null) {\r\n\t\t\tunpack = new Unpack(dataIO);\r\n\t\t}\r\n\t\tif (!hd.isSolid()) {\r\n\t\t\tunpack.init(null);\r\n\t\t}\r\n\t\tunpack.setDestSize(hd.getFullUnpackSize());\r\n\t\ttry {\r\n\t\t\tunpack.doUnpack(hd.getUnpVersion(), hd.isSolid());\r\n\t\t\t// Verify file CRC\r\n\t\t\thd = dataIO.getSubHeader();\r\n\t\t\tlong actualCRC = hd.isSplitAfter() ? ~dataIO.getPackedCRC()\r\n\t\t\t\t\t: ~dataIO.getUnpFileCRC();\r\n\t\t\tint expectedCRC = hd.getFileCRC();\r\n\t\t\tif (actualCRC != expectedCRC) {\r\n\t\t\t\tthrow new RarException(RarExceptionType.crcError);\r\n\t\t\t}\r\n\t\t\t// if (!hd.isSplitAfter()) {\r\n\t\t\t// // Verify file CRC\r\n\t\t\t// if(~dataIO.getUnpFileCRC() != hd.getFileCRC()){\r\n\t\t\t// throw new RarException(RarExceptionType.crcError);\r\n\t\t\t// }\r\n\t\t\t// }\r\n\t\t} catch (Exception e) {\r\n\t\t\tunpack.cleanUp();\r\n\t\t\tif (e instanceof RarException) {\r\n\t\t\t\t// throw new RarException((RarException)e);\r\n\t\t\t\tthrow (RarException) e;\r\n\t\t\t} else {\r\n\t\t\t\tthrow new RarException(e);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @return returns the main header of this archive\r\n\t */\r\n\tpublic MainHeader getMainHeader() {\r\n\t\treturn newMhd;\r\n\t}\r\n\r\n\t/**\r\n\t * @return whether the archive is old format\r\n\t */\r\n\tpublic boolean isOldFormat() {\r\n\t\treturn markHead.isOldFormat();\r\n\t}\r\n\r\n\t/** Close the underlying compressed file. */\r\n\tpublic void close() throws IOException {\r\n\t\tif (rof != null) {\r\n\t\t\trof.close();\r\n\t\t\trof = null;\r\n\t\t}\r\n\t\tif (unpack != null) {\r\n\t\t\tunpack.cleanUp();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @return the volumeManager\r\n\t */\r\n\tpublic VolumeManager getVolumeManager() {\r\n\t\treturn volumeManager;\r\n\t}\r\n\r\n\t/**\r\n\t * @param volumeManager\r\n\t *            the volumeManager to set\r\n\t */\r\n\tpublic void setVolumeManager(VolumeManager volumeManager) {\r\n\t\tthis.volumeManager = volumeManager;\r\n\t}\r\n\r\n\t/**\r\n\t * @return the volume\r\n\t */\r\n\tpublic Volume getVolume() {\r\n\t\treturn volume;\r\n\t}\r\n\r\n\t/**\r\n\t * @param volume\r\n\t *            the volume to set\r\n\t * @throws IOException\r\n\t */\r\n\tpublic void setVolume(Volume volume) throws IOException {\r\n\t\tthis.volume = volume;\r\n\t\tsetFile(volume.getReadOnlyAccess(), volume.getLength());\r\n\t}\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/MVTest.java",
    "content": "package com.github.junrar;\n\nimport java.io.File;\nimport java.io.FileNotFoundException;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\n\nimport com.github.junrar.exception.RarException;\nimport com.github.junrar.impl.FileVolumeManager;\nimport com.github.junrar.rarfile.FileHeader;\n\n\npublic class MVTest {\n\n\t/**\n\t * @param args\n\t */\n\tpublic static void main(String[] args) {\n\t\tString filename = \"/home/rogiel/fs/home/ae721273-eade-45e7-8112-d14115ebae56/Village People - Y.M.C.A.mp3.part1.rar\";\n\t\tFile f = new File(filename);\n\t\tArchive a = null;\n\t\ttry {\n\t\t\ta = new Archive(new FileVolumeManager(f));\n\t\t} catch (RarException e) {\n\t\t\t// TODO Auto-generated catch block\n\t\t\te.printStackTrace();\n\t\t} catch (IOException e) {\n\t\t\t// TODO Auto-generated catch block\n\t\t\te.printStackTrace();\n\t\t}\n\t\tif (a != null) {\n\t\t\ta.getMainHeader().print();\n\t\t\tFileHeader fh = a.nextFileHeader();\n\t\t\twhile (fh != null) {\n\t\t\t\ttry {\n\t\t\t\t\tFile out = new File(\"/home/rogiel/fs/test/\"\n\t\t\t\t\t\t\t+ fh.getFileNameString().trim());\n\t\t\t\t\tSystem.out.println(out.getAbsolutePath());\n\t\t\t\t\tFileOutputStream os = new FileOutputStream(out);\n\t\t\t\t\ta.extractFile(fh, os);\n\t\t\t\t\tos.close();\n\t\t\t\t} catch (FileNotFoundException e) {\n\t\t\t\t\t// TODO Auto-generated catch block\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t} catch (RarException e) {\n\t\t\t\t\t// TODO Auto-generated catch block\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t} catch (IOException e) {\n\t\t\t\t\t// TODO Auto-generated catch block\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t}\n\t\t\t\tfh = a.nextFileHeader();\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/UnrarCallback.java",
    "content": "package com.github.junrar;\r\n\r\n\r\n/**\r\n *\r\n * @author alban\r\n */\r\npublic interface UnrarCallback {\r\n\r\n    /**\r\n     * Return <tt>true</tt> if the next volume is ready to be processed,\r\n     * <tt>false</tt> otherwise.\r\n     */\r\n    boolean isNextVolumeReady(Volume nextVolume);\r\n\r\n    /**\r\n     * This method is invoked each time the progress of the current\r\n     * volume changes.\r\n     */\r\n    void volumeProgressChanged(long current, long total);\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/Volume.java",
    "content": "/*\n * This file is part of seedbox <github.com/seedbox>.\n *\n * seedbox is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * seedbox is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with seedbox.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage com.github.junrar;\n\nimport java.io.IOException;\n\nimport com.github.junrar.io.IReadOnlyAccess;\n\n\n/**\n * @author <a href=\"http://www.rogiel.com\">Rogiel</a>\n * \n */\npublic interface Volume {\n\t/**\n\t * @return the access\n\t * @throws IOException\n\t */\n\tIReadOnlyAccess getReadOnlyAccess() throws IOException;\n\n\t/**\n\t * @return the data length\n\t */\n\tlong getLength();\n\t\n\t/**\n\t * @return the archive this volume belongs to\n\t */\n\tArchive getArchive();\n}\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/VolumeManager.java",
    "content": "/*\n * This file is part of seedbox <github.com/seedbox>.\n *\n * seedbox is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * seedbox is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with seedbox.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage com.github.junrar;\n\nimport java.io.IOException;\n\n/**\n * @author <a href=\"http://www.rogiel.com\">Rogiel</a>\n * \n */\npublic interface VolumeManager {\n\tpublic Volume nextArchive(Archive archive, Volume lastVolume)\n\t\t\tthrows IOException;\n}\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/crc/RarCRC.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 29.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n *  \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.crc;\r\n\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class RarCRC {\r\n\t\r\n\tprivate final static int crcTab[];\r\n    static {\r\n\t\tcrcTab = new int[256];\r\n\t\tfor (int i = 0; i < 256; i++) {\r\n\t\t\tint c = i;\r\n\t\t\tfor (int j = 0; j < 8; j++){\r\n\t\t\t\tif ((c & 1) !=0) {\r\n\t\t\t\t\tc >>>= 1;\r\n\t\t\t\t\tc ^= 0xEDB88320;\r\n\t\t\t\t}\r\n                else{\r\n\t\t\t\t\tc >>>= 1;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tcrcTab[i] = c;\r\n\t\t}\r\n    }\r\n\r\n\tprivate RarCRC() {\r\n\t}\r\n\r\n\tpublic static int checkCrc(int startCrc, byte[] data, int offset,\r\n            int count) {\r\n\t\tint size = Math.min(data.length-offset,count);\r\n\t\t// #if defined(LITTLE_ENDIAN) && defined(PRESENT_INT32) &&\r\n\t\t// defined(ALLOW_NOT_ALIGNED_INT)\r\n\t\t/*\r\n\t\tfor (int i = 0; (0 < size) && i < data.length - 8\r\n\t\t\t\t&& ((data[i + 8] & 7) != 0); i++) {\r\n\t\t\tstartCrc = crcTab[(short) (startCrc ^ data[i]) & 0x00FF] ^ (startCrc >>> 8);\r\n\t\t\tsize--;\r\n\t\t}\r\n\t\t\r\n\t\tfor (int i = 0; size >= 8; i += 8) {\r\n\t\t\tstartCrc ^= data[i + 0] << 24;\r\n\t\t\tstartCrc ^= data[i + 1] << 16;\r\n\t\t\tstartCrc ^= data[i + 2] << 8;\r\n\t\t\tstartCrc ^= data[i + 3];\r\n\r\n\t\t\tstartCrc = crcTab[(short) startCrc & 0x00FF] ^ (startCrc >>> 8);\r\n\t\t\tstartCrc = crcTab[(short) startCrc & 0x00FF] ^ (startCrc >>> 8);\r\n\t\t\tstartCrc = crcTab[(short) startCrc & 0x00FF] ^ (startCrc >>> 8);\r\n\t\t\tstartCrc = crcTab[(short) startCrc & 0x00FF] ^ (startCrc >>> 8);\r\n\r\n\t\t\tstartCrc ^= data[i + 4] << 24;\r\n\t\t\tstartCrc ^= data[i + 5] << 16;\r\n\t\t\tstartCrc ^= data[i + 6] << 8;\r\n\t\t\tstartCrc ^= data[i + 7];\r\n\t\t\tstartCrc = crcTab[(short) startCrc & 0x00FF] ^ (startCrc >>> 8);\r\n\t\t\tstartCrc = crcTab[(short) startCrc & 0x00FF] ^ (startCrc >>> 8);\r\n\t\t\tstartCrc = crcTab[(short) startCrc & 0x00FF] ^ (startCrc >>> 8);\r\n\t\t\tstartCrc = crcTab[(short) startCrc & 0x00FF] ^ (startCrc >>> 8);\r\n\t\t\tsize -= 8;\r\n\t\t}*/\r\n\t\t\r\n\t\tfor (int i = 0; i < size; i++)\r\n\t\t{\r\n/*\r\n\t\t\t// (byte)(StartCRC^Data[I])\r\n\t\t\tint pos = 0; // pos=0x00000000\r\n\t\t\tpos |= startCrc; // pos=ffffffff\r\n\t\t\t\r\n\t\t\tpos ^= data[i]; // data[0]=0x73=115dec --> pos=140\r\n\t\t\tSystem.out.println(Integer.toHexString(pos));\r\n\t\t\t\r\n\t\t\t// Only last 8 bit because CRCtab has length 256\r\n\t\t\tpos = pos & 0x000000FF;\r\n\t\t\tSystem.out.println(\"pos:\"+pos);\r\n\t\t\t//startCrc >>>= 8;\r\n\t\t\t\r\n\t\t\t\r\n\t\t\t//StartCRC>>8\r\n\t\t\tint temp =0;\r\n\t\t\ttemp|=startCrc;\r\n\t\t\ttemp >>>= 8;\r\n\t\t\tSystem.out.println(\"temp:\"+Integer.toHexString(temp));\r\n\t\t\t\r\n\t\t\t\r\n\t\t\tstartCrc = (crcTab[pos]^temp);\r\n\t\t\tSystem.out.println(\"--\"+Integer.toHexString(startCrc));*/\r\n\t\t\t\r\n\t\t\tstartCrc=(crcTab[((int)((int)startCrc ^\r\n                    (int)data[offset+i]))&0xff]^(startCrc>>>8));\r\n\t\t\t\r\n\t\t\t//System.out.println(Integer.toHexString(startCrc));\r\n\t\t\t\r\n\t\t\t// Original code:\r\n\t\t\t//StartCRC=CRCTab[(byte)(StartCRC^Data[I])]^(StartCRC>>8);\r\n\t\t}\r\n\t\treturn (startCrc);\r\n\t}\r\n\r\n\tpublic static short checkOldCrc(short startCrc, byte[] data, int count) {\r\n        int n = Math.min(data.length, count);\r\n\t\tfor (int i = 0; i < n; i++) {\r\n\t\t\tstartCrc = (short) ((short) (startCrc + (short) (data[i]&0x00ff)) & -1);\r\n\t\t\tstartCrc = (short) (((startCrc << 1) | (startCrc >>> 15)) & -1);\r\n\t\t}\r\n\t\treturn (startCrc);\r\n\t}\r\n\r\n//\tpublic static void main(String[] args)\r\n//\t{\r\n//\t\tRarCRC rc = new RarCRC();\r\n//\t\t//byte[] data = { 0x72, 0x21, 0x1A, 0x07, 0x00};\r\n//\t\t\r\n//\t\tbyte[] data = {0x73 ,0x00 ,0x00 ,0x0D ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00};\r\n//\t\t\r\n//\t\tint crc = 0x90CF;\r\n//\t\t\r\n//\r\n//\t\tint result = rc.checkCrc(0xFFFFffff, data,0,data.length);\r\n//\t\tSystem.out.println(\"3: \"+Integer.toHexString(~result&0xffff));\r\n//\t\t\r\n//\t}\r\n\t\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/crypt/Rijndael.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 31.05.2007\r\n *\r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.crypt;\r\n\r\n/**\r\n * DOCUMENT ME\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class Rijndael {\r\n\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/exception/RarException.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 30.07.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.exception;\r\n\r\n/**\r\n * DOCUMENT ME\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class RarException extends Exception\r\n{\r\n\tprivate static final long serialVersionUID = 1L;\r\n\tprivate RarExceptionType type;\r\n\t\r\n\tpublic RarException(Exception e){\r\n\t\tsuper(RarExceptionType.unkownError.name(),e);\r\n\t\tthis.type = RarExceptionType.unkownError;\r\n\t}\r\n\t\r\n\tpublic RarException(RarException e)\r\n\t{\r\n\t\t\r\n\t\tsuper(e.getMessage(),e);\r\n\t\tthis.type = e.getType();\r\n\t}\r\n\t\r\n\tpublic RarException(RarExceptionType type){\r\n\t\tsuper(type.name());\r\n\t\tthis.type = type;\r\n\t}\r\n\t\r\n\t\r\n\t\r\n\tpublic enum RarExceptionType{\r\n\t\tnotImplementedYet,\r\n\t\tcrcError,\r\n\t\tnotRarArchive,\r\n\t\tbadRarArchive,\r\n\t\tunkownError,\r\n\t\theaderNotInArchive,\r\n\t\twrongHeaderType,\r\n\t\tioError,\r\n\t\trarEncryptedException ;\r\n\t}\r\n\r\n\r\n\r\n\tpublic RarExceptionType getType()\r\n\t{\r\n\t\treturn type;\r\n\t}\r\n\r\n\tpublic void setType(RarExceptionType type)\r\n\t{\r\n\t\tthis.type = type;\r\n\t}\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/impl/FileVolume.java",
    "content": "/*\n * This file is part of seedbox <github.com/seedbox>.\n *\n * seedbox is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * seedbox is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with seedbox.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage com.github.junrar.impl;\n\nimport java.io.File;\nimport java.io.IOException;\n\nimport com.github.junrar.Archive;\nimport com.github.junrar.Volume;\nimport com.github.junrar.io.IReadOnlyAccess;\nimport com.github.junrar.io.ReadOnlyAccessFile;\n\n\n/**\n * @author <a href=\"http://www.rogiel.com\">Rogiel</a>\n * \n */\npublic class FileVolume implements Volume {\n\tprivate final Archive archive;\n\tprivate final File file;\n\n\t/**\n\t * @param file\n\t */\n\tpublic FileVolume(Archive archive, File file) {\n\t\tthis.archive = archive;\n\t\tthis.file = file;\n\t}\n\n\t@Override\n\tpublic IReadOnlyAccess getReadOnlyAccess() throws IOException {\n\t\treturn new ReadOnlyAccessFile(file);\n\t}\n\n\t@Override\n\tpublic long getLength() {\n\t\treturn file.length();\n\t}\n\n\t@Override\n\tpublic Archive getArchive() {\n\t\treturn archive;\n\t}\n\n\t/**\n\t * @return the file\n\t */\n\tpublic File getFile() {\n\t\treturn file;\n\t}\n}\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/impl/FileVolumeManager.java",
    "content": "/*\n * This file is part of seedbox <github.com/seedbox>.\n *\n * seedbox is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * seedbox is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with seedbox.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage com.github.junrar.impl;\n\nimport java.io.File;\nimport java.io.IOException;\n\nimport com.github.junrar.Archive;\nimport com.github.junrar.Volume;\nimport com.github.junrar.VolumeManager;\nimport com.github.junrar.util.VolumeHelper;\n\n\n/**\n * @author <a href=\"http://www.rogiel.com\">Rogiel</a>\n * \n */\npublic class FileVolumeManager implements VolumeManager {\n\tprivate final File firstVolume;\n\n\tpublic FileVolumeManager(File firstVolume) {\n\t\tthis.firstVolume = firstVolume;\n\t}\n\n\t@Override\n\tpublic Volume nextArchive(Archive archive, Volume last)\n\t\t\tthrows IOException {\n\t\tif (last == null)\n\t\t\treturn new FileVolume(archive, firstVolume);\n\n\t\tFileVolume lastFileVolume = (FileVolume) last;\n\t\tboolean oldNumbering = !archive.getMainHeader().isNewNumbering()\n\t\t\t\t|| archive.isOldFormat();\n\t\tString nextName = VolumeHelper.nextVolumeName(lastFileVolume.getFile()\n\t\t\t\t.getAbsolutePath(), oldNumbering);\n\t\tFile nextVolume = new File(nextName);\n\n\t\treturn new FileVolume(archive, nextVolume);\n\t}\n}\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/io/IReadOnlyAccess.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 23.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.io;\r\n\r\nimport java.io.IOException;\r\n\r\n\r\n/**\r\n * DOCUMENT ME\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic interface IReadOnlyAccess {\r\n\r\n\t/**\r\n\t * @return the current position in the file\r\n\t */\r\n\tpublic long getPosition() throws IOException;\r\n\t\t\r\n\t/**\r\n\t * @param pos the position in the file\r\n\t * @return success ? true : false \r\n\t */\r\n\tpublic void setPosition(long pos) throws IOException;\r\n\r\n    /** Read a single byte of data. */\r\n    public int read() throws IOException;\r\n\r\n\t/**\r\n     * Read up to <tt>count</tt> bytes to the specified buffer.\r\n     */\r\n    public int read(byte[] buffer, int off, int count) throws IOException;\r\n\r\n    /**\r\n     * Read exactly <tt>count</tt> bytes to the specified buffer.\r\n     *\r\n\t * @param buffer where to store the read data\r\n\t * @param count how many bytes to read\r\n\t * @return bytes read || -1 if  IO problem \r\n\t */\r\n\tpublic int readFully(byte[] buffer, int count) throws IOException;\r\n\r\n    /** Close this file. */\r\n    public void close() throws IOException;\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/io/InputStreamReadOnlyAccessFile.java",
    "content": "package com.github.junrar.io;\r\n\r\nimport java.io.BufferedInputStream;\r\nimport java.io.IOException;\r\nimport java.io.InputStream;\r\n\r\n\r\n\r\n\r\n/**\r\n * InputStream based implementation of the <code>IReadOnlyAccess</code> interface.\r\n * \r\n * @see http://rsbweb.nih.gov/ij/\r\n * @author martinr\r\n */\r\npublic class InputStreamReadOnlyAccessFile implements IReadOnlyAccess {\r\n\tprivate RandomAccessStream is;\r\n\r\n\t/**\r\n\t * Create new instance.\r\n\t * \r\n\t * @param is The input stream to wrap.\r\n\t */\r\n\tpublic InputStreamReadOnlyAccessFile(final InputStream is) {\r\n\t\tthis.is = new RandomAccessStream(new BufferedInputStream(is));\r\n\t}\r\n\t\r\n\t@Override\r\n\tpublic long getPosition() throws IOException {\r\n\t\treturn is.getLongFilePointer();\r\n\t}\r\n\r\n\t@Override\r\n\tpublic void setPosition(long pos) throws IOException {\r\n\t\tis.seek(pos);\r\n\t}\r\n\r\n\t@Override\r\n\tpublic int read() throws IOException {\r\n\t\treturn is.read();\r\n\t}\r\n\r\n\t@Override\r\n\tpublic int read(byte[] buffer, int off, int count) throws IOException {\r\n\t\treturn is.read(buffer, off, count);\r\n\t}\r\n\r\n\t@Override\r\n\tpublic int readFully(byte[] buffer, int count) throws IOException {\r\n\t\tis.readFully(buffer, count);\r\n\t\treturn count;\r\n\t}\r\n\r\n\t@Override\r\n\tpublic void close() throws IOException {\r\n\t\tis.close();\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/io/RandomAccessStream.java",
    "content": "/*\n * public domain as of http://rsbweb.nih.gov/ij/disclaimer.html\n */\npackage com.github.junrar.io;\n\nimport java.io.*;\nimport java.util.Vector;\n\n/**\n * This is a class that uses a memory cache to allow seeking within an\n * InputStream. Based on the JAI MemoryCacheSeekableStream class. Can also be\n * constructed from a RandomAccessFile, which uses less memory since the memory\n * cache is not required.\n */\n@SuppressWarnings(\"rawtypes\")\npublic final class RandomAccessStream extends InputStream {\n\n\tprivate static final int BLOCK_SIZE = 512;\n\tprivate static final int BLOCK_MASK = 511;\n\tprivate static final int BLOCK_SHIFT = 9;\n\n\tprivate InputStream src;\n\tprivate RandomAccessFile ras;\n\tprivate long pointer;\n\tprivate Vector data;\n\tprivate int length;\n\tprivate boolean foundEOS;\n\n\t/**\n\t * Constructs a RandomAccessStream from an InputStream. Seeking backwards is\n\t * supported using a memory cache.\n\t */\n\tpublic RandomAccessStream(InputStream inputstream) {\n\t\tpointer = 0L;\n\t\tdata = new Vector();\n\t\tlength = 0;\n\t\tfoundEOS = false;\n\t\tsrc = inputstream;\n\t}\n\n\t/** Constructs a RandomAccessStream from an RandomAccessFile. */\n\tpublic RandomAccessStream(RandomAccessFile ras) {\n\t\tthis.ras = ras;\n\t}\n\n\tpublic int getFilePointer() throws IOException {\n\t\tif (ras != null)\n\t\t\treturn (int) ras.getFilePointer();\n\t\telse\n\t\t\treturn (int) pointer;\n\t}\n\n\tpublic long getLongFilePointer() throws IOException {\n\t\tif (ras != null)\n\t\t\treturn ras.getFilePointer();\n\t\telse\n\t\t\treturn pointer;\n\t}\n\n\tpublic int read() throws IOException {\n\t\tif (ras != null)\n\t\t\treturn ras.read();\n\t\tlong l = pointer + 1L;\n\t\tlong l1 = readUntil(l);\n\t\tif (l1 >= l) {\n\t\t\tbyte abyte0[] = (byte[]) data\n\t\t\t\t\t.elementAt((int) (pointer >> BLOCK_SHIFT));\n\t\t\treturn abyte0[(int) (pointer++ & BLOCK_MASK)] & 0xff;\n\t\t} else\n\t\t\treturn -1;\n\t}\n\n\tpublic int read(byte[] bytes, int off, int len) throws IOException {\n\t\tif (bytes == null)\n\t\t\tthrow new NullPointerException();\n\t\tif (ras != null)\n\t\t\treturn ras.read(bytes, off, len);\n\t\tif (off < 0 || len < 0 || off + len > bytes.length)\n\t\t\tthrow new IndexOutOfBoundsException();\n\t\tif (len == 0)\n\t\t\treturn 0;\n\t\tlong l = readUntil(pointer + len);\n\t\tif (l <= pointer)\n\t\t\treturn -1;\n\t\telse {\n\t\t\tbyte abyte1[] = (byte[]) data\n\t\t\t\t\t.elementAt((int) (pointer >> BLOCK_SHIFT));\n\t\t\tint k = Math.min(len, BLOCK_SIZE - (int) (pointer & BLOCK_MASK));\n\t\t\tSystem.arraycopy(abyte1, (int) (pointer & BLOCK_MASK), bytes, off,\n\t\t\t\t\tk);\n\t\t\tpointer += k;\n\t\t\treturn k;\n\t\t}\n\t}\n\n\tpublic final void readFully(byte[] bytes) throws IOException {\n\t\treadFully(bytes, bytes.length);\n\t}\n\n\tpublic final void readFully(byte[] bytes, int len) throws IOException {\n\t\tint read = 0;\n\t\tdo {\n\t\t\tint l = read(bytes, read, len - read);\n\t\t\tif (l < 0)\n\t\t\t\tbreak;\n\t\t\tread += l;\n\t\t} while (read < len);\n\t}\n\n\t@SuppressWarnings(\"unchecked\")\n\tprivate long readUntil(long l) throws IOException {\n\t\tif (l < length)\n\t\t\treturn l;\n\t\tif (foundEOS)\n\t\t\treturn length;\n\t\tint i = (int) (l >> BLOCK_SHIFT);\n\t\tint j = length >> BLOCK_SHIFT;\n\t\tfor (int k = j; k <= i; k++) {\n\t\t\tbyte abyte0[] = new byte[BLOCK_SIZE];\n\t\t\tdata.addElement(abyte0);\n\t\t\tint i1 = BLOCK_SIZE;\n\t\t\tint j1 = 0;\n\t\t\twhile (i1 > 0) {\n\t\t\t\tint k1 = src.read(abyte0, j1, i1);\n\t\t\t\tif (k1 == -1) {\n\t\t\t\t\tfoundEOS = true;\n\t\t\t\t\treturn length;\n\t\t\t\t}\n\t\t\t\tj1 += k1;\n\t\t\t\ti1 -= k1;\n\t\t\t\tlength += k1;\n\t\t\t}\n\n\t\t}\n\n\t\treturn length;\n\t}\n\n\tpublic void seek(long loc) throws IOException {\n\t\tif (ras != null) {\n\t\t\tras.seek(loc);\n\t\t\treturn;\n\t\t}\n\t\tif (loc < 0L)\n\t\t\tpointer = 0L;\n\t\telse\n\t\t\tpointer = loc;\n\t}\n\n\tpublic void seek(int loc) throws IOException {\n\t\tlong lloc = ((long) loc) & 0xffffffffL;\n\t\tif (ras != null) {\n\t\t\tras.seek(lloc);\n\t\t\treturn;\n\t\t}\n\t\tif (lloc < 0L)\n\t\t\tpointer = 0L;\n\t\telse\n\t\t\tpointer = lloc;\n\t}\n\n\tpublic final int readInt() throws IOException {\n\t\tint i = read();\n\t\tint j = read();\n\t\tint k = read();\n\t\tint l = read();\n\t\tif ((i | j | k | l) < 0)\n\t\t\tthrow new EOFException();\n\t\telse\n\t\t\treturn (i << 24) + (j << 16) + (k << 8) + l;\n\t}\n\n\tpublic final long readLong() throws IOException {\n\t\treturn ((long) readInt() << 32) + ((long) readInt() & 0xffffffffL);\n\t}\n\n\tpublic final double readDouble() throws IOException {\n\t\treturn Double.longBitsToDouble(readLong());\n\t}\n\n\tpublic final short readShort() throws IOException {\n\t\tint i = read();\n\t\tint j = read();\n\t\tif ((i | j) < 0)\n\t\t\tthrow new EOFException();\n\t\telse\n\t\t\treturn (short) ((i << 8) + j);\n\t}\n\n\tpublic final float readFloat() throws IOException {\n\t\treturn Float.intBitsToFloat(readInt());\n\t}\n\n\tpublic void close() throws IOException {\n\t\tif (ras != null)\n\t\t\tras.close();\n\t\telse {\n\t\t\tdata.removeAllElements();\n\t\t\tsrc.close();\n\t\t}\n\t}\n\n}"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/io/Raw.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 18.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.io;\r\n\r\n/**\r\n * Read / write numbers to a byte[] regarding the endianness of the array\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class Raw {\r\n    /**\r\n     * Read a short value from the byte array at the given position (Big Endian)\r\n     * \r\n     * @param array\r\n     *            the array to read from\r\n     * @param pos\r\n     *            the position\r\n     * @return the value\r\n     */\r\n    public static final short readShortBigEndian(byte[] array, int pos) {\r\n\tshort temp = 0;\r\n\ttemp |= array[pos] & 0xff;\r\n\ttemp <<= 8;\r\n\ttemp |= array[pos + 1] & 0xff;\r\n\treturn temp;\r\n    }\r\n\r\n    /**\r\n     * Read a int value from the byte array at the given position (Big Endian)\r\n     * \r\n     * @param array\r\n     *            the array to read from\r\n     * @param pos\r\n     *            the offset\r\n     * @return the value\r\n     */\r\n    public static final int readIntBigEndian(byte[] array, int pos) {\r\n\tint temp = 0;\r\n\ttemp |= array[pos] & 0xff;\r\n\ttemp <<= 8;\r\n\ttemp |= array[pos + 1] & 0xff;\r\n\ttemp <<= 8;\r\n\ttemp |= array[pos + 2] & 0xff;\r\n\ttemp <<= 8;\r\n\ttemp |= array[pos + 3] & 0xff;\r\n\treturn temp;\r\n    }\r\n\r\n    /**\r\n     * Read a long value from the byte array at the given position (Big Endian)\r\n     * \r\n     * @param array\r\n     *            the array to read from\r\n     * @param pos\r\n     *            the offset\r\n     * @return the value\r\n     */\r\n    public static final long readLongBigEndian(byte[] array, int pos) {\r\n\tint temp = 0;\r\n\ttemp |= array[pos] & 0xff;\r\n\ttemp <<= 8;\r\n\ttemp |= array[pos + 1] & 0xff;\r\n\ttemp <<= 8;\r\n\ttemp |= array[pos + 2] & 0xff;\r\n\ttemp <<= 8;\r\n\ttemp |= array[pos + 3] & 0xff;\r\n\ttemp <<= 8;\r\n\ttemp |= array[pos + 4] & 0xff;\r\n\ttemp <<= 8;\r\n\ttemp |= array[pos + 5] & 0xff;\r\n\ttemp <<= 8;\r\n\ttemp |= array[pos + 6] & 0xff;\r\n\ttemp <<= 8;\r\n\ttemp |= array[pos + 7] & 0xff;\r\n\treturn temp;\r\n    }\r\n\r\n    /**\r\n     * Read a short value from the byte array at the given position (little\r\n     * Endian)\r\n     * \r\n     * @param array\r\n     *            the array to read from\r\n     * @param pos\r\n     *            the offset\r\n     * @return the value\r\n     */\r\n    public static final short readShortLittleEndian(byte[] array, int pos) {\r\n\tshort result = 0;\r\n\tresult += array[pos + 1] & 0xff;\r\n\tresult <<= 8;\r\n\tresult += array[pos] & 0xff;\r\n\treturn result;\r\n    }\r\n\r\n    /**\r\n     * Read an int value from the byte array at the given position (little\r\n     * Endian)\r\n     * \r\n     * @param array\r\n     *            the array to read from\r\n     * @param pos\r\n     *            the offset\r\n     * @return the value\r\n     */\r\n    public static final int readIntLittleEndian(byte[] array, int pos) {\r\n\treturn ((array[pos + 3] & 0xff) << 24)\r\n\t\t| ((array[pos + 2] & 0xff) << 16)\r\n\t\t| ((array[pos + 1] & 0xff) << 8) | ((array[pos] & 0xff));\r\n    }\r\n\r\n    /**\r\n     * Read an long value(unsigned int) from the byte array at the given\r\n     * position (little Endian)\r\n     * \r\n     * @param array\r\n     * @param pos\r\n     * @return\r\n     */\r\n    public static final long readIntLittleEndianAsLong(byte[] array, int pos) {\r\n\treturn (((long) array[pos + 3] & 0xff) << 24)\r\n\t\t| (((long) array[pos + 2] & 0xff) << 16)\r\n\t\t| (((long) array[pos + 1] & 0xff) << 8)\r\n\t\t| (((long) array[pos] & 0xff));\r\n    }\r\n\r\n    /**\r\n     * Read a long value from the byte array at the given position (little\r\n     * Endian)\r\n     * \r\n     * @param array\r\n     *            the array to read from\r\n     * @param pos\r\n     *            the offset\r\n     * @return the value\r\n     */\r\n    public static final long readLongLittleEndian(byte[] array, int pos) {\r\n\tint temp = 0;\r\n\ttemp |= array[pos + 7] & 0xff;\r\n\ttemp <<= 8;\r\n\ttemp |= array[pos + 6] & 0xff;\r\n\ttemp <<= 8;\r\n\ttemp |= array[pos + 5] & 0xff;\r\n\ttemp <<= 8;\r\n\ttemp |= array[pos + 4] & 0xff;\r\n\ttemp <<= 8;\r\n\ttemp |= array[pos + 3] & 0xff;\r\n\ttemp <<= 8;\r\n\ttemp |= array[pos + 2] & 0xff;\r\n\ttemp <<= 8;\r\n\ttemp |= array[pos + 1] & 0xff;\r\n\ttemp <<= 8;\r\n\ttemp |= array[pos];\r\n\treturn temp;\r\n    }\r\n\r\n    /**\r\n     * Write a short value into the byte array at the given position (Big\r\n     * endian)\r\n     * \r\n     * @param array\r\n     *            the array\r\n     * @param pos\r\n     *            the offset\r\n     * @param value\r\n     *            the value to write\r\n     */\r\n    public static final void writeShortBigEndian(byte[] array, int pos,\r\n\t    short value) {\r\n\tarray[pos] = (byte) (value >>> 8);\r\n\tarray[pos + 1] = (byte) (value & 0xFF);\r\n\r\n    }\r\n\r\n    /**\r\n     * Write an int value into the byte array at the given position (Big endian)\r\n     * \r\n     * @param array\r\n     *            the array\r\n     * @param pos\r\n     *            the offset\r\n     * @param value\r\n     *            the value to write\r\n     */\r\n    public static final void writeIntBigEndian(byte[] array, int pos, int value) {\r\n\tarray[pos] = (byte) ((value >>> 24) & 0xff);\r\n\tarray[pos + 1] = (byte) ((value >>> 16) & 0xff);\r\n\tarray[pos + 2] = (byte) ((value >>> 8) & 0xff);\r\n\tarray[pos + 3] = (byte) ((value) & 0xff);\r\n\r\n    }\r\n\r\n    /**\r\n     * Write a long value into the byte array at the given position (Big endian)\r\n     * \r\n     * @param array\r\n     *            the array\r\n     * @param pos\r\n     *            the offset\r\n     * @param value\r\n     *            the value to write\r\n     */\r\n    public static final void writeLongBigEndian(byte[] array, int pos,\r\n\t    long value) {\r\n\tarray[pos] = (byte) (value >>> 56);\r\n\tarray[pos + 1] = (byte) (value >>> 48);\r\n\tarray[pos + 2] = (byte) (value >>> 40);\r\n\tarray[pos + 3] = (byte) (value >>> 32);\r\n\tarray[pos + 4] = (byte) (value >>> 24);\r\n\tarray[pos + 5] = (byte) (value >>> 16);\r\n\tarray[pos + 6] = (byte) (value >>> 8);\r\n\tarray[pos + 7] = (byte) (value & 0xFF);\r\n\r\n    }\r\n\r\n    /**\r\n     * Write a short value into the byte array at the given position (little\r\n     * endian)\r\n     * \r\n     * @param array\r\n     *            the array\r\n     * @param pos\r\n     *            the offset\r\n     * @param value\r\n     *            the value to write\r\n     */\r\n    public static final void writeShortLittleEndian(byte[] array, int pos,\r\n\t    short value) {\r\n\tarray[pos + 1] = (byte) (value >>> 8);\r\n\tarray[pos] = (byte) (value & 0xFF);\r\n\r\n    }\r\n\r\n    /**\r\n     * Increment a short value at the specified position by the specified amount\r\n     * (little endian).\r\n     */\r\n    public static final void incShortLittleEndian(byte[] array, int pos, int dv) {\r\n\tint c = ((array[pos] & 0xff) + (dv & 0xff)) >>> 8;\r\n\tarray[pos] += dv & 0xff;\r\n\tif ((c > 0) || ((dv & 0xff00) != 0)) {\r\n\t    array[pos + 1] += ((dv >>> 8) & 0xff) + c;\r\n\t}\r\n    }\r\n\r\n    /**\r\n     * Write an int value into the byte array at the given position (little\r\n     * endian)\r\n     * \r\n     * @param array\r\n     *            the array\r\n     * @param pos\r\n     *            the offset\r\n     * @param value\r\n     *            the value to write\r\n     */\r\n    public static final void writeIntLittleEndian(byte[] array, int pos,\r\n\t    int value) {\r\n\tarray[pos + 3] = (byte) (value >>> 24);\r\n\tarray[pos + 2] = (byte) (value >>> 16);\r\n\tarray[pos + 1] = (byte) (value >>> 8);\r\n\tarray[pos] = (byte) (value & 0xFF);\r\n\r\n    }\r\n\r\n    /**\r\n     * Write a long value into the byte array at the given position (little\r\n     * endian)\r\n     * \r\n     * @param array\r\n     *            the array\r\n     * @param pos\r\n     *            the offset\r\n     * @param value\r\n     *            the value to write\r\n     */\r\n    public static final void writeLongLittleEndian(byte[] array, int pos,\r\n\t    long value) {\r\n\tarray[pos + 7] = (byte) (value >>> 56);\r\n\tarray[pos + 6] = (byte) (value >>> 48);\r\n\tarray[pos + 5] = (byte) (value >>> 40);\r\n\tarray[pos + 4] = (byte) (value >>> 32);\r\n\tarray[pos + 3] = (byte) (value >>> 24);\r\n\tarray[pos + 2] = (byte) (value >>> 16);\r\n\tarray[pos + 1] = (byte) (value >>> 8);\r\n\tarray[pos] = (byte) (value & 0xFF);\r\n\r\n    }\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/io/ReadOnlyAccessByteArray.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 30.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.io;\r\n\r\nimport java.io.EOFException;\r\nimport java.io.IOException;\r\n\r\n/**\r\n * A File like access to a byte array.\r\n * (seek and read certain number of bytes)\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class ReadOnlyAccessByteArray implements IReadOnlyAccess{\r\n\r\n\tprivate int positionInFile;\r\n\tprivate byte[] file;\r\n\t\r\n\t/**\r\n\t * Initialize with byte[ ]\r\n\t * @param file the file given as byte array\r\n\t */\r\n\tpublic ReadOnlyAccessByteArray(byte[] file){\r\n\t\tif(file == null){\r\n\t\t\tthrow new NullPointerException(\"file must not be null!!\");\r\n\t\t}\r\n\t\tthis.file = file;\r\n\t\tthis.positionInFile = 0;\r\n\t}\r\n\r\n    public long getPosition() throws IOException {\r\n\t\treturn positionInFile;\r\n\t}\r\n\r\n\tpublic void setPosition(long pos) throws IOException {\r\n\t\tif (pos < file.length && pos >= 0){\r\n\t\t\tthis.positionInFile = (int)pos;\r\n\t\t}\r\n        else{\r\n\t\t\tthrow new EOFException();\r\n\t\t}\r\n\t}\r\n\r\n    /** Read a single byte of data. */\r\n    public int read() throws IOException {\r\n        return file[positionInFile++];\r\n    }\r\n\r\n\t/**\r\n     * Read up to <tt>count</tt> bytes to the specified buffer.\r\n     */\r\n    public int read(byte[] buffer, int off, int count) throws IOException {\r\n        int read = Math.min(count, file.length-positionInFile);\r\n        System.arraycopy(file, positionInFile, buffer, off, read);\r\n        positionInFile += read;\r\n        return read;\r\n    }\r\n\r\n\tpublic int readFully(byte[] buffer, int count) throws IOException {\r\n\t\tif(buffer == null ){\r\n\t\t\tthrow new NullPointerException(\"buffer must not be null\");\r\n\t\t}\r\n\t\tif(count == 0){\r\n\t\t\tthrow new IllegalArgumentException(\"cannot read 0 bytes ;-)\");\r\n\t\t}\r\n\t\tint read = Math.min(count, file.length-(int)positionInFile-1);\t\r\n\t\tSystem.arraycopy(file, (int)positionInFile, buffer, 0, read );\r\n\t\tpositionInFile+=read;\r\n\t\treturn read;\r\n\t}\r\n\r\n    public void close() throws IOException {\r\n    }\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/io/ReadOnlyAccessFile.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 23.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.io;\r\n\r\nimport java.io.File;\r\nimport java.io.FileNotFoundException;\r\nimport java.io.IOException;\r\nimport java.io.RandomAccessFile;\r\n\r\n/**\r\n * DOCUMENT ME\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class ReadOnlyAccessFile extends RandomAccessFile\r\n        implements IReadOnlyAccess{\r\n\r\n\t/**\r\n\t * @param file the file\r\n\t * @throws FileNotFoundException\r\n\t */\r\n\tpublic ReadOnlyAccessFile(File file) throws FileNotFoundException {\r\n\t\tsuper(file, \"r\");\r\n\t}\r\n\r\n\tpublic int readFully(byte[] buffer, int count) throws IOException {\r\n        assert (count > 0) : count;\r\n        this.readFully(buffer, 0, count);\r\n        return count;\r\n    }\r\n\r\n\tpublic long getPosition() throws IOException {\r\n        return this.getFilePointer();\r\n\t}\r\n\r\n\tpublic void setPosition(long pos) throws IOException {\r\n        this.seek(pos);\r\n\t}\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/io/ReadOnlyAccessInputStream.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 26.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression\r\n * algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.io;\r\n\r\nimport java.io.IOException;\r\nimport java.io.InputStream;\r\n\r\n/**\r\n * DOCUMENT ME\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class ReadOnlyAccessInputStream extends InputStream {\r\n\tprivate IReadOnlyAccess file;\r\n\t\r\n\tprivate long curPos;\r\n\tprivate final long startPos;\r\n\tprivate final long endPos;\r\n\t\r\n\tpublic ReadOnlyAccessInputStream(IReadOnlyAccess file, long startPos,\r\n            long endPos) throws IOException {\r\n\t\tsuper();\r\n\t\tthis.file = file;\r\n\t\tthis.startPos = startPos;\r\n\t\tcurPos = startPos;\r\n\t\tthis.endPos = endPos;\r\n\t\tfile.setPosition(curPos);\r\n\t}\r\n\r\n\t@Override\r\n\tpublic int read() throws IOException {\r\n        if (curPos == endPos) {\r\n            return -1;\r\n        }\r\n        else {\r\n            int b = file.read();\r\n            curPos++;\r\n            return b;\r\n        }\r\n\t}\r\n\r\n\t@Override\r\n\tpublic int read(byte[] b, int off, int len) throws IOException {\r\n        if (len == 0) {\r\n            return 0;\r\n        }\r\n        if (curPos == endPos) {\r\n            return -1;\r\n        }\r\n        int bytesRead = file.read(b, off,\r\n                (int)Math.min(len, endPos - curPos));\r\n        curPos += bytesRead;\r\n        return bytesRead;\r\n\t}\r\n\r\n\t@Override\r\n\tpublic int read(byte[] b) throws IOException {\r\n        return read(b, 0, b.length);\r\n\t}\r\n//\r\n//    public void close() throws IOException {\r\n//        file.close();\r\n//    }\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/rarfile/AVHeader.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 24.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n *\r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.rarfile;\r\n\r\nimport com.github.junrar.io.Raw;\r\n\r\n/**\r\n * extended version info header\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class AVHeader extends BaseBlock {\r\n\t\r\n\tpublic static final int avHeaderSize = 7;\r\n\t\r\n\tprivate byte unpackVersion;\r\n\tprivate byte method;\r\n\tprivate byte avVersion;\r\n\tprivate int avInfoCRC;\r\n\t\r\n\tpublic AVHeader(BaseBlock bb, byte[] avHeader){\r\n\t\tsuper(bb);\r\n\t\t\r\n\t\tint pos =0;\r\n\t\tunpackVersion |= avHeader[pos]&0xff;\r\n\t\tpos++;\r\n\t\tmethod |= avHeader[pos]&0xff;\r\n\t\tpos++;\r\n\t\tavVersion |= avHeader[pos]&0xff;\r\n\t\tpos++;\r\n\t\tavInfoCRC = Raw.readIntLittleEndian(avHeader, pos);\r\n\t}\r\n\t\r\n\tpublic int getAvInfoCRC() {\r\n\t\treturn avInfoCRC;\r\n\t}\r\n\t\r\n\tpublic byte getAvVersion() {\r\n\t\treturn avVersion;\r\n\t}\r\n\t\r\n\tpublic byte getMethod() {\r\n\t\treturn method;\r\n\t}\r\n\t\r\n\tpublic byte getUnpackVersion() {\r\n\t\treturn unpackVersion;\r\n\t}\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/rarfile/BaseBlock.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 22.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n *\r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.rarfile;\r\n\r\nimport org.apache.commons.logging.Log;\r\nimport org.apache.commons.logging.LogFactory;\r\n\r\nimport com.github.junrar.io.Raw;\r\n\r\n\r\n\r\n/**\r\n * Base class of all rar headers\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class BaseBlock{\r\n\t\r\n\tLog logger = LogFactory.getLog(BaseBlock.class.getName());\r\n\t\r\n\tpublic static final short BaseBlockSize = 7;\r\n\t\r\n\t//TODO move somewhere else\r\n\t\r\n\tpublic static final short MHD_VOLUME = 0x0001;\r\n\tpublic static final short MHD_COMMENT = 0x0002;\r\n\tpublic static final short MHD_LOCK = 0x0004;\r\n\tpublic static final short MHD_SOLID = 0x0008;\r\n\tpublic static final short MHD_PACK_COMMENT = 0x0010;\r\n\tpublic static final short MHD_NEWNUMBERING = 0x0010;\r\n\tpublic static final short MHD_AV = 0x0020;\r\n\tpublic static final short MHD_PROTECT = 0x0040;\r\n\tpublic static final short MHD_PASSWORD = 0x0080;\r\n\tpublic static final short MHD_FIRSTVOLUME = 0x0100;\r\n\tpublic static final short MHD_ENCRYPTVER = 0x0200;\r\n\t\r\n\t\r\n\tpublic static final short LHD_SPLIT_BEFORE =  0x0001;\r\n\tpublic static final short LHD_SPLIT_AFTER  =  0x0002;\r\n\tpublic static final short LHD_PASSWORD     =  0x0004;\r\n\tpublic static final short LHD_COMMENT      =  0x0008;\r\n\tpublic static final short LHD_SOLID        =  0x0010;\r\n\r\n\tpublic static final short LHD_WINDOWMASK   =  0x00e0;\r\n\tpublic static final short LHD_WINDOW64     =  0x0000;\r\n\tpublic static final short LHD_WINDOW128    =  0x0020;\r\n\tpublic static final short LHD_WINDOW256    =  0x0040;\r\n\tpublic static final short LHD_WINDOW512    =  0x0060;\r\n\tpublic static final short LHD_WINDOW1024   =  0x0080;\r\n\tpublic static final short LHD_WINDOW2048   =  0x00a0;\r\n\tpublic static final short LHD_WINDOW4096   =  0x00c0;\r\n\tpublic static final short LHD_DIRECTORY    =  0x00e0;\r\n\r\n\tpublic static final short LHD_LARGE        =  0x0100;\r\n\tpublic static final short LHD_UNICODE      =  0x0200;\r\n\tpublic static final short LHD_SALT         =  0x0400;\r\n\tpublic static final short LHD_VERSION      =  0x0800;\r\n\tpublic static final short LHD_EXTTIME      =  0x1000;\r\n\tpublic static final short LHD_EXTFLAGS     =  0x2000;\r\n\r\n\tpublic static final short SKIP_IF_UNKNOWN  =  0x4000;\r\n\tpublic static final short LONG_BLOCK \t   = -0x8000;\r\n\r\n\tpublic static final short EARC_NEXT_VOLUME =  0x0001;\r\n\tpublic static final short EARC_DATACRC     =  0x0002;\r\n\tpublic static final short EARC_REVSPACE    =  0x0004;\r\n\tpublic static final short EARC_VOLNUMBER   =  0x0008;\r\n\t\r\n\t\r\n\tprotected long positionInFile;\r\n\t\r\n\tprotected short headCRC = 0;\r\n\tprotected byte headerType = 0;\r\n\tprotected short flags = 0;\r\n\tprotected short headerSize = 0 ;\r\n\r\n\t/**\r\n\t * \r\n\t */\r\n\tpublic BaseBlock(){\r\n\t\t\r\n\t}\r\n\t\r\n\tpublic BaseBlock(BaseBlock bb){\r\n\t\tthis.flags = bb.getFlags();\r\n    \tthis.headCRC = bb.getHeadCRC();\r\n    \tthis.headerType = bb.getHeaderType().getHeaderByte();\r\n    \tthis.headerSize = bb.getHeaderSize();\r\n    \tthis.positionInFile = bb.getPositionInFile();\r\n\t}\r\n\tpublic BaseBlock(byte[] baseBlockHeader){\r\n\t\t\r\n\t\tint pos = 0;\r\n\t\tthis.headCRC = Raw.readShortLittleEndian(baseBlockHeader, pos);\r\n\t\tpos+=2;\r\n\t\tthis.headerType |= baseBlockHeader[pos]&0xff;\r\n\t\tpos++;\r\n\t\tthis.flags = Raw.readShortLittleEndian(baseBlockHeader, pos);\r\n\t\tpos+=2;\r\n\t\tthis.headerSize = Raw.readShortLittleEndian(baseBlockHeader, pos);\r\n\t}\r\n\t\r\n\t\r\n\tpublic boolean hasArchiveDataCRC(){\r\n\t\treturn (this.flags & EARC_DATACRC)!=0;\r\n\t}\r\n\t\r\n\tpublic boolean hasVolumeNumber(){\r\n\t\treturn (this.flags & EARC_VOLNUMBER)!=0;\r\n\t}\r\n\t\r\n\tpublic boolean hasEncryptVersion(){\r\n\t\treturn (flags & MHD_ENCRYPTVER)!=0;\r\n\t}\r\n\t\r\n\t/**\r\n\t * @return is it a sub block\r\n\t */\r\n\tpublic boolean isSubBlock()\r\n\t{\r\n\t\t if (UnrarHeadertype.SubHeader.equals(headerType)){\r\n\t\t\t return(true);\r\n\t\t }\r\n\t\t if (UnrarHeadertype.NewSubHeader.equals(headerType) && (flags & LHD_SOLID)!=0)\r\n\t\t {\r\n\t\t\t return(true);\r\n\t\t }\r\n\t\t return(false);\r\n\t\t\r\n\t}\r\n\r\n\tpublic long getPositionInFile() {\r\n\t\treturn positionInFile;\r\n\t}\r\n\r\n\tpublic short getFlags() {\r\n\t\treturn flags;\r\n\t}\r\n\r\n\tpublic short getHeadCRC() {\r\n\t\treturn headCRC;\r\n\t}\r\n\t\r\n\tpublic short getHeaderSize() {\r\n\t\treturn headerSize;\r\n\t}\r\n\r\n\tpublic UnrarHeadertype getHeaderType() {\r\n\t\treturn UnrarHeadertype.findType(headerType);\r\n\t}\r\n\t\r\n\tpublic void setPositionInFile(long positionInFile) {\r\n\t\tthis.positionInFile = positionInFile;\r\n\t}\r\n\t\r\n\tpublic void print(){\r\n\t\tStringBuilder str  =new StringBuilder();\r\n\t\tstr.append(\"HeaderType: \" + getHeaderType());\r\n\t\tstr.append(\"\\nHeadCRC: \"+Integer.toHexString(getHeadCRC()));\r\n\t\tstr.append(\"\\nFlags: \"+Integer.toHexString(getFlags()));\r\n\t\tstr.append(\"\\nHeaderSize: \"+getHeaderSize());\r\n\t\tstr.append(\"\\nPosition in file: \"+getPositionInFile());\r\n\t\tlogger.info(str.toString());\r\n\t}\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/rarfile/BlockHeader.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 22.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n *\r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.rarfile;\r\n\r\nimport org.apache.commons.logging.Log;\r\nimport org.apache.commons.logging.LogFactory;\r\n\r\nimport com.github.junrar.io.Raw;\r\n\r\n\r\n/**\r\n * Base class of headers that contain data\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class BlockHeader extends BaseBlock{\r\n\tpublic static final short blockHeaderSize = 4;\r\n\t\r\n\tprivate Log logger = LogFactory.getLog(BlockHeader.class.getName());\r\n\t\r\n\tprivate int dataSize;\r\n\tprivate int packSize;\r\n    \r\n    public BlockHeader(){\r\n    \t\r\n    }\r\n    \r\n    public BlockHeader(BlockHeader bh){\r\n    \tsuper(bh);\r\n    \tthis.packSize = bh.getDataSize();\r\n    \tthis.dataSize = packSize;\r\n    \tthis.positionInFile = bh.getPositionInFile();\r\n    }\r\n    \r\n    public BlockHeader(BaseBlock bb, byte[] blockHeader) \r\n    {\r\n    \tsuper(bb);\r\n    \t\r\n    \tthis.packSize = Raw.readIntLittleEndian(blockHeader, 0);\r\n    \tthis.dataSize  = this.packSize;\r\n    }\r\n    \r\n\tpublic int getDataSize() {\r\n\t\treturn dataSize;\r\n\t}\r\n\t\r\n\tpublic int getPackSize() {\r\n\t\treturn packSize;\r\n\t}\r\n    \r\n    public void print(){\r\n    \tsuper.print();\r\n    \tString s = \"DataSize: \"+getDataSize()+\" packSize: \"+getPackSize();\r\n    \tlogger.info(s);\r\n    }\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/rarfile/CommentHeader.java",
    "content": "/*\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\n * Original author: Edmund Wagner\n * Creation date: 23.05.2007\n *\n * Source: $HeadURL$\n * Last changed: $LastChangedDate$\n *\n * \n * the unrar licence applies to all junrar source and binary distributions \n * you are not allowed to use this source to re-create the RAR compression algorithm\n *\n * Here some html entities which can be used for escaping javadoc tags:\n * \"&\":  \"&#038;\" or \"&amp;\"\n * \"<\":  \"&#060;\" or \"&lt;\"\n * \">\":  \"&#062;\" or \"&gt;\"\n * \"@\":  \"&#064;\" \n */\n\npackage com.github.junrar.rarfile;\n\nimport com.github.junrar.io.Raw;\n\n/**\n * Comment header\n *\n * @author $LastChangedBy$\n * @version $LastChangedRevision$\n */\npublic class CommentHeader extends BaseBlock {\n\t\n\tpublic static final short commentHeaderSize = 6;\n\t\n\tprivate short unpSize;\n\tprivate byte unpVersion;\n\tprivate byte unpMethod;\n\tprivate short commCRC;\n\t\n\t\n\tpublic CommentHeader(BaseBlock bb, byte[] commentHeader){\n\t\tsuper(bb);\n\t\t\n\t\tint pos =0;\n\t\tunpSize = Raw.readShortLittleEndian(commentHeader, pos);\n\t\tpos += 2;\n\t\tunpVersion |= commentHeader[pos]&0xff;\n\t\tpos++;\n\t\t\n\t\tunpMethod |= commentHeader[pos]&0xff;\n\t\tpos++;\n\t\tcommCRC =Raw.readShortLittleEndian(commentHeader, pos);\n\t\t\n\t}\n\t\n\tpublic short getCommCRC() {\n\t\treturn commCRC;\n\t}\n\t\n\tpublic byte getUnpMethod() {\n\t\treturn unpMethod;\n\t}\n\t\n\tpublic short getUnpSize() {\n\t\treturn unpSize;\n\t}\n\t\n\tpublic byte getUnpVersion() {\n\t\treturn unpVersion;\n\t}\n}\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/rarfile/EAHeader.java",
    "content": "/*\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\n * Original author: Edmund Wagner\n * Creation date: 27.11.2007\n *\n * Source: $HeadURL$\n * Last changed: $LastChangedDate$\n * \n * \n * the unrar licence applies to all junrar source and binary distributions \n * you are not allowed to use this source to re-create the RAR compression algorithm\n *\n * Here some html entities which can be used for escaping javadoc tags:\n * \"&\":  \"&#038;\" or \"&amp;\"\n * \"<\":  \"&#060;\" or \"&lt;\"\n * \">\":  \"&#062;\" or \"&gt;\"\n * \"@\":  \"&#064;\" \n */\npackage com.github.junrar.rarfile;\n\nimport org.apache.commons.logging.Log;\nimport org.apache.commons.logging.LogFactory;\n\nimport com.github.junrar.io.Raw;\n\n\n/**\n * extended archive CRC header\n *\n */\npublic class EAHeader \nextends SubBlockHeader \n{\n\tprivate Log logger = LogFactory.getLog(getClass());\n\t\n\tpublic static final short EAHeaderSize = 10;\n\t\n\tprivate int unpSize;\n\tprivate byte unpVer;\n\tprivate byte method;\n\tprivate int EACRC;\n\t\n\tpublic EAHeader(SubBlockHeader sb, byte[] eahead)\n\t{\n\t\tsuper(sb);\n\t\tint pos = 0;\n\t\tunpSize = Raw.readIntLittleEndian(eahead, pos);\n\t\tpos+=4;\n\t\tunpVer |= eahead[pos]&0xff;\n\t\tpos++;\n\t\tmethod |= eahead[pos]&0xff;\n\t\tpos++;\n\t\tEACRC = Raw.readIntLittleEndian(eahead, pos);\n\t}\n\n\t/**\n\t * @return the eACRC\n\t */\n\tpublic int getEACRC() {\n\t\treturn EACRC;\n\t}\n\n\t/**\n\t * @return the method\n\t */\n\tpublic byte getMethod() {\n\t\treturn method;\n\t}\n\n\t/**\n\t * @return the unpSize\n\t */\n\tpublic int getUnpSize() {\n\t\treturn unpSize;\n\t}\n\n\t/**\n\t * @return the unpVer\n\t */\n\tpublic byte getUnpVer() {\n\t\treturn unpVer;\n\t}\n\t\n\tpublic void print()\n\t{\n\t\tsuper.print();\n\t\tlogger.info(\"unpSize: \"+unpSize);\n\t\tlogger.info(\"unpVersion: \" + unpVer);\n\t\tlogger.info(\"method: \"+method);\n\t\tlogger.info(\"EACRC:\" + EACRC);\n\t}\n}\n\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/rarfile/EndArcHeader.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 24.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n *\r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.rarfile;\r\n\r\nimport com.github.junrar.io.Raw;\r\n\r\n/**\r\n * \r\n * the optional End header\r\n * \r\n */\r\npublic class EndArcHeader extends BaseBlock{\r\n\t\r\n\tprivate static final short EARC_NEXT_VOLUME = 0x0001;\r\n\tprivate static final short EARC_DATACRC = 0x0002;\r\n\tprivate static final short EARC_REVSPACE = 0x0004;\r\n\tprivate static final short EARC_VOLNUMBER = 0x0008;\r\n\t\r\n\tprivate static final short endArcHeaderSize = 6;\r\n\tpublic static final short endArcArchiveDataCrcSize = 4;\r\n\tpublic static final short endArcVolumeNumberSize = 2;\r\n\t\r\n\tprivate int archiveDataCRC;\r\n\tprivate short volumeNumber;\r\n\t\r\n\t\r\n\tpublic EndArcHeader(BaseBlock bb, byte[] endArcHeader){\r\n\t\tsuper(bb);\r\n\t\t\r\n\t\tint pos = 0;\r\n\t\tif(hasArchiveDataCRC()){\r\n\t\t\tarchiveDataCRC =Raw.readIntLittleEndian(endArcHeader, pos);\r\n\t\t\tpos+=4;\r\n\t\t}\r\n\t\tif(hasVolumeNumber()){\r\n\t\t\tvolumeNumber = Raw.readShortLittleEndian(endArcHeader, pos);\r\n\t\t}\r\n\t}\r\n\t\r\n\tpublic int getArchiveDataCRC() {\r\n\t\treturn archiveDataCRC;\r\n\t}\r\n\r\n\tpublic short getVolumeNumber() {\r\n\t\treturn volumeNumber;\r\n\t}\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/rarfile/FileHeader.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 22.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n *\r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.rarfile;\r\n\r\nimport java.util.Calendar;\r\nimport java.util.Date;\r\n\r\nimport org.apache.commons.logging.Log;\r\nimport org.apache.commons.logging.LogFactory;\r\n\r\nimport com.github.junrar.io.Raw;\r\n\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class FileHeader extends BlockHeader {\r\n\r\n    private final Log logger = LogFactory.getLog(FileHeader.class.getName());\r\n\r\n    private static final byte SALT_SIZE = 8;\r\n\r\n    private static final byte NEWLHD_SIZE = 32;\r\n\r\n    private long unpSize;\r\n\r\n    private final HostSystem hostOS;\r\n\r\n    private final int fileCRC;\r\n\r\n    private final int fileTime;\r\n\r\n    private byte unpVersion;\r\n\r\n    private byte unpMethod;\r\n\r\n    private short nameSize;\r\n\r\n    private int highPackSize;\r\n\r\n    private int highUnpackSize;\r\n\r\n    private final byte[] fileNameBytes;\r\n\r\n    private String fileName;\r\n    private String fileNameW;\r\n\r\n    private byte[] subData;\r\n\r\n    private final byte[] salt = new byte[SALT_SIZE];\r\n\r\n    private Date mTime;\r\n\r\n    private Date cTime;\r\n\r\n    private Date aTime;\r\n\r\n    private Date arcTime;\r\n\r\n    private long fullPackSize;\r\n\r\n    private long fullUnpackSize;\r\n\r\n    private int fileAttr;\r\n\r\n    private int subFlags; // same as fileAttr (in header)\r\n\r\n    private int recoverySectors = -1;\r\n\r\n    public FileHeader(BlockHeader bh, byte[] fileHeader) {\r\n\tsuper(bh);\r\n\r\n\tint position = 0;\r\n\tunpSize = Raw.readIntLittleEndianAsLong(fileHeader, position);\r\n\tposition += 4;\r\n\thostOS = HostSystem.findHostSystem(fileHeader[4]);\r\n\tposition++;\r\n\r\n\tfileCRC = Raw.readIntLittleEndian(fileHeader, position);\r\n\tposition += 4;\r\n\r\n\tfileTime = Raw.readIntLittleEndian(fileHeader, position);\r\n\tposition += 4;\r\n\r\n\tunpVersion |= fileHeader[13] & 0xff;\r\n\tposition++;\r\n\tunpMethod |= fileHeader[14] & 0xff;\r\n\tposition++;\r\n\tnameSize = Raw.readShortLittleEndian(fileHeader, position);\r\n\tposition += 2;\r\n\r\n\tfileAttr = Raw.readIntLittleEndian(fileHeader, position);\r\n\tposition += 4;\r\n\tif (isLargeBlock()) {\r\n\t    highPackSize = Raw.readIntLittleEndian(fileHeader, position);\r\n\t    position += 4;\r\n\r\n\t    highUnpackSize = Raw.readIntLittleEndian(fileHeader, position);\r\n\t    position += 4;\r\n\t} else {\r\n\t    highPackSize = 0;\r\n\t    highUnpackSize = 0;\r\n\t    if (unpSize == 0xffffffff) {\r\n\r\n\t\tunpSize = 0xffffffff;\r\n\t\thighUnpackSize = Integer.MAX_VALUE;\r\n\t    }\r\n\r\n\t}\r\n\tfullPackSize |= highPackSize;\r\n\tfullPackSize <<= 32;\r\n\tfullPackSize |= getPackSize();\r\n\r\n\tfullUnpackSize |= highUnpackSize;\r\n\tfullUnpackSize <<= 32;\r\n\tfullUnpackSize += unpSize;\r\n\r\n\tnameSize = nameSize > 4 * 1024 ? 4 * 1024 : nameSize;\r\n\r\n\tfileNameBytes = new byte[nameSize];\r\n\tfor (int i = 0; i < nameSize; i++) {\r\n\t    fileNameBytes[i] = fileHeader[position];\r\n\t    position++;\r\n\t}\r\n\r\n\tif (isFileHeader()) {\r\n\t    if (isUnicode()) {\r\n\t\tint length = 0;\r\n\t\tfileName = \"\";\r\n\t\tfileNameW = \"\";\r\n\t\twhile (length < fileNameBytes.length\r\n\t\t\t&& fileNameBytes[length] != 0) {\r\n\t\t    length++;\r\n\t\t}\r\n\t\tbyte[] name = new byte[length];\r\n\t\tSystem.arraycopy(fileNameBytes, 0, name, 0, name.length);\r\n\t\tfileName = new String(name);\r\n\t\tif (length != nameSize) {\r\n\t\t    length++;\r\n\t\t    fileNameW = FileNameDecoder.decode(fileNameBytes, length);\r\n\t\t}\r\n\t    } else {\r\n\t\tfileName = new String(fileNameBytes);\r\n\t\tfileNameW = \"\";\r\n\t    }\r\n\t}\r\n\r\n\tif (UnrarHeadertype.NewSubHeader.equals(headerType)) {\r\n\t    int datasize = headerSize - NEWLHD_SIZE - nameSize;\r\n\t    if (hasSalt()) {\r\n\t\tdatasize -= SALT_SIZE;\r\n\t    }\r\n\t    if (datasize > 0) {\r\n\t\tsubData = new byte[datasize];\r\n\t\tfor (int i = 0; i < datasize; i++) {\r\n\t\t    subData[i] = (fileHeader[position]);\r\n\t\t    position++;\r\n\t\t}\r\n\t    }\r\n\r\n\t    if (NewSubHeaderType.SUBHEAD_TYPE_RR.byteEquals(fileNameBytes)) {\r\n\t\trecoverySectors = subData[8] + (subData[9] << 8)\r\n\t\t\t+ (subData[10] << 16) + (subData[11] << 24);\r\n\t    }\r\n\t}\r\n\r\n\tif (hasSalt()) {\r\n\t    for (int i = 0; i < SALT_SIZE; i++) {\r\n\t\tsalt[i] = fileHeader[position];\r\n\t\tposition++;\r\n\t    }\r\n\t}\r\n\tmTime = getDateDos(fileTime);\r\n\t// TODO rartime -> extended\r\n\r\n    }\r\n\r\n    @Override\r\n    public void print() {\r\n\tsuper.print();\r\n\tStringBuilder str = new StringBuilder();\r\n\tstr.append(\"unpSize: \" + getUnpSize());\r\n\tstr.append(\"\\nHostOS: \" + hostOS.name());\r\n\tstr.append(\"\\nMDate: \" + mTime);\r\n\tstr.append(\"\\nFileName: \" + getFileNameString());\r\n\tstr.append(\"\\nunpMethod: \" + Integer.toHexString(getUnpMethod()));\r\n\tstr.append(\"\\nunpVersion: \" + Integer.toHexString(getUnpVersion()));\r\n\tstr.append(\"\\nfullpackedsize: \" + getFullPackSize());\r\n\tstr.append(\"\\nfullunpackedsize: \" + getFullUnpackSize());\r\n\tstr.append(\"\\nisEncrypted: \" + isEncrypted());\r\n\tstr.append(\"\\nisfileHeader: \" + isFileHeader());\r\n\tstr.append(\"\\nisSolid: \" + isSolid());\r\n\tstr.append(\"\\nisSplitafter: \" + isSplitAfter());\r\n\tstr.append(\"\\nisSplitBefore:\" + isSplitBefore());\r\n\tstr.append(\"\\nunpSize: \" + getUnpSize());\r\n\tstr.append(\"\\ndataSize: \" + getDataSize());\r\n\tstr.append(\"\\nisUnicode: \" + isUnicode());\r\n\tstr.append(\"\\nhasVolumeNumber: \" + hasVolumeNumber());\r\n\tstr.append(\"\\nhasArchiveDataCRC: \" + hasArchiveDataCRC());\r\n\tstr.append(\"\\nhasSalt: \" + hasSalt());\r\n\tstr.append(\"\\nhasEncryptVersions: \" + hasEncryptVersion());\r\n\tstr.append(\"\\nisSubBlock: \" + isSubBlock());\r\n\tlogger.info(str.toString());\r\n    }\r\n\r\n    private Date getDateDos(int time) {\r\n\tCalendar cal = Calendar.getInstance();\r\n\tcal.set(Calendar.YEAR, (time >>> 25) + 1980);\r\n\tcal.set(Calendar.MONTH, ((time >>> 21) & 0x0f) - 1);\r\n\tcal.set(Calendar.DAY_OF_MONTH, (time >>> 16) & 0x1f);\r\n\tcal.set(Calendar.HOUR_OF_DAY, (time >>> 11) & 0x1f);\r\n\tcal.set(Calendar.MINUTE, (time >>> 5) & 0x3f);\r\n\tcal.set(Calendar.SECOND, (time & 0x1f) * 2);\r\n\treturn cal.getTime();\r\n    }\r\n\r\n    public Date getArcTime() {\r\n\treturn arcTime;\r\n    }\r\n\r\n    public void setArcTime(Date arcTime) {\r\n\tthis.arcTime = arcTime;\r\n    }\r\n\r\n    public Date getATime() {\r\n\treturn aTime;\r\n    }\r\n\r\n    public void setATime(Date time) {\r\n\taTime = time;\r\n    }\r\n\r\n    public Date getCTime() {\r\n\treturn cTime;\r\n    }\r\n\r\n    public void setCTime(Date time) {\r\n\tcTime = time;\r\n    }\r\n\r\n    public int getFileAttr() {\r\n\treturn fileAttr;\r\n    }\r\n\r\n    public void setFileAttr(int fileAttr) {\r\n\tthis.fileAttr = fileAttr;\r\n    }\r\n\r\n    public int getFileCRC() {\r\n\treturn fileCRC;\r\n    }\r\n\r\n    public byte[] getFileNameByteArray() {\r\n\treturn fileNameBytes;\r\n    }\r\n\r\n    public String getFileNameString() {\r\n\treturn fileName;\r\n    }\r\n\r\n    public void setFileName(String fileName) {\r\n\tthis.fileName = fileName;\r\n    }\r\n\r\n    public String getFileNameW() {\r\n\treturn fileNameW;\r\n    }\r\n\r\n    public void setFileNameW(String fileNameW) {\r\n\tthis.fileNameW = fileNameW;\r\n    }\r\n\r\n    public int getHighPackSize() {\r\n\treturn highPackSize;\r\n    }\r\n\r\n    public int getHighUnpackSize() {\r\n\treturn highUnpackSize;\r\n    }\r\n\r\n    public HostSystem getHostOS() {\r\n\treturn hostOS;\r\n    }\r\n\r\n    public Date getMTime() {\r\n\treturn mTime;\r\n    }\r\n\r\n    public void setMTime(Date time) {\r\n\tmTime = time;\r\n    }\r\n\r\n    public short getNameSize() {\r\n\treturn nameSize;\r\n    }\r\n\r\n    public int getRecoverySectors() {\r\n\treturn recoverySectors;\r\n    }\r\n\r\n    public byte[] getSalt() {\r\n\treturn salt;\r\n    }\r\n\r\n    public byte[] getSubData() {\r\n\treturn subData;\r\n    }\r\n\r\n    public int getSubFlags() {\r\n\treturn subFlags;\r\n    }\r\n\r\n    public byte getUnpMethod() {\r\n\treturn unpMethod;\r\n    }\r\n\r\n    public long getUnpSize() {\r\n\treturn unpSize;\r\n    }\r\n\r\n    public byte getUnpVersion() {\r\n\treturn unpVersion;\r\n    }\r\n\r\n    public long getFullPackSize() {\r\n\treturn fullPackSize;\r\n    }\r\n\r\n    public long getFullUnpackSize() {\r\n\treturn fullUnpackSize;\r\n    }\r\n\r\n    @Override\r\n    public String toString() {\r\n\treturn super.toString();\r\n    }\r\n\r\n    /**\r\n     * the file will be continued in the next archive part\r\n     * \r\n     * @return\r\n     */\r\n    public boolean isSplitAfter() {\r\n\treturn (this.flags & BlockHeader.LHD_SPLIT_AFTER) != 0;\r\n    }\r\n\r\n    /**\r\n     * the file is continued in this archive\r\n     * \r\n     * @return\r\n     */\r\n    public boolean isSplitBefore() {\r\n\treturn (this.flags & LHD_SPLIT_BEFORE) != 0;\r\n    }\r\n\r\n    /**\r\n     * this file is compressed as solid (all files handeled as one)\r\n     * \r\n     * @return\r\n     */\r\n    public boolean isSolid() {\r\n\treturn (this.flags & LHD_SOLID) != 0;\r\n    }\r\n\r\n    /**\r\n     * the file is encrypted\r\n     * \r\n     * @return\r\n     */\r\n    public boolean isEncrypted() {\r\n\treturn (this.flags & BlockHeader.LHD_PASSWORD) != 0;\r\n    }\r\n\r\n    /**\r\n     * the filename is also present in unicode\r\n     * \r\n     * @return\r\n     */\r\n    public boolean isUnicode() {\r\n\treturn (flags & LHD_UNICODE) != 0;\r\n    }\r\n\r\n    public boolean isFileHeader() {\r\n\treturn UnrarHeadertype.FileHeader.equals(headerType);\r\n    }\r\n\r\n    public boolean hasSalt() {\r\n\treturn (flags & LHD_SALT) != 0;\r\n    }\r\n\r\n    public boolean isLargeBlock() {\r\n\treturn (flags & LHD_LARGE) != 0;\r\n    }\r\n\r\n    /**\r\n     * whether this fileheader represents a directory\r\n     * \r\n     * @return\r\n     */\r\n    public boolean isDirectory() {\r\n\treturn (flags & LHD_WINDOWMASK) == LHD_DIRECTORY;\r\n    }\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/rarfile/FileNameDecoder.java",
    "content": "/*\n * \n * Original author: alpha_lam\n * Creation date: ?\n *\n * Source: $HeadURL$\n * Last changed: $LastChangedDate$\n * \n * \n * the unrar licence applies to all junrar source and binary distributions \n * you are not allowed to use this source to re-create the RAR compression algorithm\n *\n * Here some html entities which can be used for escaping javadoc tags:\n * \"&\":  \"&#038;\" or \"&amp;\"\n * \"<\":  \"&#060;\" or \"&lt;\"\n * \">\":  \"&#062;\" or \"&gt;\"\n * \"@\":  \"&#064;\" \n */\npackage com.github.junrar.rarfile;\n\npublic class FileNameDecoder {\n\tpublic static int getChar(byte [] name,int pos){ \n\t\treturn name[pos]&0xff; \n\t} \n\n\tpublic static String decode(byte [] name,int encPos){ \n\t\tint decPos = 0; \n\t\tint flags = 0; \n\t\tint flagBits = 0; \n\n\t\tint low = 0; \n\t\tint high = 0; \n\t\tint highByte = getChar(name,encPos++); \n\t\tStringBuffer buf = new StringBuffer(); \n\t\twhile(encPos < name.length){ \n\t\t\tif(flagBits == 0){ \n\t\t\t\tflags = getChar(name,encPos++); \n\t\t\t\tflagBits = 8; \n\t\t\t} \n\t\t\tswitch(flags >> 6){ \n\t\t\tcase 0: \n\t\t\t\tbuf.append((char)(getChar(name,encPos++))); \n\t\t\t\t++decPos; \n\t\t\t\tbreak; \n\t\t\tcase 1: \n\t\t\t\tbuf.append((char)(getChar(name,encPos++)+(highByte<<8))); \n\t\t\t\t++decPos; \n\t\t\t\tbreak; \n\t\t\tcase 2: \n\t\t\t\tlow = getChar(name,encPos); \n\t\t\t\thigh = getChar(name,encPos+1); \n\t\t\t\tbuf.append((char)((high << 8) + low)); \n\t\t\t\t++decPos; \n\t\t\t\tencPos += 2; \n\t\t\t\tbreak; \n\t\t\tcase 3: \n\t\t\t\tint length = getChar(name,encPos++); \n\t\t\t\tif((length&0x80)!=0){ \n\t\t\t\t\tint correction = getChar(name,encPos++); \n\t\t\t\t\tfor(length=(length&0x7f)+2;length>0&&decPos<name.length;length--,decPos++){ \n\t\t\t\t\t\tlow = (getChar(name,decPos) + correction)&0xff; \n\t\t\t\t\t\tbuf.append((char)((highByte << 8) + low)); \n\t\t\t\t\t} \n\t\t\t\t}else{ \n\t\t\t\t\tfor(length+=2;length>0&&decPos<name.length;length--,decPos++){ \n\t\t\t\t\t\tbuf.append((char)(getChar(name,decPos))); \n\t\t\t\t\t} \n\t\t\t\t} \n\t\t\t\tbreak; \n\t\t\t} \n\t\t\tflags = (flags << 2) & 0xff; \n\t\t\tflagBits -= 2; \n\t\t} \n\t\treturn buf.toString(); \n\t} \n}\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/rarfile/HostSystem.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 22.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n *\r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.rarfile;\r\n\r\n/**\r\n * DOCUMENT ME\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic enum HostSystem {\r\n\tmsdos  ((byte)0),\r\n\tos2  ((byte)1),\r\n\twin32  ((byte)2),\r\n\tunix  ((byte)3),\r\n\tmacos  ((byte)4),\r\n\tbeos   ((byte)5);\r\n\t\r\n\tprivate byte hostByte;\r\n\t\r\n\tpublic static HostSystem findHostSystem(byte hostByte){\r\n\t\tif(HostSystem.msdos.equals(hostByte)){\r\n\t\t\treturn HostSystem.msdos;\r\n\t\t}\r\n\t\tif(HostSystem.os2.equals(hostByte)){\r\n\t\t\treturn HostSystem.os2;\r\n\t\t}\r\n\t\tif(HostSystem.win32.equals(hostByte)){\r\n\t\t\treturn HostSystem.win32;\r\n\t\t}\r\n\t\tif(HostSystem.unix.equals(hostByte)){\r\n\t\t\treturn HostSystem.unix;\r\n\t\t}\r\n\t\tif(HostSystem.macos.equals(hostByte)){\r\n\t\t\treturn HostSystem.macos;\r\n\t\t}\r\n\t\tif(HostSystem.beos.equals(hostByte)){\r\n\t\t\treturn HostSystem.beos;\r\n\t\t}\r\n\t\treturn null;\r\n\t}\r\n\t\r\n\t\r\n\tprivate HostSystem(byte hostByte){\r\n\t\tthis.hostByte = hostByte;\r\n\t}\r\n\t\r\n\tpublic boolean equals(byte hostByte){\r\n\t\treturn this.hostByte == hostByte;\r\n\t}\r\n\t\r\n\tpublic byte getHostByte(){\r\n\t\treturn hostByte;\r\n\t}\r\n\t//???? public static final byte max = 6; \r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/rarfile/MacInfoHeader.java",
    "content": "/*\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\n * Original author: Edmund Wagner\n * Creation date: 26.11.2007\n *\n * Source: $HeadURL$\n * Last changed: $LastChangedDate$\n * \n * \n * the unrar licence applies to all junrar source and binary distributions \n * you are not allowed to use this source to re-create the RAR compression algorithm\n *\n * Here some html entities which can be used for escaping javadoc tags:\n * \"&\":  \"&#038;\" or \"&amp;\"\n * \"<\":  \"&#060;\" or \"&lt;\"\n * \">\":  \"&#062;\" or \"&gt;\"\n * \"@\":  \"&#064;\" \n */\npackage com.github.junrar.rarfile;\n\nimport org.apache.commons.logging.Log;\nimport org.apache.commons.logging.LogFactory;\n\nimport com.github.junrar.io.Raw;\n\n\n/**\n * Mac File attribute header\n *\n */\npublic class MacInfoHeader \nextends SubBlockHeader \n{\n\tprivate Log logger = LogFactory.getLog(getClass());\n\t\n\tpublic static final short MacInfoHeaderSize = 8;\n\t\n\tprivate int fileType;\n\tprivate int fileCreator;\n\t\n\tpublic MacInfoHeader(SubBlockHeader sb, byte[] macHeader)\n\t{\n\t\tsuper(sb);\n\t\tint pos = 0;\n\t\tfileType = Raw.readIntLittleEndian(macHeader, pos);\n\t\tpos+=4;\n\t\tfileCreator = Raw.readIntLittleEndian(macHeader, pos);\n\t}\n\n\t/**\n\t * @return the fileCreator\n\t */\n\tpublic int getFileCreator() {\n\t\treturn fileCreator;\n\t}\n\n\t/**\n\t * @param fileCreator the fileCreator to set\n\t */\n\tpublic void setFileCreator(int fileCreator) {\n\t\tthis.fileCreator = fileCreator;\n\t}\n\n\t/**\n\t * @return the fileType\n\t */\n\tpublic int getFileType() {\n\t\treturn fileType;\n\t}\n\n\t/**\n\t * @param fileType the fileType to set\n\t */\n\tpublic void setFileType(int fileType) {\n\t\tthis.fileType = fileType;\n\t}\n\t\n\tpublic void print(){\n\t\tsuper.print();\n\t\tlogger.info(\"filetype: \"+fileType);\n\t\tlogger.info(\"creator :\"+fileCreator);\n\t}\n\t\n}\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/rarfile/MainHeader.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 22.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n *\r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.rarfile;\r\n\r\nimport org.apache.commons.logging.Log;\r\nimport org.apache.commons.logging.LogFactory;\r\n\r\nimport com.github.junrar.io.Raw;\r\n\r\n\r\n/**\r\n * The main header of an rar archive. holds information concerning the whole archive (solid, encrypted etc). \r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class MainHeader extends BaseBlock {\r\n\tprivate Log logger = LogFactory.getLog(MainHeader.class.getName());\r\n\tpublic static final short mainHeaderSizeWithEnc = 7;\r\n\tpublic static final short mainHeaderSize = 6;\r\n\tprivate short highPosAv;\r\n\tprivate int posAv;\r\n\tprivate byte encryptVersion;\r\n\t\r\n\tpublic MainHeader(BaseBlock bb, byte[] mainHeader) {\r\n\t\tsuper(bb);\r\n\t\tint pos = 0;\r\n\t\thighPosAv = Raw.readShortLittleEndian(mainHeader, pos);\r\n\t\tpos += 2;\r\n\t\tposAv = Raw.readIntLittleEndian(mainHeader, pos);\r\n\t\tpos+=4;\r\n\t\t\r\n\t\tif(hasEncryptVersion()){\r\n\t\t\tencryptVersion |= mainHeader[pos]&0xff;\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * old cmt block is present\r\n\t * @return true if has cmt block\r\n\t */\r\n\tpublic boolean hasArchCmt(){\r\n\t\treturn (this.flags & BaseBlock.MHD_COMMENT)!=0;\r\n\t}\r\n\t/**\r\n\t * the version the the encryption \r\n\t * @return\r\n\t */\r\n\tpublic byte getEncryptVersion() {\r\n\t\treturn encryptVersion;\r\n\t}\r\n\t\r\n\tpublic short getHighPosAv() {\r\n\t\treturn highPosAv;\r\n\t}\r\n\t\r\n\tpublic int getPosAv() {\r\n\t\treturn posAv;\r\n\t}\r\n\t\r\n\t/**\r\n\t * returns whether the archive is encrypted \r\n\t * @return\r\n\t */\r\n\tpublic boolean isEncrypted(){\r\n\t\treturn (this.flags & BaseBlock.MHD_PASSWORD)!=0;\r\n\t}\r\n\t\r\n\t/**\r\n\t * return whether the archive is a multivolume archive\r\n\t * @return\r\n\t */\r\n\tpublic boolean isMultiVolume(){\r\n\t\treturn (this.flags & BaseBlock.MHD_VOLUME)!=0;\r\n\t}\r\n\t\r\n\t/**\r\n\t * if the archive is a multivolume archive this method returns whether this instance is the first part of the multivolume archive\r\n\t * @return\r\n\t */\r\n\tpublic boolean isFirstVolume(){\r\n\t\treturn (this.flags & BaseBlock.MHD_FIRSTVOLUME)!=0;\r\n\t}\r\n\t\r\n\tpublic void print(){\r\n\t\tsuper.print();\r\n\t\tStringBuilder str=new StringBuilder();\r\n\t\tstr.append(\"posav: \"+getPosAv());\r\n\t\tstr.append(\"\\nhighposav: \"+getHighPosAv());\r\n\t\tstr.append(\"\\nhasencversion: \"+hasEncryptVersion()+(hasEncryptVersion()?getEncryptVersion():\"\"));\r\n\t\tstr.append(\"\\nhasarchcmt: \"+hasArchCmt());\r\n\t\tstr.append(\"\\nisEncrypted: \"+isEncrypted());\r\n\t\tstr.append(\"\\nisMultivolume: \"+isMultiVolume());\r\n\t\tstr.append(\"\\nisFirstvolume: \"+isFirstVolume());\r\n\t\tstr.append(\"\\nisSolid: \"+isSolid());\r\n\t\tstr.append(\"\\nisLocked: \"+isLocked());\r\n\t\tstr.append(\"\\nisProtected: \"+isProtected());\r\n\t\tstr.append(\"\\nisAV: \"+isAV());\r\n\t\tlogger.info(str.toString());\r\n\t}\r\n\t\r\n\t/**\r\n\t * returns whether this archive is solid. in this case you can only extract all file at once\r\n\t * @return\r\n\t */\r\n\tpublic boolean isSolid(){\r\n\t\treturn (this.flags&MHD_SOLID)!=0;\r\n\t}\r\n\t\r\n\tpublic boolean isLocked(){\r\n\t\treturn (this.flags&MHD_LOCK)!=0;\r\n\t}\r\n\t\r\n\tpublic boolean isProtected(){\r\n\t\treturn (this.flags&MHD_PROTECT)!=0;\r\n\t}\r\n\t\r\n\tpublic boolean isAV(){\r\n\t\treturn (this.flags&MHD_AV)!=0;\r\n\t}\r\n\t/**\r\n\t * the numbering format a multivolume archive\r\n\t * @return\r\n\t */\r\n\tpublic boolean isNewNumbering(){\r\n\t\treturn (this.flags&MHD_NEWNUMBERING)!=0;\r\n\t}\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/rarfile/MarkHeader.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 24.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n *\r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.rarfile;\r\n\r\nimport org.apache.commons.logging.Log;\r\nimport org.apache.commons.logging.LogFactory;\r\n\r\nimport com.github.junrar.io.Raw;\r\n\r\n\r\n/**\r\n * the header to recognize a file to be a rar archive\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class MarkHeader extends BaseBlock {\r\n\t\r\n\tprivate Log logger = LogFactory.getLog(MarkHeader.class.getName());\r\n\tprivate boolean oldFormat = false;\r\n\t\r\n\tpublic MarkHeader(BaseBlock bb){\r\n\t\tsuper(bb);\r\n\t}\r\n\tpublic boolean isValid(){\r\n\t\tif(!(getHeadCRC() == 0x6152)){\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\tif(!(getHeaderType() == UnrarHeadertype.MarkHeader)){\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\tif(!(getFlags() == 0x1a21)){\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\tif(!(getHeaderSize() == BaseBlockSize)){\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\treturn true;\r\n\t}\r\n\t\r\n\tpublic boolean isSignature() {\r\n        boolean valid=false;\r\n        byte[] d = new byte[BaseBlock.BaseBlockSize];\r\n        Raw.writeShortLittleEndian(d, 0, headCRC);\r\n        d[2] = headerType;\r\n        Raw.writeShortLittleEndian(d, 3, flags);\r\n        Raw.writeShortLittleEndian(d, 5, headerSize);\r\n        \r\n        if (d[0] == 0x52) {\r\n            if (d[1]==0x45 && d[2]==0x7e && d[3]==0x5e) {\r\n                oldFormat=true;\r\n                valid=true;\r\n            }\r\n            else if (d[1]==0x61 && d[2]==0x72 && d[3]==0x21 && d[4]==0x1a &&\r\n                    d[5]==0x07 && d[6]==0x00) {\r\n                oldFormat=false;\r\n                valid=true;\r\n            }\r\n        }\r\n        return valid;\r\n    }\r\n\r\n    public boolean isOldFormat() {\r\n        return oldFormat;\r\n    }\r\n    \r\n\tpublic void print(){\r\n\t\tsuper.print();\r\n\t\tlogger.info(\"valid: \"+isValid());\r\n\t}\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/rarfile/NewSubHeaderType.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 24.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n *\r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.rarfile;\r\n\r\nimport java.util.Arrays;\r\n\r\n/**\r\n * subheaders new version of the info headers\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class NewSubHeaderType {\r\n    \r\n    /**\r\n     * comment subheader\r\n     */\r\n    public static final NewSubHeaderType SUBHEAD_TYPE_CMT = new NewSubHeaderType(new byte[]{'C','M','T'});\r\n    /**\r\n     * \r\n     */\r\n    public static final NewSubHeaderType SUBHEAD_TYPE_ACL = new NewSubHeaderType(new byte[]{'A','C','L'});\r\n    /**\r\n     * \r\n     */\r\n    public static final NewSubHeaderType SUBHEAD_TYPE_STREAM = new NewSubHeaderType(new byte[]{'S','T','M'});\r\n    /**\r\n     * \r\n     */\r\n    public static final NewSubHeaderType SUBHEAD_TYPE_UOWNER = new NewSubHeaderType(new byte[]{'U','O','W'});\r\n    /**\r\n     * \r\n     */\r\n    public static final NewSubHeaderType SUBHEAD_TYPE_AV = new NewSubHeaderType(new byte[]{'A','V'});\r\n    /**\r\n     * recovery record subheader\r\n     */\r\n    public static final NewSubHeaderType SUBHEAD_TYPE_RR = new NewSubHeaderType(new byte[]{'R','R'});\r\n    /**\r\n     * \r\n     */\r\n    public static final NewSubHeaderType SUBHEAD_TYPE_OS2EA = new NewSubHeaderType(new byte[]{'E','A','2'});\r\n    /**\r\n     * \r\n     */\r\n    public static final NewSubHeaderType SUBHEAD_TYPE_BEOSEA = new NewSubHeaderType(new byte[]{'E','A','B','E'});\r\n    \r\n    private byte[] headerTypes;\r\n    \r\n    /**\r\n     * Private constructor\r\n     * @param headerTypes\r\n     */\r\n    private NewSubHeaderType(byte[] headerTypes)\r\n    {\r\n        this.headerTypes = headerTypes;\r\n    }\r\n    \r\n    /**\r\n     * @param toCompare\r\n     * @return Returns true if the given byte array matches to the internal byte array of this header.\r\n     */\r\n    public boolean byteEquals(byte[] toCompare)\r\n    {\r\n        return Arrays.equals(this.headerTypes, toCompare);\r\n    }\r\n\r\n    @Override\r\n    public String toString()\r\n    {\r\n        return new String(this.headerTypes);\r\n    }\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/rarfile/ProtectHeader.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 24.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n *\r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.rarfile;\r\n\r\nimport com.github.junrar.io.Raw;\r\n\r\n/**\r\n * recovery header\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class ProtectHeader extends BlockHeader {\r\n\t\t\r\n\t/**\r\n\t * the header size\r\n\t */\r\n\tpublic static final int protectHeaderSize = 8;\r\n\t\r\n\tprivate byte version;\r\n\tprivate short recSectors;\r\n\tprivate int totalBlocks;\r\n\tprivate byte mark;\r\n\t\r\n\t\r\n\tpublic ProtectHeader(BlockHeader bh, byte[] protectHeader){\r\n\t\tsuper(bh);\r\n\t\t\r\n\t\tint pos = 0;\r\n\t\tversion |= protectHeader[pos]&0xff;\r\n\t\t\r\n\t\trecSectors = Raw.readShortLittleEndian(protectHeader, pos);\r\n\t\tpos += 2;\r\n\t\ttotalBlocks = Raw.readIntLittleEndian(protectHeader, pos);\r\n\t\tpos += 4;\r\n\t\tmark |= protectHeader[pos]&0xff;\r\n\t}\r\n\t\r\n\t\r\n\tpublic byte getMark() {\r\n\t\treturn mark;\r\n\t}\r\n\t\r\n\tpublic short getRecSectors() {\r\n\t\treturn recSectors;\r\n\t}\r\n\t\r\n\tpublic int getTotalBlocks() {\r\n\t\treturn totalBlocks;\r\n\t}\r\n\t\r\n\tpublic byte getVersion() {\r\n\t\treturn version;\r\n\t}\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/rarfile/SignHeader.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 24.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n *\r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.rarfile;\r\n\r\nimport com.github.junrar.io.Raw;\r\n\r\n/**\r\n * sign header\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class SignHeader extends BaseBlock {\r\n\t\r\n\tpublic static final short signHeaderSize = 8;\r\n\t\r\n\tprivate int creationTime=0;\r\n\tprivate short arcNameSize=0;\r\n\tprivate short userNameSize=0;\r\n\t\r\n\t\r\n\tpublic SignHeader(BaseBlock bb, byte[] signHeader){\r\n\t\tsuper(bb);\r\n\t\t\r\n\t\tint pos = 0;\r\n\t\tcreationTime = Raw.readIntLittleEndian(signHeader, pos);\r\n\t\tpos +=4;\r\n\t\tarcNameSize = Raw.readShortLittleEndian(signHeader, pos);\r\n\t\tpos+=2;\r\n\t\tuserNameSize = Raw.readShortLittleEndian(signHeader, pos);\r\n\t}\r\n\t\r\n\tpublic short getArcNameSize() {\r\n\t\treturn arcNameSize;\r\n\t}\r\n\t\r\n\tpublic int getCreationTime() {\r\n\t\treturn creationTime;\r\n\t}\r\n\t\r\n\tpublic short getUserNameSize() {\r\n\t\treturn userNameSize;\r\n\t}\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/rarfile/SubBlockHeader.java",
    "content": "/*\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\n * Original author: Edmund Wagner\n * Creation date: 21.11.2007\n *\n * Source: $HeadURL$\n * Last changed: $LastChangedDate$\n * \n * \n * the unrar licence applies to all junrar source and binary distributions \n * you are not allowed to use this source to re-create the RAR compression algorithm\n *\n * Here some html entities which can be used for escaping javadoc tags:\n * \"&\":  \"&#038;\" or \"&amp;\"\n * \"<\":  \"&#060;\" or \"&lt;\"\n * \">\":  \"&#062;\" or \"&gt;\"\n * \"@\":  \"&#064;\" \n */\npackage com.github.junrar.rarfile;\n\nimport org.apache.commons.logging.Log;\nimport org.apache.commons.logging.LogFactory;\n\nimport com.github.junrar.io.Raw;\n\n\npublic class SubBlockHeader \nextends BlockHeader \n{\n\tprivate Log logger = LogFactory.getLog(getClass());\n\t\n\tpublic static final short SubBlockHeaderSize = 3;\n\t\n\tprivate short subType;\n\tprivate byte level;\n\t\n\tpublic SubBlockHeader(SubBlockHeader sb)\n\t{\n\t\tsuper(sb);\n\t\tsubType = sb.getSubType().getSubblocktype();\n\t\tlevel = sb.getLevel();\n\t}\n\t\n\tpublic SubBlockHeader(BlockHeader bh, byte[] subblock)\n\t{\n\t\tsuper(bh);\n\t\tint position = 0;\n\t\tsubType = Raw.readShortLittleEndian(subblock, position);\n\t\tposition +=2;\n\t\tlevel |= subblock[position]&0xff;\n\t}\n\n\t/**\n\t * @return\n\t */\n\tpublic byte getLevel() {\n\t\treturn level;\n\t}\n\n\t/**\n\t * @return\n\t */\n\tpublic SubBlockHeaderType getSubType() {\n\t\treturn SubBlockHeaderType.findSubblockHeaderType(subType);\n\t}\n\n\tpublic void print()\n\t{\n\t\tsuper.print();\n\t\tlogger.info(\"subtype: \"+getSubType());\n\t\tlogger.info(\"level: \"+level);\n\t}\n}\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/rarfile/SubBlockHeaderType.java",
    "content": "/*\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\n * Original author: Edmund Wagner\n * Creation date: 20.11.2007\n *\n * Source: $HeadURL$\n * Last changed: $LastChangedDate$\n * \n * \n * the unrar licence applies to all junrar source and binary distributions \n * you are not allowed to use this source to re-create the RAR compression algorithm\n *\n * Here some html entities which can be used for escaping javadoc tags:\n * \"&\":  \"&#038;\" or \"&amp;\"\n * \"<\":  \"&#060;\" or \"&lt;\"\n * \">\":  \"&#062;\" or \"&gt;\"\n * \"@\":  \"&#064;\" \n */\n\npackage com.github.junrar.rarfile;\n\npublic enum SubBlockHeaderType \n{\n\tEA_HEAD \t((short)0x100),\n\tUO_HEAD \t((short)0x101),\n\tMAC_HEAD \t((short)0x102),\n\tBEEA_HEAD \t((short)0x103),\n    NTACL_HEAD \t((short)0x104),\n    STREAM_HEAD ((short)0x105);\n\t\n\tprivate short subblocktype;\n\n\tprivate SubBlockHeaderType(short subblocktype)\n\t{\n\t\tthis.subblocktype = subblocktype;\n\t}\n\t\n\t/**\n\t * Return true if the given value is equal to the enum's value\n\t * @param subblocktype\n\t * @return true if the given value is equal to the enum's value\n\t */\n\tpublic boolean equals(short subblocktype)\n\t{\n\t\treturn this.subblocktype == subblocktype;\n\t}\n\n\t/**\n\t * find the header type for the given short value\n\t * @param SubType the short value\n\t * @return the correspo nding enum or null\n\t */\n\tpublic static SubBlockHeaderType findSubblockHeaderType(short subType)\n\t{\n\t\tif(EA_HEAD.equals(subType)){\n\t\t\treturn EA_HEAD;\n\t\t}else if(UO_HEAD.equals(subType)){\n\t\t\treturn UO_HEAD;\n\t\t}else if(MAC_HEAD.equals(subType)){\n\t\t\treturn MAC_HEAD;\n\t\t}else if(BEEA_HEAD.equals(subType)){\n\t\t\treturn BEEA_HEAD;\n\t\t}else if(NTACL_HEAD.equals(subType)){\n\t\t\treturn NTACL_HEAD;\n\t\t}else if(STREAM_HEAD.equals(subType)){\n\t\t\treturn STREAM_HEAD;\n\t\t}\n\t\treturn null;\n\t}\n\t\n\t/**\n\t * @return the short representation of this enum\n\t */\n\tpublic short getSubblocktype() {\n\t\treturn subblocktype;\n\t}\n}\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/rarfile/UnixOwnersHeader.java",
    "content": "package com.github.junrar.rarfile;\n\nimport org.apache.commons.logging.Log;\nimport org.apache.commons.logging.LogFactory;\n\nimport com.github.junrar.io.Raw;\n\n\npublic class UnixOwnersHeader \nextends SubBlockHeader \n{\n\tprivate Log logger = LogFactory.getLog(UnixOwnersHeader.class);\n\tprivate int ownerNameSize;\n\tprivate int groupNameSize;\n\tprivate String owner;\n\tprivate String group;\n\t\n\tpublic  UnixOwnersHeader(SubBlockHeader sb, byte[] uoHeader) {\n\t\tsuper(sb);\n\t\tint pos = 0;\n\t\townerNameSize = Raw.readShortLittleEndian(uoHeader, pos)&0xFFFF;\n\t\tpos+=2;\n\t\tgroupNameSize = Raw.readShortLittleEndian(uoHeader, pos)&0xFFFF;\n\t\tpos+=2;\n\t\tif(pos+ownerNameSize<uoHeader.length){\n\t\t\tbyte[] ownerBuffer = new byte[ownerNameSize];\n\t\t\tSystem.arraycopy(uoHeader, pos, ownerBuffer, 0, ownerNameSize);\n\t\t\towner = new String(ownerBuffer);\n\t\t}\n\t\tpos+=ownerNameSize;\n\t\tif(pos+groupNameSize<uoHeader.length){\n\t\t\tbyte[] groupBuffer = new byte[groupNameSize];\n\t\t\tSystem.arraycopy(uoHeader, pos, groupBuffer, 0, groupNameSize);\n\t\t\tgroup = new String(groupBuffer);\n\t\t}\n\t}\n\t/**\n\t * @return the group\n\t */\n\tpublic String getGroup() {\n\t\treturn group;\n\t}\n\t/**\n\t * @param group the group to set\n\t */\n\tpublic void setGroup(String group) {\n\t\tthis.group = group;\n\t}\n\t/**\n\t * @return the groupNameSize\n\t */\n\tpublic int getGroupNameSize() {\n\t\treturn groupNameSize;\n\t}\n\t/**\n\t * @param groupNameSize the groupNameSize to set\n\t */\n\tpublic void setGroupNameSize(int groupNameSize) {\n\t\tthis.groupNameSize = groupNameSize;\n\t}\n\t/**\n\t * @return the owner\n\t */\n\tpublic String getOwner() {\n\t\treturn owner;\n\t}\n\t/**\n\t * @param owner the owner to set\n\t */\n\tpublic void setOwner(String owner) {\n\t\tthis.owner = owner;\n\t}\n\t/**\n\t * @return the ownerNameSize\n\t */\n\tpublic int getOwnerNameSize() {\n\t\treturn ownerNameSize;\n\t}\n\t/**\n\t * @param ownerNameSize the ownerNameSize to set\n\t */\n\tpublic void setOwnerNameSize(int ownerNameSize) {\n\t\tthis.ownerNameSize = ownerNameSize;\n\t}\n\t\n\t/* (non-Javadoc)\n\t * @see de.innosystec.unrar.rarfile.SubBlockHeader#print()\n\t */\n\tpublic void print(){\n\t\tsuper.print();\n\t\tlogger.info(\"ownerNameSize: \"+ownerNameSize);\n\t\tlogger.info(\"owner: \"+owner);\n\t\tlogger.info(\"groupNameSize: \"+groupNameSize);\n\t\tlogger.info(\"group: \"+group);\n\t}\n}\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/rarfile/UnrarHeadertype.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 22.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n *\r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.rarfile;\r\n\r\n/**\r\n * DOCUMENT ME\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic enum UnrarHeadertype {\r\n\t\r\n\t\r\n\t/**\r\n\t * \r\n\t */\r\n\tMainHeader\t\t((byte)0x73),\r\n\t\r\n\t/**\r\n\t * \r\n\t */\r\n\tMarkHeader\t\t((byte)0x72),\r\n\t\r\n\t/**\r\n\t * \r\n\t */\r\n\tFileHeader \t\t((byte) 0x74),\r\n\t\r\n\t/**\r\n\t * \r\n\t */\r\n\tCommHeader  \t((byte) 0x75),\r\n\t\r\n\t/**\r\n\t * \r\n\t */\r\n\tAvHeader \t\t((byte) 0x76),\r\n\t\r\n\t/**\r\n\t * \r\n\t */\r\n\tSubHeader \t\t((byte)  0x77),\r\n\t\r\n\t/**\r\n\t * \r\n\t */\r\n\tProtectHeader  \t((byte) 0x78),\r\n\t\r\n\t/**\r\n\t * \r\n\t */\r\n\tSignHeader \t\t((byte)  0x79),\r\n\t\r\n\t/**\r\n\t * \r\n\t */\r\n\tNewSubHeader \t((byte) 0x7a),\r\n\t\r\n\t/**\r\n\t * \r\n\t */\r\n\tEndArcHeader \t((byte)  0x7b);\r\n\t\r\n\t/**\r\n\t * Returns the enum according to the given byte or null \r\n\t * @param headerType the headerbyte\r\n\t * @return the enum or null\r\n\t */\r\n\tpublic static UnrarHeadertype findType(byte headerType) \r\n\t{\r\n\t\tif(UnrarHeadertype.MarkHeader.equals(headerType)){\r\n\t\t\treturn UnrarHeadertype.MarkHeader;\r\n\t\t}\r\n\t\tif(UnrarHeadertype.MainHeader.equals(headerType)){\r\n\t\t\treturn UnrarHeadertype.MainHeader;\r\n\t\t}\r\n\t\tif(UnrarHeadertype.FileHeader.equals(headerType)){\r\n\t\t\treturn UnrarHeadertype.FileHeader;\r\n\t\t}\r\n\t\tif(UnrarHeadertype.EndArcHeader.equals(headerType)){\r\n\t\t\treturn UnrarHeadertype.EndArcHeader;\r\n\t\t}\r\n\t\tif(UnrarHeadertype.NewSubHeader.equals(headerType)){\r\n\t\t\treturn UnrarHeadertype.NewSubHeader;\r\n\t\t}\r\n\t\tif(UnrarHeadertype.SubHeader.equals(headerType)){\r\n\t\t\treturn UnrarHeadertype.SubHeader;\r\n\t\t}\r\n\t\tif(UnrarHeadertype.SignHeader.equals(headerType)){\r\n\t\t\treturn UnrarHeadertype.SignHeader;\r\n\t\t}\r\n\t\tif(UnrarHeadertype.ProtectHeader.equals(headerType)){\r\n\t\t\treturn UnrarHeadertype.ProtectHeader;\r\n\t\t}\r\n\t\tif(UnrarHeadertype.MarkHeader.equals(headerType)){\r\n\t\t\treturn UnrarHeadertype.MarkHeader;\r\n\t\t}\r\n\t\tif(UnrarHeadertype.MainHeader.equals(headerType)){\r\n\t\t\treturn UnrarHeadertype.MainHeader;\r\n\t\t}\r\n\t\tif(UnrarHeadertype.FileHeader.equals(headerType)){\r\n\t\t\treturn UnrarHeadertype.FileHeader;\r\n\t\t}\r\n\t\tif(UnrarHeadertype.EndArcHeader.equals(headerType)){\r\n\t\t\treturn UnrarHeadertype.EndArcHeader;\r\n\t\t}\r\n\t\tif(UnrarHeadertype.CommHeader.equals(headerType)){\r\n\t\t\treturn UnrarHeadertype.CommHeader;\r\n\t\t}\r\n\t\tif(UnrarHeadertype.AvHeader.equals(headerType)){\r\n\t\t\treturn UnrarHeadertype.AvHeader;\r\n\t\t}\r\n\t\treturn null;\r\n\t}\r\n\r\n\t\r\n\t\r\n\tprivate byte headerByte;\r\n\t\r\n\tprivate UnrarHeadertype(byte headerByte)\r\n\t{\r\n\t\tthis.headerByte = headerByte;\r\n\t}\r\n\r\n\t\r\n\t/**\r\n\t * Return true if the given byte is equal to the enum's byte\r\n\t * @param header\r\n\t * @return true if the given byte is equal to the enum's byte\r\n\t */\r\n\tpublic boolean equals(byte header)\r\n\t{\r\n\t\treturn headerByte == header;\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * the header byte of this enum\r\n\t * @return the header byte of this enum\r\n\t */\r\n\tpublic byte getHeaderByte() {\r\n\t\treturn headerByte;\r\n\t}\r\n\r\n\r\n\t\r\n\t\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/ComprDataIO.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 31.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack;\r\n\r\nimport java.io.EOFException;\r\nimport java.io.IOException;\r\nimport java.io.InputStream;\r\nimport java.io.OutputStream;\r\n\r\nimport com.github.junrar.Archive;\r\nimport com.github.junrar.UnrarCallback;\r\nimport com.github.junrar.Volume;\r\nimport com.github.junrar.crc.RarCRC;\r\nimport com.github.junrar.exception.RarException;\r\nimport com.github.junrar.exception.RarException.RarExceptionType;\r\nimport com.github.junrar.io.ReadOnlyAccessInputStream;\r\nimport com.github.junrar.rarfile.FileHeader;\r\n\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class ComprDataIO {\r\n\r\n\tprivate final Archive archive;\r\n\r\n\tprivate long unpPackedSize;\r\n\r\n\tprivate boolean testMode;\r\n\r\n\tprivate boolean skipUnpCRC;\r\n\r\n\tprivate InputStream inputStream;\r\n\r\n\tprivate OutputStream outputStream;\r\n\r\n\tprivate FileHeader subHead;\r\n\r\n\t// cryptData Crypt;\r\n\t// cryptData Decrypt;\r\n\tprivate boolean packVolume;\r\n\r\n\tprivate boolean unpVolume;\r\n\r\n\tprivate boolean nextVolumeMissing;\r\n\r\n\tprivate long totalPackRead;\r\n\r\n\tprivate long unpArcSize;\r\n\r\n\tprivate long curPackRead, curPackWrite, curUnpRead, curUnpWrite;\r\n\r\n\tprivate long processedArcSize, totalArcSize;\r\n\r\n\tprivate long packFileCRC, unpFileCRC, packedCRC;\r\n\r\n\tprivate int encryption;\r\n\r\n\tprivate int decryption;\r\n\r\n\tprivate int lastPercent;\r\n\r\n\tprivate char currentCommand;\r\n\r\n\tpublic ComprDataIO(Archive arc) {\r\n\t\tthis.archive = arc;\r\n\t}\r\n\r\n\tpublic void init(OutputStream outputStream) {\r\n\t\tthis.outputStream = outputStream;\r\n\t\tunpPackedSize = 0;\r\n\t\ttestMode = false;\r\n\t\tskipUnpCRC = false;\r\n\t\tpackVolume = false;\r\n\t\tunpVolume = false;\r\n\t\tnextVolumeMissing = false;\r\n\t\t// command = null;\r\n\t\tencryption = 0;\r\n\t\tdecryption = 0;\r\n\t\ttotalPackRead = 0;\r\n\t\tcurPackRead = curPackWrite = curUnpRead = curUnpWrite = 0;\r\n\t\tpackFileCRC = unpFileCRC = packedCRC = 0xffffffff;\r\n\t\tlastPercent = -1;\r\n\t\tsubHead = null;\r\n\r\n\t\tcurrentCommand = 0;\r\n\t\tprocessedArcSize = totalArcSize = 0;\r\n\t}\r\n\r\n\tpublic void init(FileHeader hd) throws IOException {\r\n\t\tlong startPos = hd.getPositionInFile() + hd.getHeaderSize();\r\n\t\tunpPackedSize = hd.getFullPackSize();\r\n\t\tinputStream = new ReadOnlyAccessInputStream(archive.getRof(), startPos,\r\n\t\t\t\tstartPos + unpPackedSize);\r\n\t\tsubHead = hd;\r\n\t\tcurUnpRead = 0;\r\n\t\tcurPackWrite = 0;\r\n\t\tpackedCRC = 0xFFffFFff;\r\n\t}\r\n\r\n\tpublic int unpRead(byte[] addr, int offset, int count) throws IOException,\r\n\t\t\tRarException {\r\n\t\tint retCode = 0, totalRead = 0;\r\n\t\twhile (count > 0) {\r\n\t\t\tint readSize = (count > unpPackedSize) ? (int) unpPackedSize\r\n\t\t\t\t\t: count;\r\n\t\t\tretCode = inputStream.read(addr, offset, readSize);\r\n\t\t\tif (retCode < 0) {\r\n\t\t\t\tthrow new EOFException();\r\n\t\t\t}\r\n\t\t\tif (subHead.isSplitAfter()) {\r\n\t\t\t\tpackedCRC = RarCRC.checkCrc((int) packedCRC, addr, offset,\r\n\t\t\t\t\t\tretCode);\r\n\t\t\t}\r\n\r\n\t\t\tcurUnpRead += retCode;\r\n\t\t\ttotalRead += retCode;\r\n\t\t\toffset += retCode;\r\n\t\t\tcount -= retCode;\r\n\t\t\tunpPackedSize -= retCode;\r\n\t\t\tarchive.bytesReadRead(retCode);\r\n\t\t\tif (unpPackedSize == 0 && subHead.isSplitAfter()) {\r\n\t\t\t\tVolume nextVolume = archive.getVolumeManager().nextArchive(\r\n\t\t\t\t\t\tarchive, archive.getVolume());\r\n\t\t\t\tif (nextVolume == null) {\r\n\t\t\t\t\tnextVolumeMissing = true;\r\n\t\t\t\t\treturn -1;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tFileHeader hd = this.getSubHeader();\r\n\t\t\t\tif (hd.getUnpVersion() >= 20 && hd.getFileCRC() != 0xffffffff\r\n\t\t\t\t\t\t&& this.getPackedCRC() != ~hd.getFileCRC()) {\r\n\t\t\t\t\tthrow new RarException(RarExceptionType.crcError);\r\n\t\t\t\t}\r\n\t\t\t\tUnrarCallback callback = archive.getUnrarCallback();\r\n\t\t\t\tif ((callback != null)\r\n\t\t\t\t\t\t&& !callback.isNextVolumeReady(nextVolume)) {\r\n\t\t\t\t\treturn -1;\r\n\t\t\t\t}\r\n\t\t\t\tarchive.setVolume(nextVolume);\r\n\t\t\t\thd = archive.nextFileHeader();\r\n\t\t\t\tif (hd == null) {\r\n\t\t\t\t\treturn -1;\r\n\t\t\t\t}\r\n\t\t\t\tthis.init(hd);\r\n\t\t\t} else {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (retCode != -1) {\r\n\t\t\tretCode = totalRead;\r\n\t\t}\r\n\t\treturn retCode;\r\n\r\n\t}\r\n\r\n\tpublic void unpWrite(byte[] addr, int offset, int count) throws IOException {\r\n\t\tif (!testMode) {\r\n\t\t\t// DestFile->Write(Addr,Count);\r\n\t\t\toutputStream.write(addr, offset, count);\r\n\t\t}\r\n\r\n\t\tcurUnpWrite += count;\r\n\r\n\t\tif (!skipUnpCRC) {\r\n\t\t\tif (archive.isOldFormat()) {\r\n\t\t\t\tunpFileCRC = RarCRC\r\n\t\t\t\t\t\t.checkOldCrc((short) unpFileCRC, addr, count);\r\n\t\t\t} else {\r\n\t\t\t\tunpFileCRC = RarCRC.checkCrc((int) unpFileCRC, addr, offset,\r\n\t\t\t\t\t\tcount);\r\n\t\t\t}\r\n\t\t}\r\n\t\t// if (!skipArcCRC) {\r\n\t\t// archive.updateDataCRC(Addr, offset, ReadSize);\r\n\t\t// }\r\n\t}\r\n\r\n\tpublic void setPackedSizeToRead(long size) {\r\n\t\tunpPackedSize = size;\r\n\t}\r\n\r\n\tpublic void setTestMode(boolean mode) {\r\n\t\ttestMode = mode;\r\n\t}\r\n\r\n\tpublic void setSkipUnpCRC(boolean skip) {\r\n\t\tskipUnpCRC = skip;\r\n\t}\r\n\r\n\tpublic void setSubHeader(FileHeader hd) {\r\n\t\tsubHead = hd;\r\n\r\n\t}\r\n\r\n\tpublic long getCurPackRead() {\r\n\t\treturn curPackRead;\r\n\t}\r\n\r\n\tpublic void setCurPackRead(long curPackRead) {\r\n\t\tthis.curPackRead = curPackRead;\r\n\t}\r\n\r\n\tpublic long getCurPackWrite() {\r\n\t\treturn curPackWrite;\r\n\t}\r\n\r\n\tpublic void setCurPackWrite(long curPackWrite) {\r\n\t\tthis.curPackWrite = curPackWrite;\r\n\t}\r\n\r\n\tpublic long getCurUnpRead() {\r\n\t\treturn curUnpRead;\r\n\t}\r\n\r\n\tpublic void setCurUnpRead(long curUnpRead) {\r\n\t\tthis.curUnpRead = curUnpRead;\r\n\t}\r\n\r\n\tpublic long getCurUnpWrite() {\r\n\t\treturn curUnpWrite;\r\n\t}\r\n\r\n\tpublic void setCurUnpWrite(long curUnpWrite) {\r\n\t\tthis.curUnpWrite = curUnpWrite;\r\n\t}\r\n\r\n\tpublic int getDecryption() {\r\n\t\treturn decryption;\r\n\t}\r\n\r\n\tpublic void setDecryption(int decryption) {\r\n\t\tthis.decryption = decryption;\r\n\t}\r\n\r\n\tpublic int getEncryption() {\r\n\t\treturn encryption;\r\n\t}\r\n\r\n\tpublic void setEncryption(int encryption) {\r\n\t\tthis.encryption = encryption;\r\n\t}\r\n\r\n\tpublic boolean isNextVolumeMissing() {\r\n\t\treturn nextVolumeMissing;\r\n\t}\r\n\r\n\tpublic void setNextVolumeMissing(boolean nextVolumeMissing) {\r\n\t\tthis.nextVolumeMissing = nextVolumeMissing;\r\n\t}\r\n\r\n\tpublic long getPackedCRC() {\r\n\t\treturn packedCRC;\r\n\t}\r\n\r\n\tpublic void setPackedCRC(long packedCRC) {\r\n\t\tthis.packedCRC = packedCRC;\r\n\t}\r\n\r\n\tpublic long getPackFileCRC() {\r\n\t\treturn packFileCRC;\r\n\t}\r\n\r\n\tpublic void setPackFileCRC(long packFileCRC) {\r\n\t\tthis.packFileCRC = packFileCRC;\r\n\t}\r\n\r\n\tpublic boolean isPackVolume() {\r\n\t\treturn packVolume;\r\n\t}\r\n\r\n\tpublic void setPackVolume(boolean packVolume) {\r\n\t\tthis.packVolume = packVolume;\r\n\t}\r\n\r\n\tpublic long getProcessedArcSize() {\r\n\t\treturn processedArcSize;\r\n\t}\r\n\r\n\tpublic void setProcessedArcSize(long processedArcSize) {\r\n\t\tthis.processedArcSize = processedArcSize;\r\n\t}\r\n\r\n\tpublic long getTotalArcSize() {\r\n\t\treturn totalArcSize;\r\n\t}\r\n\r\n\tpublic void setTotalArcSize(long totalArcSize) {\r\n\t\tthis.totalArcSize = totalArcSize;\r\n\t}\r\n\r\n\tpublic long getTotalPackRead() {\r\n\t\treturn totalPackRead;\r\n\t}\r\n\r\n\tpublic void setTotalPackRead(long totalPackRead) {\r\n\t\tthis.totalPackRead = totalPackRead;\r\n\t}\r\n\r\n\tpublic long getUnpArcSize() {\r\n\t\treturn unpArcSize;\r\n\t}\r\n\r\n\tpublic void setUnpArcSize(long unpArcSize) {\r\n\t\tthis.unpArcSize = unpArcSize;\r\n\t}\r\n\r\n\tpublic long getUnpFileCRC() {\r\n\t\treturn unpFileCRC;\r\n\t}\r\n\r\n\tpublic void setUnpFileCRC(long unpFileCRC) {\r\n\t\tthis.unpFileCRC = unpFileCRC;\r\n\t}\r\n\r\n\tpublic boolean isUnpVolume() {\r\n\t\treturn unpVolume;\r\n\t}\r\n\r\n\tpublic void setUnpVolume(boolean unpVolume) {\r\n\t\tthis.unpVolume = unpVolume;\r\n\t}\r\n\r\n\tpublic FileHeader getSubHeader() {\r\n\t\treturn subHead;\r\n\t}\r\n\r\n\t// public void setEncryption(int method, char[] Password, byte[] Salt,\r\n\t// boolean encrypt, boolean handsOffHash)\r\n\t// {\r\n\t//\r\n\t// }\r\n\t//\r\n\t// public void setAV15Encryption()\r\n\t// {\r\n\t//\r\n\t// }\r\n\t//\r\n\t// public void setCmt13Encryption()\r\n\t// {\r\n\t//\r\n\t// }\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/Unpack.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 31.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack;\r\n\r\nimport java.io.IOException;\r\nimport java.util.ArrayList;\r\nimport java.util.Arrays;\r\nimport java.util.List;\r\nimport java.util.Vector;\r\n\r\nimport com.github.junrar.exception.RarException;\r\nimport com.github.junrar.unpack.decode.Compress;\r\nimport com.github.junrar.unpack.ppm.BlockTypes;\r\nimport com.github.junrar.unpack.ppm.ModelPPM;\r\nimport com.github.junrar.unpack.ppm.SubAllocator;\r\nimport com.github.junrar.unpack.vm.BitInput;\r\nimport com.github.junrar.unpack.vm.RarVM;\r\nimport com.github.junrar.unpack.vm.VMPreparedProgram;\r\n\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic final class Unpack extends Unpack20 {\r\n\r\n    private final ModelPPM ppm = new ModelPPM();\r\n\r\n    private int ppmEscChar;\r\n\r\n    private RarVM rarVM = new RarVM();\r\n\r\n    /* Filters code, one entry per filter */\r\n    private List<UnpackFilter> filters = new ArrayList<UnpackFilter>();\r\n\r\n    /* Filters stack, several entrances of same filter are possible */\r\n    private List<UnpackFilter> prgStack = new ArrayList<UnpackFilter>();\r\n\r\n    /*\r\n     * lengths of preceding blocks, one length per filter. Used to reduce size\r\n     * required to write block length if lengths are repeating\r\n     */\r\n    private List<Integer> oldFilterLengths = new ArrayList<Integer>();\r\n\r\n    private int lastFilter;\r\n\r\n    private boolean tablesRead;\r\n\r\n    private byte[] unpOldTable = new byte[Compress.HUFF_TABLE_SIZE];\r\n\r\n    private BlockTypes unpBlockType;\r\n\r\n    private boolean externalWindow;\r\n\r\n    private long writtenFileSize;\r\n\r\n    private boolean fileExtracted;\r\n\r\n    private boolean ppmError;\r\n\r\n    private int prevLowDist;\r\n\r\n    private int lowDistRepCount;\r\n\r\n    public static int[] DBitLengthCounts = { 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\r\n\t    2, 2, 2, 2, 2, 14, 0, 12 };\r\n\r\n    public Unpack(ComprDataIO DataIO) {\r\n\tunpIO = DataIO;\r\n\twindow = null;\r\n\texternalWindow = false;\r\n\tsuspended = false;\r\n\tunpAllBuf = false;\r\n\tunpSomeRead = false;\r\n    }\r\n\r\n    public void init(byte[] window) {\r\n\tif (window == null) {\r\n\t    this.window = new byte[Compress.MAXWINSIZE];\r\n\t} else {\r\n\t    this.window = window;\r\n\t    externalWindow = true;\r\n\t}\r\n\tinAddr = 0;\r\n\tunpInitData(false);\r\n    }\r\n\r\n    public void doUnpack(int method, boolean solid) throws IOException,\r\n\t    RarException {\r\n\tif (unpIO.getSubHeader().getUnpMethod() == 0x30) {\r\n\t    unstoreFile();\r\n\t}\r\n\tswitch (method) {\r\n\tcase 15: // rar 1.5 compression\r\n\t    unpack15(solid);\r\n\t    break;\r\n\tcase 20: // rar 2.x compression\r\n\tcase 26: // files larger than 2GB\r\n\t    unpack20(solid);\r\n\t    break;\r\n\tcase 29: // rar 3.x compression\r\n\tcase 36: // alternative hash\r\n\t    unpack29(solid);\r\n\t    break;\r\n\t}\r\n    }\r\n\r\n    private void unstoreFile() throws IOException, RarException {\r\n\tbyte[] buffer = new byte[0x10000];\r\n\twhile (true) {\r\n\t    int code = unpIO.unpRead(buffer, 0, (int) Math.min(buffer.length,\r\n\t\t    destUnpSize));\r\n\t    if (code == 0 || code == -1)\r\n\t\tbreak;\r\n\t    code = code < destUnpSize ? code : (int) destUnpSize;\r\n\t    unpIO.unpWrite(buffer, 0, code);\r\n\t    if (destUnpSize >= 0)\r\n\t\tdestUnpSize -= code;\r\n\t}\r\n\r\n    }\r\n\r\n    private void unpack29(boolean solid) throws IOException, RarException {\r\n\r\n\tint[] DDecode = new int[Compress.DC];\r\n\tbyte[] DBits = new byte[Compress.DC];\r\n\r\n\tint Bits;\r\n\r\n\tif (DDecode[1] == 0) {\r\n\t    int Dist = 0, BitLength = 0, Slot = 0;\r\n\t    for (int I = 0; I < DBitLengthCounts.length; I++, BitLength++) {\r\n\t\tint count = DBitLengthCounts[I];\r\n\t\tfor (int J = 0; J < count; J++, Slot++, Dist += (1 << BitLength)) {\r\n\t\t    DDecode[Slot] = Dist;\r\n\t\t    DBits[Slot] = (byte) BitLength;\r\n\t\t}\r\n\t    }\r\n\t}\r\n\r\n\tfileExtracted = true;\r\n\r\n\tif (!suspended) {\r\n\t    unpInitData(solid);\r\n\t    if (!unpReadBuf()) {\r\n\t\treturn;\r\n\t    }\r\n\t    if ((!solid || !tablesRead) && !readTables()) {\r\n\t\treturn;\r\n\t    }\r\n\t}\r\n\r\n\tif (ppmError) {\r\n\t    return;\r\n\t}\r\n\r\n\twhile (true) {\r\n\t    unpPtr &= Compress.MAXWINMASK;\r\n\r\n\t    if (inAddr > readBorder) {\r\n\t\tif (!unpReadBuf()) {\r\n\t\t    break;\r\n\t\t}\r\n\t    }\r\n\t    // System.out.println(((wrPtr - unpPtr) &\r\n\t    // Compress.MAXWINMASK)+\":\"+wrPtr+\":\"+unpPtr);\r\n\t    if (((wrPtr - unpPtr) & Compress.MAXWINMASK) < 260\r\n\t\t    && wrPtr != unpPtr) {\r\n\r\n\t\tUnpWriteBuf();\r\n\t\tif (writtenFileSize > destUnpSize) {\r\n\t\t    return;\r\n\t\t}\r\n\t\tif (suspended) {\r\n\t\t    fileExtracted = false;\r\n\t\t    return;\r\n\t\t}\r\n\t    }\r\n\t    if (unpBlockType == BlockTypes.BLOCK_PPM) {\r\n\t\tint Ch = ppm.decodeChar();\r\n\t\tif (Ch == -1) {\r\n\t\t    ppmError = true;\r\n\t\t    break;\r\n\t\t}\r\n\t\tif (Ch == ppmEscChar) {\r\n\t\t    int NextCh = ppm.decodeChar();\r\n\t\t    if (NextCh == 0) {\r\n\t\t\tif (!readTables()) {\r\n\t\t\t    break;\r\n\t\t\t}\r\n\t\t\tcontinue;\r\n\t\t    }\r\n\t\t    if (NextCh == 2 || NextCh == -1) {\r\n\t\t\tbreak;\r\n\t\t    }\r\n\t\t    if (NextCh == 3) {\r\n\t\t\tif (!readVMCodePPM()) {\r\n\t\t\t    break;\r\n\t\t\t}\r\n\t\t\tcontinue;\r\n\t\t    }\r\n\t\t    if (NextCh == 4) {\r\n\t\t\tint Distance = 0, Length = 0;\r\n\t\t\tboolean failed = false;\r\n\t\t\tfor (int I = 0; I < 4 && !failed; I++) {\r\n\t\t\t    int ch = ppm.decodeChar();\r\n\t\t\t    if (ch == -1) {\r\n\t\t\t\tfailed = true;\r\n\t\t\t    } else {\r\n\t\t\t\tif (I == 3) {\r\n\t\t\t\t    // Bug fixed\r\n\t\t\t\t    Length = ch & 0xff;\r\n\t\t\t\t} else {\r\n\t\t\t\t    // Bug fixed\r\n\t\t\t\t    Distance = (Distance << 8) + (ch & 0xff);\r\n\t\t\t\t}\r\n\t\t\t    }\r\n\t\t\t}\r\n\t\t\tif (failed) {\r\n\t\t\t    break;\r\n\t\t\t}\r\n\t\t\tcopyString(Length + 32, Distance + 2);\r\n\t\t\tcontinue;\r\n\t\t    }\r\n\t\t    if (NextCh == 5) {\r\n\t\t\tint Length = ppm.decodeChar();\r\n\t\t\tif (Length == -1) {\r\n\t\t\t    break;\r\n\t\t\t}\r\n\t\t\tcopyString(Length + 4, 1);\r\n\t\t\tcontinue;\r\n\t\t    }\r\n\t\t}\r\n\t\twindow[unpPtr++] = (byte) Ch;\r\n\t\tcontinue;\r\n\t    }\r\n\r\n\t    int Number = decodeNumber(LD);\r\n\t    if (Number < 256) {\r\n\t\twindow[unpPtr++] = (byte) Number;\r\n\t\tcontinue;\r\n\t    }\r\n\t    if (Number >= 271) {\r\n\t\tint Length = LDecode[Number -= 271] + 3;\r\n\t\tif ((Bits = LBits[Number]) > 0) {\r\n\t\t    Length += getbits() >>> (16 - Bits);\r\n\t\t    addbits(Bits);\r\n\t\t}\r\n\r\n\t\tint DistNumber = decodeNumber(DD);\r\n\t\tint Distance = DDecode[DistNumber] + 1;\r\n\t\tif ((Bits = DBits[DistNumber]) > 0) {\r\n\t\t    if (DistNumber > 9) {\r\n\t\t\tif (Bits > 4) {\r\n\t\t\t    Distance += ((getbits() >>> (20 - Bits)) << 4);\r\n\t\t\t    addbits(Bits - 4);\r\n\t\t\t}\r\n\t\t\tif (lowDistRepCount > 0) {\r\n\t\t\t    lowDistRepCount--;\r\n\t\t\t    Distance += prevLowDist;\r\n\t\t\t} else {\r\n\t\t\t    int LowDist = decodeNumber(LDD);\r\n\t\t\t    if (LowDist == 16) {\r\n\t\t\t\tlowDistRepCount = Compress.LOW_DIST_REP_COUNT - 1;\r\n\t\t\t\tDistance += prevLowDist;\r\n\t\t\t    } else {\r\n\t\t\t\tDistance += LowDist;\r\n\t\t\t\tprevLowDist = LowDist;\r\n\t\t\t    }\r\n\t\t\t}\r\n\t\t    } else {\r\n\t\t\tDistance += getbits() >>> (16 - Bits);\r\n\t\t\taddbits(Bits);\r\n\t\t    }\r\n\t\t}\r\n\r\n\t\tif (Distance >= 0x2000) {\r\n\t\t    Length++;\r\n\t\t    if (Distance >= 0x40000L) {\r\n\t\t\tLength++;\r\n\t\t    }\r\n\t\t}\r\n\r\n\t\tinsertOldDist(Distance);\r\n\t\tinsertLastMatch(Length, Distance);\r\n\r\n\t\tcopyString(Length, Distance);\r\n\t\tcontinue;\r\n\t    }\r\n\t    if (Number == 256) {\r\n\t\tif (!readEndOfBlock()) {\r\n\t\t    break;\r\n\t\t}\r\n\t\tcontinue;\r\n\t    }\r\n\t    if (Number == 257) {\r\n\t\tif (!readVMCode()) {\r\n\t\t    break;\r\n\t\t}\r\n\t\tcontinue;\r\n\t    }\r\n\t    if (Number == 258) {\r\n\t\tif (lastLength != 0) {\r\n\t\t    copyString(lastLength, lastDist);\r\n\t\t}\r\n\t\tcontinue;\r\n\t    }\r\n\t    if (Number < 263) {\r\n\t\tint DistNum = Number - 259;\r\n\t\tint Distance = oldDist[DistNum];\r\n\t\tfor (int I = DistNum; I > 0; I--) {\r\n\t\t    oldDist[I] = oldDist[I - 1];\r\n\t\t}\r\n\t\toldDist[0] = Distance;\r\n\r\n\t\tint LengthNumber = decodeNumber(RD);\r\n\t\tint Length = LDecode[LengthNumber] + 2;\r\n\t\tif ((Bits = LBits[LengthNumber]) > 0) {\r\n\t\t    Length += getbits() >>> (16 - Bits);\r\n\t\t    addbits(Bits);\r\n\t\t}\r\n\t\tinsertLastMatch(Length, Distance);\r\n\t\tcopyString(Length, Distance);\r\n\t\tcontinue;\r\n\t    }\r\n\t    if (Number < 272) {\r\n\t\tint Distance = SDDecode[Number -= 263] + 1;\r\n\t\tif ((Bits = SDBits[Number]) > 0) {\r\n\t\t    Distance += getbits() >>> (16 - Bits);\r\n\t\t    addbits(Bits);\r\n\t\t}\r\n\t\tinsertOldDist(Distance);\r\n\t\tinsertLastMatch(2, Distance);\r\n\t\tcopyString(2, Distance);\r\n\t\tcontinue;\r\n\t    }\r\n\t}\r\n\tUnpWriteBuf();\r\n\r\n    }\r\n\r\n    private void UnpWriteBuf() throws IOException {\r\n\tint WrittenBorder = wrPtr;\r\n\tint WriteSize = (unpPtr - WrittenBorder) & Compress.MAXWINMASK;\r\n\tfor (int I = 0; I < prgStack.size(); I++) {\r\n\t    UnpackFilter flt = prgStack.get(I);\r\n\t    if (flt == null) {\r\n\t\tcontinue;\r\n\t    }\r\n\t    if (flt.isNextWindow()) {\r\n\t\tflt.setNextWindow(false);// ->NextWindow=false;\r\n\t\tcontinue;\r\n\t    }\r\n\t    int BlockStart = flt.getBlockStart();// ->BlockStart;\r\n\t    int BlockLength = flt.getBlockLength();// ->BlockLength;\r\n\t    if (((BlockStart - WrittenBorder) & Compress.MAXWINMASK) < WriteSize) {\r\n\t\tif (WrittenBorder != BlockStart) {\r\n\t\t    UnpWriteArea(WrittenBorder, BlockStart);\r\n\t\t    WrittenBorder = BlockStart;\r\n\t\t    WriteSize = (unpPtr - WrittenBorder) & Compress.MAXWINMASK;\r\n\t\t}\r\n\t\tif (BlockLength <= WriteSize) {\r\n\t\t    int BlockEnd = (BlockStart + BlockLength)\r\n\t\t\t    & Compress.MAXWINMASK;\r\n\t\t    if (BlockStart < BlockEnd || BlockEnd == 0) {\r\n\t\t\t// VM.SetMemory(0,Window+BlockStart,BlockLength);\r\n\t\t\trarVM.setMemory(0, window, BlockStart, BlockLength);\r\n\t\t    } else {\r\n\t\t\tint FirstPartLength = Compress.MAXWINSIZE - BlockStart;\r\n\t\t\t// VM.SetMemory(0,Window+BlockStart,FirstPartLength);\r\n\t\t\trarVM.setMemory(0, window, BlockStart, FirstPartLength);\r\n\t\t\t// VM.SetMemory(FirstPartLength,Window,BlockEnd);\r\n\t\t\trarVM.setMemory(FirstPartLength, window, 0, BlockEnd);\r\n\r\n\t\t    }\r\n\r\n\t\t    VMPreparedProgram ParentPrg = filters.get(\r\n\t\t\t    flt.getParentFilter()).getPrg();\r\n\t\t    VMPreparedProgram Prg = flt.getPrg();\r\n\r\n\t\t    if (ParentPrg.getGlobalData().size() > RarVM.VM_FIXEDGLOBALSIZE) {\r\n\t\t\t// copy global data from previous script execution if\r\n\t\t\t// any\r\n\t\t\t// Prg->GlobalData.Alloc(ParentPrg->GlobalData.Size());\r\n\t\t\t// memcpy(&Prg->GlobalData[VM_FIXEDGLOBALSIZE],&ParentPrg->GlobalData[VM_FIXEDGLOBALSIZE],ParentPrg->GlobalData.Size()-VM_FIXEDGLOBALSIZE);\r\n\t\t\tPrg.getGlobalData().setSize(\r\n\t\t\t\tParentPrg.getGlobalData().size());\r\n\t\t\tfor (int i = 0; i < ParentPrg.getGlobalData().size()\r\n\t\t\t\t- RarVM.VM_FIXEDGLOBALSIZE; i++) {\r\n\t\t\t    Prg.getGlobalData().set(\r\n\t\t\t\t    RarVM.VM_FIXEDGLOBALSIZE + i,\r\n\t\t\t\t    ParentPrg.getGlobalData().get(\r\n\t\t\t\t\t    RarVM.VM_FIXEDGLOBALSIZE + i));\r\n\t\t\t}\r\n\t\t    }\r\n\r\n\t\t    ExecuteCode(Prg);\r\n\r\n\t\t    if (Prg.getGlobalData().size() > RarVM.VM_FIXEDGLOBALSIZE) {\r\n\t\t\t// save global data for next script execution\r\n\t\t\tif (ParentPrg.getGlobalData().size() < Prg\r\n\t\t\t\t.getGlobalData().size()) {\r\n\t\t\t    ParentPrg.getGlobalData().setSize(\r\n\t\t\t\t    Prg.getGlobalData().size());// ->GlobalData.Alloc(Prg->GlobalData.Size());\r\n\t\t\t}\r\n\t\t\t// memcpy(&ParentPrg->GlobalData[VM_FIXEDGLOBALSIZE],&Prg->GlobalData[VM_FIXEDGLOBALSIZE],Prg->GlobalData.Size()-VM_FIXEDGLOBALSIZE);\r\n\t\t\tfor (int i = 0; i < Prg.getGlobalData().size()\r\n\t\t\t\t- RarVM.VM_FIXEDGLOBALSIZE; i++) {\r\n\t\t\t    ParentPrg.getGlobalData().set(\r\n\t\t\t\t    RarVM.VM_FIXEDGLOBALSIZE + i,\r\n\t\t\t\t    Prg.getGlobalData().get(\r\n\t\t\t\t\t    RarVM.VM_FIXEDGLOBALSIZE + i));\r\n\t\t\t}\r\n\t\t    } else {\r\n\t\t\tParentPrg.getGlobalData().clear();\r\n\t\t    }\r\n\r\n\t\t    int FilteredDataOffset = Prg.getFilteredDataOffset();\r\n\t\t    int FilteredDataSize = Prg.getFilteredDataSize();\r\n\t\t    byte[] FilteredData = new byte[FilteredDataSize];\r\n\r\n\t\t    for (int i = 0; i < FilteredDataSize; i++) {\r\n\t\t\tFilteredData[i] = rarVM.getMem()[FilteredDataOffset + i];// Prg.getGlobalData().get(FilteredDataOffset\r\n\t\t\t\t\t\t\t\t\t\t // +\r\n\t\t\t\t\t\t\t\t\t\t // i);\r\n\t\t    }\r\n\r\n\t\t    prgStack.set(I, null);\r\n\t\t    while (I + 1 < prgStack.size()) {\r\n\t\t\tUnpackFilter NextFilter = prgStack.get(I + 1);\r\n\t\t\tif (NextFilter == null\r\n\t\t\t\t|| NextFilter.getBlockStart() != BlockStart\r\n\t\t\t\t|| NextFilter.getBlockLength() != FilteredDataSize\r\n\t\t\t\t|| NextFilter.isNextWindow()) {\r\n\t\t\t    break;\r\n\t\t\t}\r\n\t\t\t// apply several filters to same data block\r\n\r\n\t\t\trarVM.setMemory(0, FilteredData, 0, FilteredDataSize);// .SetMemory(0,FilteredData,FilteredDataSize);\r\n\r\n\t\t\tVMPreparedProgram pPrg = filters.get(\r\n\t\t\t\tNextFilter.getParentFilter()).getPrg();\r\n\t\t\tVMPreparedProgram NextPrg = NextFilter.getPrg();\r\n\r\n\t\t\tif (pPrg.getGlobalData().size() > RarVM.VM_FIXEDGLOBALSIZE) {\r\n\t\t\t    // copy global data from previous script execution\r\n\t\t\t    // if any\r\n\t\t\t    // NextPrg->GlobalData.Alloc(ParentPrg->GlobalData.Size());\r\n\t\t\t    NextPrg.getGlobalData().setSize(\r\n\t\t\t\t    pPrg.getGlobalData().size());\r\n\t\t\t    // memcpy(&NextPrg->GlobalData[VM_FIXEDGLOBALSIZE],&ParentPrg->GlobalData[VM_FIXEDGLOBALSIZE],ParentPrg->GlobalData.Size()-VM_FIXEDGLOBALSIZE);\r\n\t\t\t    for (int i = 0; i < pPrg.getGlobalData().size()\r\n\t\t\t\t    - RarVM.VM_FIXEDGLOBALSIZE; i++) {\r\n\t\t\t\tNextPrg.getGlobalData().set(\r\n\t\t\t\t\tRarVM.VM_FIXEDGLOBALSIZE + i,\r\n\t\t\t\t\tpPrg.getGlobalData().get(\r\n\t\t\t\t\t\tRarVM.VM_FIXEDGLOBALSIZE + i));\r\n\t\t\t    }\r\n\t\t\t}\r\n\r\n\t\t\tExecuteCode(NextPrg);\r\n\r\n\t\t\tif (NextPrg.getGlobalData().size() > RarVM.VM_FIXEDGLOBALSIZE) {\r\n\t\t\t    // save global data for next script execution\r\n\t\t\t    if (pPrg.getGlobalData().size() < NextPrg\r\n\t\t\t\t    .getGlobalData().size()) {\r\n\t\t\t\tpPrg.getGlobalData().setSize(\r\n\t\t\t\t\tNextPrg.getGlobalData().size());\r\n\t\t\t    }\r\n\t\t\t    // memcpy(&ParentPrg->GlobalData[VM_FIXEDGLOBALSIZE],&NextPrg->GlobalData[VM_FIXEDGLOBALSIZE],NextPrg->GlobalData.Size()-VM_FIXEDGLOBALSIZE);\r\n\t\t\t    for (int i = 0; i < NextPrg.getGlobalData().size()\r\n\t\t\t\t    - RarVM.VM_FIXEDGLOBALSIZE; i++) {\r\n\t\t\t\tpPrg.getGlobalData().set(\r\n\t\t\t\t\tRarVM.VM_FIXEDGLOBALSIZE + i,\r\n\t\t\t\t\tNextPrg.getGlobalData().get(\r\n\t\t\t\t\t\tRarVM.VM_FIXEDGLOBALSIZE + i));\r\n\t\t\t    }\r\n\t\t\t} else {\r\n\t\t\t    pPrg.getGlobalData().clear();\r\n\t\t\t}\r\n\t\t\tFilteredDataOffset = NextPrg.getFilteredDataOffset();\r\n\t\t\tFilteredDataSize = NextPrg.getFilteredDataSize();\r\n\r\n\t\t\tFilteredData = new byte[FilteredDataSize];\r\n\t\t\tfor (int i = 0; i < FilteredDataSize; i++) {\r\n\t\t\t    FilteredData[i] = NextPrg.getGlobalData().get(\r\n\t\t\t\t    FilteredDataOffset + i);\r\n\t\t\t}\r\n\r\n\t\t\tI++;\r\n\t\t\tprgStack.set(I, null);\r\n\t\t    }\r\n\t\t    unpIO.unpWrite(FilteredData, 0, FilteredDataSize);\r\n\t\t    unpSomeRead = true;\r\n\t\t    writtenFileSize += FilteredDataSize;\r\n\t\t    WrittenBorder = BlockEnd;\r\n\t\t    WriteSize = (unpPtr - WrittenBorder) & Compress.MAXWINMASK;\r\n\t\t} else {\r\n\t\t    for (int J = I; J < prgStack.size(); J++) {\r\n\t\t\tUnpackFilter filt = prgStack.get(J);\r\n\t\t\tif (filt != null && filt.isNextWindow()) {\r\n\t\t\t    filt.setNextWindow(false);\r\n\t\t\t}\r\n\t\t    }\r\n\t\t    wrPtr = WrittenBorder;\r\n\t\t    return;\r\n\t\t}\r\n\t    }\r\n\t}\r\n\r\n\tUnpWriteArea(WrittenBorder, unpPtr);\r\n\twrPtr = unpPtr;\r\n\r\n    }\r\n\r\n    private void UnpWriteArea(int startPtr, int endPtr) throws IOException {\r\n\tif (endPtr != startPtr) {\r\n\t    unpSomeRead = true;\r\n\t}\r\n\tif (endPtr < startPtr) {\r\n\t    UnpWriteData(window, startPtr, -startPtr & Compress.MAXWINMASK);\r\n\t    UnpWriteData(window, 0, endPtr);\r\n\t    unpAllBuf = true;\r\n\t} else {\r\n\t    UnpWriteData(window, startPtr, endPtr - startPtr);\r\n\t}\r\n    }\r\n\r\n    private void UnpWriteData(byte[] data, int offset, int size)\r\n\t    throws IOException {\r\n\tif (writtenFileSize >= destUnpSize) {\r\n\t    return;\r\n\t}\r\n\tint writeSize = size;\r\n\tlong leftToWrite = destUnpSize - writtenFileSize;\r\n\tif (writeSize > leftToWrite) {\r\n\t    writeSize = (int) leftToWrite;\r\n\t}\r\n\tunpIO.unpWrite(data, offset, writeSize);\r\n\r\n\twrittenFileSize += size;\r\n\r\n    }\r\n\r\n    private void insertOldDist(int distance) {\r\n\toldDist[3] = oldDist[2];\r\n\toldDist[2] = oldDist[1];\r\n\toldDist[1] = oldDist[0];\r\n\toldDist[0] = distance;\r\n    }\r\n\r\n    private void insertLastMatch(int length, int distance) {\r\n\tlastDist = distance;\r\n\tlastLength = length;\r\n    }\r\n\r\n    private void copyString(int length, int distance) {\r\n\t// System.out.println(\"copyString(\" + length + \", \" + distance + \")\");\r\n\r\n\tint destPtr = unpPtr - distance;\r\n\t// System.out.println(unpPtr+\":\"+distance);\r\n\tif (destPtr >= 0 && destPtr < Compress.MAXWINSIZE - 260\r\n\t\t&& unpPtr < Compress.MAXWINSIZE - 260) {\r\n\r\n\t    window[unpPtr++] = window[destPtr++];\r\n\r\n\t    while (--length > 0)\r\n\r\n\t\twindow[unpPtr++] = window[destPtr++];\r\n\t} else\r\n\t    while (length-- != 0) {\r\n\t\twindow[unpPtr] = window[destPtr++ & Compress.MAXWINMASK];\r\n\t\tunpPtr = (unpPtr + 1) & Compress.MAXWINMASK;\r\n\t    }\r\n    }\r\n\r\n    protected void unpInitData(boolean solid) {\r\n\tif (!solid) {\r\n\t    tablesRead = false;\r\n\t    Arrays.fill(oldDist, 0); // memset(oldDist,0,sizeof(OldDist));\r\n\r\n\t    oldDistPtr = 0;\r\n\t    lastDist = 0;\r\n\t    lastLength = 0;\r\n\r\n\t    Arrays.fill(unpOldTable, (byte) 0);// memset(UnpOldTable,0,sizeof(UnpOldTable));\r\n\r\n\t    unpPtr = 0;\r\n\t    wrPtr = 0;\r\n\t    ppmEscChar = 2;\r\n\r\n\t    initFilters();\r\n\t}\r\n\tInitBitInput();\r\n\tppmError = false;\r\n\twrittenFileSize = 0;\r\n\treadTop = 0;\r\n\treadBorder = 0;\r\n\tunpInitData20(solid);\r\n    }\r\n\r\n    private void initFilters() {\r\n\toldFilterLengths.clear();\r\n\tlastFilter = 0;\r\n\r\n\tfilters.clear();\r\n\r\n\tprgStack.clear();\r\n    }\r\n\r\n    private boolean readEndOfBlock() throws IOException, RarException {\r\n\tint BitField = getbits();\r\n\tboolean NewTable, NewFile = false;\r\n\tif ((BitField & 0x8000) != 0) {\r\n\t    NewTable = true;\r\n\t    addbits(1);\r\n\t} else {\r\n\t    NewFile = true;\r\n\t    NewTable = (BitField & 0x4000) != 0 ? true : false;\r\n\t    addbits(2);\r\n\t}\r\n\ttablesRead = !NewTable;\r\n\treturn !(NewFile || NewTable && !readTables());\r\n    }\r\n\r\n    private boolean readTables() throws IOException, RarException {\r\n\tbyte[] bitLength = new byte[Compress.BC];\r\n\r\n\tbyte[] table = new byte[Compress.HUFF_TABLE_SIZE];\r\n\tif (inAddr > readTop - 25) {\r\n\t    if (!unpReadBuf()) {\r\n\t\treturn (false);\r\n\t    }\r\n\t}\r\n\tfaddbits((8 - inBit) & 7);\r\n\tlong bitField = fgetbits() & 0xffFFffFF;\r\n\tif ((bitField & 0x8000) != 0) {\r\n\t    unpBlockType = BlockTypes.BLOCK_PPM;\r\n\t    return (ppm.decodeInit(this, ppmEscChar));\r\n\t}\r\n\tunpBlockType = BlockTypes.BLOCK_LZ;\r\n\r\n\tprevLowDist = 0;\r\n\tlowDistRepCount = 0;\r\n\r\n\tif ((bitField & 0x4000) == 0) {\r\n\t    Arrays.fill(unpOldTable, (byte) 0);// memset(UnpOldTable,0,sizeof(UnpOldTable));\r\n\t}\r\n\tfaddbits(2);\r\n\r\n\tfor (int i = 0; i < Compress.BC; i++) {\r\n\t    int length = (fgetbits() >>> 12) & 0xFF;\r\n\t    faddbits(4);\r\n\t    if (length == 15) {\r\n\t\tint zeroCount = (fgetbits() >>> 12) & 0xFF;\r\n\t\tfaddbits(4);\r\n\t\tif (zeroCount == 0) {\r\n\t\t    bitLength[i] = 15;\r\n\t\t} else {\r\n\t\t    zeroCount += 2;\r\n\t\t    while (zeroCount-- > 0 && i < bitLength.length) {\r\n\t\t\tbitLength[i++] = 0;\r\n\t\t    }\r\n\t\t    i--;\r\n\t\t}\r\n\t    } else {\r\n\t\tbitLength[i] = (byte) length;\r\n\t    }\r\n\t}\r\n\r\n\tmakeDecodeTables(bitLength, 0, BD, Compress.BC);\r\n\r\n\tint TableSize = Compress.HUFF_TABLE_SIZE;\r\n\r\n\tfor (int i = 0; i < TableSize;) {\r\n\t    if (inAddr > readTop - 5) {\r\n\t\tif (!unpReadBuf()) {\r\n\t\t    return (false);\r\n\t\t}\r\n\t    }\r\n\t    int Number = decodeNumber(BD);\r\n\t    if (Number < 16) {\r\n\t\ttable[i] = (byte) ((Number + unpOldTable[i]) & 0xf);\r\n\t\ti++;\r\n\t    } else if (Number < 18) {\r\n\t\tint N;\r\n\t\tif (Number == 16) {\r\n\t\t    N = (fgetbits() >>> 13) + 3;\r\n\t\t    faddbits(3);\r\n\t\t} else {\r\n\t\t    N = (fgetbits() >>> 9) + 11;\r\n\t\t    faddbits(7);\r\n\t\t}\r\n\t\twhile (N-- > 0 && i < TableSize) {\r\n\t\t    table[i] = table[i - 1];\r\n\t\t    i++;\r\n\t\t}\r\n\t    } else {\r\n\t\tint N;\r\n\t\tif (Number == 18) {\r\n\t\t    N = (fgetbits() >>> 13) + 3;\r\n\t\t    faddbits(3);\r\n\t\t} else {\r\n\t\t    N = (fgetbits() >>> 9) + 11;\r\n\t\t    faddbits(7);\r\n\t\t}\r\n\t\twhile (N-- > 0 && i < TableSize) {\r\n\t\t    table[i++] = 0;\r\n\t\t}\r\n\t    }\r\n\t}\r\n\ttablesRead = true;\r\n\tif (inAddr > readTop) {\r\n\t    return (false);\r\n\t}\r\n\tmakeDecodeTables(table, 0, LD, Compress.NC);\r\n\tmakeDecodeTables(table, Compress.NC, DD, Compress.DC);\r\n\tmakeDecodeTables(table, Compress.NC + Compress.DC, LDD, Compress.LDC);\r\n\tmakeDecodeTables(table, Compress.NC + Compress.DC + Compress.LDC, RD,\r\n\t\tCompress.RC);\r\n\r\n\t// memcpy(unpOldTable,table,sizeof(unpOldTable));\r\n\tfor (int i = 0; i < unpOldTable.length; i++) {\r\n\t    unpOldTable[i] = table[i];\r\n\t}\r\n\treturn (true);\r\n\r\n    }\r\n\r\n    private boolean readVMCode() throws IOException, RarException {\r\n\tint FirstByte = getbits() >> 8;\r\n\taddbits(8);\r\n\tint Length = (FirstByte & 7) + 1;\r\n\tif (Length == 7) {\r\n\t    Length = (getbits() >> 8) + 7;\r\n\t    addbits(8);\r\n\t} else if (Length == 8) {\r\n\t    Length = getbits();\r\n\t    addbits(16);\r\n\t}\r\n\tList<Byte> vmCode = new ArrayList<Byte>();\r\n\tfor (int I = 0; I < Length; I++) {\r\n\t    if (inAddr >= readTop - 1 && !unpReadBuf() && I < Length - 1) {\r\n\t\treturn (false);\r\n\t    }\r\n\t    vmCode.add(Byte.valueOf((byte) (getbits() >> 8)));\r\n\t    addbits(8);\r\n\t}\r\n\treturn (addVMCode(FirstByte, vmCode, Length));\r\n    }\r\n\r\n    private boolean readVMCodePPM() throws IOException, RarException {\r\n\tint FirstByte = ppm.decodeChar();\r\n\tif ((int) FirstByte == -1) {\r\n\t    return (false);\r\n\t}\r\n\tint Length = (FirstByte & 7) + 1;\r\n\tif (Length == 7) {\r\n\t    int B1 = ppm.decodeChar();\r\n\t    if (B1 == -1) {\r\n\t\treturn (false);\r\n\t    }\r\n\t    Length = B1 + 7;\r\n\t} else if (Length == 8) {\r\n\t    int B1 = ppm.decodeChar();\r\n\t    if (B1 == -1) {\r\n\t\treturn (false);\r\n\t    }\r\n\t    int B2 = ppm.decodeChar();\r\n\t    if (B2 == -1) {\r\n\t\treturn (false);\r\n\t    }\r\n\t    Length = B1 * 256 + B2;\r\n\t}\r\n\tList<Byte> vmCode = new ArrayList<Byte>();\r\n\tfor (int I = 0; I < Length; I++) {\r\n\t    int Ch = ppm.decodeChar();\r\n\t    if (Ch == -1) {\r\n\t\treturn (false);\r\n\t    }\r\n\t    vmCode.add(Byte.valueOf((byte) Ch));// VMCode[I]=Ch;\r\n\t}\r\n\treturn (addVMCode(FirstByte, vmCode, Length));\r\n    }\r\n\r\n    private boolean addVMCode(int firstByte, List<Byte> vmCode, int length) {\r\n\tBitInput Inp = new BitInput();\r\n\tInp.InitBitInput();\r\n\t// memcpy(Inp.InBuf,Code,Min(BitInput::MAX_SIZE,CodeSize));\r\n\tfor (int i = 0; i < Math.min(BitInput.MAX_SIZE, vmCode.size()); i++) {\r\n\t    Inp.getInBuf()[i] = vmCode.get(i);\r\n\t}\r\n\trarVM.init();\r\n\r\n\tint FiltPos;\r\n\tif ((firstByte & 0x80) != 0) {\r\n\t    FiltPos = RarVM.ReadData(Inp);\r\n\t    if (FiltPos == 0) {\r\n\t\tinitFilters();\r\n\t    } else {\r\n\t\tFiltPos--;\r\n\t    }\r\n\t} else\r\n\t    FiltPos = lastFilter; // use the same filter as last time\r\n\r\n\tif (FiltPos > filters.size() || FiltPos > oldFilterLengths.size()) {\r\n\t    return (false);\r\n\t}\r\n\tlastFilter = FiltPos;\r\n\tboolean NewFilter = (FiltPos == filters.size());\r\n\r\n\tUnpackFilter StackFilter = new UnpackFilter(); // new filter for\r\n\t// PrgStack\r\n\r\n\tUnpackFilter Filter;\r\n\tif (NewFilter) // new filter code, never used before since VM reset\r\n\t{\r\n\t    // too many different filters, corrupt archive\r\n\t    if (FiltPos > 1024) {\r\n\t\treturn (false);\r\n\t    }\r\n\r\n\t    // Filters[Filters.Size()-1]=Filter=new UnpackFilter;\r\n\t    Filter = new UnpackFilter();\r\n\t    filters.add(Filter);\r\n\t    StackFilter.setParentFilter(filters.size() - 1);\r\n\t    oldFilterLengths.add(0);\r\n\t    Filter.setExecCount(0);\r\n\t} else // filter was used in the past\r\n\t{\r\n\t    Filter = filters.get(FiltPos);\r\n\t    StackFilter.setParentFilter(FiltPos);\r\n\t    Filter.setExecCount(Filter.getExecCount() + 1);// ->ExecCount++;\r\n\t}\r\n\r\n\tprgStack.add(StackFilter);\r\n\tStackFilter.setExecCount(Filter.getExecCount());// ->ExecCount;\r\n\r\n\tint BlockStart = RarVM.ReadData(Inp);\r\n\tif ((firstByte & 0x40) != 0) {\r\n\t    BlockStart += 258;\r\n\t}\r\n\tStackFilter.setBlockStart((BlockStart + unpPtr) & Compress.MAXWINMASK);\r\n\tif ((firstByte & 0x20) != 0) {\r\n\t    StackFilter.setBlockLength(RarVM.ReadData(Inp));\r\n\t} else {\r\n\t    StackFilter\r\n\t\t    .setBlockLength(FiltPos < oldFilterLengths.size() ? oldFilterLengths\r\n\t\t\t    .get(FiltPos)\r\n\t\t\t    : 0);\r\n\t}\r\n\tStackFilter.setNextWindow((wrPtr != unpPtr)\r\n\t\t&& ((wrPtr - unpPtr) & Compress.MAXWINMASK) <= BlockStart);\r\n\r\n\t// DebugLog(\"\\nNextWindow: UnpPtr=%08x WrPtr=%08x\r\n\t// BlockStart=%08x\",UnpPtr,WrPtr,BlockStart);\r\n\r\n\toldFilterLengths.set(FiltPos, StackFilter.getBlockLength());\r\n\r\n\t// memset(StackFilter->Prg.InitR,0,sizeof(StackFilter->Prg.InitR));\r\n\tArrays.fill(StackFilter.getPrg().getInitR(), 0);\r\n\tStackFilter.getPrg().getInitR()[3] = RarVM.VM_GLOBALMEMADDR;// StackFilter->Prg.InitR[3]=VM_GLOBALMEMADDR;\r\n\tStackFilter.getPrg().getInitR()[4] = StackFilter.getBlockLength();// StackFilter->Prg.InitR[4]=StackFilter->BlockLength;\r\n\tStackFilter.getPrg().getInitR()[5] = StackFilter.getExecCount();// StackFilter->Prg.InitR[5]=StackFilter->ExecCount;\r\n\r\n\tif ((firstByte & 0x10) != 0) // set registers to optional parameters\r\n\t// if any\r\n\t{\r\n\t    int InitMask = Inp.fgetbits() >>> 9;\r\n\t    Inp.faddbits(7);\r\n\t    for (int I = 0; I < 7; I++) {\r\n\t\tif ((InitMask & (1 << I)) != 0) {\r\n\t\t    // StackFilter->Prg.InitR[I]=RarVM::ReadData(Inp);\r\n\t\t    StackFilter.getPrg().getInitR()[I] = RarVM.ReadData(Inp);\r\n\t\t}\r\n\t    }\r\n\t}\r\n\r\n\tif (NewFilter) {\r\n\t    int VMCodeSize = RarVM.ReadData(Inp);\r\n\t    if (VMCodeSize >= 0x10000 || VMCodeSize == 0) {\r\n\t\treturn (false);\r\n\t    }\r\n\t    byte[] VMCode = new byte[VMCodeSize];\r\n\t    for (int I = 0; I < VMCodeSize; I++) {\r\n\t\tif (Inp.Overflow(3)) {\r\n\t\t    return (false);\r\n\t\t}\r\n\t\tVMCode[I] = (byte) (Inp.fgetbits() >> 8);\r\n\t\tInp.faddbits(8);\r\n\t    }\r\n\t    // VM.Prepare(&VMCode[0],VMCodeSize,&Filter->Prg);\r\n\t    rarVM.prepare(VMCode, VMCodeSize, Filter.getPrg());\r\n\t}\r\n\tStackFilter.getPrg().setAltCmd(Filter.getPrg().getCmd());// StackFilter->Prg.AltCmd=&Filter->Prg.Cmd[0];\r\n\tStackFilter.getPrg().setCmdCount(Filter.getPrg().getCmdCount());// StackFilter->Prg.CmdCount=Filter->Prg.CmdCount;\r\n\r\n\tint StaticDataSize = Filter.getPrg().getStaticData().size();\r\n\tif (StaticDataSize > 0 && StaticDataSize < RarVM.VM_GLOBALMEMSIZE) {\r\n\t    // read statically defined data contained in DB commands\r\n\t    // StackFilter->Prg.StaticData.Add(StaticDataSize);\r\n\t    StackFilter.getPrg().setStaticData(Filter.getPrg().getStaticData());\r\n\t    // memcpy(&StackFilter->Prg.StaticData[0],&Filter->Prg.StaticData[0],StaticDataSize);\r\n\t}\r\n\r\n\tif (StackFilter.getPrg().getGlobalData().size() < RarVM.VM_FIXEDGLOBALSIZE) {\r\n\t    // StackFilter->Prg.GlobalData.Reset();\r\n\t    // StackFilter->Prg.GlobalData.Add(VM_FIXEDGLOBALSIZE);\r\n\t    StackFilter.getPrg().getGlobalData().clear();\r\n\t    StackFilter.getPrg().getGlobalData().setSize(\r\n\t\t    RarVM.VM_FIXEDGLOBALSIZE);\r\n\t}\r\n\r\n\t// byte *GlobalData=&StackFilter->Prg.GlobalData[0];\r\n\tVector<Byte> globalData = StackFilter.getPrg().getGlobalData();\r\n\tfor (int I = 0; I < 7; I++) {\r\n\t    rarVM.setLowEndianValue(globalData, I * 4, StackFilter.getPrg()\r\n\t\t    .getInitR()[I]);\r\n\t}\r\n\r\n\t// VM.SetLowEndianValue((uint\r\n\t// *)&GlobalData[0x1c],StackFilter->BlockLength);\r\n\trarVM.setLowEndianValue(globalData, 0x1c, StackFilter.getBlockLength());\r\n\t// VM.SetLowEndianValue((uint *)&GlobalData[0x20],0);\r\n\trarVM.setLowEndianValue(globalData, 0x20, 0);\r\n\trarVM.setLowEndianValue(globalData, 0x24, 0);\r\n\trarVM.setLowEndianValue(globalData, 0x28, 0);\r\n\r\n\t// VM.SetLowEndianValue((uint\r\n\t// *)&GlobalData[0x2c],StackFilter->ExecCount);\r\n\trarVM.setLowEndianValue(globalData, 0x2c, StackFilter.getExecCount());\r\n\t// memset(&GlobalData[0x30],0,16);\r\n\tfor (int i = 0; i < 16; i++) {\r\n\t    globalData.set(0x30 + i, Byte.valueOf((byte) (0)));\r\n\t}\r\n\tif ((firstByte & 8) != 0) // put data block passed as parameter if any\r\n\t{\r\n\t    if (Inp.Overflow(3)) {\r\n\t\treturn (false);\r\n\t    }\r\n\t    int DataSize = RarVM.ReadData(Inp);\r\n\t    if (DataSize > RarVM.VM_GLOBALMEMSIZE - RarVM.VM_FIXEDGLOBALSIZE) {\r\n\t\treturn (false);\r\n\t    }\r\n\t    int CurSize = StackFilter.getPrg().getGlobalData().size();\r\n\t    if (CurSize < DataSize + RarVM.VM_FIXEDGLOBALSIZE) {\r\n\t\t// StackFilter->Prg.GlobalData.Add(DataSize+VM_FIXEDGLOBALSIZE-CurSize);\r\n\t\tStackFilter.getPrg().getGlobalData().setSize(\r\n\t\t\tDataSize + RarVM.VM_FIXEDGLOBALSIZE - CurSize);\r\n\t    }\r\n\t    int offset = RarVM.VM_FIXEDGLOBALSIZE;\r\n\t    globalData = StackFilter.getPrg().getGlobalData();\r\n\t    for (int I = 0; I < DataSize; I++) {\r\n\t\tif (Inp.Overflow(3)) {\r\n\t\t    return (false);\r\n\t\t}\r\n\t\tglobalData.set(offset + I, Byte\r\n\t\t\t.valueOf((byte) (Inp.fgetbits() >>> 8)));\r\n\t\tInp.faddbits(8);\r\n\t    }\r\n\t}\r\n\treturn (true);\r\n    }\r\n\r\n    private void ExecuteCode(VMPreparedProgram Prg) {\r\n\tif (Prg.getGlobalData().size() > 0) {\r\n\t    // Prg->InitR[6]=int64to32(WrittenFileSize);\r\n\t    Prg.getInitR()[6] = (int) (writtenFileSize);\r\n\t    // rarVM.SetLowEndianValue((uint\r\n\t    // *)&Prg->GlobalData[0x24],int64to32(WrittenFileSize));\r\n\t    rarVM.setLowEndianValue(Prg.getGlobalData(), 0x24,\r\n\t\t    (int) writtenFileSize);\r\n\t    // rarVM.SetLowEndianValue((uint\r\n\t    // *)&Prg->GlobalData[0x28],int64to32(WrittenFileSize>>32));\r\n\t    rarVM.setLowEndianValue(Prg.getGlobalData(), 0x28,\r\n\t\t    (int) (writtenFileSize >>> 32));\r\n\t    rarVM.execute(Prg);\r\n\t}\r\n    }\r\n\r\n    // Duplicate method\r\n    // private boolean ReadEndOfBlock() throws IOException, RarException\r\n    // {\r\n    // int BitField = getbits();\r\n    // boolean NewTable, NewFile = false;\r\n    // if ((BitField & 0x8000) != 0) {\r\n    // NewTable = true;\r\n    // addbits(1);\r\n    // } else {\r\n    // NewFile = true;\r\n    // NewTable = (BitField & 0x4000) != 0;\r\n    // addbits(2);\r\n    // }\r\n    // tablesRead = !NewTable;\r\n    // return !(NewFile || NewTable && !readTables());\r\n    // }\r\n\r\n    public boolean isFileExtracted() {\r\n\treturn fileExtracted;\r\n    }\r\n\r\n    public void setDestSize(long destSize) {\r\n\tthis.destUnpSize = destSize;\r\n\tthis.fileExtracted = false;\r\n    }\r\n\r\n    public void setSuspended(boolean suspended) {\r\n\tthis.suspended = suspended;\r\n    }\r\n\r\n    public int getChar() throws IOException, RarException {\r\n\tif (inAddr > BitInput.MAX_SIZE - 30) {\r\n\t    unpReadBuf();\r\n\t}\r\n\treturn (inBuf[inAddr++] & 0xff);\r\n    }\r\n\r\n    public int getPpmEscChar() {\r\n\treturn ppmEscChar;\r\n    }\r\n\r\n    public void setPpmEscChar(int ppmEscChar) {\r\n\tthis.ppmEscChar = ppmEscChar;\r\n    }\r\n\r\n    public void cleanUp() {\r\n\tif (ppm != null) {\r\n\t    SubAllocator allocator = ppm.getSubAlloc();\r\n\t    if (allocator != null) {\r\n\t\tallocator.stopSubAllocator();\r\n\t    }\r\n\t}\r\n    }\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/Unpack15.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 21.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack;\r\n\r\nimport java.io.IOException;\r\nimport java.util.Arrays;\r\n\r\nimport com.github.junrar.exception.RarException;\r\nimport com.github.junrar.unpack.decode.Compress;\r\nimport com.github.junrar.unpack.vm.BitInput;\r\n\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic abstract class Unpack15 extends BitInput\r\n{\r\n\r\n\tprotected int readBorder;\r\n\t\r\n\tprotected boolean suspended;\r\n\r\n\tprotected boolean unpAllBuf;\r\n\r\n\tprotected ComprDataIO unpIO;\r\n\r\n\tprotected boolean unpSomeRead;\r\n\r\n\tprotected int readTop;\r\n\r\n\tprotected long destUnpSize;\r\n\r\n\tprotected byte[] window;\r\n\r\n\tprotected int[] oldDist = new int[4];\r\n\r\n\tprotected int unpPtr, wrPtr;\r\n\r\n\tprotected int oldDistPtr;\r\n\r\n\tprotected int[] ChSet = new int[256], ChSetA = new int[256],\r\n\t\t\tChSetB = new int[256], ChSetC = new int[256];\r\n\r\n\tprotected int[] Place = new int[256], PlaceA = new int[256],\r\n\t\t\tPlaceB = new int[256], PlaceC = new int[256];\r\n\r\n\tprotected int[] NToPl = new int[256], NToPlB = new int[256],\r\n\t\t\tNToPlC = new int[256];\r\n\r\n\tprotected int FlagBuf, AvrPlc, AvrPlcB, AvrLn1, AvrLn2, AvrLn3;\r\n\r\n\tprotected int Buf60, NumHuf, StMode, LCount, FlagsCnt;\r\n\r\n\tprotected int Nhfb, Nlzb, MaxDist3;\r\n\r\n\tprotected int lastDist, lastLength;\r\n\r\n\tprivate static final int STARTL1 = 2;\r\n\r\n\tprivate static int DecL1[] = { 0x8000, 0xa000, 0xc000, 0xd000, 0xe000,\r\n\t\t\t0xea00, 0xee00, 0xf000, 0xf200, 0xf200, 0xffff };\r\n\r\n\tprivate static int PosL1[] = { 0, 0, 0, 2, 3, 5, 7, 11, 16, 20, 24, 32, 32 };\r\n\r\n\tprivate static final int STARTL2 = 3;\r\n\r\n\tprivate static int DecL2[] = { 0xa000, 0xc000, 0xd000, 0xe000, 0xea00,\r\n\t\t\t0xee00, 0xf000, 0xf200, 0xf240, 0xffff };\r\n\r\n\tprivate static int PosL2[] = { 0, 0, 0, 0, 5, 7, 9, 13, 18, 22, 26, 34, 36 };\r\n\r\n\tprivate static final int STARTHF0 = 4;\r\n\r\n\tprivate static int DecHf0[] = { 0x8000, 0xc000, 0xe000, 0xf200, 0xf200,\r\n\t\t\t0xf200, 0xf200, 0xf200, 0xffff };\r\n\r\n\tprivate static int PosHf0[] = { 0, 0, 0, 0, 0, 8, 16, 24, 33, 33, 33, 33,\r\n\t\t\t33 };\r\n\r\n\tprivate static final int STARTHF1 = 5;\r\n\r\n\tprivate static int DecHf1[] = { 0x2000, 0xc000, 0xe000, 0xf000, 0xf200,\r\n\t\t\t0xf200, 0xf7e0, 0xffff };\r\n\r\n\tprivate static int PosHf1[] = { 0, 0, 0, 0, 0, 0, 4, 44, 60, 76, 80, 80,\r\n\t\t\t127 };\r\n\r\n\tprivate static final int STARTHF2 = 5;\r\n\r\n\tprivate static int DecHf2[] = { 0x1000, 0x2400, 0x8000, 0xc000, 0xfa00,\r\n\t\t\t0xffff, 0xffff, 0xffff };\r\n\r\n\tprivate static int PosHf2[] = { 0, 0, 0, 0, 0, 0, 2, 7, 53, 117, 233, 0, 0 };\r\n\r\n\tprivate static final int STARTHF3 = 6;\r\n\r\n\tprivate static int DecHf3[] = { 0x800, 0x2400, 0xee00, 0xfe80, 0xffff,\r\n\t\t\t0xffff, 0xffff };\r\n\r\n\tprivate static int PosHf3[] = { 0, 0, 0, 0, 0, 0, 0, 2, 16, 218, 251, 0, 0 };\r\n\r\n\tprivate static final int STARTHF4 = 8;\r\n\r\n\tprivate static int DecHf4[] = { 0xff00, 0xffff, 0xffff, 0xffff, 0xffff,\r\n\t\t\t0xffff };\r\n\r\n\tprivate static int PosHf4[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0 };\r\n\r\n\tstatic int ShortLen1[] = { 1, 3, 4, 4, 5, 6, 7, 8, 8, 4, 4, 5, 6, 6, 4, 0 };\r\n\r\n\tstatic int ShortXor1[] = { 0, 0xa0, 0xd0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe,\r\n\t\t\t0xff, 0xc0, 0x80, 0x90, 0x98, 0x9c, 0xb0 };\r\n\r\n\tstatic int ShortLen2[] = { 2, 3, 3, 3, 4, 4, 5, 6, 6, 4, 4, 5, 6, 6, 4, 0 };\r\n\r\n\tstatic int ShortXor2[] = { 0, 0x40, 0x60, 0xa0, 0xd0, 0xe0, 0xf0, 0xf8,\r\n\t\t\t0xfc, 0xc0, 0x80, 0x90, 0x98, 0x9c, 0xb0 };\r\n\r\n\tprotected abstract void unpInitData(boolean solid);\r\n\r\n\tprotected void unpack15(boolean solid) throws IOException, RarException\r\n\t{\r\n\t\tif (suspended) {\r\n\t\t\tunpPtr = wrPtr;\r\n\t\t} else {\r\n\t\t\tunpInitData(solid);\r\n\t\t\toldUnpInitData(solid);\r\n\t\t\tunpReadBuf();\r\n\t\t\tif (!solid) {\r\n\t\t\t\tinitHuff();\r\n\t\t\t\tunpPtr = 0;\r\n\t\t\t} else {\r\n\t\t\t\tunpPtr = wrPtr;\r\n\t\t\t}\r\n\t\t\t--destUnpSize;\r\n\t\t}\r\n\t\tif (destUnpSize >= 0) {\r\n\t\t\tgetFlagsBuf();\r\n\t\t\tFlagsCnt = 8;\r\n\t\t}\r\n\r\n\t\twhile (destUnpSize >= 0) {\r\n\t\t\tunpPtr &= Compress.MAXWINMASK;\r\n\r\n\t\t\tif (inAddr > readTop - 30 && !unpReadBuf()) {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tif (((wrPtr - unpPtr) & Compress.MAXWINMASK) < 270\r\n\t\t\t\t\t&& wrPtr != unpPtr) {\r\n\t\t\t\toldUnpWriteBuf();\r\n\t\t\t\tif (suspended) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (StMode != 0) {\r\n\t\t\t\thuffDecode();\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\tif (--FlagsCnt < 0) {\r\n\t\t\t\tgetFlagsBuf();\r\n\t\t\t\tFlagsCnt = 7;\r\n\t\t\t}\r\n\r\n\t\t\tif ((FlagBuf & 0x80) != 0) {\r\n\t\t\t\tFlagBuf <<= 1;\r\n\t\t\t\tif (Nlzb > Nhfb) {\r\n\t\t\t\t\tlongLZ();\r\n\t\t\t\t} else {\r\n\t\t\t\t\thuffDecode();\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tFlagBuf <<= 1;\r\n\t\t\t\tif (--FlagsCnt < 0) {\r\n\t\t\t\t\tgetFlagsBuf();\r\n\t\t\t\t\tFlagsCnt = 7;\r\n\t\t\t\t}\r\n\t\t\t\tif ((FlagBuf & 0x80) != 0) {\r\n\t\t\t\t\tFlagBuf <<= 1;\r\n\t\t\t\t\tif (Nlzb > Nhfb) {\r\n\t\t\t\t\t\thuffDecode();\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tlongLZ();\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tFlagBuf <<= 1;\r\n\t\t\t\t\tshortLZ();\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\toldUnpWriteBuf();\r\n\t}\r\n\r\n\r\n\r\n\tprotected boolean unpReadBuf() throws IOException, RarException\r\n\t{\r\n\t\t  int dataSize=readTop-inAddr;\r\n\t\t  if (dataSize<0){\r\n\t\t    return(false);\r\n\t\t  }\r\n\t\t  if (inAddr>BitInput.MAX_SIZE/2) {\r\n\t\t    if (dataSize>0){\r\n\t\t      //memmove(InBuf,InBuf+InAddr,DataSize);\r\n//\t\t    \tfor (int i = 0; i < dataSize; i++) {\r\n//\t\t\t\t\tinBuf[i] = inBuf[inAddr + i];\r\n//\t\t\t\t}\r\n                System.arraycopy(inBuf, inAddr, inBuf, 0, dataSize);\r\n\t\t    }\r\n\t\t    inAddr=0;\r\n\t\t    readTop=dataSize;\r\n\t\t  }\r\n\t\t  else{\r\n\t\t    dataSize=readTop;\r\n\t\t  }\r\n\t\t  //int readCode=UnpIO->UnpRead(InBuf+DataSize,(BitInput::MAX_SIZE-DataSize)&~0xf);\r\n\t\t  int readCode=unpIO.unpRead(inBuf, dataSize, (BitInput.MAX_SIZE-dataSize)&~0xf);\r\n\t\t  if (readCode>0){\r\n\t\t    readTop+=readCode;\r\n\t\t  }\r\n\t\t  readBorder=readTop-30;\r\n\t\t  return(readCode!=-1);\r\n\t}\r\n\r\n\tprivate int getShortLen1(int pos)\r\n\t{\r\n\t\treturn pos == 1 ? Buf60 + 3 : ShortLen1[pos];\r\n\t}\r\n\r\n\tprivate int getShortLen2(int pos)\r\n\t{\r\n\t\treturn pos == 3 ? Buf60 + 3 : ShortLen2[pos];\r\n\t}\r\n\r\n\tprotected void shortLZ()\r\n\t{\r\n\t\tint Length, SaveLength;\r\n\t\tint LastDistance;\r\n\t\tint Distance;\r\n\t\tint DistancePlace;\r\n\t\tNumHuf = 0;\r\n\r\n\t\tint BitField = fgetbits();\r\n\t\tif (LCount == 2) {\r\n\t\t\tfaddbits(1);\r\n\t\t\tif (BitField >= 0x8000) {\r\n\t\t\t\toldCopyString(lastDist, lastLength);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tBitField <<= 1;\r\n\t\t\tLCount = 0;\r\n\t\t}\r\n\t\tBitField >>>= 8;\r\n\t\tif (AvrLn1 < 37) {\r\n\t\t\tfor (Length = 0;; Length++) {\r\n\t\t\t\tif (((BitField ^ ShortXor1[Length]) & (~(0xff >>> getShortLen1(Length)))) == 0) {\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tfaddbits(getShortLen1(Length));\r\n\t\t} else {\r\n\t\t\tfor (Length = 0;; Length++) {\r\n\t\t\t\tif (((BitField ^ ShortXor2[Length]) & (~(0xff >> getShortLen2(Length)))) == 0) {\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tfaddbits(getShortLen2(Length));\r\n\t\t}\r\n\r\n\t\tif (Length >= 9) {\r\n\t\t\tif (Length == 9) {\r\n\t\t\t\tLCount++;\r\n\t\t\t\toldCopyString(lastDist, lastLength);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tif (Length == 14) {\r\n\t\t\t\tLCount = 0;\r\n\t\t\t\tLength = decodeNum(fgetbits(), STARTL2, DecL2, PosL2) + 5;\r\n\t\t\t\tDistance = (fgetbits() >> 1) | 0x8000;\r\n\t\t\t\tfaddbits(15);\r\n\t\t\t\tlastLength = Length;\r\n\t\t\t\tlastDist = Distance;\r\n\t\t\t\toldCopyString(Distance, Length);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tLCount = 0;\r\n\t\t\tSaveLength = Length;\r\n\t\t\tDistance = oldDist[(oldDistPtr - (Length - 9)) & 3];\r\n\t\t\tLength = decodeNum(fgetbits(), STARTL1, DecL1, PosL1) + 2;\r\n\t\t\tif (Length == 0x101 && SaveLength == 10) {\r\n\t\t\t\tBuf60 ^= 1;\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tif (Distance > 256)\r\n\t\t\t\tLength++;\r\n\t\t\tif (Distance >= MaxDist3)\r\n\t\t\t\tLength++;\r\n\r\n\t\t\toldDist[oldDistPtr++] = Distance;\r\n\t\t\toldDistPtr = oldDistPtr & 3;\r\n\t\t\tlastLength = Length;\r\n\t\t\tlastDist = Distance;\r\n\t\t\toldCopyString(Distance, Length);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tLCount = 0;\r\n\t\tAvrLn1 += Length;\r\n\t\tAvrLn1 -= AvrLn1 >> 4;\r\n\r\n\t\tDistancePlace = decodeNum(fgetbits(), STARTHF2, DecHf2, PosHf2) & 0xff;\r\n\t\tDistance = ChSetA[DistancePlace];\r\n\t\tif (--DistancePlace != -1) {\r\n\t\t\tPlaceA[Distance]--;\r\n\t\t\tLastDistance = ChSetA[DistancePlace];\r\n\t\t\tPlaceA[LastDistance]++;\r\n\t\t\tChSetA[DistancePlace + 1] = LastDistance;\r\n\t\t\tChSetA[DistancePlace] = Distance;\r\n\t\t}\r\n\t\tLength += 2;\r\n\t\toldDist[oldDistPtr++] = ++Distance;\r\n\t\toldDistPtr = oldDistPtr & 3;\r\n\t\tlastLength = Length;\r\n\t\tlastDist = Distance;\r\n\t\toldCopyString(Distance, Length);\r\n\t}\r\n\r\n\tprotected void longLZ()\r\n\t{\r\n\t\tint Length;\r\n\t\tint Distance;\r\n\t\tint DistancePlace, NewDistancePlace;\r\n\t\tint OldAvr2, OldAvr3;\r\n\r\n\t\tNumHuf = 0;\r\n\t\tNlzb += 16;\r\n\t\tif (Nlzb > 0xff) {\r\n\t\t\tNlzb = 0x90;\r\n\t\t\tNhfb >>>= 1;\r\n\t\t}\r\n\t\tOldAvr2 = AvrLn2;\r\n\r\n\t\tint BitField = fgetbits();\r\n\t\tif (AvrLn2 >= 122) {\r\n\t\t\tLength = decodeNum(BitField, STARTL2, DecL2, PosL2);\r\n\t\t} else {\r\n\t\t\tif (AvrLn2 >= 64) {\r\n\t\t\t\tLength = decodeNum(BitField, STARTL1, DecL1, PosL1);\r\n\t\t\t} else {\r\n\t\t\t\tif (BitField < 0x100) {\r\n\t\t\t\t\tLength = BitField;\r\n\t\t\t\t\tfaddbits(16);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tfor (Length = 0; ((BitField << Length) & 0x8000) == 0; Length++) {\r\n\t\t\t\t\t\t;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tfaddbits(Length + 1);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tAvrLn2 += Length;\r\n\t\tAvrLn2 -= AvrLn2 >>> 5;\r\n\r\n\t\tBitField = fgetbits();\r\n\t\tif (AvrPlcB > 0x28ff) {\r\n\t\t\tDistancePlace = decodeNum(BitField, STARTHF2, DecHf2, PosHf2);\r\n\t\t} else {\r\n\t\t\tif (AvrPlcB > 0x6ff) {\r\n\t\t\t\tDistancePlace = decodeNum(BitField, STARTHF1, DecHf1, PosHf1);\r\n\t\t\t} else {\r\n\t\t\t\tDistancePlace = decodeNum(BitField, STARTHF0, DecHf0, PosHf0);\r\n\t\t\t}\r\n\t\t}\r\n\t\tAvrPlcB += DistancePlace;\r\n\t\tAvrPlcB -= AvrPlcB >> 8;\r\n\t\twhile (true) {\r\n\t\t\tDistance = ChSetB[DistancePlace & 0xff];\r\n\t\t\tNewDistancePlace = NToPlB[Distance++ & 0xff]++;\r\n\t\t\tif ((Distance & 0xff) == 0) {\r\n\t\t\t\tcorrHuff(ChSetB, NToPlB);\r\n\t\t\t} else {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tChSetB[DistancePlace] = ChSetB[NewDistancePlace];\r\n\t\tChSetB[NewDistancePlace] = Distance;\r\n\r\n\t\tDistance = ((Distance & 0xff00) | (fgetbits() >>> 8)) >>> 1;\r\n\t\tfaddbits(7);\r\n\r\n\t\tOldAvr3 = AvrLn3;\r\n\t\tif (Length != 1 && Length != 4) {\r\n\t\t\tif (Length == 0 && Distance <= MaxDist3) {\r\n\t\t\t\tAvrLn3++;\r\n\t\t\t\tAvrLn3 -= AvrLn3 >> 8;\r\n\t\t\t} else {\r\n\t\t\t\tif (AvrLn3 > 0) {\r\n\t\t\t\t\tAvrLn3--;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tLength += 3;\r\n\t\tif (Distance >= MaxDist3) {\r\n\t\t\tLength++;\r\n\t\t}\r\n\t\tif (Distance <= 256) {\r\n\t\t\tLength += 8;\r\n\t\t}\r\n\t\tif (OldAvr3 > 0xb0 || AvrPlc >= 0x2a00 && OldAvr2 < 0x40) {\r\n\t\t\tMaxDist3 = 0x7f00;\r\n\t\t} else {\r\n\t\t\tMaxDist3 = 0x2001;\r\n\t\t}\r\n\t\toldDist[oldDistPtr++] = Distance;\r\n\t\toldDistPtr = oldDistPtr & 3;\r\n\t\tlastLength = Length;\r\n\t\tlastDist = Distance;\r\n\t\toldCopyString(Distance, Length);\r\n\t}\r\n\r\n\tprotected void huffDecode()\r\n\t{\r\n\t\tint CurByte, NewBytePlace;\r\n\t\tint Length;\r\n\t\tint Distance;\r\n\t\tint BytePlace;\r\n\r\n\t\tint BitField = fgetbits();\r\n\r\n\t\tif (AvrPlc > 0x75ff) {\r\n\t\t\tBytePlace = decodeNum(BitField, STARTHF4, DecHf4, PosHf4);\r\n\t\t} else {\r\n\t\t\tif (AvrPlc > 0x5dff) {\r\n\t\t\t\tBytePlace = decodeNum(BitField, STARTHF3, DecHf3, PosHf3);\r\n\t\t\t} else {\r\n\t\t\t\tif (AvrPlc > 0x35ff) {\r\n\t\t\t\t\tBytePlace = decodeNum(BitField, STARTHF2, DecHf2, PosHf2);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tif (AvrPlc > 0x0dff) {\r\n\t\t\t\t\t\tBytePlace = decodeNum(BitField, STARTHF1, DecHf1,\r\n\t\t\t\t\t\t\t\tPosHf1);\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tBytePlace = decodeNum(BitField, STARTHF0, DecHf0,\r\n\t\t\t\t\t\t\t\tPosHf0);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tBytePlace &= 0xff;\r\n\t\tif (StMode != 0) {\r\n\t\t\tif (BytePlace == 0 && BitField > 0xfff) {\r\n\t\t\t\tBytePlace = 0x100;\r\n\t\t\t}\r\n\t\t\tif (--BytePlace == -1) {\r\n\t\t\t\tBitField = fgetbits();\r\n\t\t\t\tfaddbits(1);\r\n\t\t\t\tif ((BitField & 0x8000) != 0) {\r\n\t\t\t\t\tNumHuf = StMode = 0;\r\n\t\t\t\t\treturn;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tLength = (BitField & 0x4000) != 0 ? 4 : 3;\r\n\t\t\t\t\tfaddbits(1);\r\n\t\t\t\t\tDistance = decodeNum(fgetbits(), STARTHF2, DecHf2, PosHf2);\r\n\t\t\t\t\tDistance = (Distance << 5) | (fgetbits() >>> 11);\r\n\t\t\t\t\tfaddbits(5);\r\n\t\t\t\t\toldCopyString(Distance, Length);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tif (NumHuf++ >= 16 && FlagsCnt == 0) {\r\n\t\t\t\tStMode = 1;\r\n\t\t\t}\r\n\t\t}\r\n\t\tAvrPlc += BytePlace;\r\n\t\tAvrPlc -= AvrPlc >>> 8;\r\n\t\tNhfb += 16;\r\n\t\tif (Nhfb > 0xff) {\r\n\t\t\tNhfb = 0x90;\r\n\t\t\tNlzb >>>= 1;\r\n\t\t}\r\n\r\n\t\twindow[unpPtr++] = (byte) (ChSet[BytePlace] >>> 8);\r\n\t\t--destUnpSize;\r\n\r\n\t\twhile (true) {\r\n\t\t\tCurByte = ChSet[BytePlace];\r\n\t\t\tNewBytePlace = NToPl[CurByte++ & 0xff]++;\r\n\t\t\tif ((CurByte & 0xff) > 0xa1) {\r\n\t\t\t\tcorrHuff(ChSet, NToPl);\r\n\t\t\t} else {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tChSet[BytePlace] = ChSet[NewBytePlace];\r\n\t\tChSet[NewBytePlace] = CurByte;\r\n\t}\r\n\r\n\tprotected void getFlagsBuf()\r\n\t{\r\n\t\tint Flags, NewFlagsPlace;\r\n\t\tint FlagsPlace = decodeNum(fgetbits(), STARTHF2, DecHf2, PosHf2);\r\n\r\n\t\twhile (true) {\r\n\t\t\tFlags = ChSetC[FlagsPlace];\r\n\t\t\tFlagBuf = Flags >>> 8;\r\n\t\t\tNewFlagsPlace = NToPlC[Flags++ & 0xff]++;\r\n\t\t\tif ((Flags & 0xff) != 0) {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tcorrHuff(ChSetC, NToPlC);\r\n\t\t}\r\n\r\n\t\tChSetC[FlagsPlace] = ChSetC[NewFlagsPlace];\r\n\t\tChSetC[NewFlagsPlace] = Flags;\r\n\t}\r\n\r\n\tprotected void oldUnpInitData(boolean Solid)\r\n\t{\r\n\t\tif (!Solid ) {\r\n\t\t\tAvrPlcB = AvrLn1 = AvrLn2 = AvrLn3 = NumHuf = Buf60 = 0;\r\n\t\t\tAvrPlc = 0x3500;\r\n\t\t\tMaxDist3 = 0x2001;\r\n\t\t\tNhfb = Nlzb = 0x80;\r\n\t\t}\r\n\t\tFlagsCnt = 0;\r\n\t\tFlagBuf = 0;\r\n\t\tStMode = 0;\r\n\t\tLCount = 0;\r\n\t\treadTop = 0;\r\n\t}\r\n\r\n\tprotected void initHuff()\r\n\t{\r\n\t\tfor (int I = 0; I < 256; I++) {\r\n\t\t\tPlace[I] = PlaceA[I] = PlaceB[I] = I;\r\n\t\t\tPlaceC[I] = (~I + 1) & 0xff;\r\n\t\t\tChSet[I] = ChSetB[I] = I << 8;\r\n\t\t\tChSetA[I] = I;\r\n\t\t\tChSetC[I] = ((~I + 1) & 0xff) << 8;\r\n\t\t}\r\n\r\n\t\tArrays.fill(NToPl, 0);// memset(NToPl,0,sizeof(NToPl));\r\n\t\tArrays.fill(NToPlB, 0); // memset(NToPlB,0,sizeof(NToPlB));\r\n\t\tArrays.fill(NToPlC, 0); // memset(NToPlC,0,sizeof(NToPlC));\r\n\t\tcorrHuff(ChSetB, NToPlB);\r\n\t}\r\n\r\n\tprotected void corrHuff(int[] CharSet, int[] NumToPlace)\r\n\t{\r\n\t\tint I, J, pos = 0;\r\n\t\tfor (I = 7; I >= 0; I--) {\r\n\t\t\tfor (J = 0; J < 32; J++, pos++) {\r\n\t\t\t\tCharSet[pos] = ((CharSet[pos] & ~0xff) | I);// *CharSet=(*CharSet\r\n\t\t\t\t// & ~0xff) | I;\r\n\t\t\t}\r\n\t\t}\r\n\t\tArrays.fill(NumToPlace, 0);// memset(NumToPlace,0,sizeof(NToPl));\r\n\t\tfor (I = 6; I >= 0; I--) {\r\n\t\t\tNumToPlace[I] = (7 - I) * 32;\r\n\t\t}\r\n\t}\r\n\r\n\tprotected void oldCopyString(int Distance, int Length)\r\n\t{\r\n\t\tdestUnpSize -= Length;\r\n\t\twhile ((Length--) != 0) {\r\n\t\t\twindow[unpPtr] = window[(unpPtr - Distance) & Compress.MAXWINMASK];\r\n\t\t\tunpPtr = (unpPtr + 1) & Compress.MAXWINMASK;\r\n\t\t}\r\n\t}\r\n\r\n\tprotected int decodeNum(int Num, int StartPos, int[] DecTab, int[] PosTab)\r\n\t{\r\n\t\tint I;\r\n\t\tfor (Num &= 0xfff0, I = 0; DecTab[I] <= Num; I++) {\r\n\t\t\tStartPos++;\r\n\t\t}\r\n\t\tfaddbits(StartPos);\r\n\t\treturn (((Num - (I != 0 ? DecTab[I - 1] : 0)) >>> (16 - StartPos)) + PosTab[StartPos]);\r\n\t}\r\n\r\n\tprotected void oldUnpWriteBuf() throws IOException\r\n\t{\r\n\t\tif (unpPtr != wrPtr) {\r\n\t\t\tunpSomeRead = true;\r\n\t\t}\r\n\t\tif (unpPtr < wrPtr) {\r\n\t\t\tunpIO.unpWrite(window, wrPtr, -wrPtr & Compress.MAXWINMASK);\r\n\t\t\tunpIO.unpWrite(window, 0, unpPtr);\r\n\t\t\tunpAllBuf = true;\r\n\t\t} else {\r\n\t\t\tunpIO.unpWrite(window, wrPtr, unpPtr - wrPtr);\r\n\t\t}\r\n\t\twrPtr = unpPtr;\r\n\t}\r\n\r\n\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/Unpack20.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 21.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack;\r\n\r\nimport java.io.IOException;\r\nimport java.util.Arrays;\r\n\r\nimport com.github.junrar.exception.RarException;\r\nimport com.github.junrar.unpack.decode.AudioVariables;\r\nimport com.github.junrar.unpack.decode.BitDecode;\r\nimport com.github.junrar.unpack.decode.Compress;\r\nimport com.github.junrar.unpack.decode.Decode;\r\nimport com.github.junrar.unpack.decode.DistDecode;\r\nimport com.github.junrar.unpack.decode.LitDecode;\r\nimport com.github.junrar.unpack.decode.LowDistDecode;\r\nimport com.github.junrar.unpack.decode.MultDecode;\r\nimport com.github.junrar.unpack.decode.RepDecode;\r\n\r\n\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic abstract class Unpack20 extends Unpack15\r\n{\r\n\r\n\tprotected MultDecode[] MD = new MultDecode[4];\r\n\r\n\tprotected byte[] UnpOldTable20 = new byte[Compress.MC20 * 4];\r\n\r\n\tprotected int UnpAudioBlock, UnpChannels, UnpCurChannel, UnpChannelDelta;\r\n\r\n\tprotected AudioVariables[] AudV = new AudioVariables[4];\r\n\r\n\tprotected LitDecode LD = new LitDecode();\r\n\r\n\tprotected DistDecode DD = new DistDecode();\r\n\r\n\tprotected LowDistDecode LDD = new LowDistDecode();\r\n\r\n\tprotected RepDecode RD = new RepDecode();\r\n\r\n\tprotected BitDecode BD = new BitDecode();\r\n\r\n\tpublic static final int[] LDecode = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12,\r\n\t\t\t14, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192,\r\n\t\t\t224 };\r\n\r\n\tpublic static final byte[] LBits = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2,\r\n\t\t\t2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5 };\r\n\r\n\tpublic static final int[] DDecode = { 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32,\r\n\t\t\t48, 64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072,\r\n\t\t\t4096, 6144, 8192, 12288, 16384, 24576, 32768, 49152, 65536, 98304,\r\n\t\t\t131072, 196608, 262144, 327680, 393216, 458752, 524288, 589824,\r\n\t\t\t655360, 720896, 786432, 851968, 917504, 983040 };\r\n\r\n\tpublic static final int[] DBits = { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5,\r\n\t\t\t5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14,\r\n\t\t\t15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 };\r\n\r\n\tpublic static final int[] SDDecode = { 0, 4, 8, 16, 32, 64, 128, 192 };\r\n\r\n\tpublic static final int[] SDBits = { 2, 2, 3, 4, 5, 6, 6, 6 };\r\n\r\n\tprotected void unpack20(boolean solid) throws IOException, RarException\r\n\t{\r\n\r\n\t\tint Bits;\r\n\r\n\t\tif (suspended) {\r\n\t\t\tunpPtr = wrPtr;\r\n\t\t} else {\r\n\t\t\tunpInitData(solid);\r\n\t\t\tif (!unpReadBuf()) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tif (!solid) {\r\n\t\t\t\tif (!ReadTables20()) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t--destUnpSize;\r\n\t\t}\r\n\r\n\t\twhile (destUnpSize >= 0) {\r\n\t\t\tunpPtr &= Compress.MAXWINMASK;\r\n\r\n\t\t\tif (inAddr > readTop - 30)\r\n\t\t\t\tif (!unpReadBuf())\r\n\t\t\t\t\tbreak;\r\n\t\t\tif (((wrPtr - unpPtr) & Compress.MAXWINMASK) < 270\r\n\t\t\t\t\t&& wrPtr != unpPtr) {\r\n\t\t\t\toldUnpWriteBuf();\r\n\t\t\t\tif (suspended)\r\n\t\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tif (UnpAudioBlock != 0) {\r\n\t\t\t\tint AudioNumber = decodeNumber(MD[UnpCurChannel]);\r\n\r\n\t\t\t\tif (AudioNumber == 256) {\r\n\t\t\t\t\tif (!ReadTables20())\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\t\t\t\twindow[unpPtr++] = DecodeAudio(AudioNumber);\r\n\t\t\t\tif (++UnpCurChannel == UnpChannels)\r\n\t\t\t\t\tUnpCurChannel = 0;\r\n\t\t\t\t--destUnpSize;\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\tint Number = decodeNumber(LD);\r\n\t\t\tif (Number < 256) {\r\n\t\t\t\twindow[unpPtr++] = (byte) Number;\r\n\t\t\t\t--destUnpSize;\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t\tif (Number > 269) {\r\n\t\t\t\tint Length = LDecode[Number -= 270] + 3;\r\n\t\t\t\tif ((Bits = LBits[Number]) > 0) {\r\n\t\t\t\t\tLength += getbits() >>> (16 - Bits);\r\n\t\t\t\t\taddbits(Bits);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tint DistNumber = decodeNumber(DD);\r\n\t\t\t\tint Distance = DDecode[DistNumber] + 1;\r\n\t\t\t\tif ((Bits = DBits[DistNumber]) > 0) {\r\n\t\t\t\t\tDistance += getbits() >>> (16 - Bits);\r\n\t\t\t\t\taddbits(Bits);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (Distance >= 0x2000) {\r\n\t\t\t\t\tLength++;\r\n\t\t\t\t\tif (Distance >= 0x40000L)\r\n\t\t\t\t\t\tLength++;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tCopyString20(Length, Distance);\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t\tif (Number == 269) {\r\n\t\t\t\tif (!ReadTables20())\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t\tif (Number == 256) {\r\n\t\t\t\tCopyString20(lastLength, lastDist);\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t\tif (Number < 261) {\r\n\t\t\t\tint Distance = oldDist[(oldDistPtr - (Number - 256)) & 3];\r\n\t\t\t\tint LengthNumber = decodeNumber(RD);\r\n\t\t\t\tint Length = LDecode[LengthNumber] + 2;\r\n\t\t\t\tif ((Bits = LBits[LengthNumber]) > 0) {\r\n\t\t\t\t\tLength += getbits() >>> (16 - Bits);\r\n\t\t\t\t\taddbits(Bits);\r\n\t\t\t\t}\r\n\t\t\t\tif (Distance >= 0x101) {\r\n\t\t\t\t\tLength++;\r\n\t\t\t\t\tif (Distance >= 0x2000) {\r\n\t\t\t\t\t\tLength++;\r\n\t\t\t\t\t\tif (Distance >= 0x40000)\r\n\t\t\t\t\t\t\tLength++;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tCopyString20(Length, Distance);\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t\tif (Number < 270) {\r\n\t\t\t\tint Distance = SDDecode[Number -= 261] + 1;\r\n\t\t\t\tif ((Bits = SDBits[Number]) > 0) {\r\n\t\t\t\t\tDistance += getbits() >>> (16 - Bits);\r\n\t\t\t\t\taddbits(Bits);\r\n\t\t\t\t}\r\n\t\t\t\tCopyString20(2, Distance);\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t}\r\n\t\tReadLastTables();\r\n\t\toldUnpWriteBuf();\r\n\r\n\t}\r\n\r\n\tprotected void CopyString20(int Length, int Distance)\r\n\t{\r\n\t\tlastDist = oldDist[oldDistPtr++ & 3] = Distance;\r\n\t\tlastLength = Length;\r\n\t\tdestUnpSize -= Length;\r\n\r\n\t\tint DestPtr = unpPtr - Distance;\r\n\t\tif (DestPtr < Compress.MAXWINSIZE - 300\r\n\t\t\t\t&& unpPtr < Compress.MAXWINSIZE - 300) {\r\n\t\t\twindow[unpPtr++] = window[DestPtr++];\r\n\t\t\twindow[unpPtr++] = window[DestPtr++];\r\n\t\t\twhile (Length > 2) {\r\n\t\t\t\tLength--;\r\n\t\t\t\twindow[unpPtr++] = window[DestPtr++];\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\twhile ((Length--) != 0) {\r\n\t\t\t\twindow[unpPtr] = window[DestPtr++ & Compress.MAXWINMASK];\r\n\t\t\t\tunpPtr = (unpPtr + 1) & Compress.MAXWINMASK;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tprotected void makeDecodeTables(byte[] lenTab, int offset, Decode dec,\r\n\t\t\tint size)\r\n\t{\r\n\t\tint[] lenCount = new int[16];\r\n\t\tint[] tmpPos = new int[16];\r\n\t\tint i;\r\n\t\tlong M, N;\r\n\r\n\t\tArrays.fill(lenCount, 0);// memset(LenCount,0,sizeof(LenCount));\r\n\r\n\t\tArrays.fill(dec.getDecodeNum(), 0);// memset(Dec->DecodeNum,0,Size*sizeof(*Dec->DecodeNum));\r\n\r\n\t\tfor (i = 0; i < size; i++) {\r\n\t\t\tlenCount[(int) (lenTab[offset + i] & 0xF)]++;\r\n\t\t}\r\n\t\tlenCount[0] = 0;\r\n\t\tfor (tmpPos[0] = 0, dec.getDecodePos()[0] = 0, dec.getDecodeLen()[0] = 0, N = 0, i = 1; i < 16; i++) {\r\n\t\t\tN = 2 * (N + lenCount[i]);\r\n\t\t\tM = N << (15 - i);\r\n\t\t\tif (M > 0xFFFF) {\r\n\t\t\t\tM = 0xFFFF;\r\n\t\t\t}\r\n\t\t\tdec.getDecodeLen()[i] = (int) M;\r\n\t\t\ttmpPos[i] = dec.getDecodePos()[i] = dec.getDecodePos()[i - 1]\r\n\t\t\t\t\t+ lenCount[i - 1];\r\n\t\t}\r\n\r\n\t\tfor (i = 0; i < size; i++) {\r\n\t\t\tif (lenTab[offset + i] != 0) {\r\n\t\t\t\tdec.getDecodeNum()[tmpPos[lenTab[offset + i] & 0xF]++] = i;\r\n\t\t\t}\r\n\t\t}\r\n\t\tdec.setMaxNum(size);\r\n\t}\r\n\r\n\tprotected int decodeNumber(Decode dec)\r\n\t{\r\n\t\tint bits;\r\n\t\tlong bitField = getbits() & 0xfffe;\r\n//        if (bitField < dec.getDecodeLen()[8]) {\r\n//\t\t\tif (bitField < dec.getDecodeLen()[4]) {\r\n//\t\t\t\tif (bitField < dec.getDecodeLen()[2]) {\r\n//\t\t\t\t\tif (bitField < dec.getDecodeLen()[1]) {\r\n//\t\t\t\t\t\tbits = 1;\r\n//\t\t\t\t\t} else {\r\n//\t\t\t\t\t\tbits = 2;\r\n//\t\t\t\t\t}\r\n//\t\t\t\t} else {\r\n//\t\t\t\t\tif (bitField < dec.getDecodeLen()[3]) {\r\n//\t\t\t\t\t\tbits = 3;\r\n//\t\t\t\t\t} else {\r\n//\t\t\t\t\t\tbits = 4;\r\n//\t\t\t\t\t}\r\n//\t\t\t\t}\r\n//\t\t\t} else {\r\n//\t\t\t\tif (bitField < dec.getDecodeLen()[6]) {\r\n//\t\t\t\t\tif (bitField < dec.getDecodeLen()[5])\r\n//\t\t\t\t\t\tbits = 5;\r\n//\t\t\t\t\telse\r\n//\t\t\t\t\t\tbits = 6;\r\n//\t\t\t\t} else {\r\n//\t\t\t\t\tif (bitField < dec.getDecodeLen()[7]) {\r\n//\t\t\t\t\t\tbits = 7;\r\n//\t\t\t\t\t} else {\r\n//\t\t\t\t\t\tbits = 8;\r\n//\t\t\t\t\t}\r\n//\t\t\t\t}\r\n//\t\t\t}\r\n//\t\t} else {\r\n//\t\t\tif (bitField < dec.getDecodeLen()[12]) {\r\n//\t\t\t\tif (bitField < dec.getDecodeLen()[10])\r\n//\t\t\t\t\tif (bitField < dec.getDecodeLen()[9])\r\n//\t\t\t\t\t\tbits = 9;\r\n//\t\t\t\t\telse\r\n//\t\t\t\t\t\tbits = 10;\r\n//\t\t\t\telse if (bitField < dec.getDecodeLen()[11])\r\n//\t\t\t\t\tbits = 11;\r\n//\t\t\t\telse\r\n//\t\t\t\t\tbits = 12;\r\n//\t\t\t} else {\r\n//\t\t\t\tif (bitField < dec.getDecodeLen()[14]) {\r\n//\t\t\t\t\tif (bitField < dec.getDecodeLen()[13]) {\r\n//\t\t\t\t\t\tbits = 13;\r\n//\t\t\t\t\t} else {\r\n//\t\t\t\t\t\tbits = 14;\r\n//\t\t\t\t\t}\r\n//\t\t\t\t} else {\r\n//\t\t\t\t\tbits = 15;\r\n//\t\t\t\t}\r\n//\t\t\t}\r\n//\t\t}\r\n//\t\taddbits(bits);\r\n//\t\tint N = dec.getDecodePos()[bits]\r\n//\t\t\t\t+ (((int) bitField - dec.getDecodeLen()[bits - 1]) >>> (16 - bits));\r\n//\t\tif (N >= dec.getMaxNum()) {\r\n//\t\t\tN = 0;\r\n//\t\t}\r\n//\t\treturn (dec.getDecodeNum()[N]);\r\n        int[] decodeLen = dec.getDecodeLen();\r\n        if (bitField < decodeLen[8]) {\r\n\t\t\tif (bitField < decodeLen[4]) {\r\n\t\t\t\tif (bitField < decodeLen[2]) {\r\n\t\t\t\t\tif (bitField < decodeLen[1]) {\r\n\t\t\t\t\t\tbits = 1;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tbits = 2;\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tif (bitField < decodeLen[3]) {\r\n\t\t\t\t\t\tbits = 3;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tbits = 4;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (bitField < decodeLen[6]) {\r\n\t\t\t\t\tif (bitField < decodeLen[5])\r\n\t\t\t\t\t\tbits = 5;\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\tbits = 6;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tif (bitField < decodeLen[7]) {\r\n\t\t\t\t\t\tbits = 7;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tbits = 8;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tif (bitField < decodeLen[12]) {\r\n\t\t\t\tif (bitField < decodeLen[10])\r\n\t\t\t\t\tif (bitField < decodeLen[9])\r\n\t\t\t\t\t\tbits = 9;\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\tbits = 10;\r\n\t\t\t\telse if (bitField < decodeLen[11])\r\n\t\t\t\t\tbits = 11;\r\n\t\t\t\telse\r\n\t\t\t\t\tbits = 12;\r\n\t\t\t} else {\r\n\t\t\t\tif (bitField < decodeLen[14]) {\r\n\t\t\t\t\tif (bitField < decodeLen[13]) {\r\n\t\t\t\t\t\tbits = 13;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tbits = 14;\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tbits = 15;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\taddbits(bits);\r\n\t\tint N = dec.getDecodePos()[bits]\r\n\t\t\t\t+ (((int) bitField - decodeLen[bits - 1]) >>> (16 - bits));\r\n\t\tif (N >= dec.getMaxNum()) {\r\n\t\t\tN = 0;\r\n\t\t}\r\n\t\treturn (dec.getDecodeNum()[N]);\r\n\t}\r\n\r\n\tprotected boolean ReadTables20() throws IOException, RarException\r\n\t{\r\n\t\tbyte[] BitLength = new byte[Compress.BC20];\r\n\t\tbyte[] Table = new byte[Compress.MC20 * 4];\r\n\t\tint TableSize, N, I;\r\n\t\tif (inAddr > readTop - 25) {\r\n\t\t\tif (!unpReadBuf()) {\r\n\t\t\t\treturn (false);\r\n\t\t\t}\r\n\t\t}\r\n\t\tint BitField = getbits();\r\n\t\tUnpAudioBlock = (BitField & 0x8000);\r\n\r\n\t\tif (0 == (BitField & 0x4000)) {\r\n\t\t\t// memset(UnpOldTable20,0,sizeof(UnpOldTable20));\r\n\t\t\tArrays.fill(UnpOldTable20, (byte) 0);\r\n\t\t}\r\n\t\taddbits(2);\r\n\r\n\t\tif (UnpAudioBlock != 0) {\r\n\t\t\tUnpChannels = ((BitField >>> 12) & 3) + 1;\r\n\t\t\tif (UnpCurChannel >= UnpChannels) {\r\n\t\t\t\tUnpCurChannel = 0;\r\n\t\t\t}\r\n\t\t\taddbits(2);\r\n\t\t\tTableSize = Compress.MC20 * UnpChannels;\r\n\t\t} else {\r\n\t\t\tTableSize = Compress.NC20 + Compress.DC20 + Compress.RC20;\r\n\t\t}\r\n\t\tfor (I = 0; I < Compress.BC20; I++) {\r\n\t\t\tBitLength[I] = (byte) (getbits() >>> 12);\r\n\t\t\taddbits(4);\r\n\t\t}\r\n\t\tmakeDecodeTables(BitLength, 0, BD, Compress.BC20);\r\n\t\tI = 0;\r\n\t\twhile (I < TableSize) {\r\n\t\t\tif (inAddr > readTop - 5) {\r\n\t\t\t\tif (!unpReadBuf()) {\r\n\t\t\t\t\treturn (false);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tint Number = decodeNumber(BD);\r\n\t\t\tif (Number < 16) {\r\n\t\t\t\tTable[I] = (byte) ((Number + UnpOldTable20[I]) & 0xf);\r\n\t\t\t\tI++;\r\n\t\t\t} else if (Number == 16) {\r\n\t\t\t\tN = (getbits() >>> 14) + 3;\r\n\t\t\t\taddbits(2);\r\n\t\t\t\twhile (N-- > 0 && I < TableSize) {\r\n\t\t\t\t\tTable[I] = Table[I - 1];\r\n\t\t\t\t\tI++;\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (Number == 17) {\r\n\t\t\t\t\tN = (getbits() >>> 13) + 3;\r\n\t\t\t\t\taddbits(3);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tN = (getbits() >>> 9) + 11;\r\n\t\t\t\t\taddbits(7);\r\n\t\t\t\t}\r\n\t\t\t\twhile (N-- > 0 && I < TableSize)\r\n\t\t\t\t\tTable[I++] = 0;\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (inAddr > readTop) {\r\n\t\t\treturn (true);\r\n\t\t}\r\n\t\tif (UnpAudioBlock != 0)\r\n\t\t\tfor (I = 0; I < UnpChannels; I++)\r\n\t\t\t\tmakeDecodeTables(Table, I * Compress.MC20, MD[I], Compress.MC20);\r\n\t\telse {\r\n\t\t\tmakeDecodeTables(Table, 0, LD, Compress.NC20);\r\n\t\t\tmakeDecodeTables(Table, Compress.NC20, DD, Compress.DC20);\r\n\t\t\tmakeDecodeTables(Table, Compress.NC20 + Compress.DC20, RD,\r\n\t\t\t\t\tCompress.RC20);\r\n\t\t}\r\n\t\t// memcpy(UnpOldTable20,Table,sizeof(UnpOldTable20));\r\n\t\tfor (int i = 0; i < UnpOldTable20.length; i++) {\r\n\t\t\tUnpOldTable20[i] = Table[i];\r\n\t\t}\r\n\t\treturn (true);\r\n\t}\r\n\r\n\tprotected void unpInitData20(boolean Solid)\r\n\t{\r\n\t\tif (!Solid) {\r\n\t\t\tUnpChannelDelta = UnpCurChannel = 0;\r\n\t\t\tUnpChannels = 1;\r\n\t\t\t// memset(AudV,0,sizeof(AudV));\r\n\t\t\tArrays.fill(AudV, new AudioVariables());\r\n\t\t\t// memset(UnpOldTable20,0,sizeof(UnpOldTable20));\r\n\t\t\tArrays.fill(UnpOldTable20, (byte) 0);\r\n\t\t}\r\n\t}\r\n\r\n\tprotected void ReadLastTables() throws IOException, RarException\r\n\t{\r\n\t\tif (readTop >= inAddr + 5) {\r\n\t\t\tif (UnpAudioBlock != 0) {\r\n\t\t\t\tif (decodeNumber(MD[UnpCurChannel]) == 256) {\r\n\t\t\t\t\tReadTables20();\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (decodeNumber(LD) == 269) {\r\n\t\t\t\t\tReadTables20();\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tprotected byte DecodeAudio(int Delta)\r\n\t{\r\n\t\tAudioVariables v = AudV[UnpCurChannel];\r\n\t\tv.setByteCount(v.getByteCount() + 1);\r\n\t\tv.setD4(v.getD3());\r\n\t\tv.setD3(v.getD2());// ->D3=V->D2;\r\n\t\tv.setD2(v.getLastDelta() - v.getD1());// ->D2=V->LastDelta-V->D1;\r\n\t\tv.setD1(v.getLastDelta());// V->D1=V->LastDelta;\r\n\t\t// int PCh=8*V->LastChar+V->K1*V->D1 +V->K2*V->D2 +V->K3*V->D3\r\n\t\t// +V->K4*V->D4+ V->K5*UnpChannelDelta;\r\n\t\tint PCh = 8 * v.getLastChar() + v.getK1() * v.getD1();\r\n\t\tPCh += v.getK2() * v.getD2() + v.getK3() * v.getD3();\r\n\t\tPCh += v.getK4() * v.getD4() + v.getK5() * UnpChannelDelta;\r\n\t\tPCh = (PCh >>> 3) & 0xFF;\r\n\r\n\t\tint Ch = PCh - Delta;\r\n\r\n\t\tint D = ((byte) Delta) << 3;\r\n\r\n\t\tv.getDif()[0] += Math.abs(D);// V->Dif[0]+=abs(D);\r\n\t\tv.getDif()[1] += Math.abs(D - v.getD1());// V->Dif[1]+=abs(D-V->D1);\r\n\t\tv.getDif()[2] += Math.abs(D + v.getD1());// V->Dif[2]+=abs(D+V->D1);\r\n\t\tv.getDif()[3] += Math.abs(D - v.getD2());// V->Dif[3]+=abs(D-V->D2);\r\n\t\tv.getDif()[4] += Math.abs(D + v.getD2());// V->Dif[4]+=abs(D+V->D2);\r\n\t\tv.getDif()[5] += Math.abs(D - v.getD3());// V->Dif[5]+=abs(D-V->D3);\r\n\t\tv.getDif()[6] += Math.abs(D + v.getD3());// V->Dif[6]+=abs(D+V->D3);\r\n\t\tv.getDif()[7] += Math.abs(D - v.getD4());// V->Dif[7]+=abs(D-V->D4);\r\n\t\tv.getDif()[8] += Math.abs(D + v.getD4());// V->Dif[8]+=abs(D+V->D4);\r\n\t\tv.getDif()[9] += Math.abs(D - UnpChannelDelta);// V->Dif[9]+=abs(D-UnpChannelDelta);\r\n\t\tv.getDif()[10] += Math.abs(D + UnpChannelDelta);// V->Dif[10]+=abs(D+UnpChannelDelta);\r\n\r\n\t\tv.setLastDelta((byte) (Ch - v.getLastChar()));\r\n\t\tUnpChannelDelta = v.getLastDelta();\r\n\t\tv.setLastChar(Ch);// V->LastChar=Ch;\r\n\r\n\t\tif ((v.getByteCount() & 0x1F) == 0) {\r\n\t\t\tint MinDif = v.getDif()[0], NumMinDif = 0;\r\n\t\t\tv.getDif()[0] = 0;// ->Dif[0]=0;\r\n\t\t\tfor (int I = 1; I < v.getDif().length; I++) {\r\n\t\t\t\tif (v.getDif()[I] < MinDif) {\r\n\t\t\t\t\tMinDif = v.getDif()[I];\r\n\t\t\t\t\tNumMinDif = I;\r\n\t\t\t\t}\r\n\t\t\t\tv.getDif()[I] = 0;\r\n\t\t\t}\r\n\t\t\tswitch (NumMinDif) {\r\n\t\t\tcase 1:\r\n\t\t\t\tif (v.getK1() >= -16) {\r\n\t\t\t\t\tv.setK1(v.getK1() - 1);// V->K1--;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase 2:\r\n\t\t\t\tif (v.getK1() < 16) {\r\n\t\t\t\t\tv.setK1(v.getK1() + 1);// V->K1++;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase 3:\r\n\t\t\t\tif (v.getK2() >= -16) {\r\n\t\t\t\t\tv.setK2(v.getK2() - 1);// V->K2--;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase 4:\r\n\t\t\t\tif (v.getK2() < 16) {\r\n\t\t\t\t\tv.setK2(v.getK2() + 1);// V->K2++;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase 5:\r\n\t\t\t\tif (v.getK3() >= -16) {\r\n\t\t\t\t\tv.setK3(v.getK3() - 1);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase 6:\r\n\t\t\t\tif (v.getK3() < 16) {\r\n\t\t\t\t\tv.setK3(v.getK3() + 1);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase 7:\r\n\t\t\t\tif (v.getK4() >= -16) {\r\n\t\t\t\t\tv.setK4(v.getK4() - 1);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase 8:\r\n\t\t\t\tif (v.getK4() < 16) {\r\n\t\t\t\t\tv.setK4(v.getK4() + 1);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase 9:\r\n\t\t\t\tif (v.getK5() >= -16) {\r\n\t\t\t\t\tv.setK5(v.getK5() - 1);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase 10:\r\n\t\t\t\tif (v.getK5() < 16) {\r\n\t\t\t\t\tv.setK5(v.getK5() + 1);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn ((byte) Ch);\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/UnpackFilter.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 01.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack;\r\n\r\nimport com.github.junrar.unpack.vm.VMPreparedProgram;\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class UnpackFilter {\r\n\r\n\tprivate int BlockStart;\r\n\r\n\tprivate int BlockLength;\r\n\r\n\tprivate int ExecCount;\r\n\r\n\tprivate boolean NextWindow;\r\n\r\n\t// position of parent filter in Filters array used as prototype for filter\r\n\t// in PrgStack array. Not defined for filters in Filters array.\r\n\tprivate int ParentFilter;\r\n\r\n\tprivate VMPreparedProgram Prg  = new VMPreparedProgram();\r\n\r\n\tpublic int getBlockLength() {\r\n\t\treturn BlockLength;\r\n\t}\r\n\r\n\tpublic void setBlockLength(int blockLength) {\r\n\t\tBlockLength = blockLength;\r\n\t}\r\n\r\n\tpublic int getBlockStart() {\r\n\t\treturn BlockStart;\r\n\t}\r\n\r\n\tpublic void setBlockStart(int blockStart) {\r\n\t\tBlockStart = blockStart;\r\n\t}\r\n\r\n\tpublic int getExecCount() {\r\n\t\treturn ExecCount;\r\n\t}\r\n\r\n\tpublic void setExecCount(int execCount) {\r\n\t\tExecCount = execCount;\r\n\t}\r\n\r\n\tpublic boolean isNextWindow() {\r\n\t\treturn NextWindow;\r\n\t}\r\n\r\n\tpublic void setNextWindow(boolean nextWindow) {\r\n\t\tNextWindow = nextWindow;\r\n\t}\r\n\r\n\tpublic int getParentFilter() {\r\n\t\treturn ParentFilter;\r\n\t}\r\n\r\n\tpublic void setParentFilter(int parentFilter) {\r\n\t\tParentFilter = parentFilter;\r\n\t}\r\n\r\n\tpublic VMPreparedProgram getPrg() {\r\n\t\treturn Prg;\r\n\t}\r\n\r\n\tpublic void setPrg(VMPreparedProgram prg) {\r\n\t\tPrg = prg;\r\n\t}\r\n\r\n\t\r\n\t\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/decode/AudioVariables.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 01.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.decode;\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class AudioVariables {\r\n\tint k1, k2, k3, k4, k5;\r\n\r\n\tint d1, d2, d3, d4;\r\n\r\n\tint lastDelta;\r\n\r\n\tint dif[] = new int[11];\r\n\r\n\tint byteCount;\r\n\r\n\tint lastChar;\r\n\r\n\tpublic int getByteCount() {\r\n\t\treturn byteCount;\r\n\t}\r\n\r\n\tpublic void setByteCount(int byteCount) {\r\n\t\tthis.byteCount = byteCount;\r\n\t}\r\n\r\n\tpublic int getD1() {\r\n\t\treturn d1;\r\n\t}\r\n\r\n\tpublic void setD1(int d1) {\r\n\t\tthis.d1 = d1;\r\n\t}\r\n\r\n\tpublic int getD2() {\r\n\t\treturn d2;\r\n\t}\r\n\r\n\tpublic void setD2(int d2) {\r\n\t\tthis.d2 = d2;\r\n\t}\r\n\r\n\tpublic int getD3() {\r\n\t\treturn d3;\r\n\t}\r\n\r\n\tpublic void setD3(int d3) {\r\n\t\tthis.d3 = d3;\r\n\t}\r\n\r\n\tpublic int getD4() {\r\n\t\treturn d4;\r\n\t}\r\n\r\n\tpublic void setD4(int d4) {\r\n\t\tthis.d4 = d4;\r\n\t}\r\n\r\n\tpublic int[] getDif() {\r\n\t\treturn dif;\r\n\t}\r\n\r\n\tpublic void setDif(int[] dif) {\r\n\t\tthis.dif = dif;\r\n\t}\r\n\r\n\tpublic int getK1() {\r\n\t\treturn k1;\r\n\t}\r\n\r\n\tpublic void setK1(int k1) {\r\n\t\tthis.k1 = k1;\r\n\t}\r\n\r\n\tpublic int getK2() {\r\n\t\treturn k2;\r\n\t}\r\n\r\n\tpublic void setK2(int k2) {\r\n\t\tthis.k2 = k2;\r\n\t}\r\n\r\n\tpublic int getK3() {\r\n\t\treturn k3;\r\n\t}\r\n\r\n\tpublic void setK3(int k3) {\r\n\t\tthis.k3 = k3;\r\n\t}\r\n\r\n\tpublic int getK4() {\r\n\t\treturn k4;\r\n\t}\r\n\r\n\tpublic void setK4(int k4) {\r\n\t\tthis.k4 = k4;\r\n\t}\r\n\r\n\tpublic int getK5() {\r\n\t\treturn k5;\r\n\t}\r\n\r\n\tpublic void setK5(int k5) {\r\n\t\tthis.k5 = k5;\r\n\t}\r\n\r\n\tpublic int getLastChar() {\r\n\t\treturn lastChar;\r\n\t}\r\n\r\n\tpublic void setLastChar(int lastChar) {\r\n\t\tthis.lastChar = lastChar;\r\n\t}\r\n\r\n\tpublic int getLastDelta() {\r\n\t\treturn lastDelta;\r\n\t}\r\n\r\n\tpublic void setLastDelta(int lastDelta) {\r\n\t\tthis.lastDelta = lastDelta;\r\n\t}\r\n\r\n\t\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/decode/BitDecode.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 01.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.decode;\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class BitDecode extends Decode\r\n{\r\n\t/**\r\n\t * \r\n\t */\r\n\tpublic BitDecode()\r\n\t{\r\n\t\tdecodeNum = new int[Compress.BC];\r\n\t}\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/decode/CodeType.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 01.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.decode;\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic enum CodeType {\r\n\tCODE_HUFFMAN,CODE_LZ,CODE_LZ2,CODE_REPEATLZ,CODE_CACHELZ,\r\n    CODE_STARTFILE,CODE_ENDFILE,CODE_VM,CODE_VMDATA;\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/decode/Compress.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 01.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.decode;\r\n\r\n/**\r\n * DOCUMENT ME\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class Compress {\r\n\tpublic static final int CODEBUFSIZE   \t\t= 0x4000;\r\n\tpublic static final int MAXWINSIZE    \t\t= 0x400000;\r\n\tpublic static final int MAXWINMASK      \t= (MAXWINSIZE-1);\r\n\r\n\tpublic static final int LOW_DIST_REP_COUNT \t= 16;\r\n\r\n\tpublic static final int NC \t\t\t\t\t= 299;  /* alphabet = {0, 1, 2, ..., NC - 1} */\r\n\tpublic static final int DC  \t\t\t\t= 60;\r\n\tpublic static final int LDC \t\t\t\t= 17;\r\n\tpublic static final int RC  \t\t\t\t= 28;\r\n\tpublic static final int HUFF_TABLE_SIZE \t= (NC+DC+RC+LDC);\r\n\tpublic static final int BC  \t\t\t\t= 20;\r\n\r\n\tpublic static final int NC20 \t\t\t\t= 298;  /* alphabet = {0, 1, 2, ..., NC - 1} */\r\n\tpublic static final int DC20 \t\t\t\t= 48;\r\n\tpublic static final int RC20 \t\t\t\t= 28;\r\n\tpublic static final int BC20 \t\t\t\t= 19;\r\n\tpublic static final int MC20 \t\t\t\t= 257;\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/decode/Decode.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 01.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.decode;\r\n\r\n/**\r\n * Used to store information for lz decoding\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class Decode\r\n{\r\n\tprivate int maxNum;\r\n\r\n\tprivate final int[] decodeLen = new int[16];\r\n\r\n\tprivate final int[] decodePos = new int[16];\r\n\r\n\tprotected int[] decodeNum = new int[2];\r\n\r\n\t/**\r\n\t * returns the decode Length array\r\n\t * @return decodeLength\r\n\t */\r\n\tpublic int[] getDecodeLen()\r\n\t{\r\n\t\treturn decodeLen;\r\n\t}\r\n\r\n\t/**\r\n\t * returns the decode num array\r\n\t * @return decodeNum\r\n\t */\r\n\tpublic int[] getDecodeNum()\r\n\t{\r\n\t\treturn decodeNum;\r\n\t}\r\n\r\n\t/**\r\n\t * returns the decodePos array\r\n\t * @return decodePos\r\n\t */\r\n\tpublic int[] getDecodePos()\r\n\t{\r\n\t\treturn decodePos;\r\n\t}\r\n\r\n\t/**\r\n\t * returns the max num\r\n\t * @return maxNum\r\n\t */\r\n\tpublic int getMaxNum()\r\n\t{\r\n\t\treturn maxNum;\r\n\t}\r\n\r\n\t/**\r\n\t * sets the max num\r\n\t * @param maxNum to be set to maxNum\r\n\t */\r\n\tpublic void setMaxNum(int maxNum)\r\n\t{\r\n\t\tthis.maxNum = maxNum;\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/decode/DistDecode.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 01.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.decode;\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class DistDecode extends Decode\r\n{\r\n\r\n\t/**\r\n\t * \r\n\t */\r\n\tpublic DistDecode()\r\n\t{\r\n\t\tdecodeNum = new int[Compress.DC];\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/decode/FilterType.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 01.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.decode;\r\n\r\n/**\r\n * DOCUMENT ME\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic enum FilterType {\r\n\tFILTER_NONE, FILTER_PPM /*dummy*/, FILTER_E8, FILTER_E8E9,\r\n\t  FILTER_UPCASETOLOW, FILTER_AUDIO, FILTER_RGB, FILTER_DELTA,\r\n\t  FILTER_ITANIUM, FILTER_E8E9V2;\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/decode/LitDecode.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 01.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.decode;\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class LitDecode extends Decode\r\n{\r\n\t/**\r\n\t * \r\n\t */\r\n\tpublic LitDecode()\r\n\t{\r\n\t\tdecodeNum = new int[Compress.NC];\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/decode/LowDistDecode.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 01.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.decode;\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class LowDistDecode extends Decode\r\n{\r\n\r\n\t/**\r\n\t * \r\n\t */\r\n\tpublic LowDistDecode()\r\n\t{\r\n\t\tdecodeNum = new int[Compress.LDC];\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/decode/MultDecode.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 01.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.decode;\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class MultDecode extends Decode\r\n{\r\n\r\n\t/**\r\n\t * \r\n\t */\r\n\tpublic MultDecode()\r\n\t{\r\n\t\tdecodeNum = new int[Compress.MC20];\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/decode/RepDecode.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 01.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.decode;\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class RepDecode extends Decode\r\n{\r\n\t/**\r\n\t * \r\n\t */\r\n\tpublic RepDecode()\r\n\t{\r\n\t\tdecodeNum = new int[Compress.RC];\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/ppm/AnalyzeHeapDump.java",
    "content": "package com.github.junrar.unpack.ppm;\r\n\r\nimport java.io.BufferedInputStream;\r\nimport java.io.File;\r\nimport java.io.FileInputStream;\r\nimport java.io.IOException;\r\nimport java.io.InputStream;\r\n\r\n/**\r\n * For debugging purposes only.\r\n *\r\n * @author alban\r\n */\r\npublic class AnalyzeHeapDump {\r\n    \r\n    /** Creates a new instance of AnalyzeHeapDump */\r\n    public AnalyzeHeapDump() {\r\n    }\r\n\r\n    public static void main(String[] argv) {\r\n        File cfile = new File(\"P:\\\\test\\\\heapdumpc\");\r\n        File jfile = new File(\"P:\\\\test\\\\heapdumpj\");\r\n        if (!cfile.exists()) {\r\n            System.err.println(\"File not found: \" + cfile.getAbsolutePath());\r\n            return;\r\n        }\r\n        if (!jfile.exists()) {\r\n            System.err.println(\"File not found: \" + jfile.getAbsolutePath());\r\n            return;\r\n        }\r\n        long clen = cfile.length();\r\n        long jlen = jfile.length();\r\n        if (clen != jlen) {\r\n            System.out.println(\"File size mismatch\");\r\n            System.out.println(\"clen = \" + clen);\r\n            System.out.println(\"jlen = \" + jlen);\r\n        }\r\n        // Do byte comparison\r\n        long len = Math.min(clen, jlen);\r\n        InputStream cin = null;\r\n        InputStream jin = null;\r\n        int bufferLen = 256*1024;\r\n        try {\r\n            cin = new BufferedInputStream(\r\n                    new FileInputStream(cfile), bufferLen);\r\n            jin = new BufferedInputStream(\r\n                    new FileInputStream(jfile), bufferLen);\r\n            boolean matching = true;\r\n            boolean mismatchFound = false;\r\n            long startOff = 0L;\r\n            long off = 0L;\r\n            while (off < len) {\r\n                if (cin.read() != jin.read()) {\r\n                    if (matching) {\r\n                        startOff = off;\r\n                        matching = false;\r\n                        mismatchFound = true;\r\n                    }\r\n                }\r\n                else { // match\r\n                    if (!matching) {\r\n                        printMismatch(startOff, off);\r\n                        matching = true;\r\n                    }\r\n                }\r\n                off++;\r\n            }\r\n            if (!matching) {\r\n                printMismatch(startOff, off);\r\n            }\r\n            if (!mismatchFound) {\r\n                System.out.println(\"Files are identical\");\r\n            }\r\n            System.out.println(\"Done\");\r\n        }\r\n        catch (IOException e) {\r\n            e.printStackTrace();\r\n        }\r\n        finally {\r\n            try {\r\n\t\t\t\tcin.close();\r\n\t\t\t\tjin.close();\r\n\t\t\t} catch (IOException e) {\r\n\t\t\t\te.printStackTrace();\r\n\t\t\t}\r\n        }\r\n    }\r\n\r\n    private static void printMismatch(long startOff, long bytesRead) {\r\n        System.out.println(\"Mismatch: off=\" + startOff +\r\n                \"(0x\" + Long.toHexString(startOff) +\r\n                \"), len=\" + (bytesRead - startOff));\r\n    }\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/ppm/BlockTypes.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 01.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.ppm;\r\n\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic enum BlockTypes\r\n{\r\n\tBLOCK_LZ(0), BLOCK_PPM(1);\r\n\r\n\tprivate int blockType;\r\n\r\n\tprivate BlockTypes(int blockType)\r\n\t{\r\n\t\tthis.blockType = blockType;\r\n\t}\r\n\r\n\tpublic int getBlockType()\r\n\t{\r\n\t\treturn blockType;\r\n\t}\r\n\r\n\tpublic boolean equals(int blockType)\r\n\t{\r\n\t\treturn this.blockType == blockType;\r\n\t}\r\n\r\n\tpublic static BlockTypes findBlockType(int blockType)\r\n\t{\r\n\t\tif (BLOCK_LZ.equals(blockType)) {\r\n\t\t\treturn BLOCK_LZ;\r\n\t\t}\r\n\t\tif (BLOCK_PPM.equals(blockType)) {\r\n\t\t\treturn BLOCK_PPM;\r\n\t\t}\r\n\t\treturn null;\r\n\t}\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/ppm/FreqData.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 04.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.ppm;\r\n\r\nimport com.github.junrar.io.Raw;\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class FreqData extends Pointer{\r\n\r\n\tpublic static final int size = 6; \r\n\r\n//    struct FreqData\r\n//    {\r\n//        ushort SummFreq;\r\n//        STATE _PACK_ATTR * Stats;\r\n//    };\r\n\r\n\tpublic FreqData(byte[]mem){\r\n\t\tsuper(mem);\r\n\t}\r\n\r\n    public FreqData init(byte[] mem) {\r\n        this.mem = mem;\r\n        pos = 0;\r\n        return this;\r\n    }\r\n\r\n    public int getSummFreq() {\r\n\t\treturn Raw.readShortLittleEndian(mem,  pos)&0xffff;\r\n\t}\r\n\r\n\tpublic void setSummFreq(int summFreq) {\r\n        Raw.writeShortLittleEndian(mem, pos, (short)summFreq);\r\n\t}\r\n\r\n    public void incSummFreq(int dSummFreq) {\r\n        Raw.incShortLittleEndian(mem, pos, dSummFreq);\r\n    }\r\n\r\n    public int getStats() {\r\n        return Raw.readIntLittleEndian(mem,  pos+2);\r\n\t}\r\n\r\n\tpublic void setStats(State state) {\r\n\t\tsetStats(state.getAddress());\r\n\t}\r\n\r\n    public void setStats(int state) {\r\n        Raw.writeIntLittleEndian(mem, pos+2, state);\r\n\t}\r\n\r\n    public String toString() {\r\n        StringBuilder buffer = new StringBuilder();\r\n        buffer.append(\"FreqData[\");\r\n        buffer.append(\"\\n  pos=\");\r\n        buffer.append(pos);\r\n        buffer.append(\"\\n  size=\");\r\n        buffer.append(size);\r\n        buffer.append(\"\\n  summFreq=\");\r\n        buffer.append(getSummFreq());\r\n        buffer.append(\"\\n  stats=\");\r\n        buffer.append(getStats());\r\n        buffer.append(\"\\n]\");\r\n        return buffer.toString();\r\n    }\r\n\t\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/ppm/ModelPPM.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 31.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.ppm;\r\n\r\nimport java.io.IOException;\r\nimport java.util.Arrays;\r\n\r\nimport com.github.junrar.exception.RarException;\r\nimport com.github.junrar.unpack.Unpack;\r\n\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class ModelPPM\r\n{\r\n\tpublic static final int MAX_O = 64; /* maximum allowed model order */\r\n\r\n\tpublic static final int INT_BITS = 7;\r\n\r\n\tpublic static final int PERIOD_BITS = 7;\r\n\r\n\tpublic static final int TOT_BITS = INT_BITS + PERIOD_BITS;\r\n\r\n\tpublic static final int INTERVAL = 1 << INT_BITS;\r\n\r\n\tpublic static final int BIN_SCALE = 1 << TOT_BITS;\r\n\r\n\tpublic static final int MAX_FREQ = 124;\r\n\r\n\tprivate SEE2Context[][] SEE2Cont = new SEE2Context[25][16];\r\n\r\n\tprivate SEE2Context dummySEE2Cont;\r\n\r\n\tprivate PPMContext minContext, medContext, maxContext;\r\n\r\n\tprivate State foundState; // found next state transition\r\n\r\n\tprivate int numMasked, initEsc, orderFall, maxOrder, runLength, initRL;\r\n\r\n\tprivate int[] charMask = new int[256];\r\n\r\n\tprivate int[] NS2Indx = new int[256];\r\n\r\n\tprivate int[] NS2BSIndx = new int[256];\r\n\r\n\tprivate int[] HB2Flag = new int[256];\r\n\r\n    // byte EscCount, PrevSuccess, HiBitsFlag;\r\n\tprivate int escCount, prevSuccess, hiBitsFlag;\r\n\r\n\tprivate int[][] binSumm = new int[128][64]; // binary SEE-contexts\r\n\r\n\tprivate RangeCoder coder = new RangeCoder();\r\n\r\n\tprivate SubAllocator subAlloc = new SubAllocator();\r\n\r\n\tprivate static int InitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3,\r\n\t\t\t0x64A1, 0x5ABC, 0x6632, 0x6051 };\r\n\r\n    // Temp fields\r\n    private final State tempState1 = new State(null);\r\n    private final State tempState2 = new State(null);\r\n    private final State tempState3 = new State(null);\r\n    private final State tempState4 = new State(null);\r\n    private final StateRef tempStateRef1 = new StateRef();\r\n    private final StateRef tempStateRef2 = new StateRef();\r\n    private final PPMContext tempPPMContext1 = new PPMContext(null);\r\n    private final PPMContext tempPPMContext2 = new PPMContext(null);\r\n    private final PPMContext tempPPMContext3 = new PPMContext(null);\r\n    private final PPMContext tempPPMContext4 = new PPMContext(null);\r\n    private final int[] ps = new int[MAX_O];\r\n\r\n\tpublic ModelPPM()\r\n\t{\r\n\t\tminContext = null;\r\n\t\tmaxContext = null;\r\n\t\tmedContext = null;\r\n\t}\r\n\r\n\tpublic SubAllocator getSubAlloc()\r\n\t{\r\n\t\treturn subAlloc;\r\n\t}\r\n\r\n\tprivate void restartModelRare()\r\n\t{\r\n\t\tArrays.fill(charMask, 0);\r\n\t\tsubAlloc.initSubAllocator();\r\n\t\tinitRL = -(maxOrder < 12 ? maxOrder : 12) - 1;\r\n\t\tint addr = subAlloc.allocContext();\r\n\t\tminContext.setAddress(addr);\r\n\t\tmaxContext.setAddress(addr);\r\n\t\tminContext.setSuffix(0);\r\n\t\torderFall = maxOrder;\r\n\t\tminContext.setNumStats(256);\r\n\t\tminContext.getFreqData().setSummFreq(minContext.getNumStats()+1);\r\n\t\t\t\t\r\n\t\taddr = subAlloc.allocUnits(256 / 2);\r\n\t\tfoundState.setAddress(addr);\r\n\t\tminContext.getFreqData().setStats(addr);\r\n\r\n\t\tState state = new State(subAlloc.getHeap());\r\n\t\taddr = minContext.getFreqData().getStats();\r\n        runLength = initRL;\r\n        prevSuccess = 0;\r\n\t\tfor (int i = 0; i < 256; i++) {\r\n\t\t\tstate.setAddress(addr + i * State.size);\r\n\t\t\tstate.setSymbol(i);\r\n\t\t\tstate.setFreq(1);\r\n\t\t\tstate.setSuccessor(0);\r\n\t\t}\r\n\r\n\t\tfor (int i = 0; i < 128; i++) {\r\n\t\t\tfor (int k = 0; k < 8; k++) {\r\n\t\t\t\tfor (int m = 0; m < 64; m += 8) {\r\n\t\t\t\t\tbinSumm[i][k + m] = BIN_SCALE - InitBinEsc[k] / (i + 2);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tfor (int i = 0; i < 25; i++) {\r\n\t\t\tfor (int k = 0; k < 16; k++) {\r\n\t\t\t\tSEE2Cont[i][k].init(5 * i + 10);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tprivate void startModelRare(int MaxOrder)\r\n\t{\r\n        int i, k, m, Step;\r\n\t\tescCount = 1;\r\n\t\tthis.maxOrder = MaxOrder;\r\n\t\trestartModelRare();\r\n        // Bug Fixed\r\n        NS2BSIndx[0] = 0;\r\n        NS2BSIndx[1] = 2;\r\n\t\tfor (int j = 0; j < 9; j++) {\r\n\t\t\tNS2BSIndx[2 + j] = 4;\r\n\t\t}\r\n\t\tfor (int j = 0; j < 256 - 11; j++) {\r\n\t\t\tNS2BSIndx[11 + j] = 6;\r\n\t\t}\r\n\t\tfor (i = 0; i < 3; i++) {\r\n\t\t\tNS2Indx[i] = i;\r\n\t\t}\r\n\t\tfor (m = i, k = 1, Step = 1; i < 256; i++) {\r\n\t\t\tNS2Indx[i] = m;\r\n\t\t\tif ((--k) == 0) {\r\n\t\t\t\tk = ++Step;\r\n\t\t\t\tm++;\r\n\t\t\t}\r\n\t\t}\r\n\t\tfor (int j = 0; j < 0x40; j++) {\r\n\t\t\tHB2Flag[j] = 0;\r\n\t\t}\r\n\t\tfor (int j = 0; j < 0x100 - 0x40; j++) {\r\n\t\t\tHB2Flag[0x40 + j] = 0x08;\r\n\t\t}\r\n\t\tdummySEE2Cont.setShift(PERIOD_BITS);\r\n\r\n\t}\r\n\r\n\tprivate void clearMask()\r\n\t{\r\n\t\tescCount = 1;\r\n\t\tArrays.fill(charMask, 0);\r\n\t}\r\n\r\n\tpublic boolean decodeInit(Unpack unpackRead, int escChar/* ref */)\r\n\t\t\tthrows IOException, RarException\r\n\t{\r\n\r\n\t\tint MaxOrder = unpackRead.getChar() & 0xff;\r\n\t\tboolean reset = ((MaxOrder & 0x20) != 0);\r\n\r\n\t\tint MaxMB = 0;\r\n\t\tif (reset) {\r\n\t\t\tMaxMB = unpackRead.getChar();\r\n\t\t} else {\r\n\t\t\tif (subAlloc.GetAllocatedMemory() == 0) {\r\n\t\t\t\treturn (false);\r\n\t\t\t}\r\n\t\t}\r\n\t\tif ((MaxOrder & 0x40) != 0) {\r\n\t\t\tescChar = unpackRead.getChar();\r\n\t\t\tunpackRead.setPpmEscChar(escChar);\r\n\t\t}\r\n\t\tcoder.initDecoder(unpackRead);\r\n\t\tif (reset) {\r\n\t\t\tMaxOrder = (MaxOrder & 0x1f) + 1;\r\n\t\t\tif (MaxOrder > 16) {\r\n\t\t\t\tMaxOrder = 16 + (MaxOrder - 16) * 3;\r\n\t\t\t}\r\n\t\t\tif (MaxOrder == 1) {\r\n\t\t\t\tsubAlloc.stopSubAllocator();\r\n\t\t\t\treturn (false);\r\n\t\t\t}\r\n\t\t\tsubAlloc.startSubAllocator(MaxMB + 1);\r\n\t\t\tminContext = new PPMContext(getHeap());\r\n\t\t\tmedContext = new PPMContext(getHeap());\r\n\t\t\tmaxContext = new PPMContext(getHeap());\r\n\t\t\tfoundState = new State(getHeap());\r\n\t\t\tdummySEE2Cont = new SEE2Context();\r\n\t\t\tfor (int i = 0; i < 25; i++) {\r\n\t\t\t\tfor (int j = 0; j < 16; j++) {\r\n\t\t\t\t\tSEE2Cont[i][j] = new SEE2Context();\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tstartModelRare(MaxOrder);\r\n\t\t}\r\n\t\treturn (minContext.getAddress() != 0);\r\n\t}\r\n\r\n\tpublic int decodeChar() throws IOException, RarException\r\n\t{\r\n        // Debug\r\n        //subAlloc.dumpHeap();\r\n\r\n\t\tif (minContext.getAddress() <= subAlloc.getPText()\r\n\t\t\t\t|| minContext.getAddress() > subAlloc.getHeapEnd()) {\r\n\t\t\treturn (-1);\r\n\t\t}\r\n\r\n\t\tif (minContext.getNumStats() != 1) {\r\n\t\t\tif (minContext.getFreqData().getStats() <= subAlloc.getPText()\r\n\t\t\t\t\t|| minContext.getFreqData().getStats() > subAlloc.getHeapEnd()) {\r\n\t\t\t\treturn (-1);\r\n\t\t\t}\r\n\t\t\tif (!minContext.decodeSymbol1(this)) {\r\n\t\t\t\treturn (-1);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tminContext.decodeBinSymbol(this);\r\n\t\t}\r\n\t\tcoder.decode();\r\n\t\twhile (foundState.getAddress() == 0) {\r\n\t\t\tcoder.ariDecNormalize();\r\n\t\t\tdo {\r\n\t\t\t\torderFall++;\r\n\t\t\t\tminContext.setAddress(minContext.getSuffix());// =MinContext->Suffix;\r\n\t\t\t\tif (minContext.getAddress() <= subAlloc.getPText()\r\n\t\t\t\t\t\t|| minContext.getAddress() > subAlloc.getHeapEnd()) {\r\n\t\t\t\t\treturn (-1);\r\n\t\t\t\t}\r\n\t\t\t} while (minContext.getNumStats() == numMasked);\r\n\t\t\tif (!minContext.decodeSymbol2(this)) {\r\n\t\t\t\treturn (-1);\r\n\t\t\t}\r\n\t\t\tcoder.decode();\r\n\t\t}\r\n\t\tint Symbol = foundState.getSymbol();\r\n\t\tif ((orderFall == 0) && foundState.getSuccessor() > subAlloc.getPText()) {\r\n\t\t\t// MinContext=MaxContext=FoundState->Successor;\r\n\t\t\tint addr = foundState.getSuccessor();\r\n\t\t\tminContext.setAddress(addr);\r\n\t\t\tmaxContext.setAddress(addr);\r\n\t\t} else {\r\n\t\t\tupdateModel();\r\n\t\t\t//this.foundState.setAddress(foundState.getAddress());//TODO just 4 debugging\r\n\t\t\tif (escCount == 0) {\r\n\t\t\t\tclearMask();\r\n\t\t\t}\r\n\t\t}\r\n\t\tcoder.ariDecNormalize();// ARI_DEC_NORMALIZE(Coder.code,Coder.low,Coder.range,Coder.UnpackRead);\r\n\t\treturn (Symbol);\r\n\t}\r\n\r\n\tpublic SEE2Context[][] getSEE2Cont()\r\n\t{\r\n\t\treturn SEE2Cont;\r\n\t}\r\n\r\n\tpublic SEE2Context getDummySEE2Cont()\r\n\t{\r\n\t\treturn dummySEE2Cont;\r\n\t}\r\n\r\n\tpublic int getInitRL()\r\n\t{\r\n\t\treturn initRL;\r\n\t}\r\n\r\n\tpublic void setEscCount(int escCount)\r\n\t{\r\n\t\tthis.escCount = escCount&0xff;\r\n\t}\r\n\r\n\tpublic int getEscCount()\r\n\t{\r\n\t\treturn escCount;\r\n\t}\r\n\r\n    public void incEscCount(int dEscCount) {\r\n        setEscCount(getEscCount() + dEscCount);\r\n    }\r\n\r\n\tpublic int[] getCharMask()\r\n\t{\r\n\t\treturn charMask;\r\n\t}\r\n\r\n\tpublic int getNumMasked()\r\n\t{\r\n\t\treturn numMasked;\r\n\t}\r\n\r\n\tpublic void setNumMasked(int numMasked)\r\n\t{\r\n\t\tthis.numMasked = numMasked;\r\n\t}\r\n\r\n\tpublic void setPrevSuccess(int prevSuccess)\r\n\t{\r\n\t\tthis.prevSuccess = prevSuccess&0xff;\r\n\t}\r\n\r\n\tpublic int getInitEsc()\r\n\t{\r\n\t\treturn initEsc;\r\n\t}\r\n\r\n\tpublic void setInitEsc(int initEsc)\r\n\t{\r\n\t\tthis.initEsc = initEsc;\r\n\t}\r\n\r\n\tpublic void setRunLength(int runLength)\r\n\t{\r\n\t\tthis.runLength = runLength;\r\n\t}\r\n\r\n\tpublic int getRunLength()\r\n\t{\r\n\t\treturn runLength;\r\n\t}\r\n\r\n    public void incRunLength(int dRunLength) {\r\n        setRunLength(getRunLength() + dRunLength);\r\n    }\r\n\r\n\tpublic int getPrevSuccess()\r\n\t{\r\n\t\treturn prevSuccess;\r\n\t}\r\n\r\n\tpublic int getHiBitsFlag()\r\n\t{\r\n\t\treturn hiBitsFlag;\r\n\t}\r\n\r\n\tpublic void setHiBitsFlag(int hiBitsFlag)\r\n\t{\r\n\t\tthis.hiBitsFlag = hiBitsFlag&0xff;\r\n\t}\r\n\r\n\tpublic int[][] getBinSumm()\r\n\t{\r\n\t\treturn binSumm;\r\n\t}\r\n\r\n\tpublic RangeCoder getCoder()\r\n\t{\r\n\t\treturn coder;\r\n\t}\r\n\r\n\tpublic int[] getHB2Flag()\r\n\t{\r\n\t\treturn HB2Flag;\r\n\t}\r\n\r\n\tpublic int[] getNS2BSIndx()\r\n\t{\r\n\t\treturn NS2BSIndx;\r\n\t}\r\n\r\n\tpublic int[] getNS2Indx()\r\n\t{\r\n\t\treturn NS2Indx;\r\n\t}\r\n\r\n\tpublic State getFoundState()\r\n\t{\r\n\t\treturn foundState;\r\n\t}\r\n\r\n\tpublic byte[] getHeap()\r\n\t{\r\n\t\treturn subAlloc.getHeap();\r\n\t}\r\n\r\n\tpublic int getOrderFall()\r\n\t{\r\n\t\treturn orderFall;\r\n\t}\r\n\r\n\tprivate int /* ppmcontext ptr */createSuccessors(boolean Skip,\r\n            State p1 /* state ptr */) {\r\n\t\t//State upState = tempState1.init(null);\r\n\t\tStateRef upState = tempStateRef2;\r\n\t\tState tempState = tempState1.init(getHeap());\r\n\r\n\t\t// PPM_CONTEXT* pc=MinContext, * UpBranch=FoundState->Successor;\r\n\t\tPPMContext pc = tempPPMContext1.init(getHeap());\r\n\t\tpc.setAddress(minContext.getAddress());\r\n\t\tPPMContext upBranch = tempPPMContext2.init(getHeap());\r\n\t\tupBranch.setAddress(foundState.getSuccessor());\r\n\r\n\t\t// STATE * p, * ps[MAX_O], ** pps=ps;\r\n\t\tState p = tempState2.init(getHeap());\r\n\t\tint pps = 0;\r\n\r\n\t\tboolean noLoop = false;\r\n\r\n\t\tif (!Skip) {\r\n\t\t\tps[pps++] = foundState.getAddress();// *pps++ = FoundState;\r\n\t\t\tif (pc.getSuffix() == 0) {\r\n\t\t\t\tnoLoop = true;\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (!noLoop) {\r\n\t\t\tboolean loopEntry = false;\r\n\t\t\tif (p1.getAddress() != 0) {\r\n\t\t\t\tp.setAddress(p1.getAddress());\r\n\t\t\t\tpc.setAddress(pc.getSuffix());// =pc->Suffix;\r\n\t\t\t\tloopEntry = true;\r\n\t\t\t}\r\n\t\t\tdo {\r\n\t\t\t\tif (!loopEntry) {\r\n\t\t\t\t\tpc.setAddress(pc.getSuffix());// pc=pc->Suffix;\r\n\t\t\t\t\tif (pc.getNumStats() != 1) {\r\n\t\t\t\t\t\tp.setAddress(pc.getFreqData().getStats());// p=pc->U.Stats\r\n\t\t\t\t\t\tif (p.getSymbol() != foundState.getSymbol()) {\r\n\t\t\t\t\t\t\tdo {\r\n\t\t\t\t\t\t\t\tp.incAddress();\r\n\t\t\t\t\t\t\t} while (p.getSymbol() != foundState.getSymbol());\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tp.setAddress(pc.getOneState().getAddress());// p=&(pc->OneState);\r\n\t\t\t\t\t}\r\n\t\t\t\t}// LOOP_ENTRY:\r\n\t\t\t\tloopEntry = false;\r\n\t\t\t\tif (p.getSuccessor() != upBranch.getAddress()) {\r\n\t\t\t\t\tpc.setAddress(p.getSuccessor());// =p->Successor;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t\tps[pps++] = p.getAddress();\r\n\t\t\t} while (pc.getSuffix() != 0);\r\n\r\n\t\t} // NO_LOOP:\r\n\t\tif (pps == 0) {\r\n\t\t\treturn pc.getAddress();\r\n\t\t}\r\n\t\tupState.setSymbol(getHeap()[upBranch.getAddress()]);// UpState.Symbol=*(byte*)\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// UpBranch;\r\n\t\t// UpState.Successor=(PPM_CONTEXT*) (((byte*) UpBranch)+1);\r\n\t\tupState.setSuccessor(upBranch.getAddress() + 1); //TODO check if +1 necessary\r\n\t\tif (pc.getNumStats() != 1) {\r\n\t\t\tif (pc.getAddress() <= subAlloc.getPText()) {\r\n\t\t\t\treturn (0);\r\n\t\t\t}\r\n\t\t\tp.setAddress(pc.getFreqData().getStats());\r\n\t\t\tif (p.getSymbol() != upState.getSymbol()) {\r\n\t\t\t\tdo {\r\n\t\t\t\t\tp.incAddress();\r\n\t\t\t\t} while (p.getSymbol() != upState.getSymbol());\r\n\t\t\t}\r\n\t\t\tint cf = p.getFreq() - 1;\r\n\t\t\tint s0 = pc.getFreqData().getSummFreq() - pc.getNumStats() - cf;\r\n\t\t\t// UpState.Freq=1+((2*cf <= s0)?(5*cf > s0):((2*cf+3*s0-1)/(2*s0)));\r\n\t\t\tupState.setFreq(1 + ((2 * cf <= s0) ? (5 * cf > s0 ? 1 : 0) :\r\n                    ((2 * cf + 3 * s0 - 1) / (2 * s0))));\r\n\t\t} else {\r\n\t\t\tupState.setFreq(pc.getOneState().getFreq());// UpState.Freq=pc->OneState.Freq;\r\n\t\t}\r\n\t\tdo {\r\n\t\t\t// pc = pc->createChild(this,*--pps,UpState);\r\n\t\t\ttempState.setAddress(ps[--pps]);\r\n\t\t\tpc.setAddress(pc.createChild(this, tempState, upState));\r\n\t\t\tif (pc.getAddress() == 0) {\r\n\t\t\t\treturn 0;\r\n\t\t\t}\r\n\t\t} while (pps != 0);\r\n\t\treturn pc.getAddress();\r\n\t}\r\n\r\n\tprivate void updateModelRestart()\r\n\t{\r\n\t\trestartModelRare();\r\n\t\tescCount = 0;\r\n\t}\r\n\r\n\tprivate void updateModel()\r\n\t{\r\n        //System.out.println(\"ModelPPM.updateModel()\");\r\n\t\t// STATE fs = *FoundState, *p = NULL;\r\n\t\tStateRef fs = tempStateRef1;\r\n\t\tfs.setValues(foundState);\r\n\t\tState p = tempState3.init(getHeap());\r\n\t\tState tempState = tempState4.init(getHeap());\r\n\r\n\t\tPPMContext pc = tempPPMContext3.init(getHeap());\r\n\t\tPPMContext successor = tempPPMContext4.init(getHeap());\r\n\r\n\t\tint ns1, ns, cf, sf, s0;\r\n\t\tpc.setAddress(minContext.getSuffix());\r\n\t\tif (fs.getFreq() < MAX_FREQ / 4 && pc.getAddress() != 0) {\r\n\t\t\tif (pc.getNumStats() != 1) {\r\n\t\t\t\tp.setAddress(pc.getFreqData().getStats());\r\n\t\t\t\tif (p.getSymbol() != fs.getSymbol()) {\r\n\t\t\t\t\tdo {\r\n\t\t\t\t\t\tp.incAddress();\r\n\t\t\t\t\t} while (p.getSymbol() != fs.getSymbol());\r\n\t\t\t\t\ttempState.setAddress(p.getAddress() - State.size);\r\n\t\t\t\t\tif (p.getFreq() >= tempState.getFreq()) {\r\n\t\t\t\t\t\tState.ppmdSwap(p, tempState);\r\n\t\t\t\t\t\tp.decAddress();\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif (p.getFreq() < MAX_FREQ - 9) {\r\n\t\t\t\t\tp.incFreq(2);\r\n\t\t\t\t\tpc.getFreqData().incSummFreq(2);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tp.setAddress(pc.getOneState().getAddress());\r\n                if (p.getFreq() < 32) {\r\n                    p.incFreq(1);\r\n                }\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (orderFall == 0) {\r\n\t\t\tfoundState.setSuccessor(createSuccessors(true, p));\r\n\t\t\tminContext.setAddress(foundState.getSuccessor());\r\n\t\t\tmaxContext.setAddress(foundState.getSuccessor());\r\n\t\t\tif (minContext.getAddress() == 0) {\r\n\t\t\t\tupdateModelRestart();\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tsubAlloc.getHeap()[subAlloc.getPText()] = (byte)fs.getSymbol();\r\n\t\tsubAlloc.incPText();\r\n\t\tsuccessor.setAddress(subAlloc.getPText());\r\n\t\tif (subAlloc.getPText() >= subAlloc.getFakeUnitsStart()) {\r\n\t\t\tupdateModelRestart();\r\n\t\t\treturn;\r\n\t\t}\r\n//        // Debug\r\n//        subAlloc.dumpHeap();\r\n\t\tif (fs.getSuccessor() != 0) {\r\n\t\t\tif (fs.getSuccessor() <= subAlloc.getPText()) {\r\n\t\t\t\tfs.setSuccessor(createSuccessors(false, p));\r\n\t\t\t\tif (fs.getSuccessor() == 0) {\r\n\t\t\t\t\tupdateModelRestart();\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (--orderFall == 0) {\r\n\t\t\t\tsuccessor.setAddress(fs.getSuccessor());\r\n                if (maxContext.getAddress() != minContext.getAddress()) {\r\n                    subAlloc.decPText(1);\r\n                }\r\n\t\t\t}\r\n\t\t}\r\n        else {\r\n\t\t\tfoundState.setSuccessor(successor.getAddress());\r\n\t\t\tfs.setSuccessor(minContext);\r\n\t\t}\r\n//        // Debug\r\n//        subAlloc.dumpHeap();\r\n\t\tns = minContext.getNumStats();\r\n\t\ts0 = minContext.getFreqData().getSummFreq() - (ns) - (fs.getFreq() - 1);\r\n\t\tfor (pc.setAddress(maxContext.getAddress());\r\n                pc.getAddress() != minContext.getAddress();\r\n                pc.setAddress(pc.getSuffix())) {\r\n\t\t\tif ((ns1 = pc.getNumStats()) != 1) {\r\n\t\t\t\tif ((ns1 & 1) == 0) {\r\n\t\t\t\t\t//System.out.println(ns1);\r\n\t\t\t\t\tpc.getFreqData().setStats(\r\n\t\t\t\t\t\t\tsubAlloc.expandUnits(pc.getFreqData().getStats(),\r\n\t\t\t\t\t\t\t\t\tns1 >>> 1));\r\n\t\t\t\t\tif (pc.getFreqData().getStats() == 0) {\r\n\t\t\t\t\t\tupdateModelRestart();\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n                // bug fixed\r\n//\t\t\t\tint sum = ((2 * ns1 < ns) ? 1 : 0) +\r\n//                        2 * ((4 * ((ns1 <= ns) ? 1 : 0)) & ((pc.getFreqData()\r\n//\t\t\t\t\t\t\t\t.getSummFreq() <= 8 * ns1) ? 1 : 0));\r\n\t\t\t\tint sum = ((2 * ns1 < ns) ? 1 : 0) + 2 * (\r\n                        ((4 * ns1 <= ns) ? 1 : 0) &\r\n                        ((pc.getFreqData().getSummFreq() <= 8 * ns1) ? 1 : 0)\r\n                        );\r\n\t\t\t\tpc.getFreqData().incSummFreq(sum);\r\n\t\t\t}\r\n            else {\r\n\t\t\t\tp.setAddress(subAlloc.allocUnits(1));\r\n\t\t\t\tif (p.getAddress() == 0) {\r\n\t\t\t\t\tupdateModelRestart();\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tp.setValues(pc.getOneState());\r\n\t\t\t\tpc.getFreqData().setStats(p);\r\n\t\t\t\tif (p.getFreq() < MAX_FREQ / 4 - 1) {\r\n\t\t\t\t\tp.incFreq(p.getFreq());\r\n\t\t\t\t}\r\n                else {\r\n\t\t\t\t\tp.setFreq(MAX_FREQ - 4);\r\n\t\t\t\t}\r\n\t\t\t\tpc.getFreqData().setSummFreq(\r\n                        (p.getFreq() + initEsc + (ns > 3 ? 1 : 0)));\r\n\t\t\t}\r\n\t\t\tcf = 2 * fs.getFreq() * (pc.getFreqData().getSummFreq() + 6);\r\n\t\t\tsf = s0 + pc.getFreqData().getSummFreq();\r\n\t\t\tif (cf < 6 * sf) {\r\n\t\t\t\tcf = 1 + (cf > sf ? 1 : 0) + (cf >= 4 * sf ? 1 : 0);\r\n\t\t\t\tpc.getFreqData().incSummFreq(3);\r\n\t\t\t}\r\n            else {\r\n\t\t\t\tcf = 4 + (cf >= 9 * sf ? 1 : 0) + (cf >= 12 * sf ? 1 : 0) +\r\n                        (cf >= 15 * sf ? 1 : 0);\r\n\t\t\t\tpc.getFreqData().incSummFreq(cf);\r\n\t\t\t}\r\n\t\t\tp.setAddress(pc.getFreqData().getStats() + ns1*State.size);\r\n\t\t\tp.setSuccessor(successor);\r\n\t\t\tp.setSymbol(fs.getSymbol());\r\n\t\t\tp.setFreq(cf);\r\n\t\t\tpc.setNumStats(++ns1);\r\n\t\t}\r\n\t\t\r\n\t\tint address = fs.getSuccessor();\r\n\t\tmaxContext.setAddress(address);\r\n\t\tminContext.setAddress(address);\r\n\t\t//TODO-----debug\r\n//\t\tint pos = minContext.getFreqData().getStats();\r\n//\t\tState a = new State(getHeap());\r\n//\t\ta.setAddress(pos);\r\n//\t\tpos+=State.size;\r\n//\t\ta.setAddress(pos);\r\n\t\t//--dbg end\r\n\t\treturn;\r\n\t}\r\n\r\n    // Debug\r\n    public String toString() {\r\n        StringBuilder buffer = new StringBuilder();\r\n        buffer.append(\"ModelPPM[\");\r\n        buffer.append(\"\\n  numMasked=\");\r\n        buffer.append(numMasked);\r\n        buffer.append(\"\\n  initEsc=\");\r\n        buffer.append(initEsc);\r\n        buffer.append(\"\\n  orderFall=\");\r\n        buffer.append(orderFall);\r\n        buffer.append(\"\\n  maxOrder=\");\r\n        buffer.append(maxOrder);\r\n        buffer.append(\"\\n  runLength=\");\r\n        buffer.append(runLength);\r\n        buffer.append(\"\\n  initRL=\");\r\n        buffer.append(initRL);\r\n        buffer.append(\"\\n  escCount=\");\r\n        buffer.append(escCount);\r\n        buffer.append(\"\\n  prevSuccess=\");\r\n        buffer.append(prevSuccess);\r\n        buffer.append(\"\\n  foundState=\");\r\n        buffer.append(foundState);\r\n        buffer.append(\"\\n  coder=\");\r\n        buffer.append(coder);\r\n        buffer.append(\"\\n  subAlloc=\");\r\n        buffer.append(subAlloc);\r\n        buffer.append(\"\\n]\");\r\n        return buffer.toString();\r\n    }\r\n\r\n    // Debug\r\n//    public void dumpHeap() {\r\n//        subAlloc.dumpHeap();\r\n//    }\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/ppm/PPMContext.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 31.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.ppm;\r\n\r\nimport com.github.junrar.io.Raw;\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class PPMContext extends Pointer\r\n{\r\n\r\n    private static final int unionSize = Math.max(FreqData.size, State.size);\r\n\r\n\tpublic static final int size = 2 + unionSize + 4; // 12\r\n\r\n    // ushort NumStats;\r\n\tprivate int numStats; // determines if feqData or onstate is used\r\n\r\n\t// (1==onestate)\r\n\r\n\tprivate final FreqData freqData; // -\\\r\n\r\n\t// |-> union\r\n\tprivate final State oneState; // -/\r\n\r\n\tprivate int suffix; // pointer ppmcontext\r\n\r\n\tpublic final static int[] ExpEscape =\r\n            { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };\r\n\r\n    // Temp fields\r\n    private final State tempState1 = new State(null);\r\n    private final State tempState2 = new State(null);\r\n    private final State tempState3 = new State(null);\r\n    private final State tempState4 = new State(null);\r\n    private final State tempState5 = new State(null);\r\n    private PPMContext tempPPMContext = null;\r\n    private final int[] ps = new int[256];\r\n\r\n\tpublic PPMContext(byte[] mem)\r\n\t{\r\n\t\tsuper(mem);\r\n\t\toneState = new State(mem);\r\n\t\tfreqData = new FreqData(mem);\r\n\t}\r\n\r\n    public PPMContext init(byte[] mem) {\r\n\t\tthis.mem = mem;\r\n        pos = 0;\r\n\t\toneState.init(mem);\r\n\t\tfreqData.init(mem);\r\n        return this;\r\n    }\r\n\r\n\tpublic FreqData getFreqData()\r\n\t{\r\n\t\treturn freqData;\r\n\t}\r\n\r\n\tpublic void setFreqData(FreqData freqData)\r\n\t{\r\n\t\tthis.freqData.setSummFreq(freqData.getSummFreq());\r\n\t\tthis.freqData.setStats(freqData.getStats());\r\n\t}\r\n\r\n\tpublic final int getNumStats()\r\n\t{\r\n\t\tif (mem!=null){\r\n\t\t\tnumStats = Raw.readShortLittleEndian(mem,  pos)&0xffff;\r\n\t\t}\r\n\t\treturn numStats;\r\n\t}\r\n\r\n\tpublic final void setNumStats(int numStats)\r\n\t{\r\n\t\tthis.numStats = numStats&0xffff;\r\n\t\tif (mem != null) {\r\n\t\t\tRaw.writeShortLittleEndian(mem, pos, (short)numStats);\r\n\t\t}\r\n\t}\r\n\r\n\tpublic State getOneState()\r\n\t{\r\n\t\treturn oneState;\r\n\t}\r\n\r\n\tpublic void setOneState(StateRef oneState)\r\n\t{\r\n\t\tthis.oneState.setValues(oneState);\r\n\t}\r\n\r\n\tpublic int getSuffix()\r\n\t{\r\n\t\tif(mem!=null){\r\n\t\t\tsuffix = Raw.readIntLittleEndian(mem,  pos+8);\r\n\t\t}\r\n\t\treturn suffix;\r\n\t}\r\n\r\n\tpublic void setSuffix(PPMContext suffix)\r\n\t{\r\n\t\tsetSuffix(suffix.getAddress());\r\n\t}\r\n\r\n\tpublic void setSuffix(int suffix)\r\n\t{\r\n\t\tthis.suffix = suffix;\r\n\t\tif (mem != null) {\r\n\t\t\tRaw.writeIntLittleEndian(mem, pos + 8, suffix);\r\n\t\t}\r\n\t}\r\n\r\n\t@Override\r\n\tpublic void setAddress(int pos)\r\n\t{\r\n        super.setAddress(pos);\r\n        oneState.setAddress(pos+2);\r\n        freqData.setAddress(pos+2);\r\n\t}\r\n\r\n    private PPMContext getTempPPMContext(byte[] mem) {\r\n        if (tempPPMContext == null) {\r\n            tempPPMContext = new PPMContext(null);\r\n        }\r\n        return tempPPMContext.init(mem);\r\n    }\r\n\r\n\tpublic int createChild(ModelPPM model, State pStats/* ptr */,\r\n\t\t\tStateRef firstState /* ref */)\r\n\t{\r\n\t\tPPMContext pc = getTempPPMContext(model.getSubAlloc().getHeap());\r\n\t\tpc.setAddress(model.getSubAlloc().allocContext()); \r\n\t\tif (pc != null) { \r\n\t\t\tpc.setNumStats(1);\r\n\t\t\tpc.setOneState(firstState);\r\n\t\t\tpc.setSuffix(this);\r\n\t\t\tpStats.setSuccessor(pc);\r\n\t\t}\r\n\t\treturn pc.getAddress();\r\n\t}\r\n\r\n\tpublic void rescale(ModelPPM model)\r\n\t{\r\n\t\tint OldNS = getNumStats(), i = getNumStats() - 1, Adder, EscFreq;\r\n\t\t// STATE* p1, * p;\r\n\t\tState p1 = new State(model.getHeap());\r\n\t\tState p = new State(model.getHeap());\r\n\t\tState temp = new State(model.getHeap());\r\n\r\n\t\tfor (p.setAddress(model.getFoundState().getAddress());\r\n                p.getAddress() != freqData.getStats();\r\n                p.decAddress()) {\r\n\t\t\ttemp.setAddress(p.getAddress() - State.size);\r\n\t\t\tState.ppmdSwap(p, temp);\r\n\t\t}\r\n\t\ttemp.setAddress(freqData.getStats());\r\n\t\ttemp.incFreq(4);\r\n\t\tfreqData.incSummFreq(4);\r\n\t\tEscFreq = freqData.getSummFreq() - p.getFreq();\r\n\t\tAdder = (model.getOrderFall() != 0) ? 1 : 0;\r\n\t\tp.setFreq((p.getFreq() + Adder) >>> 1);\r\n\t\tfreqData.setSummFreq(p.getFreq());\r\n\t\tdo {\r\n            p.incAddress();\r\n\t\t\tEscFreq -= p.getFreq();\r\n\t\t\tp.setFreq((p.getFreq() + Adder) >>> 1);\r\n\t\t\tfreqData.incSummFreq(p.getFreq());\r\n\t\t\ttemp.setAddress(p.getAddress() - State.size);\r\n\t\t\tif (p.getFreq() > temp.getFreq()) {\r\n\t\t\t\tp1.setAddress(p.getAddress());\r\n                StateRef tmp = new StateRef();\r\n                tmp.setValues(p1);\r\n\t\t\t\tState temp2 = new State(model.getHeap());\r\n\t\t\t\tState temp3 = new State(model.getHeap());\r\n\t\t\t\tdo {\r\n\t\t\t\t\t// p1[0]=p1[-1];\r\n\t\t\t\t\ttemp2.setAddress(p1.getAddress() - State.size);\r\n\t\t\t\t\tp1.setValues(temp2);\r\n                    p1.decAddress();\r\n\t\t\t\t\ttemp3.setAddress(p1.getAddress() - State.size);\r\n\t\t\t\t} while (p1.getAddress() != freqData.getStats() && tmp.getFreq() > temp3.getFreq());\r\n\t\t\t\tp1.setValues(tmp);\r\n\t\t\t}\r\n\t\t} while (--i != 0);\r\n\t\tif (p.getFreq() == 0) {\r\n\t\t\tdo {\r\n\t\t\t\ti++;\r\n\t\t\t\tp.decAddress();\r\n\t\t\t} while (p.getFreq() == 0);\r\n\t\t\tEscFreq += i;\r\n            setNumStats(getNumStats() - i);\r\n\t\t\tif (getNumStats() == 1) {\r\n\t\t\t\tStateRef tmp = new StateRef();\r\n\t\t\t\ttemp.setAddress(freqData.getStats());\r\n\t\t\t\ttmp.setValues(temp);\r\n\t\t\t\t// STATE tmp=*U.Stats;\r\n\t\t\t\tdo {\r\n                    // tmp.Freq-=(tmp.Freq >> 1)\r\n\t\t\t\t\ttmp.decFreq(tmp.getFreq() >>> 1);\r\n\t\t\t\t\tEscFreq >>>= 1;\r\n\t\t\t\t} while (EscFreq > 1);\r\n\t\t\t\tmodel.getSubAlloc().freeUnits(freqData.getStats(),(OldNS + 1) >>> 1);\r\n\t\t\t\toneState.setValues(tmp);\r\n\t\t\t\tmodel.getFoundState().setAddress(oneState.getAddress());\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t}\r\n\t\tEscFreq -= EscFreq >>> 1;\r\n\t\tfreqData.incSummFreq(EscFreq);\r\n\t\tint n0 = (OldNS + 1) >>> 1, n1 = (getNumStats() + 1) >>> 1;\r\n\t\tif (n0 != n1) {\r\n\t\t\tfreqData.setStats(model.getSubAlloc().shrinkUnits(freqData.getStats(), n0, n1));\r\n\t\t}\r\n\t\tmodel.getFoundState().setAddress(freqData.getStats());\r\n\t}\r\n\r\n\tprivate int getArrayIndex(ModelPPM Model, State rs)\r\n\t{\r\n\t\tPPMContext tempSuffix = getTempPPMContext(Model.getSubAlloc().getHeap());\r\n\t\ttempSuffix.setAddress(getSuffix());\r\n\t\tint ret = 0;\r\n\t\tret += Model.getPrevSuccess();\r\n\t\tret += Model.getNS2BSIndx()[tempSuffix.getNumStats() - 1];\r\n\t\tret += Model.getHiBitsFlag() + 2* Model.getHB2Flag()[rs.getSymbol()];\r\n\t\tret += ((Model.getRunLength() >>> 26) & 0x20);\r\n\t\treturn ret;\r\n\t}\r\n\r\n    public int getMean(int summ, int shift, int round)\r\n\t{\r\n\t\treturn ( (summ + (1 << (shift - round) ) ) >>> (shift) );\r\n\t}\r\n\r\n\tpublic void decodeBinSymbol(ModelPPM model)\r\n\t{\r\n\t\tState rs = tempState1.init(model.getHeap());\r\n\t\trs.setAddress(oneState.getAddress());// State&\r\n\t\tmodel.setHiBitsFlag(model.getHB2Flag()[model.getFoundState().getSymbol()]);\r\n\t\tint off1 = rs.getFreq() - 1;\r\n\t\tint off2 = getArrayIndex(model, rs);\r\n\t\tint bs = model.getBinSumm()[off1][off2];\r\n\t\tif (model.getCoder().getCurrentShiftCount(ModelPPM.TOT_BITS) < bs) {\r\n\t\t\tmodel.getFoundState().setAddress(rs.getAddress());\r\n\t\t\trs.incFreq((rs.getFreq() < 128) ? 1 : 0);\r\n\t\t\tmodel.getCoder().getSubRange().setLowCount(0);\r\n\t\t\tmodel.getCoder().getSubRange().setHighCount(bs); \r\n\t\t\tbs = ((bs + ModelPPM.INTERVAL - getMean(bs, ModelPPM.PERIOD_BITS, 2)) & 0xffff);\r\n\t\t\tmodel.getBinSumm()[off1][off2] = bs;\r\n\t\t\tmodel.setPrevSuccess(1); \r\n\t\t\tmodel.incRunLength(1);\r\n\t\t} else {\r\n\t\t\tmodel.getCoder().getSubRange().setLowCount(bs);\r\n\t\t\tbs = (bs - getMean(bs, ModelPPM.PERIOD_BITS, 2)) & 0xFFFF;\r\n\t\t\tmodel.getBinSumm()[off1][off2] = bs;\r\n\t\t\tmodel.getCoder().getSubRange().setHighCount(ModelPPM.BIN_SCALE);\r\n\t\t\tmodel.setInitEsc(ExpEscape[bs >>> 10]);\r\n\t\t\tmodel.setNumMasked(1);\r\n\t\t\tmodel.getCharMask()[rs.getSymbol()] = model.getEscCount();\r\n\t\t\tmodel.setPrevSuccess(0);\r\n\t\t\tmodel.getFoundState().setAddress(0);\r\n\t\t}\r\n\t\t//int a = 0;//TODO just 4 debugging\r\n\t}\r\n\r\n//\tpublic static void ppmdSwap(ModelPPM model, StatePtr state1, StatePtr state2)\r\n//\t{\r\n//\t\tbyte[] bytes = model.getSubAlloc().getHeap();\r\n//\t\tint p1 = state1.getAddress();\r\n//\t\tint p2 = state2.getAddress();\r\n//\t\t\r\n//\t\tfor (int i = 0; i < StatePtr.size; i++) {\r\n//\t\t\tbyte temp = bytes[p1+i];\r\n//\t\t\tbytes[p1+i] = bytes[p2+i];\r\n//\t\t\tbytes[p2+i] = temp;\r\n//\t\t}\r\n//\t\tstate1.setAddress(p1);\r\n//\t\tstate2.setAddress(p2);\r\n//\t}\r\n\r\n\tpublic void update1(ModelPPM model, int p/* ptr */)\r\n\t{\r\n\t\tmodel.getFoundState().setAddress(p);\r\n\t\tmodel.getFoundState().incFreq(4);\r\n\t\tfreqData.incSummFreq(4);\r\n\t\tState p0 = tempState3.init(model.getHeap());\r\n\t\tState p1 = tempState4.init(model.getHeap());\r\n\t\tp0.setAddress(p);\r\n\t\tp1.setAddress(p - State.size);\r\n\t\tif (p0.getFreq() > p1.getFreq()) {\r\n\t\t\tState.ppmdSwap(p0, p1);\r\n\t\t\tmodel.getFoundState().setAddress(p1.getAddress());\r\n\t\t\tif (p1.getFreq() > ModelPPM.MAX_FREQ)\r\n\t\t\t\trescale(model);\r\n\t\t}\r\n\t}\r\n\r\n\tpublic boolean decodeSymbol2(ModelPPM model)\r\n\t{\r\n\t\tlong count;\r\n        int hiCnt, i = getNumStats() - model.getNumMasked();\r\n\t\tSEE2Context psee2c = makeEscFreq2(model, i);\r\n\t\tRangeCoder coder = model.getCoder();\r\n\t\t// STATE* ps[256], ** pps=ps, * p=U.Stats-1;\r\n\t\tState p = tempState1.init(model.getHeap());\r\n\t\tState temp = tempState2.init(model.getHeap());\r\n\t\tp.setAddress(freqData.getStats() - State.size); \r\n\t\tint pps = 0;\r\n\t\thiCnt = 0;\r\n\r\n\t\tdo {\r\n\t\t\tdo {\r\n\t\t\t\tp.incAddress();// p++;\r\n\t\t\t} while (model.getCharMask()[p.getSymbol()] == model.getEscCount());\r\n\t\t\thiCnt += p.getFreq();\r\n\t\t\tps[pps++] = p.getAddress();\r\n\t\t} while (--i != 0);\r\n\t\tcoder.getSubRange().incScale(hiCnt);\r\n\t\tcount = coder.getCurrentCount();\r\n\t\tif (count >= coder.getSubRange().getScale()) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\tpps = 0;\r\n\t\tp.setAddress(ps[pps]);\r\n\t\tif (count < hiCnt) {\r\n\t\t\thiCnt = 0;\r\n\t\t\twhile ((hiCnt += p.getFreq()) <= count) {\r\n\t\t\t\tp.setAddress(ps[++pps]);// p=*++pps;\r\n\t\t\t}\r\n\t\t\tcoder.getSubRange().setHighCount(hiCnt);\r\n\t\t\tcoder.getSubRange().setLowCount(hiCnt - p.getFreq());\r\n\t\t\tpsee2c.update();\r\n\t\t\tupdate2(model, p.getAddress());\r\n\t\t} else {\r\n\t\t\tcoder.getSubRange().setLowCount(hiCnt);\r\n\t\t\tcoder.getSubRange().setHighCount(coder.getSubRange().getScale());\r\n\t\t\ti = getNumStats() - model.getNumMasked();// ->NumMasked;\r\n\t\t\tpps--;\r\n\t\t\tdo {\r\n\t\t\t\ttemp.setAddress(ps[++pps]);// (*++pps)\r\n\t\t\t\tmodel.getCharMask()[temp.getSymbol()] = model.getEscCount();\r\n\t\t\t} while (--i != 0);\r\n\t\t\tpsee2c.incSumm((int)coder.getSubRange().getScale());\r\n\t\t\tmodel.setNumMasked(getNumStats());\r\n\t\t}\r\n\t\treturn (true);\r\n\t}\r\n\r\n\tpublic void update2(ModelPPM model, int p/* state ptr */)\r\n\t{\r\n\t\tState temp = tempState5.init(model.getHeap());\r\n\t\ttemp.setAddress(p);\r\n\t\tmodel.getFoundState().setAddress(p);\r\n\t\tmodel.getFoundState().incFreq(4); \r\n\t\tfreqData.incSummFreq(4);\r\n\t\tif (temp.getFreq() > ModelPPM.MAX_FREQ) {\r\n\t\t\trescale(model);\r\n\t\t}\r\n\t\tmodel.incEscCount(1);\r\n\t\tmodel.setRunLength(model.getInitRL());\r\n\t}\r\n\r\n\tprivate SEE2Context makeEscFreq2(ModelPPM model, int Diff)\r\n\t{\r\n\t\tSEE2Context psee2c;\r\n        int numStats = getNumStats();\r\n\t\tif (numStats != 256) {\r\n\t\t\tPPMContext suff = getTempPPMContext(model.getHeap());\r\n\t\t\tsuff.setAddress(getSuffix());\r\n            int idx1 = model.getNS2Indx()[Diff - 1];\r\n            int idx2 = 0;\r\n            idx2 += (Diff < suff.getNumStats() - numStats) ? 1 : 0;\r\n\t\t\tidx2 += 2 * ((freqData.getSummFreq() < 11 * numStats) ? 1 : 0); \r\n\t\t\tidx2 += 4 * ((model.getNumMasked() > Diff) ? 1 : 0); \r\n\t\t\tidx2 += model.getHiBitsFlag();\r\n\t\t\tpsee2c = model.getSEE2Cont()[idx1][idx2];\r\n\t\t\tmodel.getCoder().getSubRange().setScale(psee2c.getMean());\r\n\t\t} else {\r\n\t\t\tpsee2c = model.getDummySEE2Cont();\r\n\t\t\tmodel.getCoder().getSubRange().setScale(1);\r\n\t\t}\r\n\t\treturn psee2c;\r\n\t}\r\n\r\n\tpublic boolean decodeSymbol1(ModelPPM model)\r\n\t{\r\n\r\n\t\tRangeCoder coder = model.getCoder();\r\n\t\tcoder.getSubRange().setScale(freqData.getSummFreq());\r\n\t\tState p = new State(model.getHeap());\r\n\t\tp.setAddress(freqData.getStats());\r\n\t\tint i, HiCnt;\r\n\t\tlong count = coder.getCurrentCount();\r\n\t\tif (count >= coder.getSubRange().getScale()) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\tif (count < (HiCnt = p.getFreq())) {\r\n\t\t\tcoder.getSubRange().setHighCount(HiCnt);\r\n\t\t\tmodel.setPrevSuccess((2 * HiCnt > coder.getSubRange().getScale()) ? 1 : 0);\r\n\t\t\tmodel.incRunLength(model.getPrevSuccess());\r\n\t\t\tHiCnt += 4;\r\n\t\t\tmodel.getFoundState().setAddress(p.getAddress());\r\n\t\t\tmodel.getFoundState().setFreq(HiCnt);\r\n\t\t\tfreqData.incSummFreq(4);\r\n\t\t\tif (HiCnt > ModelPPM.MAX_FREQ) {\r\n\t\t\t\trescale(model);\r\n\t\t\t}\r\n\t\t\tcoder.getSubRange().setLowCount(0);\r\n\t\t\treturn true;\r\n\t\t} else {\r\n\t\t\tif (model.getFoundState().getAddress() == 0) {\r\n\t\t\t\treturn (false);\r\n\t\t\t}\r\n\t\t}\r\n\t\tmodel.setPrevSuccess(0);\r\n        int numStats = getNumStats();\r\n\t\ti = numStats - 1;\r\n\t\twhile ((HiCnt += p.incAddress().getFreq()) <= count)\r\n\t\t{\r\n\t\t\tif (--i == 0) {\r\n\t\t\t\tmodel.setHiBitsFlag(model.getHB2Flag()[model.getFoundState().getSymbol()]);\r\n\t\t\t\tcoder.getSubRange().setLowCount(HiCnt);\r\n\t\t\t\tmodel.getCharMask()[p.getSymbol()] = model.getEscCount();\r\n\t\t\t\tmodel.setNumMasked(numStats);\r\n\t\t\t\ti = numStats - 1;\r\n\t\t\t\tmodel.getFoundState().setAddress(0);\r\n\t\t\t\tdo {\r\n\t\t\t\t\tmodel.getCharMask()[p.decAddress().getSymbol()] = model.getEscCount();\r\n\t\t\t\t} while (--i != 0);\r\n\t\t\t\tcoder.getSubRange().setHighCount(coder.getSubRange().getScale());\r\n\t\t\t\treturn (true);\r\n\t\t\t}\r\n\t\t}\r\n\t\tcoder.getSubRange().setLowCount(HiCnt-p.getFreq());\r\n\t\tcoder.getSubRange().setHighCount(HiCnt);\r\n\t\tupdate1(model, p.getAddress());\r\n\t\treturn (true);\r\n\t}\r\n\r\n    public String toString() {\r\n        StringBuilder buffer = new StringBuilder();\r\n        buffer.append(\"PPMContext[\");\r\n        buffer.append(\"\\n  pos=\");\r\n        buffer.append(pos);\r\n        buffer.append(\"\\n  size=\");\r\n        buffer.append(size);\r\n        buffer.append(\"\\n  numStats=\");\r\n        buffer.append(getNumStats());\r\n        buffer.append(\"\\n  Suffix=\");\r\n        buffer.append(getSuffix());\r\n        buffer.append(\"\\n  freqData=\");\r\n        buffer.append(freqData);\r\n        buffer.append(\"\\n  oneState=\");\r\n        buffer.append(oneState);\r\n        buffer.append(\"\\n]\");\r\n        return buffer.toString();\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/ppm/Pointer.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 14.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.ppm;\r\n\r\n/**\r\n * Simulates Pointers on a single mem block as a byte[]\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic abstract class Pointer\r\n{\r\n\tprotected byte[] mem;\r\n\tprotected int pos;\r\n\t\r\n\t/** \r\n\t * Initialize the object with the array (may be null)\r\n\t * @param mem the byte array\r\n\t */\r\n\tpublic Pointer(byte[] mem){\r\n\t\tthis.mem = mem;\r\n\t}\r\n\t/**\r\n\t * returns the position of this object in the byte[] \r\n\t * @return the address of this object\r\n\t */\r\n\tpublic int getAddress(){\r\n        assert (mem != null);\r\n\t\treturn pos;\r\n\t}\r\n\r\n\t/**\r\n\t * needs to set the fields of this object to the values in the byte[] \r\n\t * at the given position.\r\n\t * be aware of the byte order\r\n\t * @param pos the position this object should point to\r\n\t * @return true if the address could be set\r\n\t */\r\n\tpublic void setAddress(int pos) {\r\n        assert (mem != null);\r\n        assert (pos >= 0) && (pos < mem.length) : pos;\r\n        this.pos = pos;\r\n    }\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/ppm/RangeCoder.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 31.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.ppm;\r\n\r\nimport java.io.IOException;\r\n\r\nimport com.github.junrar.exception.RarException;\r\nimport com.github.junrar.unpack.Unpack;\r\n\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class RangeCoder\r\n{\r\n\tpublic static final int TOP = 1 << 24;\r\n\r\n\tpublic static final int BOT = 1 << 15;\r\n\r\n\tprivate static final long uintMask = 0xFFFFffffL;\r\n\r\n    // uint low, code, range;\r\n\tprivate long low, code, range;\r\n\r\n\tprivate final SubRange subRange = new SubRange();\r\n\r\n\tprivate Unpack unpackRead;\r\n\r\n\tpublic SubRange getSubRange()\r\n\t{\r\n\t\treturn subRange;\r\n\t}\r\n\r\n\tpublic void initDecoder(Unpack unpackRead) throws IOException, RarException\r\n\t{\r\n\t\tthis.unpackRead = unpackRead;\r\n\r\n\t\tlow = code = 0L;\r\n\t\trange = 0xFFFFffffL;\r\n\t\tfor (int i = 0; i < 4; i++) {\r\n\t\t\tcode = ((code << 8) | getChar())&uintMask;\r\n\t\t}\r\n\t}\r\n\r\n\tpublic int getCurrentCount()\r\n\t{\r\n\t\trange = (range / subRange.getScale())&uintMask;\r\n\t\treturn (int)((code - low) / (range));\r\n\t}\r\n\r\n\tpublic long getCurrentShiftCount(int SHIFT)\r\n\t{\r\n\t\trange = range >>>SHIFT;\r\n\t\treturn ((code - low) / (range))&uintMask;\r\n\t}\r\n\r\n\tpublic void decode()\r\n\t{\r\n\t\tlow = (low + (range * subRange.getLowCount()))&uintMask;\r\n\t\trange = (range * (subRange.getHighCount() - subRange.getLowCount()))&uintMask;\r\n\t}\r\n\r\n    private int getChar() throws IOException, RarException\r\n\t{\r\n\t\treturn (unpackRead.getChar());\r\n\t}\r\n\r\n\tpublic void ariDecNormalize() throws IOException, RarException\r\n\t{\r\n//\t\twhile ((low ^ (low + range)) < TOP || range < BOT && ((range = -low & (BOT - 1)) != 0 ? true : true)) \r\n//\t\t{\r\n//\t\t\tcode = ((code << 8) | unpackRead.getChar()&0xff)&uintMask;\r\n//\t\t\trange = (range << 8)&uintMask;\r\n//\t\t\tlow = (low << 8)&uintMask;\r\n//\t\t}\r\n\r\n        // Rewrote for clarity\r\n        boolean c2 = false;\r\n\t\twhile ((low ^ (low + range)) < TOP || (c2 = range < BOT)) {\r\n            if (c2) {\r\n                range = (-low & (BOT - 1))&uintMask;\r\n                c2 = false;\r\n            }\r\n\t\t\tcode = ((code << 8) | getChar())&uintMask;\r\n\t\t\trange = (range << 8)&uintMask;\r\n\t\t\tlow = (low << 8)&uintMask;\r\n\t\t}\r\n    }\r\n\r\n    // Debug\r\n    public String toString() {\r\n        StringBuilder buffer = new StringBuilder();\r\n        buffer.append(\"RangeCoder[\");\r\n        buffer.append(\"\\n  low=\");\r\n        buffer.append(low);\r\n        buffer.append(\"\\n  code=\");\r\n        buffer.append(code);\r\n        buffer.append(\"\\n  range=\");\r\n        buffer.append(range);\r\n        buffer.append(\"\\n  subrange=\");\r\n        buffer.append(subRange);\r\n        buffer.append(\"]\");\r\n        return buffer.toString();\r\n    }\r\n\r\n\tpublic static class SubRange\r\n\t{\r\n        // uint LowCount, HighCount, scale;\r\n\t\tprivate long lowCount, highCount, scale;\r\n\r\n\t\tpublic long getHighCount()\r\n\t\t{\r\n\t\t\treturn highCount;\r\n\t\t}\r\n\r\n\t\tpublic void setHighCount(long highCount)\r\n\t\t{\r\n\t\t\tthis.highCount = highCount&uintMask;\r\n\t\t}\r\n\r\n\t\tpublic long getLowCount()\r\n\t\t{\r\n\t\t\treturn lowCount&uintMask;\r\n\t\t}\r\n\r\n\t\tpublic void setLowCount(long lowCount)\r\n\t\t{\r\n\t\t\tthis.lowCount = lowCount&uintMask;\r\n\t\t}\r\n\r\n\t\tpublic long getScale()\r\n\t\t{\r\n\t\t\treturn scale;\r\n\t\t}\r\n\r\n\t\tpublic void setScale(long scale)\r\n\t\t{\r\n\t\t\tthis.scale = scale&uintMask;\r\n\t\t}\r\n\r\n        public void incScale(int dScale) {\r\n            setScale(getScale() + dScale);\r\n        }\r\n        \r\n        // Debug\r\n        public String toString() {\r\n            StringBuilder buffer = new StringBuilder();\r\n            buffer.append(\"SubRange[\");\r\n            buffer.append(\"\\n  lowCount=\");\r\n            buffer.append(lowCount);\r\n            buffer.append(\"\\n  highCount=\");\r\n            buffer.append(highCount);\r\n            buffer.append(\"\\n  scale=\");\r\n            buffer.append(scale);\r\n            buffer.append(\"]\");\r\n            return buffer.toString();\r\n        }\r\n\t}\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/ppm/RarMemBlock.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 05.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.ppm;\r\n\r\nimport com.github.junrar.io.Raw;\r\n\r\n\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class RarMemBlock extends Pointer\r\n{\r\n\r\n    public static final int size = 12;\r\n\r\n\tprivate int stamp, NU;\r\n\r\n\tprivate int next, prev; // Pointer RarMemBlock\r\n\r\n\tpublic RarMemBlock(byte[] mem)\r\n\t{\r\n\t\tsuper(mem);\r\n\t}\r\n\r\n    public void insertAt(RarMemBlock p)\r\n\t{\r\n\t\tRarMemBlock temp = new RarMemBlock(mem);\r\n\t\tsetPrev(p.getAddress());\r\n\t\ttemp.setAddress(getPrev());\r\n\t\tsetNext(temp.getNext());// prev.getNext();\r\n\t\ttemp.setNext(this);// prev.setNext(this);\r\n\t\ttemp.setAddress(getNext());\r\n\t\ttemp.setPrev(this);// next.setPrev(this);\r\n\t}\r\n\r\n\tpublic void remove()\r\n\t{\r\n\t\tRarMemBlock temp = new RarMemBlock(mem);\r\n\t\ttemp.setAddress(getPrev());\r\n\t\ttemp.setNext(getNext());// prev.setNext(next);\r\n\t\ttemp.setAddress(getNext());\r\n\t\ttemp.setPrev(getPrev());// next.setPrev(prev);\r\n//\t\tnext = -1;\r\n//\t\tprev = -1;\r\n\t}\r\n\r\n\tpublic int getNext()\r\n\t{\r\n\t\tif(mem!=null){\r\n\t\t\tnext = Raw.readIntLittleEndian(mem,  pos+4);\r\n\t\t}\r\n\t\treturn next;\r\n\t}\r\n\r\n\tpublic void setNext(RarMemBlock next)\r\n\t{\r\n\t\tsetNext(next.getAddress());\r\n\t}\r\n\r\n\tpublic void setNext(int next)\r\n\t{\r\n\t\tthis.next = next;\r\n\t\tif (mem != null) {\r\n\t\t\tRaw.writeIntLittleEndian(mem, pos + 4, next);\r\n\t\t}\r\n\t}\r\n\r\n\tpublic int getNU()\r\n\t{\r\n\t\tif(mem!=null){\r\n\t\t\tNU = Raw.readShortLittleEndian(mem,  pos+2)&0xffff;\r\n\t\t}\r\n\t\treturn NU;\r\n\t}\r\n\r\n\tpublic void setNU(int nu)\r\n\t{\r\n\t\tNU = nu&0xffff;\r\n\t\tif (mem != null) {\r\n\t\t\tRaw.writeShortLittleEndian(mem, pos + 2, (short)nu);\r\n\t\t}\r\n\t}\r\n\r\n\tpublic int getPrev()\r\n\t{\r\n\t\tif(mem!=null){\r\n\t\t\tprev = Raw.readIntLittleEndian(mem,  pos+8);\r\n\t\t}\r\n\t\treturn prev;\r\n\t}\r\n\r\n\tpublic void setPrev(RarMemBlock prev)\r\n\t{\r\n\t\tsetPrev(prev.getAddress());\r\n\t}\r\n\r\n\tpublic void setPrev(int prev)\r\n\t{\r\n\t\tthis.prev = prev;\r\n\t\tif (mem != null) {\r\n\t\t\tRaw.writeIntLittleEndian(mem, pos + 8, prev);\r\n\t\t}\r\n\t}\r\n\r\n\tpublic int getStamp()\r\n\t{\r\n\t\tif(mem!=null){\r\n\t\t\tstamp =  Raw.readShortLittleEndian(mem,  pos)&0xffff;\r\n\t\t}\r\n\t\treturn stamp;\r\n\t}\r\n\r\n\tpublic void setStamp(int stamp)\r\n\t{\r\n\t\tthis.stamp = stamp;\r\n\t\tif (mem != null) {\r\n\t\t\tRaw.writeShortLittleEndian(mem, pos, (short)stamp);\r\n\t\t}\r\n\t}\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/ppm/RarNode.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 05.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.ppm;\r\n\r\nimport com.github.junrar.io.Raw;\r\n\r\n\r\n\r\n/**\r\n * DOCUMENT ME\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class RarNode extends Pointer{\r\n\tprivate int next; //rarnode pointer\r\n\r\n\tpublic static final int size = 4;\r\n\t\r\n\tpublic RarNode(byte[] mem){\r\n\t\tsuper(mem);\r\n\t}\r\n\t\r\n\tpublic int getNext() {\r\n\t\tif(mem!=null){\r\n\t\t\tnext = Raw.readIntLittleEndian(mem,  pos);\r\n\t\t}\r\n\t\treturn next;\r\n\t}\r\n\r\n\tpublic void setNext(RarNode next) {\r\n\t\tsetNext(next.getAddress());\r\n\t}\r\n\t\r\n\tpublic void setNext(int next) {\r\n\t\tthis.next = next;\r\n\t\tif(mem!=null){\r\n\t\t\tRaw.writeIntLittleEndian(mem, pos, next);\r\n\t\t}\r\n\t}\r\n\r\n    public String toString() {\r\n        StringBuilder buffer = new StringBuilder();\r\n        buffer.append(\"State[\");\r\n        buffer.append(\"\\n  pos=\");\r\n        buffer.append(pos);\r\n        buffer.append(\"\\n  size=\");\r\n        buffer.append(size);\r\n        buffer.append(\"\\n  next=\");\r\n        buffer.append(getNext());\r\n        buffer.append(\"\\n]\");\r\n        return buffer.toString();\r\n    }\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/ppm/SEE2Context.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 31.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.ppm;\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class SEE2Context {\r\n\tpublic static final int size = 4;\r\n\t\r\n    // ushort Summ;\r\n\tprivate int summ;\r\n\r\n    // byte Shift;\r\n\tprivate int shift;\r\n\r\n    // byte Count;\r\n\tprivate int count;\r\n\r\n\tpublic void init(int initVal) {\r\n\t\tshift = (ModelPPM.PERIOD_BITS - 4)&0xff;\r\n\t\tsumm = (initVal << shift)&0xffff;\r\n\t\tcount = 4;\r\n\t}\r\n\r\n    public int getMean() {\r\n        int retVal = summ >>> shift;\r\n\t\tsumm -= retVal;\r\n\t\treturn retVal + ((retVal == 0) ? 1 : 0);\r\n\t}\r\n\r\n\tpublic void update() {\r\n\t\tif (shift < ModelPPM.PERIOD_BITS && --count == 0) {\r\n\t\t\tsumm += summ;\r\n\t\t\tcount = (3 << shift++);\r\n\t\t}\r\n        summ &= 0xffff;\r\n        count &= 0xff;\r\n        shift &= 0xff;\r\n\t}\r\n\r\n\tpublic int getCount() {\r\n\t\treturn count;\r\n\t}\r\n\r\n\tpublic void setCount(int count) {\r\n\t\tthis.count = count&0xff;\r\n\t}\r\n\r\n\tpublic int getShift() {\r\n\t\treturn shift;\r\n\t}\r\n\r\n\tpublic void setShift(int shift) {\r\n\t\tthis.shift = shift&0xff;\r\n\t}\r\n\r\n\tpublic int getSumm() {\r\n\t\treturn summ;\r\n\t}\r\n\r\n\tpublic void setSumm(int summ) {\r\n\t\tthis.summ = summ&0xffff;\r\n\t}\r\n\r\n    public void incSumm(int dSumm) {\r\n        setSumm(getSumm() + dSumm);\r\n    }\r\n\r\n    public String toString() {\r\n        StringBuilder buffer = new StringBuilder();\r\n        buffer.append(\"SEE2Context[\");\r\n        buffer.append(\"\\n  size=\");\r\n        buffer.append(size);\r\n        buffer.append(\"\\n  summ=\");\r\n        buffer.append(summ);\r\n        buffer.append(\"\\n  shift=\");\r\n        buffer.append(shift);\r\n        buffer.append(\"\\n  count=\");\r\n        buffer.append(count);\r\n        buffer.append(\"\\n]\");\r\n        return buffer.toString();\r\n    }\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/ppm/State.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 01.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.ppm;\r\n\r\nimport com.github.junrar.io.Raw;\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class State extends Pointer {\r\n\r\n\tpublic static final int size = 6;\r\n\r\n\tpublic State(byte[] mem) {\r\n\t\tsuper(mem);\r\n\t}\r\n\r\n    public State init(byte[] mem) {\r\n\t\tthis.mem = mem;\r\n        pos = 0;\r\n        return this;\r\n    }\r\n\r\n\tpublic int getSymbol() {\r\n        return mem[pos]&0xff;\r\n\t}\r\n\r\n\tpublic void setSymbol(int symbol) {\r\n        mem[pos] = (byte)symbol;\r\n\t}\r\n\r\n\tpublic int getFreq() {\r\n        return mem[pos+1]&0xff;\r\n\t}\r\n\r\n\tpublic void setFreq(int freq) {\r\n        mem[pos + 1] = (byte)freq;\r\n\t}\r\n\r\n    public void incFreq(int dFreq) {\r\n        mem[pos + 1] += dFreq;\r\n    }\r\n\t\r\n\tpublic int getSuccessor() {\r\n        return Raw.readIntLittleEndian(mem, pos+2);\r\n\t}\r\n\r\n\tpublic void setSuccessor(PPMContext successor) {\r\n\t\tsetSuccessor(successor.getAddress());\r\n\t}\r\n\r\n\tpublic void setSuccessor(int successor) {\r\n        Raw.writeIntLittleEndian(mem, pos + 2, successor);\r\n\t}\r\n\r\n\tpublic void setValues(StateRef state){\r\n\t\tsetSymbol(state.getSymbol());\r\n\t\tsetFreq(state.getFreq());\r\n\t\tsetSuccessor(state.getSuccessor());\r\n\t}\r\n\r\n\tpublic void setValues(State ptr){\r\n        System.arraycopy(ptr.mem, ptr.pos, mem, pos, size);\r\n\t}\r\n\r\n\tpublic State decAddress(){\r\n\t\tsetAddress(pos-size);\r\n\t\treturn this;\r\n\t}\r\n\r\n    public State incAddress(){\r\n\t\tsetAddress(pos+size);\r\n\t\treturn this;\r\n\t}\r\n\r\n    public static void ppmdSwap(State ptr1, State ptr2) {\r\n        byte[] mem1=ptr1.mem, mem2=ptr2.mem;\r\n\t\tfor (int i=0, pos1=ptr1.pos, pos2=ptr2.pos; i < size; i++, pos1++, pos2++) {\r\n\t\t\tbyte temp = mem1[pos1];\r\n\t\t\tmem1[pos1] = mem2[pos2];\r\n\t\t\tmem2[pos2] = temp;\r\n\t\t}\r\n    }\r\n\r\n    public String toString() {\r\n        StringBuilder buffer = new StringBuilder();\r\n        buffer.append(\"State[\");\r\n        buffer.append(\"\\n  pos=\");\r\n        buffer.append(pos);\r\n        buffer.append(\"\\n  size=\");\r\n        buffer.append(size);\r\n        buffer.append(\"\\n  symbol=\");\r\n        buffer.append(getSymbol());\r\n        buffer.append(\"\\n  freq=\");\r\n        buffer.append(getFreq());\r\n        buffer.append(\"\\n  successor=\");\r\n        buffer.append(getSuccessor());\r\n        buffer.append(\"\\n]\");\r\n        return buffer.toString();\r\n    }\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/ppm/StateRef.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 01.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.ppm;\r\n\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class StateRef {\r\n\r\n\tprivate int symbol;\r\n\r\n\tprivate int freq;\r\n\r\n\tprivate int successor; // pointer ppmcontext\r\n\r\n\tpublic StateRef() {\r\n\t}\r\n\r\n\tpublic int getSymbol() {\r\n\t\treturn symbol;\r\n\t}\r\n\r\n\tpublic void setSymbol(int symbol) {\r\n\t\tthis.symbol = symbol&0xff;\r\n\t}\r\n\r\n\tpublic int getFreq() {\r\n\t\treturn freq;\r\n\t}\r\n\r\n\tpublic void setFreq(int freq) {\r\n\t\tthis.freq = freq&0xff;\r\n\t}\r\n\r\n    public void incFreq(int dFreq) {\r\n        freq = (freq + dFreq)&0xff;\r\n    }\r\n\r\n    public void decFreq(int dFreq) {\r\n        freq = (freq - dFreq)&0xff;\r\n    }\r\n\r\n\tpublic void setValues(State statePtr){\r\n\t\tsetFreq(statePtr.getFreq());\r\n\t\tsetSuccessor(statePtr.getSuccessor());\r\n\t\tsetSymbol(statePtr.getSymbol());\r\n\t}\r\n\t\r\n\tpublic int getSuccessor() {\r\n\t\treturn successor;\r\n\t}\r\n\r\n\tpublic void setSuccessor(PPMContext successor) {\r\n\t\tsetSuccessor(successor.getAddress());\r\n\t}\r\n\r\n\tpublic void setSuccessor(int successor) {\r\n\t\tthis.successor = successor;\r\n\t}\r\n\r\n    public String toString() {\r\n        StringBuilder buffer = new StringBuilder();\r\n        buffer.append(\"State[\");\r\n        buffer.append(\"\\n  symbol=\");\r\n        buffer.append(getSymbol());\r\n        buffer.append(\"\\n  freq=\");\r\n        buffer.append(getFreq());\r\n        buffer.append(\"\\n  successor=\");\r\n        buffer.append(getSuccessor());\r\n        buffer.append(\"\\n]\");\r\n        return buffer.toString();\r\n    }\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/ppm/SubAllocator.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 31.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.ppm;\r\n\r\nimport java.util.Arrays;\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class SubAllocator {\r\n    public static final int N1 = 4, N2 = 4, N3 = 4, N4 = (128 + 3 - 1 * N1 - 2\r\n\t    * N2 - 3 * N3) / 4;\r\n\r\n    public static final int N_INDEXES = N1 + N2 + N3 + N4;\r\n\r\n    public static final int UNIT_SIZE = Math.max(PPMContext.size,\r\n\t    RarMemBlock.size);\r\n\r\n    public static final int FIXED_UNIT_SIZE = 12;\r\n\r\n    private int subAllocatorSize;\r\n\r\n    // byte Indx2Units[N_INDEXES], Units2Indx[128], GlueCount;\r\n    private int[] indx2Units = new int[N_INDEXES];\r\n    private int[] units2Indx = new int[128];\r\n    private int glueCount;\r\n\r\n    // byte *HeapStart,*LoUnit, *HiUnit;\r\n    private int heapStart, loUnit, hiUnit;\r\n\r\n    private final RarNode[] freeList = new RarNode[N_INDEXES];\r\n\r\n    // byte *pText, *UnitsStart,*HeapEnd,*FakeUnitsStart;\r\n    private int pText, unitsStart, heapEnd, fakeUnitsStart;\r\n\r\n    private byte[] heap;\r\n\r\n    private int freeListPos;\r\n\r\n    private int tempMemBlockPos;\r\n\r\n    // Temp fields\r\n    private RarNode tempRarNode = null;\r\n    private RarMemBlock tempRarMemBlock1 = null;\r\n    private RarMemBlock tempRarMemBlock2 = null;\r\n    private RarMemBlock tempRarMemBlock3 = null;\r\n\r\n    public SubAllocator() {\r\n\tclean();\r\n    }\r\n\r\n    public void clean() {\r\n\tsubAllocatorSize = 0;\r\n    }\r\n\r\n    private void insertNode(int p/* rarnode ptr */, int indx) {\r\n\tRarNode temp = tempRarNode;\r\n\ttemp.setAddress(p);\r\n\ttemp.setNext(freeList[indx].getNext());\r\n\tfreeList[indx].setNext(temp);\r\n    }\r\n\r\n    public void incPText() {\r\n\tpText++;\r\n    }\r\n\r\n    private int removeNode(int indx) {\r\n\tint retVal = freeList[indx].getNext();\r\n\tRarNode temp = tempRarNode;\r\n\ttemp.setAddress(retVal);\r\n\tfreeList[indx].setNext(temp.getNext());\r\n\treturn retVal;\r\n    }\r\n\r\n    private int U2B(int NU) {\r\n\treturn /* 8*NU+4*NU */UNIT_SIZE * NU;\r\n    }\r\n\r\n    /* memblockptr */\r\n    private int MBPtr(int BasePtr, int Items) {\r\n\treturn (BasePtr + U2B(Items));\r\n    }\r\n\r\n    private void splitBlock(int pv/* ptr */, int oldIndx, int newIndx) {\r\n\tint i, uDiff = indx2Units[oldIndx] - indx2Units[newIndx];\r\n\tint p = pv + U2B(indx2Units[newIndx]);\r\n\tif (indx2Units[i = units2Indx[uDiff - 1]] != uDiff) {\r\n\t    insertNode(p, --i);\r\n\t    p += U2B(i = indx2Units[i]);\r\n\t    uDiff -= i;\r\n\t}\r\n\tinsertNode(p, units2Indx[uDiff - 1]);\r\n    }\r\n\r\n    public void stopSubAllocator() {\r\n\tif (subAllocatorSize != 0) {\r\n\t    subAllocatorSize = 0;\r\n\t    heap = null;\r\n\t    heapStart = 1;\r\n\t    // rarfree(HeapStart);\r\n\t    // Free temp fields\r\n\t    tempRarNode = null;\r\n\t    tempRarMemBlock1 = null;\r\n\t    tempRarMemBlock2 = null;\r\n\t    tempRarMemBlock3 = null;\r\n\t}\r\n    }\r\n\r\n    public int GetAllocatedMemory() {\r\n\treturn subAllocatorSize;\r\n    };\r\n\r\n    public boolean startSubAllocator(int SASize) {\r\n\tint t = SASize << 20;\r\n\tif (subAllocatorSize == t) {\r\n\t    return true;\r\n\t}\r\n\tstopSubAllocator();\r\n\tint allocSize = t / FIXED_UNIT_SIZE * UNIT_SIZE + UNIT_SIZE;\r\n\r\n\t// adding space for freelist (needed for poiters)\r\n\t// 1+ for null pointer\r\n\tint realAllocSize = 1 + allocSize + 4 * N_INDEXES;\r\n\t// adding space for an additional memblock\r\n\ttempMemBlockPos = realAllocSize;\r\n\trealAllocSize += RarMemBlock.size;\r\n\r\n\theap = new byte[realAllocSize];\r\n\theapStart = 1;\r\n\theapEnd = heapStart + allocSize - UNIT_SIZE;\r\n\tsubAllocatorSize = t;\r\n\t// Bug fixed\r\n\tfreeListPos = heapStart + allocSize;\r\n\tassert (realAllocSize - tempMemBlockPos == RarMemBlock.size) : realAllocSize\r\n\t\t+ \" \" + tempMemBlockPos + \" \" + RarMemBlock.size;\r\n\r\n\t// Init freeList\r\n\tfor (int i = 0, pos = freeListPos; i < freeList.length; i++, pos += RarNode.size) {\r\n\t    freeList[i] = new RarNode(heap);\r\n\t    freeList[i].setAddress(pos);\r\n\t}\r\n\r\n\t// Init temp fields\r\n\ttempRarNode = new RarNode(heap);\r\n\ttempRarMemBlock1 = new RarMemBlock(heap);\r\n\ttempRarMemBlock2 = new RarMemBlock(heap);\r\n\ttempRarMemBlock3 = new RarMemBlock(heap);\r\n\r\n\treturn true;\r\n    }\r\n\r\n    private void glueFreeBlocks() {\r\n\tRarMemBlock s0 = tempRarMemBlock1;\r\n\ts0.setAddress(tempMemBlockPos);\r\n\tRarMemBlock p = tempRarMemBlock2;\r\n\tRarMemBlock p1 = tempRarMemBlock3;\r\n\tint i, k, sz;\r\n\tif (loUnit != hiUnit) {\r\n\t    heap[loUnit] = 0;\r\n\t}\r\n\tfor (i = 0, s0.setPrev(s0), s0.setNext(s0); i < N_INDEXES; i++) {\r\n\t    while (freeList[i].getNext() != 0) {\r\n\t\tp.setAddress(removeNode(i));// =(RAR_MEM_BLK*)RemoveNode(i);\r\n\t\tp.insertAt(s0);// p->insertAt(&s0);\r\n\t\tp.setStamp(0xFFFF);// p->Stamp=0xFFFF;\r\n\t\tp.setNU(indx2Units[i]);// p->NU=Indx2Units[i];\r\n\t    }\r\n\t}\r\n\tfor (p.setAddress(s0.getNext()); p.getAddress() != s0.getAddress(); p\r\n\t\t.setAddress(p.getNext())) {\r\n\t    // while ((p1=MBPtr(p,p->NU))->Stamp == 0xFFFF && int(p->NU)+p1->NU\r\n\t    // < 0x10000)\r\n\t    // Bug fixed\r\n\t    p1.setAddress(MBPtr(p.getAddress(), p.getNU()));\r\n\t    while (p1.getStamp() == 0xFFFF && p.getNU() + p1.getNU() < 0x10000) {\r\n\t\tp1.remove();\r\n\t\tp.setNU(p.getNU() + p1.getNU());// ->NU += p1->NU;\r\n\t\tp1.setAddress(MBPtr(p.getAddress(), p.getNU()));\r\n\t    }\r\n\t}\r\n\t// while ((p=s0.next) != &s0)\r\n\t// Bug fixed\r\n\tp.setAddress(s0.getNext());\r\n\twhile (p.getAddress() != s0.getAddress()) {\r\n\t    for (p.remove(), sz = p.getNU(); sz > 128; sz -= 128, p\r\n\t\t    .setAddress(MBPtr(p.getAddress(), 128))) {\r\n\t\tinsertNode(p.getAddress(), N_INDEXES - 1);\r\n\t    }\r\n\t    if (indx2Units[i = units2Indx[sz - 1]] != sz) {\r\n\t\tk = sz - indx2Units[--i];\r\n\t\tinsertNode(MBPtr(p.getAddress(), sz - k), k - 1);\r\n\t    }\r\n\t    insertNode(p.getAddress(), i);\r\n\t    p.setAddress(s0.getNext());\r\n\t}\r\n    }\r\n\r\n    private int allocUnitsRare(int indx) {\r\n\tif (glueCount == 0) {\r\n\t    glueCount = 255;\r\n\t    glueFreeBlocks();\r\n\t    if (freeList[indx].getNext() != 0) {\r\n\t\treturn removeNode(indx);\r\n\t    }\r\n\t}\r\n\tint i = indx;\r\n\tdo {\r\n\t    if (++i == N_INDEXES) {\r\n\t\tglueCount--;\r\n\t\ti = U2B(indx2Units[indx]);\r\n\t\tint j = FIXED_UNIT_SIZE * indx2Units[indx];\r\n\t\tif (fakeUnitsStart - pText > j) {\r\n\t\t    fakeUnitsStart -= j;\r\n\t\t    unitsStart -= i;\r\n\t\t    return unitsStart;\r\n\t\t}\r\n\t\treturn (0);\r\n\t    }\r\n\t} while (freeList[i].getNext() == 0);\r\n\tint retVal = removeNode(i);\r\n\tsplitBlock(retVal, i, indx);\r\n\treturn retVal;\r\n    }\r\n\r\n    public int allocUnits(int NU) {\r\n\tint indx = units2Indx[NU - 1];\r\n\tif (freeList[indx].getNext() != 0) {\r\n\t    return removeNode(indx);\r\n\t}\r\n\tint retVal = loUnit;\r\n\tloUnit += U2B(indx2Units[indx]);\r\n\tif (loUnit <= hiUnit) {\r\n\t    return retVal;\r\n\t}\r\n\tloUnit -= U2B(indx2Units[indx]);\r\n\treturn allocUnitsRare(indx);\r\n    }\r\n\r\n    public int allocContext() {\r\n\tif (hiUnit != loUnit)\r\n\t    return (hiUnit -= UNIT_SIZE);\r\n\tif (freeList[0].getNext() != 0) {\r\n\t    return removeNode(0);\r\n\t}\r\n\treturn allocUnitsRare(0);\r\n    }\r\n\r\n    public int expandUnits(int oldPtr, int OldNU) {\r\n\tint i0 = units2Indx[OldNU - 1];\r\n\tint i1 = units2Indx[OldNU - 1 + 1];\r\n\tif (i0 == i1) {\r\n\t    return oldPtr;\r\n\t}\r\n\tint ptr = allocUnits(OldNU + 1);\r\n\tif (ptr != 0) {\r\n\t    // memcpy(ptr,OldPtr,U2B(OldNU));\r\n\t    System.arraycopy(heap, oldPtr, heap, ptr, U2B(OldNU));\r\n\t    insertNode(oldPtr, i0);\r\n\t}\r\n\treturn ptr;\r\n    }\r\n\r\n    public int shrinkUnits(int oldPtr, int oldNU, int newNU) {\r\n\t// System.out.println(\"SubAllocator.shrinkUnits(\" + OldPtr + \", \" +\r\n\t// OldNU + \", \" + NewNU + \")\");\r\n\tint i0 = units2Indx[oldNU - 1];\r\n\tint i1 = units2Indx[newNU - 1];\r\n\tif (i0 == i1) {\r\n\t    return oldPtr;\r\n\t}\r\n\tif (freeList[i1].getNext() != 0) {\r\n\t    int ptr = removeNode(i1);\r\n\t    // memcpy(ptr,OldPtr,U2B(NewNU));\r\n\t    // for (int i = 0; i < U2B(NewNU); i++) {\r\n\t    // heap[ptr + i] = heap[OldPtr + i];\r\n\t    // }\r\n\t    System.arraycopy(heap, oldPtr, heap, ptr, U2B(newNU));\r\n\t    insertNode(oldPtr, i0);\r\n\t    return ptr;\r\n\t} else {\r\n\t    splitBlock(oldPtr, i0, i1);\r\n\t    return oldPtr;\r\n\t}\r\n    }\r\n\r\n    public void freeUnits(int ptr, int OldNU) {\r\n\tinsertNode(ptr, units2Indx[OldNU - 1]);\r\n    }\r\n\r\n    public int getFakeUnitsStart() {\r\n\treturn fakeUnitsStart;\r\n    }\r\n\r\n    public void setFakeUnitsStart(int fakeUnitsStart) {\r\n\tthis.fakeUnitsStart = fakeUnitsStart;\r\n    }\r\n\r\n    public int getHeapEnd() {\r\n\treturn heapEnd;\r\n    }\r\n\r\n    public int getPText() {\r\n\treturn pText;\r\n    }\r\n\r\n    public void setPText(int text) {\r\n\tpText = text;\r\n    }\r\n\r\n    public void decPText(int dPText) {\r\n\tsetPText(getPText() - dPText);\r\n    }\r\n\r\n    public int getUnitsStart() {\r\n\treturn unitsStart;\r\n    }\r\n\r\n    public void setUnitsStart(int unitsStart) {\r\n\tthis.unitsStart = unitsStart;\r\n    }\r\n\r\n    public void initSubAllocator() {\r\n\tint i, k;\r\n\tArrays\r\n\t\t.fill(heap, freeListPos, freeListPos + sizeOfFreeList(),\r\n\t\t\t(byte) 0);\r\n\r\n\tpText = heapStart;\r\n\r\n\tint size2 = FIXED_UNIT_SIZE\r\n\t\t* (subAllocatorSize / 8 / FIXED_UNIT_SIZE * 7);\r\n\tint realSize2 = size2 / FIXED_UNIT_SIZE * UNIT_SIZE;\r\n\tint size1 = subAllocatorSize - size2;\r\n\tint realSize1 = size1 / FIXED_UNIT_SIZE * UNIT_SIZE + size1\r\n\t\t% FIXED_UNIT_SIZE;\r\n\thiUnit = heapStart + subAllocatorSize;\r\n\tloUnit = unitsStart = heapStart + realSize1;\r\n\tfakeUnitsStart = heapStart + size1;\r\n\thiUnit = loUnit + realSize2;\r\n\r\n\tfor (i = 0, k = 1; i < N1; i++, k += 1) {\r\n\t    indx2Units[i] = k & 0xff;\r\n\t}\r\n\tfor (k++; i < N1 + N2; i++, k += 2) {\r\n\t    indx2Units[i] = k & 0xff;\r\n\t}\r\n\tfor (k++; i < N1 + N2 + N3; i++, k += 3) {\r\n\t    indx2Units[i] = k & 0xff;\r\n\t}\r\n\tfor (k++; i < (N1 + N2 + N3 + N4); i++, k += 4) {\r\n\t    indx2Units[i] = k & 0xff;\r\n\t}\r\n\r\n\tfor (glueCount = 0, k = 0, i = 0; k < 128; k++) {\r\n\t    i += ((indx2Units[i] < (k + 1)) ? 1 : 0);\r\n\t    units2Indx[k] = i & 0xff;\r\n\t}\r\n\r\n    }\r\n\r\n    private int sizeOfFreeList() {\r\n\treturn freeList.length * RarNode.size;\r\n    }\r\n\r\n    public byte[] getHeap() {\r\n\treturn heap;\r\n    }\r\n\r\n    // Debug\r\n    // public void dumpHeap() {\r\n    // File file = new File(\"P:\\\\test\\\\heapdumpj\");\r\n    // OutputStream out = null;\r\n    // try {\r\n    // out = new FileOutputStream(file);\r\n    // out.write(heap, heapStart, heapEnd - heapStart);\r\n    // out.flush();\r\n    // System.out.println(\"Heap dumped to \" + file.getAbsolutePath());\r\n    // }\r\n    // catch (IOException e) {\r\n    // e.printStackTrace();\r\n    // }\r\n    // finally {\r\n    // FileUtil.close(out);\r\n    // }\r\n    // }\r\n\r\n    // Debug\r\n    public String toString() {\r\n\tStringBuilder buffer = new StringBuilder();\r\n\tbuffer.append(\"SubAllocator[\");\r\n\tbuffer.append(\"\\n  subAllocatorSize=\");\r\n\tbuffer.append(subAllocatorSize);\r\n\tbuffer.append(\"\\n  glueCount=\");\r\n\tbuffer.append(glueCount);\r\n\tbuffer.append(\"\\n  heapStart=\");\r\n\tbuffer.append(heapStart);\r\n\tbuffer.append(\"\\n  loUnit=\");\r\n\tbuffer.append(loUnit);\r\n\tbuffer.append(\"\\n  hiUnit=\");\r\n\tbuffer.append(hiUnit);\r\n\tbuffer.append(\"\\n  pText=\");\r\n\tbuffer.append(pText);\r\n\tbuffer.append(\"\\n  unitsStart=\");\r\n\tbuffer.append(unitsStart);\r\n\tbuffer.append(\"\\n]\");\r\n\treturn buffer.toString();\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/vm/BitInput.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 31.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.vm;\r\n\r\n/**\r\n * DOCUMENT ME\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class BitInput {\r\n\t/**\r\n\t * the max size of the input\r\n\t */\r\n\tpublic static final int MAX_SIZE = 0x8000;\r\n\tprotected int inAddr;\r\n\tprotected int inBit;\r\n\tprotected byte[] inBuf;\r\n\t\r\n\t/**\r\n\t * \r\n\t */\r\n\tpublic void InitBitInput()\r\n    {\r\n      inAddr=0;\r\n      inBit=0;\r\n    }\r\n    /**\r\n     * @param Bits \r\n     */\r\n    public void addbits(int Bits)\r\n    {\r\n      Bits+=inBit;\r\n      inAddr+=Bits>>3;\r\n      inBit=Bits&7;\r\n    }\r\n    \r\n    /**\r\n     * @return the bits (unsigned short)\r\n     */\r\n    public int getbits()\r\n    {\r\n//      int BitField=0;\r\n//      BitField|=(int)(inBuf[inAddr] << 16)&0xFF0000;\r\n//      BitField|=(int)(inBuf[inAddr+1] << 8)&0xff00;\r\n//      BitField|=(int)(inBuf[inAddr+2])&0xFF;\r\n//      BitField >>>= (8-inBit);\r\n//      return (BitField & 0xffff);\r\n      return (((((inBuf[inAddr] & 0xff) << 16) +\r\n              ((inBuf[inAddr+1] & 0xff) << 8) +\r\n              ((inBuf[inAddr+2] & 0xff))) >>> (8-inBit)) & 0xffff);\r\n    }\r\n\r\n    /**\r\n     *  \r\n     */\r\n    public BitInput()\r\n    {\r\n      inBuf=new byte[MAX_SIZE];\r\n    }\r\n\r\n    /**\r\n     * @param Bits add the bits\r\n     */\r\n    public void faddbits(int Bits)\r\n    {\r\n      addbits(Bits);\r\n    }\r\n\r\n\r\n    /**\r\n     * @return get the bits\r\n     */\r\n    public int fgetbits()\r\n    {\r\n      return(getbits());\r\n    }\r\n    \r\n    /**\r\n     * Indicates an Overfow\r\n     * @param IncPtr how many bytes to inc\r\n     * @return true if an Oververflow would occur\r\n     */\r\n    public boolean Overflow(int IncPtr) {\r\n    \treturn(inAddr+IncPtr>=MAX_SIZE);\r\n    }\r\n\tpublic byte[] getInBuf()\r\n\t{\r\n\t\treturn inBuf;\r\n\t}\r\n    \r\n    \r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/vm/RarVM.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 31.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.vm;\r\n\r\nimport java.util.List;\r\nimport java.util.Vector;\r\n\r\nimport com.github.junrar.crc.RarCRC;\r\nimport com.github.junrar.io.Raw;\r\n\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class RarVM extends BitInput {\r\n\r\n\tpublic static final int VM_MEMSIZE = 0x40000;\r\n\r\n\tpublic static final int VM_MEMMASK = (VM_MEMSIZE - 1);\r\n\r\n\tpublic static final int VM_GLOBALMEMADDR = 0x3C000;\r\n\r\n\tpublic static final int VM_GLOBALMEMSIZE = 0x2000;\r\n\r\n\tpublic static final int VM_FIXEDGLOBALSIZE = 64;\r\n\r\n\tprivate static final int regCount = 8;\r\n\r\n\tprivate static final long UINT_MASK = 0xffffFFFF;//((long)2*(long)Integer.MAX_VALUE);\r\n\r\n\tprivate byte[] mem;\r\n\r\n\tprivate int[] R = new int[regCount];\r\n\r\n\tprivate int flags;\r\n\r\n\tprivate int maxOpCount = 25000000;\r\n\r\n\tprivate int codeSize;\r\n\r\n\tprivate int IP;\r\n\r\n\tpublic RarVM() {\r\n\t\tmem = null;\r\n\t}\r\n\r\n\tpublic void init() {\r\n\t\tif (mem == null) {\r\n\t\t\tmem = new byte[VM_MEMSIZE + 4];\r\n\t\t}\r\n\t}\r\n\r\n\tprivate boolean isVMMem(byte[] mem) {\r\n\t\treturn this.mem == mem;\r\n\t}\r\n\r\n\tprivate int getValue(boolean byteMode, byte[] mem, int offset) {\r\n\t\tif (byteMode) {\r\n\t\t\tif (isVMMem(mem)) {\r\n\t\t\t\treturn (mem[offset]);\r\n\t\t\t} else {\r\n\t\t\t\treturn (mem[offset] & 0xff);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tif (isVMMem(mem)) {\r\n\t\t\t\t//little\r\n\t\t\t\treturn Raw.readIntLittleEndian(mem, offset);\r\n\t\t\t} else\r\n\t\t\t\t//big endian\r\n\t\t\t\treturn Raw.readIntBigEndian(mem, offset);\r\n\t\t}\r\n\t}\r\n\r\n\tprivate void setValue(boolean byteMode, byte[] mem, int offset, int value) {\r\n\t\tif (byteMode) {\r\n\t\t\tif (isVMMem(mem)) {\r\n\t\t\t\tmem[offset] = (byte) value;\r\n\t\t\t} else {\r\n\t\t\t\tmem[offset] = (byte) ((mem[offset] & 0x00) | (byte) (value & 0xff));\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tif (isVMMem(mem)) {\r\n\t\t\t\tRaw.writeIntLittleEndian(mem, offset, value);\r\n//\t\t\t\tmem[offset + 0] = (byte) value;\r\n//\t\t\t\tmem[offset + 1] = (byte) (value >>> 8);\r\n//\t\t\t\tmem[offset + 2] = (byte) (value >>> 16);\r\n//\t\t\t\tmem[offset + 3] = (byte) (value >>> 24);\r\n\t\t\t} else {\r\n\t\t\t\tRaw.writeIntBigEndian(mem, offset, value);\r\n//\t\t\t\tmem[offset + 3] = (byte) value;\r\n//\t\t\t\tmem[offset + 2] = (byte) (value >>> 8);\r\n//\t\t\t\tmem[offset + 1] = (byte) (value >>> 16);\r\n//\t\t\t\tmem[offset + 0] = (byte) (value >>> 24);\r\n\t\t\t}\r\n\r\n\t\t}\r\n\t\t// #define SET_VALUE(ByteMode,Addr,Value) SetValue(ByteMode,(uint\r\n\t\t// *)Addr,Value)\r\n\t}\r\n\r\n\tpublic void setLowEndianValue(byte[] mem, int offset, int value) {\r\n\t\tRaw.writeIntLittleEndian(mem, offset, value);\r\n//\t\tmem[offset + 0] = (byte) (value&0xff);\r\n//\t\tmem[offset + 1] = (byte) ((value >>> 8)&0xff);\r\n//\t\tmem[offset + 2] = (byte) ((value >>> 16)&0xff);\r\n//\t\tmem[offset + 3] = (byte) ((value >>> 24)&0xff);\r\n\t}\r\n\tpublic void setLowEndianValue(Vector<Byte> mem, int offset, int value) {\r\n\t\tmem.set(offset + 0, Byte.valueOf((byte) (value&0xff))) ;\r\n\t\tmem.set(offset + 1, Byte.valueOf((byte) ((value >>> 8)&0xff))); \r\n\t\tmem.set(offset + 2, Byte.valueOf((byte) ((value >>> 16)&0xff) )); \r\n\t\tmem.set(offset + 3, Byte.valueOf((byte) ((value >>> 24)&0xff))) ;\r\n\t}\r\n\tprivate int getOperand(VMPreparedOperand cmdOp) {\r\n\t\tint ret = 0;\r\n\t\tif (cmdOp.getType() == VMOpType.VM_OPREGMEM) {\r\n\t\t\tint pos = (cmdOp.getOffset() + cmdOp.getBase()) & VM_MEMMASK;\r\n\t\t\tret = Raw.readIntLittleEndian(mem, pos);\r\n\t\t} else {\r\n\t\t\tint pos = cmdOp.getOffset();\r\n\t\t\tret = Raw.readIntLittleEndian(mem, pos);\r\n\t\t}\r\n\t\treturn ret;\r\n\t}\r\n\r\n\tpublic void execute(VMPreparedProgram prg) {\r\n\t\tfor (int i = 0; i < prg.getInitR().length; i++) // memcpy(R,Prg->InitR,sizeof(Prg->InitR));\r\n\t\t{\r\n\t\t\tR[i] = prg.getInitR()[i];\r\n\t\t}\r\n\r\n\t\tlong globalSize = Math\r\n\t\t\t\t.min(prg.getGlobalData().size(), VM_GLOBALMEMSIZE) & 0xffFFffFF;\r\n\t\tif (globalSize != 0) {\r\n\t\t\tfor (int i = 0; i < globalSize; i++) // memcpy(Mem+VM_GLOBALMEMADDR,&Prg->GlobalData[0],GlobalSize);\r\n\t\t\t{\r\n\t\t\t\tmem[VM_GLOBALMEMADDR + i] = prg.getGlobalData().get(i);\r\n\t\t\t}\r\n\r\n\t\t}\r\n\t\tlong staticSize = Math.min(prg.getStaticData().size(), VM_GLOBALMEMSIZE\r\n\t\t\t\t- globalSize) & 0xffFFffFF;\r\n\t\tif (staticSize != 0) {\r\n\t\t\tfor (int i = 0; i < staticSize; i++) // memcpy(Mem+VM_GLOBALMEMADDR+GlobalSize,&Prg->StaticData[0],StaticSize);\r\n\t\t\t{\r\n\t\t\t\tmem[VM_GLOBALMEMADDR + (int) globalSize + i] = prg\r\n\t\t\t\t\t\t.getStaticData().get(i);\r\n\t\t\t}\r\n\r\n\t\t}\r\n\t\tR[7] = VM_MEMSIZE;\r\n\t\tflags = 0;\r\n\r\n\t\tList<VMPreparedCommand> preparedCode = prg.getAltCmd().size() != 0 ? prg\r\n\t\t\t\t.getAltCmd()\r\n\t\t\t\t: prg.getCmd();\r\n\r\n\t\tif (!ExecuteCode(preparedCode, prg.getCmdCount())) {\r\n\t\t\tpreparedCode.get(0).setOpCode(VMCommands.VM_RET);\r\n\t\t}\r\n\t\tint newBlockPos = getValue(false, mem, VM_GLOBALMEMADDR + 0x20)\r\n\t\t\t\t& VM_MEMMASK;\r\n\t\tint newBlockSize = getValue(false, mem, VM_GLOBALMEMADDR + 0x1c)\r\n\t\t\t\t& VM_MEMMASK;\r\n\t\tif ((newBlockPos + newBlockSize) >= VM_MEMSIZE) {\r\n\t\t\tnewBlockPos = 0;\r\n\t\t\tnewBlockSize = 0;\r\n\t\t}\r\n\r\n\t\tprg.setFilteredDataOffset(newBlockPos);\r\n\t\tprg.setFilteredDataSize(newBlockSize);\r\n\r\n\t\tprg.getGlobalData().clear();\r\n\r\n\t\tint dataSize = Math.min(getValue(false, mem, VM_GLOBALMEMADDR + 0x30),\r\n\t\t\t\tVM_GLOBALMEMSIZE - VM_FIXEDGLOBALSIZE);\r\n\t\tif (dataSize != 0) {\r\n\t\t\tprg.getGlobalData().setSize(dataSize + VM_FIXEDGLOBALSIZE);\r\n\t\t\t// ->GlobalData.Add(dataSize+VM_FIXEDGLOBALSIZE);\r\n\r\n\t\t\tfor (int i = 0; i < dataSize + VM_FIXEDGLOBALSIZE; i++) // memcpy(&Prg->GlobalData[0],&Mem[VM_GLOBALMEMADDR],DataSize+VM_FIXEDGLOBALSIZE);\r\n\t\t\t{\r\n\t\t\t\tprg.getGlobalData().set(i, mem[VM_GLOBALMEMADDR + i]);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tpublic byte[] getMem()\r\n\t{\r\n\t\treturn mem;\r\n\t}\r\n\r\n\tprivate boolean setIP(int ip) {\r\n\t\tif ((ip) >= codeSize) {\r\n\t\t\treturn (true);\r\n\t\t}\r\n\r\n\t\tif (--maxOpCount <= 0) {\r\n\t\t\treturn (false);\r\n\t\t}\r\n\r\n\t\tIP = ip;\r\n\t\treturn true;\r\n\t}\r\n\r\n\tprivate boolean ExecuteCode(List<VMPreparedCommand> preparedCode,\r\n\t\t\tint cmdCount) {\r\n\r\n\t\tmaxOpCount = 25000000;\r\n\t\tthis.codeSize = cmdCount;\r\n\t\tthis.IP = 0;\r\n\t\t\r\n\t\twhile (true) {\r\n\t\t\tVMPreparedCommand cmd = preparedCode.get(IP);\r\n\t\t\tint op1 = getOperand(cmd.getOp1());\r\n\t\t\tint op2 = getOperand(cmd.getOp2());\r\n\t\t\tswitch (cmd.getOpCode()) {\r\n\t\t\tcase VM_MOV:\r\n\t\t\t\tsetValue(cmd.isByteMode(), mem, op1, getValue(cmd.isByteMode(),\r\n\t\t\t\t\t\tmem, op2)); // SET_VALUE(Cmd->ByteMode,Op1,GET_VALUE(Cmd->ByteMode,Op2));\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_MOVB:\r\n\t\t\t\tsetValue(true, mem, op1, getValue(true, mem, op2));\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_MOVD:\r\n\t\t\t\tsetValue(false, mem, op1, getValue(false, mem, op2));\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase VM_CMP: {\r\n\t\t\t\tint value1 = getValue(cmd.isByteMode(), mem, op1);\r\n\t\t\t\tint result = value1 - getValue(cmd.isByteMode(), mem, op2);\r\n\r\n\t\t\t\tif (result == 0) {\r\n\t\t\t\t\tflags = VMFlags.VM_FZ.getFlag();\r\n\t\t\t\t} else {\r\n\t\t\t\t\tflags = (result > value1) ? 1 : 0 | (result & VMFlags.VM_FS\r\n\t\t\t\t\t\t\t.getFlag());\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase VM_CMPB: {\r\n\t\t\t\tint value1 = getValue(true, mem, op1);\r\n\t\t\t\tint result = value1 - getValue(true, mem, op2);\r\n\t\t\t\tif (result == 0) {\r\n\t\t\t\t\tflags = VMFlags.VM_FZ.getFlag();\r\n\t\t\t\t} else {\r\n\t\t\t\t\tflags = (result > value1) ? 1 : 0 | (result & VMFlags.VM_FS\r\n\t\t\t\t\t\t\t.getFlag());\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_CMPD: {\r\n\t\t\t\tint value1 = getValue(false, mem, op1);\r\n\t\t\t\tint result = value1 - getValue(false, mem, op2);\r\n\t\t\t\tif (result == 0) {\r\n\t\t\t\t\tflags = VMFlags.VM_FZ.getFlag();\r\n\t\t\t\t} else {\r\n\t\t\t\t\tflags = (result > value1) ? 1 : 0 | (result & VMFlags.VM_FS\r\n\t\t\t\t\t\t\t.getFlag());\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase VM_ADD: {\r\n\t\t\t\tint value1 = getValue(cmd.isByteMode(), mem, op1);\r\n\t\t\t\tint result = (int) ((((long) value1 + (long) getValue(cmd\r\n\t\t\t\t\t\t.isByteMode(), mem, op2))) & 0xffffffff);\r\n\t\t\t\tif (cmd.isByteMode()) {\r\n\t\t\t\t\tresult &= 0xff;\r\n\t\t\t\t\tflags = (result < value1) ? 1\r\n\t\t\t\t\t\t\t: 0 | (result == 0 ? VMFlags.VM_FZ.getFlag()\r\n\t\t\t\t\t\t\t\t\t: ((result & 0x80) != 0) ? VMFlags.VM_FS\r\n\t\t\t\t\t\t\t\t\t\t\t.getFlag() : 0);\r\n\t\t\t\t\t// Flags=(Result<Value1)|(Result==0 ? VM_FZ:((Result&0x80) ?\r\n\t\t\t\t\t// VM_FS:0));\r\n\t\t\t\t} else\r\n\t\t\t\t\tflags = (result < value1) ? 1\r\n\t\t\t\t\t\t\t: 0 | (result == 0 ? VMFlags.VM_FZ.getFlag()\r\n\t\t\t\t\t\t\t\t\t: (result & VMFlags.VM_FS.getFlag()));\r\n\t\t\t\tsetValue(cmd.isByteMode(), mem, op1, result);\r\n\t\t\t}\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase VM_ADDB:\r\n\t\t\t\tsetValue(true, mem, op1,\r\n\t\t\t\t\t\t(int) ((long) getValue(true, mem, op1) & 0xFFffFFff\r\n\t\t\t\t\t\t\t\t+ (long) getValue(true, mem, op2) & 0xFFffFFff));\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_ADDD:\r\n\t\t\t\tsetValue(\r\n\t\t\t\t\t\tfalse,\r\n\t\t\t\t\t\tmem,\r\n\t\t\t\t\t\top1,\r\n\t\t\t\t\t\t(int) ((long) getValue(false, mem, op1) & 0xFFffFFff\r\n\t\t\t\t\t\t\t\t+ (long) getValue(false, mem, op2) & 0xFFffFFff));\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase VM_SUB: {\r\n\t\t\t\tint value1 = getValue(cmd.isByteMode(), mem, op1);\r\n\t\t\t\tint result = (int) ((long) value1 & 0xffFFffFF\r\n\t\t\t\t\t\t- (long) getValue(cmd.isByteMode(), mem, op2) & 0xFFffFFff);\r\n\t\t\t\tflags = (result == 0) ? VMFlags.VM_FZ.getFlag()\r\n\t\t\t\t\t\t: (result > value1) ? 1 : 0 | (result & VMFlags.VM_FS\r\n\t\t\t\t\t\t\t\t.getFlag());\r\n\t\t\t\tsetValue(cmd.isByteMode(), mem, op1, result);// (Cmd->ByteMode,Op1,Result);\r\n\t\t\t}\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase VM_SUBB:\r\n\t\t\t\tsetValue(true, mem, op1,\r\n\t\t\t\t\t\t(int) ((long) getValue(true, mem, op1) & 0xFFffFFff\r\n\t\t\t\t\t\t\t\t- (long) getValue(true, mem, op2) & 0xFFffFFff));\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_SUBD:\r\n\t\t\t\tsetValue(\r\n\t\t\t\t\t\tfalse,\r\n\t\t\t\t\t\tmem,\r\n\t\t\t\t\t\top1,\r\n\t\t\t\t\t\t(int) ((long) getValue(false, mem, op1) & 0xFFffFFff\r\n\t\t\t\t\t\t\t\t- (long) getValue(false, mem, op2) & 0xFFffFFff));\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase VM_JZ:\r\n\t\t\t\tif ((flags & VMFlags.VM_FZ.getFlag()) != 0) {\r\n\t\t\t\t\tsetIP(getValue(false, mem, op1));\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_JNZ:\r\n\t\t\t\tif ((flags & VMFlags.VM_FZ.getFlag()) == 0) {\r\n\t\t\t\t\tsetIP(getValue(false, mem, op1));\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_INC: {\r\n\t\t\t\tint result = (int) ((long) getValue(cmd.isByteMode(), mem, op1) & 0xFFffFFff + 1);\r\n\t\t\t\tif (cmd.isByteMode()) {\r\n\t\t\t\t\tresult &= 0xff;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tsetValue(cmd.isByteMode(), mem, op1, result);\r\n\t\t\t\tflags = result == 0 ? VMFlags.VM_FZ.getFlag() : result\r\n\t\t\t\t\t\t& VMFlags.VM_FS.getFlag();\r\n\t\t\t}\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase VM_INCB:\r\n\t\t\t\tsetValue(\r\n\t\t\t\t\t\ttrue,\r\n\t\t\t\t\t\tmem,\r\n\t\t\t\t\t\top1,\r\n\t\t\t\t\t\t(int) ((long) getValue(true, mem, op1) & 0xFFffFFff + 1));\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_INCD:\r\n\t\t\t\tsetValue(false, mem, op1, (int) ((long) getValue(false, mem,\r\n\t\t\t\t\t\top1) & 0xFFffFFff + 1));\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase VM_DEC: {\r\n\t\t\t\tint result = (int) ((long) getValue(cmd.isByteMode(), mem, op1) & 0xFFffFFff - 1);\r\n\t\t\t\tsetValue(cmd.isByteMode(), mem, op1, result);\r\n\t\t\t\tflags = result == 0 ? VMFlags.VM_FZ.getFlag() : result\r\n\t\t\t\t\t\t& VMFlags.VM_FS.getFlag();\r\n\t\t\t}\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase VM_DECB:\r\n\t\t\t\tsetValue(\r\n\t\t\t\t\t\ttrue,\r\n\t\t\t\t\t\tmem,\r\n\t\t\t\t\t\top1,\r\n\t\t\t\t\t\t(int) ((long) getValue(true, mem, op1) & 0xFFffFFff - 1));\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_DECD:\r\n\t\t\t\tsetValue(false, mem, op1, (int) ((long) getValue(false, mem,\r\n\t\t\t\t\t\top1) & 0xFFffFFff - 1));\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase VM_JMP:\r\n\t\t\t\tsetIP(getValue(false, mem, op1));\r\n\t\t\t\tcontinue;\r\n\t\t\tcase VM_XOR: {\r\n\t\t\t\tint result = getValue(cmd.isByteMode(), mem, op1)\r\n\t\t\t\t\t\t^ getValue(cmd.isByteMode(), mem, op2);\r\n\t\t\t\tflags = result == 0 ? VMFlags.VM_FZ.getFlag() : result\r\n\t\t\t\t\t\t& VMFlags.VM_FS.getFlag();\r\n\t\t\t\tsetValue(cmd.isByteMode(), mem, op1, result);\r\n\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_AND: {\r\n\t\t\t\tint result = getValue(cmd.isByteMode(), mem, op1)\r\n\t\t\t\t\t\t& getValue(cmd.isByteMode(), mem, op2);\r\n\t\t\t\tflags = result == 0 ? VMFlags.VM_FZ.getFlag() : result\r\n\t\t\t\t\t\t& VMFlags.VM_FS.getFlag();\r\n\t\t\t\tsetValue(cmd.isByteMode(), mem, op1, result);\r\n\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_OR: {\r\n\t\t\t\tint result = getValue(cmd.isByteMode(), mem, op1)\r\n\t\t\t\t\t\t| getValue(cmd.isByteMode(), mem, op2);\r\n\t\t\t\tflags = result == 0 ? VMFlags.VM_FZ.getFlag() : result\r\n\t\t\t\t\t\t& VMFlags.VM_FS.getFlag();\r\n\t\t\t\tsetValue(cmd.isByteMode(), mem, op1, result);\r\n\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_TEST: {\r\n\t\t\t\tint result = getValue(cmd.isByteMode(), mem, op1)\r\n\t\t\t\t\t\t& getValue(cmd.isByteMode(), mem, op2);\r\n\t\t\t\tflags = result == 0 ? VMFlags.VM_FZ.getFlag() : result\r\n\t\t\t\t\t\t& VMFlags.VM_FS.getFlag();\r\n\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_JS:\r\n\t\t\t\tif ((flags & VMFlags.VM_FS.getFlag()) != 0) {\r\n\t\t\t\t\tsetIP(getValue(false, mem, op1));\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_JNS:\r\n\t\t\t\tif ((flags & VMFlags.VM_FS.getFlag()) == 0) {\r\n\t\t\t\t\tsetIP(getValue(false, mem, op1));\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_JB:\r\n\t\t\t\tif ((flags & VMFlags.VM_FC.getFlag()) != 0) {\r\n\t\t\t\t\tsetIP(getValue(false, mem, op1));\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_JBE:\r\n\t\t\t\tif ((flags & (VMFlags.VM_FC.getFlag() | VMFlags.VM_FZ.getFlag())) != 0) {\r\n\t\t\t\t\tsetIP(getValue(false, mem, op1));\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_JA:\r\n\t\t\t\tif ((flags & (VMFlags.VM_FC.getFlag() | VMFlags.VM_FZ.getFlag())) == 0) {\r\n\t\t\t\t\tsetIP(getValue(false, mem, op1));\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_JAE:\r\n\t\t\t\tif ((flags & VMFlags.VM_FC.getFlag()) == 0) {\r\n\t\t\t\t\tsetIP(getValue(false, mem, op1));\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_PUSH:\r\n\t\t\t\tR[7] -= 4;\r\n\t\t\t\tsetValue(false, mem, R[7] & VM_MEMMASK, getValue(false, mem,\r\n\t\t\t\t\t\top1));\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_POP:\r\n\t\t\t\tsetValue(false, mem, op1, getValue(false, mem, R[7]\r\n\t\t\t\t\t\t& VM_MEMMASK));\r\n\t\t\t\tR[7] += 4;\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_CALL:\r\n\t\t\t\tR[7] -= 4;\r\n\t\t\t\tsetValue(false, mem, R[7] & VM_MEMMASK, IP + 1);\r\n\t\t\t\tsetIP(getValue(false, mem, op1));\r\n\t\t\t\tcontinue;\r\n\t\t\tcase VM_NOT:\r\n\t\t\t\tsetValue(cmd.isByteMode(), mem, op1, ~getValue(\r\n\t\t\t\t\t\tcmd.isByteMode(), mem, op1));\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_SHL: {\r\n\t\t\t\tint value1 = getValue(cmd.isByteMode(), mem, op1);\r\n\t\t\t\tint value2 = getValue(cmd.isByteMode(), mem, op2);\r\n\t\t\t\tint result = value1 << value2;\r\n\t\t\t\tflags = (result == 0 ? VMFlags.VM_FZ.getFlag()\r\n\t\t\t\t\t\t: (result & VMFlags.VM_FS.getFlag()))\r\n\t\t\t\t\t\t| (((value1 << (value2 - 1)) & 0x80000000) != 0 ? VMFlags.VM_FC\r\n\t\t\t\t\t\t\t\t.getFlag()\r\n\t\t\t\t\t\t\t\t: 0);\r\n\t\t\t\tsetValue(cmd.isByteMode(), mem, op1, result);\r\n\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_SHR: {\r\n\t\t\t\tint value1 = getValue(cmd.isByteMode(), mem, op1);\r\n\t\t\t\tint value2 = getValue(cmd.isByteMode(), mem, op2);\r\n\t\t\t\tint result = value1 >>> value2;\r\n\t\t\t\tflags = (result == 0 ? VMFlags.VM_FZ.getFlag()\r\n\t\t\t\t\t\t: (result & VMFlags.VM_FS.getFlag()))\r\n\t\t\t\t\t\t| ((value1 >>> (value2 - 1)) & VMFlags.VM_FC.getFlag());\r\n\t\t\t\tsetValue(cmd.isByteMode(), mem, op1, result);\r\n\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_SAR: {\r\n\t\t\t\tint value1 = getValue(cmd.isByteMode(), mem, op1);\r\n\t\t\t\tint value2 = getValue(cmd.isByteMode(), mem, op2);\r\n\t\t\t\tint result = ((int) value1) >> value2;\r\n\t\t\t\tflags = (result == 0 ? VMFlags.VM_FZ.getFlag()\r\n\t\t\t\t\t\t: (result & VMFlags.VM_FS.getFlag()))\r\n\t\t\t\t\t\t| ((value1 >> (value2 - 1)) & VMFlags.VM_FC.getFlag());\r\n\t\t\t\tsetValue(cmd.isByteMode(), mem, op1, result);\r\n\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_NEG: {\r\n\t\t\t\tint result = -getValue(cmd.isByteMode(), mem, op1);\r\n\t\t\t\tflags = result == 0 ? VMFlags.VM_FZ.getFlag() : VMFlags.VM_FC\r\n\t\t\t\t\t\t.getFlag()\r\n\t\t\t\t\t\t| (result & VMFlags.VM_FS.getFlag());\r\n\t\t\t\tsetValue(cmd.isByteMode(), mem, op1, result);\r\n\t\t\t}\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase VM_NEGB:\r\n\t\t\t\tsetValue(true, mem, op1, -getValue(true, mem, op1));\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_NEGD:\r\n\t\t\t\tsetValue(false, mem, op1, -getValue(false, mem, op1));\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_PUSHA: {\r\n\t\t\t\tfor (int i = 0, SP = R[7] - 4; i < regCount; i++, SP -= 4) {\r\n\t\t\t\t\tsetValue(false, mem, SP & VM_MEMMASK, R[i]);\r\n\t\t\t\t}\r\n\t\t\t\tR[7] -= regCount * 4;\r\n\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_POPA: {\r\n\t\t\t\tfor (int i = 0, SP = R[7]; i < regCount; i++, SP += 4)\r\n\t\t\t\t\tR[7 - i] = getValue(false, mem, SP & VM_MEMMASK);\r\n\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_PUSHF:\r\n\t\t\t\tR[7] -= 4;\r\n\t\t\t\tsetValue(false, mem, R[7] & VM_MEMMASK, flags);\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_POPF:\r\n\t\t\t\tflags = getValue(false, mem, R[7] & VM_MEMMASK);\r\n\t\t\t\tR[7] += 4;\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_MOVZX:\r\n\t\t\t\tsetValue(false, mem, op1, getValue(true, mem, op2));\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_MOVSX:\r\n\t\t\t\tsetValue(false, mem, op1, (byte) getValue(true, mem, op2));\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_XCHG: {\r\n\t\t\t\tint value1 = getValue(cmd.isByteMode(), mem, op1);\r\n\t\t\t\tsetValue(cmd.isByteMode(), mem, op1, getValue(cmd.isByteMode(),\r\n\t\t\t\t\t\tmem, op2));\r\n\t\t\t\tsetValue(cmd.isByteMode(), mem, op2, value1);\r\n\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_MUL: {\r\n\t\t\t\tint result = (int) (((long) getValue(cmd.isByteMode(), mem, op1)\r\n\t\t\t\t\t\t& 0xFFffFFff\r\n\t\t\t\t\t\t* (long) getValue(cmd.isByteMode(), mem, op2) & 0xFFffFFff) & 0xFFffFFff);\r\n\t\t\t\tsetValue(cmd.isByteMode(), mem, op1, result);\r\n\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_DIV: {\r\n\t\t\t\tint divider = getValue(cmd.isByteMode(), mem, op2);\r\n\t\t\t\tif (divider != 0) {\r\n\t\t\t\t\tint result = getValue(cmd.isByteMode(), mem, op1) / divider;\r\n\t\t\t\t\tsetValue(cmd.isByteMode(), mem, op1, result);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_ADC: {\r\n\t\t\t\tint value1 = getValue(cmd.isByteMode(), mem, op1);\r\n\t\t\t\tint FC = (flags & VMFlags.VM_FC.getFlag());\r\n\t\t\t\tint result = (int) ((long) value1 & 0xFFffFFff\r\n\t\t\t\t\t\t+ (long) getValue(cmd.isByteMode(), mem, op2)\r\n\t\t\t\t\t\t& 0xFFffFFff + (long) FC & 0xFFffFFff);\r\n\t\t\t\tif (cmd.isByteMode()) {\r\n\t\t\t\t\tresult &= 0xff;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tflags = (result < value1 || result == value1 && FC != 0) ? 1\r\n\t\t\t\t\t\t: 0 | (result == 0 ? VMFlags.VM_FZ.getFlag()\r\n\t\t\t\t\t\t\t\t: (result & VMFlags.VM_FS.getFlag()));\r\n\t\t\t\tsetValue(cmd.isByteMode(), mem, op1, result);\r\n\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_SBB: {\r\n\t\t\t\tint value1 = getValue(cmd.isByteMode(), mem, op1);\r\n\t\t\t\tint FC = (flags & VMFlags.VM_FC.getFlag());\r\n\t\t\t\tint result = (int) ((long) value1 & 0xFFffFFff\r\n\t\t\t\t\t\t- (long) getValue(cmd.isByteMode(), mem, op2)\r\n\t\t\t\t\t\t& 0xFFffFFff - (long) FC & 0xFFffFFff);\r\n\t\t\t\tif (cmd.isByteMode()) {\r\n\t\t\t\t\tresult &= 0xff;\r\n\t\t\t\t}\r\n\t\t\t\tflags = (result > value1 || result == value1 && FC != 0) ? 1\r\n\t\t\t\t\t\t: 0 | (result == 0 ? VMFlags.VM_FZ.getFlag()\r\n\t\t\t\t\t\t\t\t: (result & VMFlags.VM_FS.getFlag()));\r\n\t\t\t\tsetValue(cmd.isByteMode(), mem, op1, result);\r\n\t\t\t}\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase VM_RET:\r\n\t\t\t\tif (R[7] >= VM_MEMSIZE) {\r\n\t\t\t\t\treturn (true);\r\n\t\t\t\t}\r\n\t\t\t\tsetIP(getValue(false, mem, R[7] & VM_MEMMASK));\r\n\t\t\t\tR[7] += 4;\r\n\t\t\t\tcontinue;\r\n\r\n\t\t\tcase VM_STANDARD:\r\n\t\t\t\tExecuteStandardFilter(VMStandardFilters.findFilter(cmd.getOp1()\r\n\t\t\t\t\t\t.getData()));\r\n\t\t\t\tbreak;\r\n\t\t\tcase VM_PRINT:\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tIP++;\r\n\t\t\t--maxOpCount;\r\n\t\t}\r\n\t}\r\n\r\n\tpublic void prepare(byte[] code, int codeSize, VMPreparedProgram prg) {\r\n\t\tInitBitInput();\r\n\t\tint cpLength = Math.min(MAX_SIZE, codeSize);\r\n\t\tfor (int i = 0; i < cpLength; i++) // memcpy(inBuf,Code,Min(CodeSize,BitInput::MAX_SIZE));\r\n\t\t{\r\n\t\t\tinBuf[i] |= code[i];\r\n\t\t}\r\n\r\n\t\tbyte xorSum = 0;\r\n\t\tfor (int i = 1; i < codeSize; i++) {\r\n\t\t\txorSum ^= code[i];\r\n\t\t}\r\n\r\n\t\tfaddbits(8);\r\n\r\n\t\tprg.setCmdCount(0);\r\n\t\tif (xorSum == code[0]) {\r\n\t\t\tVMStandardFilters filterType = IsStandardFilter(code, codeSize);\r\n\t\t\tif (filterType != VMStandardFilters.VMSF_NONE) {\r\n\r\n\t\t\t\tVMPreparedCommand curCmd = new VMPreparedCommand();\r\n\t\t\t\tcurCmd.setOpCode(VMCommands.VM_STANDARD);\r\n\t\t\t\tcurCmd.getOp1().setData(filterType.getFilter());\r\n\t\t\t\tcurCmd.getOp1().setType(VMOpType.VM_OPNONE);\r\n\t\t\t\tcurCmd.getOp2().setType(VMOpType.VM_OPNONE);\r\n\t\t\t\tcodeSize = 0;\t\t\t\r\n\t\t\t\tprg.getCmd().add(curCmd);\r\n\t\t\t\tprg.setCmdCount(prg.getCmdCount()+1);\r\n\t\t\t\t// TODO\r\n\t\t\t\t// curCmd->Op1.Data=FilterType;\r\n\t\t\t\t// >>>>>> CurCmd->Op1.Addr=&CurCmd->Op1.Data; <<<<<<<<<< not set\r\n\t\t\t\t// do i need to ?\r\n\t\t\t\t// >>>>>> CurCmd->Op2.Addr=&CurCmd->Op2.Data; <<<<<<<<<< \"\r\n\t\t\t\t// CurCmd->Op1.Type=CurCmd->Op2.Type=VM_OPNONE;\r\n\t\t\t\t// CodeSize=0;\r\n\t\t\t}\r\n\t\t\tint dataFlag = fgetbits();\r\n\t\t\tfaddbits(1);\r\n\r\n\t\t\t// Read static data contained in DB operators. This data cannot be\r\n\t\t\t// changed,\r\n\t\t\t// it is a part of VM code, not a filter parameter.\r\n\r\n\t\t\tif ((dataFlag & 0x8000) != 0) {\r\n\t\t\t\tlong dataSize = (long) ((long) ReadData(this) & 0xffFFffFF + 1);\r\n\t\t\t\tfor (int i = 0; inAddr < codeSize && i < dataSize; i++) {\r\n\t\t\t\t\tprg.getStaticData().add(\r\n\t\t\t\t\t\t\tByte.valueOf((byte) (fgetbits() >> 8)));\r\n\t\t\t\t\tfaddbits(8);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\twhile (inAddr < codeSize) {\r\n\t\t\t\tVMPreparedCommand curCmd = new VMPreparedCommand();\r\n\t\t\t\tint data = fgetbits();\r\n\t\t\t\tif ((data & 0x8000) == 0) {\r\n\t\t\t\t\tcurCmd.setOpCode(VMCommands.findVMCommand((data >> 12)));\r\n\t\t\t\t\tfaddbits(4);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tcurCmd.setOpCode(VMCommands\r\n\t\t\t\t\t\t\t.findVMCommand((data >> 10) - 24));\r\n\t\t\t\t\tfaddbits(6);\r\n\t\t\t\t}\r\n\t\t\t\tif ((VMCmdFlags.VM_CmdFlags[curCmd.getOpCode().getVMCommand()] & VMCmdFlags.VMCF_BYTEMODE) != 0) {\r\n\t\t\t\t\tcurCmd.setByteMode((fgetbits() >> 15) == 1 ? true : false);\r\n\t\t\t\t\tfaddbits(1);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tcurCmd.setByteMode(false);\r\n\t\t\t\t}\r\n\t\t\t\tcurCmd.getOp1().setType(VMOpType.VM_OPNONE);\r\n\t\t\t\tcurCmd.getOp2().setType(VMOpType.VM_OPNONE);\r\n\r\n\t\t\t\tint opNum = (VMCmdFlags.VM_CmdFlags[curCmd.getOpCode()\r\n\t\t\t\t\t\t.getVMCommand()] & VMCmdFlags.VMCF_OPMASK);\r\n\t\t\t\t// TODO >>> CurCmd->Op1.Addr=CurCmd->Op2.Addr=NULL; <<<???\r\n\t\t\t\tif (opNum > 0) {\r\n\t\t\t\t\tdecodeArg(curCmd.getOp1(), curCmd.isByteMode());\r\n\t\t\t\t\tif (opNum == 2)\r\n\t\t\t\t\t\tdecodeArg(curCmd.getOp2(), curCmd.isByteMode());\r\n\t\t\t\t\telse {\r\n\t\t\t\t\t\tif (curCmd.getOp1().getType() == VMOpType.VM_OPINT\r\n\t\t\t\t\t\t\t\t&& (VMCmdFlags.VM_CmdFlags[curCmd.getOpCode()\r\n\t\t\t\t\t\t\t\t\t\t.getVMCommand()] & (VMCmdFlags.VMCF_JUMP | VMCmdFlags.VMCF_PROC)) != 0) {\r\n\t\t\t\t\t\t\tint distance = curCmd.getOp1().getData();\r\n\t\t\t\t\t\t\tif (distance >= 256)\r\n\t\t\t\t\t\t\t\tdistance -= 256;\r\n\t\t\t\t\t\t\telse {\r\n\t\t\t\t\t\t\t\tif (distance >= 136) {\r\n\t\t\t\t\t\t\t\t\tdistance -= 264;\r\n\t\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\t\tif (distance >= 16) {\r\n\t\t\t\t\t\t\t\t\t\tdistance -= 8;\r\n\t\t\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\t\t\tif (distance >= 8) {\r\n\t\t\t\t\t\t\t\t\t\t\tdistance -= 16;\r\n\t\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\tdistance += prg.getCmdCount();\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tcurCmd.getOp1().setData(distance);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tprg.setCmdCount(prg.getCmdCount() + 1);\r\n\t\t\t\tprg.getCmd().add(curCmd);\r\n\t\t\t}\r\n\t\t}\r\n\t\tVMPreparedCommand curCmd = new VMPreparedCommand();\r\n\t\tcurCmd.setOpCode(VMCommands.VM_RET);\r\n\t\t// TODO CurCmd->Op1.Addr=&CurCmd->Op1.Data;\r\n\t\t// CurCmd->Op2.Addr=&CurCmd->Op2.Data;\r\n\t\tcurCmd.getOp1().setType(VMOpType.VM_OPNONE);\r\n\t\tcurCmd.getOp2().setType(VMOpType.VM_OPNONE);\r\n\r\n\t\t// for (int i=0;i<prg.getCmdCount();i++)\r\n\t\t// {\r\n\t\t// VM_PreparedCommand *Cmd=&Prg->Cmd[I];\r\n\t\t// if (Cmd->Op1.Addr==NULL)\r\n\t\t// Cmd->Op1.Addr=&Cmd->Op1.Data;\r\n\t\t// if (Cmd->Op2.Addr==NULL)\r\n\t\t// Cmd->Op2.Addr=&Cmd->Op2.Data;\r\n\t\t// }\r\n\r\n\t\tprg.getCmd().add(curCmd);\r\n\t\tprg.setCmdCount(prg.getCmdCount()+1);\r\n\t\t// #ifdef VM_OPTIMIZE\r\n\t\tif (codeSize != 0) {\r\n\t\t\toptimize(prg);\r\n\t\t}\r\n\t}\r\n\r\n\tprivate void decodeArg(VMPreparedOperand op, boolean byteMode) {\r\n\t\tint data = fgetbits();\r\n\t\tif ((data & 0x8000) != 0) {\r\n\t\t\top.setType(VMOpType.VM_OPREG);\r\n\t\t\top.setData((data >> 12) & 7);\r\n\t\t\top.setOffset(op.getData());\r\n\t\t\tfaddbits(4);\r\n\t\t} else {\r\n\t\t\tif ((data & 0xc000) == 0) {\r\n\t\t\t\top.setType(VMOpType.VM_OPINT);\r\n\t\t\t\tif (byteMode) {\r\n\t\t\t\t\top.setData((data >> 6) & 0xff);\r\n\t\t\t\t\tfaddbits(10);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tfaddbits(2);\r\n\t\t\t\t\top.setData(ReadData(this));\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\top.setType(VMOpType.VM_OPREGMEM);\r\n\t\t\t\tif ((data & 0x2000) == 0) {\r\n\t\t\t\t\top.setData((data >> 10) & 7);\r\n\t\t\t\t\top.setOffset(op.getData());\r\n\t\t\t\t\top.setBase(0);\r\n\t\t\t\t\tfaddbits(6);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tif ((data & 0x1000) == 0) {\r\n\t\t\t\t\t\top.setData((data >> 9) & 7);\r\n\t\t\t\t\t\top.setOffset(op.getData());\r\n\t\t\t\t\t\tfaddbits(7);\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\top.setData(0);\r\n\t\t\t\t\t\tfaddbits(4);\r\n\t\t\t\t\t}\r\n\t\t\t\t\top.setBase(ReadData(this));\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t}\r\n\r\n\tprivate void optimize(VMPreparedProgram prg) {\r\n\t\tList<VMPreparedCommand> commands = prg.getCmd();\r\n\r\n\t\tfor (VMPreparedCommand cmd : commands) {\r\n\t\t\tswitch (cmd.getOpCode()) {\r\n\t\t\tcase VM_MOV:\r\n\t\t\t\tcmd.setOpCode(cmd.isByteMode() ? VMCommands.VM_MOVB\r\n\t\t\t\t\t\t: VMCommands.VM_MOVD);\r\n\t\t\t\tcontinue;\r\n\t\t\tcase VM_CMP:\r\n\t\t\t\tcmd.setOpCode(cmd.isByteMode() ? VMCommands.VM_CMPB\r\n\t\t\t\t\t\t: VMCommands.VM_CMPD);\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t\tif ((VMCmdFlags.VM_CmdFlags[cmd.getOpCode().getVMCommand()] & VMCmdFlags.VMCF_CHFLAGS) == 0) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t\tboolean flagsRequired = false;\r\n\r\n\t\t\tfor (int i = commands.indexOf(cmd) + 1; i < commands.size(); i++) {\r\n\t\t\t\tint flags = VMCmdFlags.VM_CmdFlags[commands.get(i).getOpCode()\r\n\t\t\t\t\t\t.getVMCommand()];\r\n\t\t\t\tif ((flags & (VMCmdFlags.VMCF_JUMP | VMCmdFlags.VMCF_PROC | VMCmdFlags.VMCF_USEFLAGS)) != 0) {\r\n\t\t\t\t\tflagsRequired = true;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t\tif ((flags & VMCmdFlags.VMCF_CHFLAGS) != 0) {\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (flagsRequired) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t\tswitch (cmd.getOpCode()) {\r\n\t\t\tcase VM_ADD:\r\n\t\t\t\tcmd.setOpCode(cmd.isByteMode() ? VMCommands.VM_ADDB\r\n\t\t\t\t\t\t: VMCommands.VM_ADDD);\r\n\t\t\t\tcontinue;\r\n\t\t\tcase VM_SUB:\r\n\t\t\t\tcmd.setOpCode(cmd.isByteMode() ? VMCommands.VM_SUBB\r\n\t\t\t\t\t\t: VMCommands.VM_SUBD);\r\n\t\t\t\tcontinue;\r\n\t\t\tcase VM_INC:\r\n\t\t\t\tcmd.setOpCode(cmd.isByteMode() ? VMCommands.VM_INCB\r\n\t\t\t\t\t\t: VMCommands.VM_INCD);\r\n\t\t\t\tcontinue;\r\n\t\t\tcase VM_DEC:\r\n\t\t\t\tcmd.setOpCode(cmd.isByteMode() ? VMCommands.VM_DECB\r\n\t\t\t\t\t\t: VMCommands.VM_DECD);\r\n\t\t\t\tcontinue;\r\n\t\t\tcase VM_NEG:\r\n\t\t\t\tcmd.setOpCode(cmd.isByteMode() ? VMCommands.VM_NEGB\r\n\t\t\t\t\t\t: VMCommands.VM_NEGD);\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t}\r\n\r\n\tpublic static int ReadData(BitInput rarVM) {\r\n\t\tint data = rarVM.fgetbits();\r\n\t\tswitch (data & 0xc000) {\r\n\t\tcase 0:\r\n\t\t\trarVM.faddbits(6);\r\n\t\t\treturn ((data >> 10) & 0xf);\r\n\t\tcase 0x4000:\r\n\t\t\tif ((data & 0x3c00) == 0) {\r\n\t\t\t\tdata = 0xffffff00 | ((data >> 2) & 0xff);\r\n\t\t\t\trarVM.faddbits(14);\r\n\t\t\t} else {\r\n\t\t\t\tdata = (data >> 6) & 0xff;\r\n\t\t\t\trarVM.faddbits(10);\r\n\t\t\t}\r\n\t\t\treturn (data);\r\n\t\tcase 0x8000:\r\n\t\t\trarVM.faddbits(2);\r\n\t\t\tdata = rarVM.fgetbits();\r\n\t\t\trarVM.faddbits(16);\r\n\t\t\treturn (data);\r\n\t\tdefault:\r\n\t\t\trarVM.faddbits(2);\r\n\t\t\tdata = (rarVM.fgetbits() << 16);\r\n\t\t\trarVM.faddbits(16);\r\n\t\t\tdata |= rarVM.fgetbits();\r\n\t\t\trarVM.faddbits(16);\r\n\t\t\treturn (data);\r\n\t\t}\r\n\t}\r\n\r\n\tprivate VMStandardFilters IsStandardFilter(byte[] code, int codeSize) {\r\n\t\tVMStandardFilterSignature stdList[]={\r\n\t\t\t\tnew VMStandardFilterSignature(53, 0xad576887, VMStandardFilters.VMSF_E8),\r\n\t\t\t\tnew VMStandardFilterSignature(57, 0x3cd7e57e, VMStandardFilters.VMSF_E8E9),\r\n\t\t\t\tnew VMStandardFilterSignature(120, 0x3769893f, VMStandardFilters.VMSF_ITANIUM),\r\n\t\t\t\tnew VMStandardFilterSignature(29, 0x0e06077d, VMStandardFilters.VMSF_DELTA),\r\n\t\t\t\tnew VMStandardFilterSignature(149, 0x1c2c5dc8, VMStandardFilters.VMSF_RGB),\r\n\t\t\t\tnew VMStandardFilterSignature(216, 0xbc85e701, VMStandardFilters.VMSF_AUDIO),\r\n\t\t\t\tnew VMStandardFilterSignature(40, 0x46b9c560, VMStandardFilters.VMSF_UPCASE)\r\n\t\t};\r\n\t\tint CodeCRC = RarCRC.checkCrc(0xffffffff,code,0,code.length)^0xffffffff;\r\n\t\tfor (int i=0;i<stdList.length;i++){\r\n\t\t\tif (stdList[i].getCRC()==CodeCRC && stdList[i].getLength()==code.length){\r\n\t\t\t\treturn(stdList[i].getType());\r\n\t\t\t}\r\n\t\t\t\t\r\n\t\t}\r\n\t\treturn(VMStandardFilters.VMSF_NONE);\r\n\t}\r\n\r\n\tprivate void ExecuteStandardFilter(VMStandardFilters filterType) {\r\n\t\tswitch(filterType)\r\n\t\t  {\r\n\t\t    case VMSF_E8:\r\n\t\t    case VMSF_E8E9:\r\n\t\t      {\r\n\t\t        int dataSize=R[4];\r\n\t\t        long fileOffset=R[6]&0xFFffFFff;\r\n\r\n\t\t        if (dataSize>=VM_GLOBALMEMADDR){\r\n\t\t          break;\r\n\t\t        }\r\n\t\t        int fileSize=0x1000000;\r\n\t\t        byte cmpByte2=(byte) ((filterType==VMStandardFilters.VMSF_E8E9) ? 0xe9:0xe8);\r\n\t\t        for (int curPos=0;curPos<dataSize-4;)\r\n\t\t        {\r\n\t\t          byte curByte=mem[curPos++];\r\n\t\t          if (curByte==0xe8 || curByte==cmpByte2)\r\n\t\t          {\r\n//\t\t#ifdef PRESENT_INT32\r\n//\t\t            sint32 Offset=CurPos+FileOffset;\r\n//\t\t            sint32 Addr=GET_VALUE(false,Data);\r\n//\t\t            if (Addr<0)\r\n//\t\t            {\r\n//\t\t              if (Addr+Offset>=0)\r\n//\t\t                SET_VALUE(false,Data,Addr+FileSize);\r\n//\t\t            }\r\n//\t\t            else\r\n//\t\t              if (Addr<FileSize)\r\n//\t\t                SET_VALUE(false,Data,Addr-Offset);\r\n//\t\t#else\r\n\t\t            long offset=curPos+fileOffset;\r\n\t\t            long Addr=getValue(false,mem,curPos);\r\n\t\t            if ((Addr & 0x80000000)!=0)\r\n\t\t            {\r\n\t\t              if (((Addr+offset) & 0x80000000)==0)\r\n\t\t                setValue(false,mem,curPos,(int)Addr+fileSize);\r\n\t\t            }\r\n\t\t            else {\r\n\t\t              if (((Addr-fileSize) & 0x80000000)!=0){\r\n\t\t                setValue(false,mem,curPos,(int)(Addr-offset));\r\n\t\t              }\r\n\t\t            }\r\n//\t\t#endif\r\n\t\t            curPos+=4;\r\n\t\t          }\r\n\t\t        }\r\n\t\t      }\r\n\t\t      break;\r\n\t\t    case VMSF_ITANIUM:\r\n\t\t      {\r\n\t\t        \r\n\t\t        int dataSize=R[4];\r\n\t\t        long fileOffset=R[6]&0xFFffFFff;\r\n\r\n\t\t        if (dataSize>=VM_GLOBALMEMADDR){\r\n\t\t          break;\r\n\t\t        }\r\n\t\t        int curPos=0;\r\n\t\t        final byte Masks[]={4,4,6,6,0,0,7,7,4,4,0,0,4,4,0,0};\r\n\t\t        fileOffset>>>=4;\r\n\r\n\t\t        while (curPos<dataSize-21)\r\n\t\t        {\r\n\t\t          int Byte=(mem[curPos]&0x1f)-0x10;\r\n\t\t          if (Byte>=0)\r\n\t\t          {\r\n\t\t            \r\n\t\t            byte cmdMask=Masks[Byte];\r\n\t\t            if (cmdMask!=0)\r\n\t\t              for (int i=0;i<=2;i++)\r\n\t\t                if ((cmdMask & (1<<i))!=0)\r\n\t\t                {\r\n\t\t                  int startPos=i*41+5;\r\n\t\t                  int opType=filterItanium_GetBits(curPos,startPos+37,4);\r\n\t\t                  if (opType==5)\r\n\t\t                  {\r\n\t\t                    int offset=filterItanium_GetBits(curPos,startPos+13,20);\r\n\t\t                    filterItanium_SetBits(curPos,(int)(offset-fileOffset)&0xfffff,startPos+13,20);\r\n\t\t                  }\r\n\t\t                }\r\n\t\t          }\r\n\t\t          curPos+=16;\r\n\t\t          fileOffset++;\r\n\t\t        }\r\n\t\t      }\r\n\t\t      break;\r\n\t\t    case VMSF_DELTA:\r\n\t\t      {\r\n\t\t        int dataSize=R[4]&0xFFffFFff;\r\n\t\t        int channels=R[0]&0xFFffFFff;\r\n\t\t        int srcPos=0;\r\n\t\t        int border=(dataSize*2) &0xFFffFFff;\r\n\t\t        setValue(false,mem,VM_GLOBALMEMADDR+0x20,(int)dataSize);\r\n\t\t        if (dataSize>=VM_GLOBALMEMADDR/2){\r\n\t\t          break;\r\n\t\t        }\r\n//\t\t bytes from same channels are grouped to continual data blocks,\r\n//\t\t so we need to place them back to their interleaving positions\r\n\r\n\t\t        for (int curChannel=0;curChannel<channels;curChannel++)\r\n\t\t        {\r\n\t\t          byte PrevByte=0;\r\n\t\t          for (int destPos=dataSize+curChannel;destPos<border;destPos+=channels){\r\n\t\t        \t  mem[destPos]=(PrevByte-=mem[srcPos++]);\r\n\t\t          }\r\n\t\t            \r\n\t\t        }\r\n\t\t      }\r\n\t\t      break;\r\n\t\t    case VMSF_RGB:\r\n\t\t      {\r\n\t\t    \t // byte *SrcData=Mem,*DestData=SrcData+DataSize;\r\n\t\t    \tint dataSize=R[4],width=R[0]-3,posR=R[1];\r\n\t\t        int channels=3;\r\n\t\t        int srcPos = 0; \r\n\t\t        int destDataPos = dataSize;\r\n\t\t        setValue(false,mem,VM_GLOBALMEMADDR+0x20,dataSize);\r\n\t\t        if (dataSize>=VM_GLOBALMEMADDR/2 || posR<0){\r\n\t\t          break;\r\n\t\t        }\r\n\t\t        for (int curChannel=0;curChannel<channels;curChannel++)\r\n\t\t        {\r\n\t\t          long prevByte=0;\r\n\r\n\t\t          for (int i=curChannel;i<dataSize;i+=channels)\r\n\t\t          {\r\n\t\t            long predicted;\r\n\t\t            int upperPos=i-width;\r\n\t\t            if (upperPos>=3)\r\n\t\t            {\r\n\t\t              int upperDataPos=destDataPos+upperPos;\r\n\t\t              int  upperByte=mem[(int)upperDataPos]&0xff;\r\n\t\t              int upperLeftByte=mem[upperDataPos-3]&0xff;\r\n\t\t              predicted=prevByte+upperByte-upperLeftByte;\r\n\t\t              int pa=Math.abs((int)(predicted-prevByte));\r\n\t\t              int pb=Math.abs((int)(predicted-upperByte));\r\n\t\t              int pc=Math.abs((int)(predicted-upperLeftByte));\r\n\t\t              if (pa<=pb && pa<=pc){\r\n\t\t                predicted=prevByte;\r\n\t\t              }\r\n\t\t              else{\r\n\t\t                if (pb<=pc){\r\n\t\t                  predicted=upperByte;\r\n\t\t                }\r\n\t\t                else{\r\n\t\t                  predicted=upperLeftByte;\r\n\t\t                }\r\n\t\t              }\r\n\t\t            }\r\n\t\t            else{\r\n\t\t              predicted=prevByte;\r\n\t\t            }\r\n\t\t            \r\n\t\t            prevByte=(predicted-mem[srcPos++]&0xff)&0xff;\r\n\t\t            mem[destDataPos+i]=(byte)(prevByte&0xff);\r\n\t\t           \r\n\t\t          }\r\n\t\t        }\r\n\t\t        for (int i=posR,border=dataSize-2;i<border;i+=3)\r\n\t\t        {\r\n\t\t          byte G=mem[destDataPos+i+1];\r\n\t\t          mem[destDataPos+i]+=G;\r\n\t\t          mem[destDataPos+i+2]+=G;\r\n\t\t        }\r\n\t\t      }\r\n\t\t      break;\r\n\t\t    case VMSF_AUDIO:\r\n\t\t      {\r\n\t\t        int dataSize=R[4],channels=R[0];\r\n\t\t        int srcPos = 0; \r\n\t\t        int destDataPos = dataSize;\r\n\t\t        //byte *SrcData=Mem,*DestData=SrcData+DataSize;\r\n\t\t        setValue(false,mem,VM_GLOBALMEMADDR+0x20,dataSize);\r\n\t\t        if (dataSize>=VM_GLOBALMEMADDR/2){\r\n\t\t          break;\r\n\t\t        }\r\n\t\t        for (int curChannel=0;curChannel<channels;curChannel++)\r\n\t\t        {\r\n\t\t          long prevByte=0;\r\n\t\t          long prevDelta=0;\r\n\t\t          long Dif[] = new long[7];\r\n\t\t          int D1=0,D2=0,D3;\r\n\t\t          int K1=0,K2=0,K3=0;\r\n\t\t          \r\n\t\t          for (int i=curChannel,byteCount=0;i<dataSize;i+=channels,byteCount++)\r\n\t\t          {\r\n\t\t            D3=D2;\r\n\t\t            D2=(int)prevDelta-D1;\r\n\t\t            D1=(int)prevDelta;\r\n\r\n\t\t            long predicted=8*prevByte+K1*D1+K2*D2+K3*D3;\r\n\t\t            predicted=(predicted>>>3) & 0xff;\r\n\t\t            \r\n\t\t            long curByte=mem[srcPos++]&0xff;\r\n\r\n\t\t            predicted = (predicted - curByte)&UINT_MASK;\r\n\t\t            mem[destDataPos+i]=(byte)predicted;\r\n\t\t            prevDelta=(byte)(predicted-prevByte);\r\n\t\t            prevByte=predicted;\r\n\r\n\t\t            int D=((byte)curByte)<<3;\r\n\r\n\t\t            Dif[0]+=Math.abs(D);\r\n\t\t            Dif[1]+=Math.abs(D-D1);\r\n\t\t            Dif[2]+=Math.abs(D+D1);\r\n\t\t            Dif[3]+=Math.abs(D-D2);\r\n\t\t            Dif[4]+=Math.abs(D+D2);\r\n\t\t            Dif[5]+=Math.abs(D-D3);\r\n\t\t            Dif[6]+=Math.abs(D+D3);\r\n\r\n\t\t            if ((byteCount & 0x1f)==0)\r\n\t\t            {\r\n\t\t              long minDif=Dif[0], numMinDif=0;\r\n\t\t              Dif[0]=0;\r\n\t\t              for (int j=1;j<Dif.length;j++)\r\n\t\t              {\r\n\t\t                if (Dif[j]<minDif)\r\n\t\t                {\r\n\t\t                  minDif=Dif[j];\r\n\t\t                  numMinDif=j;\r\n\t\t                }\r\n\t\t                Dif[j]=0;\r\n\t\t              }\r\n\t\t              switch((int)numMinDif)\r\n\t\t              {\r\n\t\t                case 1: if (K1>=-16) K1--; break;\r\n\t\t                case 2: if (K1 < 16) K1++; break;\r\n\t\t                case 3: if (K2>=-16) K2--; break;\r\n\t\t                case 4: if (K2 < 16) K2++; break;\r\n\t\t                case 5: if (K3>=-16) K3--; break;\r\n\t\t                case 6: if (K3 < 16) K3++; break;\r\n\t\t              }\r\n\t\t            }\r\n\t\t          }\r\n\t\t        }\r\n\t\t      }\r\n\t\t      break;\r\n\t\t    case VMSF_UPCASE:\r\n\t\t      {\r\n\t\t        int dataSize=R[4],srcPos=0,destPos=dataSize;\r\n\t\t        if (dataSize>=VM_GLOBALMEMADDR/2){\r\n\t\t          break;\r\n\t\t        }\r\n\t\t        while (srcPos<dataSize)\r\n\t\t        {\r\n\t\t          byte curByte=mem[srcPos++];\r\n\t\t          if (curByte==2 && (curByte=mem[srcPos++])!=2){\r\n\t\t            curByte-=32;\r\n\t\t          }\r\n\t\t          mem[destPos++]=curByte;\r\n\t\t        }\r\n\t\t        setValue(false,mem,VM_GLOBALMEMADDR+0x1c,destPos-dataSize);\r\n\t\t        setValue(false,mem,VM_GLOBALMEMADDR+0x20,dataSize);\r\n\t\t      }\r\n\t\t      break;\r\n\t\t  }\r\n\t\r\n\t}\r\n\r\n\tprivate void filterItanium_SetBits(int curPos, int bitField, int bitPos, int bitCount) {\r\n\t\tint inAddr=bitPos/8;\r\n\t\t  int inBit=bitPos&7;\r\n\t\t  int andMask=0xffffffff>>>(32-bitCount);\r\n\t\t  andMask=~(andMask<<inBit);\r\n\r\n\t\t  bitField<<=inBit;\r\n\r\n\t\t  for (int i=0;i<4;i++)\r\n\t\t  {\r\n\t\t    mem[curPos+inAddr+i]&=andMask;\r\n\t\t    mem[curPos+inAddr+i]|=bitField;\r\n\t\t    andMask=(andMask>>>8)|0xff000000;\r\n\t\t    bitField>>>=8;\r\n\t\t  }\r\n\t\t\r\n\t}\r\n\r\n\tprivate int filterItanium_GetBits(int curPos, int bitPos, int bitCount) {\r\n\t\t int inAddr=bitPos/8;\r\n\t\t  int inBit=bitPos&7;\r\n\t\t  int bitField=(int)(mem[curPos+inAddr++]&0xff);\r\n\t\t  bitField|=(int) ((mem[curPos+inAddr++]&0xff) << 8);\r\n\t\t  bitField|=(int) ((mem[curPos+inAddr++]&0xff) << 16);\r\n\t\t  bitField|=(int) ((mem[curPos+inAddr]&0xff) << 24);\r\n\t\t  bitField >>>= inBit;\r\n\t\t  return(bitField & (0xffffffff>>>(32-bitCount)));\r\n\t}\r\n\r\n\r\n\tpublic void setMemory(int pos,byte[] data,int offset,int dataSize)\r\n\t{\r\n\t  if (pos<VM_MEMSIZE){ //&& data!=Mem+Pos)\r\n\t    //memmove(Mem+Pos,Data,Min(DataSize,VM_MEMSIZE-Pos));\r\n\t    for (int i = 0; i < Math.min(data.length-offset,dataSize); i++) {\r\n\t\t\tif((VM_MEMSIZE-pos)<i){\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tmem[pos+i] = data[offset+i];\r\n\t\t}\r\n\t  }\r\n\t}\r\n\r\n\r\n}\r\n\r\n//"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/vm/VMCmdFlags.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 01.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.vm;\r\n\r\n/**\r\n * DOCUMENT ME\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class VMCmdFlags {\r\n\tpublic static final byte VMCF_OP0\t\t= 0;\r\n\tpublic static final byte VMCF_OP1\t\t= 1;\r\n\tpublic static final byte VMCF_OP2\t\t= 2;\r\n\tpublic static final byte VMCF_OPMASK\t= 3;\r\n\tpublic static final byte VMCF_BYTEMODE\t= 4;\r\n\tpublic static final byte VMCF_JUMP     = 8;\r\n\tpublic static final byte VMCF_PROC     = 16;\r\n\tpublic static final byte VMCF_USEFLAGS = 32;\r\n\tpublic static final byte VMCF_CHFLAGS  = 64;\r\n\r\n\tpublic static byte VM_CmdFlags[]=\r\n\t{\r\n\t  /* VM_MOV   */ VMCF_OP2 | VMCF_BYTEMODE                                ,\r\n\t  /* VM_CMP   */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS                 ,\r\n\t  /* VM_ADD   */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS                 ,\r\n\t  /* VM_SUB   */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS                 ,\r\n\t  /* VM_JZ    */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS                    ,\r\n\t  /* VM_JNZ   */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS                    ,\r\n\t  /* VM_INC   */ VMCF_OP1 | VMCF_BYTEMODE | VMCF_CHFLAGS                 ,\r\n\t  /* VM_DEC   */ VMCF_OP1 | VMCF_BYTEMODE | VMCF_CHFLAGS                 ,\r\n\t  /* VM_JMP   */ VMCF_OP1 | VMCF_JUMP                                    ,\r\n\t  /* VM_XOR   */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS                 ,\r\n\t  /* VM_AND   */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS                 ,\r\n\t  /* VM_OR    */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS                 ,\r\n\t  /* VM_TEST  */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS                 ,\r\n\t  /* VM_JS    */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS                    ,\r\n\t  /* VM_JNS   */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS                    ,\r\n\t  /* VM_JB    */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS                    ,\r\n\t  /* VM_JBE   */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS                    ,\r\n\t  /* VM_JA    */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS                    ,\r\n\t  /* VM_JAE   */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS                    ,\r\n\t  /* VM_PUSH  */ VMCF_OP1                                                ,\r\n\t  /* VM_POP   */ VMCF_OP1                                                ,\r\n\t  /* VM_CALL  */ VMCF_OP1 | VMCF_PROC                                    ,\r\n\t  /* VM_RET   */ VMCF_OP0 | VMCF_PROC                                    ,\r\n\t  /* VM_NOT   */ VMCF_OP1 | VMCF_BYTEMODE                                ,\r\n\t  /* VM_SHL   */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS                 ,\r\n\t  /* VM_SHR   */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS                 ,\r\n\t  /* VM_SAR   */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS                 ,\r\n\t  /* VM_NEG   */ VMCF_OP1 | VMCF_BYTEMODE | VMCF_CHFLAGS                 ,\r\n\t  /* VM_PUSHA */ VMCF_OP0                                                ,\r\n\t  /* VM_POPA  */ VMCF_OP0                                                ,\r\n\t  /* VM_PUSHF */ VMCF_OP0 | VMCF_USEFLAGS                                ,\r\n\t  /* VM_POPF  */ VMCF_OP0 | VMCF_CHFLAGS                                 ,\r\n\t  /* VM_MOVZX */ VMCF_OP2                                                ,\r\n\t  /* VM_MOVSX */ VMCF_OP2                                                ,\r\n\t  /* VM_XCHG  */ VMCF_OP2 | VMCF_BYTEMODE                                ,\r\n\t  /* VM_MUL   */ VMCF_OP2 | VMCF_BYTEMODE                                ,\r\n\t  /* VM_DIV   */ VMCF_OP2 | VMCF_BYTEMODE                                ,\r\n\t  /* VM_ADC   */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_USEFLAGS | VMCF_CHFLAGS ,\r\n\t  /* VM_SBB   */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_USEFLAGS | VMCF_CHFLAGS ,\r\n\t  /* VM_PRINT */ VMCF_OP0\r\n\t};\r\n\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/vm/VMCommands.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 31.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.vm;\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic enum VMCommands {\r\n\tVM_MOV(0), VM_CMP(1), VM_ADD(2), VM_SUB(3), VM_JZ(4), VM_JNZ(5), VM_INC(6), VM_DEC(\r\n\t\t\t7), VM_JMP(8), VM_XOR(9), VM_AND(10), VM_OR(11), VM_TEST(12), VM_JS(\r\n\t\t\t13), VM_JNS(14), VM_JB(15), VM_JBE(16), VM_JA(17), VM_JAE(18), VM_PUSH(\r\n\t\t\t19), VM_POP(20), VM_CALL(21), VM_RET(22), VM_NOT(23), VM_SHL(24), VM_SHR(\r\n\t\t\t25), VM_SAR(26), VM_NEG(27), VM_PUSHA(28), VM_POPA(29), VM_PUSHF(30), VM_POPF(\r\n\t\t\t31), VM_MOVZX(32), VM_MOVSX(33), VM_XCHG(34), VM_MUL(35), VM_DIV(36), VM_ADC(\r\n\t\t\t37), VM_SBB(38), VM_PRINT(39),\r\n\r\n\t// #ifdef VM_OPTIMIZE\r\n\tVM_MOVB(40), VM_MOVD(41), VM_CMPB(42), VM_CMPD(43),\r\n\r\n\tVM_ADDB(44), VM_ADDD(45), VM_SUBB(46), VM_SUBD(47), VM_INCB(48), VM_INCD(49), VM_DECB(\r\n\t\t\t50), VM_DECD(51), VM_NEGB(52), VM_NEGD(53),\r\n\t// #endif*/\r\n\r\n\tVM_STANDARD(54);\r\n\r\n\tprivate int vmCommand;\r\n\r\n\tprivate VMCommands(int vmCommand) {\r\n\t\tthis.vmCommand = vmCommand;\r\n\t}\r\n\r\n\tpublic int getVMCommand() {\r\n\t\treturn vmCommand;\r\n\t}\r\n\r\n\tpublic boolean equals(int vmCommand) {\r\n\t\treturn this.vmCommand == vmCommand;\r\n\t}\r\n\r\n\tpublic static VMCommands findVMCommand(int vmCommand) {\r\n\t\tif (VM_MOV.equals(vmCommand)) {\r\n\t\t\treturn VM_MOV;\r\n\t\t}\r\n\t\tif (VM_CMP.equals(vmCommand)) {\r\n\t\t\treturn VM_CMP;\r\n\t\t}\r\n\t\tif (VM_ADD.equals(vmCommand)) {\r\n\t\t\treturn VM_ADD;\r\n\t\t}\r\n\t\tif (VM_SUB.equals(vmCommand)) {\r\n\t\t\treturn VM_SUB;\r\n\t\t}\r\n\t\tif (VM_JZ.equals(vmCommand)) {\r\n\t\t\treturn VM_JZ;\r\n\t\t}\r\n\t\tif (VM_JNZ.equals(vmCommand)) {\r\n\t\t\treturn VM_JNZ;\r\n\t\t}\r\n\t\tif (VM_INC.equals(vmCommand)) {\r\n\t\t\treturn VM_INC;\r\n\t\t}\r\n\t\tif (VM_DEC.equals(vmCommand)) {\r\n\t\t\treturn VM_DEC;\r\n\t\t}\r\n\t\tif (VM_JMP.equals(vmCommand)) {\r\n\t\t\treturn VM_JMP;\r\n\t\t}\r\n\t\tif (VM_XOR.equals(vmCommand)) {\r\n\t\t\treturn VM_XOR;\r\n\t\t}\r\n\t\tif (VM_AND.equals(vmCommand)) {\r\n\t\t\treturn VM_AND;\r\n\t\t}\r\n\t\tif (VM_OR.equals(vmCommand)) {\r\n\t\t\treturn VM_OR;\r\n\t\t}\r\n\t\tif (VM_TEST.equals(vmCommand)) {\r\n\t\t\treturn VM_TEST;\r\n\t\t}\r\n\t\tif (VM_JS.equals(vmCommand)) {\r\n\t\t\treturn VM_JS;\r\n\t\t}\r\n\t\tif (VM_JNS.equals(vmCommand)) {\r\n\t\t\treturn VM_JNS;\r\n\t\t}\r\n\t\tif (VM_JB.equals(vmCommand)) {\r\n\t\t\treturn VM_JB;\r\n\t\t}\r\n\t\tif (VM_JBE.equals(vmCommand)) {\r\n\t\t\treturn VM_JBE;\r\n\t\t}\r\n\t\tif (VM_JA.equals(vmCommand)) {\r\n\t\t\treturn VM_JA;\r\n\t\t}\r\n\t\tif (VM_JAE.equals(vmCommand)) {\r\n\t\t\treturn VM_JAE;\r\n\t\t}\r\n\t\tif (VM_PUSH.equals(vmCommand)) {\r\n\t\t\treturn VM_PUSH;\r\n\t\t}\r\n\t\tif (VM_POP.equals(vmCommand)) {\r\n\t\t\treturn VM_POP;\r\n\t\t}\r\n\t\tif (VM_CALL.equals(vmCommand)) {\r\n\t\t\treturn VM_CALL;\r\n\t\t}\r\n\t\tif (VM_RET.equals(vmCommand)) {\r\n\t\t\treturn VM_RET;\r\n\t\t}\r\n\t\tif (VM_NOT.equals(vmCommand)) {\r\n\t\t\treturn VM_NOT;\r\n\t\t}\r\n\t\tif (VM_SHL.equals(vmCommand)) {\r\n\t\t\treturn VM_SHL;\r\n\t\t}\r\n\t\tif (VM_SHR.equals(vmCommand)) {\r\n\t\t\treturn VM_SHR;\r\n\t\t}\r\n\t\tif (VM_SAR.equals(vmCommand)) {\r\n\t\t\treturn VM_SAR;\r\n\t\t}\r\n\t\tif (VM_NEG.equals(vmCommand)) {\r\n\t\t\treturn VM_NEG;\r\n\t\t}\r\n\t\tif (VM_PUSHA.equals(vmCommand)) {\r\n\t\t\treturn VM_PUSHA;\r\n\t\t}\r\n\t\tif (VM_POPA.equals(vmCommand)) {\r\n\t\t\treturn VM_POPA;\r\n\t\t}\r\n\t\tif (VM_PUSHF.equals(vmCommand)) {\r\n\t\t\treturn VM_PUSHF;\r\n\t\t}\r\n\t\tif (VM_POPF.equals(vmCommand)) {\r\n\t\t\treturn VM_POPF;\r\n\t\t}\r\n\t\tif (VM_MOVZX.equals(vmCommand)) {\r\n\t\t\treturn VM_MOVZX;\r\n\t\t}\r\n\t\tif (VM_MOVSX.equals(vmCommand)) {\r\n\t\t\treturn VM_MOVSX;\r\n\t\t}\r\n\t\tif (VM_XCHG.equals(vmCommand)) {\r\n\t\t\treturn VM_XCHG;\r\n\t\t}\r\n\t\tif (VM_MUL.equals(vmCommand)) {\r\n\t\t\treturn VM_MUL;\r\n\t\t}\r\n\t\tif (VM_DIV.equals(vmCommand)) {\r\n\t\t\treturn VM_DIV;\r\n\t\t}\r\n\t\tif (VM_ADC.equals(vmCommand)) {\r\n\t\t\treturn VM_ADC;\r\n\t\t}\r\n\t\tif (VM_SBB.equals(vmCommand)) {\r\n\t\t\treturn VM_SBB;\r\n\t\t}\r\n\t\tif (VM_PRINT.equals(vmCommand)) {\r\n\t\t\treturn VM_PRINT;\r\n\t\t}\r\n\t\tif (VM_MOVB.equals(vmCommand)) {\r\n\t\t\treturn VM_MOVB;\r\n\t\t}\r\n\t\tif (VM_MOVD.equals(vmCommand)) {\r\n\t\t\treturn VM_MOVD;\r\n\t\t}\r\n\t\tif (VM_CMPB.equals(vmCommand)) {\r\n\t\t\treturn VM_CMPB;\r\n\t\t}\r\n\t\tif (VM_CMPD.equals(vmCommand)) {\r\n\t\t\treturn VM_CMPD;\r\n\t\t}\r\n\t\tif (VM_ADDB.equals(vmCommand)) {\r\n\t\t\treturn VM_ADDB;\r\n\t\t}\r\n\t\tif (VM_ADDD.equals(vmCommand)) {\r\n\t\t\treturn VM_ADDD;\r\n\t\t}\r\n\t\tif (VM_SUBB.equals(vmCommand)) {\r\n\t\t\treturn VM_SUBB;\r\n\t\t}\r\n\t\tif (VM_SUBD.equals(vmCommand)) {\r\n\t\t\treturn VM_SUBD;\r\n\t\t}\r\n\t\tif (VM_INCB.equals(vmCommand)) {\r\n\t\t\treturn VM_INCB;\r\n\t\t}\r\n\t\tif (VM_INCD.equals(vmCommand)) {\r\n\t\t\treturn VM_INCD;\r\n\t\t}\r\n\t\tif (VM_DECB.equals(vmCommand)) {\r\n\t\t\treturn VM_DECB;\r\n\t\t}\r\n\t\tif (VM_DECD.equals(vmCommand)) {\r\n\t\t\treturn VM_DECD;\r\n\t\t}\r\n\t\tif (VM_NEGB.equals(vmCommand)) {\r\n\t\t\treturn VM_NEGB;\r\n\t\t}\r\n\t\tif (VM_NEGD.equals(vmCommand)) {\r\n\t\t\treturn VM_NEGD;\r\n\t\t}\r\n\t\tif (VM_STANDARD.equals(vmCommand)) {\r\n\t\t\treturn VM_STANDARD;\r\n\t\t}\r\n\t\treturn null;\r\n\t}\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/vm/VMFlags.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 31.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.vm;\r\n\r\n/**\r\n * DOCUMENT ME\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic enum VMFlags {\r\n\t/**\r\n\t * \r\n\t */\r\n\tVM_FC (1),\r\n\t/**\r\n\t * \r\n\t */\r\n\tVM_FZ (2),\r\n\t/**\r\n\t * \r\n\t */\r\n\tVM_FS (0x80000000);\r\n\t\r\n\tprivate int flag;\r\n\t\r\n\tprivate VMFlags(int flag){\r\n\t\tthis.flag = flag;\r\n\t}\r\n\t\r\n\t/**\r\n\t * Returns the VMFlags Type of the given int or null\r\n\t * @param flag as int\r\n\t * @return VMFlag of the int value\r\n\t */\r\n\tpublic static VMFlags findFlag(int flag){\r\n\t\tif(VM_FC.equals(flag)){\r\n\t\t\treturn VM_FC;\r\n\t\t}\r\n\t\tif(VM_FS.equals(flag)){\r\n\t\t\treturn VM_FS;\r\n\t\t}\r\n\t\tif(VM_FZ.equals(flag)){\r\n\t\t\treturn VM_FZ;\r\n\t\t}\r\n\t\treturn null;\r\n\t}\r\n\t\r\n\t/**\r\n\t * Returns true if the flag provided as int is equal to the enum\r\n\t * @param flag\r\n\t * @return returns true if the flag is equal to the enum\r\n\t */\r\n\tpublic boolean equals(int flag){\r\n\t\treturn this.flag == flag;\r\n\t}\r\n\t/**\r\n\t * @return the flag as int\r\n\t */\r\n\tpublic int getFlag() {\r\n\t\treturn flag;\r\n\t}\r\n\t\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/vm/VMOpType.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 31.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.vm;\r\n\r\n/**\r\n * DOCUMENT ME\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic enum VMOpType {\r\n\tVM_OPREG (0),\r\n\tVM_OPINT (1),\r\n\tVM_OPREGMEM (2),\r\n\tVM_OPNONE (3);\r\n\t\r\n\tprivate int opType;\r\n\t\r\n\tprivate VMOpType(int opType){\r\n\t\tthis.opType=opType;\r\n\t}\r\n\r\n\tpublic int getOpType() {\r\n\t\treturn opType;\r\n\t}\r\n\r\n\r\n\tpublic boolean equals(int opType){\r\n\t\treturn this.opType == opType;\r\n\t}\r\n\tpublic static VMOpType findOpType(int opType){\r\n\t\t\r\n\t\tif (VM_OPREG.equals(opType)) {\r\n\t\t\treturn VM_OPREG;\r\n\t\t}\t\t \r\n\t\t\r\n\t\t\r\n\t\tif (VM_OPINT.equals(opType)) {\r\n\t\t\treturn VM_OPINT;\r\n\t\t}\t\t \r\n\t\t\r\n\t\tif (VM_OPREGMEM.equals(opType)) {\r\n\t\t\treturn VM_OPREGMEM;\r\n\t\t}\t\t\r\n\t\t\r\n\t\tif (VM_OPNONE.equals(opType)) {\r\n\t\t\treturn VM_OPNONE;\r\n\t\t}\t\t \r\n\t\treturn null;\r\n\t}\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/vm/VMPreparedCommand.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 31.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.vm;\r\n\r\n/**\r\n * DOCUMENT ME\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class VMPreparedCommand {\r\n\tprivate VMCommands OpCode;\r\n\tprivate boolean ByteMode;\r\n\tprivate VMPreparedOperand Op1 = new VMPreparedOperand();\r\n\tprivate VMPreparedOperand Op2 = new VMPreparedOperand();\r\n\t\r\n\tpublic boolean isByteMode() {\r\n\t\treturn ByteMode;\r\n\t}\r\n\tpublic void setByteMode(boolean byteMode) {\r\n\t\tByteMode = byteMode;\r\n\t}\r\n\tpublic VMPreparedOperand getOp1() {\r\n\t\treturn Op1;\r\n\t}\r\n\tpublic void setOp1(VMPreparedOperand op1) {\r\n\t\tOp1 = op1;\r\n\t}\r\n\tpublic VMPreparedOperand getOp2() {\r\n\t\treturn Op2;\r\n\t}\r\n\tpublic void setOp2(VMPreparedOperand op2) {\r\n\t\tOp2 = op2;\r\n\t}\r\n\tpublic VMCommands getOpCode() {\r\n\t\treturn OpCode;\r\n\t}\r\n\tpublic void setOpCode(VMCommands opCode) {\r\n\t\tOpCode = opCode;\r\n\t}\r\n\t \r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/vm/VMPreparedOperand.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 31.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.vm;\r\n\r\n/**\r\n * DOCUMENT ME\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class VMPreparedOperand {\r\n\tprivate VMOpType Type;\r\n\tprivate int Data;\r\n\tprivate int Base;\r\n\tprivate int offset;\r\n\t\r\n\t\r\n\tpublic int getBase() {\r\n\t\treturn Base;\r\n\t}\r\n\tpublic void setBase(int base) {\r\n\t\tBase = base;\r\n\t}\r\n\tpublic int getData() {\r\n\t\treturn Data;\r\n\t}\r\n\tpublic void setData(int data) {\r\n\t\tData = data;\r\n\t}\r\n\tpublic VMOpType getType() {\r\n\t\treturn Type;\r\n\t}\r\n\tpublic void setType(VMOpType type) {\r\n\t\tType = type;\r\n\t}\r\n\tpublic int getOffset() {\r\n\t\treturn offset;\r\n\t}\r\n\tpublic void setOffset(int offset) {\r\n\t\tthis.offset = offset;\r\n\t}\r\n\t \r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/vm/VMPreparedProgram.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 31.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.vm;\r\n\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\nimport java.util.Vector;\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class VMPreparedProgram \r\n{\r\n\tprivate List<VMPreparedCommand> Cmd  = new ArrayList<VMPreparedCommand>();\r\n\tprivate List<VMPreparedCommand> AltCmd  =new ArrayList<VMPreparedCommand>();\r\n\tprivate int CmdCount;\r\n\r\n\r\n\t\r\n\tprivate Vector<Byte> GlobalData = new Vector<Byte>();\r\n\tprivate Vector<Byte> StaticData = new Vector<Byte>(); // static data contained in DB operators\r\n\tprivate int InitR[] = new int[7];\r\n\r\n\tprivate int FilteredDataOffset;\r\n\tprivate int FilteredDataSize;\r\n\t\r\n\tpublic VMPreparedProgram() \r\n\t{\r\n\t\tAltCmd=null;\r\n\t}\r\n\r\n\t\r\n\r\n\tpublic List<VMPreparedCommand> getAltCmd() {\r\n\t\treturn AltCmd;\r\n\t}\r\n\r\n\r\n\r\n\tpublic void setAltCmd(List<VMPreparedCommand> altCmd) {\r\n\t\tAltCmd = altCmd;\r\n\t}\r\n\r\n\r\n\r\n\tpublic List<VMPreparedCommand> getCmd() {\r\n\t\treturn Cmd;\r\n\t}\r\n\r\n\tpublic void setCmd(List<VMPreparedCommand> cmd) {\r\n\t\tCmd = cmd;\r\n\t}\r\n\r\n\tpublic int getCmdCount() {\r\n\t\treturn CmdCount;\r\n\t}\r\n\r\n\tpublic void setCmdCount(int cmdCount) {\r\n\t\tCmdCount = cmdCount;\r\n\t}\r\n\r\n\t\r\n\r\n\tpublic int getFilteredDataOffset() {\r\n\t\treturn FilteredDataOffset;\r\n\t}\r\n\r\n\r\n\r\n\tpublic void setFilteredDataOffset(int filteredDataOffset) {\r\n\t\tFilteredDataOffset = filteredDataOffset;\r\n\t}\r\n\r\n\r\n\r\n\tpublic int getFilteredDataSize() {\r\n\t\treturn FilteredDataSize;\r\n\t}\r\n\r\n\tpublic void setFilteredDataSize(int filteredDataSize) {\r\n\t\tFilteredDataSize = filteredDataSize;\r\n\t}\r\n\r\n\tpublic Vector<Byte> getGlobalData() {\r\n\t\treturn GlobalData;\r\n\t}\r\n\r\n\tpublic void setGlobalData(Vector<Byte> globalData) {\r\n\t\tGlobalData = globalData;\r\n\t}\r\n\r\n\tpublic int[] getInitR() {\r\n\t\treturn InitR;\r\n\t}\r\n\r\n\tpublic void setInitR(int[] initR) {\r\n\t\tInitR = initR;\r\n\t}\r\n\r\n\tpublic Vector<Byte> getStaticData() {\r\n\t\treturn StaticData;\r\n\t}\r\n\r\n\tpublic void setStaticData(Vector<Byte> staticData) {\r\n\t\tStaticData = staticData;\r\n\t}\r\n\t\r\n\t\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/vm/VMStandardFilterSignature.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 04.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.vm;\r\n\r\n/**\r\n * DOCUMENT ME\r\n * \r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class VMStandardFilterSignature {\r\n\tprivate int length;\r\n\r\n\tprivate int CRC;\r\n\r\n\tprivate VMStandardFilters type;\r\n\r\n\tpublic VMStandardFilterSignature(int length, int crc, VMStandardFilters type) {\r\n\t\tsuper();\r\n\t\tthis.length = length;\r\n\t\tCRC = crc;\r\n\t\tthis.type = type;\r\n\t}\r\n\r\n\tpublic int getCRC() {\r\n\t\treturn CRC;\r\n\t}\r\n\r\n\tpublic void setCRC(int crc) {\r\n\t\tCRC = crc;\r\n\t}\r\n\r\n\tpublic int getLength() {\r\n\t\treturn length;\r\n\t}\r\n\r\n\tpublic void setLength(int length) {\r\n\t\tthis.length = length;\r\n\t}\r\n\r\n\tpublic VMStandardFilters getType() {\r\n\t\treturn type;\r\n\t}\r\n\r\n\tpublic void setType(VMStandardFilters type) {\r\n\t\tthis.type = type;\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unpack/vm/VMStandardFilters.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 31.05.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n * \r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unpack.vm;\r\n\r\n/**\r\n * DOCUMENT ME\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic enum VMStandardFilters {\r\n\tVMSF_NONE ((int)0),\r\n\tVMSF_E8 ((int)1),\r\n\tVMSF_E8E9 ((int)2),\r\n\tVMSF_ITANIUM( (int)3), \r\n\tVMSF_RGB ((int)4), \r\n\tVMSF_AUDIO ((int)5), \r\n\tVMSF_DELTA ((int)6),\r\n\tVMSF_UPCASE ((int)7);\r\n\t\r\n\tprivate int filter;\r\n\t\r\n\tprivate VMStandardFilters(int filter){\r\n\t\tthis.filter=filter;\r\n\t}\r\n\r\n\tpublic int getFilter() {\r\n\t\treturn filter;\r\n\t}\r\n\t\r\n\tpublic boolean equals(int filter){\r\n\t\treturn this.filter == filter;\r\n\t}\r\n\t\r\n\tpublic static VMStandardFilters findFilter(int filter){\r\n\t\tif (VMSF_NONE.equals(filter)) {\r\n\t\t\treturn VMSF_NONE;\r\n\t\t}\t\t \r\n\t\t\r\n\t\tif (VMSF_E8.equals(filter)) {\r\n\t\t\treturn VMSF_E8;\r\n\t\t}\t\t \r\n\t\t\r\n\t\tif (VMSF_E8E9.equals(filter)) {\r\n\t\t\treturn VMSF_E8E9;\r\n\t\t}\t\t \r\n\t\tif (VMSF_ITANIUM.equals(filter)) {\r\n\t\t\treturn VMSF_ITANIUM;\r\n\t\t}\t\t \r\n\t\t\r\n\t\tif (VMSF_RGB.equals(filter)) {\r\n\t\t\treturn VMSF_RGB;\r\n\t\t}\t\t  \r\n\t\t\r\n\t\tif (VMSF_AUDIO.equals(filter)) {\r\n\t\t\treturn VMSF_AUDIO;\r\n\t\t}\t\t \r\n\t\tif (VMSF_DELTA.equals(filter)) {\r\n\t\t\treturn VMSF_DELTA;\r\n\t\t}\t\t\r\n\t\treturn null;\r\n\t}\r\n\t\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unsigned/UnsignedByte.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 04.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n *\r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unsigned;\r\n\r\nimport com.github.junrar.crc.RarCRC;\r\n\r\n/**\r\n * DOCUMENT ME\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class UnsignedByte {\r\n\t\r\n\tpublic static byte longToByte(long unsignedByte1){\r\n\t\treturn (byte) (unsignedByte1&0xff);\r\n\t}\r\n\tpublic static byte intToByte(int unsignedByte1){\r\n\t\treturn (byte) (unsignedByte1&0xff);\r\n\t}\r\n\tpublic static byte shortToByte(short unsignedByte1){\r\n\t\treturn (byte) (unsignedByte1&0xff);\r\n\t}\r\n\t\r\n\t\r\n\tpublic static short add(byte unsignedByte1, byte unsignedByte2){\r\n\t\treturn (short) (unsignedByte1 + unsignedByte2);\r\n\t}\r\n\t\r\n\tpublic static short sub(byte unsignedByte1, byte unsignedByte2){\r\n\t\t\r\n\t\treturn (short) (unsignedByte1 - unsignedByte2);\r\n\t}\r\n\t\r\n\t\r\n\tpublic static void main(String[] args)\r\n\t{\r\n\t//tests unsigned (signed)\r\n\t\t//add\r\n\t\tSystem.out.println(add((byte)0xfe,(byte)0x01)); //255 (-1)\r\n\t\tSystem.out.println(add((byte)0xff,(byte)0x01)); //0 (0)\r\n\t\tSystem.out.println(add((byte)0x7f,(byte)0x01)); //128 (-128)\r\n\t\tSystem.out.println(add((byte)0xff,(byte)0xff)); //254 (-2)\r\n\t\t\r\n\t\t//sub\r\n\t\tSystem.out.println(sub((byte)0xfe,(byte)0x01)); //253 (-3)\r\n\t\tSystem.out.println(sub((byte)0x00,(byte)0x01)); //255 (-1)\r\n\t\tSystem.out.println(sub((byte)0x80,(byte)0x01)); //127 (127)\r\n\t\t//mul\r\n\t\tSystem.out.println((byte)-1*(byte)-1);\r\n\t}\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unsigned/UnsignedInteger.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 04.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n *\r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unsigned;\r\n\r\n/**\r\n * DOCUMENT ME\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class UnsignedInteger {\r\n\t\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unsigned/UnsignedLong.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 04.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n *\r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unsigned;\r\n\r\n/**\r\n * DOCUMENT ME\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class UnsignedLong {\r\n\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/unsigned/UnsignedShort.java",
    "content": "/*\r\n * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.\r\n * Original author: Edmund Wagner\r\n * Creation date: 04.06.2007\r\n *\r\n * Source: $HeadURL$\r\n * Last changed: $LastChangedDate$\r\n * \r\n * \r\n * the unrar licence applies to all junrar source and binary distributions \r\n * you are not allowed to use this source to re-create the RAR compression algorithm\r\n *\r\n * Here some html entities which can be used for escaping javadoc tags:\r\n * \"&\":  \"&#038;\" or \"&amp;\"\r\n * \"<\":  \"&#060;\" or \"&lt;\"\r\n * \">\":  \"&#062;\" or \"&gt;\"\r\n * \"@\":  \"&#064;\" \r\n */\r\npackage com.github.junrar.unsigned;\r\n\r\n/**\r\n * DOCUMENT ME\r\n *\r\n * @author $LastChangedBy$\r\n * @version $LastChangedRevision$\r\n */\r\npublic class UnsignedShort {\r\n\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/util/VolumeHelper.java",
    "content": "package com.github.junrar.util;\r\n\r\n/**\r\n * \r\n * @author alban\r\n */\r\npublic class VolumeHelper {\r\n\tprivate VolumeHelper() {\r\n\t}\r\n\r\n\t// public static boolean mergeArchive(Archive archive, ComprDataIO dataIO)\r\n\t// throws IOException {\r\n\t// FileHeader hd = dataIO.getSubHeader();\r\n\t// if (hd.getUnpVersion() >= 20 && hd.getFileCRC() != 0xffffffff\r\n\t// && dataIO.getPackedCRC() != ~hd.getFileCRC()) {\r\n\t// System.err.println(\"Data Bad CRC\");\r\n\t// }\r\n\t//\r\n\t// boolean oldNumbering = !archive.getMainHeader().isNewNumbering()\r\n\t// || archive.isOldFormat();\r\n\t// String nextName = nextVolumeName(archive.getFile().getAbsolutePath(),\r\n\t// oldNumbering);\r\n\t// File nextVolume = new File(nextName);\r\n\t// UnrarCallback callback = archive.getUnrarCallback();\r\n\t// if ((callback != null) && !callback.isNextVolumeReady(nextVolume)) {\r\n\t// return false;\r\n\t// }\r\n\t// if (!nextVolume.exists()) {\r\n\t// return false;\r\n\t// }\r\n\t// archive.setFile(nextVolume);\r\n\t// hd = archive.nextFileHeader();\r\n\t// if (hd == null) {\r\n\t// return false;\r\n\t// }\r\n\t// dataIO.init(hd);\r\n\t// return true;\r\n\t// }\r\n\r\n\tpublic static String nextVolumeName(String arcName, boolean oldNumbering) {\r\n\t\tif (!oldNumbering) {\r\n\t\t\t// part1.rar, part2.rar, ...\r\n\t\t\tint len = arcName.length();\r\n\t\t\tint indexR = len - 1;\r\n\t\t\twhile ((indexR >= 0) && !isDigit(arcName.charAt(indexR))) {\r\n\t\t\t\tindexR--;\r\n\t\t\t}\r\n\t\t\tint index = indexR + 1;\r\n\t\t\tint indexL = indexR - 1;\r\n\t\t\twhile ((indexL >= 0) && isDigit(arcName.charAt(indexL))) {\r\n\t\t\t\tindexL--;\r\n\t\t\t}\r\n\t\t\tif (indexL < 0) {\r\n\t\t\t\treturn null;\r\n\t\t\t}\r\n\t\t\tindexL++;\r\n\t\t\tStringBuilder buffer = new StringBuilder(len);\r\n\t\t\tbuffer.append(arcName, 0, indexL);\r\n\t\t\tchar[] digits = new char[indexR - indexL + 1];\r\n\t\t\tarcName.getChars(indexL, indexR + 1, digits, 0);\r\n\t\t\tindexR = digits.length - 1;\r\n\t\t\twhile ((indexR >= 0) && (++digits[indexR]) == '9' + 1) {\r\n\t\t\t\tdigits[indexR] = '0';\r\n\t\t\t\tindexR--;\r\n\t\t\t}\r\n\t\t\tif (indexR < 0) {\r\n\t\t\t\tbuffer.append('1');\r\n\t\t\t}\r\n\t\t\tbuffer.append(digits);\r\n\t\t\tbuffer.append(arcName, index, len);\r\n\t\t\treturn buffer.toString();\r\n\t\t} else {\r\n\t\t\t// .rar, .r00, .r01, ...\r\n\t\t\tint len = arcName.length();\r\n\t\t\tif ((len <= 4) || (arcName.charAt(len - 4) != '.')) {\r\n\t\t\t\treturn null;\r\n\t\t\t}\r\n\t\t\tStringBuilder buffer = new StringBuilder();\r\n\t\t\tint off = len - 3;\r\n\t\t\tbuffer.append(arcName, 0, off);\r\n\t\t\tif (!isDigit(arcName.charAt(off + 1))\r\n\t\t\t\t\t|| !isDigit(arcName.charAt(off + 2))) {\r\n\t\t\t\tbuffer.append(\"r00\");\r\n\t\t\t} else {\r\n\t\t\t\tchar[] ext = new char[3];\r\n\t\t\t\tarcName.getChars(off, len, ext, 0);\r\n\t\t\t\tint i = ext.length - 1;\r\n\t\t\t\twhile ((++ext[i]) == '9' + 1) {\r\n\t\t\t\t\text[i] = '0';\r\n\t\t\t\t\ti--;\r\n\t\t\t\t}\r\n\t\t\t\tbuffer.append(ext);\r\n\t\t\t}\r\n\t\t\treturn buffer.toString();\r\n\t\t}\r\n\t}\r\n\r\n\tprivate static boolean isDigit(char c) {\r\n\t\treturn (c >= '0') && (c <= '9');\r\n\t}\r\n}\r\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/vfs2/provider/rar/RARFileObject.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.github.junrar.vfs2.provider.rar;\n\nimport java.io.InputStream;\nimport java.util.HashSet;\n\nimport org.apache.commons.vfs2.FileName;\nimport org.apache.commons.vfs2.FileObject;\nimport org.apache.commons.vfs2.FileSystemException;\nimport org.apache.commons.vfs2.FileType;\nimport org.apache.commons.vfs2.provider.AbstractFileName;\nimport org.apache.commons.vfs2.provider.AbstractFileObject;\n\nimport com.github.junrar.Archive;\nimport com.github.junrar.rarfile.FileHeader;\n\n\n/**\n * A file in a RAR file system.\n * \n * @author <a href=\"http://www.rogiel.com\">Rogiel</a>\n */\npublic class RARFileObject extends AbstractFileObject implements FileObject {\n\t/**\n\t * The TFile.\n\t */\n\tprotected Archive archive;\n\tprotected FileHeader header;\n\t@SuppressWarnings(\"unused\")\n\tprivate final RARFileSystem fs;\n\n\tprivate final HashSet<String> children = new HashSet<String>();\n\n\tprotected RARFileObject(AbstractFileName name, Archive archive,\n\t\t\tFileHeader header, RARFileSystem fs) throws FileSystemException {\n\t\tsuper(name, fs);\n\t\tthis.fs = fs;\n\t\tthis.archive = archive;\n\t\tthis.header = header;\n\t\tarchive.getMainHeader().isFirstVolume();\n\t}\n\n\t@Override\n\tpublic boolean doIsWriteable() throws FileSystemException {\n\t\treturn false;\n\t}\n\n\t@Override\n\tprotected FileType doGetType() {\n\t\tif (header == null || header.isDirectory()) {\n\t\t\treturn FileType.FOLDER;\n\t\t} else {\n\t\t\treturn FileType.FILE;\n\t\t}\n\t}\n\n\t@Override\n\tprotected String[] doListChildren() {\n\t\ttry {\n\t\t\tif (!getType().hasChildren()) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t} catch (FileSystemException e) {\n\t\t\t// should not happen as the type has already been cached.\n\t\t\tthrow new RuntimeException(e);\n\t\t}\n\t\treturn children.toArray(new String[children.size()]);\n\t}\n\n\t@Override\n\tprotected long doGetContentSize() {\n\t\treturn header.getFullUnpackSize();\n\t}\n\n\t@Override\n\tprotected long doGetLastModifiedTime() throws Exception {\n\t\treturn header.getMTime().getTime();\n\t}\n\n\t@Override\n\tprotected InputStream doGetInputStream() throws Exception {\n\t\tif (!getType().hasContent()) {\n\t\t\tthrow new FileSystemException(\"vfs.provider/read-not-file.error\",\n\t\t\t\t\tgetName());\n\t\t}\n\t\treturn archive.getInputStream(header);\n\t}\n\n\t/**\n\t * Attaches a child.\n\t * \n\t * @param childName\n\t *            The name of the child.\n\t */\n\tpublic void attachChild(FileName childName) {\n\t\tchildren.add(childName.getBaseName());\n\t}\n\n\t/**\n\t * @param header\n\t */\n\tpublic void setHeader(FileHeader header) {\n\t\tthis.header = header;\n\t}\n}\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/vfs2/provider/rar/RARFileProvider.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.github.junrar.vfs2.provider.rar;\n\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.Collections;\n\nimport org.apache.commons.vfs2.Capability;\nimport org.apache.commons.vfs2.FileName;\nimport org.apache.commons.vfs2.FileObject;\nimport org.apache.commons.vfs2.FileSystem;\nimport org.apache.commons.vfs2.FileSystemException;\nimport org.apache.commons.vfs2.FileSystemOptions;\nimport org.apache.commons.vfs2.FileType;\nimport org.apache.commons.vfs2.provider.AbstractFileName;\nimport org.apache.commons.vfs2.provider.AbstractLayeredFileProvider;\nimport org.apache.commons.vfs2.provider.FileProvider;\nimport org.apache.commons.vfs2.provider.LayeredFileName;\n\n/**\n * A file system provider for RAR files. Provides read-only file systems.\n * \n * @author <a href=\"http://www.rogiel.com\">Rogiel</a>\n */\npublic class RARFileProvider extends AbstractLayeredFileProvider implements\n\t\tFileProvider {\n\t/** The list of capabilities this provider supports */\n\tprotected static final Collection<Capability> capabilities = Collections\n\t\t\t.unmodifiableCollection(Arrays.asList(new Capability[] {\n\t\t\t\t\tCapability.GET_LAST_MODIFIED,\n\t\t\t\t\tCapability.GET_TYPE,\n\t\t\t\t\tCapability.LIST_CHILDREN,\n\t\t\t\t\tCapability.READ_CONTENT,\n\t\t\t\t\tCapability.URI,\n\t\t\t\t\tCapability.COMPRESS,\n\t\t\t\t\tCapability.VIRTUAL\n\t\t\t\t}));\n\n\tpublic RARFileProvider() {\n\t\tsuper();\n\t}\n\n\t/**\n\t * Creates a layered file system. This method is called if the file system\n\t * is not cached.\n\t * \n\t * @param scheme\n\t *            The URI scheme.\n\t * @param file\n\t *            The file to create the file system on top of.\n\t * @return The file system.\n\t */\n\t@Override\n\tprotected FileSystem doCreateFileSystem(final String scheme,\n\t\t\tfinal FileObject file, final FileSystemOptions fileSystemOptions)\n\t\t\tthrows FileSystemException {\n\t\tfinal AbstractFileName rootName = new LayeredFileName(scheme,\n\t\t\t\tfile.getName(), FileName.ROOT_PATH, FileType.FOLDER);\n\t\treturn new RARFileSystem(rootName, file, fileSystemOptions);\n\t}\n\n\tpublic Collection<Capability> getCapabilities() {\n\t\treturn capabilities;\n\t}\n}\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/vfs2/provider/rar/RARFileSystem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.github.junrar.vfs2.provider.rar;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.commons.vfs2.Capability;\nimport org.apache.commons.vfs2.FileObject;\nimport org.apache.commons.vfs2.FileSystem;\nimport org.apache.commons.vfs2.FileSystemException;\nimport org.apache.commons.vfs2.FileSystemOptions;\nimport org.apache.commons.vfs2.provider.AbstractFileName;\nimport org.apache.commons.vfs2.provider.AbstractFileSystem;\nimport org.apache.commons.vfs2.provider.UriParser;\n\nimport com.github.junrar.Archive;\nimport com.github.junrar.exception.RarException;\nimport com.github.junrar.rarfile.FileHeader;\n\n\n/**\n * A read-only file system for RAR files.\n * \n * @author <a href=\"http://www.rogiel.com\">Rogiel</a>\n */\npublic class RARFileSystem extends AbstractFileSystem implements FileSystem {\n\tprivate final FileObject parentLayer;\n\n\tprivate Archive archive;\n\tprivate Map<String, FileHeader> files = new HashMap<String, FileHeader>();\n\n\tpublic RARFileSystem(final AbstractFileName rootName,\n\t\t\tfinal FileObject parentLayer,\n\t\t\tfinal FileSystemOptions fileSystemOptions)\n\t\t\tthrows FileSystemException {\n\t\tsuper(rootName, parentLayer, fileSystemOptions);\n\t\tthis.parentLayer = parentLayer;\n\t}\n\n\t@Override\n\tpublic void init() throws FileSystemException {\n\t\tsuper.init();\n\n\t\ttry {\n\t\t\ttry {\n\t\t\t\tarchive = new Archive(new VFSVolumeManager(parentLayer));\n\t\t\t\t// Build the index\n\t\t\t\tList<RARFileObject> strongRef = new ArrayList<RARFileObject>(\n\t\t\t\t\t\t100);\n\t\t\t\tfor (final FileHeader header : archive.getFileHeaders()) {\n\t\t\t\t\tAbstractFileName name = (AbstractFileName) getFileSystemManager()\n\t\t\t\t\t\t\t.resolveName(\n\t\t\t\t\t\t\t\t\tgetRootName(),\n\t\t\t\t\t\t\t\t\tUriParser.encode(header.getFileNameString()));\n\n\t\t\t\t\t// Create the file\n\t\t\t\t\tRARFileObject fileObj;\n\t\t\t\t\tif (header.isDirectory() && getFileFromCache(name) != null) {\n\t\t\t\t\t\tfileObj = (RARFileObject) getFileFromCache(name);\n\t\t\t\t\t\tfileObj.setHeader(header);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tfileObj = createRARFileObject(name, header);\n\t\t\t\t\tputFileToCache(fileObj);\n\t\t\t\t\tstrongRef.add(fileObj);\n\t\t\t\t\tfileObj.holdObject(strongRef);\n\n\t\t\t\t\t// Make sure all ancestors exist\n\t\t\t\t\tRARFileObject parent;\n\t\t\t\t\tfor (AbstractFileName parentName = (AbstractFileName) name\n\t\t\t\t\t\t\t.getParent(); parentName != null; fileObj = parent, parentName = (AbstractFileName) parentName\n\t\t\t\t\t\t\t.getParent()) {\n\t\t\t\t\t\t// Locate the parent\n\t\t\t\t\t\tparent = (RARFileObject) getFileFromCache(parentName);\n\t\t\t\t\t\tif (parent == null) {\n\t\t\t\t\t\t\tparent = createRARFileObject(parentName, null);\n\t\t\t\t\t\t\tputFileToCache(parent);\n\t\t\t\t\t\t\tstrongRef.add(parent);\n\t\t\t\t\t\t\tparent.holdObject(strongRef);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Attach child to parent\n\t\t\t\t\t\tparent.attachChild(fileObj.getName());\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t} catch (RarException e) {\n\t\t\t\tthrow new FileSystemException(e);\n\t\t\t} catch (IOException e) {\n\t\t\t\tthrow new FileSystemException(e);\n\t\t\t}\n\t\t} finally {\n\t\t\t// closeCommunicationLink();\n\t\t}\n\t}\n\n\tprotected RARFileObject createRARFileObject(final AbstractFileName name,\n\t\t\tfinal FileHeader header) throws FileSystemException {\n\t\treturn new RARFileObject(name, archive, header, this);\n\t}\n\n\t@Override\n\tprotected void doCloseCommunicationLink() {\n\t\ttry {\n\t\t\tarchive.close();\n\t\t} catch (FileSystemException e) {\n\t\t\tthrow new RuntimeException(e);\n\t\t} catch (IOException e) {\n\t\t\tthrow new RuntimeException(e);\n\t\t}\n\t}\n\n\t/**\n\t * Returns the capabilities of this file system.\n\t */\n\t@Override\n\tprotected void addCapabilities(final Collection<Capability> caps) {\n\t\tcaps.addAll(RARFileProvider.capabilities);\n\t}\n\n\t/**\n\t * Creates a file object.\n\t */\n\t@Override\n\tprotected FileObject createFile(final AbstractFileName name)\n\t\t\tthrows FileSystemException {\n\t\tString path = name.getPath().substring(1);\n\t\tif (path.length() == 0) {\n\t\t\treturn new RARFileObject(name, archive, null, this);\n\t\t} else if (files.containsKey(name.getPath())) {\n\t\t\treturn new RARFileObject(name, archive, files.get(name.getPath()),\n\t\t\t\t\tthis);\n\t\t}\n\t\treturn null;\n\t}\n\n\t/**\n\t * will be called after all file-objects closed their streams.\n\t */\n\tprotected void notifyAllStreamsClosed() {\n\t\tcloseCommunicationLink();\n\t}\n}\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/vfs2/provider/rar/RandomAccessContentAccess.java",
    "content": "/*\n * This file is part of seedbox <github.com/seedbox>.\n *\n * seedbox is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * seedbox is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with seedbox.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage com.github.junrar.vfs2.provider.rar;\n\nimport java.io.IOException;\n\nimport org.apache.commons.vfs2.FileObject;\nimport org.apache.commons.vfs2.FileSystemException;\nimport org.apache.commons.vfs2.RandomAccessContent;\nimport org.apache.commons.vfs2.util.RandomAccessMode;\n\nimport com.github.junrar.io.IReadOnlyAccess;\n\n\n/**\n * @author <a href=\"http://www.rogiel.com\">Rogiel</a>\n * \n */\npublic class RandomAccessContentAccess implements IReadOnlyAccess {\n\tprivate final RandomAccessContent rac;\n\n\t/**\n\t * @param rac\n\t */\n\tpublic RandomAccessContentAccess(RandomAccessContent rac) {\n\t\tthis.rac = rac;\n\t}\n\n\t/**\n\t * @param rac\n\t * @throws FileSystemException\n\t */\n\tpublic RandomAccessContentAccess(FileObject file)\n\t\t\tthrows FileSystemException {\n\t\tthis(file.getContent().getRandomAccessContent(RandomAccessMode.READ));\n\t}\n\n\tpublic long getPosition() throws IOException {\n\t\treturn rac.getFilePointer();\n\t}\n\n\tpublic void setPosition(long pos) throws IOException {\n\t\trac.seek(pos);\n\t}\n\n\tpublic int read() throws IOException {\n\t\treturn rac.readByte();\n\t}\n\n\tpublic int read(byte[] buffer, int off, int count) throws IOException {\n\t\treturn rac.getInputStream().read(buffer, off, count);\n\t}\n\n\tpublic int readFully(byte[] buffer, int count) throws IOException {\n\t\treturn rac.getInputStream().read(buffer, 0, count);\n\t}\n\n\tpublic void close() throws IOException {\n\t\trac.close();\n\t}\n}\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/vfs2/provider/rar/VFSVolume.java",
    "content": "/*\n * This file is part of seedbox <github.com/seedbox>.\n *\n * seedbox is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * seedbox is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with seedbox.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage com.github.junrar.vfs2.provider.rar;\n\nimport java.io.IOException;\n\nimport org.apache.commons.vfs2.FileObject;\nimport org.apache.commons.vfs2.FileSystemException;\nimport org.apache.commons.vfs2.RandomAccessContent;\nimport org.apache.commons.vfs2.util.RandomAccessMode;\n\nimport com.github.junrar.Archive;\nimport com.github.junrar.Volume;\nimport com.github.junrar.io.IReadOnlyAccess;\nimport com.github.junrar.io.InputStreamReadOnlyAccessFile;\n\n\n/**\n * @author <a href=\"http://www.rogiel.com\">Rogiel</a>\n */\npublic class VFSVolume implements Volume {\n\tprivate final Archive archive;\n\tprivate final FileObject file;\n\n\t/**\n\t * @param archive\n\t * @param firstVolume\n\t */\n\tpublic VFSVolume(Archive archive, FileObject file) {\n\t\tthis.archive = archive;\n\t\tthis.file = file;\n\t}\n\n\t@Override\n\tpublic IReadOnlyAccess getReadOnlyAccess() throws IOException {\n\t\tIReadOnlyAccess input = null;\n\t\ttry {\n\t\t\tRandomAccessContent rac = file.getContent().getRandomAccessContent(\n\t\t\t\t\tRandomAccessMode.READ);\n\t\t\tinput = new RandomAccessContentAccess(rac);\n\t\t} catch (Exception e) {\n\t\t\tinput = new InputStreamReadOnlyAccessFile(file.getContent()\n\t\t\t\t\t.getInputStream());\n\t\t}\n\t\treturn input;\n\t}\n\n\t@Override\n\tpublic long getLength() {\n\t\ttry {\n\t\t\treturn file.getContent().getSize();\n\t\t} catch (FileSystemException e) {\n\t\t\treturn -1;\n\t\t}\n\t}\n\n\t@Override\n\tpublic Archive getArchive() {\n\t\treturn archive;\n\t}\n\n\t/**\n\t * @return the file\n\t */\n\tpublic FileObject getFile() {\n\t\treturn file;\n\t}\n}\n"
  },
  {
    "path": "unrar/src/main/java/com/github/junrar/vfs2/provider/rar/VFSVolumeManager.java",
    "content": "/*\n * This file is part of seedbox <github.com/seedbox>.\n *\n * seedbox is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * seedbox is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with seedbox.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage com.github.junrar.vfs2.provider.rar;\n\nimport java.io.IOException;\n\nimport org.apache.commons.vfs2.FileObject;\n\nimport com.github.junrar.Archive;\nimport com.github.junrar.Volume;\nimport com.github.junrar.VolumeManager;\nimport com.github.junrar.util.VolumeHelper;\n\n\n/**\n * @author <a href=\"http://www.rogiel.com\">Rogiel</a>\n */\npublic class VFSVolumeManager implements VolumeManager {\n\tprivate final FileObject firstVolume;\n\n\t/**\n\t * @param firstVolume\n\t */\n\tpublic VFSVolumeManager(FileObject firstVolume) {\n\t\tthis.firstVolume = firstVolume;\n\t}\n\n\t@Override\n\tpublic Volume nextArchive(Archive archive, Volume last) throws IOException {\n\t\tif (last == null)\n\t\t\treturn new VFSVolume(archive, firstVolume);\n\n\t\tVFSVolume vfsVolume = (VFSVolume) last;\n\t\tboolean oldNumbering = !archive.getMainHeader().isNewNumbering()\n\t\t\t\t|| archive.isOldFormat();\n\t\tString nextName = VolumeHelper.nextVolumeName(vfsVolume.getFile()\n\t\t\t\t.getName().getBaseName(), oldNumbering);\n\t\tFileObject nextVolumeFile = firstVolume.getParent().resolveFile(\n\t\t\t\tnextName);\n\n\t\treturn new VFSVolume(archive, nextVolumeFile);\n\t}\n}\n"
  }
]