WIP migrating to kotlin.
This commit is contained in:
parent
fd7583023d
commit
ada5ffddd5
389
LICENSE
389
LICENSE
|
@ -6,23 +6,21 @@
|
||||||
Parse and extract data from Microsoft LZX compressed .cab files for Java 8+
|
Parse and extract data from Microsoft LZX compressed .cab files for Java 8+
|
||||||
|
|
||||||
Extra license information
|
Extra license information
|
||||||
- ByteUtilties - Byte manipulation and Unsigned Number Utilities
|
- Kotlin -
|
||||||
|
[The Apache Software License, Version 2.0]
|
||||||
|
https://github.com/JetBrains/kotlin
|
||||||
|
Copyright 2020
|
||||||
|
JetBrains s.r.o. and Kotlin Programming Language contributors
|
||||||
|
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
|
||||||
|
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
|
||||||
|
|
||||||
|
- ByteUtils - Byte manipulation and SHA/xxHash utilities
|
||||||
[The Apache Software License, Version 2.0]
|
[The Apache Software License, Version 2.0]
|
||||||
https://git.dorkbox.com/dorkbox/ByteUtilities
|
https://git.dorkbox.com/dorkbox/ByteUtilities
|
||||||
Copyright 2023
|
Copyright 2023
|
||||||
Dorkbox LLC
|
Dorkbox LLC
|
||||||
|
|
||||||
Extra license information
|
Extra license information
|
||||||
- Byte Utils (UByte, UInteger, ULong, Unsigned, UNumber, UShort) -
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://github.com/jOOQ/jOOQ/tree/master/jOOQ/src/main/java/org/jooq/types
|
|
||||||
Copyright 2017
|
|
||||||
Data Geekery GmbH (http://www.datageekery.com)
|
|
||||||
Lukas Eder
|
|
||||||
Ed Schaller
|
|
||||||
Jens Nerche
|
|
||||||
Ivan Sokolov
|
|
||||||
|
|
||||||
- Kryo Serialization -
|
- Kryo Serialization -
|
||||||
[BSD 3-Clause License]
|
[BSD 3-Clause License]
|
||||||
https://github.com/EsotericSoftware/kryo
|
https://github.com/EsotericSoftware/kryo
|
||||||
|
@ -73,7 +71,7 @@
|
||||||
|
|
||||||
- Objenesis -
|
- Objenesis -
|
||||||
[The Apache Software License, Version 2.0]
|
[The Apache Software License, Version 2.0]
|
||||||
http://objenesis.org
|
https://github.com/easymock/objenesis
|
||||||
Objenesis Team and all contributors
|
Objenesis Team and all contributors
|
||||||
|
|
||||||
- MinLog-SLF4J -
|
- MinLog-SLF4J -
|
||||||
|
@ -81,6 +79,13 @@
|
||||||
https://github.com/EsotericSoftware/minlog
|
https://github.com/EsotericSoftware/minlog
|
||||||
Nathan Sweet
|
Nathan Sweet
|
||||||
|
|
||||||
|
- LZ4 and xxHash - LZ4 compression for Java, based on Yann Collet's work
|
||||||
|
[The Apache Software License, Version 2.0]
|
||||||
|
https://github.com/lz4/lz4
|
||||||
|
Copyright 2023
|
||||||
|
Yann Collet
|
||||||
|
Adrien Grand
|
||||||
|
|
||||||
- Updates - Software Update Management
|
- Updates - Software Update Management
|
||||||
[The Apache Software License, Version 2.0]
|
[The Apache Software License, Version 2.0]
|
||||||
https://git.dorkbox.com/dorkbox/Updates
|
https://git.dorkbox.com/dorkbox/Updates
|
||||||
|
@ -125,23 +130,6 @@
|
||||||
Sean Luke
|
Sean Luke
|
||||||
Michael Lecuyer (portions Copyright 1993
|
Michael Lecuyer (portions Copyright 1993
|
||||||
|
|
||||||
- FileUtil (code from FilenameUtils.java for normalize + dependencies) -
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://git.dorkbox.com/dorkbox/Utilities
|
|
||||||
http://commons.apache.org/proper/commons-io/
|
|
||||||
Copyright 2013
|
|
||||||
The Apache Software Foundation
|
|
||||||
Kevin A. Burton
|
|
||||||
Scott Sanders
|
|
||||||
Daniel Rall
|
|
||||||
Christoph.Reck
|
|
||||||
Peter Donald
|
|
||||||
Jeff Turner
|
|
||||||
Matthew Hawthorne
|
|
||||||
Martin Cooper
|
|
||||||
Jeremias Maerki
|
|
||||||
Stephen Colebourne
|
|
||||||
|
|
||||||
- FastThreadLocal -
|
- FastThreadLocal -
|
||||||
[BSD 3-Clause License]
|
[BSD 3-Clause License]
|
||||||
https://git.dorkbox.com/dorkbox/Utilities
|
https://git.dorkbox.com/dorkbox/Utilities
|
||||||
|
@ -151,21 +139,6 @@
|
||||||
Lightweight Java Game Library Project
|
Lightweight Java Game Library Project
|
||||||
Riven
|
Riven
|
||||||
|
|
||||||
- Base64Fast -
|
|
||||||
[BSD 3-Clause License]
|
|
||||||
https://git.dorkbox.com/dorkbox/Utilities
|
|
||||||
http://migbase64.sourceforge.net/
|
|
||||||
Copyright 2004
|
|
||||||
Mikael Grev, MiG InfoCom AB. (base64@miginfocom.com)
|
|
||||||
|
|
||||||
- BCrypt -
|
|
||||||
[BSD 2-Clause "Simplified" or "FreeBSD" license]
|
|
||||||
https://git.dorkbox.com/dorkbox/Utilities
|
|
||||||
http://www.mindrot.org/projects/jBCrypt
|
|
||||||
Copyright 2006
|
|
||||||
Damien Miller (djm@mindrot.org)
|
|
||||||
GWT modified version
|
|
||||||
|
|
||||||
- Modified hex conversion utility methods -
|
- Modified hex conversion utility methods -
|
||||||
[The Apache Software License, Version 2.0]
|
[The Apache Software License, Version 2.0]
|
||||||
https://git.dorkbox.com/dorkbox/Utilities
|
https://git.dorkbox.com/dorkbox/Utilities
|
||||||
|
@ -181,7 +154,7 @@
|
||||||
|
|
||||||
- Resource Listing - Listing the contents of a resource directory
|
- Resource Listing - Listing the contents of a resource directory
|
||||||
[The Apache Software License, Version 2.0]
|
[The Apache Software License, Version 2.0]
|
||||||
http://www.uofr.net/~greg/java/get-resource-listing.html
|
https://www.uofr.net/~greg/java/get-resource-listing.html
|
||||||
Copyright 2017
|
Copyright 2017
|
||||||
Greg Briggs
|
Greg Briggs
|
||||||
|
|
||||||
|
@ -192,17 +165,12 @@
|
||||||
Pronghorn Technology LLC
|
Pronghorn Technology LLC
|
||||||
Dorkbox LLC
|
Dorkbox LLC
|
||||||
|
|
||||||
- UrlRewriteFilter - UrlRewriteFilter is a Java Web Filter for any J2EE compliant web application server
|
- Kotlin Coroutine CountDownLatch -
|
||||||
[BSD 3-Clause License]
|
|
||||||
https://github.com/paultuckey/urlrewritefilter
|
|
||||||
Copyright 2022
|
|
||||||
Paul Tuckey
|
|
||||||
|
|
||||||
- kotlinx.coroutines - Library support for Kotlin coroutines with multiplatform support
|
|
||||||
[The Apache Software License, Version 2.0]
|
[The Apache Software License, Version 2.0]
|
||||||
https://github.com/Kotlin/kotlinx.coroutines
|
https://github.com/Kotlin/kotlinx.coroutines/issues/59
|
||||||
Copyright 2023
|
https://github.com/venkatperi/kotlin-coroutines-lib
|
||||||
JetBrains s.r.o.
|
Copyright 2018
|
||||||
|
Venkat Peri
|
||||||
|
|
||||||
- Java Uuid Generator - A set of Java classes for working with UUIDs
|
- Java Uuid Generator - A set of Java classes for working with UUIDs
|
||||||
[The Apache Software License, Version 2.0]
|
[The Apache Software License, Version 2.0]
|
||||||
|
@ -211,12 +179,6 @@
|
||||||
Tatu Saloranta (tatu.saloranta@iki.fi)
|
Tatu Saloranta (tatu.saloranta@iki.fi)
|
||||||
Contributors. See source release-notes/CREDITS
|
Contributors. See source release-notes/CREDITS
|
||||||
|
|
||||||
- SLF4J - Simple facade or abstraction for various logging frameworks
|
|
||||||
[MIT License]
|
|
||||||
http://www.slf4j.org
|
|
||||||
Copyright 2023
|
|
||||||
QOS.ch
|
|
||||||
|
|
||||||
- XZ for Java - Complete implementation of XZ data compression in pure Java
|
- XZ for Java - Complete implementation of XZ data compression in pure Java
|
||||||
[Public Domain, per Creative Commons CC0]
|
[Public Domain, per Creative Commons CC0]
|
||||||
https://tukaani.org/xz/java.html
|
https://tukaani.org/xz/java.html
|
||||||
|
@ -224,6 +186,13 @@
|
||||||
Lasse Collin
|
Lasse Collin
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
|
|
||||||
|
- Netty - An event-driven asynchronous network application framework
|
||||||
|
[The Apache Software License, Version 2.0]
|
||||||
|
https://netty.io
|
||||||
|
Copyright 2023
|
||||||
|
The Netty Project
|
||||||
|
Contributors. See source NOTICE
|
||||||
|
|
||||||
- Kotlin -
|
- Kotlin -
|
||||||
[The Apache Software License, Version 2.0]
|
[The Apache Software License, Version 2.0]
|
||||||
https://github.com/JetBrains/kotlin
|
https://github.com/JetBrains/kotlin
|
||||||
|
@ -232,127 +201,16 @@
|
||||||
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
|
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
|
||||||
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
|
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
|
||||||
|
|
||||||
- Netty - An event-driven asynchronous network application framework
|
- kotlinx.coroutines - Library support for Kotlin coroutines with multiplatform support
|
||||||
[The Apache Software License, Version 2.0]
|
[The Apache Software License, Version 2.0]
|
||||||
https://netty.io
|
https://github.com/Kotlin/kotlinx.coroutines
|
||||||
Copyright 2023
|
Copyright 2023
|
||||||
The Netty Project
|
JetBrains s.r.o.
|
||||||
Contributors. See source NOTICE
|
|
||||||
|
|
||||||
- Bouncy Castle Crypto - Lightweight cryptography API and JCE Extension
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
http://www.bouncycastle.org
|
|
||||||
Copyright 2023
|
|
||||||
The Legion of the Bouncy Castle Inc
|
|
||||||
|
|
||||||
- Lightweight Java Game Library - Java library that enables cross-platform access to popular native APIs
|
|
||||||
[BSD 3-Clause License]
|
|
||||||
https://github.com/LWJGL/lwjgl3
|
|
||||||
Copyright 2023
|
|
||||||
Lightweight Java Game Library
|
|
||||||
|
|
||||||
- TypeTools - A simple, zero-dependency library for working with types. Supports Java 1.6+ and Android.
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://github.com/jhalterman/typetools
|
|
||||||
Copyright 2023
|
|
||||||
Jonathan Halterman and friends
|
|
||||||
|
|
||||||
- Collections - Niche collections to augment what is already available.
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://git.dorkbox.com/dorkbox/Collections
|
|
||||||
Copyright 2022
|
|
||||||
Dorkbox LLC
|
|
||||||
|
|
||||||
Extra license information
|
|
||||||
- AhoCorasickDoubleArrayTrie - Niche collections to augment what is already available.
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://github.com/hankcs/AhoCorasickDoubleArrayTrie
|
|
||||||
Copyright 2018
|
|
||||||
hankcs <me@hankcs.com>
|
|
||||||
|
|
||||||
- Bias, BinarySearch -
|
|
||||||
[MIT License]
|
|
||||||
https://git.dorkbox.com/dorkbox/Collections
|
|
||||||
https://github.com/timboudreau/util
|
|
||||||
Copyright 2013
|
|
||||||
Tim Boudreau
|
|
||||||
|
|
||||||
- ConcurrentEntry -
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://git.dorkbox.com/dorkbox/Collections
|
|
||||||
Copyright 2016
|
|
||||||
bennidi
|
|
||||||
dorkbox
|
|
||||||
|
|
||||||
- Collection Utilities (Array, ArrayMap, BooleanArray, ByteArray, CharArray, FloatArray, IdentityMap, IntArray, IntFloatMap, IntIntMap, IntMap, IntSet, LongArray, LongMap, ObjectFloatMap, ObjectIntMap, ObjectMap, ObjectSet, OrderedMap, OrderedSet) -
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://git.dorkbox.com/dorkbox/Collections
|
|
||||||
https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/utils
|
|
||||||
Copyright 2011
|
|
||||||
LibGDX
|
|
||||||
Mario Zechner (badlogicgames@gmail.com)
|
|
||||||
Nathan Sweet (nathan.sweet@gmail.com)
|
|
||||||
|
|
||||||
- Predicate -
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://git.dorkbox.com/dorkbox/Collections
|
|
||||||
https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/utils
|
|
||||||
Copyright 2011
|
|
||||||
LibGDX
|
|
||||||
Mario Zechner (badlogicgames@gmail.com)
|
|
||||||
Nathan Sweet (nathan.sweet@gmail.com)
|
|
||||||
xoppa
|
|
||||||
|
|
||||||
- Select, QuickSelect -
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://git.dorkbox.com/dorkbox/Collections
|
|
||||||
https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/utils
|
|
||||||
Copyright 2011
|
|
||||||
LibGDX
|
|
||||||
Mario Zechner (badlogicgames@gmail.com)
|
|
||||||
Nathan Sweet (nathan.sweet@gmail.com)
|
|
||||||
Jon Renner
|
|
||||||
|
|
||||||
- TimSort, ComparableTimSort -
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://git.dorkbox.com/dorkbox/Collections
|
|
||||||
https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/utils
|
|
||||||
Copyright 2008
|
|
||||||
The Android Open Source Project
|
|
||||||
|
|
||||||
- ConcurrentWeakIdentityHashMap - Concurrent WeakIdentity HashMap
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://github.com/spring-projects/spring-loaded/blob/master/springloaded/src/main/java/org/springsource/loaded/support/ConcurrentWeakIdentityHashMap.java
|
|
||||||
Copyright 2016
|
|
||||||
zhanhb
|
|
||||||
|
|
||||||
- Kotlin -
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://github.com/JetBrains/kotlin
|
|
||||||
Copyright 2020
|
|
||||||
JetBrains s.r.o. and Kotlin Programming Language contributors
|
|
||||||
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
|
|
||||||
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
|
|
||||||
|
|
||||||
- Updates - Software Update Management
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://git.dorkbox.com/dorkbox/Updates
|
|
||||||
Copyright 2021
|
|
||||||
Dorkbox LLC
|
|
||||||
|
|
||||||
Extra license information
|
|
||||||
- Kotlin -
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://github.com/JetBrains/kotlin
|
|
||||||
Copyright 2020
|
|
||||||
JetBrains s.r.o. and Kotlin Programming Language contributors
|
|
||||||
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
|
|
||||||
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
|
|
||||||
|
|
||||||
- Executor - Shell, JVM, and SSH command execution on Linux, MacOS, or Windows for Java 8+
|
- Executor - Shell, JVM, and SSH command execution on Linux, MacOS, or Windows for Java 8+
|
||||||
[The Apache Software License, Version 2.0]
|
[The Apache Software License, Version 2.0]
|
||||||
https://git.dorkbox.com/dorkbox/Executor
|
https://git.dorkbox.com/dorkbox/Executor
|
||||||
Copyright 2022
|
Copyright 2023
|
||||||
Dorkbox LLC
|
Dorkbox LLC
|
||||||
|
|
||||||
Extra license information
|
Extra license information
|
||||||
|
@ -379,25 +237,25 @@
|
||||||
- kotlinx.coroutines - Library support for Kotlin coroutines with multiplatform support
|
- kotlinx.coroutines - Library support for Kotlin coroutines with multiplatform support
|
||||||
[The Apache Software License, Version 2.0]
|
[The Apache Software License, Version 2.0]
|
||||||
https://github.com/Kotlin/kotlinx.coroutines
|
https://github.com/Kotlin/kotlinx.coroutines
|
||||||
Copyright 2022
|
Copyright 2023
|
||||||
JetBrains s.r.o.
|
JetBrains s.r.o.
|
||||||
|
|
||||||
- SLF4J - Simple facade or abstraction for various logging frameworks
|
- SLF4J - Simple facade or abstraction for various logging frameworks
|
||||||
[MIT License]
|
[MIT License]
|
||||||
http://www.slf4j.org
|
https://www.slf4j.org
|
||||||
Copyright 2022
|
Copyright 2023
|
||||||
QOS.ch
|
QOS.ch
|
||||||
|
|
||||||
- Logback - Logback is a logging framework for Java applications
|
- Logback - Logback is a logging framework for Java applications
|
||||||
[The Apache Software License, Version 2.0]
|
[The Apache Software License, Version 2.0]
|
||||||
http://logback.qos.ch
|
https://logback.qos.ch
|
||||||
Copyright 2022
|
Copyright 2023
|
||||||
QOS.ch
|
QOS.ch
|
||||||
|
|
||||||
- SSHJ - SSHv2 library for Java
|
- SSHJ - SSHv2 library for Java
|
||||||
[The Apache Software License, Version 2.0]
|
[The Apache Software License, Version 2.0]
|
||||||
https://github.com/hierynomus/sshj
|
https://github.com/hierynomus/sshj
|
||||||
Copyright 2022
|
Copyright 2023
|
||||||
Jeroen van Erp
|
Jeroen van Erp
|
||||||
SSHJ Contributors
|
SSHJ Contributors
|
||||||
|
|
||||||
|
@ -414,13 +272,13 @@
|
||||||
|
|
||||||
- JZlib -
|
- JZlib -
|
||||||
[The Apache Software License, Version 2.0]
|
[The Apache Software License, Version 2.0]
|
||||||
http://www.jcraft.com/jzlib
|
https://github.com/ymnk/jzlib
|
||||||
Atsuhiko Yamanaka
|
Atsuhiko Yamanaka
|
||||||
JCraft, Inc.
|
JCraft, Inc.
|
||||||
|
|
||||||
- Bouncy Castle Crypto -
|
- Bouncy Castle Crypto -
|
||||||
[The Apache Software License, Version 2.0]
|
[The Apache Software License, Version 2.0]
|
||||||
http://www.bouncycastle.org
|
https://www.bouncycastle.org
|
||||||
The Legion of the Bouncy Castle Inc
|
The Legion of the Bouncy Castle Inc
|
||||||
|
|
||||||
- ed25519-java -
|
- ed25519-java -
|
||||||
|
@ -443,169 +301,6 @@
|
||||||
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
|
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
|
||||||
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
|
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
|
||||||
|
|
||||||
- NetworkUtils - Utilities for managing network configurations, IP/MAC address conversion, and ping (via OS native commands)
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://git.dorkbox.com/dorkbox/NetworkUtils
|
|
||||||
Copyright 2022
|
|
||||||
Dorkbox LLC
|
|
||||||
|
|
||||||
Extra license information
|
|
||||||
- Netty -
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://netty.io/
|
|
||||||
Copyright 2014
|
|
||||||
The Netty Project
|
|
||||||
This product contains a modified portion of Netty Network Utils
|
|
||||||
|
|
||||||
- Apache Harmony -
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
http://archive.apache.org/dist/harmony/
|
|
||||||
Copyright 2010
|
|
||||||
The Apache Software Foundation
|
|
||||||
This product contains a modified portion of 'Apache Harmony', an open source Java SE
|
|
||||||
|
|
||||||
- Apache HTTP Utils -
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/psl/
|
|
||||||
Copyright 2010
|
|
||||||
The Apache Software Foundation
|
|
||||||
This product contains a modified portion of 'PublicSuffixDomainFilter.java'
|
|
||||||
|
|
||||||
- SLF4J - Simple facade or abstraction for various logging frameworks
|
|
||||||
[MIT License]
|
|
||||||
http://www.slf4j.org
|
|
||||||
Copyright 2022
|
|
||||||
QOS.ch
|
|
||||||
|
|
||||||
- JNA - Simplified native library access for Java.
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://github.com/twall/jna
|
|
||||||
Copyright 2022
|
|
||||||
Timothy Wall
|
|
||||||
|
|
||||||
- JNA-Platform - Mappings for a number of commonly used platform functions
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://github.com/twall/jna
|
|
||||||
Copyright 2022
|
|
||||||
Timothy Wall
|
|
||||||
|
|
||||||
- Kotlin -
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://github.com/JetBrains/kotlin
|
|
||||||
Copyright 2020
|
|
||||||
JetBrains s.r.o. and Kotlin Programming Language contributors
|
|
||||||
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
|
|
||||||
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
|
|
||||||
|
|
||||||
- Executor - Shell, JVM, and SSH command execution on Linux, MacOS, or Windows for Java 8+
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://git.dorkbox.com/dorkbox/Executor
|
|
||||||
Copyright 2022
|
|
||||||
Dorkbox LLC
|
|
||||||
|
|
||||||
Extra license information
|
|
||||||
- ZT Process Executor -
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://github.com/zeroturnaround/zt-exec
|
|
||||||
Copyright 2014
|
|
||||||
ZeroTurnaround LLC
|
|
||||||
|
|
||||||
- Apache Commons Exec -
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://commons.apache.org/proper/commons-exec/
|
|
||||||
Copyright 2014
|
|
||||||
The Apache Software Foundation
|
|
||||||
|
|
||||||
- Kotlin -
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://github.com/JetBrains/kotlin
|
|
||||||
Copyright 2020
|
|
||||||
JetBrains s.r.o. and Kotlin Programming Language contributors
|
|
||||||
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
|
|
||||||
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
|
|
||||||
|
|
||||||
- kotlinx.coroutines - Library support for Kotlin coroutines with multiplatform support
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://github.com/Kotlin/kotlinx.coroutines
|
|
||||||
Copyright 2022
|
|
||||||
JetBrains s.r.o.
|
|
||||||
|
|
||||||
- SLF4J - Simple facade or abstraction for various logging frameworks
|
|
||||||
[MIT License]
|
|
||||||
http://www.slf4j.org
|
|
||||||
Copyright 2022
|
|
||||||
QOS.ch
|
|
||||||
|
|
||||||
- Logback - Logback is a logging framework for Java applications
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
http://logback.qos.ch
|
|
||||||
Copyright 2022
|
|
||||||
QOS.ch
|
|
||||||
|
|
||||||
- SSHJ - SSHv2 library for Java
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://github.com/hierynomus/sshj
|
|
||||||
Copyright 2022
|
|
||||||
Jeroen van Erp
|
|
||||||
SSHJ Contributors
|
|
||||||
|
|
||||||
Extra license information
|
|
||||||
- Apache MINA -
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://mina.apache.org/sshd-project/
|
|
||||||
The Apache Software Foundation
|
|
||||||
|
|
||||||
- Apache Commons-Net -
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://commons.apache.org/proper/commons-net/
|
|
||||||
The Apache Software Foundation
|
|
||||||
|
|
||||||
- JZlib -
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
http://www.jcraft.com/jzlib
|
|
||||||
Atsuhiko Yamanaka
|
|
||||||
JCraft, Inc.
|
|
||||||
|
|
||||||
- Bouncy Castle Crypto -
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
http://www.bouncycastle.org
|
|
||||||
The Legion of the Bouncy Castle Inc
|
|
||||||
|
|
||||||
- ed25519-java -
|
|
||||||
[Public Domain, per Creative Commons CC0]
|
|
||||||
https://github.com/str4d/ed25519-java
|
|
||||||
https://github.com/str4d
|
|
||||||
|
|
||||||
- Updates - Software Update Management
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://git.dorkbox.com/dorkbox/Updates
|
|
||||||
Copyright 2021
|
|
||||||
Dorkbox LLC
|
|
||||||
|
|
||||||
Extra license information
|
|
||||||
- Kotlin -
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://github.com/JetBrains/kotlin
|
|
||||||
Copyright 2020
|
|
||||||
JetBrains s.r.o. and Kotlin Programming Language contributors
|
|
||||||
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
|
|
||||||
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
|
|
||||||
|
|
||||||
- Updates - Software Update Management
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://git.dorkbox.com/dorkbox/Updates
|
|
||||||
Copyright 2021
|
|
||||||
Dorkbox LLC
|
|
||||||
|
|
||||||
Extra license information
|
|
||||||
- Kotlin -
|
|
||||||
[The Apache Software License, Version 2.0]
|
|
||||||
https://github.com/JetBrains/kotlin
|
|
||||||
Copyright 2020
|
|
||||||
JetBrains s.r.o. and Kotlin Programming Language contributors
|
|
||||||
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
|
|
||||||
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
|
|
||||||
|
|
||||||
- OS - Information about the system, Java runtime, OS, Window Manager, and Desktop Environment.
|
- OS - Information about the system, Java runtime, OS, Window Manager, and Desktop Environment.
|
||||||
[The Apache Software License, Version 2.0]
|
[The Apache Software License, Version 2.0]
|
||||||
https://git.dorkbox.com/dorkbox/OS
|
https://git.dorkbox.com/dorkbox/OS
|
||||||
|
|
22
LICENSE.BSD2
22
LICENSE.BSD2
|
@ -1,22 +0,0 @@
|
||||||
BSD License
|
|
||||||
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL <ORGANIZATION> BE LIABLE FOR ANY
|
|
||||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2021 dorkbox, llc
|
* Copyright 2023 dorkbox, llc
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -26,10 +26,12 @@ gradle.startParameter.showStacktrace = ShowStacktrace.ALWAYS // always show th
|
||||||
gradle.startParameter.warningMode = WarningMode.All
|
gradle.startParameter.warningMode = WarningMode.All
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("com.dorkbox.GradleUtils") version "3.9"
|
id("com.dorkbox.GradleUtils") version "3.17"
|
||||||
id("com.dorkbox.Licensing") version "2.19.1"
|
id("com.dorkbox.Licensing") version "2.25"
|
||||||
id("com.dorkbox.VersionUpdate") version "2.5"
|
id("com.dorkbox.VersionUpdate") version "2.8"
|
||||||
id("com.dorkbox.GradlePublish") version "1.17"
|
id("com.dorkbox.GradlePublish") version "1.18"
|
||||||
|
|
||||||
|
kotlin("jvm") version "1.8.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
object Extras {
|
object Extras {
|
||||||
|
@ -44,8 +46,6 @@ object Extras {
|
||||||
const val vendor = "Dorkbox LLC"
|
const val vendor = "Dorkbox LLC"
|
||||||
const val vendorUrl = "https://dorkbox.com"
|
const val vendorUrl = "https://dorkbox.com"
|
||||||
const val url = "https://git.dorkbox.com/dorkbox/CabParser"
|
const val url = "https://git.dorkbox.com/dorkbox/CabParser"
|
||||||
|
|
||||||
val buildDate = Instant.now().toString()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
@ -64,6 +64,19 @@ licensing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// make java source available to kotlin
|
||||||
|
kotlin {
|
||||||
|
sourceSets {
|
||||||
|
main {
|
||||||
|
// we have some java we depend on
|
||||||
|
kotlin.include("**/*.java", "**/*.kt")
|
||||||
|
}
|
||||||
|
test {
|
||||||
|
kotlin.include("**/*.java", "**/*.kt")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tasks.jar.get().apply {
|
tasks.jar.get().apply {
|
||||||
manifest {
|
manifest {
|
||||||
// https://docs.oracle.com/javase/tutorial/deployment/jar/packageman.html
|
// https://docs.oracle.com/javase/tutorial/deployment/jar/packageman.html
|
||||||
|
@ -74,15 +87,15 @@ tasks.jar.get().apply {
|
||||||
attributes["Specification-Vendor"] = Extras.vendor
|
attributes["Specification-Vendor"] = Extras.vendor
|
||||||
|
|
||||||
attributes["Implementation-Title"] = "${Extras.group}.${Extras.id}"
|
attributes["Implementation-Title"] = "${Extras.group}.${Extras.id}"
|
||||||
attributes["Implementation-Version"] = Extras.buildDate
|
attributes["Implementation-Version"] = GradleUtils.now()
|
||||||
attributes["Implementation-Vendor"] = Extras.vendor
|
attributes["Implementation-Vendor"] = Extras.vendor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api("com.dorkbox:ByteUtilities:1.6")
|
api("com.dorkbox:ByteUtilities:1.13")
|
||||||
api("com.dorkbox:Updates:1.1")
|
api("com.dorkbox:Updates:1.1")
|
||||||
api("com.dorkbox:Utilities:1.39")
|
api("com.dorkbox:Utilities:1.44")
|
||||||
}
|
}
|
||||||
|
|
||||||
publishToSonatype {
|
publishToSonatype {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012 dorkbox, llc
|
* Copyright 2023 dorkbox, llc
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -13,15 +13,9 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package dorkbox.cabParser;
|
package dorkbox.cabParser
|
||||||
|
|
||||||
public class CabException extends Exception {
|
open class CabException : Exception {
|
||||||
private static final long serialVersionUID = 1L;
|
constructor(errorMessage: String?) : super(errorMessage)
|
||||||
|
constructor()
|
||||||
public CabException(String errorMessage) {
|
|
||||||
super(errorMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CabException() {
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,142 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 dorkbox, llc
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package dorkbox.cabParser;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
final class CabInputStream extends InputStream {
|
|
||||||
private InputStream inputStream;
|
|
||||||
|
|
||||||
private long position;
|
|
||||||
private long a;
|
|
||||||
|
|
||||||
private boolean markSupported;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException {
|
|
||||||
this.inputStream.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void reset() throws IOException {
|
|
||||||
if (this.markSupported) {
|
|
||||||
this.inputStream.reset();
|
|
||||||
this.position = this.a;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw new IOException();
|
|
||||||
}
|
|
||||||
|
|
||||||
CabInputStream(InputStream inputStream) {
|
|
||||||
this.inputStream = inputStream;
|
|
||||||
this.position = 0L;
|
|
||||||
this.markSupported = this.inputStream.markSupported();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int read() throws IOException {
|
|
||||||
int i = this.inputStream.read();
|
|
||||||
if (i >= 0) {
|
|
||||||
this.position += 1L;
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int read(byte[] bytes) throws IOException {
|
|
||||||
int i = this.inputStream.read(bytes);
|
|
||||||
if (i > 0) {
|
|
||||||
this.position += i;
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int read(byte[] bytes, int offset, int length) throws IOException {
|
|
||||||
int i = this.inputStream.read(bytes, offset, length);
|
|
||||||
if (i > 0) {
|
|
||||||
this.position += i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int available() throws IOException {
|
|
||||||
throw new IOException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void mark(int paramInt) {
|
|
||||||
if (this.markSupported) {
|
|
||||||
this.a = this.position;
|
|
||||||
this.inputStream.mark(paramInt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getCurrentPosition() {
|
|
||||||
return this.position;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean markSupported() {
|
|
||||||
return this.markSupported;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void seek(long location) throws IOException {
|
|
||||||
if (location < this.position) {
|
|
||||||
throw new IOException("Cannot seek backwards");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (location > this.position) {
|
|
||||||
skip(location - this.position);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long skip(long ammount) throws IOException {
|
|
||||||
long l = betterSkip(this.inputStream, ammount);
|
|
||||||
this.position += (int) l;
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reliably skips over and discards n bytes of data from the input stream
|
|
||||||
* @param is input stream
|
|
||||||
* @param n the number of bytes to be skipped
|
|
||||||
* @return the actual number of bytes skipped
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public static long betterSkip(InputStream is, long n) throws IOException {
|
|
||||||
long left = n;
|
|
||||||
while(left > 0) {
|
|
||||||
long l = is.skip(left);
|
|
||||||
if(l > 0) {
|
|
||||||
left -= l;
|
|
||||||
} else if(l == 0) { // should we retry? lets read one byte
|
|
||||||
if(is.read() == -1) // EOF
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
left--;
|
|
||||||
} else {
|
|
||||||
throw new IOException("skip() returned a negative value. This should never happen");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n - left;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,141 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 dorkbox, llc
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package dorkbox.cabParser
|
||||||
|
|
||||||
|
import java.io.IOException
|
||||||
|
import java.io.InputStream
|
||||||
|
|
||||||
|
internal class CabInputStream(private val inputStream: InputStream) : InputStream() {
|
||||||
|
companion object {
|
||||||
|
/**
|
||||||
|
* Reliably skips over and discards n bytes of data from the input stream
|
||||||
|
* @param is input stream
|
||||||
|
* @param n the number of bytes to be skipped
|
||||||
|
* @return the actual number of bytes skipped
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@Throws(IOException::class)
|
||||||
|
fun betterSkip(`is`: InputStream, n: Long): Long {
|
||||||
|
var left = n
|
||||||
|
while (left > 0) {
|
||||||
|
val l = `is`.skip(left)
|
||||||
|
if (l > 0) {
|
||||||
|
left -= l
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (l == 0L) { // should we retry? lets read one byte
|
||||||
|
if (`is`.read() == -1) // EOF
|
||||||
|
break
|
||||||
|
else left--
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw IOException("skip() returned a negative value. This should never happen")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n - left
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentPosition = 0L
|
||||||
|
private set
|
||||||
|
|
||||||
|
private var a: Long = 0
|
||||||
|
private val markSupported: Boolean
|
||||||
|
|
||||||
|
init {
|
||||||
|
markSupported = inputStream.markSupported()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override fun close() {
|
||||||
|
inputStream.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override fun reset() {
|
||||||
|
if (markSupported) {
|
||||||
|
inputStream.reset()
|
||||||
|
currentPosition = a
|
||||||
|
return
|
||||||
|
}
|
||||||
|
throw IOException()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override fun read(): Int {
|
||||||
|
val i = inputStream.read()
|
||||||
|
if (i >= 0) {
|
||||||
|
currentPosition += 1L
|
||||||
|
}
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override fun read(bytes: ByteArray): Int {
|
||||||
|
val i = inputStream.read(bytes)
|
||||||
|
if (i > 0) {
|
||||||
|
currentPosition += i.toLong()
|
||||||
|
}
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override fun read(bytes: ByteArray, offset: Int, length: Int): Int {
|
||||||
|
val i = inputStream.read(bytes, offset, length)
|
||||||
|
if (i > 0) {
|
||||||
|
currentPosition += i.toLong()
|
||||||
|
}
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override fun available(): Int {
|
||||||
|
throw IOException()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
override fun mark(paramInt: Int) {
|
||||||
|
if (markSupported) {
|
||||||
|
a = currentPosition
|
||||||
|
inputStream.mark(paramInt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun markSupported(): Boolean {
|
||||||
|
return markSupported
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
fun seek(location: Long) {
|
||||||
|
if (location < currentPosition) {
|
||||||
|
throw IOException("Cannot seek backwards")
|
||||||
|
}
|
||||||
|
if (location > currentPosition) {
|
||||||
|
skip(location - currentPosition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override fun skip(ammount: Long): Long {
|
||||||
|
val l = betterSkip(inputStream, ammount)
|
||||||
|
currentPosition += l.toInt().toLong()
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -1,207 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 dorkbox, llc
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package dorkbox.cabParser;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
|
|
||||||
import dorkbox.cabParser.decompress.CabDecompressor;
|
|
||||||
import dorkbox.cabParser.structure.CabEnumerator;
|
|
||||||
import dorkbox.cabParser.structure.CabFileEntry;
|
|
||||||
import dorkbox.cabParser.structure.CabFolderEntry;
|
|
||||||
import dorkbox.cabParser.structure.CabHeader;
|
|
||||||
|
|
||||||
public final class CabParser {
|
|
||||||
/**
|
|
||||||
* Gets the version number.
|
|
||||||
*/
|
|
||||||
public static
|
|
||||||
String getVersion() {
|
|
||||||
return "3.2";
|
|
||||||
}
|
|
||||||
|
|
||||||
static {
|
|
||||||
// Add this project to the updates system, which verifies this class + UUID + version information
|
|
||||||
dorkbox.updates.Updates.INSTANCE.add(CabParser.class, "41f560ca51c04bfdbca21328e0cbf206", getVersion());
|
|
||||||
}
|
|
||||||
|
|
||||||
private CabInputStream cabInputStream;
|
|
||||||
|
|
||||||
private CabStreamSaver streamSaver;
|
|
||||||
private ByteArrayOutputStream outputStream = null;
|
|
||||||
|
|
||||||
public CabHeader header;
|
|
||||||
|
|
||||||
public CabFolderEntry[] folders;
|
|
||||||
public CabFileEntry[] files;
|
|
||||||
|
|
||||||
public
|
|
||||||
CabParser(InputStream inputStream, final String fileNameToExtract) throws CabException, IOException {
|
|
||||||
if (fileNameToExtract == null || fileNameToExtract.isEmpty()) {
|
|
||||||
throw new IllegalArgumentException("Filename must be valid!");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.cabInputStream = new CabInputStream(inputStream);
|
|
||||||
this.streamSaver = new CabStreamSaver() {
|
|
||||||
@Override
|
|
||||||
public boolean saveReservedAreaData(byte[] data, int dataLength) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public OutputStream openOutputStream(CabFileEntry cabFile) {
|
|
||||||
String name = cabFile.getName();
|
|
||||||
if (fileNameToExtract.equalsIgnoreCase(name)) {
|
|
||||||
CabParser.this.outputStream = new ByteArrayOutputStream((int) cabFile.getSize());
|
|
||||||
return CabParser.this.outputStream;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void closeOutputStream(OutputStream outputStream, CabFileEntry cabFile) {
|
|
||||||
if (outputStream != null) {
|
|
||||||
try {
|
|
||||||
outputStream.close();
|
|
||||||
} catch (IOException ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
readData();
|
|
||||||
}
|
|
||||||
|
|
||||||
public
|
|
||||||
CabParser(InputStream inputStream, CabStreamSaver streamSaver) throws CabException, IOException {
|
|
||||||
this.streamSaver = streamSaver;
|
|
||||||
this.cabInputStream = new CabInputStream(inputStream);
|
|
||||||
|
|
||||||
readData();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public
|
|
||||||
CabParser(InputStream inputStream, File extractPath) throws CabException, IOException {
|
|
||||||
this.streamSaver = new DefaultCabStreamSaver(extractPath);
|
|
||||||
this.cabInputStream = new CabInputStream(inputStream);
|
|
||||||
|
|
||||||
readData();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Enumeration<Object> entries() {
|
|
||||||
return new CabEnumerator(this, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Enumeration<Object> entries(boolean b) {
|
|
||||||
return new CabEnumerator(this, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void readData() throws CabException, IOException {
|
|
||||||
this.header = new CabHeader(this.streamSaver);
|
|
||||||
this.header.read(this.cabInputStream);
|
|
||||||
this.folders = new CabFolderEntry[this.header.cFolders];
|
|
||||||
for (int i = 0; i < this.header.cFolders; i++) {
|
|
||||||
this.folders[i] = new CabFolderEntry();
|
|
||||||
this.folders[i].read(this.cabInputStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.files = new CabFileEntry[this.header.cFiles];
|
|
||||||
this.cabInputStream.seek(this.header.coffFiles);
|
|
||||||
|
|
||||||
for (int i = 0; i < this.header.cFiles; i++) {
|
|
||||||
this.files[i] = new CabFileEntry();
|
|
||||||
this.files[i].read(this.cabInputStream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ByteArrayOutputStream extractStream() throws CabException, IOException {
|
|
||||||
int folderCount = -1;
|
|
||||||
int currentCount = 0;
|
|
||||||
int totalCount = 0;
|
|
||||||
boolean init = true;
|
|
||||||
|
|
||||||
CabDecompressor extractor = new CabDecompressor(this.cabInputStream, this.header.cbCFData);
|
|
||||||
|
|
||||||
for (int fileIndex = 0; fileIndex < this.header.cFiles; fileIndex++) {
|
|
||||||
CabFileEntry entry = this.files[fileIndex];
|
|
||||||
|
|
||||||
if (entry.iFolder != folderCount) {
|
|
||||||
if (folderCount + 1 >= this.header.cFolders) {
|
|
||||||
throw new CorruptCabException();
|
|
||||||
}
|
|
||||||
|
|
||||||
folderCount++;
|
|
||||||
init = true;
|
|
||||||
currentCount = 0;
|
|
||||||
totalCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
OutputStream localOutputStream = this.streamSaver.openOutputStream(entry);
|
|
||||||
if (localOutputStream != null) {
|
|
||||||
if (init) {
|
|
||||||
CabFolderEntry cabFolderEntry = this.folders[folderCount];
|
|
||||||
|
|
||||||
this.cabInputStream.seek(cabFolderEntry.coffCabStart);
|
|
||||||
extractor.initialize(cabFolderEntry.compressionMethod);
|
|
||||||
init = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentCount != totalCount) {
|
|
||||||
extractor.read(totalCount - currentCount, new OutputStream() {
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
void write(int i) throws IOException {
|
|
||||||
//do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
void write(byte[] b) throws IOException {
|
|
||||||
//do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
void write(byte[] b, int off, int len) throws IOException {
|
|
||||||
//do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
void flush() throws IOException {
|
|
||||||
//do nothing
|
|
||||||
}
|
|
||||||
});
|
|
||||||
currentCount = totalCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
extractor.read(entry.cbFile, localOutputStream);
|
|
||||||
this.streamSaver.closeOutputStream(localOutputStream, entry);
|
|
||||||
currentCount = (int) (currentCount + entry.cbFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
totalCount = (int) (totalCount + entry.cbFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.outputStream;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,178 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 dorkbox, llc
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package dorkbox.cabParser
|
||||||
|
|
||||||
|
import dorkbox.cabParser.decompress.CabDecompressor
|
||||||
|
import dorkbox.cabParser.structure.CabEnumerator
|
||||||
|
import dorkbox.cabParser.structure.CabFileEntry
|
||||||
|
import dorkbox.cabParser.structure.CabFolderEntry
|
||||||
|
import dorkbox.cabParser.structure.CabHeader
|
||||||
|
import dorkbox.updates.Updates.add
|
||||||
|
import java.io.*
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class CabParser {
|
||||||
|
companion object {
|
||||||
|
/**
|
||||||
|
* Gets the version number.
|
||||||
|
*/
|
||||||
|
const val version: String = "3.2"
|
||||||
|
|
||||||
|
init {
|
||||||
|
// Add this project to the updates system, which verifies this class + UUID + version information
|
||||||
|
add(CabParser::class.java, "41f560ca51c04bfdbca21328e0cbf206", version)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var cabInputStream: CabInputStream
|
||||||
|
private var streamSaver: CabStreamSaver
|
||||||
|
private var outputStream: ByteArrayOutputStream? = null
|
||||||
|
|
||||||
|
lateinit var header: CabHeader
|
||||||
|
|
||||||
|
lateinit var folders: Array<CabFolderEntry>
|
||||||
|
|
||||||
|
lateinit var files: Array<CabFileEntry>
|
||||||
|
|
||||||
|
constructor(inputStream: InputStream, fileNameToExtract: String) {
|
||||||
|
cabInputStream = CabInputStream(inputStream)
|
||||||
|
streamSaver = object : CabStreamSaver {
|
||||||
|
override fun saveReservedAreaData(data: ByteArray?, dataLength: Int): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun openOutputStream(entry: CabFileEntry): OutputStream? {
|
||||||
|
val name = entry.name
|
||||||
|
return if (fileNameToExtract.equals(name, ignoreCase = true)) {
|
||||||
|
outputStream = ByteArrayOutputStream(entry.size.toInt())
|
||||||
|
outputStream!!
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun closeOutputStream(outputStream: OutputStream, cabFile: CabFileEntry) {
|
||||||
|
try {
|
||||||
|
outputStream.close()
|
||||||
|
}
|
||||||
|
catch (ignored: IOException) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
readData()
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(inputStream: InputStream, streamSaver: CabStreamSaver) {
|
||||||
|
this.streamSaver = streamSaver
|
||||||
|
cabInputStream = CabInputStream(inputStream)
|
||||||
|
readData()
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(inputStream: InputStream, extractPath: File?) {
|
||||||
|
streamSaver = DefaultCabStreamSaver(extractPath)
|
||||||
|
cabInputStream = CabInputStream(inputStream)
|
||||||
|
readData()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun entries(): Enumeration<Any> {
|
||||||
|
return CabEnumerator(this, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun entries(b: Boolean): Enumeration<Any> {
|
||||||
|
return CabEnumerator(this, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
@Throws(CabException::class, IOException::class)
|
||||||
|
private fun readData() {
|
||||||
|
header = CabHeader(streamSaver)
|
||||||
|
header.read(cabInputStream)
|
||||||
|
folders = arrayOfNulls<CabFolderEntry>(header.cFolders) as Array<CabFolderEntry>
|
||||||
|
|
||||||
|
for (i in 0 until header.cFolders) {
|
||||||
|
folders[i] = CabFolderEntry()
|
||||||
|
folders[i].read(cabInputStream)
|
||||||
|
}
|
||||||
|
|
||||||
|
files = arrayOfNulls<CabFileEntry>(header.cFiles) as Array<CabFileEntry>
|
||||||
|
cabInputStream.seek(header.coffFiles)
|
||||||
|
for (i in 0 until header.cFiles) {
|
||||||
|
files[i] = CabFileEntry()
|
||||||
|
files[i].read(cabInputStream)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(CabException::class, IOException::class)
|
||||||
|
fun extractStream(): ByteArrayOutputStream? {
|
||||||
|
var folderCount = -1
|
||||||
|
var currentCount = 0
|
||||||
|
var totalCount = 0
|
||||||
|
var init = true
|
||||||
|
val extractor = CabDecompressor(cabInputStream, header.cbCFData)
|
||||||
|
for (fileIndex in 0 until header.cFiles) {
|
||||||
|
val entry = files[fileIndex]
|
||||||
|
if (entry.iFolder != folderCount) {
|
||||||
|
if (folderCount + 1 >= header.cFolders) {
|
||||||
|
throw CorruptCabException()
|
||||||
|
}
|
||||||
|
|
||||||
|
folderCount++
|
||||||
|
init = true
|
||||||
|
currentCount = 0
|
||||||
|
totalCount = 0
|
||||||
|
}
|
||||||
|
val localOutputStream = streamSaver.openOutputStream(entry)
|
||||||
|
if (localOutputStream != null) {
|
||||||
|
if (init) {
|
||||||
|
val cabFolderEntry = folders[folderCount]
|
||||||
|
cabInputStream.seek(cabFolderEntry.coffCabStart)
|
||||||
|
extractor.initialize(cabFolderEntry.compressionMethod)
|
||||||
|
init = false
|
||||||
|
}
|
||||||
|
if (currentCount != totalCount) {
|
||||||
|
extractor.read((totalCount - currentCount).toLong(), object : OutputStream() {
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override fun write(i: Int) {
|
||||||
|
//do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override fun write(b: ByteArray) {
|
||||||
|
//do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override fun write(b: ByteArray, off: Int, len: Int) {
|
||||||
|
//do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override fun flush() {
|
||||||
|
//do nothing
|
||||||
|
}
|
||||||
|
})
|
||||||
|
currentCount = totalCount
|
||||||
|
}
|
||||||
|
extractor.read(entry.cbFile, localOutputStream)
|
||||||
|
streamSaver.closeOutputStream(localOutputStream, entry)
|
||||||
|
currentCount = (currentCount + entry.cbFile).toInt()
|
||||||
|
}
|
||||||
|
totalCount = (totalCount + entry.cbFile).toInt()
|
||||||
|
}
|
||||||
|
return outputStream
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012 dorkbox, llc
|
* Copyright 2023 dorkbox, llc
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -13,14 +13,13 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package dorkbox.cabParser;
|
package dorkbox.cabParser
|
||||||
|
|
||||||
import java.io.OutputStream;
|
import dorkbox.cabParser.structure.CabFileEntry
|
||||||
|
import java.io.OutputStream
|
||||||
|
|
||||||
import dorkbox.cabParser.structure.CabFileEntry;
|
interface CabStreamSaver {
|
||||||
|
fun openOutputStream(entry: CabFileEntry): OutputStream?
|
||||||
public interface CabStreamSaver {
|
fun closeOutputStream(outputStream: OutputStream, entry: CabFileEntry)
|
||||||
OutputStream openOutputStream(CabFileEntry entry);
|
fun saveReservedAreaData(data: ByteArray?, dataLength: Int): Boolean
|
||||||
void closeOutputStream(OutputStream outputStream, CabFileEntry entry);
|
|
||||||
boolean saveReservedAreaData(byte[] data, int dataLength);
|
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012 dorkbox, llc
|
* Copyright 2023 dorkbox, llc
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -13,16 +13,9 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package dorkbox.cabParser;
|
package dorkbox.cabParser
|
||||||
|
|
||||||
|
class CorruptCabException : CabException {
|
||||||
public final class CorruptCabException extends CabException {
|
constructor(errorMessage: String?) : super(errorMessage)
|
||||||
private static final long serialVersionUID = 1L;
|
constructor()
|
||||||
|
|
||||||
public CorruptCabException(String errorMessage) {
|
|
||||||
super(errorMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CorruptCabException() {
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,77 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 dorkbox, llc
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package dorkbox.cabParser;
|
|
||||||
|
|
||||||
import dorkbox.cabParser.structure.CabFileEntry;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* provide default CabStreamSaver
|
|
||||||
*/
|
|
||||||
public class DefaultCabStreamSaver implements CabStreamSaver{
|
|
||||||
private File extractPath;
|
|
||||||
|
|
||||||
public DefaultCabStreamSaver(File extractPath) throws CabException {
|
|
||||||
this.extractPath = extractPath;
|
|
||||||
if(extractPath!=null){
|
|
||||||
if(!extractPath.exists()){
|
|
||||||
extractPath.mkdirs();
|
|
||||||
}else if(!extractPath.isDirectory()){
|
|
||||||
throw new CabException("extractPath is not directory");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public OutputStream openOutputStream(CabFileEntry entry) {
|
|
||||||
return new ByteArrayOutputStream((int) entry.getSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void closeOutputStream(OutputStream outputStream, CabFileEntry entry) {
|
|
||||||
if (outputStream != null) {
|
|
||||||
try {
|
|
||||||
ByteArrayOutputStream bos = (ByteArrayOutputStream)outputStream;
|
|
||||||
File cabEntityFile = new File(extractPath, entry.getName().replace("\\", File.separator));
|
|
||||||
cabEntityFile.getParentFile().mkdirs();
|
|
||||||
FileOutputStream fileOutputStream = new FileOutputStream(cabEntityFile);
|
|
||||||
try {
|
|
||||||
bos.writeTo(fileOutputStream);
|
|
||||||
} finally {
|
|
||||||
fileOutputStream.close();
|
|
||||||
}
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
} catch (IOException e) {
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
outputStream.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean saveReservedAreaData(byte[] data, int dataLength) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 dorkbox, llc
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package dorkbox.cabParser
|
||||||
|
|
||||||
|
import dorkbox.cabParser.structure.CabFileEntry
|
||||||
|
import java.io.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* provide default CabStreamSaver
|
||||||
|
*/
|
||||||
|
class DefaultCabStreamSaver(private val extractPath: File?) : CabStreamSaver {
|
||||||
|
init {
|
||||||
|
if (extractPath != null) {
|
||||||
|
if (!extractPath.exists()) {
|
||||||
|
extractPath.mkdirs()
|
||||||
|
}
|
||||||
|
else if (!extractPath.isDirectory()) {
|
||||||
|
throw CabException("extractPath is not directory")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun openOutputStream(entry: CabFileEntry): OutputStream? {
|
||||||
|
return ByteArrayOutputStream(entry.size.toInt())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun closeOutputStream(outputStream: OutputStream, entry: CabFileEntry) {
|
||||||
|
try {
|
||||||
|
val bos = outputStream as ByteArrayOutputStream
|
||||||
|
val cabEntityFile = File(extractPath, entry.name.replace("\\", File.separator))
|
||||||
|
cabEntityFile.getParentFile().mkdirs()
|
||||||
|
val fileOutputStream = FileOutputStream(cabEntityFile)
|
||||||
|
try {
|
||||||
|
bos.writeTo(fileOutputStream)
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
fileOutputStream.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e: FileNotFoundException) {
|
||||||
|
}
|
||||||
|
catch (e: IOException) {
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
try {
|
||||||
|
outputStream.close()
|
||||||
|
}
|
||||||
|
catch (e: IOException) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun saveReservedAreaData(data: ByteArray?, dataLength: Int): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012 dorkbox, llc
|
* Copyright 2023 dorkbox, llc
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -72,8 +72,8 @@ public final class CabDecompressor implements CabConstants {
|
||||||
throw new CorruptCabException("Invalid CFDATA checksum");
|
throw new CorruptCabException("Invalid CFDATA checksum");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.decompressor.decompress(this.readBuffer, this.bytes, this.cfDataRecord.cbData, this.cfDataRecord.cbUncomp);
|
this.decompressor.decompress(this.readBuffer, this.bytes, this.cfDataRecord.getCbData(), this.cfDataRecord.getCbUncomp());
|
||||||
this.uncompressedDataSize = this.cfDataRecord.cbUncomp;
|
this.uncompressedDataSize = this.cfDataRecord.getCbUncomp();
|
||||||
this.outputOffset = 0;
|
this.outputOffset = 0;
|
||||||
|
|
||||||
if (this.uncompressedDataSize >= size) {
|
if (this.uncompressedDataSize >= size) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2019 dorkbox, llc
|
* Copyright 2023 dorkbox, llc
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -160,7 +160,7 @@ public class CabExtractor {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getVersion() {
|
public static String getVersion() {
|
||||||
return CabParser.getVersion();
|
return CabParser.version;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Enumeration<Object> entries() {
|
public Enumeration<Object> entries() {
|
||||||
|
|
|
@ -13,19 +13,18 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package dorkbox.cabParser.extractor;
|
package dorkbox.cabParser.extractor
|
||||||
|
|
||||||
import dorkbox.cabParser.structure.CabFileEntry;
|
import dorkbox.cabParser.structure.CabFileEntry
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implement it to select files to extract from CAB.
|
* Implement it to select files to extract from CAB.
|
||||||
*/
|
*/
|
||||||
public interface CabFileFilter {
|
interface CabFileFilter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is invoked on each File Entry found in CAB file.
|
* Is invoked on each File Entry found in CAB file.
|
||||||
*
|
*
|
||||||
* @return <code>true</code> to extract file, <code>false</code> to ignore
|
* @return `true` to extract file, `false` to ignore
|
||||||
*/
|
*/
|
||||||
public boolean test(CabFileEntry cabFile);
|
fun test(cabFile: CabFileEntry?): Boolean
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2019 dorkbox, llc
|
* Copyright 2023 dorkbox, llc
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -13,35 +13,31 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package dorkbox.cabParser.extractor;
|
package dorkbox.cabParser.extractor
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import dorkbox.cabParser.structure.CabFileEntry
|
||||||
|
import java.io.ByteArrayOutputStream
|
||||||
import dorkbox.cabParser.structure.CabFileEntry;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To define how to handle (save) the file content, corresponding to each
|
* To define how to handle (save) the file content, corresponding to each
|
||||||
* individual file extracted from CAB.
|
* individual file extracted from CAB.
|
||||||
*/
|
*/
|
||||||
public interface CabFileSaver {
|
interface CabFileSaver {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the extracted file content.
|
* Save the extracted file content.
|
||||||
*
|
*
|
||||||
* @param fileContent
|
* @param fileContent extracted file content
|
||||||
* extracted file content
|
* @param cabFile [CabFileEntry], file to be saved
|
||||||
* @param cabFile
|
|
||||||
* {@link CabFileEntry} defining file to be be saved
|
|
||||||
*/
|
*/
|
||||||
void save(ByteArrayOutputStream fileContent, CabFileEntry cabFile);
|
fun save(fileContent: ByteArrayOutputStream?, cabFile: CabFileEntry?)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return amount successfully saved files
|
* @return amount successfully saved files
|
||||||
*/
|
*/
|
||||||
int getSucceeded();
|
val succeeded: Int
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return amount of failed save attempts
|
* @return amount of failed save attempts
|
||||||
*/
|
*/
|
||||||
int getFailed();
|
val failed: Int
|
||||||
}
|
}
|
|
@ -1,116 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2019 dorkbox, llc
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package dorkbox.cabParser.extractor;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
import dorkbox.cabParser.CabStreamSaver;
|
|
||||||
import dorkbox.cabParser.structure.CabFileEntry;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of {@link CabStreamSaver} that filters files to extract.
|
|
||||||
* {@link CabFileFilter} and saves them using {@link CabFileSaver}.
|
|
||||||
*/
|
|
||||||
public class FilteredCabStreamSaver implements CabStreamSaver {
|
|
||||||
|
|
||||||
private final CabFileSaver saver;
|
|
||||||
private final CabFileFilter filter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* To save all files to defined extract directory.
|
|
||||||
*
|
|
||||||
* @param extractDirectory
|
|
||||||
* directory to extract files (no sub-directory will be created)
|
|
||||||
*/
|
|
||||||
public FilteredCabStreamSaver(File extractDirectory) {
|
|
||||||
this(extractDirectory, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* To handle (save) all files using passed {@link CabFileSaver}.
|
|
||||||
*
|
|
||||||
* @param saver
|
|
||||||
* defines how to save the {@link ByteArrayOutputStream}
|
|
||||||
* corresponding to {@link CabFileEntry}
|
|
||||||
*/
|
|
||||||
public FilteredCabStreamSaver(CabFileSaver saver) {
|
|
||||||
this(saver, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* To save some files to defined extract directory.
|
|
||||||
*
|
|
||||||
* @param extractDirectory
|
|
||||||
* directory to extract files (no sub-directory will be created)
|
|
||||||
* @param filter
|
|
||||||
* which files to extract (extract all files if
|
|
||||||
* <code>null</code>)
|
|
||||||
*/
|
|
||||||
public FilteredCabStreamSaver(File extractDirectory, CabFileFilter filter) {
|
|
||||||
this(new DefaultCabFileSaver(extractDirectory), filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* To handle (save) some files using passed {@link CabFileSaver}.
|
|
||||||
*
|
|
||||||
* @param saver
|
|
||||||
* defines how to save the {@link ByteArrayOutputStream}
|
|
||||||
* corresponding to {@link CabFileEntry}
|
|
||||||
* @param filter
|
|
||||||
* which files to extract (extract all files if
|
|
||||||
* <code>null</code>)
|
|
||||||
*/
|
|
||||||
public FilteredCabStreamSaver(CabFileSaver saver, CabFileFilter filter) {
|
|
||||||
this.saver = null == saver ? new DefaultCabFileSaver(null) : saver;
|
|
||||||
this.filter = null == filter ? new CabFilePatternFilter(".+") : filter;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void closeOutputStream(OutputStream outputStream, CabFileEntry cabFile) {
|
|
||||||
saver.save((ByteArrayOutputStream) outputStream, cabFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public OutputStream openOutputStream(CabFileEntry cabFile) {
|
|
||||||
if (filter.test(cabFile)) {
|
|
||||||
return new ByteArrayOutputStream((int) cabFile.getSize());
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean saveReservedAreaData(byte[] data, int dataLength) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return amount successfully saved files
|
|
||||||
*/
|
|
||||||
public int getSucceeded() {
|
|
||||||
return saver.getSucceeded();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return amount of failed save attempts
|
|
||||||
*/
|
|
||||||
public int getFailed() {
|
|
||||||
return saver.getFailed();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 dorkbox, llc
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package dorkbox.cabParser.extractor
|
||||||
|
|
||||||
|
import dorkbox.cabParser.CabStreamSaver
|
||||||
|
import dorkbox.cabParser.structure.CabFileEntry
|
||||||
|
import java.io.ByteArrayOutputStream
|
||||||
|
import java.io.File
|
||||||
|
import java.io.OutputStream
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of [CabStreamSaver] that filters files to extract.
|
||||||
|
* [CabFileFilter] and saves them using [CabFileSaver].
|
||||||
|
*/
|
||||||
|
class FilteredCabStreamSaver(
|
||||||
|
|
||||||
|
/**
|
||||||
|
* defines how to save the [ByteArrayOutputStream] corresponding to [CabFileEntry]
|
||||||
|
*/
|
||||||
|
val saver: CabFileSaver = DefaultCabFileSaver(null),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* which files to extract (extract all files if `null`)
|
||||||
|
*/
|
||||||
|
val filter: CabFileFilter = CabFilePatternFilter(".+")) : CabStreamSaver {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To save some files to defined extract directory.
|
||||||
|
*
|
||||||
|
* @param extractDirectory directory to extract files (no sub-directory will be created)
|
||||||
|
* @param filter which files to extract (extract all files if `null`)
|
||||||
|
*/
|
||||||
|
constructor(extractDirectory: File?, filter: CabFileFilter) : this(DefaultCabFileSaver(extractDirectory), filter)
|
||||||
|
|
||||||
|
override fun closeOutputStream(outputStream: OutputStream, entry: CabFileEntry) {
|
||||||
|
saver.save(outputStream as ByteArrayOutputStream, entry)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun openOutputStream(entry: CabFileEntry): OutputStream? {
|
||||||
|
return if (filter.test(entry)) {
|
||||||
|
ByteArrayOutputStream(entry.size.toInt())
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun saveReservedAreaData(data: ByteArray?, dataLength: Int): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return amount successfully saved files
|
||||||
|
*/
|
||||||
|
val succeeded: Int
|
||||||
|
get() = saver.succeeded
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return amount of failed save attempts
|
||||||
|
*/
|
||||||
|
val failed: Int
|
||||||
|
get() = saver.failed
|
||||||
|
}
|
|
@ -1,54 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 dorkbox, llc
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package dorkbox.cabParser.structure;
|
|
||||||
|
|
||||||
public interface CabConstants {
|
|
||||||
int CAB_BLOCK_SIZE = 32768;
|
|
||||||
int CAB_BLOCK_SIZE_THRESH = 32767;
|
|
||||||
|
|
||||||
int COMPRESSION_TYPE_NONE = 0;
|
|
||||||
int COMPRESSION_TYPE_MSZIP = 1;
|
|
||||||
int COMPRESSION_TYPE_QUANTUM = 2;
|
|
||||||
int COMPRESSION_TYPE_LZX = 3;
|
|
||||||
|
|
||||||
int RESERVED_CFHEADER = 1;
|
|
||||||
int RESERVED_CFFOLDER = 2;
|
|
||||||
|
|
||||||
int RESERVED_CFDATA = 3;
|
|
||||||
|
|
||||||
int CAB_PROGRESS_INPUT = 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* FLAG_PREV_CABINET is set if this cabinet file is not the first in a set
|
|
||||||
* of cabinet files. When this bit is set, the szCabinetPrev and szDiskPrev
|
|
||||||
* fields are present in this CFHEADER.
|
|
||||||
*/
|
|
||||||
int FLAG_PREV_CABINET = 0x0001;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* FLAG_NEXT_CABINET is set if this cabinet file is not the last in a set of
|
|
||||||
* cabinet files. When this bit is set, the szCabinetNext and szDiskNext
|
|
||||||
* fields are present in this CFHEADER.
|
|
||||||
*/
|
|
||||||
int FLAG_NEXT_CABINET = 0x0002;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* FLAG_RESERVE_PRESENT is set if this cabinet file contains any reserved
|
|
||||||
* fields. When this bit is set, the cbCFHeader, cbCFFolder, and cbCFData
|
|
||||||
* fields are present in this CFHEADER.
|
|
||||||
*/
|
|
||||||
int FLAG_RESERVE_PRESENT = 0x0004;
|
|
||||||
}
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012 dorkbox, llc
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package dorkbox.cabParser.structure
|
||||||
|
|
||||||
|
interface CabConstants {
|
||||||
|
companion object {
|
||||||
|
const val CAB_BLOCK_SIZE = 32768
|
||||||
|
const val CAB_BLOCK_SIZE_THRESH = 32767
|
||||||
|
const val COMPRESSION_TYPE_NONE = 0
|
||||||
|
const val COMPRESSION_TYPE_MSZIP = 1
|
||||||
|
const val COMPRESSION_TYPE_QUANTUM = 2
|
||||||
|
const val COMPRESSION_TYPE_LZX = 3
|
||||||
|
const val RESERVED_CFHEADER = 1
|
||||||
|
const val RESERVED_CFFOLDER = 2
|
||||||
|
const val RESERVED_CFDATA = 3
|
||||||
|
const val CAB_PROGRESS_INPUT = 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FLAG_PREV_CABINET is set if this cabinet file is not the first in a set
|
||||||
|
* of cabinet files. When this bit is set, the szCabinetPrev and szDiskPrev
|
||||||
|
* fields are present in this CFHEADER.
|
||||||
|
*/
|
||||||
|
const val FLAG_PREV_CABINET = 0x0001
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FLAG_NEXT_CABINET is set if this cabinet file is not the last in a set of
|
||||||
|
* cabinet files. When this bit is set, the szCabinetNext and szDiskNext
|
||||||
|
* fields are present in this CFHEADER.
|
||||||
|
*/
|
||||||
|
const val FLAG_NEXT_CABINET = 0x0002
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FLAG_RESERVE_PRESENT is set if this cabinet file contains any reserved
|
||||||
|
* fields. When this bit is set, the cbCFHeader, cbCFFolder, and cbCFData
|
||||||
|
* fields are present in this CFHEADER.
|
||||||
|
*/
|
||||||
|
const val FLAG_RESERVE_PRESENT = 0x0004
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,66 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 dorkbox, llc
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package dorkbox.cabParser.structure;
|
|
||||||
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.NoSuchElementException;
|
|
||||||
|
|
||||||
import dorkbox.cabParser.CabParser;
|
|
||||||
|
|
||||||
public final class CabEnumerator implements Enumeration<Object> {
|
|
||||||
private int fileCount = 0;
|
|
||||||
private int folderCount = 0;
|
|
||||||
|
|
||||||
private CabParser cabParser;
|
|
||||||
|
|
||||||
private boolean b;
|
|
||||||
private int folderIndex;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object nextElement() {
|
|
||||||
if (!this.b) {
|
|
||||||
if (this.fileCount < this.cabParser.header.cFiles) {
|
|
||||||
return this.cabParser.files[this.fileCount++];
|
|
||||||
}
|
|
||||||
throw new NoSuchElementException();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.cabParser.files[this.fileCount].iFolder != this.folderIndex) {
|
|
||||||
this.folderIndex = this.cabParser.files[this.fileCount].iFolder;
|
|
||||||
|
|
||||||
if (this.folderCount < this.cabParser.folders.length) {
|
|
||||||
return this.cabParser.folders[this.folderCount++];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.fileCount < this.cabParser.header.cFiles) {
|
|
||||||
return this.cabParser.files[this.fileCount++];
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new NoSuchElementException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public CabEnumerator(CabParser decoder, boolean b) {
|
|
||||||
this.cabParser = decoder;
|
|
||||||
this.b = b;
|
|
||||||
this.folderIndex = -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasMoreElements() {
|
|
||||||
return this.fileCount < this.cabParser.header.cFiles;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 dorkbox, llc
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package dorkbox.cabParser.structure
|
||||||
|
|
||||||
|
import dorkbox.cabParser.CabParser
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class CabEnumerator(private val cabParser: CabParser, private val b: Boolean) : Enumeration<Any> {
|
||||||
|
private var fileCount = 0
|
||||||
|
private var folderCount = 0
|
||||||
|
private var folderIndex: Int
|
||||||
|
|
||||||
|
init {
|
||||||
|
folderIndex = -2
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun nextElement(): Any {
|
||||||
|
if (!b) {
|
||||||
|
if (fileCount < cabParser.header.cFiles) {
|
||||||
|
return cabParser.files[fileCount++]
|
||||||
|
}
|
||||||
|
throw NoSuchElementException()
|
||||||
|
}
|
||||||
|
if (cabParser.files[fileCount].iFolder != folderIndex) {
|
||||||
|
folderIndex = cabParser.files[fileCount].iFolder
|
||||||
|
if (folderCount < cabParser.folders.size) {
|
||||||
|
return cabParser.folders[folderCount++]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fileCount < cabParser.header.cFiles) {
|
||||||
|
return cabParser.files[fileCount++]
|
||||||
|
}
|
||||||
|
throw NoSuchElementException()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hasMoreElements(): Boolean {
|
||||||
|
return fileCount < cabParser.header.cFiles
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,249 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 dorkbox, llc
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package dorkbox.cabParser.structure;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import dorkbox.cabParser.CabException;
|
|
||||||
import dorkbox.cabParser.CorruptCabException;
|
|
||||||
import dorkbox.bytes.LittleEndian;
|
|
||||||
|
|
||||||
public final class CabFileEntry {
|
|
||||||
public static final Charset US_ASCII = Charset.forName("US-ASCII");
|
|
||||||
|
|
||||||
/** file is read-only (in HEX) */
|
|
||||||
static final int READONLY = 0x01;
|
|
||||||
|
|
||||||
/** file is hidden (in HEX) */
|
|
||||||
static final int HIDDEN = 0x02;
|
|
||||||
|
|
||||||
/** file is a system file (in HEX) */
|
|
||||||
static final int SYSTEM = 0x04;
|
|
||||||
|
|
||||||
/** file modified since last backup (in HEX) */
|
|
||||||
static final int ARCHIVE = 0x20;
|
|
||||||
|
|
||||||
/** szName[] contains UTF (in HEX) */
|
|
||||||
static final int NAME_IS_UTF = 0x80;
|
|
||||||
|
|
||||||
/** uncompressed size of this file in bytes , 4bytes */
|
|
||||||
public long cbFile;
|
|
||||||
/** uncompressed offset of this file in the folder , 4bytes */
|
|
||||||
public long offFolderStart;
|
|
||||||
/** index into the CFFOLDER area , 2bytes */
|
|
||||||
public int iFolder;
|
|
||||||
/** time/date stamp for this file , 2bytes */
|
|
||||||
public Date date = new Date();
|
|
||||||
/** attribute flags for this file , 2bytes */
|
|
||||||
public int attribs;
|
|
||||||
|
|
||||||
/** name of this file , 1*n bytes */
|
|
||||||
public String szName;
|
|
||||||
|
|
||||||
private Object objectOrSomething;
|
|
||||||
|
|
||||||
public void read(InputStream input) throws IOException, CabException {
|
|
||||||
byte[] arrayOfByte = new byte[256];
|
|
||||||
|
|
||||||
this.cbFile = LittleEndian.UInt_.from(input).longValue();
|
|
||||||
this.offFolderStart = LittleEndian.UInt_.from(input).longValue();
|
|
||||||
this.iFolder = LittleEndian.UShort_.from(input).intValue();
|
|
||||||
|
|
||||||
int timeA = LittleEndian.UShort_.from(input).intValue();
|
|
||||||
int timeB = LittleEndian.UShort_.from(input).intValue();
|
|
||||||
this.date = getDate(timeA, timeB);
|
|
||||||
|
|
||||||
this.attribs = LittleEndian.UShort_.from(input).intValue();
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < arrayOfByte.length; i++) {
|
|
||||||
int m = input.read();
|
|
||||||
if (m == -1) {
|
|
||||||
throw new CorruptCabException("EOF reading cffile");
|
|
||||||
}
|
|
||||||
arrayOfByte[i] = (byte) m;
|
|
||||||
if (m == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i >= arrayOfByte.length) {
|
|
||||||
throw new CorruptCabException("cffile filename not null terminated");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((this.attribs & NAME_IS_UTF) == NAME_IS_UTF) {
|
|
||||||
this.szName = readUtfString(arrayOfByte);
|
|
||||||
|
|
||||||
if (this.szName == null) {
|
|
||||||
throw new CorruptCabException("invalid utf8 code");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.szName = new String(arrayOfByte, 0, i, US_ASCII).trim();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isReadOnly() {
|
|
||||||
return (this.attribs & READONLY) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setReadOnly(boolean bool) {
|
|
||||||
if (bool) {
|
|
||||||
this.attribs |= 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.attribs &= -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isHidden() {
|
|
||||||
return (this.attribs & HIDDEN) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHidden(boolean bool) {
|
|
||||||
if (bool) {
|
|
||||||
this.attribs |= 2;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.attribs &= -3;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSystem() {
|
|
||||||
return (this.attribs & SYSTEM) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSystem(boolean bool) {
|
|
||||||
if (bool) {
|
|
||||||
this.attribs |= 4;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.attribs &= -5;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isArchive() {
|
|
||||||
return (this.attribs & ARCHIVE) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setArchive(boolean bool) {
|
|
||||||
if (bool) {
|
|
||||||
this.attribs |= 32;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.attribs &= -33;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return this.szName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getSize() {
|
|
||||||
return this.cbFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.szName = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSize(long size) {
|
|
||||||
this.cbFile = (int) size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getDate() {
|
|
||||||
return this.date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDate(Date paramDate) {
|
|
||||||
this.date = paramDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
private Date getDate(int dateInfo, int timeInfo) {
|
|
||||||
int i = dateInfo & 0x1F;
|
|
||||||
int j = (dateInfo >>> 5) - 1 & 0xF;
|
|
||||||
int k = (dateInfo >>> 9) + 80;
|
|
||||||
int m = (timeInfo & 0x1F) << 1;
|
|
||||||
int n = timeInfo >>> 5 & 0x3F;
|
|
||||||
int i1 = timeInfo >>> 11 & 0x1F;
|
|
||||||
return new Date(k, j, i, i1, n, m);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object getApplicationData() {
|
|
||||||
return this.objectOrSomething;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setApplicationData(Object obj) {
|
|
||||||
this.objectOrSomething = obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return this.szName;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String readUtfString(byte[] stringBytes) {
|
|
||||||
int j = 0;
|
|
||||||
int stringSize = 0;
|
|
||||||
int k = 0;
|
|
||||||
|
|
||||||
// count the size of the string
|
|
||||||
for (stringSize = 0; stringBytes[stringSize] != 0; stringSize++) {}
|
|
||||||
|
|
||||||
char[] stringChars = new char[stringSize];
|
|
||||||
for (k = 0; stringBytes[j] != 0; k++) {
|
|
||||||
int m = (char) (stringBytes[j++] & 0xFF);
|
|
||||||
|
|
||||||
if (m < 128) {
|
|
||||||
stringChars[k] = (char) m;
|
|
||||||
} else {
|
|
||||||
if (m < 192) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m < 224) {
|
|
||||||
stringChars[k] = (char) ((m & 0x1F) << 6);
|
|
||||||
m = (char) (stringBytes[j++] & 0xFF);
|
|
||||||
if (m < 128 || m > 191) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
stringChars[k] = (char) (stringChars[k] | (char) (m & 0x3F));
|
|
||||||
}
|
|
||||||
else if (m < 240) {
|
|
||||||
stringChars[k] = (char) ((m & 0xF) << 12);
|
|
||||||
m = (char) (stringBytes[j++] & 0xFF);
|
|
||||||
if (m < 128 || m > 191) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
stringChars[k] = (char) (stringChars[k] | (char) ((m & 0x3F) << 6));
|
|
||||||
m = (char) (stringBytes[j++] & 0xFF);
|
|
||||||
if (m < 128 || m > 191) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
stringChars[k] = (char) (stringChars[k] | (char) (m & 0x3F));
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new String(stringChars, 0, k);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,207 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 dorkbox, llc
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package dorkbox.cabParser.structure
|
||||||
|
|
||||||
|
import dorkbox.bytes.LittleEndian
|
||||||
|
import dorkbox.cabParser.CabException
|
||||||
|
import dorkbox.cabParser.CorruptCabException
|
||||||
|
import java.io.IOException
|
||||||
|
import java.io.InputStream
|
||||||
|
import java.nio.charset.Charset
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class CabFileEntry {
|
||||||
|
/** uncompressed size of this file in bytes , 4bytes */
|
||||||
|
var cbFile: Long = 0
|
||||||
|
|
||||||
|
/** uncompressed offset of this file in the folder , 4bytes */
|
||||||
|
var offFolderStart: Long = 0
|
||||||
|
|
||||||
|
/** index into the CFFOLDER area , 2bytes */
|
||||||
|
var iFolder = 0
|
||||||
|
|
||||||
|
/** time/date stamp for this file , 2bytes */
|
||||||
|
var date = Date()
|
||||||
|
|
||||||
|
/** attribute flags for this file , 2bytes */
|
||||||
|
var attribs = 0
|
||||||
|
|
||||||
|
/** name of this file , 1*n bytes */
|
||||||
|
lateinit var name: String
|
||||||
|
|
||||||
|
var applicationData: Any? = null
|
||||||
|
|
||||||
|
@Throws(IOException::class, CabException::class)
|
||||||
|
fun read(input: InputStream) {
|
||||||
|
val arrayOfByte = ByteArray(256)
|
||||||
|
cbFile = LittleEndian.UInt_.from(input).toLong()
|
||||||
|
offFolderStart = LittleEndian.UInt_.from(input).toLong()
|
||||||
|
iFolder = LittleEndian.UShort_.from(input).toInt()
|
||||||
|
val timeA: Int = LittleEndian.UShort_.from(input).toInt()
|
||||||
|
val timeB: Int = LittleEndian.UShort_.from(input).toInt()
|
||||||
|
date = getDate(timeA, timeB)
|
||||||
|
attribs = LittleEndian.UShort_.from(input).toInt()
|
||||||
|
|
||||||
|
var i = 0
|
||||||
|
i = 0
|
||||||
|
while (i < arrayOfByte.size) {
|
||||||
|
val m = input.read()
|
||||||
|
if (m == -1) {
|
||||||
|
throw CorruptCabException("EOF reading cffile")
|
||||||
|
}
|
||||||
|
arrayOfByte[i] = m.toByte()
|
||||||
|
if (m == 0) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
if (i >= arrayOfByte.size) {
|
||||||
|
throw CorruptCabException("cffile filename not null terminated")
|
||||||
|
}
|
||||||
|
name = if (attribs and NAME_IS_UTF == NAME_IS_UTF) {
|
||||||
|
readUtfString(arrayOfByte) ?: throw CorruptCabException("invalid name utf8 code")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
String(arrayOfByte, 0, i, US_ASCII).trim { it <= ' ' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var isReadOnly: Boolean
|
||||||
|
get() = attribs and READONLY != 0
|
||||||
|
set(bool) {
|
||||||
|
if (bool) {
|
||||||
|
attribs = attribs or 1
|
||||||
|
return
|
||||||
|
}
|
||||||
|
attribs = attribs and -2
|
||||||
|
}
|
||||||
|
var isHidden: Boolean
|
||||||
|
get() = attribs and HIDDEN != 0
|
||||||
|
set(bool) {
|
||||||
|
if (bool) {
|
||||||
|
attribs = attribs or 2
|
||||||
|
return
|
||||||
|
}
|
||||||
|
attribs = attribs and -3
|
||||||
|
}
|
||||||
|
var isSystem: Boolean
|
||||||
|
get() = attribs and SYSTEM != 0
|
||||||
|
set(bool) {
|
||||||
|
if (bool) {
|
||||||
|
attribs = attribs or 4
|
||||||
|
return
|
||||||
|
}
|
||||||
|
attribs = attribs and -5
|
||||||
|
}
|
||||||
|
var isArchive: Boolean
|
||||||
|
get() = attribs and ARCHIVE != 0
|
||||||
|
set(bool) {
|
||||||
|
if (bool) {
|
||||||
|
attribs = attribs or 32
|
||||||
|
return
|
||||||
|
}
|
||||||
|
attribs = attribs and -33
|
||||||
|
}
|
||||||
|
var size: Long
|
||||||
|
get() = cbFile
|
||||||
|
set(size) {
|
||||||
|
cbFile = size.toInt().toLong()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getDate(dateInfo: Int, timeInfo: Int): Date {
|
||||||
|
val i = dateInfo and 0x1F
|
||||||
|
val j = (dateInfo ushr 5) - 1 and 0xF
|
||||||
|
val k = (dateInfo ushr 9) + 80
|
||||||
|
val m = timeInfo and 0x1F shl 1
|
||||||
|
val n = timeInfo ushr 5 and 0x3F
|
||||||
|
val i1 = timeInfo ushr 11 and 0x1F
|
||||||
|
return Date(k, j, i, i1, n, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val US_ASCII = Charset.forName("US-ASCII")
|
||||||
|
|
||||||
|
/** file is read-only (in HEX) */
|
||||||
|
const val READONLY = 0x01
|
||||||
|
|
||||||
|
/** file is hidden (in HEX) */
|
||||||
|
const val HIDDEN = 0x02
|
||||||
|
|
||||||
|
/** file is a system file (in HEX) */
|
||||||
|
const val SYSTEM = 0x04
|
||||||
|
|
||||||
|
/** file modified since last backup (in HEX) */
|
||||||
|
const val ARCHIVE = 0x20
|
||||||
|
|
||||||
|
/** szName[] contains UTF (in HEX) */
|
||||||
|
const val NAME_IS_UTF = 0x80
|
||||||
|
|
||||||
|
private fun readUtfString(stringBytes: ByteArray): String? {
|
||||||
|
var j = 0
|
||||||
|
var stringSize = 0
|
||||||
|
var k = 0
|
||||||
|
|
||||||
|
// count the size of the string
|
||||||
|
stringSize = 0
|
||||||
|
while (stringBytes[stringSize].toInt() != 0) {
|
||||||
|
stringSize++
|
||||||
|
}
|
||||||
|
val stringChars = CharArray(stringSize)
|
||||||
|
k = 0
|
||||||
|
while (stringBytes[j].toInt() != 0) {
|
||||||
|
var m = (stringBytes[j++].toInt() and 0xFF).toChar().code
|
||||||
|
if (m < 128) {
|
||||||
|
stringChars[k] = m.toChar()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (m < 192) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
if (m < 224) {
|
||||||
|
stringChars[k] = (m and 0x1F shl 6).toChar()
|
||||||
|
m = (stringBytes[j++].toInt() and 0xFF).toChar().code
|
||||||
|
if (m < 128 || m > 191) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
stringChars[k] = (stringChars[k].code or (m and 0x3F).toChar().code).toChar()
|
||||||
|
}
|
||||||
|
else if (m < 240) {
|
||||||
|
stringChars[k] = (m and 0xF shl 12).toChar()
|
||||||
|
m = (stringBytes[j++].toInt() and 0xFF).toChar().code
|
||||||
|
if (m < 128 || m > 191) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
stringChars[k] = (stringChars[k].code or (m and 0x3F shl 6).toChar().code).toChar()
|
||||||
|
m = (stringBytes[j++].toInt() and 0xFF).toChar().code
|
||||||
|
if (m < 128 || m > 191) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
stringChars[k] = (stringChars[k].code or (m and 0x3F).toChar().code).toChar()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
k++
|
||||||
|
}
|
||||||
|
return String(stringChars, 0, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,72 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 dorkbox, llc
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package dorkbox.cabParser.structure;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import dorkbox.bytes.LittleEndian;
|
|
||||||
|
|
||||||
public final class CabFolderEntry implements CabConstants {
|
|
||||||
/** offset of the first CFDATA block in this folder, 4bytes */
|
|
||||||
public long coffCabStart;
|
|
||||||
|
|
||||||
/** number of CFDATA blocks in this folder, 2bytes */
|
|
||||||
public int cCFData;
|
|
||||||
|
|
||||||
/** compression type indicator , 2bytes */
|
|
||||||
public int compressionMethod = 0;
|
|
||||||
|
|
||||||
public int getCompressionMethod() {
|
|
||||||
return this.compressionMethod & 0xF;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void read(InputStream input) throws IOException {
|
|
||||||
this.coffCabStart = LittleEndian.UInt_.from(input).longValue();
|
|
||||||
this.cCFData = LittleEndian.UShort_.from(input).intValue();
|
|
||||||
this.compressionMethod = LittleEndian.UShort_.from(input).intValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCompressionWindowSize() {
|
|
||||||
if (this.compressionMethod == COMPRESSION_TYPE_NONE) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (this.compressionMethod == COMPRESSION_TYPE_MSZIP) {
|
|
||||||
return 16;
|
|
||||||
}
|
|
||||||
return (this.compressionMethod & 0x1F00) >>> 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String compressionToString() {
|
|
||||||
switch (getCompressionMethod()) {
|
|
||||||
default :
|
|
||||||
return "UNKNOWN";
|
|
||||||
case 0 :
|
|
||||||
return "NONE";
|
|
||||||
case 1 :
|
|
||||||
return "MSZIP";
|
|
||||||
case 2 :
|
|
||||||
return "QUANTUM:" + Integer.toString(getCompressionWindowSize());
|
|
||||||
case 3 :
|
|
||||||
}
|
|
||||||
return "LZX:" + Integer.toString(getCompressionWindowSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCompression(int a, int b) {
|
|
||||||
this.compressionMethod = b << 8 | a;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 dorkbox, llc
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package dorkbox.cabParser.structure
|
||||||
|
|
||||||
|
import dorkbox.bytes.LittleEndian
|
||||||
|
import java.io.IOException
|
||||||
|
import java.io.InputStream
|
||||||
|
|
||||||
|
class CabFolderEntry : CabConstants {
|
||||||
|
/** offset of the first CFDATA block in this folder, 4bytes */
|
||||||
|
var coffCabStart: Long = 0
|
||||||
|
|
||||||
|
/** number of CFDATA blocks in this folder, 2bytes */
|
||||||
|
var cCFData = 0
|
||||||
|
|
||||||
|
/** compression type indicator , 2bytes */
|
||||||
|
var compressionMethod = 0
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
fun read(input: InputStream) {
|
||||||
|
coffCabStart = LittleEndian.UInt_.from(input).toLong()
|
||||||
|
cCFData = LittleEndian.UShort_.from(input).toInt()
|
||||||
|
compressionMethod = LittleEndian.UShort_.from(input).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
val compressionWindowSize: Int
|
||||||
|
get() {
|
||||||
|
if (compressionMethod == CabConstants.COMPRESSION_TYPE_NONE) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return if (compressionMethod == CabConstants.COMPRESSION_TYPE_MSZIP) {
|
||||||
|
16
|
||||||
|
}
|
||||||
|
else compressionMethod and 0x1F00 ushr 8
|
||||||
|
}
|
||||||
|
|
||||||
|
fun compressionToString(): String {
|
||||||
|
when (compressionMethod) {
|
||||||
|
0 -> return "NONE"
|
||||||
|
1 -> return "MSZIP"
|
||||||
|
2 -> return "QUANTUM:" + compressionWindowSize.toString()
|
||||||
|
3 -> {}
|
||||||
|
else -> return "UNKNOWN"
|
||||||
|
}
|
||||||
|
return "LZX:" + compressionWindowSize.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setCompression(a: Int, b: Int) {
|
||||||
|
compressionMethod = b shl 8 or a
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,161 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 dorkbox, llc
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package dorkbox.cabParser.structure;
|
|
||||||
|
|
||||||
import java.io.EOFException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import dorkbox.cabParser.CabException;
|
|
||||||
import dorkbox.cabParser.CabStreamSaver;
|
|
||||||
import dorkbox.cabParser.CorruptCabException;
|
|
||||||
import dorkbox.bytes.LittleEndian;
|
|
||||||
|
|
||||||
public final class CabHeader implements CabConstants {
|
|
||||||
|
|
||||||
/** reserved , 4 bytes */
|
|
||||||
public long reserved1;
|
|
||||||
/** size of this cabinet file in bytes , 4 bytes */
|
|
||||||
public long cbCabinet;
|
|
||||||
/** reserved, 4 bytes */
|
|
||||||
public long reserved2;
|
|
||||||
/** offset of the first CFFILE entry , 4 bytes */
|
|
||||||
public long coffFiles;
|
|
||||||
/** reserved, 4 bytes*/
|
|
||||||
public long reserved3;
|
|
||||||
|
|
||||||
/** cabinet file format version, minor/major , 1 bytes*2 */
|
|
||||||
public int version;
|
|
||||||
|
|
||||||
/** number of CFFOLDER entries in this cabinet , 2 bytes */
|
|
||||||
public int cFolders;
|
|
||||||
/** number of CFFILE entries in this cabinet , 2 bytes */
|
|
||||||
public int cFiles;
|
|
||||||
|
|
||||||
/** cabinet file option indicators , 2 bytes */
|
|
||||||
public int flags;
|
|
||||||
/** must be the same for all cabinets in a set , 2 bytes */
|
|
||||||
public int setID;
|
|
||||||
/** number of this cabinet file in a set , 2 bytes */
|
|
||||||
public int iCabinet;
|
|
||||||
|
|
||||||
/** (optional) size of per-cabinet reserved area , 2 bytes */
|
|
||||||
public int cbCFHeader = 0;
|
|
||||||
/** (optional) size of per-folder reserved area , 1 bytes */
|
|
||||||
public int cbCFFolder = 0;
|
|
||||||
/** (optional) size of per-datablock reserved area , 1 bytes */
|
|
||||||
public int cbCFData = 0;
|
|
||||||
|
|
||||||
/** (optional) per-cabinet reserved area , 1*n bytes */
|
|
||||||
//final short abReserve[];
|
|
||||||
|
|
||||||
/** (optional) name of previous cabinet file , 1*n bytes */
|
|
||||||
//final String szCabinetPrev;
|
|
||||||
|
|
||||||
/** (optional) name of previous disk , 1*n bytes */
|
|
||||||
//final String szDiskPrev;
|
|
||||||
|
|
||||||
/** (optional) name of next cabinet file , 1*n bytes */
|
|
||||||
//final String szCabinetNext;
|
|
||||||
|
|
||||||
/** (optional) name of next disk , 1*n bytes */
|
|
||||||
//final String szDiskNext;
|
|
||||||
|
|
||||||
|
|
||||||
private CabStreamSaver decoder;
|
|
||||||
|
|
||||||
public CabHeader(CabStreamSaver paramCabDecoderInterface) {
|
|
||||||
this.decoder = paramCabDecoderInterface;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void read(InputStream input) throws IOException, CabException {
|
|
||||||
int i = input.read();
|
|
||||||
int j = input.read();
|
|
||||||
int k = input.read();
|
|
||||||
int m = input.read();
|
|
||||||
// Contains the characters "M", "S", "C", and "F" (bytes 0x4D, 0x53, 0x43, 0x46). This field is used to ensure that the file is a cabinet (.cab) file.
|
|
||||||
if (i != 77 || j != 83 || k != 67 || m != 70) {
|
|
||||||
throw new CorruptCabException("Missing header signature");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.reserved1 = LittleEndian.UInt_.from(input).longValue(); // must be 0
|
|
||||||
this.cbCabinet = LittleEndian.UInt_.from(input).longValue(); // Specifies the total size of the cabinet file, in bytes.
|
|
||||||
this.reserved2 = LittleEndian.UInt_.from(input).longValue(); // must be 0
|
|
||||||
this.coffFiles = LittleEndian.UInt_.from(input).longValue(); // Specifies the absolute file offset, in bytes, of the first CFFILE field entry.
|
|
||||||
this.reserved3 = LittleEndian.UInt_.from(input).longValue(); // must be 0
|
|
||||||
|
|
||||||
|
|
||||||
// Currently, versionMajor = 1 and versionMinor = 3
|
|
||||||
this.version = LittleEndian.UShort_.from(input).intValue();
|
|
||||||
this.cFolders = LittleEndian.UShort_.from(input).intValue();
|
|
||||||
this.cFiles = LittleEndian.UShort_.from(input).intValue();
|
|
||||||
this.flags = LittleEndian.UShort_.from(input).intValue();
|
|
||||||
this.setID = LittleEndian.UShort_.from(input).intValue();
|
|
||||||
this.iCabinet = LittleEndian.UShort_.from(input).intValue();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ((this.flags & FLAG_RESERVE_PRESENT) == FLAG_RESERVE_PRESENT) {
|
|
||||||
this.cbCFHeader = LittleEndian.UShort_.from(input).intValue();
|
|
||||||
this.cbCFFolder = input.read();
|
|
||||||
this.cbCFData = input.read();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((this.flags & FLAG_PREV_CABINET) == FLAG_PREV_CABINET ||
|
|
||||||
(this.flags & FLAG_NEXT_CABINET) == FLAG_NEXT_CABINET) {
|
|
||||||
throw new CabException("Spanned cabinets not supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
// not supported
|
|
||||||
// if (prevCabinet()) {
|
|
||||||
// szCabinetPrev = bytes.readString(false);
|
|
||||||
// szDiskPrev = bytes.readString(false);
|
|
||||||
// } else {
|
|
||||||
// szCabinetPrev = null;
|
|
||||||
// szDiskPrev = null;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (nextCabinet()) {
|
|
||||||
// szCabinetNext = bytes.readString(false);
|
|
||||||
// szDiskNext = bytes.readString(false);
|
|
||||||
// } else {
|
|
||||||
// szCabinetNext = null;
|
|
||||||
// szDiskNext = null;
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (this.cbCFHeader != 0) {
|
|
||||||
if (this.decoder.saveReservedAreaData(null, this.cbCFHeader) == true) {
|
|
||||||
byte[] data = new byte[this.cbCFHeader];
|
|
||||||
|
|
||||||
if (this.cbCFHeader != 0) {
|
|
||||||
int readTotal = 0;
|
|
||||||
while (readTotal < this.cbCFHeader) {
|
|
||||||
int read = input.read(data, readTotal, this.cbCFHeader - readTotal);
|
|
||||||
if (read < 0) {
|
|
||||||
throw new EOFException();
|
|
||||||
}
|
|
||||||
readTotal += read;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.decoder.saveReservedAreaData(data, this.cbCFHeader);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
input.skip(this.cbCFHeader);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,150 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 dorkbox, llc
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package dorkbox.cabParser.structure
|
||||||
|
|
||||||
|
import dorkbox.bytes.LittleEndian
|
||||||
|
import dorkbox.cabParser.CabException
|
||||||
|
import dorkbox.cabParser.CabStreamSaver
|
||||||
|
import dorkbox.cabParser.CorruptCabException
|
||||||
|
import java.io.EOFException
|
||||||
|
import java.io.IOException
|
||||||
|
import java.io.InputStream
|
||||||
|
|
||||||
|
class CabHeader
|
||||||
|
(
|
||||||
|
/** (optional) name of next cabinet file , 1*n bytes */ //final String szCabinetNext;
|
||||||
|
/** (optional) name of next disk , 1*n bytes */ //final String szDiskNext;
|
||||||
|
private val decoder: CabStreamSaver
|
||||||
|
) : CabConstants {
|
||||||
|
/** reserved , 4 bytes */
|
||||||
|
var reserved1: Long = 0
|
||||||
|
|
||||||
|
/** size of this cabinet file in bytes , 4 bytes */
|
||||||
|
var cbCabinet: Long = 0
|
||||||
|
|
||||||
|
/** reserved, 4 bytes */
|
||||||
|
var reserved2: Long = 0
|
||||||
|
|
||||||
|
/** offset of the first CFFILE entry , 4 bytes */
|
||||||
|
var coffFiles: Long = 0
|
||||||
|
|
||||||
|
/** reserved, 4 bytes */
|
||||||
|
var reserved3: Long = 0
|
||||||
|
|
||||||
|
/** cabinet file format version, minor/major , 1 bytes*2 */
|
||||||
|
var version = 0
|
||||||
|
|
||||||
|
/** number of CFFOLDER entries in this cabinet , 2 bytes */
|
||||||
|
var cFolders = 0
|
||||||
|
|
||||||
|
/** number of CFFILE entries in this cabinet , 2 bytes */
|
||||||
|
var cFiles = 0
|
||||||
|
|
||||||
|
/** cabinet file option indicators , 2 bytes */
|
||||||
|
var flags = 0
|
||||||
|
|
||||||
|
/** must be the same for all cabinets in a set , 2 bytes */
|
||||||
|
var setID = 0
|
||||||
|
|
||||||
|
/** number of this cabinet file in a set , 2 bytes */
|
||||||
|
var iCabinet = 0
|
||||||
|
|
||||||
|
/** (optional) size of per-cabinet reserved area , 2 bytes */
|
||||||
|
var cbCFHeader = 0
|
||||||
|
|
||||||
|
/** (optional) size of per-folder reserved area , 1 bytes */
|
||||||
|
var cbCFFolder = 0
|
||||||
|
|
||||||
|
/** (optional) size of per-datablock reserved area , 1 bytes */
|
||||||
|
var cbCFData = 0
|
||||||
|
|
||||||
|
/** (optional) per-cabinet reserved area , 1*n bytes */ //final short abReserve[];
|
||||||
|
/** (optional) name of previous cabinet file , 1*n bytes */ //final String szCabinetPrev;
|
||||||
|
/** (optional) name of previous disk , 1*n bytes */ //final String szDiskPrev;
|
||||||
|
|
||||||
|
@Throws(IOException::class, CabException::class)
|
||||||
|
fun read(input: InputStream) {
|
||||||
|
val i = input.read()
|
||||||
|
val j = input.read()
|
||||||
|
val k = input.read()
|
||||||
|
val m = input.read()
|
||||||
|
|
||||||
|
// Contains the characters "M", "S", "C", and "F" (bytes 0x4D, 0x53, 0x43, 0x46). This field is used to ensure that the file is a cabinet (.cab) file.
|
||||||
|
if (i != 77 || j != 83 || k != 67 || m != 70) {
|
||||||
|
throw CorruptCabException("Missing header signature")
|
||||||
|
}
|
||||||
|
reserved1 = LittleEndian.UInt_.from(input).toLong() // must be 0
|
||||||
|
cbCabinet = LittleEndian.UInt_.from(input).toLong() // Specifies the total size of the cabinet file, in bytes.
|
||||||
|
reserved2 = LittleEndian.UInt_.from(input).toLong() // must be 0
|
||||||
|
coffFiles = LittleEndian.UInt_.from(input).toLong() // Specifies the absolute file offset, in bytes, of the first CFFILE field entry.
|
||||||
|
reserved3 = LittleEndian.UInt_.from(input).toLong() // must be 0
|
||||||
|
|
||||||
|
|
||||||
|
// Currently, versionMajor = 1 and versionMinor = 3
|
||||||
|
version = LittleEndian.UShort_.from(input).toInt()
|
||||||
|
cFolders = LittleEndian.UShort_.from(input).toInt()
|
||||||
|
cFiles = LittleEndian.UShort_.from(input).toInt()
|
||||||
|
flags = LittleEndian.UShort_.from(input).toInt()
|
||||||
|
setID = LittleEndian.UShort_.from(input).toInt()
|
||||||
|
iCabinet = LittleEndian.UShort_.from(input).toInt()
|
||||||
|
|
||||||
|
if (flags and CabConstants.FLAG_RESERVE_PRESENT == CabConstants.FLAG_RESERVE_PRESENT) {
|
||||||
|
cbCFHeader = LittleEndian.UShort_.from(input).toInt()
|
||||||
|
cbCFFolder = input.read()
|
||||||
|
cbCFData = input.read()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags and CabConstants.FLAG_PREV_CABINET == CabConstants.FLAG_PREV_CABINET || flags and CabConstants.FLAG_NEXT_CABINET == CabConstants.FLAG_NEXT_CABINET) {
|
||||||
|
throw CabException("Spanned cabinets not supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
// not supported
|
||||||
|
// if (prevCabinet()) {
|
||||||
|
// szCabinetPrev = bytes.readString(false);
|
||||||
|
// szDiskPrev = bytes.readString(false);
|
||||||
|
// } else {
|
||||||
|
// szCabinetPrev = null;
|
||||||
|
// szDiskPrev = null;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (nextCabinet()) {
|
||||||
|
// szCabinetNext = bytes.readString(false);
|
||||||
|
// szDiskNext = bytes.readString(false);
|
||||||
|
// } else {
|
||||||
|
// szCabinetNext = null;
|
||||||
|
// szDiskNext = null;
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (cbCFHeader != 0) {
|
||||||
|
if (decoder.saveReservedAreaData(null, cbCFHeader) == true) {
|
||||||
|
val data = ByteArray(cbCFHeader)
|
||||||
|
if (cbCFHeader != 0) {
|
||||||
|
var readTotal = 0
|
||||||
|
while (readTotal < cbCFHeader) {
|
||||||
|
val read = input.read(data, readTotal, cbCFHeader - readTotal)
|
||||||
|
if (read < 0) {
|
||||||
|
throw EOFException()
|
||||||
|
}
|
||||||
|
readTotal += read
|
||||||
|
}
|
||||||
|
}
|
||||||
|
decoder.saveReservedAreaData(data, cbCFHeader)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
input.skip(cbCFHeader.toLong())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,80 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 dorkbox, llc
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package dorkbox.cabParser.structure;
|
|
||||||
|
|
||||||
import java.io.EOFException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import dorkbox.cabParser.CabException;
|
|
||||||
import dorkbox.cabParser.Checksum;
|
|
||||||
import dorkbox.cabParser.CorruptCabException;
|
|
||||||
import dorkbox.bytes.LittleEndian;
|
|
||||||
|
|
||||||
public final class CfDataRecord {
|
|
||||||
/** checksum of this CFDATA entry , 4bytes */
|
|
||||||
private int csum;
|
|
||||||
|
|
||||||
/** number of compressed bytes in this block , 2bytes */
|
|
||||||
public int cbData;
|
|
||||||
|
|
||||||
/** number of uncompressed bytes in this block , 2bytes */
|
|
||||||
public int cbUncomp;
|
|
||||||
|
|
||||||
private int sizeOfBlockData;
|
|
||||||
|
|
||||||
public CfDataRecord(int sizeOfBlockData) {
|
|
||||||
this.sizeOfBlockData = sizeOfBlockData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void read(InputStream input, byte[] bytes) throws IOException, CabException {
|
|
||||||
this.csum = LittleEndian.Int_.from(input); // safe to use signed here, since checksum also returns signed
|
|
||||||
this.cbData = LittleEndian.UShort_.from(input).intValue();
|
|
||||||
this.cbUncomp = LittleEndian.UShort_.from(input).intValue();
|
|
||||||
|
|
||||||
if (this.cbData > bytes.length) {
|
|
||||||
throw new CorruptCabException("Corrupt cfData record");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.sizeOfBlockData != 0) {
|
|
||||||
input.skip(this.sizeOfBlockData);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int readTotal = 0;
|
|
||||||
while (readTotal < this.cbData) {
|
|
||||||
int read = input.read(bytes, readTotal, this.cbData - readTotal);
|
|
||||||
if (read < 0) {
|
|
||||||
throw new EOFException();
|
|
||||||
}
|
|
||||||
readTotal += read;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int checksum(byte[] bytes) {
|
|
||||||
byte[] arrayOfByte = new byte[4];
|
|
||||||
arrayOfByte[0] = (byte) (this.cbData & 0xFF);
|
|
||||||
arrayOfByte[1] = (byte) (this.cbData >>> 8 & 0xFF);
|
|
||||||
arrayOfByte[2] = (byte) (this.cbUncomp & 0xFF);
|
|
||||||
arrayOfByte[3] = (byte) (this.cbUncomp >>> 8 & 0xFF);
|
|
||||||
|
|
||||||
return Checksum.calculate(bytes, this.cbData, Checksum.calculate(arrayOfByte, 4, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean validateCheckSum(byte[] bytesToCheck) {
|
|
||||||
return checksum(bytesToCheck) == this.csum;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 dorkbox, llc
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package dorkbox.cabParser.structure
|
||||||
|
|
||||||
|
import dorkbox.bytes.LittleEndian
|
||||||
|
import dorkbox.bytes.LittleEndian.Int_.from
|
||||||
|
import dorkbox.cabParser.CabException
|
||||||
|
import dorkbox.cabParser.Checksum
|
||||||
|
import dorkbox.cabParser.CorruptCabException
|
||||||
|
import java.io.EOFException
|
||||||
|
import java.io.IOException
|
||||||
|
import java.io.InputStream
|
||||||
|
|
||||||
|
class CfDataRecord(private val sizeOfBlockData: Int) {
|
||||||
|
/** checksum of this CFDATA entry , 4bytes */
|
||||||
|
private var csum = 0
|
||||||
|
|
||||||
|
/** number of compressed bytes in this block , 2bytes */
|
||||||
|
var cbData = 0
|
||||||
|
|
||||||
|
/** number of uncompressed bytes in this block , 2bytes */
|
||||||
|
var cbUncomp = 0
|
||||||
|
|
||||||
|
@Throws(IOException::class, CabException::class)
|
||||||
|
fun read(input: InputStream, bytes: ByteArray) {
|
||||||
|
csum = from(input) // safe to use signed here, since checksum also returns signed
|
||||||
|
cbData = LittleEndian.UShort_.from(input).toInt()
|
||||||
|
cbUncomp = LittleEndian.UShort_.from(input).toInt()
|
||||||
|
|
||||||
|
if (cbData > bytes.size) {
|
||||||
|
throw CorruptCabException("Corrupt cfData record")
|
||||||
|
}
|
||||||
|
if (sizeOfBlockData != 0) {
|
||||||
|
input.skip(sizeOfBlockData.toLong())
|
||||||
|
}
|
||||||
|
|
||||||
|
var readTotal = 0
|
||||||
|
while (readTotal < cbData) {
|
||||||
|
val read = input.read(bytes, readTotal, cbData - readTotal)
|
||||||
|
if (read < 0) {
|
||||||
|
throw EOFException()
|
||||||
|
}
|
||||||
|
readTotal += read
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checksum(bytes: ByteArray): Int {
|
||||||
|
val arrayOfByte = ByteArray(4)
|
||||||
|
arrayOfByte[0] = (cbData and 0xFF).toByte()
|
||||||
|
arrayOfByte[1] = (cbData ushr 8 and 0xFF).toByte()
|
||||||
|
arrayOfByte[2] = (cbUncomp and 0xFF).toByte()
|
||||||
|
arrayOfByte[3] = (cbUncomp ushr 8 and 0xFF).toByte()
|
||||||
|
return Checksum.calculate(bytes, cbData, Checksum.calculate(arrayOfByte, 4, 0))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun validateCheckSum(bytesToCheck: ByteArray): Boolean {
|
||||||
|
return checksum(bytesToCheck) == csum
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ module dorkbox.cabParser {
|
||||||
exports dorkbox.cabParser.structure;
|
exports dorkbox.cabParser.structure;
|
||||||
|
|
||||||
|
|
||||||
requires transitive dorkbox.bytes;
|
requires transitive dorkbox.byteUtils;
|
||||||
requires transitive dorkbox.updates;
|
requires transitive dorkbox.updates;
|
||||||
requires transitive dorkbox.utilities;
|
requires transitive dorkbox.utilities;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue