├── .gitignore ├── license.txt ├── pom.xml └── src └── main ├── java └── de │ └── innosystec │ └── unrar │ ├── Archive.java │ ├── MVTest.java │ ├── UnrarCallback.java │ ├── Volume.java │ ├── crc │ └── RarCRC.java │ ├── crypt │ └── Rijndael.java │ ├── exception │ └── RarException.java │ ├── io │ ├── IReadOnlyAccess.java │ ├── Raw.java │ ├── ReadOnlyAccessByteArray.java │ ├── ReadOnlyAccessFile.java │ └── ReadOnlyAccessInputStream.java │ ├── rarfile │ ├── AVHeader.java │ ├── BaseBlock.java │ ├── BlockHeader.java │ ├── CommentHeader.java │ ├── EAHeader.java │ ├── EndArcHeader.java │ ├── FileHeader.java │ ├── FileNameDecoder.java │ ├── HostSystem.java │ ├── MacInfoHeader.java │ ├── MainHeader.java │ ├── MarkHeader.java │ ├── NewSubHeaderType.java │ ├── ProtectHeader.java │ ├── SignHeader.java │ ├── SubBlockHeader.java │ ├── SubBlockHeaderType.java │ ├── UnixOwnersHeader.java │ └── UnrarHeadertype.java │ ├── tika │ └── RARParser.java │ ├── unpack │ ├── ComprDataIO.java │ ├── Unpack.java │ ├── Unpack15.java │ ├── Unpack20.java │ ├── UnpackFilter.java │ ├── decode │ │ ├── AudioVariables.java │ │ ├── BitDecode.java │ │ ├── CodeType.java │ │ ├── Compress.java │ │ ├── Decode.java │ │ ├── DistDecode.java │ │ ├── FilterType.java │ │ ├── LitDecode.java │ │ ├── LowDistDecode.java │ │ ├── MultDecode.java │ │ └── RepDecode.java │ ├── ppm │ │ ├── AnalyzeHeapDump.java │ │ ├── BlockTypes.java │ │ ├── FreqData.java │ │ ├── ModelPPM.java │ │ ├── PPMContext.java │ │ ├── Pointer.java │ │ ├── RangeCoder.java │ │ ├── RarMemBlock.java │ │ ├── RarNode.java │ │ ├── SEE2Context.java │ │ ├── State.java │ │ ├── StateRef.java │ │ └── SubAllocator.java │ └── vm │ │ ├── BitInput.java │ │ ├── RarVM.java │ │ ├── VMCmdFlags.java │ │ ├── VMCommands.java │ │ ├── VMFlags.java │ │ ├── VMOpType.java │ │ ├── VMPreparedCommand.java │ │ ├── VMPreparedOperand.java │ │ ├── VMPreparedProgram.java │ │ ├── VMStandardFilterSignature.java │ │ └── VMStandardFilters.java │ └── unsigned │ ├── UnsignedByte.java │ ├── UnsignedInteger.java │ ├── UnsignedLong.java │ └── UnsignedShort.java └── resources └── META-INF └── services └── org.apache.tika.parser.Parser /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | ****** ***** ****** UnRAR - free utility for RAR archives 2 | ** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 3 | ****** ******* ****** License for use and distribution of 4 | ** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 5 | ** ** ** ** ** ** FREE portable version 6 | ~~~~~~~~~~~~~~~~~~~~~ 7 | 8 | The source code of UnRAR utility is freeware. This means: 9 | 10 | 1. All copyrights to RAR and the utility UnRAR are exclusively 11 | owned by the author - Alexander Roshal. 12 | 13 | 2. The UnRAR sources may be used in any software to handle RAR 14 | archives without limitations free of charge, but cannot be used 15 | to re-create the RAR compression algorithm, which is proprietary. 16 | Distribution of modified UnRAR sources in separate form or as a 17 | part of other software is permitted, provided that it is clearly 18 | stated in the documentation and source comments that the code may 19 | not be used to develop a RAR (WinRAR) compatible archiver. 20 | 21 | 3. The UnRAR utility may be freely distributed. It is allowed 22 | to distribute UnRAR inside of other software packages. 23 | 24 | 4. THE RAR ARCHIVER AND THE UnRAR UTILITY ARE DISTRIBUTED "AS IS". 25 | NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED. YOU USE AT 26 | YOUR OWN RISK. THE AUTHOR WILL NOT BE LIABLE FOR DATA LOSS, 27 | DAMAGES, LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING 28 | OR MISUSING THIS SOFTWARE. 29 | 30 | 5. Installing and using the UnRAR utility signifies acceptance of 31 | these terms and conditions of the license. 32 | 33 | 6. If you don't agree with terms of the license you must remove 34 | UnRAR files from your storage devices and cease to use the 35 | utility. 36 | 37 | Thank you for your interest in RAR and UnRAR. 38 | 39 | 40 | Alexander L. Roshal -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | de.innosystec 6 | java-unrar 7 | 1.7.0-SNAPSHOT 8 | 9 | Java UnRar 10 | http://sourceforge.net/projects/java-unrar 11 | 12 | 13 | 14 | commons-logging 15 | commons-logging 16 | 1.1.1 17 | 18 | 19 | org.apache.tika 20 | tika-core 21 | 0.8-SNAPSHOT 22 | true 23 | 24 | 25 | 26 | 27 | 28 | 29 | maven-compiler-plugin 30 | 31 | 1.5 32 | 1.5 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/Archive.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 22.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression 11 | * algorithm 12 | * 13 | * Here some html entities which can be used for escaping javadoc tags: 14 | * "&": "&" or "&" 15 | * "<": "<" or "<" 16 | * ">": ">" or ">" 17 | * "@": "@" 18 | */ 19 | package de.innosystec.unrar; 20 | 21 | import java.io.Closeable; 22 | import java.io.File; 23 | import java.io.IOException; 24 | import java.io.OutputStream; 25 | import java.util.ArrayList; 26 | import java.util.List; 27 | import java.util.logging.Level; 28 | import java.util.logging.Logger; 29 | 30 | import de.innosystec.unrar.exception.RarException; 31 | import de.innosystec.unrar.exception.RarException.RarExceptionType; 32 | import de.innosystec.unrar.io.IReadOnlyAccess; 33 | import de.innosystec.unrar.io.ReadOnlyAccessFile; 34 | import de.innosystec.unrar.rarfile.AVHeader; 35 | import de.innosystec.unrar.rarfile.BaseBlock; 36 | import de.innosystec.unrar.rarfile.BlockHeader; 37 | import de.innosystec.unrar.rarfile.CommentHeader; 38 | import de.innosystec.unrar.rarfile.EAHeader; 39 | import de.innosystec.unrar.rarfile.EndArcHeader; 40 | import de.innosystec.unrar.rarfile.FileHeader; 41 | import de.innosystec.unrar.rarfile.MacInfoHeader; 42 | import de.innosystec.unrar.rarfile.MainHeader; 43 | import de.innosystec.unrar.rarfile.MarkHeader; 44 | import de.innosystec.unrar.rarfile.ProtectHeader; 45 | import de.innosystec.unrar.rarfile.SignHeader; 46 | import de.innosystec.unrar.rarfile.SubBlockHeader; 47 | import de.innosystec.unrar.rarfile.UnixOwnersHeader; 48 | import de.innosystec.unrar.rarfile.UnrarHeadertype; 49 | import de.innosystec.unrar.unpack.ComprDataIO; 50 | import de.innosystec.unrar.unpack.Unpack; 51 | 52 | /** 53 | * The Main Rar Class; represents a rar Archive 54 | * 55 | * @author $LastChangedBy$ 56 | * @version $LastChangedRevision$ 57 | */ 58 | public class Archive implements Closeable { 59 | 60 | private static Logger logger = Logger.getLogger(Archive.class.getName()); 61 | 62 | private File file; 63 | 64 | private IReadOnlyAccess rof; 65 | 66 | private final UnrarCallback unrarCallback; 67 | 68 | private final ComprDataIO dataIO; 69 | 70 | private final List headers = new ArrayList(); 71 | 72 | private MarkHeader markHead = null; 73 | 74 | private MainHeader newMhd = null; 75 | 76 | private EndArcHeader endHeader = null; 77 | 78 | private Unpack unpack; 79 | 80 | /** Archive data CRC. */ 81 | private long arcDataCRC = 0xffffffff; 82 | 83 | private int currentHeaderIndex; 84 | 85 | private boolean encrypted = false; 86 | 87 | private int sfxSize = 0; 88 | 89 | /** Size of packed data in current file. */ 90 | private long totalPackedSize = 0L; 91 | 92 | /** Number of bytes of compressed data read from current file. */ 93 | private long totalPackedRead = 0L; 94 | 95 | public Archive(File file) throws RarException, IOException { 96 | this(file, null); 97 | } 98 | 99 | /** 100 | * create a new archive object using the given file 101 | * 102 | * @param file 103 | * the file to extract 104 | * @throws RarException 105 | */ 106 | public Archive(File file, UnrarCallback unrarCallback) throws RarException, 107 | IOException { 108 | setFile(file); 109 | this.unrarCallback = unrarCallback; 110 | dataIO = new ComprDataIO(this); 111 | } 112 | 113 | public File getFile() { 114 | return file; 115 | } 116 | 117 | void setFile(File file) throws IOException { 118 | this.file = file; 119 | totalPackedSize = 0L; 120 | totalPackedRead = 0L; 121 | close(); 122 | rof = new ReadOnlyAccessFile(file); 123 | try { 124 | readHeaders(); 125 | } catch (Exception e) { 126 | logger.log(Level.WARNING, 127 | "exception in archive constructor maybe file is encrypted " 128 | + "or currupt", e); 129 | // ignore exceptions to allow exraction of working files in 130 | // corrupt archive 131 | } 132 | // Calculate size of packed data 133 | for (BaseBlock block : headers) { 134 | if (block.getHeaderType() == UnrarHeadertype.FileHeader) { 135 | totalPackedSize += ((FileHeader) block).getFullPackSize(); 136 | } 137 | } 138 | if (unrarCallback != null) { 139 | unrarCallback.volumeProgressChanged(totalPackedRead, 140 | totalPackedSize); 141 | } 142 | } 143 | 144 | public void bytesReadRead(int count) { 145 | if (count > 0) { 146 | totalPackedRead += count; 147 | if (unrarCallback != null) { 148 | unrarCallback.volumeProgressChanged(totalPackedRead, 149 | totalPackedSize); 150 | } 151 | } 152 | } 153 | 154 | public IReadOnlyAccess getRof() { 155 | return rof; 156 | } 157 | 158 | /** 159 | * @return returns all file headers of the archive 160 | */ 161 | public List getFileHeaders() { 162 | List list = new ArrayList(); 163 | for (BaseBlock block : headers) { 164 | if (block.getHeaderType().equals(UnrarHeadertype.FileHeader)) { 165 | list.add((FileHeader) block); 166 | } 167 | } 168 | return list; 169 | } 170 | 171 | public FileHeader nextFileHeader() { 172 | int n = headers.size(); 173 | while (currentHeaderIndex < n) { 174 | BaseBlock block = headers.get(currentHeaderIndex++); 175 | if (block.getHeaderType() == UnrarHeadertype.FileHeader) { 176 | return (FileHeader) block; 177 | } 178 | } 179 | return null; 180 | } 181 | 182 | public UnrarCallback getUnrarCallback() { 183 | return unrarCallback; 184 | } 185 | 186 | /** 187 | * 188 | * @return whether the archive is encrypted 189 | */ 190 | public boolean isEncrypted() { 191 | if (newMhd != null) { 192 | return newMhd.isEncrypted(); 193 | } else { 194 | throw new NullPointerException("mainheader is null"); 195 | } 196 | } 197 | 198 | /** 199 | * Read the headers of the archive 200 | * 201 | * @throws RarException 202 | */ 203 | private void readHeaders() throws IOException, RarException { 204 | markHead = null; 205 | newMhd = null; 206 | endHeader = null; 207 | headers.clear(); 208 | currentHeaderIndex = 0; 209 | int toRead = 0; 210 | 211 | long fileLength = this.file.length(); 212 | 213 | while (true) { 214 | int size = 0; 215 | long newpos = 0; 216 | byte[] baseBlockBuffer = new byte[BaseBlock.BaseBlockSize]; 217 | 218 | long position = rof.getPosition(); 219 | 220 | // Weird, but is trying to read beyond the end of the file 221 | if (position >= fileLength) { 222 | break; 223 | } 224 | 225 | // logger.info("\n--------reading header--------"); 226 | size = rof.readFully(baseBlockBuffer, BaseBlock.BaseBlockSize); 227 | if (size == 0) { 228 | break; 229 | } 230 | BaseBlock block = new BaseBlock(baseBlockBuffer); 231 | 232 | block.setPositionInFile(position); 233 | 234 | switch (block.getHeaderType()) { 235 | 236 | case MarkHeader: 237 | markHead = new MarkHeader(block); 238 | if (!markHead.isSignature()) { 239 | throw new RarException( 240 | RarException.RarExceptionType.badRarArchive); 241 | } 242 | headers.add(markHead); 243 | // markHead.print(); 244 | break; 245 | 246 | case MainHeader: 247 | int mainHeaderSize = 0; 248 | toRead = block.hasEncryptVersion() ? MainHeader.mainHeaderSizeWithEnc 249 | : MainHeader.mainHeaderSize; 250 | byte[] mainbuff = new byte[toRead]; 251 | mainHeaderSize = rof.readFully(mainbuff, toRead); 252 | MainHeader mainhead = new MainHeader(block, mainbuff); 253 | headers.add(mainhead); 254 | this.newMhd = mainhead; 255 | if (newMhd.isEncrypted()) { 256 | throw new RarException( 257 | RarExceptionType.rarEncryptedException); 258 | } 259 | // mainhead.print(); 260 | break; 261 | 262 | case SignHeader: 263 | int signHeaderSize = 0; 264 | toRead = SignHeader.signHeaderSize; 265 | byte[] signBuff = new byte[toRead]; 266 | signHeaderSize = rof.readFully(signBuff, toRead); 267 | SignHeader signHead = new SignHeader(block, signBuff); 268 | headers.add(signHead); 269 | // logger.info("HeaderType: SignHeader"); 270 | 271 | break; 272 | 273 | case AvHeader: 274 | int avHeaderSize = 0; 275 | toRead = AVHeader.avHeaderSize; 276 | byte[] avBuff = new byte[toRead]; 277 | avHeaderSize = rof.readFully(avBuff, toRead); 278 | AVHeader avHead = new AVHeader(block, avBuff); 279 | headers.add(avHead); 280 | // logger.info("headertype: AVHeader"); 281 | break; 282 | 283 | case CommHeader: 284 | int commHeaderSize = 0; 285 | toRead = CommentHeader.commentHeaderSize; 286 | byte[] commBuff = new byte[toRead]; 287 | commHeaderSize = rof.readFully(commBuff, toRead); 288 | CommentHeader commHead = new CommentHeader(block, commBuff); 289 | headers.add(commHead); 290 | // logger.info("method: "+commHead.getUnpMethod()+"; 0x"+ 291 | // Integer.toHexString(commHead.getUnpMethod())); 292 | newpos = commHead.getPositionInFile() 293 | + commHead.getHeaderSize(); 294 | rof.setPosition(newpos); 295 | 296 | break; 297 | case EndArcHeader: 298 | 299 | toRead = 0; 300 | if (block.hasArchiveDataCRC()) { 301 | toRead += EndArcHeader.endArcArchiveDataCrcSize; 302 | } 303 | if (block.hasVolumeNumber()) { 304 | toRead += EndArcHeader.endArcVolumeNumberSize; 305 | } 306 | EndArcHeader endArcHead; 307 | if (toRead > 0) { 308 | int endArcHeaderSize = 0; 309 | byte[] endArchBuff = new byte[toRead]; 310 | endArcHeaderSize = rof.readFully(endArchBuff, toRead); 311 | endArcHead = new EndArcHeader(block, endArchBuff); 312 | // logger.info("HeaderType: endarch\ndatacrc:"+ 313 | // endArcHead.getArchiveDataCRC()); 314 | } else { 315 | // logger.info("HeaderType: endarch - no Data"); 316 | endArcHead = new EndArcHeader(block, null); 317 | } 318 | headers.add(endArcHead); 319 | this.endHeader = endArcHead; 320 | // logger.info("\n--------end header--------"); 321 | return; 322 | 323 | default: 324 | byte[] blockHeaderBuffer = new byte[BlockHeader.blockHeaderSize]; 325 | int bhsize = rof.readFully(blockHeaderBuffer, 326 | BlockHeader.blockHeaderSize); 327 | BlockHeader blockHead = new BlockHeader(block, 328 | blockHeaderBuffer); 329 | 330 | switch (blockHead.getHeaderType()) { 331 | case NewSubHeader: 332 | case FileHeader: 333 | toRead = blockHead.getHeaderSize() 334 | - BlockHeader.BaseBlockSize 335 | - BlockHeader.blockHeaderSize; 336 | byte[] fileHeaderBuffer = new byte[toRead]; 337 | int fhsize = rof.readFully(fileHeaderBuffer, toRead); 338 | 339 | FileHeader fh = new FileHeader(blockHead, fileHeaderBuffer); 340 | // if (DEBUG) { 341 | // fh.print(); 342 | // } 343 | headers.add(fh); 344 | newpos = fh.getPositionInFile() + fh.getHeaderSize() 345 | + fh.getFullPackSize(); 346 | rof.setPosition(newpos); 347 | break; 348 | 349 | case ProtectHeader: 350 | toRead = blockHead.getHeaderSize() 351 | - BlockHeader.BaseBlockSize 352 | - BlockHeader.blockHeaderSize; 353 | byte[] protectHeaderBuffer = new byte[toRead]; 354 | int phsize = rof.readFully(protectHeaderBuffer, toRead); 355 | ProtectHeader ph = new ProtectHeader(blockHead, 356 | protectHeaderBuffer); 357 | 358 | // logger.info("totalblocks"+ph.getTotalBlocks()); 359 | newpos = ph.getPositionInFile() + ph.getHeaderSize(); 360 | rof.setPosition(newpos); 361 | break; 362 | 363 | case SubHeader: { 364 | byte[] subHeadbuffer = new byte[SubBlockHeader.SubBlockHeaderSize]; 365 | int subheadersize = rof.readFully(subHeadbuffer, 366 | SubBlockHeader.SubBlockHeaderSize); 367 | SubBlockHeader subHead = new SubBlockHeader(blockHead, 368 | subHeadbuffer); 369 | subHead.print(); 370 | switch (subHead.getSubType()) { 371 | case MAC_HEAD: { 372 | byte[] macHeaderbuffer = new byte[MacInfoHeader.MacInfoHeaderSize]; 373 | int macheadersize = rof.readFully(macHeaderbuffer, 374 | MacInfoHeader.MacInfoHeaderSize); 375 | MacInfoHeader macHeader = new MacInfoHeader(subHead, 376 | macHeaderbuffer); 377 | macHeader.print(); 378 | headers.add(macHeader); 379 | 380 | break; 381 | } 382 | // TODO implement other subheaders 383 | case BEEA_HEAD: 384 | break; 385 | case EA_HEAD: { 386 | byte[] eaHeaderBuffer = new byte[EAHeader.EAHeaderSize]; 387 | int eaheadersize = rof.readFully(eaHeaderBuffer, 388 | EAHeader.EAHeaderSize); 389 | EAHeader eaHeader = new EAHeader(subHead, 390 | eaHeaderBuffer); 391 | eaHeader.print(); 392 | headers.add(eaHeader); 393 | 394 | break; 395 | } 396 | case NTACL_HEAD: 397 | break; 398 | case STREAM_HEAD: 399 | break; 400 | case UO_HEAD: 401 | toRead = subHead.getHeaderSize(); 402 | toRead -= BaseBlock.BaseBlockSize; 403 | toRead -= BlockHeader.blockHeaderSize; 404 | toRead -= SubBlockHeader.SubBlockHeaderSize; 405 | byte[] uoHeaderBuffer = new byte[toRead]; 406 | int uoHeaderSize = rof 407 | .readFully(uoHeaderBuffer, toRead); 408 | UnixOwnersHeader uoHeader = new UnixOwnersHeader( 409 | subHead, uoHeaderBuffer); 410 | uoHeader.print(); 411 | headers.add(uoHeader); 412 | break; 413 | default: 414 | break; 415 | } 416 | 417 | break; 418 | } 419 | default: 420 | logger.warning("Unknown Header"); 421 | throw new RarException(RarExceptionType.notRarArchive); 422 | 423 | } 424 | } 425 | // logger.info("\n--------end header--------"); 426 | } 427 | } 428 | 429 | /** 430 | * Extract the file specified by the given header and write it to the 431 | * supplied output stream 432 | * 433 | * @param header 434 | * the header to be extracted 435 | * @param os 436 | * the outputstream 437 | * @throws RarException 438 | */ 439 | public void extractFile(FileHeader hd, OutputStream os) throws RarException { 440 | if (!headers.contains(hd)) { 441 | throw new RarException(RarExceptionType.headerNotInArchive); 442 | } 443 | try { 444 | doExtractFile(hd, os); 445 | } catch (Exception e) { 446 | if (e instanceof RarException) { 447 | throw (RarException) e; 448 | } else { 449 | throw new RarException(e); 450 | } 451 | } 452 | } 453 | 454 | private void doExtractFile(FileHeader hd, OutputStream os) 455 | throws RarException, IOException { 456 | dataIO.init(os); 457 | dataIO.init(hd); 458 | dataIO.setUnpFileCRC(this.isOldFormat() ? 0 : 0xffFFffFF); 459 | if (unpack == null) { 460 | unpack = new Unpack(dataIO); 461 | } 462 | if (!hd.isSolid()) { 463 | unpack.init(null); 464 | } 465 | unpack.setDestSize(hd.getFullUnpackSize()); 466 | try { 467 | unpack.doUnpack(hd.getUnpVersion(), hd.isSolid()); 468 | // Verify file CRC 469 | hd = dataIO.getSubHeader(); 470 | long actualCRC = hd.isSplitAfter() ? ~dataIO.getPackedCRC() 471 | : ~dataIO.getUnpFileCRC(); 472 | int expectedCRC = hd.getFileCRC(); 473 | if (actualCRC != expectedCRC) { 474 | throw new RarException(RarExceptionType.crcError); 475 | } 476 | // if (!hd.isSplitAfter()) { 477 | // // Verify file CRC 478 | // if(~dataIO.getUnpFileCRC() != hd.getFileCRC()){ 479 | // throw new RarException(RarExceptionType.crcError); 480 | // } 481 | // } 482 | } catch (Exception e) { 483 | unpack.cleanUp(); 484 | if (e instanceof RarException) { 485 | // throw new RarException((RarException)e); 486 | throw (RarException) e; 487 | } else { 488 | throw new RarException(e); 489 | } 490 | } 491 | } 492 | 493 | /** 494 | * @return returns the main header of this archive 495 | */ 496 | public MainHeader getMainHeader() { 497 | return newMhd; 498 | } 499 | 500 | /** 501 | * @return whether the archive is old format 502 | */ 503 | public boolean isOldFormat() { 504 | return markHead.isOldFormat(); 505 | } 506 | 507 | /** Close the underlying compressed file. */ 508 | public void close() throws IOException { 509 | if (rof != null) { 510 | rof.close(); 511 | rof = null; 512 | } 513 | if (unpack != null) { 514 | unpack.cleanUp(); 515 | } 516 | } 517 | } 518 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/MVTest.java: -------------------------------------------------------------------------------- 1 | package de.innosystec.unrar; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.io.FileOutputStream; 6 | import java.io.IOException; 7 | 8 | import de.innosystec.unrar.exception.RarException; 9 | import de.innosystec.unrar.rarfile.FileHeader; 10 | 11 | public class MVTest { 12 | 13 | /** 14 | * @param args 15 | */ 16 | public static void main(String[] args) { 17 | String filename="/home/Avenger/testdata/test2.part01.rar"; 18 | File f = new File(filename); 19 | Archive a=null; 20 | try { 21 | a = new Archive(f); 22 | } catch (RarException e) { 23 | // TODO Auto-generated catch block 24 | e.printStackTrace(); 25 | } catch (IOException e) { 26 | // TODO Auto-generated catch block 27 | e.printStackTrace(); 28 | } 29 | if(a!=null){ 30 | a.getMainHeader().print(); 31 | FileHeader fh = a.nextFileHeader(); 32 | while(fh!=null){ 33 | try { 34 | File out = new File("/home/Avenger/testdata/"+fh.getFileNameString().trim()); 35 | System.out.println(out.getAbsolutePath()); 36 | FileOutputStream os = new FileOutputStream(out); 37 | a.extractFile(fh, os); 38 | os.close(); 39 | } catch (FileNotFoundException e) { 40 | // TODO Auto-generated catch block 41 | e.printStackTrace(); 42 | } catch (RarException e) { 43 | // TODO Auto-generated catch block 44 | e.printStackTrace(); 45 | } catch (IOException e) { 46 | // TODO Auto-generated catch block 47 | e.printStackTrace(); 48 | } 49 | fh=a.nextFileHeader(); 50 | } 51 | } 52 | } 53 | } 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/UnrarCallback.java: -------------------------------------------------------------------------------- 1 | package de.innosystec.unrar; 2 | 3 | import java.io.File; 4 | 5 | /** 6 | * 7 | * @author alban 8 | */ 9 | public interface UnrarCallback { 10 | 11 | /** 12 | * Return true if the next volume is ready to be processed, 13 | * false otherwise. 14 | */ 15 | boolean isNextVolumeReady(File nextVolume); 16 | 17 | /** 18 | * This method is invoked each time the progress of the current 19 | * volume changes. 20 | */ 21 | void volumeProgressChanged(long current, long total); 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/Volume.java: -------------------------------------------------------------------------------- 1 | package de.innosystec.unrar; 2 | 3 | import de.innosystec.unrar.rarfile.FileHeader; 4 | import de.innosystec.unrar.unpack.*; 5 | import java.io.File; 6 | import java.io.IOException; 7 | 8 | /** 9 | * 10 | * @author alban 11 | */ 12 | public class Volume { 13 | 14 | private Volume() { 15 | } 16 | 17 | public static boolean mergeArchive(Archive archive, ComprDataIO dataIO) 18 | throws IOException { 19 | FileHeader hd = dataIO.getSubHeader(); 20 | if (hd.getUnpVersion()>=20 && 21 | hd.getFileCRC()!=0xffffffff && 22 | dataIO.getPackedCRC()!=~hd.getFileCRC()) { 23 | System.err.println("Data Bad CRC"); 24 | } 25 | 26 | boolean oldNumbering = !archive.getMainHeader().isNewNumbering() || 27 | archive.isOldFormat(); 28 | String nextName = nextVolumeName(archive.getFile().getAbsolutePath(), 29 | oldNumbering); 30 | File nextVolume = new File(nextName); 31 | UnrarCallback callback = archive.getUnrarCallback(); 32 | if ((callback != null) && !callback.isNextVolumeReady(nextVolume)) { 33 | return false; 34 | } 35 | if (!nextVolume.exists()) { 36 | return false; 37 | } 38 | archive.setFile(nextVolume); 39 | hd = archive.nextFileHeader(); 40 | if (hd == null) { 41 | return false; 42 | } 43 | dataIO.init(hd); 44 | return true; 45 | } 46 | 47 | public static String nextVolumeName(String arcName, 48 | boolean oldNumbering) { 49 | if (!oldNumbering) { 50 | // part1.rar, part2.rar, ... 51 | int len = arcName.length(); 52 | int indexR = len - 1; 53 | while ((indexR >= 0) && !isDigit(arcName.charAt(indexR))) { 54 | indexR--; 55 | } 56 | int index = indexR + 1; 57 | int indexL = indexR - 1; 58 | while ((indexL >= 0) && isDigit(arcName.charAt(indexL))) { 59 | indexL--; 60 | } 61 | if (indexL < 0) { 62 | return null; 63 | } 64 | indexL++; 65 | StringBuilder buffer = new StringBuilder(len); 66 | buffer.append(arcName, 0, indexL); 67 | char[] digits = new char[indexR - indexL + 1]; 68 | arcName.getChars(indexL, indexR + 1, digits, 0); 69 | indexR = digits.length - 1; 70 | while ((indexR >= 0) && (++digits[indexR]) == '9' + 1) { 71 | digits[indexR] = '0'; 72 | indexR--; 73 | } 74 | if (indexR < 0) { 75 | buffer.append('1'); 76 | } 77 | buffer.append(digits); 78 | buffer.append(arcName, index, len); 79 | return buffer.toString(); 80 | } 81 | else { 82 | // .rar, .r00, .r01, ... 83 | int len = arcName.length(); 84 | if ((len <= 4) || (arcName.charAt(len - 4) != '.')) { 85 | return null; 86 | } 87 | StringBuilder buffer = new StringBuilder(); 88 | int off = len - 3; 89 | buffer.append(arcName, 0, off); 90 | if (!isDigit(arcName.charAt(off + 1)) || 91 | !isDigit(arcName.charAt(off + 2))) { 92 | buffer.append("r00"); 93 | } 94 | else { 95 | char[] ext = new char[3]; 96 | arcName.getChars(off, len, ext, 0); 97 | int i = ext.length - 1; 98 | while ((++ext[i]) == '9' + 1) { 99 | ext[i] = '0'; 100 | i--; 101 | } 102 | buffer.append(ext); 103 | } 104 | return buffer.toString(); 105 | } 106 | } 107 | 108 | private static boolean isDigit(char c) { 109 | return (c >= '0') && (c <= '9'); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/crc/RarCRC.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 29.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.crc; 19 | 20 | import java.util.zip.CRC32; 21 | 22 | /** 23 | * DOCUMENT ME 24 | * 25 | * @author $LastChangedBy$ 26 | * @version $LastChangedRevision$ 27 | */ 28 | public class RarCRC { 29 | 30 | private final static int crcTab[]; 31 | static { 32 | crcTab = new int[256]; 33 | for (int i = 0; i < 256; i++) { 34 | int c = i; 35 | for (int j = 0; j < 8; j++){ 36 | if ((c & 1) !=0) { 37 | c >>>= 1; 38 | c ^= 0xEDB88320; 39 | } 40 | else{ 41 | c >>>= 1; 42 | } 43 | } 44 | crcTab[i] = c; 45 | } 46 | } 47 | 48 | private RarCRC() { 49 | } 50 | 51 | public static int checkCrc(int startCrc, byte[] data, int offset, 52 | int count) { 53 | int size = Math.min(data.length-offset,count); 54 | // #if defined(LITTLE_ENDIAN) && defined(PRESENT_INT32) && 55 | // defined(ALLOW_NOT_ALIGNED_INT) 56 | /* 57 | for (int i = 0; (0 < size) && i < data.length - 8 58 | && ((data[i + 8] & 7) != 0); i++) { 59 | startCrc = crcTab[(short) (startCrc ^ data[i]) & 0x00FF] ^ (startCrc >>> 8); 60 | size--; 61 | } 62 | 63 | for (int i = 0; size >= 8; i += 8) { 64 | startCrc ^= data[i + 0] << 24; 65 | startCrc ^= data[i + 1] << 16; 66 | startCrc ^= data[i + 2] << 8; 67 | startCrc ^= data[i + 3]; 68 | 69 | startCrc = crcTab[(short) startCrc & 0x00FF] ^ (startCrc >>> 8); 70 | startCrc = crcTab[(short) startCrc & 0x00FF] ^ (startCrc >>> 8); 71 | startCrc = crcTab[(short) startCrc & 0x00FF] ^ (startCrc >>> 8); 72 | startCrc = crcTab[(short) startCrc & 0x00FF] ^ (startCrc >>> 8); 73 | 74 | startCrc ^= data[i + 4] << 24; 75 | startCrc ^= data[i + 5] << 16; 76 | startCrc ^= data[i + 6] << 8; 77 | startCrc ^= data[i + 7]; 78 | startCrc = crcTab[(short) startCrc & 0x00FF] ^ (startCrc >>> 8); 79 | startCrc = crcTab[(short) startCrc & 0x00FF] ^ (startCrc >>> 8); 80 | startCrc = crcTab[(short) startCrc & 0x00FF] ^ (startCrc >>> 8); 81 | startCrc = crcTab[(short) startCrc & 0x00FF] ^ (startCrc >>> 8); 82 | size -= 8; 83 | }*/ 84 | 85 | for (int i = 0; i < size; i++) 86 | { 87 | /* 88 | // (byte)(StartCRC^Data[I]) 89 | int pos = 0; // pos=0x00000000 90 | pos |= startCrc; // pos=ffffffff 91 | 92 | pos ^= data[i]; // data[0]=0x73=115dec --> pos=140 93 | System.out.println(Integer.toHexString(pos)); 94 | 95 | // Only last 8 bit because CRCtab has length 256 96 | pos = pos & 0x000000FF; 97 | System.out.println("pos:"+pos); 98 | //startCrc >>>= 8; 99 | 100 | 101 | //StartCRC>>8 102 | int temp =0; 103 | temp|=startCrc; 104 | temp >>>= 8; 105 | System.out.println("temp:"+Integer.toHexString(temp)); 106 | 107 | 108 | startCrc = (crcTab[pos]^temp); 109 | System.out.println("--"+Integer.toHexString(startCrc));*/ 110 | 111 | startCrc=(crcTab[((int)((int)startCrc ^ 112 | (int)data[offset+i]))&0xff]^(startCrc>>>8)); 113 | 114 | //System.out.println(Integer.toHexString(startCrc)); 115 | 116 | // Original code: 117 | //StartCRC=CRCTab[(byte)(StartCRC^Data[I])]^(StartCRC>>8); 118 | } 119 | return (startCrc); 120 | } 121 | 122 | public static short checkOldCrc(short startCrc, byte[] data, int count) { 123 | int n = Math.min(data.length, count); 124 | for (int i = 0; i < n; i++) { 125 | startCrc = (short) ((short) (startCrc + (short) (data[i]&0x00ff)) & -1); 126 | startCrc = (short) (((startCrc << 1) | (startCrc >>> 15)) & -1); 127 | } 128 | return (startCrc); 129 | } 130 | 131 | // public static void main(String[] args) 132 | // { 133 | // RarCRC rc = new RarCRC(); 134 | // //byte[] data = { 0x72, 0x21, 0x1A, 0x07, 0x00}; 135 | // 136 | // byte[] data = {0x73 ,0x00 ,0x00 ,0x0D ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00}; 137 | // 138 | // int crc = 0x90CF; 139 | // 140 | // 141 | // int result = rc.checkCrc(0xFFFFffff, data,0,data.length); 142 | // System.out.println("3: "+Integer.toHexString(~result&0xffff)); 143 | // 144 | // } 145 | 146 | } 147 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/crypt/Rijndael.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 31.05.2007 5 | * 6 | * the unrar licence applies to all junrar source and binary distributions 7 | * you are not allowed to use this source to re-create the RAR compression algorithm 8 | * Source: $HeadURL$ 9 | * Last changed: $LastChangedDate$ 10 | * 11 | * Here some html entities which can be used for escaping javadoc tags: 12 | * "&": "&" or "&" 13 | * "<": "<" or "<" 14 | * ">": ">" or ">" 15 | * "@": "@" 16 | */ 17 | package de.innosystec.unrar.crypt; 18 | 19 | /** 20 | * DOCUMENT ME 21 | * 22 | * @author $LastChangedBy$ 23 | * @version $LastChangedRevision$ 24 | */ 25 | public class Rijndael { 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/exception/RarException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 30.07.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.exception; 19 | 20 | /** 21 | * DOCUMENT ME 22 | * 23 | * @author $LastChangedBy$ 24 | * @version $LastChangedRevision$ 25 | */ 26 | public class RarException extends Exception 27 | { 28 | 29 | private RarExceptionType type; 30 | 31 | public RarException(Exception e){ 32 | super(RarExceptionType.unkownError.name(),e); 33 | this.type = RarExceptionType.unkownError; 34 | } 35 | 36 | public RarException(RarException e) 37 | { 38 | 39 | super(e.getMessage(),e); 40 | this.type = e.getType(); 41 | } 42 | 43 | public RarException(RarExceptionType type){ 44 | super(type.name()); 45 | this.type = type; 46 | } 47 | 48 | 49 | 50 | public enum RarExceptionType{ 51 | notImplementedYet, 52 | crcError, 53 | notRarArchive, 54 | badRarArchive, 55 | unkownError, 56 | headerNotInArchive, 57 | wrongHeaderType, 58 | ioError, 59 | rarEncryptedException ; 60 | } 61 | 62 | 63 | 64 | public RarExceptionType getType() 65 | { 66 | return type; 67 | } 68 | 69 | public void setType(RarExceptionType type) 70 | { 71 | this.type = type; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/io/IReadOnlyAccess.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 23.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.io; 19 | 20 | import java.io.IOException; 21 | 22 | 23 | /** 24 | * DOCUMENT ME 25 | * 26 | * @author $LastChangedBy$ 27 | * @version $LastChangedRevision$ 28 | */ 29 | public interface IReadOnlyAccess { 30 | 31 | /** 32 | * @return the current position in the file 33 | */ 34 | public long getPosition() throws IOException; 35 | 36 | /** 37 | * @param pos the position in the file 38 | * @return success ? true : false 39 | */ 40 | public void setPosition(long pos) throws IOException; 41 | 42 | /** Read a single byte of data. */ 43 | public int read() throws IOException; 44 | 45 | /** 46 | * Read up to count bytes to the specified buffer. 47 | */ 48 | public int read(byte[] buffer, int off, int count) throws IOException; 49 | 50 | /** 51 | * Read exactly count bytes to the specified buffer. 52 | * 53 | * @param buffer where to store the read data 54 | * @param count how many bytes to read 55 | * @return bytes read || -1 if IO problem 56 | */ 57 | public int readFully(byte[] buffer, int count) throws IOException; 58 | 59 | /** Close this file. */ 60 | public void close() throws IOException; 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/io/Raw.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 18.06.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.io; 19 | 20 | /** 21 | * Read / write numbers to a byte[] regarding the endianness of the array 22 | * 23 | * @author $LastChangedBy$ 24 | * @version $LastChangedRevision$ 25 | */ 26 | public class Raw { 27 | /** 28 | * Read a short value from the byte array at the given position (Big Endian) 29 | * 30 | * @param array 31 | * the array to read from 32 | * @param pos 33 | * the position 34 | * @return the value 35 | */ 36 | public static final short readShortBigEndian(byte[] array, int pos) { 37 | short temp = 0; 38 | temp |= array[pos] & 0xff; 39 | temp <<= 8; 40 | temp |= array[pos + 1] & 0xff; 41 | return temp; 42 | } 43 | 44 | /** 45 | * Read a int value from the byte array at the given position (Big Endian) 46 | * 47 | * @param array 48 | * the array to read from 49 | * @param pos 50 | * the offset 51 | * @return the value 52 | */ 53 | public static final int readIntBigEndian(byte[] array, int pos) { 54 | int temp = 0; 55 | temp |= array[pos] & 0xff; 56 | temp <<= 8; 57 | temp |= array[pos + 1] & 0xff; 58 | temp <<= 8; 59 | temp |= array[pos + 2] & 0xff; 60 | temp <<= 8; 61 | temp |= array[pos + 3] & 0xff; 62 | return temp; 63 | } 64 | 65 | /** 66 | * Read a long value from the byte array at the given position (Big Endian) 67 | * 68 | * @param array 69 | * the array to read from 70 | * @param pos 71 | * the offset 72 | * @return the value 73 | */ 74 | public static final long readLongBigEndian(byte[] array, int pos) { 75 | int temp = 0; 76 | temp |= array[pos] & 0xff; 77 | temp <<= 8; 78 | temp |= array[pos + 1] & 0xff; 79 | temp <<= 8; 80 | temp |= array[pos + 2] & 0xff; 81 | temp <<= 8; 82 | temp |= array[pos + 3] & 0xff; 83 | temp <<= 8; 84 | temp |= array[pos + 4] & 0xff; 85 | temp <<= 8; 86 | temp |= array[pos + 5] & 0xff; 87 | temp <<= 8; 88 | temp |= array[pos + 6] & 0xff; 89 | temp <<= 8; 90 | temp |= array[pos + 7] & 0xff; 91 | return temp; 92 | } 93 | 94 | /** 95 | * Read a short value from the byte array at the given position (little 96 | * Endian) 97 | * 98 | * @param array 99 | * the array to read from 100 | * @param pos 101 | * the offset 102 | * @return the value 103 | */ 104 | public static final short readShortLittleEndian(byte[] array, int pos) { 105 | short result = 0; 106 | result += array[pos + 1] & 0xff; 107 | result <<= 8; 108 | result += array[pos] & 0xff; 109 | return result; 110 | } 111 | 112 | /** 113 | * Read an int value from the byte array at the given position (little 114 | * Endian) 115 | * 116 | * @param array 117 | * the array to read from 118 | * @param pos 119 | * the offset 120 | * @return the value 121 | */ 122 | public static final int readIntLittleEndian(byte[] array, int pos) { 123 | return ((array[pos + 3] & 0xff) << 24) 124 | | ((array[pos + 2] & 0xff) << 16) 125 | | ((array[pos + 1] & 0xff) << 8) | ((array[pos] & 0xff)); 126 | } 127 | 128 | /** 129 | * Read an long value(unsigned int) from the byte array at the given 130 | * position (little Endian) 131 | * 132 | * @param array 133 | * @param pos 134 | * @return 135 | */ 136 | public static final long readIntLittleEndianAsLong(byte[] array, int pos) { 137 | return (((long) array[pos + 3] & 0xff) << 24) 138 | | (((long) array[pos + 2] & 0xff) << 16) 139 | | (((long) array[pos + 1] & 0xff) << 8) 140 | | (((long) array[pos] & 0xff)); 141 | } 142 | 143 | /** 144 | * Read a long value from the byte array at the given position (little 145 | * Endian) 146 | * 147 | * @param array 148 | * the array to read from 149 | * @param pos 150 | * the offset 151 | * @return the value 152 | */ 153 | public static final long readLongLittleEndian(byte[] array, int pos) { 154 | int temp = 0; 155 | temp |= array[pos + 7] & 0xff; 156 | temp <<= 8; 157 | temp |= array[pos + 6] & 0xff; 158 | temp <<= 8; 159 | temp |= array[pos + 5] & 0xff; 160 | temp <<= 8; 161 | temp |= array[pos + 4] & 0xff; 162 | temp <<= 8; 163 | temp |= array[pos + 3] & 0xff; 164 | temp <<= 8; 165 | temp |= array[pos + 2] & 0xff; 166 | temp <<= 8; 167 | temp |= array[pos + 1] & 0xff; 168 | temp <<= 8; 169 | temp |= array[pos]; 170 | return temp; 171 | } 172 | 173 | /** 174 | * Write a short value into the byte array at the given position (Big 175 | * endian) 176 | * 177 | * @param array 178 | * the array 179 | * @param pos 180 | * the offset 181 | * @param value 182 | * the value to write 183 | */ 184 | public static final void writeShortBigEndian(byte[] array, int pos, 185 | short value) { 186 | array[pos] = (byte) (value >>> 8); 187 | array[pos + 1] = (byte) (value & 0xFF); 188 | 189 | } 190 | 191 | /** 192 | * Write an int value into the byte array at the given position (Big endian) 193 | * 194 | * @param array 195 | * the array 196 | * @param pos 197 | * the offset 198 | * @param value 199 | * the value to write 200 | */ 201 | public static final void writeIntBigEndian(byte[] array, int pos, int value) { 202 | array[pos] = (byte) ((value >>> 24) & 0xff); 203 | array[pos + 1] = (byte) ((value >>> 16) & 0xff); 204 | array[pos + 2] = (byte) ((value >>> 8) & 0xff); 205 | array[pos + 3] = (byte) ((value) & 0xff); 206 | 207 | } 208 | 209 | /** 210 | * Write a long value into the byte array at the given position (Big endian) 211 | * 212 | * @param array 213 | * the array 214 | * @param pos 215 | * the offset 216 | * @param value 217 | * the value to write 218 | */ 219 | public static final void writeLongBigEndian(byte[] array, int pos, 220 | long value) { 221 | array[pos] = (byte) (value >>> 56); 222 | array[pos + 1] = (byte) (value >>> 48); 223 | array[pos + 2] = (byte) (value >>> 40); 224 | array[pos + 3] = (byte) (value >>> 32); 225 | array[pos + 4] = (byte) (value >>> 24); 226 | array[pos + 5] = (byte) (value >>> 16); 227 | array[pos + 6] = (byte) (value >>> 8); 228 | array[pos + 7] = (byte) (value & 0xFF); 229 | 230 | } 231 | 232 | /** 233 | * Write a short value into the byte array at the given position (little 234 | * endian) 235 | * 236 | * @param array 237 | * the array 238 | * @param pos 239 | * the offset 240 | * @param value 241 | * the value to write 242 | */ 243 | public static final void writeShortLittleEndian(byte[] array, int pos, 244 | short value) { 245 | array[pos + 1] = (byte) (value >>> 8); 246 | array[pos] = (byte) (value & 0xFF); 247 | 248 | } 249 | 250 | /** 251 | * Increment a short value at the specified position by the specified amount 252 | * (little endian). 253 | */ 254 | public static final void incShortLittleEndian(byte[] array, int pos, int dv) { 255 | int c = ((array[pos] & 0xff) + (dv & 0xff)) >>> 8; 256 | array[pos] += dv & 0xff; 257 | if ((c > 0) || ((dv & 0xff00) != 0)) { 258 | array[pos + 1] += ((dv >>> 8) & 0xff) + c; 259 | } 260 | } 261 | 262 | /** 263 | * Write an int value into the byte array at the given position (little 264 | * endian) 265 | * 266 | * @param array 267 | * the array 268 | * @param pos 269 | * the offset 270 | * @param value 271 | * the value to write 272 | */ 273 | public static final void writeIntLittleEndian(byte[] array, int pos, 274 | int value) { 275 | array[pos + 3] = (byte) (value >>> 24); 276 | array[pos + 2] = (byte) (value >>> 16); 277 | array[pos + 1] = (byte) (value >>> 8); 278 | array[pos] = (byte) (value & 0xFF); 279 | 280 | } 281 | 282 | /** 283 | * Write a long value into the byte array at the given position (little 284 | * endian) 285 | * 286 | * @param array 287 | * the array 288 | * @param pos 289 | * the offset 290 | * @param value 291 | * the value to write 292 | */ 293 | public static final void writeLongLittleEndian(byte[] array, int pos, 294 | long value) { 295 | array[pos + 7] = (byte) (value >>> 56); 296 | array[pos + 6] = (byte) (value >>> 48); 297 | array[pos + 5] = (byte) (value >>> 40); 298 | array[pos + 4] = (byte) (value >>> 32); 299 | array[pos + 3] = (byte) (value >>> 24); 300 | array[pos + 2] = (byte) (value >>> 16); 301 | array[pos + 1] = (byte) (value >>> 8); 302 | array[pos] = (byte) (value & 0xFF); 303 | 304 | } 305 | } 306 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/io/ReadOnlyAccessByteArray.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 30.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.io; 19 | 20 | import java.io.EOFException; 21 | import java.io.IOException; 22 | 23 | /** 24 | * A File like access to a byte array. 25 | * (seek and read certain number of bytes) 26 | * 27 | * @author $LastChangedBy$ 28 | * @version $LastChangedRevision$ 29 | */ 30 | public class ReadOnlyAccessByteArray implements IReadOnlyAccess{ 31 | 32 | private int positionInFile; 33 | private byte[] file; 34 | 35 | /** 36 | * Initialize with byte[ ] 37 | * @param file the file given as byte array 38 | */ 39 | public ReadOnlyAccessByteArray(byte[] file){ 40 | if(file == null){ 41 | throw new NullPointerException("file must not be null!!"); 42 | } 43 | this.file = file; 44 | this.positionInFile = 0; 45 | } 46 | 47 | public long getPosition() throws IOException { 48 | return positionInFile; 49 | } 50 | 51 | public void setPosition(long pos) throws IOException { 52 | if (pos < file.length && pos >= 0){ 53 | this.positionInFile = (int)pos; 54 | } 55 | else{ 56 | throw new EOFException(); 57 | } 58 | } 59 | 60 | /** Read a single byte of data. */ 61 | public int read() throws IOException { 62 | return file[positionInFile++]; 63 | } 64 | 65 | /** 66 | * Read up to count bytes to the specified buffer. 67 | */ 68 | public int read(byte[] buffer, int off, int count) throws IOException { 69 | int read = Math.min(count, file.length-positionInFile); 70 | System.arraycopy(file, positionInFile, buffer, off, read); 71 | positionInFile += read; 72 | return read; 73 | } 74 | 75 | public int readFully(byte[] buffer, int count) throws IOException { 76 | if(buffer == null ){ 77 | throw new NullPointerException("buffer must not be null"); 78 | } 79 | if(count == 0){ 80 | throw new IllegalArgumentException("cannot read 0 bytes ;-)"); 81 | } 82 | int read = Math.min(count, file.length-(int)positionInFile-1); 83 | System.arraycopy(file, (int)positionInFile, buffer, 0, read ); 84 | positionInFile+=read; 85 | return read; 86 | } 87 | 88 | public void close() throws IOException { 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/io/ReadOnlyAccessFile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 23.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.io; 19 | 20 | import java.io.File; 21 | import java.io.FileNotFoundException; 22 | import java.io.IOException; 23 | import java.io.RandomAccessFile; 24 | 25 | /** 26 | * DOCUMENT ME 27 | * 28 | * @author $LastChangedBy$ 29 | * @version $LastChangedRevision$ 30 | */ 31 | public class ReadOnlyAccessFile extends RandomAccessFile 32 | implements IReadOnlyAccess{ 33 | 34 | /** 35 | * @param file the file 36 | * @throws FileNotFoundException 37 | */ 38 | public ReadOnlyAccessFile(File file) throws FileNotFoundException { 39 | super(file, "r"); 40 | } 41 | 42 | public int readFully(byte[] buffer, int count) throws IOException { 43 | assert (count > 0) : count; 44 | this.readFully(buffer, 0, count); 45 | return count; 46 | } 47 | 48 | public long getPosition() throws IOException { 49 | return this.getFilePointer(); 50 | } 51 | 52 | public void setPosition(long pos) throws IOException { 53 | this.seek(pos); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/io/ReadOnlyAccessInputStream.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 26.06.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression 11 | * algorithm 12 | * 13 | * Here some html entities which can be used for escaping javadoc tags: 14 | * "&": "&" or "&" 15 | * "<": "<" or "<" 16 | * ">": ">" or ">" 17 | * "@": "@" 18 | */ 19 | package de.innosystec.unrar.io; 20 | 21 | import java.io.IOException; 22 | import java.io.InputStream; 23 | 24 | /** 25 | * DOCUMENT ME 26 | * 27 | * @author $LastChangedBy$ 28 | * @version $LastChangedRevision$ 29 | */ 30 | public class ReadOnlyAccessInputStream extends InputStream { 31 | 32 | private IReadOnlyAccess file; 33 | 34 | private long curPos; 35 | private final long startPos; 36 | private final long endPos; 37 | 38 | public ReadOnlyAccessInputStream(IReadOnlyAccess file, long startPos, 39 | long endPos) throws IOException { 40 | super(); 41 | this.file = file; 42 | this.startPos = startPos; 43 | curPos = startPos; 44 | this.endPos = endPos; 45 | file.setPosition(curPos); 46 | } 47 | 48 | @Override 49 | public int read() throws IOException { 50 | if (curPos == endPos) { 51 | return -1; 52 | } 53 | else { 54 | int b = file.read(); 55 | curPos++; 56 | return b; 57 | } 58 | } 59 | 60 | @Override 61 | public int read(byte[] b, int off, int len) throws IOException { 62 | if (len == 0) { 63 | return 0; 64 | } 65 | if (curPos == endPos) { 66 | return -1; 67 | } 68 | int bytesRead = file.read(b, off, 69 | (int)Math.min(len, endPos - curPos)); 70 | curPos += bytesRead; 71 | return bytesRead; 72 | } 73 | 74 | @Override 75 | public int read(byte[] b) throws IOException { 76 | return read(b, 0, b.length); 77 | } 78 | // 79 | // public void close() throws IOException { 80 | // file.close(); 81 | // } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/rarfile/AVHeader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 24.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * 10 | * the unrar licence applies to all junrar source and binary distributions 11 | * you are not allowed to use this source to re-create the RAR compression algorithm 12 | * 13 | * Here some html entities which can be used for escaping javadoc tags: 14 | * "&": "&" or "&" 15 | * "<": "<" or "<" 16 | * ">": ">" or ">" 17 | * "@": "@" 18 | */ 19 | package de.innosystec.unrar.rarfile; 20 | 21 | import de.innosystec.unrar.io.Raw; 22 | 23 | /** 24 | * extended version info header 25 | * 26 | * @author $LastChangedBy$ 27 | * @version $LastChangedRevision$ 28 | */ 29 | public class AVHeader extends BaseBlock { 30 | 31 | public static final int avHeaderSize = 7; 32 | 33 | private byte unpackVersion; 34 | private byte method; 35 | private byte avVersion; 36 | private int avInfoCRC; 37 | 38 | public AVHeader(BaseBlock bb, byte[] avHeader){ 39 | super(bb); 40 | 41 | int pos =0; 42 | unpackVersion |= avHeader[pos]&0xff; 43 | pos++; 44 | method |= avHeader[pos]&0xff; 45 | pos++; 46 | avVersion |= avHeader[pos]&0xff; 47 | pos++; 48 | avInfoCRC = Raw.readIntLittleEndian(avHeader, pos); 49 | } 50 | 51 | public int getAvInfoCRC() { 52 | return avInfoCRC; 53 | } 54 | 55 | public byte getAvVersion() { 56 | return avVersion; 57 | } 58 | 59 | public byte getMethod() { 60 | return method; 61 | } 62 | 63 | public byte getUnpackVersion() { 64 | return unpackVersion; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/rarfile/BaseBlock.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 22.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * 10 | * the unrar licence applies to all junrar source and binary distributions 11 | * you are not allowed to use this source to re-create the RAR compression algorithm 12 | * 13 | * Here some html entities which can be used for escaping javadoc tags: 14 | * "&": "&" or "&" 15 | * "<": "<" or "<" 16 | * ">": ">" or ">" 17 | * "@": "@" 18 | */ 19 | package de.innosystec.unrar.rarfile; 20 | 21 | import org.apache.commons.logging.Log; 22 | import org.apache.commons.logging.LogFactory; 23 | 24 | import de.innosystec.unrar.io.Raw; 25 | 26 | 27 | /** 28 | * Base class of all rar headers 29 | * 30 | * @author $LastChangedBy$ 31 | * @version $LastChangedRevision$ 32 | */ 33 | public class BaseBlock{ 34 | 35 | Log logger = LogFactory.getLog(BaseBlock.class.getName()); 36 | 37 | public static final short BaseBlockSize = 7; 38 | 39 | //TODO move somewhere else 40 | 41 | public static final short MHD_VOLUME = 0x0001; 42 | public static final short MHD_COMMENT = 0x0002; 43 | public static final short MHD_LOCK = 0x0004; 44 | public static final short MHD_SOLID = 0x0008; 45 | public static final short MHD_PACK_COMMENT = 0x0010; 46 | public static final short MHD_NEWNUMBERING = 0x0010; 47 | public static final short MHD_AV = 0x0020; 48 | public static final short MHD_PROTECT = 0x0040; 49 | public static final short MHD_PASSWORD = 0x0080; 50 | public static final short MHD_FIRSTVOLUME = 0x0100; 51 | public static final short MHD_ENCRYPTVER = 0x0200; 52 | 53 | 54 | public static final short LHD_SPLIT_BEFORE = 0x0001; 55 | public static final short LHD_SPLIT_AFTER = 0x0002; 56 | public static final short LHD_PASSWORD = 0x0004; 57 | public static final short LHD_COMMENT = 0x0008; 58 | public static final short LHD_SOLID = 0x0010; 59 | 60 | public static final short LHD_WINDOWMASK = 0x00e0; 61 | public static final short LHD_WINDOW64 = 0x0000; 62 | public static final short LHD_WINDOW128 = 0x0020; 63 | public static final short LHD_WINDOW256 = 0x0040; 64 | public static final short LHD_WINDOW512 = 0x0060; 65 | public static final short LHD_WINDOW1024 = 0x0080; 66 | public static final short LHD_WINDOW2048 = 0x00a0; 67 | public static final short LHD_WINDOW4096 = 0x00c0; 68 | public static final short LHD_DIRECTORY = 0x00e0; 69 | 70 | public static final short LHD_LARGE = 0x0100; 71 | public static final short LHD_UNICODE = 0x0200; 72 | public static final short LHD_SALT = 0x0400; 73 | public static final short LHD_VERSION = 0x0800; 74 | public static final short LHD_EXTTIME = 0x1000; 75 | public static final short LHD_EXTFLAGS = 0x2000; 76 | 77 | public static final short SKIP_IF_UNKNOWN = 0x4000; 78 | public static final short LONG_BLOCK = -0x8000; 79 | 80 | public static final short EARC_NEXT_VOLUME = 0x0001; 81 | public static final short EARC_DATACRC = 0x0002; 82 | public static final short EARC_REVSPACE = 0x0004; 83 | public static final short EARC_VOLNUMBER = 0x0008; 84 | 85 | 86 | protected long positionInFile; 87 | 88 | protected short headCRC = 0; 89 | protected byte headerType = 0; 90 | protected short flags = 0; 91 | protected short headerSize = 0 ; 92 | 93 | /** 94 | * 95 | */ 96 | public BaseBlock(){ 97 | 98 | } 99 | 100 | public BaseBlock(BaseBlock bb){ 101 | this.flags = bb.getFlags(); 102 | this.headCRC = bb.getHeadCRC(); 103 | this.headerType = bb.getHeaderType().getHeaderByte(); 104 | this.headerSize = bb.getHeaderSize(); 105 | this.positionInFile = bb.getPositionInFile(); 106 | } 107 | public BaseBlock(byte[] baseBlockHeader){ 108 | 109 | int pos = 0; 110 | this.headCRC = Raw.readShortLittleEndian(baseBlockHeader, pos); 111 | pos+=2; 112 | this.headerType |= baseBlockHeader[pos]&0xff; 113 | pos++; 114 | this.flags = Raw.readShortLittleEndian(baseBlockHeader, pos); 115 | pos+=2; 116 | this.headerSize = Raw.readShortLittleEndian(baseBlockHeader, pos); 117 | } 118 | 119 | 120 | public boolean hasArchiveDataCRC(){ 121 | return (this.flags & EARC_DATACRC)!=0; 122 | } 123 | 124 | public boolean hasVolumeNumber(){ 125 | return (this.flags & EARC_VOLNUMBER)!=0; 126 | } 127 | 128 | public boolean hasEncryptVersion(){ 129 | return (flags & MHD_ENCRYPTVER)!=0; 130 | } 131 | 132 | /** 133 | * @return is it a sub block 134 | */ 135 | public boolean isSubBlock() 136 | { 137 | if (UnrarHeadertype.SubHeader.equals(headerType)){ 138 | return(true); 139 | } 140 | if (UnrarHeadertype.NewSubHeader.equals(headerType) && (flags & LHD_SOLID)!=0) 141 | { 142 | return(true); 143 | } 144 | return(false); 145 | 146 | } 147 | 148 | public long getPositionInFile() { 149 | return positionInFile; 150 | } 151 | 152 | public short getFlags() { 153 | return flags; 154 | } 155 | 156 | public short getHeadCRC() { 157 | return headCRC; 158 | } 159 | 160 | public short getHeaderSize() { 161 | return headerSize; 162 | } 163 | 164 | public UnrarHeadertype getHeaderType() { 165 | return UnrarHeadertype.findType(headerType); 166 | } 167 | 168 | public void setPositionInFile(long positionInFile) { 169 | this.positionInFile = positionInFile; 170 | } 171 | 172 | public void print(){ 173 | StringBuilder str =new StringBuilder(); 174 | str.append("HeaderType: " + getHeaderType()); 175 | str.append("\nHeadCRC: "+Integer.toHexString(getHeadCRC())); 176 | str.append("\nFlags: "+Integer.toHexString(getFlags())); 177 | str.append("\nHeaderSize: "+getHeaderSize()); 178 | str.append("\nPosition in file: "+getPositionInFile()); 179 | logger.info(str.toString()); 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/rarfile/BlockHeader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 22.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * 10 | * the unrar licence applies to all junrar source and binary distributions 11 | * you are not allowed to use this source to re-create the RAR compression algorithm 12 | * 13 | * Here some html entities which can be used for escaping javadoc tags: 14 | * "&": "&" or "&" 15 | * "<": "<" or "<" 16 | * ">": ">" or ">" 17 | * "@": "@" 18 | */ 19 | package de.innosystec.unrar.rarfile; 20 | 21 | import org.apache.commons.logging.Log; 22 | import org.apache.commons.logging.LogFactory; 23 | 24 | import de.innosystec.unrar.io.Raw; 25 | 26 | /** 27 | * Base class of headers that contain data 28 | * 29 | * @author $LastChangedBy$ 30 | * @version $LastChangedRevision$ 31 | */ 32 | public class BlockHeader extends BaseBlock{ 33 | public static final short blockHeaderSize = 4; 34 | 35 | private Log logger = LogFactory.getLog(BlockHeader.class.getName()); 36 | 37 | private int dataSize; 38 | private int packSize; 39 | 40 | public BlockHeader(){ 41 | 42 | } 43 | 44 | public BlockHeader(BlockHeader bh){ 45 | super(bh); 46 | this.packSize = bh.getDataSize(); 47 | this.dataSize = packSize; 48 | this.positionInFile = bh.getPositionInFile(); 49 | } 50 | 51 | public BlockHeader(BaseBlock bb, byte[] blockHeader) 52 | { 53 | super(bb); 54 | 55 | this.packSize = Raw.readIntLittleEndian(blockHeader, 0); 56 | this.dataSize = this.packSize; 57 | } 58 | 59 | public int getDataSize() { 60 | return dataSize; 61 | } 62 | 63 | public int getPackSize() { 64 | return packSize; 65 | } 66 | 67 | public void print(){ 68 | super.print(); 69 | String s = "DataSize: "+getDataSize()+" packSize: "+getPackSize(); 70 | logger.info(s); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/rarfile/CommentHeader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 23.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * 10 | * the unrar licence applies to all junrar source and binary distributions 11 | * you are not allowed to use this source to re-create the RAR compression algorithm 12 | * 13 | * Here some html entities which can be used for escaping javadoc tags: 14 | * "&": "&" or "&" 15 | * "<": "<" or "<" 16 | * ">": ">" or ">" 17 | * "@": "@" 18 | */ 19 | 20 | package de.innosystec.unrar.rarfile; 21 | 22 | import de.innosystec.unrar.io.Raw; 23 | 24 | /** 25 | * Comment header 26 | * 27 | * @author $LastChangedBy$ 28 | * @version $LastChangedRevision$ 29 | */ 30 | public class CommentHeader extends BaseBlock { 31 | 32 | public static final short commentHeaderSize = 6; 33 | 34 | private short unpSize; 35 | private byte unpVersion; 36 | private byte unpMethod; 37 | private short commCRC; 38 | 39 | 40 | public CommentHeader(BaseBlock bb, byte[] commentHeader){ 41 | super(bb); 42 | 43 | int pos =0; 44 | unpSize = Raw.readShortLittleEndian(commentHeader, pos); 45 | pos += 2; 46 | unpVersion |= commentHeader[pos]&0xff; 47 | pos++; 48 | 49 | unpMethod |= commentHeader[pos]&0xff; 50 | pos++; 51 | commCRC =Raw.readShortLittleEndian(commentHeader, pos); 52 | 53 | } 54 | 55 | public short getCommCRC() { 56 | return commCRC; 57 | } 58 | 59 | public byte getUnpMethod() { 60 | return unpMethod; 61 | } 62 | 63 | public short getUnpSize() { 64 | return unpSize; 65 | } 66 | 67 | public byte getUnpVersion() { 68 | return unpVersion; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/rarfile/EAHeader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 27.11.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * 10 | * the unrar licence applies to all junrar source and binary distributions 11 | * you are not allowed to use this source to re-create the RAR compression algorithm 12 | * 13 | * Here some html entities which can be used for escaping javadoc tags: 14 | * "&": "&" or "&" 15 | * "<": "<" or "<" 16 | * ">": ">" or ">" 17 | * "@": "@" 18 | */ 19 | package de.innosystec.unrar.rarfile; 20 | 21 | import org.apache.commons.logging.Log; 22 | import org.apache.commons.logging.LogFactory; 23 | 24 | import de.innosystec.unrar.io.Raw; 25 | 26 | /** 27 | * extended archive CRC header 28 | * 29 | */ 30 | public class EAHeader 31 | extends SubBlockHeader 32 | { 33 | private Log logger = LogFactory.getLog(getClass()); 34 | 35 | public static final short EAHeaderSize = 10; 36 | 37 | private int unpSize; 38 | private byte unpVer; 39 | private byte method; 40 | private int EACRC; 41 | 42 | public EAHeader(SubBlockHeader sb, byte[] eahead) 43 | { 44 | super(sb); 45 | int pos = 0; 46 | unpSize = Raw.readIntLittleEndian(eahead, pos); 47 | pos+=4; 48 | unpVer |= eahead[pos]&0xff; 49 | pos++; 50 | method |= eahead[pos]&0xff; 51 | pos++; 52 | EACRC = Raw.readIntLittleEndian(eahead, pos); 53 | } 54 | 55 | /** 56 | * @return the eACRC 57 | */ 58 | public int getEACRC() { 59 | return EACRC; 60 | } 61 | 62 | /** 63 | * @return the method 64 | */ 65 | public byte getMethod() { 66 | return method; 67 | } 68 | 69 | /** 70 | * @return the unpSize 71 | */ 72 | public int getUnpSize() { 73 | return unpSize; 74 | } 75 | 76 | /** 77 | * @return the unpVer 78 | */ 79 | public byte getUnpVer() { 80 | return unpVer; 81 | } 82 | 83 | public void print() 84 | { 85 | super.print(); 86 | logger.info("unpSize: "+unpSize); 87 | logger.info("unpVersion: " + unpVer); 88 | logger.info("method: "+method); 89 | logger.info("EACRC:" + EACRC); 90 | } 91 | } 92 | 93 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/rarfile/EndArcHeader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 24.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * 10 | * the unrar licence applies to all junrar source and binary distributions 11 | * you are not allowed to use this source to re-create the RAR compression algorithm 12 | * 13 | * Here some html entities which can be used for escaping javadoc tags: 14 | * "&": "&" or "&" 15 | * "<": "<" or "<" 16 | * ">": ">" or ">" 17 | * "@": "@" 18 | */ 19 | package de.innosystec.unrar.rarfile; 20 | 21 | import de.innosystec.unrar.io.Raw; 22 | 23 | /** 24 | * 25 | * the optional End header 26 | * 27 | */ 28 | public class EndArcHeader extends BaseBlock{ 29 | 30 | private static final short EARC_NEXT_VOLUME = 0x0001; 31 | private static final short EARC_DATACRC = 0x0002; 32 | private static final short EARC_REVSPACE = 0x0004; 33 | private static final short EARC_VOLNUMBER = 0x0008; 34 | 35 | private static final short endArcHeaderSize = 6; 36 | public static final short endArcArchiveDataCrcSize = 4; 37 | public static final short endArcVolumeNumberSize = 2; 38 | 39 | private int archiveDataCRC; 40 | private short volumeNumber; 41 | 42 | 43 | public EndArcHeader(BaseBlock bb, byte[] endArcHeader){ 44 | super(bb); 45 | 46 | int pos = 0; 47 | if(hasArchiveDataCRC()){ 48 | archiveDataCRC =Raw.readIntLittleEndian(endArcHeader, pos); 49 | pos+=4; 50 | } 51 | if(hasVolumeNumber()){ 52 | volumeNumber = Raw.readShortLittleEndian(endArcHeader, pos); 53 | } 54 | } 55 | 56 | public int getArchiveDataCRC() { 57 | return archiveDataCRC; 58 | } 59 | 60 | public short getVolumeNumber() { 61 | return volumeNumber; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/rarfile/FileHeader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 22.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * 10 | * the unrar licence applies to all junrar source and binary distributions 11 | * you are not allowed to use this source to re-create the RAR compression algorithm 12 | * 13 | * Here some html entities which can be used for escaping javadoc tags: 14 | * "&": "&" or "&" 15 | * "<": "<" or "<" 16 | * ">": ">" or ">" 17 | * "@": "@" 18 | */ 19 | package de.innosystec.unrar.rarfile; 20 | 21 | import java.util.Calendar; 22 | import java.util.Date; 23 | 24 | import org.apache.commons.logging.Log; 25 | import org.apache.commons.logging.LogFactory; 26 | 27 | import de.innosystec.unrar.io.Raw; 28 | 29 | /** 30 | * DOCUMENT ME 31 | * 32 | * @author $LastChangedBy$ 33 | * @version $LastChangedRevision$ 34 | */ 35 | public class FileHeader extends BlockHeader { 36 | 37 | private final Log logger = LogFactory.getLog(FileHeader.class.getName()); 38 | 39 | private static final byte SALT_SIZE = 8; 40 | 41 | private static final byte NEWLHD_SIZE = 32; 42 | 43 | private long unpSize; 44 | 45 | private final HostSystem hostOS; 46 | 47 | private final int fileCRC; 48 | 49 | private final int fileTime; 50 | 51 | private byte unpVersion; 52 | 53 | private byte unpMethod; 54 | 55 | private short nameSize; 56 | 57 | private int highPackSize; 58 | 59 | private int highUnpackSize; 60 | 61 | private final byte[] fileNameBytes; 62 | 63 | private String fileName; 64 | private String fileNameW; 65 | 66 | private byte[] subData; 67 | 68 | private final byte[] salt = new byte[SALT_SIZE]; 69 | 70 | private Date mTime; 71 | 72 | private Date cTime; 73 | 74 | private Date aTime; 75 | 76 | private Date arcTime; 77 | 78 | private long fullPackSize; 79 | 80 | private long fullUnpackSize; 81 | 82 | private int fileAttr; 83 | 84 | private int subFlags; // same as fileAttr (in header) 85 | 86 | private int recoverySectors = -1; 87 | 88 | public FileHeader(BlockHeader bh, byte[] fileHeader) { 89 | super(bh); 90 | 91 | int position = 0; 92 | unpSize = Raw.readIntLittleEndian(fileHeader, position); 93 | position += 4; 94 | hostOS = HostSystem.findHostSystem(fileHeader[4]); 95 | position++; 96 | 97 | fileCRC = Raw.readIntLittleEndian(fileHeader, position); 98 | position += 4; 99 | 100 | fileTime = Raw.readIntLittleEndian(fileHeader, position); 101 | position += 4; 102 | 103 | unpVersion |= fileHeader[13] & 0xff; 104 | position++; 105 | unpMethod |= fileHeader[14] & 0xff; 106 | position++; 107 | nameSize = Raw.readShortLittleEndian(fileHeader, position); 108 | position += 2; 109 | 110 | fileAttr = Raw.readIntLittleEndian(fileHeader, position); 111 | position += 4; 112 | if (isLargeBlock()) { 113 | highPackSize = Raw.readIntLittleEndian(fileHeader, position); 114 | position += 4; 115 | 116 | highUnpackSize = Raw.readIntLittleEndian(fileHeader, position); 117 | position += 4; 118 | } else { 119 | highPackSize = 0; 120 | highUnpackSize = 0; 121 | if (unpSize == 0xffffffff) { 122 | 123 | unpSize = 0xffffffff; 124 | highUnpackSize = Integer.MAX_VALUE; 125 | } 126 | 127 | } 128 | fullPackSize |= highPackSize; 129 | fullPackSize <<= 32; 130 | fullPackSize |= getPackSize(); 131 | 132 | fullUnpackSize |= highUnpackSize; 133 | fullUnpackSize <<= 32; 134 | fullUnpackSize += unpSize; 135 | 136 | nameSize = nameSize > 4 * 1024 ? 4 * 1024 : nameSize; 137 | 138 | fileNameBytes = new byte[nameSize]; 139 | for (int i = 0; i < nameSize; i++) { 140 | fileNameBytes[i] = fileHeader[position]; 141 | position++; 142 | } 143 | 144 | if (isFileHeader()) { 145 | if (isUnicode()) { 146 | int length = 0; 147 | fileName = ""; 148 | fileNameW = ""; 149 | while (length < fileNameBytes.length 150 | && fileNameBytes[length] != 0) { 151 | length++; 152 | } 153 | byte[] name = new byte[length]; 154 | System.arraycopy(fileNameBytes, 0, name, 0, name.length); 155 | fileName = new String(name); 156 | if (length != nameSize) { 157 | length++; 158 | fileNameW = FileNameDecoder.decode(fileNameBytes, length); 159 | } 160 | } else { 161 | fileName = new String(fileNameBytes); 162 | fileNameW = ""; 163 | } 164 | } 165 | 166 | if (UnrarHeadertype.NewSubHeader.equals(headerType)) { 167 | int datasize = headerSize - NEWLHD_SIZE - nameSize; 168 | if (hasSalt()) { 169 | datasize -= SALT_SIZE; 170 | } 171 | if (datasize > 0) { 172 | subData = new byte[datasize]; 173 | for (int i = 0; i < datasize; i++) { 174 | subData[i] = (fileHeader[position]); 175 | position++; 176 | } 177 | } 178 | 179 | if (NewSubHeaderType.SUBHEAD_TYPE_RR.byteEquals(fileNameBytes)) { 180 | recoverySectors = subData[8] + (subData[9] << 8) 181 | + (subData[10] << 16) + (subData[11] << 24); 182 | } 183 | } 184 | 185 | if (hasSalt()) { 186 | for (int i = 0; i < SALT_SIZE; i++) { 187 | salt[i] = fileHeader[position]; 188 | position++; 189 | } 190 | } 191 | mTime = getDateDos(fileTime); 192 | // TODO rartime -> extended 193 | 194 | } 195 | 196 | @Override 197 | public void print() { 198 | super.print(); 199 | StringBuilder str = new StringBuilder(); 200 | str.append("unpSize: " + getUnpSize()); 201 | str.append("\nHostOS: " + hostOS.name()); 202 | str.append("\nMDate: " + mTime); 203 | str.append("\nFileName: " + getFileNameString()); 204 | str.append("\nunpMethod: " + Integer.toHexString(getUnpMethod())); 205 | str.append("\nunpVersion: " + Integer.toHexString(getUnpVersion())); 206 | str.append("\nfullpackedsize: " + getFullPackSize()); 207 | str.append("\nfullunpackedsize: " + getFullUnpackSize()); 208 | str.append("\nisEncrypted: " + isEncrypted()); 209 | str.append("\nisfileHeader: " + isFileHeader()); 210 | str.append("\nisSolid: " + isSolid()); 211 | str.append("\nisSplitafter: " + isSplitAfter()); 212 | str.append("\nisSplitBefore:" + isSplitBefore()); 213 | str.append("\nunpSize: " + getUnpSize()); 214 | str.append("\ndataSize: " + getDataSize()); 215 | str.append("\nisUnicode: " + isUnicode()); 216 | str.append("\nhasVolumeNumber: " + hasVolumeNumber()); 217 | str.append("\nhasArchiveDataCRC: " + hasArchiveDataCRC()); 218 | str.append("\nhasSalt: " + hasSalt()); 219 | str.append("\nhasEncryptVersions: " + hasEncryptVersion()); 220 | str.append("\nisSubBlock: " + isSubBlock()); 221 | logger.info(str.toString()); 222 | } 223 | 224 | private Date getDateDos(int time) { 225 | Calendar cal = Calendar.getInstance(); 226 | cal.set(Calendar.YEAR, (time >>> 25) + 1980); 227 | cal.set(Calendar.MONTH, ((time >>> 21) & 0x0f) - 1); 228 | cal.set(Calendar.DAY_OF_MONTH, (time >>> 16) & 0x1f); 229 | cal.set(Calendar.HOUR_OF_DAY, (time >>> 11) & 0x1f); 230 | cal.set(Calendar.MINUTE, (time >>> 5) & 0x3f); 231 | cal.set(Calendar.SECOND, (time & 0x1f) * 2); 232 | return cal.getTime(); 233 | } 234 | 235 | public Date getArcTime() { 236 | return arcTime; 237 | } 238 | 239 | public void setArcTime(Date arcTime) { 240 | this.arcTime = arcTime; 241 | } 242 | 243 | public Date getATime() { 244 | return aTime; 245 | } 246 | 247 | public void setATime(Date time) { 248 | aTime = time; 249 | } 250 | 251 | public Date getCTime() { 252 | return cTime; 253 | } 254 | 255 | public void setCTime(Date time) { 256 | cTime = time; 257 | } 258 | 259 | public int getFileAttr() { 260 | return fileAttr; 261 | } 262 | 263 | public void setFileAttr(int fileAttr) { 264 | this.fileAttr = fileAttr; 265 | } 266 | 267 | public int getFileCRC() { 268 | return fileCRC; 269 | } 270 | 271 | public byte[] getFileNameByteArray() { 272 | return fileNameBytes; 273 | } 274 | 275 | public String getFileNameString() { 276 | return fileName; 277 | } 278 | 279 | public void setFileName(String fileName) { 280 | this.fileName = fileName; 281 | } 282 | 283 | public String getFileNameW() { 284 | return fileNameW; 285 | } 286 | 287 | public void setFileNameW(String fileNameW) { 288 | this.fileNameW = fileNameW; 289 | } 290 | 291 | public int getHighPackSize() { 292 | return highPackSize; 293 | } 294 | 295 | public int getHighUnpackSize() { 296 | return highUnpackSize; 297 | } 298 | 299 | public HostSystem getHostOS() { 300 | return hostOS; 301 | } 302 | 303 | public Date getMTime() { 304 | return mTime; 305 | } 306 | 307 | public void setMTime(Date time) { 308 | mTime = time; 309 | } 310 | 311 | public short getNameSize() { 312 | return nameSize; 313 | } 314 | 315 | public int getRecoverySectors() { 316 | return recoverySectors; 317 | } 318 | 319 | public byte[] getSalt() { 320 | return salt; 321 | } 322 | 323 | public byte[] getSubData() { 324 | return subData; 325 | } 326 | 327 | public int getSubFlags() { 328 | return subFlags; 329 | } 330 | 331 | public byte getUnpMethod() { 332 | return unpMethod; 333 | } 334 | 335 | public long getUnpSize() { 336 | return unpSize; 337 | } 338 | 339 | public byte getUnpVersion() { 340 | return unpVersion; 341 | } 342 | 343 | public long getFullPackSize() { 344 | return fullPackSize; 345 | } 346 | 347 | public long getFullUnpackSize() { 348 | return fullUnpackSize; 349 | } 350 | 351 | @Override 352 | public String toString() { 353 | return super.toString(); 354 | } 355 | 356 | /** 357 | * the file will be continued in the next archive part 358 | * 359 | * @return 360 | */ 361 | public boolean isSplitAfter() { 362 | return (this.flags & BlockHeader.LHD_SPLIT_AFTER) != 0; 363 | } 364 | 365 | /** 366 | * the file is continued in this archive 367 | * 368 | * @return 369 | */ 370 | public boolean isSplitBefore() { 371 | return (this.flags & LHD_SPLIT_BEFORE) != 0; 372 | } 373 | 374 | /** 375 | * this file is compressed as solid (all files handeled as one) 376 | * 377 | * @return 378 | */ 379 | public boolean isSolid() { 380 | return (this.flags & LHD_SOLID) != 0; 381 | } 382 | 383 | /** 384 | * the file is encrypted 385 | * 386 | * @return 387 | */ 388 | public boolean isEncrypted() { 389 | return (this.flags & BlockHeader.LHD_PASSWORD) != 0; 390 | } 391 | 392 | /** 393 | * the filename is also present in unicode 394 | * 395 | * @return 396 | */ 397 | public boolean isUnicode() { 398 | return (flags & LHD_UNICODE) != 0; 399 | } 400 | 401 | public boolean isFileHeader() { 402 | return UnrarHeadertype.FileHeader.equals(headerType); 403 | } 404 | 405 | public boolean hasSalt() { 406 | return (flags & LHD_SALT) != 0; 407 | } 408 | 409 | public boolean isLargeBlock() { 410 | return (flags & LHD_LARGE) != 0; 411 | } 412 | 413 | /** 414 | * whether this fileheader represents a directory 415 | * 416 | * @return 417 | */ 418 | public boolean isDirectory() { 419 | return (flags & LHD_WINDOWMASK) == LHD_DIRECTORY; 420 | } 421 | } 422 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/rarfile/FileNameDecoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Original author: alpha_lam 4 | * Creation date: ? 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * 10 | * the unrar licence applies to all junrar source and binary distributions 11 | * you are not allowed to use this source to re-create the RAR compression algorithm 12 | * 13 | * Here some html entities which can be used for escaping javadoc tags: 14 | * "&": "&" or "&" 15 | * "<": "<" or "<" 16 | * ">": ">" or ">" 17 | * "@": "@" 18 | */ 19 | package de.innosystec.unrar.rarfile; 20 | 21 | public class FileNameDecoder { 22 | public static int getChar(byte [] name,int pos){ 23 | return name[pos]&0xff; 24 | } 25 | 26 | public static String decode(byte [] name,int encPos){ 27 | int decPos = 0; 28 | int flags = 0; 29 | int flagBits = 0; 30 | 31 | int low = 0; 32 | int high = 0; 33 | int highByte = getChar(name,encPos++); 34 | StringBuffer buf = new StringBuffer(); 35 | while(encPos < name.length){ 36 | if(flagBits == 0){ 37 | flags = getChar(name,encPos++); 38 | flagBits = 8; 39 | } 40 | switch(flags >> 6){ 41 | case 0: 42 | buf.append((char)(getChar(name,encPos++))); 43 | ++decPos; 44 | break; 45 | case 1: 46 | buf.append((char)(getChar(name,encPos++)+(highByte<<8))); 47 | ++decPos; 48 | break; 49 | case 2: 50 | low = getChar(name,encPos); 51 | high = getChar(name,encPos+1); 52 | buf.append((char)((high << 8) + low)); 53 | ++decPos; 54 | encPos += 2; 55 | break; 56 | case 3: 57 | int length = getChar(name,encPos++); 58 | if((length&0x80)!=0){ 59 | int correction = getChar(name,encPos++); 60 | for(length=(length&0x7f)+2;length>0&&decPos0&&decPos": ">" or ">" 17 | * "@": "@" 18 | */ 19 | package de.innosystec.unrar.rarfile; 20 | 21 | /** 22 | * DOCUMENT ME 23 | * 24 | * @author $LastChangedBy$ 25 | * @version $LastChangedRevision$ 26 | */ 27 | public enum HostSystem { 28 | msdos ((byte)0), 29 | os2 ((byte)1), 30 | win32 ((byte)2), 31 | unix ((byte)3), 32 | macos ((byte)4), 33 | beos ((byte)5); 34 | 35 | private byte hostByte; 36 | 37 | public static HostSystem findHostSystem(byte hostByte){ 38 | if(HostSystem.msdos.equals(hostByte)){ 39 | return HostSystem.msdos; 40 | } 41 | if(HostSystem.os2.equals(hostByte)){ 42 | return HostSystem.os2; 43 | } 44 | if(HostSystem.win32.equals(hostByte)){ 45 | return HostSystem.win32; 46 | } 47 | if(HostSystem.unix.equals(hostByte)){ 48 | return HostSystem.unix; 49 | } 50 | if(HostSystem.macos.equals(hostByte)){ 51 | return HostSystem.macos; 52 | } 53 | if(HostSystem.beos.equals(hostByte)){ 54 | return HostSystem.beos; 55 | } 56 | return null; 57 | } 58 | 59 | 60 | private HostSystem(byte hostByte){ 61 | this.hostByte = hostByte; 62 | } 63 | 64 | public boolean equals(byte hostByte){ 65 | return this.hostByte == hostByte; 66 | } 67 | 68 | public byte getHostByte(){ 69 | return hostByte; 70 | } 71 | //???? public static final byte max = 6; 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/rarfile/MacInfoHeader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 26.11.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * 10 | * the unrar licence applies to all junrar source and binary distributions 11 | * you are not allowed to use this source to re-create the RAR compression algorithm 12 | * 13 | * Here some html entities which can be used for escaping javadoc tags: 14 | * "&": "&" or "&" 15 | * "<": "<" or "<" 16 | * ">": ">" or ">" 17 | * "@": "@" 18 | */ 19 | package de.innosystec.unrar.rarfile; 20 | 21 | import org.apache.commons.logging.Log; 22 | import org.apache.commons.logging.LogFactory; 23 | 24 | import de.innosystec.unrar.io.Raw; 25 | 26 | /** 27 | * Mac File attribute header 28 | * 29 | */ 30 | public class MacInfoHeader 31 | extends SubBlockHeader 32 | { 33 | private Log logger = LogFactory.getLog(getClass()); 34 | 35 | public static final short MacInfoHeaderSize = 8; 36 | 37 | private int fileType; 38 | private int fileCreator; 39 | 40 | public MacInfoHeader(SubBlockHeader sb, byte[] macHeader) 41 | { 42 | super(sb); 43 | int pos = 0; 44 | fileType = Raw.readIntLittleEndian(macHeader, pos); 45 | pos+=4; 46 | fileCreator = Raw.readIntLittleEndian(macHeader, pos); 47 | } 48 | 49 | /** 50 | * @return the fileCreator 51 | */ 52 | public int getFileCreator() { 53 | return fileCreator; 54 | } 55 | 56 | /** 57 | * @param fileCreator the fileCreator to set 58 | */ 59 | public void setFileCreator(int fileCreator) { 60 | this.fileCreator = fileCreator; 61 | } 62 | 63 | /** 64 | * @return the fileType 65 | */ 66 | public int getFileType() { 67 | return fileType; 68 | } 69 | 70 | /** 71 | * @param fileType the fileType to set 72 | */ 73 | public void setFileType(int fileType) { 74 | this.fileType = fileType; 75 | } 76 | 77 | public void print(){ 78 | super.print(); 79 | logger.info("filetype: "+fileType); 80 | logger.info("creator :"+fileCreator); 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/rarfile/MainHeader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 22.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * 10 | * the unrar licence applies to all junrar source and binary distributions 11 | * you are not allowed to use this source to re-create the RAR compression algorithm 12 | * 13 | * Here some html entities which can be used for escaping javadoc tags: 14 | * "&": "&" or "&" 15 | * "<": "<" or "<" 16 | * ">": ">" or ">" 17 | * "@": "@" 18 | */ 19 | package de.innosystec.unrar.rarfile; 20 | 21 | import org.apache.commons.logging.Log; 22 | import org.apache.commons.logging.LogFactory; 23 | 24 | import de.innosystec.unrar.io.Raw; 25 | 26 | /** 27 | * The main header of an rar archive. holds information concerning the whole archive (solid, encrypted etc). 28 | * 29 | * @author $LastChangedBy$ 30 | * @version $LastChangedRevision$ 31 | */ 32 | public class MainHeader extends BaseBlock { 33 | private Log logger = LogFactory.getLog(MainHeader.class.getName()); 34 | public static final short mainHeaderSizeWithEnc = 7; 35 | public static final short mainHeaderSize = 6; 36 | private short highPosAv; 37 | private int posAv; 38 | private byte encryptVersion; 39 | 40 | public MainHeader(BaseBlock bb, byte[] mainHeader) { 41 | super(bb); 42 | int pos = 0; 43 | highPosAv = Raw.readShortLittleEndian(mainHeader, pos); 44 | pos += 2; 45 | posAv = Raw.readIntLittleEndian(mainHeader, pos); 46 | pos+=4; 47 | 48 | if(hasEncryptVersion()){ 49 | encryptVersion |= mainHeader[pos]&0xff; 50 | } 51 | } 52 | 53 | /** 54 | * old cmt block is present 55 | * @return true if has cmt block 56 | */ 57 | public boolean hasArchCmt(){ 58 | return (this.flags & BaseBlock.MHD_COMMENT)!=0; 59 | } 60 | /** 61 | * the version the the encryption 62 | * @return 63 | */ 64 | public byte getEncryptVersion() { 65 | return encryptVersion; 66 | } 67 | 68 | public short getHighPosAv() { 69 | return highPosAv; 70 | } 71 | 72 | public int getPosAv() { 73 | return posAv; 74 | } 75 | 76 | /** 77 | * returns whether the archive is encrypted 78 | * @return 79 | */ 80 | public boolean isEncrypted(){ 81 | return (this.flags & BaseBlock.MHD_PASSWORD)!=0; 82 | } 83 | 84 | /** 85 | * return whether the archive is a multivolume archive 86 | * @return 87 | */ 88 | public boolean isMultiVolume(){ 89 | return (this.flags & BaseBlock.MHD_VOLUME)!=0; 90 | } 91 | 92 | /** 93 | * if the archive is a multivolume archive this method returns whether this instance is the first part of the multivolume archive 94 | * @return 95 | */ 96 | public boolean isFirstVolume(){ 97 | return (this.flags & BaseBlock.MHD_FIRSTVOLUME)!=0; 98 | } 99 | 100 | public void print(){ 101 | super.print(); 102 | StringBuilder str=new StringBuilder(); 103 | str.append("posav: "+getPosAv()); 104 | str.append("\nhighposav: "+getHighPosAv()); 105 | str.append("\nhasencversion: "+hasEncryptVersion()+(hasEncryptVersion()?getEncryptVersion():"")); 106 | str.append("\nhasarchcmt: "+hasArchCmt()); 107 | str.append("\nisEncrypted: "+isEncrypted()); 108 | str.append("\nisMultivolume: "+isMultiVolume()); 109 | str.append("\nisFirstvolume: "+isFirstVolume()); 110 | str.append("\nisSolid: "+isSolid()); 111 | str.append("\nisLocked: "+isLocked()); 112 | str.append("\nisProtected: "+isProtected()); 113 | str.append("\nisAV: "+isAV()); 114 | logger.info(str.toString()); 115 | } 116 | 117 | /** 118 | * returns whether this archive is solid. in this case you can only extract all file at once 119 | * @return 120 | */ 121 | public boolean isSolid(){ 122 | return (this.flags&MHD_SOLID)!=0; 123 | } 124 | 125 | public boolean isLocked(){ 126 | return (this.flags&MHD_LOCK)!=0; 127 | } 128 | 129 | public boolean isProtected(){ 130 | return (this.flags&MHD_PROTECT)!=0; 131 | } 132 | 133 | public boolean isAV(){ 134 | return (this.flags&MHD_AV)!=0; 135 | } 136 | /** 137 | * the numbering format a multivolume archive 138 | * @return 139 | */ 140 | public boolean isNewNumbering(){ 141 | return (this.flags&MHD_NEWNUMBERING)!=0; 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/rarfile/MarkHeader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 24.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * 10 | * the unrar licence applies to all junrar source and binary distributions 11 | * you are not allowed to use this source to re-create the RAR compression algorithm 12 | * 13 | * Here some html entities which can be used for escaping javadoc tags: 14 | * "&": "&" or "&" 15 | * "<": "<" or "<" 16 | * ">": ">" or ">" 17 | * "@": "@" 18 | */ 19 | package de.innosystec.unrar.rarfile; 20 | 21 | import org.apache.commons.logging.Log; 22 | import org.apache.commons.logging.LogFactory; 23 | 24 | import de.innosystec.unrar.io.Raw; 25 | 26 | /** 27 | * the header to recognize a file to be a rar archive 28 | * 29 | * @author $LastChangedBy$ 30 | * @version $LastChangedRevision$ 31 | */ 32 | public class MarkHeader extends BaseBlock { 33 | 34 | private Log logger = LogFactory.getLog(MarkHeader.class.getName()); 35 | private boolean oldFormat = false; 36 | 37 | public MarkHeader(BaseBlock bb){ 38 | super(bb); 39 | } 40 | public boolean isValid(){ 41 | if(!(getHeadCRC() == 0x6152)){ 42 | return false; 43 | } 44 | if(!(getHeaderType() == UnrarHeadertype.MarkHeader)){ 45 | return false; 46 | } 47 | if(!(getFlags() == 0x1a21)){ 48 | return false; 49 | } 50 | if(!(getHeaderSize() == BaseBlockSize)){ 51 | return false; 52 | } 53 | return true; 54 | } 55 | 56 | public boolean isSignature() { 57 | boolean valid=false; 58 | byte[] d = new byte[BaseBlock.BaseBlockSize]; 59 | Raw.writeShortLittleEndian(d, 0, headCRC); 60 | d[2] = headerType; 61 | Raw.writeShortLittleEndian(d, 3, flags); 62 | Raw.writeShortLittleEndian(d, 5, headerSize); 63 | 64 | if (d[0] == 0x52) { 65 | if (d[1]==0x45 && d[2]==0x7e && d[3]==0x5e) { 66 | oldFormat=true; 67 | valid=true; 68 | } 69 | else if (d[1]==0x61 && d[2]==0x72 && d[3]==0x21 && d[4]==0x1a && 70 | d[5]==0x07 && d[6]==0x00) { 71 | oldFormat=false; 72 | valid=true; 73 | } 74 | } 75 | return valid; 76 | } 77 | 78 | public boolean isOldFormat() { 79 | return oldFormat; 80 | } 81 | 82 | public void print(){ 83 | super.print(); 84 | logger.info("valid: "+isValid()); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/rarfile/NewSubHeaderType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 24.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * 10 | * the unrar licence applies to all junrar source and binary distributions 11 | * you are not allowed to use this source to re-create the RAR compression algorithm 12 | * 13 | * Here some html entities which can be used for escaping javadoc tags: 14 | * "&": "&" or "&" 15 | * "<": "<" or "<" 16 | * ">": ">" or ">" 17 | * "@": "@" 18 | */ 19 | package de.innosystec.unrar.rarfile; 20 | 21 | import java.util.Arrays; 22 | 23 | /** 24 | * subheaders new version of the info headers 25 | * 26 | * @author $LastChangedBy$ 27 | * @version $LastChangedRevision$ 28 | */ 29 | public class NewSubHeaderType { 30 | 31 | /** 32 | * comment subheader 33 | */ 34 | public static final NewSubHeaderType SUBHEAD_TYPE_CMT = new NewSubHeaderType(new byte[]{'C','M','T'}); 35 | /** 36 | * 37 | */ 38 | public static final NewSubHeaderType SUBHEAD_TYPE_ACL = new NewSubHeaderType(new byte[]{'A','C','L'}); 39 | /** 40 | * 41 | */ 42 | public static final NewSubHeaderType SUBHEAD_TYPE_STREAM = new NewSubHeaderType(new byte[]{'S','T','M'}); 43 | /** 44 | * 45 | */ 46 | public static final NewSubHeaderType SUBHEAD_TYPE_UOWNER = new NewSubHeaderType(new byte[]{'U','O','W'}); 47 | /** 48 | * 49 | */ 50 | public static final NewSubHeaderType SUBHEAD_TYPE_AV = new NewSubHeaderType(new byte[]{'A','V'}); 51 | /** 52 | * recovery record subheader 53 | */ 54 | public static final NewSubHeaderType SUBHEAD_TYPE_RR = new NewSubHeaderType(new byte[]{'R','R'}); 55 | /** 56 | * 57 | */ 58 | public static final NewSubHeaderType SUBHEAD_TYPE_OS2EA = new NewSubHeaderType(new byte[]{'E','A','2'}); 59 | /** 60 | * 61 | */ 62 | public static final NewSubHeaderType SUBHEAD_TYPE_BEOSEA = new NewSubHeaderType(new byte[]{'E','A','B','E'}); 63 | 64 | private byte[] headerTypes; 65 | 66 | /** 67 | * Private constructor 68 | * @param headerTypes 69 | */ 70 | private NewSubHeaderType(byte[] headerTypes) 71 | { 72 | this.headerTypes = headerTypes; 73 | } 74 | 75 | /** 76 | * @param toCompare 77 | * @return Returns true if the given byte array matches to the internal byte array of this header. 78 | */ 79 | public boolean byteEquals(byte[] toCompare) 80 | { 81 | return Arrays.equals(this.headerTypes, toCompare); 82 | } 83 | 84 | @Override 85 | public String toString() 86 | { 87 | return new String(this.headerTypes); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/rarfile/ProtectHeader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 24.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * 10 | * the unrar licence applies to all junrar source and binary distributions 11 | * you are not allowed to use this source to re-create the RAR compression algorithm 12 | * 13 | * Here some html entities which can be used for escaping javadoc tags: 14 | * "&": "&" or "&" 15 | * "<": "<" or "<" 16 | * ">": ">" or ">" 17 | * "@": "@" 18 | */ 19 | package de.innosystec.unrar.rarfile; 20 | 21 | import de.innosystec.unrar.io.Raw; 22 | 23 | /** 24 | * recovery header 25 | * 26 | * @author $LastChangedBy$ 27 | * @version $LastChangedRevision$ 28 | */ 29 | public class ProtectHeader extends BlockHeader { 30 | 31 | /** 32 | * the header size 33 | */ 34 | public static final int protectHeaderSize = 8; 35 | 36 | private byte version; 37 | private short recSectors; 38 | private int totalBlocks; 39 | private byte mark; 40 | 41 | 42 | public ProtectHeader(BlockHeader bh, byte[] protectHeader){ 43 | super(bh); 44 | 45 | int pos = 0; 46 | version |= protectHeader[pos]&0xff; 47 | 48 | recSectors = Raw.readShortLittleEndian(protectHeader, pos); 49 | pos += 2; 50 | totalBlocks = Raw.readIntLittleEndian(protectHeader, pos); 51 | pos += 4; 52 | mark |= protectHeader[pos]&0xff; 53 | } 54 | 55 | 56 | public byte getMark() { 57 | return mark; 58 | } 59 | 60 | public short getRecSectors() { 61 | return recSectors; 62 | } 63 | 64 | public int getTotalBlocks() { 65 | return totalBlocks; 66 | } 67 | 68 | public byte getVersion() { 69 | return version; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/rarfile/SignHeader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 24.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * 10 | * the unrar licence applies to all junrar source and binary distributions 11 | * you are not allowed to use this source to re-create the RAR compression algorithm 12 | * 13 | * Here some html entities which can be used for escaping javadoc tags: 14 | * "&": "&" or "&" 15 | * "<": "<" or "<" 16 | * ">": ">" or ">" 17 | * "@": "@" 18 | */ 19 | package de.innosystec.unrar.rarfile; 20 | 21 | import de.innosystec.unrar.io.Raw; 22 | 23 | /** 24 | * sign header 25 | * 26 | * @author $LastChangedBy$ 27 | * @version $LastChangedRevision$ 28 | */ 29 | public class SignHeader extends BaseBlock { 30 | 31 | public static final short signHeaderSize = 8; 32 | 33 | private int creationTime=0; 34 | private short arcNameSize=0; 35 | private short userNameSize=0; 36 | 37 | 38 | public SignHeader(BaseBlock bb, byte[] signHeader){ 39 | super(bb); 40 | 41 | int pos = 0; 42 | creationTime = Raw.readIntLittleEndian(signHeader, pos); 43 | pos +=4; 44 | arcNameSize = Raw.readShortLittleEndian(signHeader, pos); 45 | pos+=2; 46 | userNameSize = Raw.readShortLittleEndian(signHeader, pos); 47 | } 48 | 49 | public short getArcNameSize() { 50 | return arcNameSize; 51 | } 52 | 53 | public int getCreationTime() { 54 | return creationTime; 55 | } 56 | 57 | public short getUserNameSize() { 58 | return userNameSize; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/rarfile/SubBlockHeader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 21.11.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * 10 | * the unrar licence applies to all junrar source and binary distributions 11 | * you are not allowed to use this source to re-create the RAR compression algorithm 12 | * 13 | * Here some html entities which can be used for escaping javadoc tags: 14 | * "&": "&" or "&" 15 | * "<": "<" or "<" 16 | * ">": ">" or ">" 17 | * "@": "@" 18 | */ 19 | package de.innosystec.unrar.rarfile; 20 | 21 | import org.apache.commons.logging.Log; 22 | import org.apache.commons.logging.LogFactory; 23 | 24 | import de.innosystec.unrar.io.Raw; 25 | 26 | public class SubBlockHeader 27 | extends BlockHeader 28 | { 29 | private Log logger = LogFactory.getLog(getClass()); 30 | 31 | public static final short SubBlockHeaderSize = 3; 32 | 33 | private short subType; 34 | private byte level; 35 | 36 | public SubBlockHeader(SubBlockHeader sb) 37 | { 38 | super(sb); 39 | subType = sb.getSubType().getSubblocktype(); 40 | level = sb.getLevel(); 41 | } 42 | 43 | public SubBlockHeader(BlockHeader bh, byte[] subblock) 44 | { 45 | super(bh); 46 | int position = 0; 47 | subType = Raw.readShortLittleEndian(subblock, position); 48 | position +=2; 49 | level |= subblock[position]&0xff; 50 | } 51 | 52 | /** 53 | * @return 54 | */ 55 | public byte getLevel() { 56 | return level; 57 | } 58 | 59 | /** 60 | * @return 61 | */ 62 | public SubBlockHeaderType getSubType() { 63 | return SubBlockHeaderType.findSubblockHeaderType(subType); 64 | } 65 | 66 | public void print() 67 | { 68 | super.print(); 69 | logger.info("subtype: "+getSubType()); 70 | logger.info("level: "+level); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/rarfile/SubBlockHeaderType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 20.11.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * 10 | * the unrar licence applies to all junrar source and binary distributions 11 | * you are not allowed to use this source to re-create the RAR compression algorithm 12 | * 13 | * Here some html entities which can be used for escaping javadoc tags: 14 | * "&": "&" or "&" 15 | * "<": "<" or "<" 16 | * ">": ">" or ">" 17 | * "@": "@" 18 | */ 19 | 20 | package de.innosystec.unrar.rarfile; 21 | 22 | public enum SubBlockHeaderType 23 | { 24 | EA_HEAD ((short)0x100), 25 | UO_HEAD ((short)0x101), 26 | MAC_HEAD ((short)0x102), 27 | BEEA_HEAD ((short)0x103), 28 | NTACL_HEAD ((short)0x104), 29 | STREAM_HEAD ((short)0x105); 30 | 31 | private short subblocktype; 32 | 33 | private SubBlockHeaderType(short subblocktype) 34 | { 35 | this.subblocktype = subblocktype; 36 | } 37 | 38 | /** 39 | * Return true if the given value is equal to the enum's value 40 | * @param subblocktype 41 | * @return true if the given value is equal to the enum's value 42 | */ 43 | public boolean equals(short subblocktype) 44 | { 45 | return this.subblocktype == subblocktype; 46 | } 47 | 48 | /** 49 | * find the header type for the given short value 50 | * @param SubType the short value 51 | * @return the correspo nding enum or null 52 | */ 53 | public static SubBlockHeaderType findSubblockHeaderType(short subType) 54 | { 55 | if(EA_HEAD.equals(subType)){ 56 | return EA_HEAD; 57 | }else if(UO_HEAD.equals(subType)){ 58 | return UO_HEAD; 59 | }else if(MAC_HEAD.equals(subType)){ 60 | return MAC_HEAD; 61 | }else if(BEEA_HEAD.equals(subType)){ 62 | return BEEA_HEAD; 63 | }else if(NTACL_HEAD.equals(subType)){ 64 | return NTACL_HEAD; 65 | }else if(STREAM_HEAD.equals(subType)){ 66 | return STREAM_HEAD; 67 | } 68 | return null; 69 | } 70 | 71 | /** 72 | * @return the short representation of this enum 73 | */ 74 | public short getSubblocktype() { 75 | return subblocktype; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/rarfile/UnixOwnersHeader.java: -------------------------------------------------------------------------------- 1 | package de.innosystec.unrar.rarfile; 2 | 3 | import org.apache.commons.logging.Log; 4 | import org.apache.commons.logging.LogFactory; 5 | 6 | import de.innosystec.unrar.io.Raw; 7 | 8 | public class UnixOwnersHeader 9 | extends SubBlockHeader 10 | { 11 | private Log logger = LogFactory.getLog(UnixOwnersHeader.class); 12 | private int ownerNameSize; 13 | private int groupNameSize; 14 | private String owner; 15 | private String group; 16 | 17 | public UnixOwnersHeader(SubBlockHeader sb, byte[] uoHeader) { 18 | super(sb); 19 | int pos = 0; 20 | ownerNameSize = Raw.readShortLittleEndian(uoHeader, pos)&0xFFFF; 21 | pos+=2; 22 | groupNameSize = Raw.readShortLittleEndian(uoHeader, pos)&0xFFFF; 23 | pos+=2; 24 | if(pos+ownerNameSize": ">" or ">" 17 | * "@": "@" 18 | */ 19 | package de.innosystec.unrar.rarfile; 20 | 21 | /** 22 | * DOCUMENT ME 23 | * 24 | * @author $LastChangedBy$ 25 | * @version $LastChangedRevision$ 26 | */ 27 | public enum UnrarHeadertype { 28 | 29 | 30 | /** 31 | * 32 | */ 33 | MainHeader ((byte)0x73), 34 | 35 | /** 36 | * 37 | */ 38 | MarkHeader ((byte)0x72), 39 | 40 | /** 41 | * 42 | */ 43 | FileHeader ((byte) 0x74), 44 | 45 | /** 46 | * 47 | */ 48 | CommHeader ((byte) 0x75), 49 | 50 | /** 51 | * 52 | */ 53 | AvHeader ((byte) 0x76), 54 | 55 | /** 56 | * 57 | */ 58 | SubHeader ((byte) 0x77), 59 | 60 | /** 61 | * 62 | */ 63 | ProtectHeader ((byte) 0x78), 64 | 65 | /** 66 | * 67 | */ 68 | SignHeader ((byte) 0x79), 69 | 70 | /** 71 | * 72 | */ 73 | NewSubHeader ((byte) 0x7a), 74 | 75 | /** 76 | * 77 | */ 78 | EndArcHeader ((byte) 0x7b); 79 | 80 | /** 81 | * Returns the enum according to the given byte or null 82 | * @param headerType the headerbyte 83 | * @return the enum or null 84 | */ 85 | public static UnrarHeadertype findType(byte headerType) 86 | { 87 | if(UnrarHeadertype.MarkHeader.equals(headerType)){ 88 | return UnrarHeadertype.MarkHeader; 89 | } 90 | if(UnrarHeadertype.MainHeader.equals(headerType)){ 91 | return UnrarHeadertype.MainHeader; 92 | } 93 | if(UnrarHeadertype.FileHeader.equals(headerType)){ 94 | return UnrarHeadertype.FileHeader; 95 | } 96 | if(UnrarHeadertype.EndArcHeader.equals(headerType)){ 97 | return UnrarHeadertype.EndArcHeader; 98 | } 99 | if(UnrarHeadertype.NewSubHeader.equals(headerType)){ 100 | return UnrarHeadertype.NewSubHeader; 101 | } 102 | if(UnrarHeadertype.SubHeader.equals(headerType)){ 103 | return UnrarHeadertype.SubHeader; 104 | } 105 | if(UnrarHeadertype.SignHeader.equals(headerType)){ 106 | return UnrarHeadertype.SignHeader; 107 | } 108 | if(UnrarHeadertype.ProtectHeader.equals(headerType)){ 109 | return UnrarHeadertype.ProtectHeader; 110 | } 111 | if(UnrarHeadertype.MarkHeader.equals(headerType)){ 112 | return UnrarHeadertype.MarkHeader; 113 | } 114 | if(UnrarHeadertype.MainHeader.equals(headerType)){ 115 | return UnrarHeadertype.MainHeader; 116 | } 117 | if(UnrarHeadertype.FileHeader.equals(headerType)){ 118 | return UnrarHeadertype.FileHeader; 119 | } 120 | if(UnrarHeadertype.EndArcHeader.equals(headerType)){ 121 | return UnrarHeadertype.EndArcHeader; 122 | } 123 | if(UnrarHeadertype.CommHeader.equals(headerType)){ 124 | return UnrarHeadertype.CommHeader; 125 | } 126 | if(UnrarHeadertype.AvHeader.equals(headerType)){ 127 | return UnrarHeadertype.AvHeader; 128 | } 129 | return null; 130 | } 131 | 132 | 133 | 134 | private byte headerByte; 135 | 136 | private UnrarHeadertype(byte headerByte) 137 | { 138 | this.headerByte = headerByte; 139 | } 140 | 141 | 142 | /** 143 | * Return true if the given byte is equal to the enum's byte 144 | * @param header 145 | * @return true if the given byte is equal to the enum's byte 146 | */ 147 | public boolean equals(byte header) 148 | { 149 | return headerByte == header; 150 | } 151 | 152 | 153 | /** 154 | * the header byte of this enum 155 | * @return the header byte of this enum 156 | */ 157 | public byte getHeaderByte() { 158 | return headerByte; 159 | } 160 | 161 | 162 | 163 | 164 | } 165 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/tika/RARParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 Jukka Zitting 3 | * 4 | * the unrar licence applies to all junrar source and binary distributions 5 | * you are not allowed to use this source to re-create the RAR compression 6 | * algorithm 7 | */ 8 | package de.innosystec.unrar.tika; 9 | 10 | import java.io.File; 11 | import java.io.IOException; 12 | import java.io.InputStream; 13 | import java.util.Collections; 14 | import java.util.Set; 15 | 16 | import org.apache.tika.exception.TikaException; 17 | import org.apache.tika.extractor.EmbeddedDocumentExtractor; 18 | import org.apache.tika.io.TikaInputStream; 19 | import org.apache.tika.metadata.Metadata; 20 | import org.apache.tika.mime.MediaType; 21 | import org.apache.tika.parser.ParseContext; 22 | import org.apache.tika.parser.Parser; 23 | import org.apache.tika.sax.XHTMLContentHandler; 24 | import org.xml.sax.ContentHandler; 25 | import org.xml.sax.SAXException; 26 | 27 | import de.innosystec.unrar.Archive; 28 | import de.innosystec.unrar.exception.RarException; 29 | import de.innosystec.unrar.rarfile.FileHeader; 30 | 31 | public class RARParser implements Parser { 32 | 33 | private static final MediaType TYPE = 34 | MediaType.application("x-rar-compressed"); 35 | 36 | public Set getSupportedTypes(ParseContext context) { 37 | return Collections.singleton(TYPE); 38 | } 39 | 40 | public void parse( 41 | InputStream stream, ContentHandler handler, 42 | Metadata metadata, ParseContext context) 43 | throws SAXException, IOException, TikaException { 44 | EmbeddedDocumentExtractor extractor = 45 | new EmbeddedDocumentExtractor(context); 46 | 47 | try { 48 | File file = TikaInputStream.get(stream).getFile(); 49 | Archive archive = new Archive(file); 50 | 51 | metadata.set(Metadata.CONTENT_TYPE, TYPE.toString()); 52 | XHTMLContentHandler xhtml = 53 | new XHTMLContentHandler(handler, metadata); 54 | xhtml.startDocument(); 55 | for (FileHeader header : archive.getFileHeaders()) { 56 | Metadata entrydata = new Metadata(); 57 | entrydata.set( 58 | Metadata.RESOURCE_NAME_KEY, 59 | header.getFileNameString()); 60 | if (extractor.shouldParseEmbedded(entrydata)) { 61 | extractor.parseEmbedded(stream, xhtml, entrydata, true); 62 | } 63 | } 64 | xhtml.endDocument(); 65 | } catch (RarException e) { 66 | throw new TikaException("Unable to parse a RAR archive", e); 67 | } 68 | } 69 | 70 | public void parse( 71 | InputStream stream, ContentHandler handler, Metadata metadata) 72 | throws IOException, SAXException, TikaException { 73 | parse(stream, handler, metadata, new ParseContext()); 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/ComprDataIO.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 31.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack; 19 | 20 | import de.innosystec.unrar.Archive; 21 | import de.innosystec.unrar.Volume; 22 | import de.innosystec.unrar.crc.RarCRC; 23 | import de.innosystec.unrar.exception.RarException; 24 | import de.innosystec.unrar.io.ReadOnlyAccessInputStream; 25 | import de.innosystec.unrar.rarfile.FileHeader; 26 | import java.io.EOFException; 27 | import java.io.IOException; 28 | import java.io.InputStream; 29 | import java.io.OutputStream; 30 | 31 | /** 32 | * DOCUMENT ME 33 | * 34 | * @author $LastChangedBy$ 35 | * @version $LastChangedRevision$ 36 | */ 37 | public class ComprDataIO { 38 | 39 | private final Archive archive; 40 | 41 | private long unpPackedSize; 42 | 43 | private boolean testMode; 44 | 45 | private boolean skipUnpCRC; 46 | 47 | private InputStream inputStream; 48 | 49 | private OutputStream outputStream; 50 | 51 | 52 | private FileHeader subHead; 53 | 54 | // cryptData Crypt; 55 | // cryptData Decrypt; 56 | private boolean packVolume; 57 | 58 | private boolean unpVolume; 59 | 60 | private boolean nextVolumeMissing; 61 | 62 | private long totalPackRead; 63 | 64 | private long unpArcSize; 65 | 66 | private long curPackRead, curPackWrite, curUnpRead, curUnpWrite; 67 | 68 | private long processedArcSize, totalArcSize; 69 | 70 | private long packFileCRC, unpFileCRC, packedCRC; 71 | 72 | private int encryption; 73 | 74 | private int decryption; 75 | 76 | private int lastPercent; 77 | 78 | private char currentCommand; 79 | 80 | public ComprDataIO(Archive arc) { 81 | this.archive = arc; 82 | } 83 | 84 | public void init(OutputStream outputStream) { 85 | this.outputStream = outputStream; 86 | unpPackedSize = 0; 87 | testMode = false; 88 | skipUnpCRC = false; 89 | packVolume = false; 90 | unpVolume = false; 91 | nextVolumeMissing = false; 92 | // command = null; 93 | encryption = 0; 94 | decryption = 0; 95 | totalPackRead = 0; 96 | curPackRead = curPackWrite = curUnpRead = curUnpWrite = 0; 97 | packFileCRC = unpFileCRC = packedCRC = 0xffffffff; 98 | lastPercent = -1; 99 | subHead = null; 100 | 101 | currentCommand = 0; 102 | processedArcSize = totalArcSize = 0; 103 | } 104 | 105 | public void init(FileHeader hd) throws IOException { 106 | long startPos = hd.getPositionInFile() + hd.getHeaderSize(); 107 | unpPackedSize = hd.getFullPackSize(); 108 | inputStream = new ReadOnlyAccessInputStream( 109 | archive.getRof(), 110 | startPos, 111 | startPos + unpPackedSize); 112 | subHead = hd; 113 | curUnpRead = 0; 114 | curPackWrite = 0; 115 | packedCRC = 0xFFffFFff; 116 | } 117 | 118 | public int unpRead(byte[] addr, int offset, int count) 119 | throws IOException, RarException { 120 | int retCode=0, totalRead=0; 121 | while (count > 0) { 122 | int readSize = (count > unpPackedSize) ? (int)unpPackedSize : count; 123 | retCode = inputStream.read(addr, offset, readSize); 124 | if (retCode < 0) { 125 | throw new EOFException(); 126 | } 127 | if (subHead.isSplitAfter()){ 128 | packedCRC = RarCRC.checkCrc( 129 | (int)packedCRC, addr, offset, retCode); 130 | } 131 | 132 | curUnpRead += retCode; 133 | totalRead += retCode; 134 | offset += retCode; 135 | count -= retCode; 136 | unpPackedSize -= retCode; 137 | archive.bytesReadRead(retCode); 138 | if (unpPackedSize == 0 && subHead.isSplitAfter()) { 139 | if (!Volume.mergeArchive(archive, this)) { 140 | nextVolumeMissing=true; 141 | return -1; 142 | } 143 | } 144 | else { 145 | break; 146 | } 147 | } 148 | 149 | if (retCode != -1) { 150 | retCode = totalRead; 151 | } 152 | return retCode; 153 | 154 | 155 | } 156 | 157 | public void unpWrite(byte[] addr, int offset, int count) 158 | throws IOException { 159 | if (!testMode) { 160 | // DestFile->Write(Addr,Count); 161 | outputStream.write(addr, offset, count); 162 | } 163 | 164 | curUnpWrite += count; 165 | 166 | if (!skipUnpCRC){ 167 | if (archive.isOldFormat()){ 168 | unpFileCRC = RarCRC.checkOldCrc( 169 | (short)unpFileCRC, addr, count); 170 | } 171 | else{ 172 | unpFileCRC = RarCRC.checkCrc( 173 | (int)unpFileCRC, addr,offset, count); 174 | } 175 | } 176 | // if (!skipArcCRC) { 177 | // archive.updateDataCRC(Addr, offset, ReadSize); 178 | // } 179 | } 180 | 181 | public void setPackedSizeToRead(long size) 182 | { 183 | unpPackedSize = size; 184 | } 185 | 186 | public void setTestMode(boolean mode) 187 | { 188 | testMode = mode; 189 | } 190 | 191 | public void setSkipUnpCRC(boolean skip) 192 | { 193 | skipUnpCRC = skip; 194 | } 195 | 196 | public void setSubHeader(FileHeader hd) 197 | { 198 | subHead = hd; 199 | 200 | } 201 | 202 | public long getCurPackRead() 203 | { 204 | return curPackRead; 205 | } 206 | 207 | public void setCurPackRead(long curPackRead) 208 | { 209 | this.curPackRead = curPackRead; 210 | } 211 | 212 | public long getCurPackWrite() 213 | { 214 | return curPackWrite; 215 | } 216 | 217 | public void setCurPackWrite(long curPackWrite) 218 | { 219 | this.curPackWrite = curPackWrite; 220 | } 221 | 222 | public long getCurUnpRead() 223 | { 224 | return curUnpRead; 225 | } 226 | 227 | public void setCurUnpRead(long curUnpRead) 228 | { 229 | this.curUnpRead = curUnpRead; 230 | } 231 | 232 | public long getCurUnpWrite() 233 | { 234 | return curUnpWrite; 235 | } 236 | 237 | public void setCurUnpWrite(long curUnpWrite) 238 | { 239 | this.curUnpWrite = curUnpWrite; 240 | } 241 | 242 | public int getDecryption() 243 | { 244 | return decryption; 245 | } 246 | 247 | public void setDecryption(int decryption) 248 | { 249 | this.decryption = decryption; 250 | } 251 | 252 | public int getEncryption() 253 | { 254 | return encryption; 255 | } 256 | 257 | public void setEncryption(int encryption) 258 | { 259 | this.encryption = encryption; 260 | } 261 | 262 | public boolean isNextVolumeMissing() 263 | { 264 | return nextVolumeMissing; 265 | } 266 | 267 | public void setNextVolumeMissing(boolean nextVolumeMissing) 268 | { 269 | this.nextVolumeMissing = nextVolumeMissing; 270 | } 271 | 272 | public long getPackedCRC() { 273 | return packedCRC; 274 | } 275 | 276 | public void setPackedCRC(long packedCRC) { 277 | this.packedCRC = packedCRC; 278 | } 279 | 280 | public long getPackFileCRC() 281 | { 282 | return packFileCRC; 283 | } 284 | 285 | public void setPackFileCRC(long packFileCRC) 286 | { 287 | this.packFileCRC = packFileCRC; 288 | } 289 | 290 | public boolean isPackVolume() 291 | { 292 | return packVolume; 293 | } 294 | 295 | public void setPackVolume(boolean packVolume) 296 | { 297 | this.packVolume = packVolume; 298 | } 299 | 300 | public long getProcessedArcSize() 301 | { 302 | return processedArcSize; 303 | } 304 | 305 | public void setProcessedArcSize(long processedArcSize) 306 | { 307 | this.processedArcSize = processedArcSize; 308 | } 309 | 310 | public long getTotalArcSize() 311 | { 312 | return totalArcSize; 313 | } 314 | 315 | public void setTotalArcSize(long totalArcSize) 316 | { 317 | this.totalArcSize = totalArcSize; 318 | } 319 | 320 | public long getTotalPackRead() 321 | { 322 | return totalPackRead; 323 | } 324 | 325 | public void setTotalPackRead(long totalPackRead) 326 | { 327 | this.totalPackRead = totalPackRead; 328 | } 329 | 330 | public long getUnpArcSize() 331 | { 332 | return unpArcSize; 333 | } 334 | 335 | public void setUnpArcSize(long unpArcSize) 336 | { 337 | this.unpArcSize = unpArcSize; 338 | } 339 | 340 | public long getUnpFileCRC() 341 | { 342 | return unpFileCRC; 343 | } 344 | 345 | public void setUnpFileCRC(long unpFileCRC) 346 | { 347 | this.unpFileCRC = unpFileCRC; 348 | } 349 | 350 | public boolean isUnpVolume() 351 | { 352 | return unpVolume; 353 | } 354 | 355 | public void setUnpVolume(boolean unpVolume) 356 | { 357 | this.unpVolume = unpVolume; 358 | } 359 | 360 | public FileHeader getSubHeader() 361 | { 362 | return subHead; 363 | } 364 | 365 | 366 | 367 | // public void setEncryption(int method, char[] Password, byte[] Salt, 368 | // boolean encrypt, boolean handsOffHash) 369 | // { 370 | // 371 | // } 372 | // 373 | // public void setAV15Encryption() 374 | // { 375 | // 376 | // } 377 | // 378 | // public void setCmt13Encryption() 379 | // { 380 | // 381 | // } 382 | } 383 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/UnpackFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 01.06.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack; 19 | 20 | import de.innosystec.unrar.unpack.vm.VMPreparedProgram; 21 | 22 | /** 23 | * DOCUMENT ME 24 | * 25 | * @author $LastChangedBy$ 26 | * @version $LastChangedRevision$ 27 | */ 28 | public class UnpackFilter { 29 | 30 | private int BlockStart; 31 | 32 | private int BlockLength; 33 | 34 | private int ExecCount; 35 | 36 | private boolean NextWindow; 37 | 38 | // position of parent filter in Filters array used as prototype for filter 39 | // in PrgStack array. Not defined for filters in Filters array. 40 | private int ParentFilter; 41 | 42 | private VMPreparedProgram Prg = new VMPreparedProgram(); 43 | 44 | public int getBlockLength() { 45 | return BlockLength; 46 | } 47 | 48 | public void setBlockLength(int blockLength) { 49 | BlockLength = blockLength; 50 | } 51 | 52 | public int getBlockStart() { 53 | return BlockStart; 54 | } 55 | 56 | public void setBlockStart(int blockStart) { 57 | BlockStart = blockStart; 58 | } 59 | 60 | public int getExecCount() { 61 | return ExecCount; 62 | } 63 | 64 | public void setExecCount(int execCount) { 65 | ExecCount = execCount; 66 | } 67 | 68 | public boolean isNextWindow() { 69 | return NextWindow; 70 | } 71 | 72 | public void setNextWindow(boolean nextWindow) { 73 | NextWindow = nextWindow; 74 | } 75 | 76 | public int getParentFilter() { 77 | return ParentFilter; 78 | } 79 | 80 | public void setParentFilter(int parentFilter) { 81 | ParentFilter = parentFilter; 82 | } 83 | 84 | public VMPreparedProgram getPrg() { 85 | return Prg; 86 | } 87 | 88 | public void setPrg(VMPreparedProgram prg) { 89 | Prg = prg; 90 | } 91 | 92 | 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/decode/AudioVariables.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 01.06.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.decode; 19 | 20 | /** 21 | * DOCUMENT ME 22 | * 23 | * @author $LastChangedBy$ 24 | * @version $LastChangedRevision$ 25 | */ 26 | public class AudioVariables { 27 | int k1, k2, k3, k4, k5; 28 | 29 | int d1, d2, d3, d4; 30 | 31 | int lastDelta; 32 | 33 | int dif[] = new int[11]; 34 | 35 | int byteCount; 36 | 37 | int lastChar; 38 | 39 | public int getByteCount() { 40 | return byteCount; 41 | } 42 | 43 | public void setByteCount(int byteCount) { 44 | this.byteCount = byteCount; 45 | } 46 | 47 | public int getD1() { 48 | return d1; 49 | } 50 | 51 | public void setD1(int d1) { 52 | this.d1 = d1; 53 | } 54 | 55 | public int getD2() { 56 | return d2; 57 | } 58 | 59 | public void setD2(int d2) { 60 | this.d2 = d2; 61 | } 62 | 63 | public int getD3() { 64 | return d3; 65 | } 66 | 67 | public void setD3(int d3) { 68 | this.d3 = d3; 69 | } 70 | 71 | public int getD4() { 72 | return d4; 73 | } 74 | 75 | public void setD4(int d4) { 76 | this.d4 = d4; 77 | } 78 | 79 | public int[] getDif() { 80 | return dif; 81 | } 82 | 83 | public void setDif(int[] dif) { 84 | this.dif = dif; 85 | } 86 | 87 | public int getK1() { 88 | return k1; 89 | } 90 | 91 | public void setK1(int k1) { 92 | this.k1 = k1; 93 | } 94 | 95 | public int getK2() { 96 | return k2; 97 | } 98 | 99 | public void setK2(int k2) { 100 | this.k2 = k2; 101 | } 102 | 103 | public int getK3() { 104 | return k3; 105 | } 106 | 107 | public void setK3(int k3) { 108 | this.k3 = k3; 109 | } 110 | 111 | public int getK4() { 112 | return k4; 113 | } 114 | 115 | public void setK4(int k4) { 116 | this.k4 = k4; 117 | } 118 | 119 | public int getK5() { 120 | return k5; 121 | } 122 | 123 | public void setK5(int k5) { 124 | this.k5 = k5; 125 | } 126 | 127 | public int getLastChar() { 128 | return lastChar; 129 | } 130 | 131 | public void setLastChar(int lastChar) { 132 | this.lastChar = lastChar; 133 | } 134 | 135 | public int getLastDelta() { 136 | return lastDelta; 137 | } 138 | 139 | public void setLastDelta(int lastDelta) { 140 | this.lastDelta = lastDelta; 141 | } 142 | 143 | 144 | } 145 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/decode/BitDecode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 01.06.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.decode; 19 | 20 | /** 21 | * DOCUMENT ME 22 | * 23 | * @author $LastChangedBy$ 24 | * @version $LastChangedRevision$ 25 | */ 26 | public class BitDecode extends Decode 27 | { 28 | /** 29 | * 30 | */ 31 | public BitDecode() 32 | { 33 | decodeNum = new int[Compress.BC]; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/decode/CodeType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 01.06.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * Here some html entities which can be used for escaping javadoc tags: 10 | * "&": "&" or "&" 11 | * "<": "<" or "<" 12 | * ">": ">" or ">" 13 | * "@": "@" 14 | */ 15 | package de.innosystec.unrar.unpack.decode; 16 | 17 | /** 18 | * DOCUMENT ME 19 | * 20 | * the unrar licence applies to all junrar source and binary distributions 21 | * you are not allowed to use this source to re-create the RAR compression algorithm 22 | * 23 | * @author $LastChangedBy$ 24 | * @version $LastChangedRevision$ 25 | */ 26 | public enum CodeType { 27 | CODE_HUFFMAN,CODE_LZ,CODE_LZ2,CODE_REPEATLZ,CODE_CACHELZ, 28 | CODE_STARTFILE,CODE_ENDFILE,CODE_VM,CODE_VMDATA; 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/decode/Compress.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 01.06.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.decode; 19 | 20 | /** 21 | * DOCUMENT ME 22 | * 23 | * @author $LastChangedBy$ 24 | * @version $LastChangedRevision$ 25 | */ 26 | public class Compress { 27 | public static final int CODEBUFSIZE = 0x4000; 28 | public static final int MAXWINSIZE = 0x400000; 29 | public static final int MAXWINMASK = (MAXWINSIZE-1); 30 | 31 | public static final int LOW_DIST_REP_COUNT = 16; 32 | 33 | public static final int NC = 299; /* alphabet = {0, 1, 2, ..., NC - 1} */ 34 | public static final int DC = 60; 35 | public static final int LDC = 17; 36 | public static final int RC = 28; 37 | public static final int HUFF_TABLE_SIZE = (NC+DC+RC+LDC); 38 | public static final int BC = 20; 39 | 40 | public static final int NC20 = 298; /* alphabet = {0, 1, 2, ..., NC - 1} */ 41 | public static final int DC20 = 48; 42 | public static final int RC20 = 28; 43 | public static final int BC20 = 19; 44 | public static final int MC20 = 257; 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/decode/Decode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 01.06.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.decode; 19 | 20 | /** 21 | * Used to store information for lz decoding 22 | * 23 | * @author $LastChangedBy$ 24 | * @version $LastChangedRevision$ 25 | */ 26 | public class Decode 27 | { 28 | private int maxNum; 29 | 30 | private final int[] decodeLen = new int[16]; 31 | 32 | private final int[] decodePos = new int[16]; 33 | 34 | protected int[] decodeNum = new int[2]; 35 | 36 | /** 37 | * returns the decode Length array 38 | * @return decodeLength 39 | */ 40 | public int[] getDecodeLen() 41 | { 42 | return decodeLen; 43 | } 44 | 45 | /** 46 | * returns the decode num array 47 | * @return decodeNum 48 | */ 49 | public int[] getDecodeNum() 50 | { 51 | return decodeNum; 52 | } 53 | 54 | /** 55 | * returns the decodePos array 56 | * @return decodePos 57 | */ 58 | public int[] getDecodePos() 59 | { 60 | return decodePos; 61 | } 62 | 63 | /** 64 | * returns the max num 65 | * @return maxNum 66 | */ 67 | public int getMaxNum() 68 | { 69 | return maxNum; 70 | } 71 | 72 | /** 73 | * sets the max num 74 | * @param maxNum to be set to maxNum 75 | */ 76 | public void setMaxNum(int maxNum) 77 | { 78 | this.maxNum = maxNum; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/decode/DistDecode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 01.06.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.decode; 19 | 20 | /** 21 | * DOCUMENT ME 22 | * 23 | * @author $LastChangedBy$ 24 | * @version $LastChangedRevision$ 25 | */ 26 | public class DistDecode extends Decode 27 | { 28 | 29 | /** 30 | * 31 | */ 32 | public DistDecode() 33 | { 34 | decodeNum = new int[Compress.DC]; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/decode/FilterType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 01.06.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.decode; 19 | 20 | /** 21 | * DOCUMENT ME 22 | * 23 | * @author $LastChangedBy$ 24 | * @version $LastChangedRevision$ 25 | */ 26 | public enum FilterType { 27 | FILTER_NONE, FILTER_PPM /*dummy*/, FILTER_E8, FILTER_E8E9, 28 | FILTER_UPCASETOLOW, FILTER_AUDIO, FILTER_RGB, FILTER_DELTA, 29 | FILTER_ITANIUM, FILTER_E8E9V2; 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/decode/LitDecode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 01.06.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.decode; 19 | 20 | /** 21 | * DOCUMENT ME 22 | * 23 | * @author $LastChangedBy$ 24 | * @version $LastChangedRevision$ 25 | */ 26 | public class LitDecode extends Decode 27 | { 28 | /** 29 | * 30 | */ 31 | public LitDecode() 32 | { 33 | decodeNum = new int[Compress.NC]; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/decode/LowDistDecode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 01.06.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.decode; 19 | 20 | /** 21 | * DOCUMENT ME 22 | * 23 | * @author $LastChangedBy$ 24 | * @version $LastChangedRevision$ 25 | */ 26 | public class LowDistDecode extends Decode 27 | { 28 | 29 | /** 30 | * 31 | */ 32 | public LowDistDecode() 33 | { 34 | decodeNum = new int[Compress.LDC]; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/decode/MultDecode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 01.06.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.decode; 19 | 20 | /** 21 | * DOCUMENT ME 22 | * 23 | * @author $LastChangedBy$ 24 | * @version $LastChangedRevision$ 25 | */ 26 | public class MultDecode extends Decode 27 | { 28 | 29 | /** 30 | * 31 | */ 32 | public MultDecode() 33 | { 34 | decodeNum = new int[Compress.MC20]; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/decode/RepDecode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 01.06.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.decode; 19 | 20 | /** 21 | * DOCUMENT ME 22 | * 23 | * @author $LastChangedBy$ 24 | * @version $LastChangedRevision$ 25 | */ 26 | public class RepDecode extends Decode 27 | { 28 | /** 29 | * 30 | */ 31 | public RepDecode() 32 | { 33 | decodeNum = new int[Compress.RC]; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/ppm/AnalyzeHeapDump.java: -------------------------------------------------------------------------------- 1 | package de.innosystec.unrar.unpack.ppm; 2 | 3 | import java.io.BufferedInputStream; 4 | import java.io.File; 5 | import java.io.FileInputStream; 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | 9 | /** 10 | * For debugging purposes only. 11 | * 12 | * @author alban 13 | */ 14 | public class AnalyzeHeapDump { 15 | 16 | /** Creates a new instance of AnalyzeHeapDump */ 17 | public AnalyzeHeapDump() { 18 | } 19 | 20 | public static void main(String[] argv) { 21 | File cfile = new File("P:\\test\\heapdumpc"); 22 | File jfile = new File("P:\\test\\heapdumpj"); 23 | if (!cfile.exists()) { 24 | System.err.println("File not found: " + cfile.getAbsolutePath()); 25 | return; 26 | } 27 | if (!jfile.exists()) { 28 | System.err.println("File not found: " + jfile.getAbsolutePath()); 29 | return; 30 | } 31 | long clen = cfile.length(); 32 | long jlen = jfile.length(); 33 | if (clen != jlen) { 34 | System.out.println("File size mismatch"); 35 | System.out.println("clen = " + clen); 36 | System.out.println("jlen = " + jlen); 37 | } 38 | // Do byte comparison 39 | long len = Math.min(clen, jlen); 40 | InputStream cin = null; 41 | InputStream jin = null; 42 | int bufferLen = 256*1024; 43 | try { 44 | cin = new BufferedInputStream( 45 | new FileInputStream(cfile), bufferLen); 46 | jin = new BufferedInputStream( 47 | new FileInputStream(jfile), bufferLen); 48 | boolean matching = true; 49 | boolean mismatchFound = false; 50 | long startOff = 0L; 51 | long off = 0L; 52 | while (off < len) { 53 | if (cin.read() != jin.read()) { 54 | if (matching) { 55 | startOff = off; 56 | matching = false; 57 | mismatchFound = true; 58 | } 59 | } 60 | else { // match 61 | if (!matching) { 62 | printMismatch(startOff, off); 63 | matching = true; 64 | } 65 | } 66 | off++; 67 | } 68 | if (!matching) { 69 | printMismatch(startOff, off); 70 | } 71 | if (!mismatchFound) { 72 | System.out.println("Files are identical"); 73 | } 74 | System.out.println("Done"); 75 | } 76 | catch (IOException e) { 77 | e.printStackTrace(); 78 | } 79 | finally { 80 | try { 81 | cin.close(); 82 | jin.close(); 83 | } catch (IOException e) { 84 | e.printStackTrace(); 85 | } 86 | } 87 | } 88 | 89 | private static void printMismatch(long startOff, long bytesRead) { 90 | System.out.println("Mismatch: off=" + startOff + 91 | "(0x" + Long.toHexString(startOff) + 92 | "), len=" + (bytesRead - startOff)); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/ppm/BlockTypes.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 01.06.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.ppm; 19 | 20 | 21 | /** 22 | * DOCUMENT ME 23 | * 24 | * @author $LastChangedBy$ 25 | * @version $LastChangedRevision$ 26 | */ 27 | public enum BlockTypes 28 | { 29 | BLOCK_LZ(0), BLOCK_PPM(1); 30 | 31 | private int blockType; 32 | 33 | private BlockTypes(int blockType) 34 | { 35 | this.blockType = blockType; 36 | } 37 | 38 | public int getBlockType() 39 | { 40 | return blockType; 41 | } 42 | 43 | public boolean equals(int blockType) 44 | { 45 | return this.blockType == blockType; 46 | } 47 | 48 | public static BlockTypes findBlockType(int blockType) 49 | { 50 | if (BLOCK_LZ.equals(blockType)) { 51 | return BLOCK_LZ; 52 | } 53 | if (BLOCK_PPM.equals(blockType)) { 54 | return BLOCK_PPM; 55 | } 56 | return null; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/ppm/FreqData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 04.06.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.ppm; 19 | 20 | import de.innosystec.unrar.io.Raw; 21 | 22 | /** 23 | * DOCUMENT ME 24 | * 25 | * @author $LastChangedBy$ 26 | * @version $LastChangedRevision$ 27 | */ 28 | public class FreqData extends Pointer{ 29 | 30 | public static final int size = 6; 31 | 32 | // struct FreqData 33 | // { 34 | // ushort SummFreq; 35 | // STATE _PACK_ATTR * Stats; 36 | // }; 37 | 38 | public FreqData(byte[]mem){ 39 | super(mem); 40 | } 41 | 42 | public FreqData init(byte[] mem) { 43 | this.mem = mem; 44 | pos = 0; 45 | return this; 46 | } 47 | 48 | public int getSummFreq() { 49 | return Raw.readShortLittleEndian(mem, pos)&0xffff; 50 | } 51 | 52 | public void setSummFreq(int summFreq) { 53 | Raw.writeShortLittleEndian(mem, pos, (short)summFreq); 54 | } 55 | 56 | public void incSummFreq(int dSummFreq) { 57 | Raw.incShortLittleEndian(mem, pos, dSummFreq); 58 | } 59 | 60 | public int getStats() { 61 | return Raw.readIntLittleEndian(mem, pos+2); 62 | } 63 | 64 | public void setStats(State state) { 65 | setStats(state.getAddress()); 66 | } 67 | 68 | public void setStats(int state) { 69 | Raw.writeIntLittleEndian(mem, pos+2, state); 70 | } 71 | 72 | public String toString() { 73 | StringBuilder buffer = new StringBuilder(); 74 | buffer.append("FreqData["); 75 | buffer.append("\n pos="); 76 | buffer.append(pos); 77 | buffer.append("\n size="); 78 | buffer.append(size); 79 | buffer.append("\n summFreq="); 80 | buffer.append(getSummFreq()); 81 | buffer.append("\n stats="); 82 | buffer.append(getStats()); 83 | buffer.append("\n]"); 84 | return buffer.toString(); 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/ppm/PPMContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 31.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.ppm; 19 | 20 | import de.innosystec.unrar.io.Raw; 21 | 22 | /** 23 | * DOCUMENT ME 24 | * 25 | * @author $LastChangedBy$ 26 | * @version $LastChangedRevision$ 27 | */ 28 | public class PPMContext extends Pointer 29 | { 30 | 31 | private static final int unionSize = Math.max(FreqData.size, State.size); 32 | 33 | public static final int size = 2 + unionSize + 4; // 12 34 | 35 | // ushort NumStats; 36 | private int numStats; // determines if feqData or onstate is used 37 | 38 | // (1==onestate) 39 | 40 | private final FreqData freqData; // -\ 41 | 42 | // |-> union 43 | private final State oneState; // -/ 44 | 45 | private int suffix; // pointer ppmcontext 46 | 47 | public final static int[] ExpEscape = 48 | { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 }; 49 | 50 | // Temp fields 51 | private final State tempState1 = new State(null); 52 | private final State tempState2 = new State(null); 53 | private final State tempState3 = new State(null); 54 | private final State tempState4 = new State(null); 55 | private final State tempState5 = new State(null); 56 | private PPMContext tempPPMContext = null; 57 | private final int[] ps = new int[256]; 58 | 59 | public PPMContext(byte[] mem) 60 | { 61 | super(mem); 62 | oneState = new State(mem); 63 | freqData = new FreqData(mem); 64 | } 65 | 66 | public PPMContext init(byte[] mem) { 67 | this.mem = mem; 68 | pos = 0; 69 | oneState.init(mem); 70 | freqData.init(mem); 71 | return this; 72 | } 73 | 74 | public FreqData getFreqData() 75 | { 76 | return freqData; 77 | } 78 | 79 | public void setFreqData(FreqData freqData) 80 | { 81 | this.freqData.setSummFreq(freqData.getSummFreq()); 82 | this.freqData.setStats(freqData.getStats()); 83 | } 84 | 85 | public final int getNumStats() 86 | { 87 | if (mem!=null){ 88 | numStats = Raw.readShortLittleEndian(mem, pos)&0xffff; 89 | } 90 | return numStats; 91 | } 92 | 93 | public final void setNumStats(int numStats) 94 | { 95 | this.numStats = numStats&0xffff; 96 | if (mem != null) { 97 | Raw.writeShortLittleEndian(mem, pos, (short)numStats); 98 | } 99 | } 100 | 101 | public State getOneState() 102 | { 103 | return oneState; 104 | } 105 | 106 | public void setOneState(StateRef oneState) 107 | { 108 | this.oneState.setValues(oneState); 109 | } 110 | 111 | public int getSuffix() 112 | { 113 | if(mem!=null){ 114 | suffix = Raw.readIntLittleEndian(mem, pos+8); 115 | } 116 | return suffix; 117 | } 118 | 119 | public void setSuffix(PPMContext suffix) 120 | { 121 | setSuffix(suffix.getAddress()); 122 | } 123 | 124 | public void setSuffix(int suffix) 125 | { 126 | this.suffix = suffix; 127 | if (mem != null) { 128 | Raw.writeIntLittleEndian(mem, pos + 8, suffix); 129 | } 130 | } 131 | 132 | @Override 133 | public void setAddress(int pos) 134 | { 135 | super.setAddress(pos); 136 | oneState.setAddress(pos+2); 137 | freqData.setAddress(pos+2); 138 | } 139 | 140 | private PPMContext getTempPPMContext(byte[] mem) { 141 | if (tempPPMContext == null) { 142 | tempPPMContext = new PPMContext(null); 143 | } 144 | return tempPPMContext.init(mem); 145 | } 146 | 147 | public int createChild(ModelPPM model, State pStats/* ptr */, 148 | StateRef firstState /* ref */) 149 | { 150 | PPMContext pc = getTempPPMContext(model.getSubAlloc().getHeap()); 151 | pc.setAddress(model.getSubAlloc().allocContext()); 152 | if (pc != null) { 153 | pc.setNumStats(1); 154 | pc.setOneState(firstState); 155 | pc.setSuffix(this); 156 | pStats.setSuccessor(pc); 157 | } 158 | return pc.getAddress(); 159 | } 160 | 161 | public void rescale(ModelPPM model) 162 | { 163 | int OldNS = getNumStats(), i = getNumStats() - 1, Adder, EscFreq; 164 | // STATE* p1, * p; 165 | State p1 = new State(model.getHeap()); 166 | State p = new State(model.getHeap()); 167 | State temp = new State(model.getHeap()); 168 | 169 | for (p.setAddress(model.getFoundState().getAddress()); 170 | p.getAddress() != freqData.getStats(); 171 | p.decAddress()) { 172 | temp.setAddress(p.getAddress() - State.size); 173 | State.ppmdSwap(p, temp); 174 | } 175 | temp.setAddress(freqData.getStats()); 176 | temp.incFreq(4); 177 | freqData.incSummFreq(4); 178 | EscFreq = freqData.getSummFreq() - p.getFreq(); 179 | Adder = (model.getOrderFall() != 0) ? 1 : 0; 180 | p.setFreq((p.getFreq() + Adder) >>> 1); 181 | freqData.setSummFreq(p.getFreq()); 182 | do { 183 | p.incAddress(); 184 | EscFreq -= p.getFreq(); 185 | p.setFreq((p.getFreq() + Adder) >>> 1); 186 | freqData.incSummFreq(p.getFreq()); 187 | temp.setAddress(p.getAddress() - State.size); 188 | if (p.getFreq() > temp.getFreq()) { 189 | p1.setAddress(p.getAddress()); 190 | StateRef tmp = new StateRef(); 191 | tmp.setValues(p1); 192 | State temp2 = new State(model.getHeap()); 193 | State temp3 = new State(model.getHeap()); 194 | do { 195 | // p1[0]=p1[-1]; 196 | temp2.setAddress(p1.getAddress() - State.size); 197 | p1.setValues(temp2); 198 | p1.decAddress(); 199 | temp3.setAddress(p1.getAddress() - State.size); 200 | } while (p1.getAddress() != freqData.getStats() && tmp.getFreq() > temp3.getFreq()); 201 | p1.setValues(tmp); 202 | } 203 | } while (--i != 0); 204 | if (p.getFreq() == 0) { 205 | do { 206 | i++; 207 | p.decAddress(); 208 | } while (p.getFreq() == 0); 209 | EscFreq += i; 210 | setNumStats(getNumStats() - i); 211 | if (getNumStats() == 1) { 212 | StateRef tmp = new StateRef(); 213 | temp.setAddress(freqData.getStats()); 214 | tmp.setValues(temp); 215 | // STATE tmp=*U.Stats; 216 | do { 217 | // tmp.Freq-=(tmp.Freq >> 1) 218 | tmp.decFreq(tmp.getFreq() >>> 1); 219 | EscFreq >>>= 1; 220 | } while (EscFreq > 1); 221 | model.getSubAlloc().freeUnits(freqData.getStats(),(OldNS + 1) >>> 1); 222 | oneState.setValues(tmp); 223 | model.getFoundState().setAddress(oneState.getAddress()); 224 | return; 225 | } 226 | } 227 | EscFreq -= EscFreq >>> 1; 228 | freqData.incSummFreq(EscFreq); 229 | int n0 = (OldNS + 1) >>> 1, n1 = (getNumStats() + 1) >>> 1; 230 | if (n0 != n1) { 231 | freqData.setStats(model.getSubAlloc().shrinkUnits(freqData.getStats(), n0, n1)); 232 | } 233 | model.getFoundState().setAddress(freqData.getStats()); 234 | } 235 | 236 | private int getArrayIndex(ModelPPM Model, State rs) 237 | { 238 | PPMContext tempSuffix = getTempPPMContext(Model.getSubAlloc().getHeap()); 239 | tempSuffix.setAddress(getSuffix()); 240 | int ret = 0; 241 | ret += Model.getPrevSuccess(); 242 | ret += Model.getNS2BSIndx()[tempSuffix.getNumStats() - 1]; 243 | ret += Model.getHiBitsFlag() + 2* Model.getHB2Flag()[rs.getSymbol()]; 244 | ret += ((Model.getRunLength() >>> 26) & 0x20); 245 | return ret; 246 | } 247 | 248 | public int getMean(int summ, int shift, int round) 249 | { 250 | return ( (summ + (1 << (shift - round) ) ) >>> (shift) ); 251 | } 252 | 253 | public void decodeBinSymbol(ModelPPM model) 254 | { 255 | State rs = tempState1.init(model.getHeap()); 256 | rs.setAddress(oneState.getAddress());// State& 257 | model.setHiBitsFlag(model.getHB2Flag()[model.getFoundState().getSymbol()]); 258 | int off1 = rs.getFreq() - 1; 259 | int off2 = getArrayIndex(model, rs); 260 | int bs = model.getBinSumm()[off1][off2]; 261 | if (model.getCoder().getCurrentShiftCount(ModelPPM.TOT_BITS) < bs) { 262 | model.getFoundState().setAddress(rs.getAddress()); 263 | rs.incFreq((rs.getFreq() < 128) ? 1 : 0); 264 | model.getCoder().getSubRange().setLowCount(0); 265 | model.getCoder().getSubRange().setHighCount(bs); 266 | bs = ((bs + ModelPPM.INTERVAL - getMean(bs, ModelPPM.PERIOD_BITS, 2)) & 0xffff); 267 | model.getBinSumm()[off1][off2] = bs; 268 | model.setPrevSuccess(1); 269 | model.incRunLength(1); 270 | } else { 271 | model.getCoder().getSubRange().setLowCount(bs); 272 | bs = (bs - getMean(bs, ModelPPM.PERIOD_BITS, 2)) & 0xFFFF; 273 | model.getBinSumm()[off1][off2] = bs; 274 | model.getCoder().getSubRange().setHighCount(ModelPPM.BIN_SCALE); 275 | model.setInitEsc(ExpEscape[bs >>> 10]); 276 | model.setNumMasked(1); 277 | model.getCharMask()[rs.getSymbol()] = model.getEscCount(); 278 | model.setPrevSuccess(0); 279 | model.getFoundState().setAddress(0); 280 | } 281 | //int a = 0;//TODO just 4 debugging 282 | } 283 | 284 | // public static void ppmdSwap(ModelPPM model, StatePtr state1, StatePtr state2) 285 | // { 286 | // byte[] bytes = model.getSubAlloc().getHeap(); 287 | // int p1 = state1.getAddress(); 288 | // int p2 = state2.getAddress(); 289 | // 290 | // for (int i = 0; i < StatePtr.size; i++) { 291 | // byte temp = bytes[p1+i]; 292 | // bytes[p1+i] = bytes[p2+i]; 293 | // bytes[p2+i] = temp; 294 | // } 295 | // state1.setAddress(p1); 296 | // state2.setAddress(p2); 297 | // } 298 | 299 | public void update1(ModelPPM model, int p/* ptr */) 300 | { 301 | model.getFoundState().setAddress(p); 302 | model.getFoundState().incFreq(4); 303 | freqData.incSummFreq(4); 304 | State p0 = tempState3.init(model.getHeap()); 305 | State p1 = tempState4.init(model.getHeap()); 306 | p0.setAddress(p); 307 | p1.setAddress(p - State.size); 308 | if (p0.getFreq() > p1.getFreq()) { 309 | State.ppmdSwap(p0, p1); 310 | model.getFoundState().setAddress(p1.getAddress()); 311 | if (p1.getFreq() > ModelPPM.MAX_FREQ) 312 | rescale(model); 313 | } 314 | } 315 | 316 | public boolean decodeSymbol2(ModelPPM model) 317 | { 318 | long count; 319 | int hiCnt, i = getNumStats() - model.getNumMasked(); 320 | SEE2Context psee2c = makeEscFreq2(model, i); 321 | RangeCoder coder = model.getCoder(); 322 | // STATE* ps[256], ** pps=ps, * p=U.Stats-1; 323 | State p = tempState1.init(model.getHeap()); 324 | State temp = tempState2.init(model.getHeap()); 325 | p.setAddress(freqData.getStats() - State.size); 326 | int pps = 0; 327 | hiCnt = 0; 328 | 329 | do { 330 | do { 331 | p.incAddress();// p++; 332 | } while (model.getCharMask()[p.getSymbol()] == model.getEscCount()); 333 | hiCnt += p.getFreq(); 334 | ps[pps++] = p.getAddress(); 335 | } while (--i != 0); 336 | coder.getSubRange().incScale(hiCnt); 337 | count = coder.getCurrentCount(); 338 | if (count >= coder.getSubRange().getScale()) { 339 | return false; 340 | } 341 | pps = 0; 342 | p.setAddress(ps[pps]); 343 | if (count < hiCnt) { 344 | hiCnt = 0; 345 | while ((hiCnt += p.getFreq()) <= count) { 346 | p.setAddress(ps[++pps]);// p=*++pps; 347 | } 348 | coder.getSubRange().setHighCount(hiCnt); 349 | coder.getSubRange().setLowCount(hiCnt - p.getFreq()); 350 | psee2c.update(); 351 | update2(model, p.getAddress()); 352 | } else { 353 | coder.getSubRange().setLowCount(hiCnt); 354 | coder.getSubRange().setHighCount(coder.getSubRange().getScale()); 355 | i = getNumStats() - model.getNumMasked();// ->NumMasked; 356 | pps--; 357 | do { 358 | temp.setAddress(ps[++pps]);// (*++pps) 359 | model.getCharMask()[temp.getSymbol()] = model.getEscCount(); 360 | } while (--i != 0); 361 | psee2c.incSumm((int)coder.getSubRange().getScale()); 362 | model.setNumMasked(getNumStats()); 363 | } 364 | return (true); 365 | } 366 | 367 | public void update2(ModelPPM model, int p/* state ptr */) 368 | { 369 | State temp = tempState5.init(model.getHeap()); 370 | temp.setAddress(p); 371 | model.getFoundState().setAddress(p); 372 | model.getFoundState().incFreq(4); 373 | freqData.incSummFreq(4); 374 | if (temp.getFreq() > ModelPPM.MAX_FREQ) { 375 | rescale(model); 376 | } 377 | model.incEscCount(1); 378 | model.setRunLength(model.getInitRL()); 379 | } 380 | 381 | private SEE2Context makeEscFreq2(ModelPPM model, int Diff) 382 | { 383 | SEE2Context psee2c; 384 | int numStats = getNumStats(); 385 | if (numStats != 256) { 386 | PPMContext suff = getTempPPMContext(model.getHeap()); 387 | suff.setAddress(getSuffix()); 388 | int idx1 = model.getNS2Indx()[Diff - 1]; 389 | int idx2 = 0; 390 | idx2 += (Diff < suff.getNumStats() - numStats) ? 1 : 0; 391 | idx2 += 2 * ((freqData.getSummFreq() < 11 * numStats) ? 1 : 0); 392 | idx2 += 4 * ((model.getNumMasked() > Diff) ? 1 : 0); 393 | idx2 += model.getHiBitsFlag(); 394 | psee2c = model.getSEE2Cont()[idx1][idx2]; 395 | model.getCoder().getSubRange().setScale(psee2c.getMean()); 396 | } else { 397 | psee2c = model.getDummySEE2Cont(); 398 | model.getCoder().getSubRange().setScale(1); 399 | } 400 | return psee2c; 401 | } 402 | 403 | public boolean decodeSymbol1(ModelPPM model) 404 | { 405 | 406 | RangeCoder coder = model.getCoder(); 407 | coder.getSubRange().setScale(freqData.getSummFreq()); 408 | State p = new State(model.getHeap()); 409 | p.setAddress(freqData.getStats()); 410 | int i, HiCnt; 411 | long count = coder.getCurrentCount(); 412 | if (count >= coder.getSubRange().getScale()) { 413 | return false; 414 | } 415 | if (count < (HiCnt = p.getFreq())) { 416 | coder.getSubRange().setHighCount(HiCnt); 417 | model.setPrevSuccess((2 * HiCnt > coder.getSubRange().getScale()) ? 1 : 0); 418 | model.incRunLength(model.getPrevSuccess()); 419 | HiCnt += 4; 420 | model.getFoundState().setAddress(p.getAddress()); 421 | model.getFoundState().setFreq(HiCnt); 422 | freqData.incSummFreq(4); 423 | if (HiCnt > ModelPPM.MAX_FREQ) { 424 | rescale(model); 425 | } 426 | coder.getSubRange().setLowCount(0); 427 | return true; 428 | } else { 429 | if (model.getFoundState().getAddress() == 0) { 430 | return (false); 431 | } 432 | } 433 | model.setPrevSuccess(0); 434 | int numStats = getNumStats(); 435 | i = numStats - 1; 436 | while ((HiCnt += p.incAddress().getFreq()) <= count) 437 | { 438 | if (--i == 0) { 439 | model.setHiBitsFlag(model.getHB2Flag()[model.getFoundState().getSymbol()]); 440 | coder.getSubRange().setLowCount(HiCnt); 441 | model.getCharMask()[p.getSymbol()] = model.getEscCount(); 442 | model.setNumMasked(numStats); 443 | i = numStats - 1; 444 | model.getFoundState().setAddress(0); 445 | do { 446 | model.getCharMask()[p.decAddress().getSymbol()] = model.getEscCount(); 447 | } while (--i != 0); 448 | coder.getSubRange().setHighCount(coder.getSubRange().getScale()); 449 | return (true); 450 | } 451 | } 452 | coder.getSubRange().setLowCount(HiCnt-p.getFreq()); 453 | coder.getSubRange().setHighCount(HiCnt); 454 | update1(model, p.getAddress()); 455 | return (true); 456 | } 457 | 458 | public String toString() { 459 | StringBuilder buffer = new StringBuilder(); 460 | buffer.append("PPMContext["); 461 | buffer.append("\n pos="); 462 | buffer.append(pos); 463 | buffer.append("\n size="); 464 | buffer.append(size); 465 | buffer.append("\n numStats="); 466 | buffer.append(getNumStats()); 467 | buffer.append("\n Suffix="); 468 | buffer.append(getSuffix()); 469 | buffer.append("\n freqData="); 470 | buffer.append(freqData); 471 | buffer.append("\n oneState="); 472 | buffer.append(oneState); 473 | buffer.append("\n]"); 474 | return buffer.toString(); 475 | } 476 | 477 | } 478 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/ppm/Pointer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 14.06.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.ppm; 19 | 20 | /** 21 | * Simulates Pointers on a single mem block as a byte[] 22 | * 23 | * @author $LastChangedBy$ 24 | * @version $LastChangedRevision$ 25 | */ 26 | public abstract class Pointer 27 | { 28 | protected byte[] mem; 29 | protected int pos; 30 | 31 | /** 32 | * Initialize the object with the array (may be null) 33 | * @param mem the byte array 34 | */ 35 | public Pointer(byte[] mem){ 36 | this.mem = mem; 37 | } 38 | /** 39 | * returns the position of this object in the byte[] 40 | * @return the address of this object 41 | */ 42 | public int getAddress(){ 43 | assert (mem != null); 44 | return pos; 45 | } 46 | 47 | /** 48 | * needs to set the fields of this object to the values in the byte[] 49 | * at the given position. 50 | * be aware of the byte order 51 | * @param pos the position this object should point to 52 | * @return true if the address could be set 53 | */ 54 | public void setAddress(int pos) { 55 | assert (mem != null); 56 | assert (pos >= 0) && (pos < mem.length) : pos; 57 | this.pos = pos; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/ppm/RangeCoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 31.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.ppm; 19 | 20 | import java.io.IOException; 21 | 22 | import de.innosystec.unrar.exception.RarException; 23 | import de.innosystec.unrar.unpack.Unpack; 24 | 25 | /** 26 | * DOCUMENT ME 27 | * 28 | * @author $LastChangedBy$ 29 | * @version $LastChangedRevision$ 30 | */ 31 | public class RangeCoder 32 | { 33 | public static final int TOP = 1 << 24; 34 | 35 | public static final int BOT = 1 << 15; 36 | 37 | private static final long uintMask = 0xFFFFffffL; 38 | 39 | // uint low, code, range; 40 | private long low, code, range; 41 | 42 | private final SubRange subRange = new SubRange(); 43 | 44 | private Unpack unpackRead; 45 | 46 | public SubRange getSubRange() 47 | { 48 | return subRange; 49 | } 50 | 51 | public void initDecoder(Unpack unpackRead) throws IOException, RarException 52 | { 53 | this.unpackRead = unpackRead; 54 | 55 | low = code = 0L; 56 | range = 0xFFFFffffL; 57 | for (int i = 0; i < 4; i++) { 58 | code = ((code << 8) | getChar())&uintMask; 59 | } 60 | } 61 | 62 | public int getCurrentCount() 63 | { 64 | range = (range / subRange.getScale())&uintMask; 65 | return (int)((code - low) / (range)); 66 | } 67 | 68 | public long getCurrentShiftCount(int SHIFT) 69 | { 70 | range = range >>>SHIFT; 71 | return ((code - low) / (range))&uintMask; 72 | } 73 | 74 | public void decode() 75 | { 76 | low = (low + (range * subRange.getLowCount()))&uintMask; 77 | range = (range * (subRange.getHighCount() - subRange.getLowCount()))&uintMask; 78 | } 79 | 80 | private int getChar() throws IOException, RarException 81 | { 82 | return (unpackRead.getChar()); 83 | } 84 | 85 | public void ariDecNormalize() throws IOException, RarException 86 | { 87 | // while ((low ^ (low + range)) < TOP || range < BOT && ((range = -low & (BOT - 1)) != 0 ? true : true)) 88 | // { 89 | // code = ((code << 8) | unpackRead.getChar()&0xff)&uintMask; 90 | // range = (range << 8)&uintMask; 91 | // low = (low << 8)&uintMask; 92 | // } 93 | 94 | // Rewrote for clarity 95 | boolean c2 = false; 96 | while ((low ^ (low + range)) < TOP || (c2 = range < BOT)) { 97 | if (c2) { 98 | range = (-low & (BOT - 1))&uintMask; 99 | c2 = false; 100 | } 101 | code = ((code << 8) | getChar())&uintMask; 102 | range = (range << 8)&uintMask; 103 | low = (low << 8)&uintMask; 104 | } 105 | } 106 | 107 | // Debug 108 | public String toString() { 109 | StringBuilder buffer = new StringBuilder(); 110 | buffer.append("RangeCoder["); 111 | buffer.append("\n low="); 112 | buffer.append(low); 113 | buffer.append("\n code="); 114 | buffer.append(code); 115 | buffer.append("\n range="); 116 | buffer.append(range); 117 | buffer.append("\n subrange="); 118 | buffer.append(subRange); 119 | buffer.append("]"); 120 | return buffer.toString(); 121 | } 122 | 123 | public static class SubRange 124 | { 125 | // uint LowCount, HighCount, scale; 126 | private long lowCount, highCount, scale; 127 | 128 | public long getHighCount() 129 | { 130 | return highCount; 131 | } 132 | 133 | public void setHighCount(long highCount) 134 | { 135 | this.highCount = highCount&uintMask; 136 | } 137 | 138 | public long getLowCount() 139 | { 140 | return lowCount&uintMask; 141 | } 142 | 143 | public void setLowCount(long lowCount) 144 | { 145 | this.lowCount = lowCount&uintMask; 146 | } 147 | 148 | public long getScale() 149 | { 150 | return scale; 151 | } 152 | 153 | public void setScale(long scale) 154 | { 155 | this.scale = scale&uintMask; 156 | } 157 | 158 | public void incScale(int dScale) { 159 | setScale(getScale() + dScale); 160 | } 161 | 162 | // Debug 163 | public String toString() { 164 | StringBuilder buffer = new StringBuilder(); 165 | buffer.append("SubRange["); 166 | buffer.append("\n lowCount="); 167 | buffer.append(lowCount); 168 | buffer.append("\n highCount="); 169 | buffer.append(highCount); 170 | buffer.append("\n scale="); 171 | buffer.append(scale); 172 | buffer.append("]"); 173 | return buffer.toString(); 174 | } 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/ppm/RarMemBlock.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 05.06.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.ppm; 19 | 20 | import de.innosystec.unrar.io.Raw; 21 | 22 | 23 | 24 | /** 25 | * DOCUMENT ME 26 | * 27 | * @author $LastChangedBy$ 28 | * @version $LastChangedRevision$ 29 | */ 30 | public class RarMemBlock extends Pointer 31 | { 32 | 33 | public static final int size = 12; 34 | 35 | private int stamp, NU; 36 | 37 | private int next, prev; // Pointer RarMemBlock 38 | 39 | public RarMemBlock(byte[] mem) 40 | { 41 | super(mem); 42 | } 43 | 44 | public void insertAt(RarMemBlock p) 45 | { 46 | RarMemBlock temp = new RarMemBlock(mem); 47 | setPrev(p.getAddress()); 48 | temp.setAddress(getPrev()); 49 | setNext(temp.getNext());// prev.getNext(); 50 | temp.setNext(this);// prev.setNext(this); 51 | temp.setAddress(getNext()); 52 | temp.setPrev(this);// next.setPrev(this); 53 | } 54 | 55 | public void remove() 56 | { 57 | RarMemBlock temp = new RarMemBlock(mem); 58 | temp.setAddress(getPrev()); 59 | temp.setNext(getNext());// prev.setNext(next); 60 | temp.setAddress(getNext()); 61 | temp.setPrev(getPrev());// next.setPrev(prev); 62 | // next = -1; 63 | // prev = -1; 64 | } 65 | 66 | public int getNext() 67 | { 68 | if(mem!=null){ 69 | next = Raw.readIntLittleEndian(mem, pos+4); 70 | } 71 | return next; 72 | } 73 | 74 | public void setNext(RarMemBlock next) 75 | { 76 | setNext(next.getAddress()); 77 | } 78 | 79 | public void setNext(int next) 80 | { 81 | this.next = next; 82 | if (mem != null) { 83 | Raw.writeIntLittleEndian(mem, pos + 4, next); 84 | } 85 | } 86 | 87 | public int getNU() 88 | { 89 | if(mem!=null){ 90 | NU = Raw.readShortLittleEndian(mem, pos+2)&0xffff; 91 | } 92 | return NU; 93 | } 94 | 95 | public void setNU(int nu) 96 | { 97 | NU = nu&0xffff; 98 | if (mem != null) { 99 | Raw.writeShortLittleEndian(mem, pos + 2, (short)nu); 100 | } 101 | } 102 | 103 | public int getPrev() 104 | { 105 | if(mem!=null){ 106 | prev = Raw.readIntLittleEndian(mem, pos+8); 107 | } 108 | return prev; 109 | } 110 | 111 | public void setPrev(RarMemBlock prev) 112 | { 113 | setPrev(prev.getAddress()); 114 | } 115 | 116 | public void setPrev(int prev) 117 | { 118 | this.prev = prev; 119 | if (mem != null) { 120 | Raw.writeIntLittleEndian(mem, pos + 8, prev); 121 | } 122 | } 123 | 124 | public int getStamp() 125 | { 126 | if(mem!=null){ 127 | stamp = Raw.readShortLittleEndian(mem, pos)&0xffff; 128 | } 129 | return stamp; 130 | } 131 | 132 | public void setStamp(int stamp) 133 | { 134 | this.stamp = stamp; 135 | if (mem != null) { 136 | Raw.writeShortLittleEndian(mem, pos, (short)stamp); 137 | } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/ppm/RarNode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 05.06.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.ppm; 19 | 20 | import de.innosystec.unrar.io.Raw; 21 | 22 | 23 | 24 | /** 25 | * DOCUMENT ME 26 | * 27 | * @author $LastChangedBy$ 28 | * @version $LastChangedRevision$ 29 | */ 30 | public class RarNode extends Pointer{ 31 | private int next; //rarnode pointer 32 | 33 | public static final int size = 4; 34 | 35 | public RarNode(byte[] mem){ 36 | super(mem); 37 | } 38 | 39 | public int getNext() { 40 | if(mem!=null){ 41 | next = Raw.readIntLittleEndian(mem, pos); 42 | } 43 | return next; 44 | } 45 | 46 | public void setNext(RarNode next) { 47 | setNext(next.getAddress()); 48 | } 49 | 50 | public void setNext(int next) { 51 | this.next = next; 52 | if(mem!=null){ 53 | Raw.writeIntLittleEndian(mem, pos, next); 54 | } 55 | } 56 | 57 | public String toString() { 58 | StringBuilder buffer = new StringBuilder(); 59 | buffer.append("State["); 60 | buffer.append("\n pos="); 61 | buffer.append(pos); 62 | buffer.append("\n size="); 63 | buffer.append(size); 64 | buffer.append("\n next="); 65 | buffer.append(getNext()); 66 | buffer.append("\n]"); 67 | return buffer.toString(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/ppm/SEE2Context.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 31.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.ppm; 19 | 20 | /** 21 | * DOCUMENT ME 22 | * 23 | * @author $LastChangedBy$ 24 | * @version $LastChangedRevision$ 25 | */ 26 | public class SEE2Context { 27 | public static final int size = 4; 28 | 29 | // ushort Summ; 30 | private int summ; 31 | 32 | // byte Shift; 33 | private int shift; 34 | 35 | // byte Count; 36 | private int count; 37 | 38 | public void init(int initVal) { 39 | shift = (ModelPPM.PERIOD_BITS - 4)&0xff; 40 | summ = (initVal << shift)&0xffff; 41 | count = 4; 42 | } 43 | 44 | public int getMean() { 45 | int retVal = summ >>> shift; 46 | summ -= retVal; 47 | return retVal + ((retVal == 0) ? 1 : 0); 48 | } 49 | 50 | public void update() { 51 | if (shift < ModelPPM.PERIOD_BITS && --count == 0) { 52 | summ += summ; 53 | count = (3 << shift++); 54 | } 55 | summ &= 0xffff; 56 | count &= 0xff; 57 | shift &= 0xff; 58 | } 59 | 60 | public int getCount() { 61 | return count; 62 | } 63 | 64 | public void setCount(int count) { 65 | this.count = count&0xff; 66 | } 67 | 68 | public int getShift() { 69 | return shift; 70 | } 71 | 72 | public void setShift(int shift) { 73 | this.shift = shift&0xff; 74 | } 75 | 76 | public int getSumm() { 77 | return summ; 78 | } 79 | 80 | public void setSumm(int summ) { 81 | this.summ = summ&0xffff; 82 | } 83 | 84 | public void incSumm(int dSumm) { 85 | setSumm(getSumm() + dSumm); 86 | } 87 | 88 | public String toString() { 89 | StringBuilder buffer = new StringBuilder(); 90 | buffer.append("SEE2Context["); 91 | buffer.append("\n size="); 92 | buffer.append(size); 93 | buffer.append("\n summ="); 94 | buffer.append(summ); 95 | buffer.append("\n shift="); 96 | buffer.append(shift); 97 | buffer.append("\n count="); 98 | buffer.append(count); 99 | buffer.append("\n]"); 100 | return buffer.toString(); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/ppm/State.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 01.06.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.ppm; 19 | 20 | import de.innosystec.unrar.io.Raw; 21 | 22 | /** 23 | * DOCUMENT ME 24 | * 25 | * @author $LastChangedBy$ 26 | * @version $LastChangedRevision$ 27 | */ 28 | public class State extends Pointer { 29 | 30 | public static final int size = 6; 31 | 32 | public State(byte[] mem) { 33 | super(mem); 34 | } 35 | 36 | public State init(byte[] mem) { 37 | this.mem = mem; 38 | pos = 0; 39 | return this; 40 | } 41 | 42 | public int getSymbol() { 43 | return mem[pos]&0xff; 44 | } 45 | 46 | public void setSymbol(int symbol) { 47 | mem[pos] = (byte)symbol; 48 | } 49 | 50 | public int getFreq() { 51 | return mem[pos+1]&0xff; 52 | } 53 | 54 | public void setFreq(int freq) { 55 | mem[pos + 1] = (byte)freq; 56 | } 57 | 58 | public void incFreq(int dFreq) { 59 | mem[pos + 1] += dFreq; 60 | } 61 | 62 | public int getSuccessor() { 63 | return Raw.readIntLittleEndian(mem, pos+2); 64 | } 65 | 66 | public void setSuccessor(PPMContext successor) { 67 | setSuccessor(successor.getAddress()); 68 | } 69 | 70 | public void setSuccessor(int successor) { 71 | Raw.writeIntLittleEndian(mem, pos + 2, successor); 72 | } 73 | 74 | public void setValues(StateRef state){ 75 | setSymbol(state.getSymbol()); 76 | setFreq(state.getFreq()); 77 | setSuccessor(state.getSuccessor()); 78 | } 79 | 80 | public void setValues(State ptr){ 81 | System.arraycopy(ptr.mem, ptr.pos, mem, pos, size); 82 | } 83 | 84 | public State decAddress(){ 85 | setAddress(pos-size); 86 | return this; 87 | } 88 | 89 | public State incAddress(){ 90 | setAddress(pos+size); 91 | return this; 92 | } 93 | 94 | public static void ppmdSwap(State ptr1, State ptr2) { 95 | byte[] mem1=ptr1.mem, mem2=ptr2.mem; 96 | for (int i=0, pos1=ptr1.pos, pos2=ptr2.pos; i < size; i++, pos1++, pos2++) { 97 | byte temp = mem1[pos1]; 98 | mem1[pos1] = mem2[pos2]; 99 | mem2[pos2] = temp; 100 | } 101 | } 102 | 103 | public String toString() { 104 | StringBuilder buffer = new StringBuilder(); 105 | buffer.append("State["); 106 | buffer.append("\n pos="); 107 | buffer.append(pos); 108 | buffer.append("\n size="); 109 | buffer.append(size); 110 | buffer.append("\n symbol="); 111 | buffer.append(getSymbol()); 112 | buffer.append("\n freq="); 113 | buffer.append(getFreq()); 114 | buffer.append("\n successor="); 115 | buffer.append(getSuccessor()); 116 | buffer.append("\n]"); 117 | return buffer.toString(); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/ppm/StateRef.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 01.06.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.ppm; 19 | 20 | 21 | /** 22 | * DOCUMENT ME 23 | * 24 | * @author $LastChangedBy$ 25 | * @version $LastChangedRevision$ 26 | */ 27 | public class StateRef { 28 | 29 | private int symbol; 30 | 31 | private int freq; 32 | 33 | private int successor; // pointer ppmcontext 34 | 35 | public StateRef() { 36 | } 37 | 38 | public int getSymbol() { 39 | return symbol; 40 | } 41 | 42 | public void setSymbol(int symbol) { 43 | this.symbol = symbol&0xff; 44 | } 45 | 46 | public int getFreq() { 47 | return freq; 48 | } 49 | 50 | public void setFreq(int freq) { 51 | this.freq = freq&0xff; 52 | } 53 | 54 | public void incFreq(int dFreq) { 55 | freq = (freq + dFreq)&0xff; 56 | } 57 | 58 | public void decFreq(int dFreq) { 59 | freq = (freq - dFreq)&0xff; 60 | } 61 | 62 | public void setValues(State statePtr){ 63 | setFreq(statePtr.getFreq()); 64 | setSuccessor(statePtr.getSuccessor()); 65 | setSymbol(statePtr.getSymbol()); 66 | } 67 | 68 | public int getSuccessor() { 69 | return successor; 70 | } 71 | 72 | public void setSuccessor(PPMContext successor) { 73 | setSuccessor(successor.getAddress()); 74 | } 75 | 76 | public void setSuccessor(int successor) { 77 | this.successor = successor; 78 | } 79 | 80 | public String toString() { 81 | StringBuilder buffer = new StringBuilder(); 82 | buffer.append("State["); 83 | buffer.append("\n symbol="); 84 | buffer.append(getSymbol()); 85 | buffer.append("\n freq="); 86 | buffer.append(getFreq()); 87 | buffer.append("\n successor="); 88 | buffer.append(getSuccessor()); 89 | buffer.append("\n]"); 90 | return buffer.toString(); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/ppm/SubAllocator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 31.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.ppm; 19 | 20 | import java.util.Arrays; 21 | 22 | /** 23 | * DOCUMENT ME 24 | * 25 | * @author $LastChangedBy$ 26 | * @version $LastChangedRevision$ 27 | */ 28 | public class SubAllocator { 29 | public static final int N1 = 4, N2 = 4, N3 = 4, N4 = (128 + 3 - 1 * N1 - 2 30 | * N2 - 3 * N3) / 4; 31 | 32 | public static final int N_INDEXES = N1 + N2 + N3 + N4; 33 | 34 | public static final int UNIT_SIZE = Math.max(PPMContext.size, 35 | RarMemBlock.size); 36 | 37 | public static final int FIXED_UNIT_SIZE = 12; 38 | 39 | private int subAllocatorSize; 40 | 41 | // byte Indx2Units[N_INDEXES], Units2Indx[128], GlueCount; 42 | private int[] indx2Units = new int[N_INDEXES]; 43 | private int[] units2Indx = new int[128]; 44 | private int glueCount; 45 | 46 | // byte *HeapStart,*LoUnit, *HiUnit; 47 | private int heapStart, loUnit, hiUnit; 48 | 49 | private final RarNode[] freeList = new RarNode[N_INDEXES]; 50 | 51 | // byte *pText, *UnitsStart,*HeapEnd,*FakeUnitsStart; 52 | private int pText, unitsStart, heapEnd, fakeUnitsStart; 53 | 54 | private byte[] heap; 55 | 56 | private int freeListPos; 57 | 58 | private int tempMemBlockPos; 59 | 60 | // Temp fields 61 | private RarNode tempRarNode = null; 62 | private RarMemBlock tempRarMemBlock1 = null; 63 | private RarMemBlock tempRarMemBlock2 = null; 64 | private RarMemBlock tempRarMemBlock3 = null; 65 | 66 | public SubAllocator() { 67 | clean(); 68 | } 69 | 70 | public void clean() { 71 | subAllocatorSize = 0; 72 | } 73 | 74 | private void insertNode(int p/* rarnode ptr */, int indx) { 75 | RarNode temp = tempRarNode; 76 | temp.setAddress(p); 77 | temp.setNext(freeList[indx].getNext()); 78 | freeList[indx].setNext(temp); 79 | } 80 | 81 | public void incPText() { 82 | pText++; 83 | } 84 | 85 | private int removeNode(int indx) { 86 | int retVal = freeList[indx].getNext(); 87 | RarNode temp = tempRarNode; 88 | temp.setAddress(retVal); 89 | freeList[indx].setNext(temp.getNext()); 90 | return retVal; 91 | } 92 | 93 | private int U2B(int NU) { 94 | return /* 8*NU+4*NU */UNIT_SIZE * NU; 95 | } 96 | 97 | /* memblockptr */ 98 | private int MBPtr(int BasePtr, int Items) { 99 | return (BasePtr + U2B(Items)); 100 | } 101 | 102 | private void splitBlock(int pv/* ptr */, int oldIndx, int newIndx) { 103 | int i, uDiff = indx2Units[oldIndx] - indx2Units[newIndx]; 104 | int p = pv + U2B(indx2Units[newIndx]); 105 | if (indx2Units[i = units2Indx[uDiff - 1]] != uDiff) { 106 | insertNode(p, --i); 107 | p += U2B(i = indx2Units[i]); 108 | uDiff -= i; 109 | } 110 | insertNode(p, units2Indx[uDiff - 1]); 111 | } 112 | 113 | public void stopSubAllocator() { 114 | if (subAllocatorSize != 0) { 115 | subAllocatorSize = 0; 116 | heap = null; 117 | heapStart = 1; 118 | // rarfree(HeapStart); 119 | // Free temp fields 120 | tempRarNode = null; 121 | tempRarMemBlock1 = null; 122 | tempRarMemBlock2 = null; 123 | tempRarMemBlock3 = null; 124 | } 125 | } 126 | 127 | public int GetAllocatedMemory() { 128 | return subAllocatorSize; 129 | }; 130 | 131 | public boolean startSubAllocator(int SASize) { 132 | int t = SASize << 20; 133 | if (subAllocatorSize == t) { 134 | return true; 135 | } 136 | stopSubAllocator(); 137 | int allocSize = t / FIXED_UNIT_SIZE * UNIT_SIZE + UNIT_SIZE; 138 | 139 | // adding space for freelist (needed for poiters) 140 | // 1+ for null pointer 141 | int realAllocSize = 1 + allocSize + 4 * N_INDEXES; 142 | // adding space for an additional memblock 143 | tempMemBlockPos = realAllocSize; 144 | realAllocSize += RarMemBlock.size; 145 | 146 | heap = new byte[realAllocSize]; 147 | heapStart = 1; 148 | heapEnd = heapStart + allocSize - UNIT_SIZE; 149 | subAllocatorSize = t; 150 | // Bug fixed 151 | freeListPos = heapStart + allocSize; 152 | assert (realAllocSize - tempMemBlockPos == RarMemBlock.size) : realAllocSize 153 | + " " + tempMemBlockPos + " " + RarMemBlock.size; 154 | 155 | // Init freeList 156 | for (int i = 0, pos = freeListPos; i < freeList.length; i++, pos += RarNode.size) { 157 | freeList[i] = new RarNode(heap); 158 | freeList[i].setAddress(pos); 159 | } 160 | 161 | // Init temp fields 162 | tempRarNode = new RarNode(heap); 163 | tempRarMemBlock1 = new RarMemBlock(heap); 164 | tempRarMemBlock2 = new RarMemBlock(heap); 165 | tempRarMemBlock3 = new RarMemBlock(heap); 166 | 167 | return true; 168 | } 169 | 170 | private void glueFreeBlocks() { 171 | RarMemBlock s0 = tempRarMemBlock1; 172 | s0.setAddress(tempMemBlockPos); 173 | RarMemBlock p = tempRarMemBlock2; 174 | RarMemBlock p1 = tempRarMemBlock3; 175 | int i, k, sz; 176 | if (loUnit != hiUnit) { 177 | heap[loUnit] = 0; 178 | } 179 | for (i = 0, s0.setPrev(s0), s0.setNext(s0); i < N_INDEXES; i++) { 180 | while (freeList[i].getNext() != 0) { 181 | p.setAddress(removeNode(i));// =(RAR_MEM_BLK*)RemoveNode(i); 182 | p.insertAt(s0);// p->insertAt(&s0); 183 | p.setStamp(0xFFFF);// p->Stamp=0xFFFF; 184 | p.setNU(indx2Units[i]);// p->NU=Indx2Units[i]; 185 | } 186 | } 187 | for (p.setAddress(s0.getNext()); p.getAddress() != s0.getAddress(); p 188 | .setAddress(p.getNext())) { 189 | // while ((p1=MBPtr(p,p->NU))->Stamp == 0xFFFF && int(p->NU)+p1->NU 190 | // < 0x10000) 191 | // Bug fixed 192 | p1.setAddress(MBPtr(p.getAddress(), p.getNU())); 193 | while (p1.getStamp() == 0xFFFF && p.getNU() + p1.getNU() < 0x10000) { 194 | p1.remove(); 195 | p.setNU(p.getNU() + p1.getNU());// ->NU += p1->NU; 196 | p1.setAddress(MBPtr(p.getAddress(), p.getNU())); 197 | } 198 | } 199 | // while ((p=s0.next) != &s0) 200 | // Bug fixed 201 | p.setAddress(s0.getNext()); 202 | while (p.getAddress() != s0.getAddress()) { 203 | for (p.remove(), sz = p.getNU(); sz > 128; sz -= 128, p 204 | .setAddress(MBPtr(p.getAddress(), 128))) { 205 | insertNode(p.getAddress(), N_INDEXES - 1); 206 | } 207 | if (indx2Units[i = units2Indx[sz - 1]] != sz) { 208 | k = sz - indx2Units[--i]; 209 | insertNode(MBPtr(p.getAddress(), sz - k), k - 1); 210 | } 211 | insertNode(p.getAddress(), i); 212 | p.setAddress(s0.getNext()); 213 | } 214 | } 215 | 216 | private int allocUnitsRare(int indx) { 217 | if (glueCount == 0) { 218 | glueCount = 255; 219 | glueFreeBlocks(); 220 | if (freeList[indx].getNext() != 0) { 221 | return removeNode(indx); 222 | } 223 | } 224 | int i = indx; 225 | do { 226 | if (++i == N_INDEXES) { 227 | glueCount--; 228 | i = U2B(indx2Units[indx]); 229 | int j = FIXED_UNIT_SIZE * indx2Units[indx]; 230 | if (fakeUnitsStart - pText > j) { 231 | fakeUnitsStart -= j; 232 | unitsStart -= i; 233 | return unitsStart; 234 | } 235 | return (0); 236 | } 237 | } while (freeList[i].getNext() == 0); 238 | int retVal = removeNode(i); 239 | splitBlock(retVal, i, indx); 240 | return retVal; 241 | } 242 | 243 | public int allocUnits(int NU) { 244 | int indx = units2Indx[NU - 1]; 245 | if (freeList[indx].getNext() != 0) { 246 | return removeNode(indx); 247 | } 248 | int retVal = loUnit; 249 | loUnit += U2B(indx2Units[indx]); 250 | if (loUnit <= hiUnit) { 251 | return retVal; 252 | } 253 | loUnit -= U2B(indx2Units[indx]); 254 | return allocUnitsRare(indx); 255 | } 256 | 257 | public int allocContext() { 258 | if (hiUnit != loUnit) 259 | return (hiUnit -= UNIT_SIZE); 260 | if (freeList[0].getNext() != 0) { 261 | return removeNode(0); 262 | } 263 | return allocUnitsRare(0); 264 | } 265 | 266 | public int expandUnits(int oldPtr, int OldNU) { 267 | int i0 = units2Indx[OldNU - 1]; 268 | int i1 = units2Indx[OldNU - 1 + 1]; 269 | if (i0 == i1) { 270 | return oldPtr; 271 | } 272 | int ptr = allocUnits(OldNU + 1); 273 | if (ptr != 0) { 274 | // memcpy(ptr,OldPtr,U2B(OldNU)); 275 | System.arraycopy(heap, oldPtr, heap, ptr, U2B(OldNU)); 276 | insertNode(oldPtr, i0); 277 | } 278 | return ptr; 279 | } 280 | 281 | public int shrinkUnits(int oldPtr, int oldNU, int newNU) { 282 | // System.out.println("SubAllocator.shrinkUnits(" + OldPtr + ", " + 283 | // OldNU + ", " + NewNU + ")"); 284 | int i0 = units2Indx[oldNU - 1]; 285 | int i1 = units2Indx[newNU - 1]; 286 | if (i0 == i1) { 287 | return oldPtr; 288 | } 289 | if (freeList[i1].getNext() != 0) { 290 | int ptr = removeNode(i1); 291 | // memcpy(ptr,OldPtr,U2B(NewNU)); 292 | // for (int i = 0; i < U2B(NewNU); i++) { 293 | // heap[ptr + i] = heap[OldPtr + i]; 294 | // } 295 | System.arraycopy(heap, oldPtr, heap, ptr, U2B(newNU)); 296 | insertNode(oldPtr, i0); 297 | return ptr; 298 | } else { 299 | splitBlock(oldPtr, i0, i1); 300 | return oldPtr; 301 | } 302 | } 303 | 304 | public void freeUnits(int ptr, int OldNU) { 305 | insertNode(ptr, units2Indx[OldNU - 1]); 306 | } 307 | 308 | public int getFakeUnitsStart() { 309 | return fakeUnitsStart; 310 | } 311 | 312 | public void setFakeUnitsStart(int fakeUnitsStart) { 313 | this.fakeUnitsStart = fakeUnitsStart; 314 | } 315 | 316 | public int getHeapEnd() { 317 | return heapEnd; 318 | } 319 | 320 | public int getPText() { 321 | return pText; 322 | } 323 | 324 | public void setPText(int text) { 325 | pText = text; 326 | } 327 | 328 | public void decPText(int dPText) { 329 | setPText(getPText() - dPText); 330 | } 331 | 332 | public int getUnitsStart() { 333 | return unitsStart; 334 | } 335 | 336 | public void setUnitsStart(int unitsStart) { 337 | this.unitsStart = unitsStart; 338 | } 339 | 340 | public void initSubAllocator() { 341 | int i, k; 342 | Arrays 343 | .fill(heap, freeListPos, freeListPos + sizeOfFreeList(), 344 | (byte) 0); 345 | 346 | pText = heapStart; 347 | 348 | int size2 = FIXED_UNIT_SIZE 349 | * (subAllocatorSize / 8 / FIXED_UNIT_SIZE * 7); 350 | int realSize2 = size2 / FIXED_UNIT_SIZE * UNIT_SIZE; 351 | int size1 = subAllocatorSize - size2; 352 | int realSize1 = size1 / FIXED_UNIT_SIZE * UNIT_SIZE + size1 353 | % FIXED_UNIT_SIZE; 354 | hiUnit = heapStart + subAllocatorSize; 355 | loUnit = unitsStart = heapStart + realSize1; 356 | fakeUnitsStart = heapStart + size1; 357 | hiUnit = loUnit + realSize2; 358 | 359 | for (i = 0, k = 1; i < N1; i++, k += 1) { 360 | indx2Units[i] = k & 0xff; 361 | } 362 | for (k++; i < N1 + N2; i++, k += 2) { 363 | indx2Units[i] = k & 0xff; 364 | } 365 | for (k++; i < N1 + N2 + N3; i++, k += 3) { 366 | indx2Units[i] = k & 0xff; 367 | } 368 | for (k++; i < (N1 + N2 + N3 + N4); i++, k += 4) { 369 | indx2Units[i] = k & 0xff; 370 | } 371 | 372 | for (glueCount = 0, k = 0, i = 0; k < 128; k++) { 373 | i += ((indx2Units[i] < (k + 1)) ? 1 : 0); 374 | units2Indx[k] = i & 0xff; 375 | } 376 | 377 | } 378 | 379 | private int sizeOfFreeList() { 380 | return freeList.length * RarNode.size; 381 | } 382 | 383 | public byte[] getHeap() { 384 | return heap; 385 | } 386 | 387 | // Debug 388 | // public void dumpHeap() { 389 | // File file = new File("P:\\test\\heapdumpj"); 390 | // OutputStream out = null; 391 | // try { 392 | // out = new FileOutputStream(file); 393 | // out.write(heap, heapStart, heapEnd - heapStart); 394 | // out.flush(); 395 | // System.out.println("Heap dumped to " + file.getAbsolutePath()); 396 | // } 397 | // catch (IOException e) { 398 | // e.printStackTrace(); 399 | // } 400 | // finally { 401 | // FileUtil.close(out); 402 | // } 403 | // } 404 | 405 | // Debug 406 | public String toString() { 407 | StringBuilder buffer = new StringBuilder(); 408 | buffer.append("SubAllocator["); 409 | buffer.append("\n subAllocatorSize="); 410 | buffer.append(subAllocatorSize); 411 | buffer.append("\n glueCount="); 412 | buffer.append(glueCount); 413 | buffer.append("\n heapStart="); 414 | buffer.append(heapStart); 415 | buffer.append("\n loUnit="); 416 | buffer.append(loUnit); 417 | buffer.append("\n hiUnit="); 418 | buffer.append(hiUnit); 419 | buffer.append("\n pText="); 420 | buffer.append(pText); 421 | buffer.append("\n unitsStart="); 422 | buffer.append(unitsStart); 423 | buffer.append("\n]"); 424 | return buffer.toString(); 425 | } 426 | 427 | } 428 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/vm/BitInput.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 31.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.vm; 19 | 20 | /** 21 | * DOCUMENT ME 22 | * 23 | * @author $LastChangedBy$ 24 | * @version $LastChangedRevision$ 25 | */ 26 | public class BitInput { 27 | /** 28 | * the max size of the input 29 | */ 30 | public static final int MAX_SIZE = 0x8000; 31 | protected int inAddr; 32 | protected int inBit; 33 | protected byte[] inBuf; 34 | 35 | /** 36 | * 37 | */ 38 | public void InitBitInput() 39 | { 40 | inAddr=0; 41 | inBit=0; 42 | } 43 | /** 44 | * @param Bits 45 | */ 46 | public void addbits(int Bits) 47 | { 48 | Bits+=inBit; 49 | inAddr+=Bits>>3; 50 | inBit=Bits&7; 51 | } 52 | 53 | /** 54 | * @return the bits (unsigned short) 55 | */ 56 | public int getbits() 57 | { 58 | // int BitField=0; 59 | // BitField|=(int)(inBuf[inAddr] << 16)&0xFF0000; 60 | // BitField|=(int)(inBuf[inAddr+1] << 8)&0xff00; 61 | // BitField|=(int)(inBuf[inAddr+2])&0xFF; 62 | // BitField >>>= (8-inBit); 63 | // return (BitField & 0xffff); 64 | return (((((inBuf[inAddr] & 0xff) << 16) + 65 | ((inBuf[inAddr+1] & 0xff) << 8) + 66 | ((inBuf[inAddr+2] & 0xff))) >>> (8-inBit)) & 0xffff); 67 | } 68 | 69 | /** 70 | * 71 | */ 72 | public BitInput() 73 | { 74 | inBuf=new byte[MAX_SIZE]; 75 | } 76 | 77 | /** 78 | * @param Bits add the bits 79 | */ 80 | public void faddbits(int Bits) 81 | { 82 | addbits(Bits); 83 | } 84 | 85 | 86 | /** 87 | * @return get the bits 88 | */ 89 | public int fgetbits() 90 | { 91 | return(getbits()); 92 | } 93 | 94 | /** 95 | * Indicates an Overfow 96 | * @param IncPtr how many bytes to inc 97 | * @return true if an Oververflow would occur 98 | */ 99 | public boolean Overflow(int IncPtr) { 100 | return(inAddr+IncPtr>=MAX_SIZE); 101 | } 102 | public byte[] getInBuf() 103 | { 104 | return inBuf; 105 | } 106 | 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/vm/VMCmdFlags.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 01.06.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.vm; 19 | 20 | /** 21 | * DOCUMENT ME 22 | * 23 | * @author $LastChangedBy$ 24 | * @version $LastChangedRevision$ 25 | */ 26 | public class VMCmdFlags { 27 | public static final byte VMCF_OP0 = 0; 28 | public static final byte VMCF_OP1 = 1; 29 | public static final byte VMCF_OP2 = 2; 30 | public static final byte VMCF_OPMASK = 3; 31 | public static final byte VMCF_BYTEMODE = 4; 32 | public static final byte VMCF_JUMP = 8; 33 | public static final byte VMCF_PROC = 16; 34 | public static final byte VMCF_USEFLAGS = 32; 35 | public static final byte VMCF_CHFLAGS = 64; 36 | 37 | public static byte VM_CmdFlags[]= 38 | { 39 | /* VM_MOV */ VMCF_OP2 | VMCF_BYTEMODE , 40 | /* VM_CMP */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , 41 | /* VM_ADD */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , 42 | /* VM_SUB */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , 43 | /* VM_JZ */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS , 44 | /* VM_JNZ */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS , 45 | /* VM_INC */ VMCF_OP1 | VMCF_BYTEMODE | VMCF_CHFLAGS , 46 | /* VM_DEC */ VMCF_OP1 | VMCF_BYTEMODE | VMCF_CHFLAGS , 47 | /* VM_JMP */ VMCF_OP1 | VMCF_JUMP , 48 | /* VM_XOR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , 49 | /* VM_AND */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , 50 | /* VM_OR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , 51 | /* VM_TEST */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , 52 | /* VM_JS */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS , 53 | /* VM_JNS */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS , 54 | /* VM_JB */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS , 55 | /* VM_JBE */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS , 56 | /* VM_JA */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS , 57 | /* VM_JAE */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS , 58 | /* VM_PUSH */ VMCF_OP1 , 59 | /* VM_POP */ VMCF_OP1 , 60 | /* VM_CALL */ VMCF_OP1 | VMCF_PROC , 61 | /* VM_RET */ VMCF_OP0 | VMCF_PROC , 62 | /* VM_NOT */ VMCF_OP1 | VMCF_BYTEMODE , 63 | /* VM_SHL */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , 64 | /* VM_SHR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , 65 | /* VM_SAR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , 66 | /* VM_NEG */ VMCF_OP1 | VMCF_BYTEMODE | VMCF_CHFLAGS , 67 | /* VM_PUSHA */ VMCF_OP0 , 68 | /* VM_POPA */ VMCF_OP0 , 69 | /* VM_PUSHF */ VMCF_OP0 | VMCF_USEFLAGS , 70 | /* VM_POPF */ VMCF_OP0 | VMCF_CHFLAGS , 71 | /* VM_MOVZX */ VMCF_OP2 , 72 | /* VM_MOVSX */ VMCF_OP2 , 73 | /* VM_XCHG */ VMCF_OP2 | VMCF_BYTEMODE , 74 | /* VM_MUL */ VMCF_OP2 | VMCF_BYTEMODE , 75 | /* VM_DIV */ VMCF_OP2 | VMCF_BYTEMODE , 76 | /* VM_ADC */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_USEFLAGS | VMCF_CHFLAGS , 77 | /* VM_SBB */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_USEFLAGS | VMCF_CHFLAGS , 78 | /* VM_PRINT */ VMCF_OP0 79 | }; 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/vm/VMCommands.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 31.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.vm; 19 | 20 | /** 21 | * DOCUMENT ME 22 | * 23 | * @author $LastChangedBy$ 24 | * @version $LastChangedRevision$ 25 | */ 26 | public enum VMCommands { 27 | VM_MOV(0), VM_CMP(1), VM_ADD(2), VM_SUB(3), VM_JZ(4), VM_JNZ(5), VM_INC(6), VM_DEC( 28 | 7), VM_JMP(8), VM_XOR(9), VM_AND(10), VM_OR(11), VM_TEST(12), VM_JS( 29 | 13), VM_JNS(14), VM_JB(15), VM_JBE(16), VM_JA(17), VM_JAE(18), VM_PUSH( 30 | 19), VM_POP(20), VM_CALL(21), VM_RET(22), VM_NOT(23), VM_SHL(24), VM_SHR( 31 | 25), VM_SAR(26), VM_NEG(27), VM_PUSHA(28), VM_POPA(29), VM_PUSHF(30), VM_POPF( 32 | 31), VM_MOVZX(32), VM_MOVSX(33), VM_XCHG(34), VM_MUL(35), VM_DIV(36), VM_ADC( 33 | 37), VM_SBB(38), VM_PRINT(39), 34 | 35 | // #ifdef VM_OPTIMIZE 36 | VM_MOVB(40), VM_MOVD(41), VM_CMPB(42), VM_CMPD(43), 37 | 38 | VM_ADDB(44), VM_ADDD(45), VM_SUBB(46), VM_SUBD(47), VM_INCB(48), VM_INCD(49), VM_DECB( 39 | 50), VM_DECD(51), VM_NEGB(52), VM_NEGD(53), 40 | // #endif*/ 41 | 42 | VM_STANDARD(54); 43 | 44 | private int vmCommand; 45 | 46 | private VMCommands(int vmCommand) { 47 | this.vmCommand = vmCommand; 48 | } 49 | 50 | public int getVMCommand() { 51 | return vmCommand; 52 | } 53 | 54 | public boolean equals(int vmCommand) { 55 | return this.vmCommand == vmCommand; 56 | } 57 | 58 | public static VMCommands findVMCommand(int vmCommand) { 59 | if (VM_MOV.equals(vmCommand)) { 60 | return VM_MOV; 61 | } 62 | if (VM_CMP.equals(vmCommand)) { 63 | return VM_CMP; 64 | } 65 | if (VM_ADD.equals(vmCommand)) { 66 | return VM_ADD; 67 | } 68 | if (VM_SUB.equals(vmCommand)) { 69 | return VM_SUB; 70 | } 71 | if (VM_JZ.equals(vmCommand)) { 72 | return VM_JZ; 73 | } 74 | if (VM_JNZ.equals(vmCommand)) { 75 | return VM_JNZ; 76 | } 77 | if (VM_INC.equals(vmCommand)) { 78 | return VM_INC; 79 | } 80 | if (VM_DEC.equals(vmCommand)) { 81 | return VM_DEC; 82 | } 83 | if (VM_JMP.equals(vmCommand)) { 84 | return VM_JMP; 85 | } 86 | if (VM_XOR.equals(vmCommand)) { 87 | return VM_XOR; 88 | } 89 | if (VM_AND.equals(vmCommand)) { 90 | return VM_AND; 91 | } 92 | if (VM_OR.equals(vmCommand)) { 93 | return VM_OR; 94 | } 95 | if (VM_TEST.equals(vmCommand)) { 96 | return VM_TEST; 97 | } 98 | if (VM_JS.equals(vmCommand)) { 99 | return VM_JS; 100 | } 101 | if (VM_JNS.equals(vmCommand)) { 102 | return VM_JNS; 103 | } 104 | if (VM_JB.equals(vmCommand)) { 105 | return VM_JB; 106 | } 107 | if (VM_JBE.equals(vmCommand)) { 108 | return VM_JBE; 109 | } 110 | if (VM_JA.equals(vmCommand)) { 111 | return VM_JA; 112 | } 113 | if (VM_JAE.equals(vmCommand)) { 114 | return VM_JAE; 115 | } 116 | if (VM_PUSH.equals(vmCommand)) { 117 | return VM_PUSH; 118 | } 119 | if (VM_POP.equals(vmCommand)) { 120 | return VM_POP; 121 | } 122 | if (VM_CALL.equals(vmCommand)) { 123 | return VM_CALL; 124 | } 125 | if (VM_RET.equals(vmCommand)) { 126 | return VM_RET; 127 | } 128 | if (VM_NOT.equals(vmCommand)) { 129 | return VM_NOT; 130 | } 131 | if (VM_SHL.equals(vmCommand)) { 132 | return VM_SHL; 133 | } 134 | if (VM_SHR.equals(vmCommand)) { 135 | return VM_SHR; 136 | } 137 | if (VM_SAR.equals(vmCommand)) { 138 | return VM_SAR; 139 | } 140 | if (VM_NEG.equals(vmCommand)) { 141 | return VM_NEG; 142 | } 143 | if (VM_PUSHA.equals(vmCommand)) { 144 | return VM_PUSHA; 145 | } 146 | if (VM_POPA.equals(vmCommand)) { 147 | return VM_POPA; 148 | } 149 | if (VM_PUSHF.equals(vmCommand)) { 150 | return VM_PUSHF; 151 | } 152 | if (VM_POPF.equals(vmCommand)) { 153 | return VM_POPF; 154 | } 155 | if (VM_MOVZX.equals(vmCommand)) { 156 | return VM_MOVZX; 157 | } 158 | if (VM_MOVSX.equals(vmCommand)) { 159 | return VM_MOVSX; 160 | } 161 | if (VM_XCHG.equals(vmCommand)) { 162 | return VM_XCHG; 163 | } 164 | if (VM_MUL.equals(vmCommand)) { 165 | return VM_MUL; 166 | } 167 | if (VM_DIV.equals(vmCommand)) { 168 | return VM_DIV; 169 | } 170 | if (VM_ADC.equals(vmCommand)) { 171 | return VM_ADC; 172 | } 173 | if (VM_SBB.equals(vmCommand)) { 174 | return VM_SBB; 175 | } 176 | if (VM_PRINT.equals(vmCommand)) { 177 | return VM_PRINT; 178 | } 179 | if (VM_MOVB.equals(vmCommand)) { 180 | return VM_MOVB; 181 | } 182 | if (VM_MOVD.equals(vmCommand)) { 183 | return VM_MOVD; 184 | } 185 | if (VM_CMPB.equals(vmCommand)) { 186 | return VM_CMPB; 187 | } 188 | if (VM_CMPD.equals(vmCommand)) { 189 | return VM_CMPD; 190 | } 191 | if (VM_ADDB.equals(vmCommand)) { 192 | return VM_ADDB; 193 | } 194 | if (VM_ADDD.equals(vmCommand)) { 195 | return VM_ADDD; 196 | } 197 | if (VM_SUBB.equals(vmCommand)) { 198 | return VM_SUBB; 199 | } 200 | if (VM_SUBD.equals(vmCommand)) { 201 | return VM_SUBD; 202 | } 203 | if (VM_INCB.equals(vmCommand)) { 204 | return VM_INCB; 205 | } 206 | if (VM_INCD.equals(vmCommand)) { 207 | return VM_INCD; 208 | } 209 | if (VM_DECB.equals(vmCommand)) { 210 | return VM_DECB; 211 | } 212 | if (VM_DECD.equals(vmCommand)) { 213 | return VM_DECD; 214 | } 215 | if (VM_NEGB.equals(vmCommand)) { 216 | return VM_NEGB; 217 | } 218 | if (VM_NEGD.equals(vmCommand)) { 219 | return VM_NEGD; 220 | } 221 | if (VM_STANDARD.equals(vmCommand)) { 222 | return VM_STANDARD; 223 | } 224 | return null; 225 | } 226 | } 227 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/vm/VMFlags.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 31.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.vm; 19 | 20 | /** 21 | * DOCUMENT ME 22 | * 23 | * @author $LastChangedBy$ 24 | * @version $LastChangedRevision$ 25 | */ 26 | public enum VMFlags { 27 | /** 28 | * 29 | */ 30 | VM_FC (1), 31 | /** 32 | * 33 | */ 34 | VM_FZ (2), 35 | /** 36 | * 37 | */ 38 | VM_FS (0x80000000); 39 | 40 | private int flag; 41 | 42 | private VMFlags(int flag){ 43 | this.flag = flag; 44 | } 45 | 46 | /** 47 | * Returns the VMFlags Type of the given int or null 48 | * @param flag as int 49 | * @return VMFlag of the int value 50 | */ 51 | public static VMFlags findFlag(int flag){ 52 | if(VM_FC.equals(flag)){ 53 | return VM_FC; 54 | } 55 | if(VM_FS.equals(flag)){ 56 | return VM_FS; 57 | } 58 | if(VM_FZ.equals(flag)){ 59 | return VM_FZ; 60 | } 61 | return null; 62 | } 63 | 64 | /** 65 | * Returns true if the flag provided as int is equal to the enum 66 | * @param flag 67 | * @return returns true if the flag is equal to the enum 68 | */ 69 | public boolean equals(int flag){ 70 | return this.flag == flag; 71 | } 72 | /** 73 | * @return the flag as int 74 | */ 75 | public int getFlag() { 76 | return flag; 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/vm/VMOpType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 31.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.vm; 19 | 20 | /** 21 | * DOCUMENT ME 22 | * 23 | * @author $LastChangedBy$ 24 | * @version $LastChangedRevision$ 25 | */ 26 | public enum VMOpType { 27 | VM_OPREG (0), 28 | VM_OPINT (1), 29 | VM_OPREGMEM (2), 30 | VM_OPNONE (3); 31 | 32 | private int opType; 33 | 34 | private VMOpType(int opType){ 35 | this.opType=opType; 36 | } 37 | 38 | public int getOpType() { 39 | return opType; 40 | } 41 | 42 | 43 | public boolean equals(int opType){ 44 | return this.opType == opType; 45 | } 46 | public static VMOpType findOpType(int opType){ 47 | 48 | if (VM_OPREG.equals(opType)) { 49 | return VM_OPREG; 50 | } 51 | 52 | 53 | if (VM_OPINT.equals(opType)) { 54 | return VM_OPINT; 55 | } 56 | 57 | if (VM_OPREGMEM.equals(opType)) { 58 | return VM_OPREGMEM; 59 | } 60 | 61 | if (VM_OPNONE.equals(opType)) { 62 | return VM_OPNONE; 63 | } 64 | return null; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/vm/VMPreparedCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 31.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.vm; 19 | 20 | /** 21 | * DOCUMENT ME 22 | * 23 | * @author $LastChangedBy$ 24 | * @version $LastChangedRevision$ 25 | */ 26 | public class VMPreparedCommand { 27 | private VMCommands OpCode; 28 | private boolean ByteMode; 29 | private VMPreparedOperand Op1 = new VMPreparedOperand(); 30 | private VMPreparedOperand Op2 = new VMPreparedOperand(); 31 | 32 | public boolean isByteMode() { 33 | return ByteMode; 34 | } 35 | public void setByteMode(boolean byteMode) { 36 | ByteMode = byteMode; 37 | } 38 | public VMPreparedOperand getOp1() { 39 | return Op1; 40 | } 41 | public void setOp1(VMPreparedOperand op1) { 42 | Op1 = op1; 43 | } 44 | public VMPreparedOperand getOp2() { 45 | return Op2; 46 | } 47 | public void setOp2(VMPreparedOperand op2) { 48 | Op2 = op2; 49 | } 50 | public VMCommands getOpCode() { 51 | return OpCode; 52 | } 53 | public void setOpCode(VMCommands opCode) { 54 | OpCode = opCode; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/vm/VMPreparedOperand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 31.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.vm; 19 | 20 | /** 21 | * DOCUMENT ME 22 | * 23 | * @author $LastChangedBy$ 24 | * @version $LastChangedRevision$ 25 | */ 26 | public class VMPreparedOperand { 27 | private VMOpType Type; 28 | private int Data; 29 | private int Base; 30 | private int offset; 31 | 32 | 33 | public int getBase() { 34 | return Base; 35 | } 36 | public void setBase(int base) { 37 | Base = base; 38 | } 39 | public int getData() { 40 | return Data; 41 | } 42 | public void setData(int data) { 43 | Data = data; 44 | } 45 | public VMOpType getType() { 46 | return Type; 47 | } 48 | public void setType(VMOpType type) { 49 | Type = type; 50 | } 51 | public int getOffset() { 52 | return offset; 53 | } 54 | public void setOffset(int offset) { 55 | this.offset = offset; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/vm/VMPreparedProgram.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 31.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.vm; 19 | 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | import java.util.Vector; 23 | 24 | /** 25 | * DOCUMENT ME 26 | * 27 | * @author $LastChangedBy$ 28 | * @version $LastChangedRevision$ 29 | */ 30 | public class VMPreparedProgram 31 | { 32 | private List Cmd = new ArrayList(); 33 | private List AltCmd =new ArrayList(); 34 | private int CmdCount; 35 | 36 | 37 | 38 | private Vector GlobalData = new Vector(); 39 | private Vector StaticData = new Vector(); // static data contained in DB operators 40 | private int InitR[] = new int[7]; 41 | 42 | private int FilteredDataOffset; 43 | private int FilteredDataSize; 44 | 45 | public VMPreparedProgram() 46 | { 47 | AltCmd=null; 48 | } 49 | 50 | 51 | 52 | public List getAltCmd() { 53 | return AltCmd; 54 | } 55 | 56 | 57 | 58 | public void setAltCmd(List altCmd) { 59 | AltCmd = altCmd; 60 | } 61 | 62 | 63 | 64 | public List getCmd() { 65 | return Cmd; 66 | } 67 | 68 | public void setCmd(List cmd) { 69 | Cmd = cmd; 70 | } 71 | 72 | public int getCmdCount() { 73 | return CmdCount; 74 | } 75 | 76 | public void setCmdCount(int cmdCount) { 77 | CmdCount = cmdCount; 78 | } 79 | 80 | 81 | 82 | public int getFilteredDataOffset() { 83 | return FilteredDataOffset; 84 | } 85 | 86 | 87 | 88 | public void setFilteredDataOffset(int filteredDataOffset) { 89 | FilteredDataOffset = filteredDataOffset; 90 | } 91 | 92 | 93 | 94 | public int getFilteredDataSize() { 95 | return FilteredDataSize; 96 | } 97 | 98 | public void setFilteredDataSize(int filteredDataSize) { 99 | FilteredDataSize = filteredDataSize; 100 | } 101 | 102 | public Vector getGlobalData() { 103 | return GlobalData; 104 | } 105 | 106 | public void setGlobalData(Vector globalData) { 107 | GlobalData = globalData; 108 | } 109 | 110 | public int[] getInitR() { 111 | return InitR; 112 | } 113 | 114 | public void setInitR(int[] initR) { 115 | InitR = initR; 116 | } 117 | 118 | public Vector getStaticData() { 119 | return StaticData; 120 | } 121 | 122 | public void setStaticData(Vector staticData) { 123 | StaticData = staticData; 124 | } 125 | 126 | 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/vm/VMStandardFilterSignature.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 04.06.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.vm; 19 | 20 | /** 21 | * DOCUMENT ME 22 | * 23 | * @author $LastChangedBy$ 24 | * @version $LastChangedRevision$ 25 | */ 26 | public class VMStandardFilterSignature { 27 | private int length; 28 | 29 | private int CRC; 30 | 31 | private VMStandardFilters type; 32 | 33 | public VMStandardFilterSignature(int length, int crc, VMStandardFilters type) { 34 | super(); 35 | this.length = length; 36 | CRC = crc; 37 | this.type = type; 38 | } 39 | 40 | public int getCRC() { 41 | return CRC; 42 | } 43 | 44 | public void setCRC(int crc) { 45 | CRC = crc; 46 | } 47 | 48 | public int getLength() { 49 | return length; 50 | } 51 | 52 | public void setLength(int length) { 53 | this.length = length; 54 | } 55 | 56 | public VMStandardFilters getType() { 57 | return type; 58 | } 59 | 60 | public void setType(VMStandardFilters type) { 61 | this.type = type; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unpack/vm/VMStandardFilters.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 31.05.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * the unrar licence applies to all junrar source and binary distributions 10 | * you are not allowed to use this source to re-create the RAR compression algorithm 11 | * 12 | * Here some html entities which can be used for escaping javadoc tags: 13 | * "&": "&" or "&" 14 | * "<": "<" or "<" 15 | * ">": ">" or ">" 16 | * "@": "@" 17 | */ 18 | package de.innosystec.unrar.unpack.vm; 19 | 20 | /** 21 | * DOCUMENT ME 22 | * 23 | * @author $LastChangedBy$ 24 | * @version $LastChangedRevision$ 25 | */ 26 | public enum VMStandardFilters { 27 | VMSF_NONE ((int)0), 28 | VMSF_E8 ((int)1), 29 | VMSF_E8E9 ((int)2), 30 | VMSF_ITANIUM( (int)3), 31 | VMSF_RGB ((int)4), 32 | VMSF_AUDIO ((int)5), 33 | VMSF_DELTA ((int)6), 34 | VMSF_UPCASE ((int)7); 35 | 36 | private int filter; 37 | 38 | private VMStandardFilters(int filter){ 39 | this.filter=filter; 40 | } 41 | 42 | public int getFilter() { 43 | return filter; 44 | } 45 | 46 | public boolean equals(int filter){ 47 | return this.filter == filter; 48 | } 49 | 50 | public static VMStandardFilters findFilter(int filter){ 51 | if (VMSF_NONE.equals(filter)) { 52 | return VMSF_NONE; 53 | } 54 | 55 | if (VMSF_E8.equals(filter)) { 56 | return VMSF_E8; 57 | } 58 | 59 | if (VMSF_E8E9.equals(filter)) { 60 | return VMSF_E8E9; 61 | } 62 | if (VMSF_ITANIUM.equals(filter)) { 63 | return VMSF_ITANIUM; 64 | } 65 | 66 | if (VMSF_RGB.equals(filter)) { 67 | return VMSF_RGB; 68 | } 69 | 70 | if (VMSF_AUDIO.equals(filter)) { 71 | return VMSF_AUDIO; 72 | } 73 | if (VMSF_DELTA.equals(filter)) { 74 | return VMSF_DELTA; 75 | } 76 | return null; 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unsigned/UnsignedByte.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 04.06.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * 10 | * the unrar licence applies to all junrar source and binary distributions 11 | * you are not allowed to use this source to re-create the RAR compression algorithm 12 | * 13 | * Here some html entities which can be used for escaping javadoc tags: 14 | * "&": "&" or "&" 15 | * "<": "<" or "<" 16 | * ">": ">" or ">" 17 | * "@": "@" 18 | */ 19 | package de.innosystec.unrar.unsigned; 20 | 21 | import de.innosystec.unrar.crc.RarCRC; 22 | 23 | /** 24 | * DOCUMENT ME 25 | * 26 | * @author $LastChangedBy$ 27 | * @version $LastChangedRevision$ 28 | */ 29 | public class UnsignedByte { 30 | 31 | public static byte longToByte(long unsignedByte1){ 32 | return (byte) (unsignedByte1&0xff); 33 | } 34 | public static byte intToByte(int unsignedByte1){ 35 | return (byte) (unsignedByte1&0xff); 36 | } 37 | public static byte shortToByte(short unsignedByte1){ 38 | return (byte) (unsignedByte1&0xff); 39 | } 40 | 41 | 42 | public static short add(byte unsignedByte1, byte unsignedByte2){ 43 | return (short) (unsignedByte1 + unsignedByte2); 44 | } 45 | 46 | public static short sub(byte unsignedByte1, byte unsignedByte2){ 47 | 48 | return (short) (unsignedByte1 - unsignedByte2); 49 | } 50 | 51 | 52 | public static void main(String[] args) 53 | { 54 | //tests unsigned (signed) 55 | //add 56 | System.out.println(add((byte)0xfe,(byte)0x01)); //255 (-1) 57 | System.out.println(add((byte)0xff,(byte)0x01)); //0 (0) 58 | System.out.println(add((byte)0x7f,(byte)0x01)); //128 (-128) 59 | System.out.println(add((byte)0xff,(byte)0xff)); //254 (-2) 60 | 61 | //sub 62 | System.out.println(sub((byte)0xfe,(byte)0x01)); //253 (-3) 63 | System.out.println(sub((byte)0x00,(byte)0x01)); //255 (-1) 64 | System.out.println(sub((byte)0x80,(byte)0x01)); //127 (127) 65 | //mul 66 | System.out.println((byte)-1*(byte)-1); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unsigned/UnsignedInteger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 04.06.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * 10 | * the unrar licence applies to all junrar source and binary distributions 11 | * you are not allowed to use this source to re-create the RAR compression algorithm 12 | * 13 | * Here some html entities which can be used for escaping javadoc tags: 14 | * "&": "&" or "&" 15 | * "<": "<" or "<" 16 | * ">": ">" or ">" 17 | * "@": "@" 18 | */ 19 | package de.innosystec.unrar.unsigned; 20 | 21 | /** 22 | * DOCUMENT ME 23 | * 24 | * @author $LastChangedBy$ 25 | * @version $LastChangedRevision$ 26 | */ 27 | public class UnsignedInteger { 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unsigned/UnsignedLong.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 04.06.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * 10 | * the unrar licence applies to all junrar source and binary distributions 11 | * you are not allowed to use this source to re-create the RAR compression algorithm 12 | * 13 | * Here some html entities which can be used for escaping javadoc tags: 14 | * "&": "&" or "&" 15 | * "<": "<" or "<" 16 | * ">": ">" or ">" 17 | * "@": "@" 18 | */ 19 | package de.innosystec.unrar.unsigned; 20 | 21 | /** 22 | * DOCUMENT ME 23 | * 24 | * @author $LastChangedBy$ 25 | * @version $LastChangedRevision$ 26 | */ 27 | public class UnsignedLong { 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/de/innosystec/unrar/unsigned/UnsignedShort.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. 3 | * Original author: Edmund Wagner 4 | * Creation date: 04.06.2007 5 | * 6 | * Source: $HeadURL$ 7 | * Last changed: $LastChangedDate$ 8 | * 9 | * 10 | * the unrar licence applies to all junrar source and binary distributions 11 | * you are not allowed to use this source to re-create the RAR compression algorithm 12 | * 13 | * Here some html entities which can be used for escaping javadoc tags: 14 | * "&": "&" or "&" 15 | * "<": "<" or "<" 16 | * ">": ">" or ">" 17 | * "@": "@" 18 | */ 19 | package de.innosystec.unrar.unsigned; 20 | 21 | /** 22 | * DOCUMENT ME 23 | * 24 | * @author $LastChangedBy$ 25 | * @version $LastChangedRevision$ 26 | */ 27 | public class UnsignedShort { 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/services/org.apache.tika.parser.Parser: -------------------------------------------------------------------------------- 1 | de.innosystec.unrar.tika.RARParser 2 | --------------------------------------------------------------------------------