WIP migrating to kotlin.
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+
|
||||
|
||||
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]
|
||||
https://git.dorkbox.com/dorkbox/ByteUtilities
|
||||
Copyright 2023
|
||||
Dorkbox LLC
|
||||
|
||||
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 -
|
||||
[BSD 3-Clause License]
|
||||
https://github.com/EsotericSoftware/kryo
|
||||
|
@ -73,7 +71,7 @@
|
|||
|
||||
- Objenesis -
|
||||
[The Apache Software License, Version 2.0]
|
||||
http://objenesis.org
|
||||
https://github.com/easymock/objenesis
|
||||
Objenesis Team and all contributors
|
||||
|
||||
- MinLog-SLF4J -
|
||||
|
@ -81,6 +79,13 @@
|
|||
https://github.com/EsotericSoftware/minlog
|
||||
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
|
||||
[The Apache Software License, Version 2.0]
|
||||
https://git.dorkbox.com/dorkbox/Updates
|
||||
|
@ -125,23 +130,6 @@
|
|||
Sean Luke
|
||||
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 -
|
||||
[BSD 3-Clause License]
|
||||
https://git.dorkbox.com/dorkbox/Utilities
|
||||
|
@ -151,21 +139,6 @@
|
|||
Lightweight Java Game Library Project
|
||||
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 -
|
||||
[The Apache Software License, Version 2.0]
|
||||
https://git.dorkbox.com/dorkbox/Utilities
|
||||
|
@ -181,7 +154,7 @@
|
|||
|
||||
- Resource Listing - Listing the contents of a resource directory
|
||||
[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
|
||||
Greg Briggs
|
||||
|
||||
|
@ -192,17 +165,12 @@
|
|||
Pronghorn Technology LLC
|
||||
Dorkbox LLC
|
||||
|
||||
- UrlRewriteFilter - UrlRewriteFilter is a Java Web Filter for any J2EE compliant web application server
|
||||
[BSD 3-Clause License]
|
||||
https://github.com/paultuckey/urlrewritefilter
|
||||
Copyright 2022
|
||||
Paul Tuckey
|
||||
|
||||
- kotlinx.coroutines - Library support for Kotlin coroutines with multiplatform support
|
||||
- Kotlin Coroutine CountDownLatch -
|
||||
[The Apache Software License, Version 2.0]
|
||||
https://github.com/Kotlin/kotlinx.coroutines
|
||||
Copyright 2023
|
||||
JetBrains s.r.o.
|
||||
https://github.com/Kotlin/kotlinx.coroutines/issues/59
|
||||
https://github.com/venkatperi/kotlin-coroutines-lib
|
||||
Copyright 2018
|
||||
Venkat Peri
|
||||
|
||||
- Java Uuid Generator - A set of Java classes for working with UUIDs
|
||||
[The Apache Software License, Version 2.0]
|
||||
|
@ -211,12 +179,6 @@
|
|||
Tatu Saloranta (tatu.saloranta@iki.fi)
|
||||
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
|
||||
[Public Domain, per Creative Commons CC0]
|
||||
https://tukaani.org/xz/java.html
|
||||
|
@ -224,6 +186,13 @@
|
|||
Lasse Collin
|
||||
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 -
|
||||
[The Apache Software License, Version 2.0]
|
||||
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
|
||||
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]
|
||||
https://netty.io
|
||||
https://github.com/Kotlin/kotlinx.coroutines
|
||||
Copyright 2023
|
||||
The Netty Project
|
||||
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
|
||||
JetBrains s.r.o.
|
||||
|
||||
- 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
|
||||
Copyright 2023
|
||||
Dorkbox LLC
|
||||
|
||||
Extra license information
|
||||
|
@ -379,25 +237,25 @@
|
|||
- 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
|
||||
Copyright 2023
|
||||
JetBrains s.r.o.
|
||||
|
||||
- SLF4J - Simple facade or abstraction for various logging frameworks
|
||||
[MIT License]
|
||||
http://www.slf4j.org
|
||||
Copyright 2022
|
||||
https://www.slf4j.org
|
||||
Copyright 2023
|
||||
QOS.ch
|
||||
|
||||
- Logback - Logback is a logging framework for Java applications
|
||||
[The Apache Software License, Version 2.0]
|
||||
http://logback.qos.ch
|
||||
Copyright 2022
|
||||
https://logback.qos.ch
|
||||
Copyright 2023
|
||||
QOS.ch
|
||||
|
||||
- SSHJ - SSHv2 library for Java
|
||||
[The Apache Software License, Version 2.0]
|
||||
https://github.com/hierynomus/sshj
|
||||
Copyright 2022
|
||||
Copyright 2023
|
||||
Jeroen van Erp
|
||||
SSHJ Contributors
|
||||
|
||||
|
@ -414,13 +272,13 @@
|
|||
|
||||
- JZlib -
|
||||
[The Apache Software License, Version 2.0]
|
||||
http://www.jcraft.com/jzlib
|
||||
https://github.com/ymnk/jzlib
|
||||
Atsuhiko Yamanaka
|
||||
JCraft, Inc.
|
||||
|
||||
- Bouncy Castle Crypto -
|
||||
[The Apache Software License, Version 2.0]
|
||||
http://www.bouncycastle.org
|
||||
https://www.bouncycastle.org
|
||||
The Legion of the Bouncy Castle Inc
|
||||
|
||||
- ed25519-java -
|
||||
|
@ -443,169 +301,6 @@
|
|||
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
|
||||
|
||||
- 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.
|
||||
[The Apache Software License, Version 2.0]
|
||||
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");
|
||||
* 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
|
||||
|
||||
plugins {
|
||||
id("com.dorkbox.GradleUtils") version "3.9"
|
||||
id("com.dorkbox.Licensing") version "2.19.1"
|
||||
id("com.dorkbox.VersionUpdate") version "2.5"
|
||||
id("com.dorkbox.GradlePublish") version "1.17"
|
||||
id("com.dorkbox.GradleUtils") version "3.17"
|
||||
id("com.dorkbox.Licensing") version "2.25"
|
||||
id("com.dorkbox.VersionUpdate") version "2.8"
|
||||
id("com.dorkbox.GradlePublish") version "1.18"
|
||||
|
||||
kotlin("jvm") version "1.8.0"
|
||||
}
|
||||
|
||||
object Extras {
|
||||
|
@ -44,8 +46,6 @@ object Extras {
|
|||
const val vendor = "Dorkbox LLC"
|
||||
const val vendorUrl = "https://dorkbox.com"
|
||||
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 {
|
||||
manifest {
|
||||
// https://docs.oracle.com/javase/tutorial/deployment/jar/packageman.html
|
||||
|
@ -74,15 +87,15 @@ tasks.jar.get().apply {
|
|||
attributes["Specification-Vendor"] = Extras.vendor
|
||||
|
||||
attributes["Implementation-Title"] = "${Extras.group}.${Extras.id}"
|
||||
attributes["Implementation-Version"] = Extras.buildDate
|
||||
attributes["Implementation-Version"] = GradleUtils.now()
|
||||
attributes["Implementation-Vendor"] = Extras.vendor
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api("com.dorkbox:ByteUtilities:1.6")
|
||||
api("com.dorkbox:ByteUtilities:1.13")
|
||||
api("com.dorkbox:Updates:1.1")
|
||||
api("com.dorkbox:Utilities:1.39")
|
||||
api("com.dorkbox:Utilities:1.44")
|
||||
}
|
||||
|
||||
publishToSonatype {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012 dorkbox, llc
|
||||
* 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.
|
||||
|
@ -13,15 +13,9 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.cabParser;
|
||||
package dorkbox.cabParser
|
||||
|
||||
public class CabException extends Exception {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public CabException(String errorMessage) {
|
||||
super(errorMessage);
|
||||
}
|
||||
|
||||
public CabException() {
|
||||
}
|
||||
open class CabException : Exception {
|
||||
constructor(errorMessage: String?) : super(errorMessage)
|
||||
constructor()
|
||||
}
|
|
@ -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");
|
||||
* 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
|
||||
* 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;
|
||||
|
||||
public interface CabStreamSaver {
|
||||
OutputStream openOutputStream(CabFileEntry entry);
|
||||
void closeOutputStream(OutputStream outputStream, CabFileEntry entry);
|
||||
boolean saveReservedAreaData(byte[] data, int dataLength);
|
||||
interface CabStreamSaver {
|
||||
fun openOutputStream(entry: CabFileEntry): OutputStream?
|
||||
fun closeOutputStream(outputStream: OutputStream, entry: CabFileEntry)
|
||||
fun saveReservedAreaData(data: ByteArray?, dataLength: Int): Boolean
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012 dorkbox, llc
|
||||
* 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.
|
||||
|
@ -13,16 +13,9 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.cabParser;
|
||||
package dorkbox.cabParser
|
||||
|
||||
|
||||
public final class CorruptCabException extends CabException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public CorruptCabException(String errorMessage) {
|
||||
super(errorMessage);
|
||||
}
|
||||
|
||||
public CorruptCabException() {
|
||||
}
|
||||
class CorruptCabException : CabException {
|
||||
constructor(errorMessage: String?) : super(errorMessage)
|
||||
constructor()
|
||||
}
|
|
@ -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");
|
||||
* 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");
|
||||
}
|
||||
|
||||
this.decompressor.decompress(this.readBuffer, this.bytes, this.cfDataRecord.cbData, this.cfDataRecord.cbUncomp);
|
||||
this.uncompressedDataSize = this.cfDataRecord.cbUncomp;
|
||||
this.decompressor.decompress(this.readBuffer, this.bytes, this.cfDataRecord.getCbData(), this.cfDataRecord.getCbUncomp());
|
||||
this.uncompressedDataSize = this.cfDataRecord.getCbUncomp();
|
||||
this.outputOffset = 0;
|
||||
|
||||
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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -160,7 +160,7 @@ public class CabExtractor {
|
|||
}
|
||||
|
||||
public static String getVersion() {
|
||||
return CabParser.getVersion();
|
||||
return CabParser.version;
|
||||
}
|
||||
|
||||
public Enumeration<Object> entries() {
|
||||
|
|
|
@ -13,19 +13,18 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* 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.
|
||||
*/
|
||||
public interface CabFileFilter {
|
||||
|
||||
interface CabFileFilter {
|
||||
/**
|
||||
* 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");
|
||||
* 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
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.cabParser.extractor;
|
||||
package dorkbox.cabParser.extractor
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
import dorkbox.cabParser.structure.CabFileEntry;
|
||||
import dorkbox.cabParser.structure.CabFileEntry
|
||||
import java.io.ByteArrayOutputStream
|
||||
|
||||
/**
|
||||
* To define how to handle (save) the file content, corresponding to each
|
||||
* individual file extracted from CAB.
|
||||
*/
|
||||
public interface CabFileSaver {
|
||||
|
||||
interface CabFileSaver {
|
||||
/**
|
||||
* Save the extracted file content.
|
||||
*
|
||||
* @param fileContent
|
||||
* extracted file content
|
||||
* @param cabFile
|
||||
* {@link CabFileEntry} defining file to be be saved
|
||||
*
|
||||
* @param fileContent extracted file content
|
||||
* @param cabFile [CabFileEntry], file to be saved
|
||||
*/
|
||||
void save(ByteArrayOutputStream fileContent, CabFileEntry cabFile);
|
||||
fun save(fileContent: ByteArrayOutputStream?, cabFile: CabFileEntry?)
|
||||
|
||||
/**
|
||||
* @return amount successfully saved files
|
||||
*/
|
||||
int getSucceeded();
|
||||
val succeeded: Int
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
|
||||
requires transitive dorkbox.bytes;
|
||||
requires transitive dorkbox.byteUtils;
|
||||
requires transitive dorkbox.updates;
|
||||
requires transitive dorkbox.utilities;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue