Moved Byte utilities from common Utilities project

master
Robinson 2021-01-15 01:10:21 +01:00
commit 43903e681b
23 changed files with 6819 additions and 0 deletions

121
.gitignore vendored Normal file
View File

@ -0,0 +1,121 @@
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff:
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/dictionaries
.idea/**/codeStyles/
.idea/**/codeStyleSettings.xml
# Sensitive or high-churn files:
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.xml
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/shelf/
# Gradle:
.idea/**/gradle.xml
.idea/**/libraries
# CMake
cmake-build-debug/
# Mongo Explorer plugin:
.idea/**/mongoSettings.xml
## File-based project format:
*.iws
## Plugin-specific files:
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
######################
# End JetBrains IDEs #
######################
# From https://github.com/github/gitignore/blob/master/Gradle.gitignore
.gradle
/build/
# Ignore Gradle GUI config
gradle-app.setting
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar
!gradle-wrapper.properties
# Cache of project
.gradletasknamecache
# From https://github.com/github/gitignore/blob/master/Java.gitignore
*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
*.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
##########################################################
# Specific to this module
# iml files are generated by intellij/gradle now
**/*.iml

29
LICENSE Normal file
View File

@ -0,0 +1,29 @@
- ByteUtilties - Byte manipulation and Unsigned Number Utilities
[The Apache Software License, Version 2.0]
https://git.dorkbox.com/dorkbox/ByteUtilities
Copyright 2021
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
Copyright 2020
Nathan Sweet
- Netty - An event-driven asynchronous network application framework
[The Apache Software License, Version 2.0]
https://netty.io
Copyright 2021
The Netty Project
Contributors. See source NOTICE

218
LICENSE.Apachev2 Normal file
View File

@ -0,0 +1,218 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.

26
LICENSE.BSD3 Normal file
View File

@ -0,0 +1,26 @@
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.
* Neither the name of the <ORGANIZATION> nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
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.

33
README.md Normal file
View File

@ -0,0 +1,33 @@
Byte manipulation and Unsigned Number Utilities
###### [![Dorkbox](https://badge.dorkbox.com/dorkbox.svg "Dorkbox")](https://git.dorkbox.com/dorkbox/ByteUtilities) [![Github](https://badge.dorkbox.com/github.svg "Github")](https://github.com/dorkbox/ByteUtilities) [![Gitlab](https://badge.dorkbox.com/gitlab.svg "Gitlab")](https://gitlab.com/dorkbox/ByteUtilities)
Maven Info
---------
```
<dependencies>
...
<dependency>
<groupId>com.dorkbox</groupId>
<artifactId>ByteUtilities</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
```
Gradle Info
---------
````
dependencies {
...
compile "com.dorkbox:ByteUtilities:1.0"
}
````
License
---------
This project is © 2021 dorkbox llc, and is distributed under the terms of the Apache v2.0 License. See file "LICENSE" for further
references.

146
build.gradle.kts Normal file
View File

@ -0,0 +1,146 @@
/*
* Copyright 2021 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.
*/
import java.time.Instant
///////////////////////////////
////// PUBLISH TO SONATYPE / MAVEN CENTRAL
////// TESTING : (to local maven repo) <'publish and release' - 'publishToMavenLocal'>
////// RELEASE : (to sonatype/maven central), <'publish and release' - 'publishToSonatypeAndRelease'>
///////////////////////////////
gradle.startParameter.showStacktrace = ShowStacktrace.ALWAYS // always show the stacktrace!
gradle.startParameter.warningMode = WarningMode.All
plugins {
java
id("com.dorkbox.GradleUtils") version "1.12"
id("com.dorkbox.Licensing") version "2.5.3"
id("com.dorkbox.VersionUpdate") version "2.1"
id("com.dorkbox.GradlePublish") version "1.9"
}
object Extras {
// set for the project
const val description = "Byte manipulation and Unsigned Number Utilities"
const val group = "com.dorkbox"
const val version = "1.0"
// set as project.ext
const val name = "ByteUtilities"
const val id = "ByteUtilities"
const val vendor = "Dorkbox LLC"
const val vendorUrl = "https://dorkbox.com"
const val url = "https://git.dorkbox.com/dorkbox/ByteUtilities"
val buildDate = Instant.now().toString()
}
///////////////////////////////
///// assign 'Extras'
///////////////////////////////
GradleUtils.load("$projectDir/../../gradle.properties", Extras)
GradleUtils.fixIntellijPaths()
GradleUtils.defaultResolutionStrategy()
GradleUtils.compileConfiguration(JavaVersion.VERSION_1_8)
licensing {
license(License.APACHE_2) {
description(Extras.description)
author(Extras.vendor)
url(Extras.url)
extra("Byte Utils (UByte, UInteger, ULong, Unsigned, UNumber, UShort)", License.APACHE_2) {
it.url("https://github.com/jOOQ/jOOQ/tree/master/jOOQ/src/main/java/org/jooq/types")
it.copyright(2017)
it.author("Data Geekery GmbH (http://www.datageekery.com)")
it.author("Lukas Eder")
it.author("Ed Schaller")
it.author("Jens Nerche")
it.author("Ivan Sokolov")
}
extra("Kryo Serialization", License.BSD_3) {
it.copyright(2020)
it.author("Nathan Sweet")
it.url("https://github.com/EsotericSoftware/kryo")
}
}
}
sourceSets {
main {
java {
setSrcDirs(listOf("src"))
// want to include java files for the source. 'setSrcDirs' resets includes...
include("**/*.java")
}
}
}
repositories {
mavenLocal() // this must be first!
jcenter()
}
tasks.jar.get().apply {
manifest {
// https://docs.oracle.com/javase/tutorial/deployment/jar/packageman.html
attributes["Name"] = Extras.name
attributes["Specification-Title"] = Extras.name
attributes["Specification-Version"] = Extras.version
attributes["Specification-Vendor"] = Extras.vendor
attributes["Implementation-Title"] = "${Extras.group}.${Extras.id}"
attributes["Implementation-Version"] = Extras.buildDate
attributes["Implementation-Vendor"] = Extras.vendor
attributes["Automatic-Module-Name"] = Extras.id
}
}
dependencies {
// listed as compileOnly, since we will be using netty bytebuf utils if we ALREADY are using netty byte buffs. **We don't want a hard dependency.**
compileOnly("io.netty:netty-buffer:4.1.58.Final")
}
publishToSonatype {
groupId = Extras.group
artifactId = Extras.id
version = Extras.version
name = Extras.name
description = Extras.description
url = Extras.url
vendor = Extras.vendor
vendorUrl = Extras.vendorUrl
issueManagement {
url = "${Extras.url}/issues"
nickname = "Gitea Issues"
}
developer {
id = "dorkbox"
name = Extras.vendor
email = "email@dorkbox.com"
}
}

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

185
gradlew vendored Normal file
View File

@ -0,0 +1,185 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# 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
#
# https://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.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

104
gradlew.bat vendored Normal file
View File

@ -0,0 +1,104 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

15
settings.gradle.kts Normal file
View File

@ -0,0 +1,15 @@
/*
* Copyright 2021 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.
*/

View File

@ -0,0 +1,772 @@
/*
* Copyright 2021 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.bytes;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.nio.ByteBuffer;
/**
* This is "motorola endian", or commonly as "network byte order".
* <p/>
* This is also the default for Java.
* <p/>
* arm is technically bi-endian
*/
@SuppressWarnings("ALL")
public
class BigEndian {
// the following are ALL in Bit-Endian (byte[0] is MOST significant)
/**
* CHAR to and from bytes
*/
public static final
class Char_ {
@SuppressWarnings("fallthrough")
public static
char from(final byte[] bytes, final int offset, final int bytenum) {
char number = 0;
switch (bytenum) {
case 2:
number |= (bytes[offset + 0] & 0xFF) << 8;
case 1:
number |= (bytes[offset + 1] & 0xFF) << 0;
}
return number;
}
@SuppressWarnings("fallthrough")
public static
char from(final byte[] bytes) {
char number = 0;
switch (bytes.length) {
default:
case 2:
number |= (bytes[0] & 0xFF) << 8;
case 1:
number |= (bytes[1] & 0xFF) << 0;
}
return number;
}
public static
char from(final byte b0, final byte b1) {
return (char) ((b0 & 0xFF) << 8 | (b1 & 0xFF) << 0);
}
public static
char from(final ByteBuffer buff) {
return from(buff.get(), buff.get());
}
public static
char from(final InputStream inputStream) throws IOException {
return from((byte) inputStream.read(), (byte) inputStream.read());
}
public static
byte[] toBytes(final char x) {
return new byte[] {(byte) (x >> 8), (byte) (x >> 0)};
}
public static
void toBytes(final char x, final byte[] bytes, final int offset) {
bytes[offset + 0] = (byte) (x >> 8);
bytes[offset + 1] = (byte) (x >> 0);
}
public static
void toBytes(final char x, final byte[] bytes) {
bytes[0] = (byte) (x >> 8);
bytes[1] = (byte) (x >> 0);
}
private
Char_() {
}
}
/**
* UNSIGNED CHAR to and from bytes
*/
public static final
class UChar_ {
@SuppressWarnings("fallthrough")
public static
dorkbox.bytes.UShort from(final byte[] bytes, final int offset, final int bytenum) {
char number = 0;
switch (bytenum) {
case 2:
number |= (bytes[offset + 0] & 0xFF) << 8;
case 1:
number |= (bytes[offset + 1] & 0xFF) << 0;
}
return dorkbox.bytes.UShort.valueOf(number);
}
@SuppressWarnings("fallthrough")
public static
dorkbox.bytes.UShort from(final byte[] bytes) {
short number = 0;
switch (bytes.length) {
default:
case 2:
number |= (bytes[0] & 0xFF) << 8;
case 1:
number |= (bytes[1] & 0xFF) << 0;
}
return dorkbox.bytes.UShort.valueOf(number);
}
public static
dorkbox.bytes.UShort from(final byte b0, final byte b1) {
return dorkbox.bytes.UShort.valueOf((short) ((b0 & 0xFF) << 8) | (b1 & 0xFF) << 0);
}
public static
dorkbox.bytes.UShort from(final ByteBuffer buff) {
return from(buff.get(), buff.get());
}
public static
dorkbox.bytes.UShort from(final InputStream inputStream) throws IOException {
return from((byte) inputStream.read(), (byte) inputStream.read());
}
public static
byte[] toBytes(final dorkbox.bytes.UShort x) {
int num = x.intValue();
return new byte[] {(byte) ((num & 0xFF00) >> 8), (byte) (num & 0x00FF >> 0)};
}
public static
void toBytes(final dorkbox.bytes.UShort x, final byte[] bytes, final int offset) {
int num = x.intValue();
bytes[offset + 0] = (byte) ((num & 0xFF00) >> 8);
bytes[offset + 1] = (byte) (num & 0x00FF >> 0);
}
public static
void toBytes(final dorkbox.bytes.UShort x, final byte[] bytes) {
int num = x.intValue();
bytes[0] = (byte) ((num & 0xFF00) >> 8);
bytes[1] = (byte) (num & 0x00FF >> 0);
}
private
UChar_() {
}
}
/**
* SHORT to and from bytes
*/
public static final
class Short_ {
@SuppressWarnings("fallthrough")
public static
short from(final byte[] bytes, final int offset, final int bytenum) {
short number = 0;
switch (bytenum) {
case 2:
number |= (bytes[offset + 0] & 0xFF) << 8;
case 1:
number |= (bytes[offset + 1] & 0xFF) << 0;
}
return number;
}
@SuppressWarnings("fallthrough")
public static
short from(final byte[] bytes) {
short number = 0;
switch (bytes.length) {
default:
case 2:
number |= (bytes[0] & 0xFF) << 8;
case 1:
number |= (bytes[1] & 0xFF) << 0;
}
return number;
}
public static
short from(final byte b0, final byte b1) {
return (short) ((b0 & 0xFF) << 8 | (b1 & 0xFF) << 0);
}
public static
short from(final ByteBuffer buff) {
return from(buff.get(), buff.get());
}
public static
short from(final InputStream inputStream) throws IOException {
return from((byte) inputStream.read(), (byte) inputStream.read());
}
public static
byte[] toBytes(final short x) {
return new byte[] {(byte) (x >> 8), (byte) (x >> 0)};
}
public static
void toBytes(final short x, final byte[] bytes, final int offset) {
bytes[offset + 0] = (byte) (x >> 8);
bytes[offset + 1] = (byte) (x >> 0);
}
public static
void toBytes(final short x, final byte[] bytes) {
bytes[0] = (byte) (x >> 8);
bytes[1] = (byte) (x >> 0);
}
private
Short_() {
}
}
/**
* UNSIGNED SHORT to and from bytes
*/
public static final
class UShort_ {
@SuppressWarnings("fallthrough")
public static
dorkbox.bytes.UShort from(final byte[] bytes, final int offset, final int bytenum) {
char number = 0;
switch (bytenum) {
case 2:
number |= (bytes[offset + 0] & 0xFF) << 8;
case 1:
number |= (bytes[offset + 1] & 0xFF) << 0;
}
return dorkbox.bytes.UShort.valueOf(number);
}
@SuppressWarnings("fallthrough")
public static
dorkbox.bytes.UShort from(final byte[] bytes) {
short number = 0;
switch (bytes.length) {
default:
case 2:
number |= (bytes[0] & 0xFF) << 8;
case 1:
number |= (bytes[1] & 0xFF) << 0;
}
return dorkbox.bytes.UShort.valueOf(number);
}
public static
dorkbox.bytes.UShort from(final byte b0, final byte b1) {
return dorkbox.bytes.UShort.valueOf((short) ((b0 & 0xFF) << 8) | (b1 & 0xFF) << 0);
}
public static
dorkbox.bytes.UShort from(final ByteBuffer buff) {
return from(buff.get(), buff.get());
}
public static
dorkbox.bytes.UShort from(final InputStream inputStream) throws IOException {
return from((byte) inputStream.read(), (byte) inputStream.read());
}
public static
byte[] toBytes(final dorkbox.bytes.UShort x) {
final int num = x.intValue();
return new byte[] {(byte) ((num & 0xFF00) >> 8), (byte) (num & 0x00FF >> 0)};
}
public static
void toBytes(final dorkbox.bytes.UShort x, final byte[] bytes, final int offset) {
int num = x.intValue();
bytes[offset + 0] = (byte) ((num & 0xFF00) >> 8);
bytes[offset + 1] = (byte) (num & 0x00FF >> 0);
}
public static
void toBytes(final dorkbox.bytes.UShort x, final byte[] bytes) {
int num = x.intValue();
bytes[0] = (byte) ((num & 0xFF00) >> 8);
bytes[1] = (byte) (num & 0x00FF >> 0);
}
private
UShort_() {
}
}
/**
* INT to and from bytes
*/
public static final
class Int_ {
@SuppressWarnings("fallthrough")
public static
int from(final byte[] bytes, final int offset, final int bytenum) {
int number = 0;
switch (bytenum) {
case 4:
number |= (bytes[offset + 0] & 0xFF) << 24;
case 3:
number |= (bytes[offset + 1] & 0xFF) << 16;
case 2:
number |= (bytes[offset + 2] & 0xFF) << 8;
case 1:
number |= (bytes[offset + 3] & 0xFF) << 0;
}
return number;
}
@SuppressWarnings("fallthrough")
public static
int from(final byte[] bytes) {
int number = 0;
switch (bytes.length) {
default:
case 4:
number |= (bytes[0] & 0xFF) << 24;
case 3:
number |= (bytes[1] & 0xFF) << 16;
case 2:
number |= (bytes[2] & 0xFF) << 8;
case 1:
number |= (bytes[3] & 0xFF) << 0;
}
return number;
}
public static
int from(final byte b0, final byte b1, final byte b2, final byte b3) {
return (b0 & 0xFF) << 24 |
(b1 & 0xFF) << 16 |
(b2 & 0xFF) << 8 |
(b3 & 0xFF) << 0;
}
public static
int from(final ByteBuffer buff) {
return from(buff.get(), buff.get(), buff.get(), buff.get());
}
public static
int from(InputStream inputStream) throws IOException {
return from((byte) inputStream.read(), (byte) inputStream.read(), (byte) inputStream.read(), (byte) inputStream.read());
}
public static
byte[] toBytes(final int x) {
return new byte[] {(byte) (x >> 24), (byte) (x >> 16), (byte) (x >> 8), (byte) (x >> 0)};
}
public static
void toBytes(final int x, final byte[] bytes, final int offset) {
bytes[offset + 0] = (byte) (x >> 24);
bytes[offset + 1] = (byte) (x >> 16);
bytes[offset + 2] = (byte) (x >> 8);
bytes[offset + 3] = (byte) (x >> 0);
}
public static
void toBytes(final int x, final byte[] bytes) {
bytes[0] = (byte) (x >> 24);
bytes[1] = (byte) (x >> 16);
bytes[2] = (byte) (x >> 8);
bytes[3] = (byte) (x >> 0);
}
private
Int_() {
}
}
/**
* UNSIGNED INT to and from bytes
*/
public static final
class UInt_ {
@SuppressWarnings("fallthrough")
public static
dorkbox.bytes.UInteger from(final byte[] bytes, final int offset, final int bytenum) {
int number = 0;
switch (bytenum) {
case 4:
number |= (bytes[offset + 0] & 0xFF) << 24;
case 3:
number |= (bytes[offset + 1] & 0xFF) << 16;
case 2:
number |= (bytes[offset + 2] & 0xFF) << 8;
case 1:
number |= (bytes[offset + 3] & 0xFF) << 0;
}
return dorkbox.bytes.UInteger.valueOf(number);
}
@SuppressWarnings("fallthrough")
public static
dorkbox.bytes.UInteger from(final byte[] bytes) {
int number = 0;
switch (bytes.length) {
default:
case 4:
number |= (bytes[0] & 0xFF) << 24;
case 3:
number |= (bytes[1] & 0xFF) << 16;
case 2:
number |= (bytes[2] & 0xFF) << 8;
case 1:
number |= (bytes[3] & 0xFF) << 0;
}
return dorkbox.bytes.UInteger.valueOf(number);
}
public static
dorkbox.bytes.UInteger from(final byte b0, final byte b1, final byte b2, final byte b3) {
int number = (b0 & 0xFF) << 24 |
(b1 & 0xFF) << 16 |
(b2 & 0xFF) << 8 |
(b3 & 0xFF) << 0;
return dorkbox.bytes.UInteger.valueOf(number);
}
public static
dorkbox.bytes.UInteger from(final ByteBuffer buff) {
return from(buff.get(), buff.get(), buff.get(), buff.get());
}
public static
dorkbox.bytes.UInteger from(final InputStream inputStream) throws IOException {
return from((byte) inputStream.read(), (byte) inputStream.read(), (byte) inputStream.read(), (byte) inputStream.read());
}
public static
byte[] toBytes(final dorkbox.bytes.UInteger x) {
long num = x.longValue();
return new byte[] {(byte) ((num & 0xFF000000L) >> 24), (byte) ((num & 0x00FF0000L) >> 16), (byte) ((num & 0x0000FF00L) >> 8),
(byte) (num & 0x000000FFL >> 0)};
}
public static
void toBytes(final dorkbox.bytes.UInteger x, final byte[] bytes, final int offset) {
long num = x.longValue();
bytes[offset + 0] = (byte) ((num & 0xFF000000L) >> 24);
bytes[offset + 1] = (byte) ((num & 0x00FF0000L) >> 16);
bytes[offset + 2] = (byte) ((num & 0x0000FF00L) >> 8);
bytes[offset + 3] = (byte) (num & 0x000000FFL >> 0);
}
public static
void toBytes(final dorkbox.bytes.UInteger x, final byte[] bytes) {
long num = x.longValue();
bytes[0] = (byte) ((num & 0xFF000000L) >> 24);
bytes[1] = (byte) ((num & 0x00FF0000L) >> 16);
bytes[2] = (byte) ((num & 0x0000FF00L) >> 8);
bytes[3] = (byte) (num & 0x000000FFL >> 0);
}
private
UInt_() {
}
}
/**
* LONG to and from bytes
*/
public static final
class Long_ {
@SuppressWarnings("fallthrough")
public static
long from(final byte[] bytes, final int offset, final int bytenum) {
long number = 0;
switch (bytenum) {
case 8:
number |= (long) (bytes[offset + 0] & 0xFF) << 56;
case 7:
number |= (long) (bytes[offset + 1] & 0xFF) << 48;
case 6:
number |= (long) (bytes[offset + 2] & 0xFF) << 40;
case 5:
number |= (long) (bytes[offset + 3] & 0xFF) << 32;
case 4:
number |= (long) (bytes[offset + 4] & 0xFF) << 24;
case 3:
number |= (long) (bytes[offset + 5] & 0xFF) << 16;
case 2:
number |= (long) (bytes[offset + 6] & 0xFF) << 8;
case 1:
number |= (long) (bytes[offset + 7] & 0xFF) << 0;
}
return number;
}
@SuppressWarnings("fallthrough")
public static
long from(final byte[] bytes) {
long number = 0L;
switch (bytes.length) {
default:
case 8:
number |= (long) (bytes[0] & 0xFF) << 56;
case 7:
number |= (long) (bytes[1] & 0xFF) << 48;
case 6:
number |= (long) (bytes[2] & 0xFF) << 40;
case 5:
number |= (long) (bytes[3] & 0xFF) << 32;
case 4:
number |= (long) (bytes[4] & 0xFF) << 24;
case 3:
number |= (long) (bytes[5] & 0xFF) << 16;
case 2:
number |= (long) (bytes[6] & 0xFF) << 8;
case 1:
number |= (long) (bytes[7] & 0xFF) << 0;
}
return number;
}
public static
long from(final byte b0, final byte b1, final byte b2, final byte b3, final byte b4, final byte b5, final byte b6, final byte b7) {
return (long) (b0 & 0xFF) << 56 |
(long) (b1 & 0xFF) << 48 |
(long) (b2 & 0xFF) << 40 |
(long) (b3 & 0xFF) << 32 |
(long) (b4 & 0xFF) << 24 |
(long) (b5 & 0xFF) << 16 |
(long) (b6 & 0xFF) << 8 |
(long) (b7 & 0xFF) << 0;
}
public static
long from(final ByteBuffer buff) {
return from(buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get());
}
public static
long from(final InputStream inputStream) throws IOException {
return from((byte) inputStream.read(),
(byte) inputStream.read(),
(byte) inputStream.read(),
(byte) inputStream.read(),
(byte) inputStream.read(),
(byte) inputStream.read(),
(byte) inputStream.read(),
(byte) inputStream.read());
}
public static
byte[] toBytes(final long x) {
return new byte[] {(byte) (x >> 56), (byte) (x >> 48), (byte) (x >> 40), (byte) (x >> 32), (byte) (x >> 24), (byte) (x >> 16),
(byte) (x >> 8), (byte) (x >> 0)};
}
public static
void toBytes(final long x, final byte[] bytes, final int offset) {
bytes[offset + 0] = (byte) (x >> 56);
bytes[offset + 1] = (byte) (x >> 48);
bytes[offset + 2] = (byte) (x >> 40);
bytes[offset + 3] = (byte) (x >> 32);
bytes[offset + 4] = (byte) (x >> 24);
bytes[offset + 5] = (byte) (x >> 16);
bytes[offset + 6] = (byte) (x >> 8);
bytes[offset + 7] = (byte) (x >> 0);
}
public static
void toBytes(final long x, final byte[] bytes) {
bytes[0] = (byte) (x >> 56);
bytes[1] = (byte) (x >> 48);
bytes[2] = (byte) (x >> 40);
bytes[3] = (byte) (x >> 32);
bytes[4] = (byte) (x >> 24);
bytes[5] = (byte) (x >> 16);
bytes[6] = (byte) (x >> 8);
bytes[7] = (byte) (x >> 0);
}
private
Long_() {
}
}
/**
* UNSIGNED LONG to and from bytes
*/
public static final
class ULong_ {
@SuppressWarnings("fallthrough")
public static
dorkbox.bytes.ULong from(final byte[] bytes, final int offset, final int bytenum) {
long number = 0;
switch (bytenum) {
case 8:
number |= (long) (bytes[offset + 0] & 0xFF) << 56;
case 7:
number |= (long) (bytes[offset + 1] & 0xFF) << 48;
case 6:
number |= (long) (bytes[offset + 2] & 0xFF) << 40;
case 5:
number |= (long) (bytes[offset + 3] & 0xFF) << 32;
case 4:
number |= (long) (bytes[offset + 4] & 0xFF) << 24;
case 3:
number |= (long) (bytes[offset + 5] & 0xFF) << 16;
case 2:
number |= (long) (bytes[offset + 6] & 0xFF) << 8;
case 1:
number |= (long) (bytes[offset + 7] & 0xFF) << 0;
}
return dorkbox.bytes.ULong.valueOf(number);
}
public static
dorkbox.bytes.ULong from(final byte[] bytes) {
BigInteger ulong = new BigInteger(1, bytes);
return dorkbox.bytes.ULong.valueOf(ulong);
}
public static
dorkbox.bytes.ULong from(final byte b0, final byte b1, final byte b2, final byte b3, final byte b4, final byte b5, final byte b6, final byte b7) {
byte[] bytes = new byte[] {b0, b1, b2, b3, b4, b5, b6, b7};
BigInteger ulong = new BigInteger(1, bytes);
return dorkbox.bytes.ULong.valueOf(ulong);
}
public static
dorkbox.bytes.ULong from(final ByteBuffer buff) {
return from(buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get());
}
public static
dorkbox.bytes.ULong from(final InputStream inputStream) throws IOException {
return from((byte) inputStream.read(),
(byte) inputStream.read(),
(byte) inputStream.read(),
(byte) inputStream.read(),
(byte) inputStream.read(),
(byte) inputStream.read(),
(byte) inputStream.read(),
(byte) inputStream.read());
}
public static
byte[] toBytes(final dorkbox.bytes.ULong x) {
// returns the shortest length byte array possible
byte[] bytes = x.toBigInteger()
.toByteArray();
if (bytes.length < 8) {
byte[] fixedBytes = new byte[8];
int length = bytes.length;
for (int i = 0; i < 8; i++) {
if (i < length) {
fixedBytes[i] = bytes[i];
}
else {
fixedBytes[i] = 0;
}
}
bytes = fixedBytes;
}
return bytes;
}
public static
void toBytes(final dorkbox.bytes.ULong x, final byte[] bytes, final int offset) {
final byte[] bytes1 = toBytes(x);
int length = bytes.length;
int pos = 8;
while (length > 0) {
bytes[pos--] = bytes1[offset + length--];
}
}
public static
void toBytes(final dorkbox.bytes.ULong x, final byte[] bytes) {
final byte[] bytes1 = toBytes(x);
int length = bytes.length;
int pos = 8;
while (length > 0) {
bytes[pos--] = bytes1[length--];
}
}
private
ULong_() {
}
}
}

View File

@ -0,0 +1,114 @@
/*
* Copyright 2021 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.bytes;
import java.util.Arrays;
/**
* Necessary to provide equals and hashcode methods on a byte arrays, if they are to be used as keys in a map/set/etc
*/
public
class ByteArrayWrapper {
private byte[] data;
private Integer hashCode;
private
ByteArrayWrapper() {
// this is necessary for kryo
}
/**
* Permits the re-use of a byte array.
*
* @param copyBytes if TRUE, then the byteArray is copied. if FALSE, the byte array is used as-is.
* Using FALSE IS DANGEROUS!!!! If the underlying byte array is modified, this changes as well.
*/
public
ByteArrayWrapper(byte[] data, boolean copyBytes) {
if (data == null) {
throw new NullPointerException();
}
int length = data.length;
if (copyBytes) {
this.data = new byte[length];
// copy so it's immutable as a key.
System.arraycopy(data, 0, this.data, 0, length);
}
else {
this.data = data;
}
}
/**
* Makes a safe copy of the byte array, so that changes to the original do not affect the wrapper.
* Side affect is additional memory is used.
*/
public static
ByteArrayWrapper copy(byte[] data) {
if (data == null) {
return null;
}
return new ByteArrayWrapper(data, true);
}
/**
* Does not make a copy of the data, so changes to the original will also affect the wrapper.
* Side affect is no extra memory is needed.
*/
public static
ByteArrayWrapper wrap(byte[] data) {
if (data == null) {
return null;
}
return new ByteArrayWrapper(data, false);
}
public
byte[] getBytes() {
return this.data;
}
@Override
public
int hashCode() {
// might be null for a thread because it's stale. who cares, get the value again
Integer hashCode = this.hashCode;
if (hashCode == null) {
hashCode = Arrays.hashCode(this.data);
this.hashCode = hashCode;
}
return hashCode;
}
@Override
public
boolean equals(Object other) {
if (!(other instanceof ByteArrayWrapper)) {
return false;
}
// CANNOT be null, so we don't have to null check!
return Arrays.equals(this.data, ((ByteArrayWrapper) other).data);
}
@Override
public
String toString() {
return "ByteArrayWrapper " + java.util.Arrays.toString(this.data);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,769 @@
/*
* Copyright 2021 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.bytes;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.nio.ByteBuffer;
/**
* This is intel/amd/arm arch!
* <p/>
* arm is technically bi-endian
* <p/>
* Network byte order IS big endian, as is Java.
*/
@SuppressWarnings("ALL")
public
class LittleEndian {
// the following are ALL in Little-Endian (byte[0] is LEAST significant)
/**
* CHAR to and from bytes
*/
public static final
class Char_ {
@SuppressWarnings("fallthrough")
public static
char from(final byte[] bytes, final int offset, final int byteNum) {
char number = 0;
switch (byteNum) {
case 2:
number |= (bytes[offset + 1] & 0xFF) << 8;
case 1:
number |= (bytes[offset + 0] & 0xFF) << 0;
}
return number;
}
@SuppressWarnings("fallthrough")
public static
char from(final byte[] bytes) {
char number = 0;
switch (bytes.length) {
default:
case 2:
number |= (bytes[1] & 0xFF) << 8;
case 1:
number |= (bytes[0] & 0xFF) << 0;
}
return number;
}
public static
char from(final byte b0, final byte b1) {
return (char) ((b1 & 0xFF) << 8 | (b0 & 0xFF) << 0);
}
public static
char from(final ByteBuffer buff) {
return from(buff.get(), buff.get());
}
public static
char from(final InputStream inputStream) throws IOException {
return from((byte) inputStream.read(), (byte) inputStream.read());
}
public static
byte[] toBytes(final char x) {
return new byte[] {(byte) (x >> 0), (byte) (x >> 8)};
}
public static
void toBytes(final char x, final byte[] bytes, final int offset) {
bytes[offset + 1] = (byte) (x >> 8);
bytes[offset + 0] = (byte) (x >> 0);
}
public static
void toBytes(final char x, final byte[] bytes) {
bytes[1] = (byte) (x >> 8);
bytes[0] = (byte) (x >> 0);
}
private
Char_() {
}
}
/**
* UNSIGNED CHAR to and from bytes
*/
public static final
class UChar_ {
@SuppressWarnings("fallthrough")
public static
UShort from(final byte[] bytes, final int offset, final int bytenum) {
char number = 0;
switch (bytenum) {
case 2:
number |= (bytes[offset + 1] & 0xFF) << 8;
case 1:
number |= (bytes[offset + 0] & 0xFF) << 0;
}
return UShort.valueOf(number);
}
@SuppressWarnings("fallthrough")
public static
UShort from(final byte[] bytes) {
short number = 0;
switch (bytes.length) {
default:
case 2:
number |= (bytes[1] & 0xFF) << 8;
case 1:
number |= (bytes[0] & 0xFF) << 0;
}
return UShort.valueOf(number);
}
public static
UShort from(final byte b0, final byte b1) {
return UShort.valueOf((short) ((b1 & 0xFF) << 8) | (b0 & 0xFF) << 0);
}
public static
UShort from(final ByteBuffer buff) {
return from(buff.get(), buff.get());
}
public static
UShort from(final InputStream inputStream) throws IOException {
return from((byte) inputStream.read(), (byte) inputStream.read());
}
public static
byte[] toBytes(UShort x) {
int num = x.intValue();
return new byte[] {(byte) (num & 0x00FF >> 0), (byte) ((num & 0xFF00) >> 8)};
}
public static
void toBytes(final UShort x, final byte[] bytes, final int offset) {
int num = x.intValue();
bytes[offset + 1] = (byte) ((num & 0xFF00) >> 8);
bytes[offset + 0] = (byte) (num & 0x00FF >> 0);
}
public static
void toBytes(final UShort x, final byte[] bytes) {
int num = x.intValue();
bytes[1] = (byte) ((num & 0xFF00) >> 8);
bytes[0] = (byte) (num & 0x00FF >> 0);
}
private
UChar_() {
}
}
/**
* SHORT to and from bytes
*/
public static final
class Short_ {
@SuppressWarnings("fallthrough")
public static
short from(final byte[] bytes, final int offset, final int bytenum) {
short number = 0;
switch (bytenum) {
case 2:
number |= (bytes[offset + 1] & 0xFF) << 8;
case 1:
number |= (bytes[offset + 0] & 0xFF) << 0;
}
return number;
}
@SuppressWarnings("fallthrough")
public static
short from(final byte[] bytes) {
short number = 0;
switch (bytes.length) {
default:
case 2:
number |= (bytes[1] & 0xFF) << 8;
case 1:
number |= (bytes[0] & 0xFF) << 0;
}
return number;
}
public static
short from(final byte b0, final byte b1) {
return (short) ((b1 & 0xFF) << 8 | (b0 & 0xFF) << 0);
}
public static
short from(final ByteBuffer buff) {
return from(buff.get(), buff.get());
}
public static
short from(final InputStream inputStream) throws IOException {
return from((byte) inputStream.read(), (byte) inputStream.read());
}
public static
byte[] toBytes(final short x) {
return new byte[] {(byte) (x >> 0), (byte) (x >> 8)};
}
public static
void toBytes(final short x, final byte[] bytes, final int offset) {
bytes[offset + 1] = (byte) (x >> 8);
bytes[offset + 0] = (byte) (x >> 0);
}
public static
void toBytes(final short x, final byte[] bytes) {
bytes[1] = (byte) (x >> 8);
bytes[0] = (byte) (x >> 0);
}
private
Short_() {
}
}
/**
* UNSIGNED SHORT to and from bytes
*/
public static final
class UShort_ {
@SuppressWarnings("fallthrough")
public static
UShort from(final byte[] bytes, final int offset, final int bytenum) {
short number = 0;
switch (bytenum) {
case 2:
number |= (bytes[offset + 1] & 0xFF) << 8;
case 1:
number |= (bytes[offset + 0] & 0xFF) << 0;
}
return UShort.valueOf(number);
}
@SuppressWarnings("fallthrough")
public static
UShort from(final byte[] bytes) {
short number = 0;
switch (bytes.length) {
default:
case 2:
number |= (bytes[1] & 0xFF) << 8;
case 1:
number |= (bytes[0] & 0xFF) << 0;
}
return UShort.valueOf(number);
}
public static
UShort from(final byte b0, final byte b1) {
return UShort.valueOf((short) ((b1 & 0xFF) << 8 | (b0 & 0xFF) << 0));
}
public static
UShort from(final ByteBuffer buff) {
return from(buff.get(), buff.get());
}
public static
UShort from(final InputStream inputStream) throws IOException {
return from((byte) inputStream.read(), (byte) inputStream.read());
}
public static
byte[] toBytes(final UShort x) {
int num = x.intValue();
return new byte[] {(byte) (num & 0x00FF >> 0), (byte) ((num & 0xFF00) >> 8)};
}
public static
void toBytes(final UShort x, final byte[] bytes, final int offset) {
int num = x.intValue();
bytes[offset + 1] = (byte) ((num & 0xFF00) >> 8);
bytes[offset + 0] = (byte) (num & 0x00FF >> 0);
}
public static
void toBytes(final UShort x, final byte[] bytes) {
int num = x.intValue();
bytes[1] = (byte) ((num & 0xFF00) >> 8);
bytes[0] = (byte) (num & 0x00FF >> 0);
}
private
UShort_() {
}
}
/**
* INT to and from bytes
*/
public static final
class Int_ {
@SuppressWarnings("fallthrough")
public static
int from(final byte[] bytes, final int offset, final int bytenum) {
int number = 0;
switch (bytenum) {
case 4:
number |= (bytes[offset + 3] & 0xFF) << 24;
case 3:
number |= (bytes[offset + 2] & 0xFF) << 16;
case 2:
number |= (bytes[offset + 1] & 0xFF) << 8;
case 1:
number |= (bytes[offset + 0] & 0xFF) << 0;
}
return number;
}
@SuppressWarnings("fallthrough")
public static
int from(final byte[] bytes) {
int number = 0;
switch (bytes.length) {
default:
case 4:
number |= (bytes[3] & 0xFF) << 24;
case 3:
number |= (bytes[2] & 0xFF) << 16;
case 2:
number |= (bytes[1] & 0xFF) << 8;
case 1:
number |= (bytes[0] & 0xFF) << 0;
}
return number;
}
public static
int from(final byte b0, final byte b1, final byte b2, final byte b3) {
return (b3 & 0xFF) << 24 |
(b2 & 0xFF) << 16 |
(b1 & 0xFF) << 8 |
(b0 & 0xFF) << 0;
}
public static
int from(final ByteBuffer buff) {
return from(buff.get(), buff.get(), buff.get(), buff.get());
}
public static
int from(final InputStream inputStream) throws IOException {
return from((byte) inputStream.read(), (byte) inputStream.read(), (byte) inputStream.read(), (byte) inputStream.read());
}
public static
byte[] toBytes(final int x) {
return new byte[] {(byte) (x >> 0), (byte) (x >> 8), (byte) (x >> 16), (byte) (x >> 24)};
}
public static
void toBytes(final int x, final byte[] bytes, final int offset) {
bytes[offset + 3] = (byte) (x >> 24);
bytes[offset + 2] = (byte) (x >> 16);
bytes[offset + 1] = (byte) (x >> 8);
bytes[offset + 0] = (byte) (x >> 0);
}
public static
void toBytes(final int x, final byte[] bytes) {
bytes[3] = (byte) (x >> 24);
bytes[2] = (byte) (x >> 16);
bytes[1] = (byte) (x >> 8);
bytes[0] = (byte) (x >> 0);
}
private
Int_() {
}
}
/**
* UNSIGNED INT to and from bytes
*/
public static final
class UInt_ {
@SuppressWarnings("fallthrough")
public static
UInteger from(final byte[] bytes, final int offset, final int bytenum) {
int number = 0;
switch (bytenum) {
case 4:
number |= (bytes[offset + 3] & 0xFF) << 24;
case 3:
number |= (bytes[offset + 2] & 0xFF) << 16;
case 2:
number |= (bytes[offset + 1] & 0xFF) << 8;
case 1:
number |= (bytes[offset + 0] & 0xFF) << 0;
}
return UInteger.valueOf(number);
}
@SuppressWarnings("fallthrough")
public static
UInteger from(final byte[] bytes) {
int number = 0;
switch (bytes.length) {
default:
case 4:
number |= (bytes[3] & 0xFF) << 24;
case 3:
number |= (bytes[2] & 0xFF) << 16;
case 2:
number |= (bytes[1] & 0xFF) << 8;
case 1:
number |= (bytes[0] & 0xFF) << 0;
}
return UInteger.valueOf(number);
}
public static
UInteger from(final byte b0, final byte b1, final byte b2, final byte b3) {
int number = (b3 & 0xFF) << 24 |
(b2 & 0xFF) << 16 |
(b1 & 0xFF) << 8 |
(b0 & 0xFF) << 0;
return UInteger.valueOf(number);
}
public static
UInteger from(final ByteBuffer buff) {
return from(buff.get(), buff.get(), buff.get(), buff.get());
}
public static
UInteger from(final InputStream inputStream) throws IOException {
return from((byte) inputStream.read(), (byte) inputStream.read(), (byte) inputStream.read(), (byte) inputStream.read());
}
public static
byte[] toBytes(final UInteger x) {
long num = x.longValue();
return new byte[] {(byte) (num & 0x000000FFL >> 0), (byte) ((num & 0x0000FF00L) >> 8), (byte) ((num & 0x00FF0000L) >> 16),
(byte) ((num & 0xFF000000L) >> 24)};
}
public static
void toBytes(final UInteger x, final byte[] bytes, final int offset) {
long num = x.longValue();
bytes[offset + 3] = (byte) ((num & 0xFF000000L) >> 24);
bytes[offset + 2] = (byte) ((num & 0x00FF0000L) >> 16);
bytes[offset + 1] = (byte) ((num & 0x0000FF00L) >> 8);
bytes[offset + 0] = (byte) (num & 0x000000FFL >> 0);
}
public static
void toBytes(final UInteger x, final byte[] bytes) {
long num = x.longValue();
bytes[3] = (byte) ((num & 0xFF000000L) >> 24);
bytes[2] = (byte) ((num & 0x00FF0000L) >> 16);
bytes[1] = (byte) ((num & 0x0000FF00L) >> 8);
bytes[0] = (byte) (num & 0x000000FFL >> 0);
}
private
UInt_() {
}
}
/**
* LONG to and from bytes
*/
public static final
class Long_ {
@SuppressWarnings("fallthrough")
public static
long from(final byte[] bytes, final int offset, final int bytenum) {
long number = 0;
switch (bytenum) {
case 8:
number |= (long) (bytes[offset + 7] & 0xFF) << 56;
case 7:
number |= (long) (bytes[offset + 6] & 0xFF) << 48;
case 6:
number |= (long) (bytes[offset + 5] & 0xFF) << 40;
case 5:
number |= (long) (bytes[offset + 4] & 0xFF) << 32;
case 4:
number |= (long) (bytes[offset + 3] & 0xFF) << 24;
case 3:
number |= (long) (bytes[offset + 2] & 0xFF) << 16;
case 2:
number |= (long) (bytes[offset + 1] & 0xFF) << 8;
case 1:
number |= (long) (bytes[offset + 0] & 0xFF) << 0;
}
return number;
}
@SuppressWarnings("fallthrough")
public static
long from(final byte[] bytes) {
long number = 0L;
switch (bytes.length) {
default:
case 8:
number |= (long) (bytes[7] & 0xFF) << 56;
case 7:
number |= (long) (bytes[6] & 0xFF) << 48;
case 6:
number |= (long) (bytes[5] & 0xFF) << 40;
case 5:
number |= (long) (bytes[4] & 0xFF) << 32;
case 4:
number |= (long) (bytes[3] & 0xFF) << 24;
case 3:
number |= (long) (bytes[2] & 0xFF) << 16;
case 2:
number |= (long) (bytes[1] & 0xFF) << 8;
case 1:
number |= (long) (bytes[0] & 0xFF) << 0;
}
return number;
}
public static
long from(final byte b0, final byte b1, final byte b2, final byte b3, final byte b4, final byte b5, final byte b6, final byte b7) {
return (long) (b7 & 0xFF) << 56 |
(long) (b6 & 0xFF) << 48 |
(long) (b5 & 0xFF) << 40 |
(long) (b4 & 0xFF) << 32 |
(long) (b3 & 0xFF) << 24 |
(long) (b2 & 0xFF) << 16 |
(long) (b1 & 0xFF) << 8 |
(long) (b0 & 0xFF) << 0;
}
public static
long from(final ByteBuffer buff) {
return from(buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get());
}
public static
long from(final InputStream inputStream) throws IOException {
return from((byte) inputStream.read(),
(byte) inputStream.read(),
(byte) inputStream.read(),
(byte) inputStream.read(),
(byte) inputStream.read(),
(byte) inputStream.read(),
(byte) inputStream.read(),
(byte) inputStream.read());
}
public static
byte[] toBytes(final long x) {
return new byte[] {(byte) (x >> 0), (byte) (x >> 8), (byte) (x >> 16), (byte) (x >> 24), (byte) (x >> 32), (byte) (x >> 40),
(byte) (x >> 48), (byte) (x >> 56),};
}
public static
void toBytes(final long x, final byte[] bytes, final int offset) {
bytes[offset + 7] = (byte) (x >> 56);
bytes[offset + 6] = (byte) (x >> 48);
bytes[offset + 5] = (byte) (x >> 40);
bytes[offset + 4] = (byte) (x >> 32);
bytes[offset + 3] = (byte) (x >> 24);
bytes[offset + 2] = (byte) (x >> 16);
bytes[offset + 1] = (byte) (x >> 8);
bytes[offset + 0] = (byte) (x >> 0);
}
public static
void toBytes(final long x, final byte[] bytes) {
bytes[7] = (byte) (x >> 56);
bytes[6] = (byte) (x >> 48);
bytes[5] = (byte) (x >> 40);
bytes[4] = (byte) (x >> 32);
bytes[3] = (byte) (x >> 24);
bytes[2] = (byte) (x >> 16);
bytes[1] = (byte) (x >> 8);
bytes[0] = (byte) (x >> 0);
}
private
Long_() {
}
}
/**
* UNSIGNED LONG to and from bytes
*/
public static final
class ULong_ {
@SuppressWarnings("fallthrough")
public static
ULong from(final byte[] bytes, final int offset, final int bytenum) {
long number = 0;
switch (bytenum) {
case 8:
number |= (long) (bytes[offset + 7] & 0xFF) << 56;
case 7:
number |= (long) (bytes[offset + 6] & 0xFF) << 48;
case 6:
number |= (long) (bytes[offset + 5] & 0xFF) << 40;
case 5:
number |= (long) (bytes[offset + 4] & 0xFF) << 32;
case 4:
number |= (long) (bytes[offset + 3] & 0xFF) << 24;
case 3:
number |= (long) (bytes[offset + 2] & 0xFF) << 16;
case 2:
number |= (long) (bytes[offset + 1] & 0xFF) << 8;
case 1:
number |= (long) (bytes[offset + 0] & 0xFF) << 0;
}
return ULong.valueOf(number);
}
public static
ULong from(final byte[] bytes) {
BigInteger ulong = new BigInteger(1, bytes);
return ULong.valueOf(ulong);
}
public static
ULong from(final byte b0, final byte b1, final byte b2, final byte b3, final byte b4, final byte b5, final byte b6, final byte b7) {
byte[] bytes = new byte[] {b7, b6, b5, b4, b3, b2, b1, b0};
BigInteger ulong = new BigInteger(1, bytes);
return ULong.valueOf(ulong);
}
public static
ULong from(final ByteBuffer buff) {
return from(buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get());
}
public static
ULong from(final InputStream inputStream) throws IOException {
return from((byte) inputStream.read(),
(byte) inputStream.read(),
(byte) inputStream.read(),
(byte) inputStream.read(),
(byte) inputStream.read(),
(byte) inputStream.read(),
(byte) inputStream.read(),
(byte) inputStream.read());
}
public static
byte[] toBytes(final ULong x) {
byte[] bytes = new byte[8];
int offset = 0;
byte temp_byte[] = x.toBigInteger()
.toByteArray();
int array_count = temp_byte.length - 1;
for (int i = 7; i >= 0; i--) {
if (array_count >= 0) {
bytes[offset] = temp_byte[array_count];
}
else {
bytes[offset] = (byte) 00;
}
offset++;
array_count--;
}
return bytes;
}
public static
void toBytes(final ULong x, final byte[] bytes, final int offset) {
final byte[] bytes1 = toBytes(x);
int length = bytes.length;
int pos = 8;
while (length > 0) {
bytes[pos--] = bytes1[offset + length--];
}
}
public static
void toBytes(final ULong x, final byte[] bytes) {
final byte[] bytes1 = toBytes(x);
int length = bytes.length;
int pos = 8;
while (length > 0) {
bytes[pos--] = bytes1[length--];
}
}
private
ULong_() {
}
}
}

View File

@ -0,0 +1,477 @@
/*
* Copyright 2021 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.
*
* Copyright (c) 2008, Nathan Sweet
* All rights reserved.
*
* 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.
* - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
*/
package dorkbox.bytes;
@SuppressWarnings({"Duplicates", "NumericCastThatLosesPrecision", "UnusedAssignment", "unused"})
public
class OptimizeUtilsByteArray {
/**
* Returns the number of bytes that would be written with {@link #writeInt(byte[], int, boolean)}.
*
* @param optimizePositive
* true if you want to optimize the number of bytes needed to write the length value
*/
public static
int intLength(int value, boolean optimizePositive) {
return dorkbox.bytes.OptimizeUtilsByteBuf.intLength(value, optimizePositive);
}
// int
/**
* look at buffer, and see if we can read the length of the int off of it. (from the reader index)
*
* @return 0 if we could not read anything, >0 for the number of bytes for the int on the buffer
*/
@SuppressWarnings("SimplifiableIfStatement")
public static
boolean canReadInt(byte[] buffer) {
int position = 0;
return canReadInt(buffer, position);
}
/**
* FROM KRYO
* <p>
* look at buffer, and see if we can read the length of the int off of it. (from the reader index)
*
* @param position where in the buffer to start reading
* @return 0 if we could not read anything, >0 for the number of bytes for the int on the buffer
*/
@SuppressWarnings("SimplifiableIfStatement")
public static
boolean canReadInt(final byte[] buffer, int position) {
int length = buffer.length;
if (length >= 5) {
return true;
}
if ((buffer[position++] & 0x80) == 0) {
return true;
}
if (position == length) {
return false;
}
if ((buffer[position++] & 0x80) == 0) {
return true;
}
if (position == length) {
return false;
}
if ((buffer[position++] & 0x80) == 0) {
return true;
}
if (position == length) {
return false;
}
if ((buffer[position++] & 0x80) == 0) {
return true;
}
return position != length;
}
/**
* Reads an int from the buffer that was optimized at position 0
*
* @param optimizePositive
* If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (5
* bytes). This ultimately means that it will use fewer bytes for positive numbers.
*/
public static
int readInt(byte[] buffer, boolean optimizePositive) {
int position = 0;
return readInt(buffer, optimizePositive, position);
}
/**
* FROM KRYO
* <p>
* Reads an int from the buffer that was optimized.
*
* @param position where in the buffer to start reading
* @param optimizePositive
* If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (5
* bytes). This ultimately means that it will use fewer bytes for positive numbers.
*/
public static
int readInt(final byte[] buffer, final boolean optimizePositive, int position) {
int b = buffer[position++];
int result = b & 0x7F;
if ((b & 0x80) != 0) {
b = buffer[position++];
result |= (b & 0x7F) << 7;
if ((b & 0x80) != 0) {
b = buffer[position++];
result |= (b & 0x7F) << 14;
if ((b & 0x80) != 0) {
b = buffer[position++];
result |= (b & 0x7F) << 21;
if ((b & 0x80) != 0) {
b = buffer[position++];
result |= (b & 0x7F) << 28;
}
}
}
}
return optimizePositive ? result : result >>> 1 ^ -(result & 1);
}
/**
* Writes the specified int to the buffer using 1 to 5 bytes, depending on the size of the number.
*
* @param optimizePositive
* If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (5
* bytes). This ultimately means that it will use fewer bytes for positive numbers.
*
* @return the number of bytes written.
*/
public static
int writeInt(byte[] buffer, int value, boolean optimizePositive) {
int position = 0;
return writeInt(buffer, value, optimizePositive, position);
}
/**
* FROM KRYO
* <p>
* Writes the specified int to the buffer using 1 to 5 bytes, depending on the size of the number.
*
* @param position where in the buffer to start writing
* @param optimizePositive
* If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (5
* bytes). This ultimately means that it will use fewer bytes for positive numbers.
*
* @return the number of bytes written.
*/
public static
int writeInt(final byte[] buffer, int value, final boolean optimizePositive, int position) {
if (!optimizePositive) {
value = value << 1 ^ value >> 31;
}
if (value >>> 7 == 0) {
buffer[position++] = (byte) value;
return 1;
}
if (value >>> 14 == 0) {
buffer[position++] = (byte) (value & 0x7F | 0x80);
buffer[position++] = (byte) (value >>> 7);
return 2;
}
if (value >>> 21 == 0) {
buffer[position++] = (byte) (value & 0x7F | 0x80);
buffer[position++] = (byte) (value >>> 7 | 0x80);
buffer[position++] = (byte) (value >>> 14);
return 3;
}
if (value >>> 28 == 0) {
buffer[position++] = (byte) (value & 0x7F | 0x80);
buffer[position++] = (byte) (value >>> 7 | 0x80);
buffer[position++] = (byte) (value >>> 14 | 0x80);
buffer[position++] = (byte) (value >>> 21);
return 4;
}
buffer[position++] = (byte) (value & 0x7F | 0x80);
buffer[position++] = (byte) (value >>> 7 | 0x80);
buffer[position++] = (byte) (value >>> 14 | 0x80);
buffer[position++] = (byte) (value >>> 21 | 0x80);
buffer[position++] = (byte) (value >>> 28);
return 5;
}
/**
* Returns 1-9 bytes that would be written with {@link #writeLong(byte[], long, boolean)}.
*
* @param optimizePositive
* If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (9
* bytes). This ultimately means that it will use fewer bytes for positive numbers.
*/
public static
int longLength(long value, boolean optimizePositive) {
return dorkbox.bytes.OptimizeUtilsByteBuf.longLength(value, optimizePositive);
}
// long
/**
* Reads a 1-9 byte long.
*
* @param optimizePositive
* If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (9
* bytes). This ultimately means that it will use fewer bytes for positive numbers.
*/
public static
long readLong(byte[] buffer, boolean optimizePositive) {
int position = 0;
return readLong(buffer, optimizePositive, position);
}
/**
* FROM KRYO
* <p>
* Reads a 1-9 byte long.
*
* @param position where in the buffer to start reading
* @param optimizePositive
* If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (9
* bytes). This ultimately means that it will use fewer bytes for positive numbers.
*/
public static
long readLong(final byte[] buffer, final boolean optimizePositive, int position) {
int b = buffer[position++];
long result = b & 0x7F;
if ((b & 0x80) != 0) {
b = buffer[position++];
result |= (b & 0x7F) << 7;
if ((b & 0x80) != 0) {
b = buffer[position++];
result |= (b & 0x7F) << 14;
if ((b & 0x80) != 0) {
b = buffer[position++];
result |= (b & 0x7F) << 21;
if ((b & 0x80) != 0) {
b = buffer[position++];
result |= (long) (b & 0x7F) << 28;
if ((b & 0x80) != 0) {
b = buffer[position++];
result |= (long) (b & 0x7F) << 35;
if ((b & 0x80) != 0) {
b = buffer[position++];
result |= (long) (b & 0x7F) << 42;
if ((b & 0x80) != 0) {
b = buffer[position++];
result |= (long) (b & 0x7F) << 49;
if ((b & 0x80) != 0) {
b = buffer[position++];
result |= (long) b << 56;
}
}
}
}
}
}
}
}
if (!optimizePositive) {
result = result >>> 1 ^ -(result & 1);
}
return result;
}
/**
* Writes a 1-9 byte long.
*
* @param optimizePositive
* If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (9
* bytes).
*
* @return the number of bytes written.
*/
public static
int writeLong(byte[] buffer, long value, boolean optimizePositive) {
int position = 0;
return writeLong(buffer, value, optimizePositive, position);
}
/**
* FROM KRYO
* <p>
* Writes a 1-9 byte long.
*
* @param position where in the buffer to start writing
* @param optimizePositive
* If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (9
* bytes).
*
* @return the number of bytes written.
*/
public static
int writeLong(final byte[] buffer, long value, final boolean optimizePositive, int position) {
if (!optimizePositive) {
value = value << 1 ^ value >> 63;
}
if (value >>> 7 == 0) {
buffer[position++] = (byte) value;
return 1;
}
if (value >>> 14 == 0) {
buffer[position++] = (byte) (value & 0x7F | 0x80);
buffer[position++] = (byte) (value >>> 7);
return 2;
}
if (value >>> 21 == 0) {
buffer[position++] = (byte) (value & 0x7F | 0x80);
buffer[position++] = (byte) (value >>> 7 | 0x80);
buffer[position++] = (byte) (value >>> 14);
return 3;
}
if (value >>> 28 == 0) {
buffer[position++] = (byte) (value & 0x7F | 0x80);
buffer[position++] = (byte) (value >>> 7 | 0x80);
buffer[position++] = (byte) (value >>> 14 | 0x80);
buffer[position++] = (byte) (value >>> 21);
return 4;
}
if (value >>> 35 == 0) {
buffer[position++] = (byte) (value & 0x7F | 0x80);
buffer[position++] = (byte) (value >>> 7 | 0x80);
buffer[position++] = (byte) (value >>> 14 | 0x80);
buffer[position++] = (byte) (value >>> 21 | 0x80);
buffer[position++] = (byte) (value >>> 28);
return 5;
}
if (value >>> 42 == 0) {
buffer[position++] = (byte) (value & 0x7F | 0x80);
buffer[position++] = (byte) (value >>> 7 | 0x80);
buffer[position++] = (byte) (value >>> 14 | 0x80);
buffer[position++] = (byte) (value >>> 21 | 0x80);
buffer[position++] = (byte) (value >>> 28 | 0x80);
buffer[position++] = (byte) (value >>> 35);
return 6;
}
if (value >>> 49 == 0) {
buffer[position++] = (byte) (value & 0x7F | 0x80);
buffer[position++] = (byte) (value >>> 7 | 0x80);
buffer[position++] = (byte) (value >>> 14 | 0x80);
buffer[position++] = (byte) (value >>> 21 | 0x80);
buffer[position++] = (byte) (value >>> 28 | 0x80);
buffer[position++] = (byte) (value >>> 35 | 0x80);
buffer[position++] = (byte) (value >>> 42);
return 7;
}
if (value >>> 56 == 0) {
buffer[position++] = (byte) (value & 0x7F | 0x80);
buffer[position++] = (byte) (value >>> 7 | 0x80);
buffer[position++] = (byte) (value >>> 14 | 0x80);
buffer[position++] = (byte) (value >>> 21 | 0x80);
buffer[position++] = (byte) (value >>> 28 | 0x80);
buffer[position++] = (byte) (value >>> 35 | 0x80);
buffer[position++] = (byte) (value >>> 42 | 0x80);
buffer[position++] = (byte) (value >>> 49);
return 8;
}
buffer[position++] = (byte) (value & 0x7F | 0x80);
buffer[position++] = (byte) (value >>> 7 | 0x80);
buffer[position++] = (byte) (value >>> 14 | 0x80);
buffer[position++] = (byte) (value >>> 21 | 0x80);
buffer[position++] = (byte) (value >>> 28 | 0x80);
buffer[position++] = (byte) (value >>> 35 | 0x80);
buffer[position++] = (byte) (value >>> 42 | 0x80);
buffer[position++] = (byte) (value >>> 49 | 0x80);
buffer[position++] = (byte) (value >>> 56);
return 9;
}
/**
* look at buffer, and see if we can read the length of the long off of it (from the reader index).
*
* @return 0 if we could not read anything, >0 for the number of bytes for the long on the buffer
*/
public static
boolean canReadLong(byte[] buffer) {
int position = 0;
return canReadLong(buffer, position);
}
/**
* FROM KRYO
* <p>
* look at buffer, and see if we can read the length of the long off of it (from the reader index).
*
* @param position where in the buffer to start reading
* @return 0 if we could not read anything, >0 for the number of bytes for the long on the buffer
*/
private static
boolean canReadLong(final byte[] buffer, int position) {
int limit = buffer.length;
if (limit >= 9) {
return true;
}
if ((buffer[position++] & 0x80) == 0) {
return true;
}
if (position == limit) {
return false;
}
if ((buffer[position++] & 0x80) == 0) {
return true;
}
if (position == limit) {
return false;
}
if ((buffer[position++] & 0x80) == 0) {
return true;
}
if (position == limit) {
return false;
}
if ((buffer[position++] & 0x80) == 0) {
return true;
}
if (position == limit) {
return false;
}
if ((buffer[position++] & 0x80) == 0) {
return true;
}
if (position == limit) {
return false;
}
if ((buffer[position++] & 0x80) == 0) {
return true;
}
if (position == limit) {
return false;
}
if ((buffer[position++] & 0x80) == 0) {
return true;
}
if (position == limit) {
return false;
}
//noinspection SimplifiableIfStatement
if ((buffer[position++] & 0x80) == 0) {
return true;
}
return position != limit;
}
private
OptimizeUtilsByteArray() {
}
}

View File

@ -0,0 +1,381 @@
/*
* Copyright 2021 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.
*
* Copyright (c) 2008, Nathan Sweet
* All rights reserved.
*
* 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.
* - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
*/
package dorkbox.bytes;
import io.netty.buffer.ByteBuf;
@SuppressWarnings({"Duplicates", "NumericCastThatLosesPrecision", "unused"})
public
class OptimizeUtilsByteBuf {
// int
/**
* FROM KRYO
* <p>
* Returns the number of bytes that would be written with {@link #writeInt(ByteBuf, int, boolean)}.
*
* @param optimizePositive
* If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (5
* bytes). This ultimately means that it will use fewer bytes for positive numbers.
*/
public static
int intLength(int value, boolean optimizePositive) {
if (!optimizePositive) {
value = value << 1 ^ value >> 31;
}
if (value >>> 7 == 0) {
return 1;
}
if (value >>> 14 == 0) {
return 2;
}
if (value >>> 21 == 0) {
return 3;
}
if (value >>> 28 == 0) {
return 4;
}
return 5;
}
/**
* FROM KRYO
* <p>
* look at buffer, and see if we can read the length of the int off of it. (from the reader index)
*
* @return 0 if we could not read anything, >0 for the number of bytes for the int on the buffer
*/
public static
int canReadInt(ByteBuf buffer) {
int startIndex = buffer.readerIndex();
try {
int remaining = buffer.readableBytes();
for (int offset = 0, count = 1; offset < 32 && remaining > 0; offset += 7, remaining--, count++) {
int b = buffer.readByte();
if ((b & 0x80) == 0) {
return count;
}
}
return 0;
} finally {
buffer.readerIndex(startIndex);
}
}
/**
* FROM KRYO
* <p>
* Reads an int from the buffer that was optimized.
*
* @param optimizePositive
* If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (5
* bytes). This ultimately means that it will use fewer bytes for positive numbers.
*
* @return the number of bytes written.
*/
public static
int readInt(ByteBuf buffer, boolean optimizePositive) {
int b = buffer.readByte();
int result = b & 0x7F;
if ((b & 0x80) != 0) {
b = buffer.readByte();
result |= (b & 0x7F) << 7;
if ((b & 0x80) != 0) {
b = buffer.readByte();
result |= (b & 0x7F) << 14;
if ((b & 0x80) != 0) {
b = buffer.readByte();
result |= (b & 0x7F) << 21;
if ((b & 0x80) != 0) {
b = buffer.readByte();
result |= (b & 0x7F) << 28;
}
}
}
}
return optimizePositive ? result : result >>> 1 ^ -(result & 1);
}
/**
* FROM KRYO
* <p>
* Writes the specified int to the buffer using 1 to 5 bytes, depending on the size of the number.
*
* @param optimizePositive
* If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (5
* bytes). This ultimately means that it will use fewer bytes for positive numbers.
*
* @return the number of bytes written.
*/
public static
int writeInt(ByteBuf buffer, int value, boolean optimizePositive) {
if (!optimizePositive) {
value = value << 1 ^ value >> 31;
}
if (value >>> 7 == 0) {
buffer.writeByte((byte) value);
return 1;
}
if (value >>> 14 == 0) {
buffer.writeByte((byte) (value & 0x7F | 0x80));
buffer.writeByte((byte) (value >>> 7));
return 2;
}
if (value >>> 21 == 0) {
buffer.writeByte((byte) (value & 0x7F | 0x80));
buffer.writeByte((byte) (value >>> 7 | 0x80));
buffer.writeByte((byte) (value >>> 14));
return 3;
}
if (value >>> 28 == 0) {
buffer.writeByte((byte) (value & 0x7F | 0x80));
buffer.writeByte((byte) (value >>> 7 | 0x80));
buffer.writeByte((byte) (value >>> 14 | 0x80));
buffer.writeByte((byte) (value >>> 21));
return 4;
}
buffer.writeByte((byte) (value & 0x7F | 0x80));
buffer.writeByte((byte) (value >>> 7 | 0x80));
buffer.writeByte((byte) (value >>> 14 | 0x80));
buffer.writeByte((byte) (value >>> 21 | 0x80));
buffer.writeByte((byte) (value >>> 28));
return 5;
}
// long
/**
* Returns the 1-9 bytes that would be written with {@link #writeLong(ByteBuf, long, boolean)}.
*
* @param optimizePositive
* If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (9
* bytes). This ultimately means that it will use fewer bytes for positive numbers.
*/
public static
int longLength(long value, boolean optimizePositive) {
if (!optimizePositive) {
value = value << 1 ^ value >> 63;
}
if (value >>> 7 == 0) {
return 1;
}
if (value >>> 14 == 0) {
return 2;
}
if (value >>> 21 == 0) {
return 3;
}
if (value >>> 28 == 0) {
return 4;
}
if (value >>> 35 == 0) {
return 5;
}
if (value >>> 42 == 0) {
return 6;
}
if (value >>> 49 == 0) {
return 7;
}
if (value >>> 56 == 0) {
return 8;
}
return 9;
}
/**
* FROM KRYO
* <p>
* Reads a 1-9 byte long.
*
* @param optimizePositive
* If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (9
* bytes). This ultimately means that it will use fewer bytes for positive numbers.
*/
public static
long readLong(ByteBuf buffer, boolean optimizePositive) {
int b = buffer.readByte();
long result = b & 0x7F;
if ((b & 0x80) != 0) {
b = buffer.readByte();
result |= (b & 0x7F) << 7;
if ((b & 0x80) != 0) {
b = buffer.readByte();
result |= (b & 0x7F) << 14;
if ((b & 0x80) != 0) {
b = buffer.readByte();
result |= (b & 0x7F) << 21;
if ((b & 0x80) != 0) {
b = buffer.readByte();
result |= (long) (b & 0x7F) << 28;
if ((b & 0x80) != 0) {
b = buffer.readByte();
result |= (long) (b & 0x7F) << 35;
if ((b & 0x80) != 0) {
b = buffer.readByte();
result |= (long) (b & 0x7F) << 42;
if ((b & 0x80) != 0) {
b = buffer.readByte();
result |= (long) (b & 0x7F) << 49;
if ((b & 0x80) != 0) {
b = buffer.readByte();
result |= (long) b << 56;
}
}
}
}
}
}
}
}
if (!optimizePositive) {
result = result >>> 1 ^ -(result & 1);
}
return result;
}
/**
* FROM KRYO
* <p>
* Writes a 1-9 byte long.
*
* @param optimizePositive
* If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (9
* bytes). This ultimately means that it will use fewer bytes for positive numbers.
*
* @return the number of bytes written.
*/
public static
int writeLong(ByteBuf buffer, long value, boolean optimizePositive) {
if (!optimizePositive) {
value = value << 1 ^ value >> 63;
}
if (value >>> 7 == 0) {
buffer.writeByte((byte) value);
return 1;
}
if (value >>> 14 == 0) {
buffer.writeByte((byte) (value & 0x7F | 0x80));
buffer.writeByte((byte) (value >>> 7));
return 2;
}
if (value >>> 21 == 0) {
buffer.writeByte((byte) (value & 0x7F | 0x80));
buffer.writeByte((byte) (value >>> 7 | 0x80));
buffer.writeByte((byte) (value >>> 14));
return 3;
}
if (value >>> 28 == 0) {
buffer.writeByte((byte) (value & 0x7F | 0x80));
buffer.writeByte((byte) (value >>> 7 | 0x80));
buffer.writeByte((byte) (value >>> 14 | 0x80));
buffer.writeByte((byte) (value >>> 21));
return 4;
}
if (value >>> 35 == 0) {
buffer.writeByte((byte) (value & 0x7F | 0x80));
buffer.writeByte((byte) (value >>> 7 | 0x80));
buffer.writeByte((byte) (value >>> 14 | 0x80));
buffer.writeByte((byte) (value >>> 21 | 0x80));
buffer.writeByte((byte) (value >>> 28));
return 5;
}
if (value >>> 42 == 0) {
buffer.writeByte((byte) (value & 0x7F | 0x80));
buffer.writeByte((byte) (value >>> 7 | 0x80));
buffer.writeByte((byte) (value >>> 14 | 0x80));
buffer.writeByte((byte) (value >>> 21 | 0x80));
buffer.writeByte((byte) (value >>> 28 | 0x80));
buffer.writeByte((byte) (value >>> 35));
return 6;
}
if (value >>> 49 == 0) {
buffer.writeByte((byte) (value & 0x7F | 0x80));
buffer.writeByte((byte) (value >>> 7 | 0x80));
buffer.writeByte((byte) (value >>> 14 | 0x80));
buffer.writeByte((byte) (value >>> 21 | 0x80));
buffer.writeByte((byte) (value >>> 28 | 0x80));
buffer.writeByte((byte) (value >>> 35 | 0x80));
buffer.writeByte((byte) (value >>> 42));
return 7;
}
if (value >>> 56 == 0) {
buffer.writeByte((byte) (value & 0x7F | 0x80));
buffer.writeByte((byte) (value >>> 7 | 0x80));
buffer.writeByte((byte) (value >>> 14 | 0x80));
buffer.writeByte((byte) (value >>> 21 | 0x80));
buffer.writeByte((byte) (value >>> 28 | 0x80));
buffer.writeByte((byte) (value >>> 35 | 0x80));
buffer.writeByte((byte) (value >>> 42 | 0x80));
buffer.writeByte((byte) (value >>> 49));
return 8;
}
buffer.writeByte((byte) (value & 0x7F | 0x80));
buffer.writeByte((byte) (value >>> 7 | 0x80));
buffer.writeByte((byte) (value >>> 14 | 0x80));
buffer.writeByte((byte) (value >>> 21 | 0x80));
buffer.writeByte((byte) (value >>> 28 | 0x80));
buffer.writeByte((byte) (value >>> 35 | 0x80));
buffer.writeByte((byte) (value >>> 42 | 0x80));
buffer.writeByte((byte) (value >>> 49 | 0x80));
buffer.writeByte((byte) (value >>> 56));
return 9;
}
/**
* FROM KRYO
* <p>
* look at buffer, and see if we can read the length of the long off of it (from the reader index).
*
* @return 0 if we could not read anything, >0 for the number of bytes for the long on the buffer
*/
public static
int canReadLong(ByteBuf buffer) {
int position = buffer.readerIndex();
try {
int remaining = buffer.readableBytes();
for (int offset = 0, count = 1; offset < 64 && remaining > 0; offset += 7, remaining--, count++) {
int b = buffer.readByte();
if ((b & 0x80) == 0) {
return count;
}
}
return 0;
} finally {
buffer.readerIndex(position);
}
}
}

View File

@ -0,0 +1,326 @@
/*
* Copyright 2021 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.
*
*
* Copyright (c) 2011-2017, Data Geekery GmbH (http://www.datageekery.com)
*
* 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.bytes;
import java.io.ObjectStreamException;
import java.math.BigInteger;
/**
* The <code>unsigned byte</code> type
*
* @author Lukas Eder
* @author Ed Schaller
* @author Jens Nerche
*/
public final class UByte extends UNumber implements Comparable<UByte> {
/**
* Generated UID
*/
private static final long serialVersionUID = -6821055240959745390L;
/**
* Cached values
*/
private static final UByte[] VALUES = mkValues();
/**
* A constant holding the minimum value an <code>unsigned byte</code> can
* have, 0.
*/
public static final short MIN_VALUE = 0x00;
/**
* A constant holding the maximum value an <code>unsigned byte</code> can
* have, 2<sup>8</sup>-1.
*/
public static final short MAX_VALUE = 0xff;
/**
* A constant holding the minimum value an <code>unsigned byte</code> can
* have as UByte, 0.
*/
public static final UByte MIN = valueOf(0x00);
/**
* A constant holding the maximum value an <code>unsigned byte</code> can
* have as UByte, 2<sup>8</sup>-1.
*/
public static final UByte MAX = valueOf(0xff);
/**
* The value modelling the content of this <code>unsigned byte</code>
*/
private final short value;
/**
* Generate a cached value for each byte value.
*
* @return Array of cached values for UByte.
*/
private static final UByte[] mkValues() {
UByte[] ret = new UByte[256];
for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++)
ret[i & MAX_VALUE] = new UByte((byte) i);
return ret;
}
/**
* Get an instance of an <code>unsigned byte</code>
*
* @throws NumberFormatException If <code>value</code> does not contain a
* parsable <code>unsigned byte</code>.
*/
public static UByte valueOf(String value) throws NumberFormatException {
return valueOfUnchecked(rangeCheck(Short.parseShort(value)));
}
/**
* Get an instance of an <code>unsigned byte</code> by masking it with
* <code>0xFF</code> i.e. <code>(byte) -1</code> becomes
* <code>(ubyte) 255</code>
*/
public static UByte valueOf(byte value) {
return valueOfUnchecked((short) (value & MAX_VALUE));
}
/**
* Get the value of a short without checking the value.
*/
private static UByte valueOfUnchecked(short value) throws NumberFormatException {
return VALUES[value & MAX_VALUE];
}
/**
* Get an instance of an <code>unsigned byte</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned byte</code>
*/
public static UByte valueOf(short value) throws NumberFormatException {
return valueOfUnchecked(rangeCheck(value));
}
/**
* Get an instance of an <code>unsigned byte</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned byte</code>
*/
public static UByte valueOf(int value) throws NumberFormatException {
return valueOfUnchecked(rangeCheck(value));
}
/**
* Get an instance of an <code>unsigned byte</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned byte</code>
*/
public static UByte valueOf(long value) throws NumberFormatException {
return valueOfUnchecked(rangeCheck(value));
}
/**
* Create an <code>unsigned byte</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned byte</code>
*/
private UByte(long value) throws NumberFormatException {
this.value = rangeCheck(value);
}
/**
* Create an <code>unsigned byte</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned byte</code>
*/
private UByte(int value) throws NumberFormatException {
this.value = rangeCheck(value);
}
/**
* Create an <code>unsigned byte</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned byte</code>
*/
private UByte(short value) throws NumberFormatException {
this.value = rangeCheck(value);
}
/**
* Create an <code>unsigned byte</code> by masking it with <code>0xFF</code>
* i.e. <code>(byte) -1</code> becomes <code>(ubyte) 255</code>
*/
private UByte(byte value) {
this.value = (short) (value & MAX_VALUE);
}
/**
* Create an <code>unsigned byte</code>
*
* @throws NumberFormatException If <code>value</code> does not contain a
* parsable <code>unsigned byte</code>.
*/
private UByte(String value) throws NumberFormatException {
this.value = rangeCheck(Short.parseShort(value));
}
/**
* Throw exception if value out of range (short version)
*
* @param value Value to check
* @return value if it is in range
* @throws NumberFormatException if value is out of range
*/
private static short rangeCheck(short value) throws NumberFormatException {
if (value < MIN_VALUE || value > MAX_VALUE)
throw new NumberFormatException("Value is out of range : " + value);
return value;
}
/**
* Throw exception if value out of range (int version)
*
* @param value Value to check
* @return value if it is in range
* @throws NumberFormatException if value is out of range
*/
private static short rangeCheck(int value) throws NumberFormatException {
if (value < MIN_VALUE || value > MAX_VALUE)
throw new NumberFormatException("Value is out of range : " + value);
return (short) value;
}
/**
* Throw exception if value out of range (long version)
*
* @param value Value to check
* @return value if it is in range
* @throws NumberFormatException if value is out of range
*/
private static short rangeCheck(long value) throws NumberFormatException {
if (value < MIN_VALUE || value > MAX_VALUE)
throw new NumberFormatException("Value is out of range : " + value);
return (short) value;
}
/**
* Replace version read through deserialization with cached version. Note
* that this does not use the {@link #valueOfUnchecked(short)} as we have no
* guarantee that the value from the stream is valid.
*
* @return cached instance of this object's value
* @throws ObjectStreamException
*/
private Object readResolve() throws ObjectStreamException {
return valueOf(value);
}
@Override
public int intValue() {
return value;
}
@Override
public long longValue() {
return value;
}
@Override
public float floatValue() {
return value;
}
@Override
public double doubleValue() {
return value;
}
@Override
public int hashCode() {
return Short.valueOf(value).hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj instanceof UByte)
return value == ((UByte) obj).value;
return false;
}
@Override
public String toString() {
return Short.valueOf(value).toString();
}
@Override
public String toHexString() {
return Integer.toHexString(this.value);
}
@Override
public int compareTo(UByte o) {
return (value < o.value ? -1 : (value == o.value ? 0 : 1));
}
@Override
public BigInteger toBigInteger() {
return BigInteger.valueOf(value);
}
public UByte add(UByte val) throws NumberFormatException {
return valueOf(value + val.value);
}
public UByte add(int val) throws NumberFormatException {
return valueOf(value + val);
}
public UByte subtract(final UByte val) {
return valueOf(value - val.value);
}
public UByte subtract(final int val) {
return valueOf(value - val);
}
}

View File

@ -0,0 +1,364 @@
/*
* Copyright 2021 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.
*
*
* Copyright (c) 2011-2017, Data Geekery GmbH (http://www.datageekery.com)
*
* 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.bytes;
import java.io.ObjectStreamException;
import java.math.BigInteger;
/**
* The <code>unsigned int</code> type
*
* @author Lukas Eder
* @author Ed Schaller
* @author Jens Nerche
*/
public final class UInteger extends UNumber implements Comparable<UInteger> {
private static final Class<UInteger> CLASS = UInteger.class;
private static final String CLASS_NAME = CLASS.getName();
/**
* System property name for the property to set the size of the pre-cache.
*/
private static final String PRECACHE_PROPERTY = CLASS_NAME + ".precacheSize";
/**
* Default size for the value cache.
*/
private static final int DEFAULT_PRECACHE_SIZE = 256;
/**
* Generated UID
*/
private static final long serialVersionUID = -6821055240959745390L;
/**
* Cached values
*/
private static final UInteger[] VALUES = mkValues();
/**
* A constant holding the minimum value an <code>unsigned int</code> can
* have, 0.
*/
public static final long MIN_VALUE = 0x00000000;
/**
* A constant holding the maximum value an <code>unsigned int</code> can
* have, 2<sup>32</sup>-1.
*/
public static final long MAX_VALUE = 0xffffffffL;
/**
* A constant holding the minimum value an <code>unsigned int</code> can
* have as UInteger, 0.
*/
public static final UInteger MIN = valueOf(MIN_VALUE);
/**
* A constant holding the maximum value an <code>unsigned int</code> can
* have as UInteger, 2<sup>32</sup>-1.
*/
public static final UInteger MAX = valueOf(MAX_VALUE);
/**
* The value modelling the content of this <code>unsigned int</code>
*/
private final long value;
/**
* Figure out the size of the precache.
*
* @return The parsed value of the system property
* {@link #PRECACHE_PROPERTY} or {@link #DEFAULT_PRECACHE_SIZE} if
* the property is not set, not a number or retrieving results in a
* {@link SecurityException}. If the parsed value is zero or
* negative no cache will be created. If the value is larger than
* {@link Integer#MAX_VALUE} then Integer#MAX_VALUE will be used.
*/
private static final int getPrecacheSize() {
String prop = null;
long propParsed;
try {
prop = System.getProperty(PRECACHE_PROPERTY);
}
catch (SecurityException e) {
// security manager stopped us so use default
// FIXME: should we log this somewhere?
return DEFAULT_PRECACHE_SIZE;
}
if (prop == null)
return DEFAULT_PRECACHE_SIZE;
// empty value
// FIXME: should we log this somewhere?
if (prop.length() <= 0)
return DEFAULT_PRECACHE_SIZE;
try {
propParsed = Long.parseLong(prop);
}
catch (NumberFormatException e) {
// not a valid number
// FIXME: should we log this somewhere?
return DEFAULT_PRECACHE_SIZE;
}
// treat negative value as no cache...
if (propParsed < 0)
return 0;
// FIXME: should we log this somewhere?
if (propParsed > Integer.MAX_VALUE)
return Integer.MAX_VALUE;
return (int) propParsed;
}
/**
* Generate a cached value for initial unsigned integer values.
*
* @return Array of cached values for UInteger
*/
private static final UInteger[] mkValues() {
int precacheSize = getPrecacheSize();
UInteger[] ret;
if (precacheSize <= 0)
return null;
ret = new UInteger[precacheSize];
for (int i = 0; i < precacheSize; i++)
ret[i] = new UInteger(i);
return ret;
}
/**
* Unchecked internal constructor. This serves two purposes: first it allows
* {@link #UInteger(long)} to stay deprecated without warnings and second
* constructor without unnecessary value checks.
*
* @param value The value to wrap
* @param unused Unused parameter to distinguish between this and the
* deprecated public constructor.
*/
private UInteger(long value, boolean unused) {
this.value = value;
}
/**
* Retrieve a cached value.
*
* @param value Cached value to retrieve
* @return Cached value if one exists. Null otherwise.
*/
private static UInteger getCached(long value) {
if (VALUES != null && value < VALUES.length)
return VALUES[(int) value];
return null;
}
/**
* Get the value of a long without checking the value.
*/
private static UInteger valueOfUnchecked(long value) {
UInteger cached;
if ((cached = getCached(value)) != null)
return cached;
return new UInteger(value, true);
}
/**
* Create an <code>unsigned int</code>
*
* @throws NumberFormatException If <code>value</code> does not contain a
* parsable <code>unsigned int</code>.
*/
public static UInteger valueOf(String value) throws NumberFormatException {
return valueOfUnchecked(rangeCheck(Long.parseLong(value)));
}
/**
* Create an <code>unsigned int</code> by masking it with
* <code>0xFFFFFFFF</code> i.e. <code>(int) -1</code> becomes
* <code>(uint) 4294967295</code>
*/
public static UInteger valueOf(int value) {
return valueOfUnchecked(value & MAX_VALUE);
}
/**
* Create an <code>unsigned int</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned byte</code>
*/
public static UInteger valueOf(long value) throws NumberFormatException {
return valueOfUnchecked(rangeCheck(value));
}
/**
* Create an <code>unsigned int</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned int</code>
*/
private UInteger(long value) throws NumberFormatException {
this.value = rangeCheck(value);
}
/**
* Create an <code>unsigned int</code> by masking it with
* <code>0xFFFFFFFF</code> i.e. <code>(int) -1</code> becomes
* <code>(uint) 4294967295</code>
*/
private UInteger(int value) {
this.value = value & MAX_VALUE;
}
/**
* Create an <code>unsigned int</code>
*
* @throws NumberFormatException If <code>value</code> does not contain a
* parsable <code>unsigned int</code>.
*/
private UInteger(String value) throws NumberFormatException {
this.value = rangeCheck(Long.parseLong(value));
}
/**
* Throw exception if value out of range (long version)
*
* @param value Value to check
* @return value if it is in range
* @throws NumberFormatException if value is out of range
*/
private static long rangeCheck(long value) throws NumberFormatException {
if (value < MIN_VALUE || value > MAX_VALUE)
throw new NumberFormatException("Value is out of range : " + value);
return value;
}
/**
* Replace version read through deserialization with cached version.
*
* @return cached instance of this object's value if one exists, otherwise
* this object
* @throws ObjectStreamException
*/
private Object readResolve() throws ObjectStreamException {
UInteger cached;
// the value read could be invalid so check it
rangeCheck(value);
if ((cached = getCached(value)) != null)
return cached;
return this;
}
@Override
public int intValue() {
return (int) value;
}
@Override
public long longValue() {
return value;
}
@Override
public float floatValue() {
return value;
}
@Override
public double doubleValue() {
return value;
}
@Override
public BigInteger toBigInteger() {
return BigInteger.valueOf(value);
}
@Override
public int hashCode() {
return Long.valueOf(value).hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj instanceof UInteger)
return value == ((UInteger) obj).value;
return false;
}
@Override
public String toString() {
return Long.valueOf(value).toString();
}
@Override
public String toHexString() {
return Long.toHexString(this.value);
}
@Override
public int compareTo(UInteger o) {
return (value < o.value ? -1 : (value == o.value ? 0 : 1));
}
public UInteger add(final UInteger val) {
return valueOf(value + val.value);
}
public UInteger add(final int val) {
return valueOf(value + val);
}
public UInteger subtract(final UInteger val) {
return valueOf(value - val.value);
}
public UInteger subtract(final int val) {
return valueOf(value - val);
}
}

View File

@ -0,0 +1,288 @@
/*
* Copyright 2021 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.
*
*
* Copyright (c) 2011-2017, Data Geekery GmbH (http://www.datageekery.com)
*
* 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.bytes;
import java.math.BigInteger;
/**
* The <code>unsigned long</code> type
*
* @author Lukas Eder
* @author Jens Nerche
* @author Ivan Sokolov
*/
public final class ULong extends UNumber implements Comparable<ULong> {
/**
* Generated UID
*/
private static final long serialVersionUID = -6821055240959745390L;
/**
* A constant holding the minimum value an <code>unsigned long</code> can
* have, 0.
*/
public static final BigInteger MIN_VALUE = BigInteger.ZERO;
/**
* A constant holding the maximum value an <code>unsigned long</code> can
* have, 2<sup>64</sup>-1.
*/
public static final BigInteger MAX_VALUE = new BigInteger("18446744073709551615");
/**
* A constant holding the maximum value + 1 an <code>signed long</code> can
* have, 2<sup>63</sup>.
*/
public static final BigInteger MAX_VALUE_LONG = new BigInteger("9223372036854775808");
/**
* A constant holding the minimum value an <code>unsigned long</code> can
* have as ULong, 0.
*/
public static final ULong MIN = valueOf(MIN_VALUE.longValue());
/**
* A constant holding the maximum value + 1 an <code>signed long</code> can
* have as ULong, 2<sup>63</sup>.
*/
public static final ULong MAX = valueOf(MAX_VALUE);
/**
* The value modelling the content of this <code>unsigned long</code>
*/
private final long value;
/**
* Create an <code>unsigned long</code>
*
* @throws NumberFormatException If <code>value</code> does not contain a
* parsable <code>unsigned long</code>.
*/
public static ULong valueOf(String value) throws NumberFormatException {
return new ULong(value);
}
/**
* Create an <code>unsigned long</code> by masking it with
* <code>0xFFFFFFFFFFFFFFFF</code> i.e. <code>(long) -1</code> becomes
* <code>(uint) 18446744073709551615</code>
*/
public static ULong valueOf(long value) {
return new ULong(value);
}
/**
* Create an <code>unsigned long</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned long</code>
*/
public static ULong valueOf(BigInteger value) throws NumberFormatException {
return new ULong(value);
}
public static int compare(long x, long y) {
x += Long.MIN_VALUE;
y += Long.MIN_VALUE;
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
/**
* Create an <code>unsigned long</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned long</code>
*/
private ULong(BigInteger value) throws NumberFormatException {
if (value.compareTo(MIN_VALUE) < 0 || value.compareTo(MAX_VALUE) > 0)
throw new NumberFormatException();
else
this.value = value.longValue();
}
/**
* Create an <code>unsigned long</code> by masking it with
* <code>0xFFFFFFFFFFFFFFFF</code> i.e. <code>(long) -1</code> becomes
* <code>(uint) 18446744073709551615</code>
*/
private ULong(long value) {
this.value = value;
}
/**
* Create an <code>unsigned long</code>
*
* @throws NumberFormatException If <code>value</code> does not contain a
* parsable <code>unsigned long</code>.
*/
private ULong(String value) throws NumberFormatException {
if (value == null)
throw new NumberFormatException("null");
int length = value.length();
if (length == 0)
throw new NumberFormatException("Empty input string");
if (value.charAt(0) == '-')
throw new NumberFormatException(
String.format("Illegal leading minus sign on unsigned string %s", value));
if (length <= 18) {
this.value = Long.parseLong(value, 10);
return;
}
final long first = Long.parseLong(value.substring(0, length - 1), 10);
final int second = Character.digit(value.charAt(length - 1), 10);
if (second < 0)
throw new NumberFormatException("Bad digit at end of " + value);
long result = first * 10 + second;
if (compare(result, first) < 0)
throw new NumberFormatException(
String.format("String value %s exceeds range of unsigned long", value));
this.value = result;
}
@Override
public int intValue() {
return (int) value;
}
@Override
public long longValue() {
return value;
}
@Override
public float floatValue() {
if (value < 0)
return ((float) (value & Long.MAX_VALUE)) + Long.MAX_VALUE;
else
return value;
}
@Override
public double doubleValue() {
if (value < 0)
return ((double) (value & Long.MAX_VALUE)) + Long.MAX_VALUE;
else
return value;
}
@Override
public int hashCode() {
return Long.valueOf(value).hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof ULong)
return value == ((ULong) obj).value;
return false;
}
@Override
public String toString() {
if (value >= 0)
return Long.toString(value);
else
return BigInteger.valueOf(value & Long.MAX_VALUE).add(MAX_VALUE_LONG).toString();
}
@Override
public String toHexString() {
return Long.toHexString(this.value);
}
@Override
public int compareTo(ULong o) {
return compare(value, o.value);
}
public ULong add(ULong val) throws NumberFormatException {
if (value < 0 && val.value < 0)
throw new NumberFormatException();
final long result = value + val.value;
if ((value < 0 || val.value < 0) && result >= 0)
throw new NumberFormatException();
return valueOf(result);
}
public ULong add(int val) throws NumberFormatException {
return add((long) val);
}
public ULong add(long val) throws NumberFormatException {
if (val < 0)
return subtract(Math.abs(val));
final long result = value + val;
if (value < 0 && result >= 0)
throw new NumberFormatException();
return valueOf(result);
}
public ULong subtract(final ULong val) {
if (this.compareTo(val) < 0)
throw new NumberFormatException();
final long result = value - val.value;
if (value < 0 && result >= 0)
throw new NumberFormatException();
return valueOf(result);
}
public ULong subtract(final int val) {
return subtract((long) val);
}
public ULong subtract(final long val) {
if (val < 0)
return add(-val);
if (compare(value, val) < 0)
throw new NumberFormatException();
final long result = value - val;
if (value < 0 && result >= 0)
throw new NumberFormatException();
return valueOf(result);
}
}

View File

@ -0,0 +1,59 @@
/*
* Copyright 2021 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.
*
*
* Copyright (c) 2011-2017, Data Geekery GmbH (http://www.datageekery.com)
*
* 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.bytes;
import java.math.BigInteger;
/**
* A base type for unsigned numbers.
*
* @author Lukas Eder
*/
public abstract class UNumber extends Number {
/**
* Generated UID
*/
private static final long serialVersionUID = -7666221938815339843L;
/**
* Get this number as a {@link BigInteger}. This is a convenience method for
* calling <code>new BigInteger(toString())</code>
*/
public BigInteger toBigInteger() {
return new BigInteger(toString());
}
/**
* Converts this number to a hex string representation
*/
public abstract String toHexString();
}

View File

@ -0,0 +1,211 @@
/*
* Copyright 2021 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.
*
*
* Copyright (c) 2011-2017, Data Geekery GmbH (http://www.datageekery.com)
*
* 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.bytes;
import java.math.BigInteger;
/**
* The <code>unsigned short</code> type
*
* @author Lukas Eder
* @author Jens Nerche
*/
@SuppressWarnings("unused")
public final class UShort extends dorkbox.bytes.UNumber implements Comparable<UShort> {
/**
* Generated UID
*/
private static final long serialVersionUID = -6821055240959745390L;
/**
* A constant holding the minimum value an <code>unsigned short</code> can
* have, 0.
*/
public static final int MIN_VALUE = 0x0000;
/**
* A constant holding the maximum value an <code>unsigned short</code> can
* have, 2<sup>16</sup>-1.
*/
public static final int MAX_VALUE = 0xffff;
/**
* A constant holding the minimum value an <code>unsigned short</code> can
* have as UShort, 0.
*/
public static final UShort MIN = valueOf(MIN_VALUE);
/**
* A constant holding the maximum value an <code>unsigned short</code> can
* have as UShort, 2<sup>16</sup>-1.
*/
public static final UShort MAX = valueOf(MAX_VALUE);
/**
* The value modelling the content of this <code>unsigned short</code>
*/
private final int value;
/**
* Create an <code>unsigned short</code>
*
* @throws NumberFormatException If <code>value</code> does not contain a
* parsable <code>unsigned short</code>.
*/
public static UShort valueOf(String value) throws NumberFormatException {
return new UShort(value);
}
/**
* Create an <code>unsigned short</code> by masking it with
* <code>0xFFFF</code> i.e. <code>(short) -1</code> becomes
* <code>(ushort) 65535</code>
*/
public static UShort valueOf(short value) {
return new UShort(value);
}
/**
* Create an <code>unsigned short</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned short</code>
*/
public static UShort valueOf(int value) throws NumberFormatException {
return new UShort(value);
}
/**
* Create an <code>unsigned short</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned short</code>
*/
private UShort(int value) throws NumberFormatException {
this.value = value;
rangeCheck();
}
/**
* Create an <code>unsigned short</code> by masking it with
* <code>0xFFFF</code> i.e. <code>(short) -1</code> becomes
* <code>(ushort) 65535</code>
*/
private UShort(short value) {
this.value = value & MAX_VALUE;
}
/**
* Create an <code>unsigned short</code>
*
* @throws NumberFormatException If <code>value</code> does not contain a
* parsable <code>unsigned short</code>.
*/
private UShort(String value) throws NumberFormatException {
this.value = Integer.parseInt(value);
rangeCheck();
}
private void rangeCheck() throws NumberFormatException {
if (value < MIN_VALUE || value > MAX_VALUE)
throw new NumberFormatException("Value is out of range : " + value);
}
@Override
public int intValue() {
return value;
}
@Override
public long longValue() {
return value;
}
@Override
public float floatValue() {
return value;
}
@Override
public double doubleValue() {
return value;
}
@Override
public BigInteger toBigInteger() {
return BigInteger.valueOf(value);
}
@Override
public int hashCode() {
return Integer.valueOf(value).hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof UShort)
return value == ((UShort) obj).value;
return false;
}
@Override
public String toString() {
return Integer.valueOf(value).toString();
}
@Override
public String toHexString() {
return Integer.toHexString(this.value);
}
@Override
public int compareTo(UShort o) {
return (Integer.compare(value, o.value));
}
public UShort add(UShort val) throws NumberFormatException {
return valueOf(value + val.value);
}
public UShort add(int val) throws NumberFormatException {
return valueOf(value + val);
}
public UShort subtract(final UShort val) {
return valueOf(value - val.value);
}
public UShort subtract(final int val) {
return valueOf(value - val);
}
}

View File

@ -0,0 +1,216 @@
/*
* Copyright 2021 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.
*
*
* Copyright (c) 2011-2017, Data Geekery GmbH (http://www.datageekery.com)
*
* 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.bytes;
import java.math.BigInteger;
/**
* A utility class for static access to unsigned number functionality.
* <p>
* It essentially contains factory methods for unsigned number wrappers. In
* future versions, it will also contain some arithmetic methods, handling
* regular arithmetic and bitwise operations
*
* @author Lukas Eder
*/
@SuppressWarnings("unused")
public final class Unsigned {
/**
* Create an <code>unsigned byte</code>
*
* @throws NumberFormatException If <code>value</code> does not contain a
* parsable <code>unsigned byte</code>.
* @see UByte#valueOf(String)
*/
public static
dorkbox.bytes.UByte ubyte(String value) throws NumberFormatException {
return value == null ? null : dorkbox.bytes.UByte.valueOf(value);
}
/**
* Create an <code>unsigned byte</code> by masking it with <code>0xFF</code>
* i.e. <code>(byte) -1</code> becomes <code>(ubyte) 255</code>
*
* @see UByte#valueOf(byte)
*/
public static
dorkbox.bytes.UByte ubyte(byte value) {
return dorkbox.bytes.UByte.valueOf(value);
}
/**
* Create an <code>unsigned byte</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned byte</code>
* @see UByte#valueOf(short)
*/
public static
dorkbox.bytes.UByte ubyte(short value) throws NumberFormatException {
return dorkbox.bytes.UByte.valueOf(value);
}
/**
* Create an <code>unsigned byte</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned byte</code>
* @see UByte#valueOf(short)
*/
public static
dorkbox.bytes.UByte ubyte(int value) throws NumberFormatException {
return dorkbox.bytes.UByte.valueOf(value);
}
/**
* Create an <code>unsigned byte</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned byte</code>
* @see UByte#valueOf(short)
*/
public static
dorkbox.bytes.UByte ubyte(long value) throws NumberFormatException {
return dorkbox.bytes.UByte.valueOf(value);
}
/**
* Create an <code>unsigned short</code>
*
* @throws NumberFormatException If <code>value</code> does not contain a
* parsable <code>unsigned short</code>.
* @see UShort#valueOf(String)
*/
public static
UShort ushort(String value) throws NumberFormatException {
return value == null ? null : UShort.valueOf(value);
}
/**
* Create an <code>unsigned short</code> by masking it with
* <code>0xFFFF</code> i.e. <code>(short) -1</code> becomes
* <code>(ushort) 65535</code>
*
* @see UShort#valueOf(short)
*/
public static UShort ushort(short value) {
return UShort.valueOf(value);
}
/**
* Create an <code>unsigned short</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned short</code>
* @see UShort#valueOf(int)
*/
public static UShort ushort(int value) throws NumberFormatException {
return UShort.valueOf(value);
}
/**
* Create an <code>unsigned int</code>
*
* @throws NumberFormatException If <code>value</code> does not contain a
* parsable <code>unsigned int</code>.
* @see UInteger#valueOf(String)
*/
public static
dorkbox.bytes.UInteger uint(String value) throws NumberFormatException {
return value == null ? null : dorkbox.bytes.UInteger.valueOf(value);
}
/**
* Create an <code>unsigned int</code> by masking it with
* <code>0xFFFFFFFF</code> i.e. <code>(int) -1</code> becomes
* <code>(uint) 4294967295</code>
*
* @see UInteger#valueOf(int)
*/
public static
dorkbox.bytes.UInteger uint(int value) {
return dorkbox.bytes.UInteger.valueOf(value);
}
/**
* Create an <code>unsigned int</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned int</code>
* @see UInteger#valueOf(long)
*/
public static
dorkbox.bytes.UInteger uint(long value) throws NumberFormatException {
return dorkbox.bytes.UInteger.valueOf(value);
}
/**
* Create an <code>unsigned long</code>
*
* @throws NumberFormatException If <code>value</code> does not contain a
* parsable <code>unsigned long</code>.
* @see ULong#valueOf(String)
*/
public static
dorkbox.bytes.ULong ulong(String value) throws NumberFormatException {
return value == null ? null : dorkbox.bytes.ULong.valueOf(value);
}
/**
* Create an <code>unsigned long</code> by masking it with
* <code>0xFFFFFFFFFFFFFFFF</code> i.e. <code>(long) -1</code> becomes
* <code>(uint) 18446744073709551615</code>
*
* @see ULong#valueOf(long)
*/
public static
dorkbox.bytes.ULong ulong(long value) {
return dorkbox.bytes.ULong.valueOf(value);
}
/**
* Create an <code>unsigned long</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned long</code>
* @see ULong#valueOf(BigInteger)
*/
public static
dorkbox.bytes.ULong ulong(BigInteger value) throws NumberFormatException {
return dorkbox.bytes.ULong.valueOf(value);
}
/**
* No instances
*/
private Unsigned() {}
}