mirror of
https://github.com/corda/corda.git
synced 2024-12-27 08:22:35 +00:00
Add 'sgx-jvm/avian/' from commit '09e4fe60d01f4f4bfb6b2976973bb4913ef61edc'
git-subtree-dir: sgx-jvm/avian git-subtree-mainline:f978eab8d1
git-subtree-split:09e4fe60d0
This commit is contained in:
commit
9bb3d6b972
7
sgx-jvm/avian/.clang-format
Normal file
7
sgx-jvm/avian/.clang-format
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
BasedOnStyle: Chromium
|
||||
IndentCaseLabels: false
|
||||
BreakBeforeBraces: Stroustrup
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
BreakBeforeBinaryOperators: true
|
||||
...
|
17
sgx-jvm/avian/.gitignore
vendored
Normal file
17
sgx-jvm/avian/.gitignore
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
.gdb_history
|
||||
/build
|
||||
*~
|
||||
.classpath
|
||||
.project
|
||||
.settings
|
||||
bin
|
||||
/lib
|
||||
/distrib
|
||||
*.pdb
|
||||
*.swp
|
||||
/.gradle
|
||||
/*.sublime-*
|
||||
workspace/
|
||||
src/.cproject
|
||||
/cmake-build
|
||||
/cmake-build
|
27
sgx-jvm/avian/.mailmap
Normal file
27
sgx-jvm/avian/.mailmap
Normal file
@ -0,0 +1,27 @@
|
||||
Carsten Elton Sørensen <ces@HADDOCK.premitech.net>
|
||||
Carsten Elton Sørensen <csoren@gmail.com>
|
||||
Dain Darnell <dain.darnell@readytalk.com>
|
||||
Dain Darnell <dain@dazar.(none)>
|
||||
Edison Guo <hydra1983@gmail.com>
|
||||
Jason Treadwell <derBierBrauer@yahoo.com>
|
||||
Jason Treadwell <jason.treadwell@readytalk.com>
|
||||
Jason Treadwell <jet@debian-armel.(none)>
|
||||
Jason Treadwell <jet@jet-lappy.(none)>
|
||||
Jason Treadwell <jet@jet.ecovate.com>
|
||||
Jason Treadwell <jet@jet.readytalk.com>
|
||||
Jason Treadwell <jet@jetl.readytalk.com>
|
||||
Jason Treadwell <jet@jetp.(none)>
|
||||
Jason Treadwell <jet@nonames-power-mac-g4-agp-graphics.local>
|
||||
Joel Dice <Joel Dice@joeldicexpvm.(none)>
|
||||
Joel Dice <Joel@JDICEVM7.(none)>
|
||||
Joel Dice <dicej@bstevenstestnb.readytalk.com>
|
||||
Joel Dice <dicej@osxdesktop-2.local>
|
||||
Anonymous <anonymous@example.com>
|
||||
Joshua Warner <jwarner@radio.ecovate.com>
|
||||
Matt Weaver <mweaver@gorgotron.readytalk.com>
|
||||
Mike Jensen <jentfoo@gmail.com>
|
||||
Mike Jensen <mjensen@jentbox.ecovate.com>
|
||||
Mike Jensen <mjensen@lennyjent.ecovate.com>
|
||||
Terek Campbell <terek.campbell@colorado.edu>
|
||||
Thiago Bedin Frustaci <frustaci@gmail.com>
|
||||
Zsombor Gegesy <gzsombor@gmail.com>
|
25
sgx-jvm/avian/.travis.yml
Normal file
25
sgx-jvm/avian/.travis.yml
Normal file
@ -0,0 +1,25 @@
|
||||
language: cpp
|
||||
cache: apt
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- BUILD_STEP=""
|
||||
# disabled until/unless jfrog.org credentials are updated and someone
|
||||
# decides they care about published artifacts:
|
||||
# - BUILD_STEP="PUBLISH"
|
||||
global:
|
||||
- TERM=dumb
|
||||
- secure: rh1utD4shKmYtokItuRYEF9WsfTnvZO5XqnTU4DHTS7quHHgLihtOO2/3+B+2W2hEd5Obr2or8zx+zmzWcNUyLokZ0j/FRLWSScNkLzTtm12pupLrncY+/g1NIdfbhn+OLRIzBz6zB6m6a2qWFEJ+bScUNGD/7wZVtzkujqlDEE=
|
||||
- secure: j9DOzZMCYk/BzhKK9u4XMKpCzyGOsvP2cLTp6cXE7/tkWDAPVv6BFmeqNbiLTEqk0aGX+HYbY/2YVtpRZmDzfeWtnBFF5mL1Y1tgzx1Kf155C+P6rZgt5PiQTUdXlp2umuRifY1BbXAPc3DZ2UOPUjWKnLHVbZLQRgO1zimmMx8=
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
exclude:
|
||||
- os: osx
|
||||
env: BUILD_STEP=""
|
||||
|
||||
script: ./test/ci.sh ${BUILD_STEP}
|
31
sgx-jvm/avian/.utility/push-javadoc-to-gh-pages.sh
Executable file
31
sgx-jvm/avian/.utility/push-javadoc-to-gh-pages.sh
Executable file
@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
# This script was originally written by maxiaohao in the aws-mock GitHub project.
|
||||
# https://github.com/treelogic-swe/aws-mock/
|
||||
|
||||
if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then
|
||||
|
||||
echo "Start to publish lastest Javadoc to gh-pages..."
|
||||
|
||||
cd build/
|
||||
|
||||
if test -d gh-pages/avian-web
|
||||
then
|
||||
cd gh-pages/avian-web
|
||||
git pull
|
||||
else
|
||||
git clone --quiet https://${GH_TOKEN}@github.com/ReadyTalk/readytalk.github.io gh-pages > /dev/null
|
||||
cd gh-pages/avian-web
|
||||
git config user.email "travis@travis-ci.org"
|
||||
git config user.name "travis-ci"
|
||||
fi
|
||||
|
||||
git rm -rf ./javadoc
|
||||
cp -Rf ../javadoc ./javadoc
|
||||
git add -f .
|
||||
git commit -m "Latest javadoc on successful Travis build $TRAVIS_BUILD_NUMBER auto-pushed to readytalk.github.io"
|
||||
if ! git push -fq origin master &> /dev/null; then
|
||||
echo "Error pushing gh-pages to origin. Bad GH_TOKEN? GitHub down?"
|
||||
else
|
||||
echo "Done magic with auto publishment to readytalk.github.io."
|
||||
fi
|
||||
fi
|
29
sgx-jvm/avian/CMakeLists.txt
Normal file
29
sgx-jvm/avian/CMakeLists.txt
Normal file
@ -0,0 +1,29 @@
|
||||
# NOTE that this CMake file doesn't current build all of avian.
|
||||
# It only builds what's required for example/kaleidoscope.
|
||||
|
||||
cmake_minimum_required (VERSION 2.6)
|
||||
project (avian)
|
||||
|
||||
include_directories (include src)
|
||||
|
||||
add_definitions (
|
||||
-DAVIAN_TARGET_FORMAT=AVIAN_FORMAT_MACHO
|
||||
|
||||
-DAVIAN_TARGET_ARCH=AVIAN_ARCH_X86_64
|
||||
|
||||
-DTARGET_BYTES_PER_WORD=8
|
||||
-D__STDC_LIMIT_MACROS
|
||||
-D__STDC_CONSTANT_MACROS
|
||||
)
|
||||
|
||||
include ("cmake/Platform.cmake")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PLATFORM_CXX_FLAGS}")
|
||||
|
||||
include (CTest)
|
||||
|
||||
# Sadly, we can't use the 'test' target, as that's coopted by ctest
|
||||
add_custom_target(check ${CMAKE_CTEST_COMMAND} -V)
|
||||
|
||||
add_subdirectory (src)
|
||||
add_subdirectory (unittest)
|
15
sgx-jvm/avian/LICENSE.txt
Normal file
15
sgx-jvm/avian/LICENSE.txt
Normal file
@ -0,0 +1,15 @@
|
||||
ISC License
|
||||
|
||||
Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
750
sgx-jvm/avian/README.md
Normal file
750
sgx-jvm/avian/README.md
Normal file
@ -0,0 +1,750 @@
|
||||
Avian - A lightweight Java Virtual Machine (JVM)
|
||||
================================================
|
||||
|
||||
[![Build Status](https://travis-ci.org/ReadyTalk/avian.png?branch=master)](https://travis-ci.org/ReadyTalk/avian)
|
||||
|
||||
Quick Start
|
||||
-----------
|
||||
|
||||
These are examples of building Avian on various operating systems for
|
||||
the x86_64 architecture. You may need to modify JAVA_HOME according
|
||||
to where the JDK is installed on your system. In all cases, be sure
|
||||
to use forward slashes in the path.
|
||||
|
||||
#### on Linux:
|
||||
$ export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
|
||||
$ make
|
||||
$ build/linux-x86_64/avian -cp build/linux-x86_64/test Hello
|
||||
|
||||
#### on Mac OS X:
|
||||
$ export JAVA_HOME=$(/usr/libexec/java_home)
|
||||
$ make
|
||||
$ build/macosx-x86_64/avian -cp build/macosx-x86_64/test Hello
|
||||
|
||||
#### on Windows (Cygwin):
|
||||
$ git clone git@github.com:ReadyTalk/win64.git ../win64
|
||||
$ export JAVA_HOME="/cygdrive/c/Program Files/Java/jdk1.7.0_45"
|
||||
$ make
|
||||
$ build/windows-x86_64/avian -cp build/windows-x86_64/test Hello
|
||||
|
||||
#### on FreeBSD:
|
||||
$ export JAVA_HOME=/usr/local/openjdk7
|
||||
$ gmake
|
||||
$ build/freebsd-x86_64/avian -cp build/freebsd-x86_64/test Hello
|
||||
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
Avian is a lightweight virtual machine and class library designed to
|
||||
provide a useful subset of Java's features, suitable for building
|
||||
self-contained applications. More information is available at the
|
||||
project [web site](http://readytalk.github.io/avian).
|
||||
|
||||
If you have any trouble building, running, or embedding Avian, please
|
||||
post a message to our [discussion group](http://groups.google.com/group/avian).
|
||||
|
||||
That's also the place for any other questions, comments, or
|
||||
suggestions you might have.
|
||||
|
||||
|
||||
Supported Platforms
|
||||
-------------------
|
||||
|
||||
Avian can currently target the following platforms:
|
||||
|
||||
* Linux (i386, x86_64, ARM, and ARM64)
|
||||
* Windows (i386 and x86_64)
|
||||
* Mac OS X (i386 and x86_64)
|
||||
* Apple iOS (i386, x86_64, ARM, and ARM64)
|
||||
* FreeBSD (i386, x86_64)
|
||||
|
||||
|
||||
Building
|
||||
--------
|
||||
|
||||
Build requirements include:
|
||||
|
||||
* GNU make 3.80 or later
|
||||
* GCC 4.6 or later
|
||||
or LLVM Clang 3.1 or later (see use-clang option below)
|
||||
* JDK 1.6 or later
|
||||
* MinGW 3.4 or later (only if compiling for Windows)
|
||||
* zlib 1.2.3 or later
|
||||
|
||||
Earlier versions of some of these packages may also work but have not
|
||||
been tested.
|
||||
|
||||
The build is directed by a single makefile and may be influenced via
|
||||
certain flags described below, all of which are optional.
|
||||
|
||||
$ make \
|
||||
platform={linux,windows,macosx,ios,freebsd} \
|
||||
arch={i386,x86_64,arm,arm64} \
|
||||
process={compile,interpret} \
|
||||
mode={debug,debug-fast,fast,small} \
|
||||
lzma=<lzma source directory> \
|
||||
bootimage={true,false} \
|
||||
tails={true,false} \
|
||||
continuations={true,false} \
|
||||
use-clang={true,false} \
|
||||
openjdk=<openjdk installation directory> \
|
||||
openjdk-src=<openjdk source directory> \
|
||||
android=<android source directory>
|
||||
|
||||
* `platform` - the target platform
|
||||
* _default:_ output of $(uname -s | tr [:upper:] [:lower:]),
|
||||
normalized in some cases (e.g. CYGWIN_NT-5.1 -> windows)
|
||||
|
||||
* `arch` - the target architecture
|
||||
* _default:_ output of $(uname -m), normalized in some cases
|
||||
(e.g. i686 -> i386)
|
||||
|
||||
* `process` - choice between pure interpreter or JIT compiler
|
||||
* _default:_ compile
|
||||
|
||||
* `mode` - which set of compilation flags to use to determine
|
||||
optimization level, debug symbols, and whether to enable
|
||||
assertions
|
||||
* _default:_ fast
|
||||
|
||||
* `lzma` - if set, support use of LZMA to compress embedded JARs and
|
||||
boot images. The value of this option should be a directory
|
||||
containing a recent LZMA SDK (available [here](http://www.7-zip.org/sdk.html)). Currently, only version 9.20 of
|
||||
the SDK has been tested, but other versions might work.
|
||||
* _default:_ not set
|
||||
|
||||
* `armv6` - if true, don't use any instructions newer than armv6. By
|
||||
default, we assume the target is armv7 or later, and thus requires explicit
|
||||
memory barrier instructions to ensure cache coherency
|
||||
|
||||
* `bootimage` - if true, create a boot image containing the pre-parsed
|
||||
class library and ahead-of-time compiled methods. This option is
|
||||
only valid for process=compile builds. Note that you may need to
|
||||
specify both build-arch=x86_64 and arch=x86_64 on 64-bit systems
|
||||
where "uname -m" prints "i386".
|
||||
* _default:_ false
|
||||
|
||||
* `tails` - if true, optimize each tail call by replacing the caller's
|
||||
stack frame with the callee's. This convention ensures proper
|
||||
tail recursion, suitable for languages such as Scheme. This
|
||||
option is only valid for process=compile builds.
|
||||
* _default:_ false
|
||||
|
||||
* `continuations` - if true, support continuations via the
|
||||
avian.Continuations methods callWithCurrentContinuation and
|
||||
dynamicWind. See Continuations.java for details. This option is
|
||||
only valid for process=compile builds.
|
||||
* _default:_ false
|
||||
|
||||
* `use-clang` - if true, use LLVM's clang instead of GCC to build.
|
||||
Note that this does not currently affect cross compiles, only
|
||||
native builds.
|
||||
* _default:_ false
|
||||
|
||||
* `openjdk` - if set, use the OpenJDK class library instead of the
|
||||
default Avian class library. See "Building with the OpenJDK Class
|
||||
Library" below for details.
|
||||
* _default:_ not set
|
||||
|
||||
* `openjdk-src` - if this and the openjdk option above are both set,
|
||||
build an embeddable VM using the OpenJDK class library. The JNI
|
||||
components of the OpenJDK class library will be built from the
|
||||
sources found under the specified directory. See "Building with
|
||||
the OpenJDK Class Library" below for details.
|
||||
* _default:_ not set
|
||||
|
||||
* `android` - if set, use the Android class library instead of the
|
||||
default Avian class library. See "Building with the Android Class
|
||||
Library" below for details.
|
||||
* _default:_ not set
|
||||
|
||||
These flags determine the name of the directory used for the build.
|
||||
The name always starts with _${platform}-${arch}_, and each non-default
|
||||
build option is appended to the name. For example, a debug build with
|
||||
bootimage enabled on Linux/x86_64 would be built in
|
||||
_build/linux-x86_64-debug-bootimage_. This allows you to build with
|
||||
several different sets of options independently and even
|
||||
simultaneously without doing a clean build each time.
|
||||
|
||||
Note that not all combinations of these flags are valid. For instance,
|
||||
non-jailbroken iOS devices do not allow JIT compilation, so only
|
||||
process=interpret or bootimage=true builds will run on such
|
||||
devices. See [here](https://github.com/ReadyTalk/hello-ios) for an
|
||||
example of an Xcode project for iOS which uses Avian.
|
||||
|
||||
If you are compiling for Windows, you may either cross-compile using
|
||||
MinGW or build natively on Windows under Cygwin.
|
||||
|
||||
#### Installing Cygwin:
|
||||
|
||||
__1.__ Download and run setup.exe from [cygwin's website](http://www.cygwin.com), installing the base
|
||||
system and these packages: make, gcc-mingw-g++,
|
||||
mingw64-i686-gcc-g++, mingw64-x86_64-gcc-g++, and (optionally) git.
|
||||
|
||||
You may also find our win32 repository useful: (run this from the
|
||||
directory containing the avian directory)
|
||||
|
||||
$ git clone git@github.com:ReadyTalk/win32.git
|
||||
|
||||
This gives you the Windows JNI headers, zlib headers and library, and
|
||||
a few other useful libraries like OpenSSL, libjpeg, and libpng.
|
||||
There's also a win64 repository for 64-bit builds:
|
||||
|
||||
$ git clone git@github.com:ReadyTalk/win64.git
|
||||
|
||||
|
||||
Building with the Microsoft Visual C++ Compiler
|
||||
-----------------------------------------------
|
||||
|
||||
You can also build using the MSVC compiler, which makes debugging with
|
||||
tools like WinDbg and Visual Studio much easier. Note that you will
|
||||
still need to have GCC installed - MSVC is only used to compile the
|
||||
C++ portions of the VM, while the assembly code and helper tools are
|
||||
built using GCC.
|
||||
|
||||
*Note that the MSVC build isn't tested regularly, so is fairly likely to be broken.*
|
||||
|
||||
Avian targets MSVC 11 and above (it uses c++ features not available in older versions).
|
||||
|
||||
To build with MSVC, install Cygwin as described above and set the
|
||||
following environment variables:
|
||||
|
||||
$ export PATH="/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/cygdrive/c/Program Files/Microsoft Visual Studio 11.0/Common7/IDE:/cygdrive/c/Program Files/Microsoft Visual Studio 11.0/VC/BIN:/cygdrive/c/Program Files/Microsoft Visual Studio 11.0/Common7/Tools:/cygdrive/c/WINDOWS/Microsoft.NET/Framework/v3.5:/cygdrive/c/WINDOWS/Microsoft.NET/Framework/v2.0.50727:/cygdrive/c/Program Files/Microsoft Visual Studio 11.0/VC/VCPackages:/cygdrive/c/Program Files/Microsoft SDKs/Windows/v6.0A/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem"
|
||||
$ export LIBPATH="C:\WINDOWS\Microsoft.NET\Framework\v3.5;C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727;C:\Program Files\Microsoft Visual Studio 11.0\VC\LIB;"
|
||||
$ export VCINSTALLDIR="C:\Program Files\Microsoft Visual Studio 11.0\VC"
|
||||
$ export LIB="C:\Program Files\Microsoft Visual Studio 11.0\VC\LIB;C:\Program Files\Microsoft SDKs\Windows\v6.0A\lib;"
|
||||
$ export INCLUDE="C:\Program Files\Microsoft Visual Studio 11.0\VC\INCLUDE;C:\Program Files\Microsoft SDKs\Windows\v6.0A\include;"
|
||||
|
||||
Adjust these definitions as necessary according to your MSVC
|
||||
installation.
|
||||
|
||||
Finally, build with the msvc flag set to the MSVC tool directory:
|
||||
|
||||
$ make msvc="/cygdrive/c/Program Files/Microsoft Visual Studio 11.0/VC"
|
||||
|
||||
|
||||
Building with the OpenJDK Class Library
|
||||
---------------------------------------
|
||||
|
||||
By default, Avian uses its own lightweight class library. However,
|
||||
that library only contains a relatively small subset of the classes
|
||||
and methods included in the JRE. If your application requires
|
||||
features beyond that subset, you may want to tell Avian to use
|
||||
OpenJDK's class library instead. To do so, specify the directory
|
||||
where OpenJDK is installed, e.g.:
|
||||
|
||||
$ make openjdk=/usr/lib/jvm/java-7-openjdk
|
||||
|
||||
This will build Avian as a conventional JVM (e.g. libjvm.so) which
|
||||
loads its boot class library and native libraries (e.g. libjava.so)
|
||||
from _/usr/lib/jvm/java-7-openjdk/jre_ at runtime. Note that you must
|
||||
use an absolute path here, or else the result will not work when run
|
||||
from other directories. In this configuration, OpenJDK needs to
|
||||
remain installed for Avian to work, and you can run applications like
|
||||
this:
|
||||
|
||||
$ build/linux-x86_64-openjdk/avian-dynamic -cp /path/to/my/application \
|
||||
com.example.MyApplication
|
||||
|
||||
Alternatively, you can enable a stand-alone build using OpenJDK by
|
||||
specifying the location of the OpenJDK source code, e.g.:
|
||||
|
||||
$ make openjdk=$(pwd)/../jdk7/build/linux-amd64/j2sdk-image \
|
||||
openjdk-src=$(pwd)/../jdk7/jdk/src
|
||||
|
||||
You must ensure that the path specified for openjdk-src does not have
|
||||
any spaces in it; make gets confused when dependency paths include
|
||||
spaces, and we haven't found away around that except to avoid paths
|
||||
with spaces entirely.
|
||||
|
||||
The result of such a build is a self-contained binary which does not
|
||||
depend on external libraries, jars, or other files. In this case, the
|
||||
specified paths are used only at build time; anything needed at
|
||||
runtime is embedded in the binary. Thus, the process of running an
|
||||
application is simplified:
|
||||
|
||||
$ build/linux-x86_64-openjdk-src/avian -cp /path/to/my/application \
|
||||
com.example.MyApplication
|
||||
|
||||
Note that the resulting binary will be very large due to the size of
|
||||
OpenJDK's class library. This can be mitigated using UPX, preferably
|
||||
an LZMA-enabled version:
|
||||
|
||||
$ upx --lzma --best build/linux-x86_64-openjdk-src/avian
|
||||
|
||||
You can reduce the size futher for embedded builds by using ProGuard
|
||||
and the supplied openjdk.pro configuration file (see "Embedding with
|
||||
ProGuard and a Boot Image" below). Note that you'll still need to use
|
||||
vm.pro in that case -- openjdk.pro just adds additional constraints
|
||||
specific to the OpenJDK port. Also see
|
||||
[app.mk](https://github.com/ReadyTalk/avian-swt-examples/blob/master/app.mk)
|
||||
in the _avian-swt-examples_ project for an example of using Avian,
|
||||
OpenJDK, ProGuard, and UPX in concert.
|
||||
|
||||
Here are some examples of how to install OpenJDK and build Avian with
|
||||
it on various OSes:
|
||||
|
||||
#### Debian-based Linux:
|
||||
_Conventional build:_
|
||||
|
||||
$ apt-get install openjdk-7-jdk
|
||||
$ make openjdk=/usr/lib/jvm/java-7-openjdk test
|
||||
|
||||
_Stand-alone build:_
|
||||
|
||||
$ apt-get install openjdk-7-jdk
|
||||
$ apt-get source openjdk-7-jdk
|
||||
$ apt-get build-dep openjdk-7-jdk
|
||||
$ (cd openjdk-7-7~b147-2.0 && dpkg-buildpackage)
|
||||
$ make openjdk=/usr/lib/jvm/java-7-openjdk \
|
||||
openjdk-src=$(pwd)/openjdk-7-7~b147-2.0/build/openjdk/jdk/src \
|
||||
test
|
||||
|
||||
####Mac OS X:
|
||||
_Prerequisite:_ Build OpenJDK 7 according to [this site](https://wikis.oracle.com/display/OpenJDK/Mac+OS+X+Port).
|
||||
|
||||
_Conventional build:_
|
||||
|
||||
$ make openjdk=$(pwd)/../jdk7u-dev/build/macosx-amd64/j2sdk-image test
|
||||
|
||||
_Stand-alone build:_
|
||||
|
||||
$ make openjdk=$(pwd)/../jdk7u-dev/build/macosx-amd64/j2sdk-image \
|
||||
openjdk-src=$(pwd)/../p/jdk7u-dev/jdk/src test
|
||||
|
||||
####Windows (Cygwin):
|
||||
_Prerequisite:_ Build OpenJDK 7 according to [this site](http://weblogs.java.net/blog/simonis/archive/2011/10/28/yaojowbi-yet-another-openjdk-windows-build-instruction). Alternatively, use https://github.com/alexkasko/openjdk-unofficial-builds.
|
||||
|
||||
_Conventional build:_
|
||||
|
||||
$ make openjdk=$(pwd)/../jdk7u-dev/build/windows-i586/j2sdk-image test
|
||||
|
||||
_Stand-alone build:_
|
||||
|
||||
$ make openjdk=$(pwd)/../jdk7u-dev/build/windows-i586/j2sdk-image \
|
||||
openjdk-src=$(pwd)/../p/jdk7u-dev/jdk/src test
|
||||
|
||||
Currently, only OpenJDK 7 is supported. Later versions might work,
|
||||
but have not yet been tested.
|
||||
|
||||
|
||||
Building with the Android Class Library
|
||||
---------------------------------------
|
||||
As an alternative to both the Avian and OpenJDK class libaries, you
|
||||
can also build with the Android class library. Now it should work on Linux, OS X and Windows.
|
||||
|
||||
The simpliest way to build Avian with Android classpath is to use `avian-pack` project: https://github.com/bigfatbrowncat/avian-pack
|
||||
|
||||
Avian-pack consists of Avian itself with some Android components (such as libcore and icu4c).
|
||||
|
||||
Note that we use the upstream OpenSSL repository and apply the
|
||||
Android patches to it. This is because it is not clear how to build
|
||||
the Android fork of OpenSSL directly without checking out and building
|
||||
the entire platform. As of this writing, the patches apply cleanly
|
||||
against OpenSSL 1.0.1h, so that's the tag we check out, but this may
|
||||
change in the future when the Android fork rebases against a new
|
||||
OpenSSL version.
|
||||
|
||||
Installing
|
||||
----------
|
||||
|
||||
Installing Avian is as simple as copying the executable to the desired
|
||||
directory:
|
||||
|
||||
$ cp build/${platform}-${arch}/avian ~/bin/
|
||||
|
||||
|
||||
Embedding
|
||||
---------
|
||||
|
||||
The following series of commands illustrates how to produce a
|
||||
stand-alone executable out of a Java application using Avian.
|
||||
|
||||
Note: if you are building on Cygwin, prepend "x86_64-w64-mingw32-" or
|
||||
"i686-w64-mingw32-" to the ar, g++, gcc, strip, and dlltool commands
|
||||
below (e.g. x86_64-w64-mingw32-gcc).
|
||||
|
||||
__1.__ Build Avian, create a new directory, and populate it with the
|
||||
VM object files and bootstrap classpath jar.
|
||||
|
||||
$ make
|
||||
$ mkdir hello
|
||||
$ cd hello
|
||||
$ ar x ../build/${platform}-${arch}/libavian.a
|
||||
$ cp ../build/${platform}-${arch}/classpath.jar boot.jar
|
||||
|
||||
__2.__ Build the Java code and add it to the jar.
|
||||
|
||||
$ cat >Hello.java <<EOF
|
||||
public class Hello {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("hello, world!");
|
||||
}
|
||||
}
|
||||
EOF
|
||||
$ javac -bootclasspath boot.jar Hello.java
|
||||
$ jar u0f boot.jar Hello.class
|
||||
|
||||
__3.__ Make an object file out of the jar.
|
||||
|
||||
$ ../build/${platform}-${arch}/binaryToObject/binaryToObject boot.jar \
|
||||
boot-jar.o _binary_boot_jar_start _binary_boot_jar_end ${platform} ${arch}
|
||||
|
||||
If you've built Avian using the `lzma` option, you may optionally
|
||||
compress the jar before generating the object:
|
||||
|
||||
../build/$(platform}-${arch}-lzma/lzma/lzma encode boot.jar boot.jar.lzma
|
||||
&& ../build/${platform}-${arch}-lzma/binaryToObject/binaryToObject \
|
||||
boot.jar.lzma boot-jar.o _binary_boot_jar_start _binary_boot_jar_end \
|
||||
${platform} ${arch}
|
||||
|
||||
Note that you'll need to specify "-Xbootclasspath:[lzma.bootJar]"
|
||||
instead of "-Xbootclasspath:[bootJar]" in the next step if you've used
|
||||
LZMA to compress the jar.
|
||||
|
||||
__4.__ Write a driver which starts the VM and runs the desired main
|
||||
method. Note the bootJar function, which will be called by the VM to
|
||||
get a handle to the embedded jar. We tell the VM about this jar by
|
||||
setting the boot classpath to "[bootJar]".
|
||||
|
||||
$ cat >embedded-jar-main.cpp <<EOF
|
||||
#include "stdint.h"
|
||||
#include "jni.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
#if (defined __MINGW32__) || (defined _MSC_VER)
|
||||
# define EXPORT __declspec(dllexport)
|
||||
#else
|
||||
# define EXPORT __attribute__ ((visibility("default"))) \
|
||||
__attribute__ ((used))
|
||||
#endif
|
||||
|
||||
#if (! defined __x86_64__) && ((defined __MINGW32__) || (defined _MSC_VER))
|
||||
# define SYMBOL(x) binary_boot_jar_##x
|
||||
#else
|
||||
# define SYMBOL(x) _binary_boot_jar_##x
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
|
||||
extern const uint8_t SYMBOL(start)[];
|
||||
extern const uint8_t SYMBOL(end)[];
|
||||
|
||||
EXPORT const uint8_t*
|
||||
bootJar(size_t* size)
|
||||
{
|
||||
*size = SYMBOL(end) - SYMBOL(start);
|
||||
return SYMBOL(start);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
extern "C" void __cxa_pure_virtual(void) { abort(); }
|
||||
|
||||
int
|
||||
main(int ac, const char** av)
|
||||
{
|
||||
JavaVMInitArgs vmArgs;
|
||||
vmArgs.version = JNI_VERSION_1_2;
|
||||
vmArgs.nOptions = 1;
|
||||
vmArgs.ignoreUnrecognized = JNI_TRUE;
|
||||
|
||||
JavaVMOption options[vmArgs.nOptions];
|
||||
vmArgs.options = options;
|
||||
|
||||
options[0].optionString = const_cast<char*>("-Xbootclasspath:[bootJar]");
|
||||
|
||||
JavaVM* vm;
|
||||
void* env;
|
||||
JNI_CreateJavaVM(&vm, &env, &vmArgs);
|
||||
JNIEnv* e = static_cast<JNIEnv*>(env);
|
||||
|
||||
jclass c = e->FindClass("Hello");
|
||||
if (not e->ExceptionCheck()) {
|
||||
jmethodID m = e->GetStaticMethodID(c, "main", "([Ljava/lang/String;)V");
|
||||
if (not e->ExceptionCheck()) {
|
||||
jclass stringClass = e->FindClass("java/lang/String");
|
||||
if (not e->ExceptionCheck()) {
|
||||
jobjectArray a = e->NewObjectArray(ac-1, stringClass, 0);
|
||||
if (not e->ExceptionCheck()) {
|
||||
for (int i = 1; i < ac; ++i) {
|
||||
e->SetObjectArrayElement(a, i-1, e->NewStringUTF(av[i]));
|
||||
}
|
||||
|
||||
e->CallStaticVoidMethod(c, m, a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int exitCode = 0;
|
||||
if (e->ExceptionCheck()) {
|
||||
exitCode = -1;
|
||||
e->ExceptionDescribe();
|
||||
}
|
||||
|
||||
vm->DestroyJavaVM();
|
||||
|
||||
return exitCode;
|
||||
}
|
||||
EOF
|
||||
|
||||
__on Linux:__
|
||||
|
||||
$ g++ -I$JAVA_HOME/include -I$JAVA_HOME/include/linux \
|
||||
-D_JNI_IMPLEMENTATION_ -c embedded-jar-main.cpp -o main.o
|
||||
|
||||
__on Mac OS X:__
|
||||
|
||||
$ g++ -I$JAVA_HOME/include -I$JAVA_HOME/include/darwin \
|
||||
-D_JNI_IMPLEMENTATION_ -c embedded-jar-main.cpp -o main.o
|
||||
|
||||
__on Windows:__
|
||||
|
||||
$ g++ -fno-exceptions -fno-rtti -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/win32" \
|
||||
-D_JNI_IMPLEMENTATION_ -c embedded-jar-main.cpp -o main.o
|
||||
|
||||
__5.__ Link the objects produced above to produce the final
|
||||
executable, and optionally strip its symbols.
|
||||
|
||||
__on Linux:__
|
||||
|
||||
$ g++ -rdynamic *.o -ldl -lpthread -lz -o hello
|
||||
$ strip --strip-all hello
|
||||
|
||||
__on Mac OS X:__
|
||||
|
||||
$ g++ -rdynamic *.o -ldl -lpthread -lz -o hello -framework CoreFoundation
|
||||
$ strip -S -x hello
|
||||
|
||||
__on Windows:__
|
||||
|
||||
$ dlltool -z hello.def *.o
|
||||
$ dlltool -d hello.def -e hello.exp
|
||||
$ gcc hello.exp *.o -L../../win32/lib -lmingwthrd -lm -lz -lws2_32 \
|
||||
-lIphlpapi -mwindows -mconsole -o hello.exe
|
||||
$ strip --strip-all hello.exe
|
||||
|
||||
Embedding with ProGuard and a Boot Image
|
||||
----------------------------------------
|
||||
|
||||
The following illustrates how to embed an application as above, except
|
||||
this time we preprocess the code using ProGuard and build a boot image
|
||||
from it for quicker startup. The pros and cons of using ProGuard are
|
||||
as follow:
|
||||
|
||||
* Pros: ProGuard will eliminate unused code, optimize the rest, and
|
||||
obfuscate it as well for maximum space savings
|
||||
|
||||
* Cons: increased build time, especially for large applications, and
|
||||
extra effort needed to configure it for applications which rely
|
||||
heavily on reflection and/or calls to Java from native code
|
||||
|
||||
For boot image builds:
|
||||
|
||||
* Pros: the boot image build pre-parses all the classes and compiles
|
||||
all the methods, obviating the need for JIT compilation at runtime.
|
||||
This also makes garbage collection faster, since the pre-parsed
|
||||
classes are never visited.
|
||||
|
||||
* Cons: the pre-parsed classes and AOT-compiled methods take up more
|
||||
space in the executable than the equivalent class files. In
|
||||
practice, this can make the executable 30-50% larger. Also, AOT
|
||||
compilation does not yet yield significantly faster or smaller code
|
||||
than JIT compilation. Finally, floating point code may be slower
|
||||
on 32-bit x86 since the compiler cannot assume SSE2 support will be
|
||||
available at runtime, and the x87 FPU is not supported except via
|
||||
out-of-line helper functions.
|
||||
|
||||
Note you can use ProGuard without using a boot image and vice-versa,
|
||||
as desired.
|
||||
|
||||
The following instructions assume we are building for Linux/x86_64.
|
||||
Please refer to the previous example for guidance on other platforms.
|
||||
|
||||
__1.__ Build Avian, create a new directory, and populate it with the
|
||||
VM object files.
|
||||
|
||||
$ make bootimage=true
|
||||
$ mkdir hello
|
||||
$ cd hello
|
||||
$ ar x ../build/linux-x86_64-bootimage/libavian.a
|
||||
|
||||
__2.__ Create a stage1 directory and extract the contents of the
|
||||
class library jar into it.
|
||||
|
||||
$ mkdir stage1
|
||||
$ (cd stage1 && jar xf ../../build/linux-x86_64-bootimage/classpath.jar)
|
||||
|
||||
__3.__ Build the Java code and add it to stage1.
|
||||
|
||||
$ cat >Hello.java <<EOF
|
||||
public class Hello {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("hello, world!");
|
||||
}
|
||||
}
|
||||
EOF
|
||||
$ javac -bootclasspath stage1 -d stage1 Hello.java
|
||||
|
||||
__4.__ Create a ProGuard configuration file specifying Hello.main as
|
||||
the entry point.
|
||||
|
||||
$ cat >hello.pro <<EOF
|
||||
-keep class Hello {
|
||||
public static void main(java.lang.String[]);
|
||||
}
|
||||
EOF
|
||||
|
||||
__5.__ Run ProGuard with stage1 as input and stage2 as output.
|
||||
|
||||
$ java -jar ../../proguard4.6/lib/proguard.jar \
|
||||
-dontusemixedcaseclassnames -injars stage1 -outjars stage2 \
|
||||
@../vm.pro @hello.pro
|
||||
|
||||
(note: The -dontusemixedcaseclassnames option is only needed when
|
||||
building on systems with case-insensitive filesystems such as Windows
|
||||
and OS X. Also, you'll need to add -ignorewarnings if you use the
|
||||
OpenJDK class library since the openjdk-src build does not include all
|
||||
the JARs from OpenJDK, and thus ProGuard will not be able to resolve
|
||||
all referenced classes. If you actually plan to use such classes at
|
||||
runtime, you'll need to add them to stage1 before running ProGuard.
|
||||
Finally, you'll need to add @../openjdk.pro to the above command when
|
||||
using the OpenJDK library.)
|
||||
|
||||
__6.__ Build the boot and code images.
|
||||
|
||||
$ ../build/linux-x86_64-bootimage/bootimage-generator \
|
||||
-cp stage2 \
|
||||
-bootimage bootimage-bin.o \
|
||||
-codeimage codeimage-bin.o \
|
||||
-hostvm ../build/linux-x86_64-interpret/libjvm.so
|
||||
|
||||
Note that you can override the default names for the start and end
|
||||
symbols in the boot/code image by also passing:
|
||||
|
||||
-bootimage-symbols my_bootimage_start:my_bootimage_end \
|
||||
-codeimage-symbols my_codeimage_start:my_codeimage_end
|
||||
|
||||
__7.__ Write a driver which starts the VM and runs the desired main
|
||||
method. Note the bootimageBin function, which will be called by the
|
||||
VM to get a handle to the embedded boot image. We tell the VM about
|
||||
this function via the "avian.bootimage" property.
|
||||
|
||||
Note also that this example includes no resources besides class files.
|
||||
If our application loaded resources such as images and properties
|
||||
files via the classloader, we would also need to embed the jar file
|
||||
containing them. See the previous example for instructions.
|
||||
|
||||
$ cat >bootimage-main.cpp <<EOF
|
||||
#include "stdint.h"
|
||||
#include "jni.h"
|
||||
|
||||
#if (defined __MINGW32__) || (defined _MSC_VER)
|
||||
# define EXPORT __declspec(dllexport)
|
||||
#else
|
||||
# define EXPORT __attribute__ ((visibility("default")))
|
||||
#endif
|
||||
|
||||
#if (! defined __x86_64__) && ((defined __MINGW32__) || (defined _MSC_VER))
|
||||
# define BOOTIMAGE_BIN(x) binary_bootimage_bin_##x
|
||||
# define CODEIMAGE_BIN(x) binary_codeimage_bin_##x
|
||||
#else
|
||||
# define BOOTIMAGE_BIN(x) _binary_bootimage_bin_##x
|
||||
# define CODEIMAGE_BIN(x) _binary_codeimage_bin_##x
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
|
||||
extern const uint8_t BOOTIMAGE_BIN(start)[];
|
||||
extern const uint8_t BOOTIMAGE_BIN(end)[];
|
||||
|
||||
EXPORT const uint8_t*
|
||||
bootimageBin(size_t* size)
|
||||
{
|
||||
*size = BOOTIMAGE_BIN(end) - BOOTIMAGE_BIN(start);
|
||||
return BOOTIMAGE_BIN(start);
|
||||
}
|
||||
|
||||
extern const uint8_t CODEIMAGE_BIN(start)[];
|
||||
extern const uint8_t CODEIMAGE_BIN(end)[];
|
||||
|
||||
EXPORT const uint8_t*
|
||||
codeimageBin(size_t* size)
|
||||
{
|
||||
*size = CODEIMAGE_BIN(end) - CODEIMAGE_BIN(start);
|
||||
return CODEIMAGE_BIN(start);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
int
|
||||
main(int ac, const char** av)
|
||||
{
|
||||
JavaVMInitArgs vmArgs;
|
||||
vmArgs.version = JNI_VERSION_1_2;
|
||||
vmArgs.nOptions = 2;
|
||||
vmArgs.ignoreUnrecognized = JNI_TRUE;
|
||||
|
||||
JavaVMOption options[vmArgs.nOptions];
|
||||
vmArgs.options = options;
|
||||
|
||||
options[0].optionString
|
||||
= const_cast<char*>("-Davian.bootimage=bootimageBin");
|
||||
|
||||
options[1].optionString
|
||||
= const_cast<char*>("-Davian.codeimage=codeimageBin");
|
||||
|
||||
JavaVM* vm;
|
||||
void* env;
|
||||
JNI_CreateJavaVM(&vm, &env, &vmArgs);
|
||||
JNIEnv* e = static_cast<JNIEnv*>(env);
|
||||
|
||||
jclass c = e->FindClass("Hello");
|
||||
if (not e->ExceptionCheck()) {
|
||||
jmethodID m = e->GetStaticMethodID(c, "main", "([Ljava/lang/String;)V");
|
||||
if (not e->ExceptionCheck()) {
|
||||
jclass stringClass = e->FindClass("java/lang/String");
|
||||
if (not e->ExceptionCheck()) {
|
||||
jobjectArray a = e->NewObjectArray(ac-1, stringClass, 0);
|
||||
if (not e->ExceptionCheck()) {
|
||||
for (int i = 1; i < ac; ++i) {
|
||||
e->SetObjectArrayElement(a, i-1, e->NewStringUTF(av[i]));
|
||||
}
|
||||
|
||||
e->CallStaticVoidMethod(c, m, a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int exitCode = 0;
|
||||
if (e->ExceptionCheck()) {
|
||||
exitCode = -1;
|
||||
e->ExceptionDescribe();
|
||||
}
|
||||
|
||||
vm->DestroyJavaVM();
|
||||
|
||||
return exitCode;
|
||||
}
|
||||
EOF
|
||||
|
||||
$ g++ -I$JAVA_HOME/include -I$JAVA_HOME/include/linux \
|
||||
-D_JNI_IMPLEMENTATION_ -c bootimage-main.cpp -o main.o
|
||||
|
||||
__8.__ Link the objects produced above to produce the final
|
||||
executable, and optionally strip its symbols.
|
||||
|
||||
$ g++ -rdynamic *.o -ldl -lpthread -lz -o hello
|
||||
$ strip --strip-all hello
|
||||
|
||||
|
||||
Trademarks
|
||||
----------
|
||||
|
||||
Oracle and Java are registered trademarks of Oracle and/or its
|
||||
affiliates. Other names may be trademarks of their respective owners.
|
||||
|
||||
The Avian project is not affiliated with Oracle.
|
89
sgx-jvm/avian/android.pro
Normal file
89
sgx-jvm/avian/android.pro
Normal file
@ -0,0 +1,89 @@
|
||||
# these are referenced in JniConstants.cpp:
|
||||
|
||||
-keep class java.text.Bidi$Run
|
||||
-keep class java.math.BigDecimal
|
||||
-keep class java.lang.Boolean
|
||||
-keep class java.lang.Byte
|
||||
-keep class java.nio.charset.CharsetICU {
|
||||
CharsetICU(java.lang.String, java.lang.String, java.lang.String[]);
|
||||
}
|
||||
-keep class java.lang.reflect.Constructor
|
||||
-keep class java.util.zip.Deflater
|
||||
-keep class java.lang.Double
|
||||
-keep class libcore.io.ErrnoException
|
||||
-keep class java.lang.reflect.Field
|
||||
-keep class libcore.icu.NativeDecimalFormat$FieldPositionIterator {
|
||||
void setData(int[]);
|
||||
}
|
||||
-keep class java.io.FileDescriptor
|
||||
-keep class libcore.io.GaiException
|
||||
-keep class java.net.Inet6Address
|
||||
-keep class java.net.InetAddress
|
||||
-keep class java.net.InetSocketAddress
|
||||
-keep class java.net.InetUnixAddress
|
||||
-keep class java.util.zip.Inflater
|
||||
-keep class java.lang.Integer
|
||||
-keep class libcore.icu.LocaleData
|
||||
-keep class java.lang.Long
|
||||
-keep class java.lang.reflect.Method
|
||||
-keep class libcore.util.MutableInt
|
||||
-keep class libcore.util.MutableLong
|
||||
-keep class java.text.ParsePosition
|
||||
-keep class java.util.regex.PatternSyntaxException
|
||||
-keep class java.lang.RealToString
|
||||
-keep class java.net.Socket
|
||||
-keep class java.net.SocketImpl
|
||||
-keep class java.lang.String
|
||||
-keep class libcore.io.StructAddrinfo {
|
||||
<fields>;
|
||||
}
|
||||
-keep class libcore.io.StructFlock
|
||||
-keep class libcore.io.StructGroupReq
|
||||
-keep class libcore.io.StructLinger
|
||||
-keep class libcore.io.StructPasswd {
|
||||
StructPasswd(java.lang.String, int, int, java.lang.String, java.lang.String);
|
||||
}
|
||||
-keep class libcore.io.StructPollfd
|
||||
-keep class libcore.io.StructStat {
|
||||
StructStat(long, long, int, long, int, int, long, long, long, long, long, long, long);
|
||||
}
|
||||
-keep class libcore.io.StructStatFs
|
||||
-keep class libcore.io.StructTimeval
|
||||
-keep class libcore.io.StructUtsname {
|
||||
StructUtsname(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String);
|
||||
}
|
||||
-keep class libcore.io.StructUcred
|
||||
|
||||
# referenced from libcore native code
|
||||
|
||||
-keep class libcore.icu.LocaleData {
|
||||
<fields>;
|
||||
}
|
||||
|
||||
-keep class org.conscrypt.OpenSSLBIOInputStream {
|
||||
<methods>;
|
||||
}
|
||||
|
||||
-keep class java.util.Calendar {
|
||||
void set(int, int, int, int, int, int);
|
||||
}
|
||||
|
||||
# called from the VM
|
||||
|
||||
-keep class java.lang.Thread {
|
||||
Thread(java.lang.ThreadGroup, java.lang.String, int, boolean);
|
||||
}
|
||||
|
||||
-keep class avian.Classes {
|
||||
java.lang.Class forName(java.lang.String, boolean, java.lang.ClassLoader);
|
||||
int findField(avian.VMClass, java.lang.String);
|
||||
int findMethod(avian.VMClass, java.lang.String, java.lang.Class[]);
|
||||
java.lang.annotation.Annotation getAnnotation(java.lang.ClassLoader, java.lang.Object[]);
|
||||
}
|
||||
|
||||
-keep class java.lang.VMThread {
|
||||
VMThread(java.lang.Thread);
|
||||
}
|
||||
|
||||
# loaded reflectively to handle embedded resources:
|
||||
-keep class avian.avianvmresource.Handler
|
323
sgx-jvm/avian/build.gradle
Normal file
323
sgx-jvm/avian/build.gradle
Normal file
@ -0,0 +1,323 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'org.jfrog.buildinfo:build-info-extractor-gradle:2.2.4'
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'native-component'
|
||||
apply plugin: 'ivy-publish'
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'artifactory-publish'
|
||||
|
||||
enum SupportedOS implements OperatingSystem {
|
||||
LINUX, WINDOWS, MACOSX;
|
||||
|
||||
public static final SupportedOS CURRENT;
|
||||
|
||||
static {
|
||||
String p = System.properties['os.name']
|
||||
switch(p.replaceAll(' ', '').toLowerCase()) {
|
||||
case ~/.*linux.*/: CURRENT = LINUX; break;
|
||||
case ~/.*darwin.*/: CURRENT = MACOSX; break;
|
||||
case ~/.*osx.*/: CURRENT = MACOSX; break;
|
||||
case ~/.*win.*/: CURRENT = WINDOWS; break;
|
||||
default:
|
||||
String m = "SupportedOS: unrecognized platform: ${p}"
|
||||
println(m)
|
||||
throw new IllegalArgumentException(m)
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return toString().toLowerCase()
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return getName()
|
||||
}
|
||||
public boolean isCurrent() { return this == CURRENT }
|
||||
public boolean isFreeBSD() { return false }
|
||||
public boolean isLinux() { return this == LINUX }
|
||||
public boolean isMacOsX() { return this == MACOSX }
|
||||
public boolean isSolaris() { return false }
|
||||
public boolean isWindows() { return this == WINDOWS }
|
||||
|
||||
}
|
||||
|
||||
public String adjustArch(String arch) {
|
||||
switch(arch) {
|
||||
case ~/.*64.*/: return 'x86_64'
|
||||
default: return 'i386'
|
||||
}
|
||||
}
|
||||
|
||||
ext {
|
||||
currentPlatform = SupportedOS.CURRENT.getName()
|
||||
currentArch = adjustArch(System.properties['os.arch'])
|
||||
currentPlatformArch = "${currentPlatform}-${currentArch}"
|
||||
|
||||
platform = project.hasProperty('platform') ? platform : currentPlatform
|
||||
arch = project.hasProperty('arch') ? arch : currentArch
|
||||
platformArch = "${platform}-${arch}"
|
||||
|
||||
java_home = System.properties.'java.home'
|
||||
if(java_home.endsWith("/jre")) {
|
||||
java_home = java_home.substring(0, java_home.length() - "/jre".length())
|
||||
}
|
||||
java_home = java_home
|
||||
|
||||
libDir = "${buildDir}/lib"
|
||||
lzmaDir = "${libDir}/lzma"
|
||||
|
||||
buildOptions = ['', '-lzma']
|
||||
}
|
||||
|
||||
repositories {
|
||||
ivy {
|
||||
name "ivyLocal"
|
||||
url "${System.env.HOME}/.ivy2/local"
|
||||
layout 'maven'
|
||||
}
|
||||
|
||||
ivy {
|
||||
name "jcenter"
|
||||
if(version.contains("SNAPSHOT")) {
|
||||
url "http://oss.jfrog.org/artifactory/oss-snapshot-local"
|
||||
} else {
|
||||
url "http://oss.jfrog.org/artifactory/oss-release-local"
|
||||
}
|
||||
layout 'maven'
|
||||
}
|
||||
}
|
||||
|
||||
configurations {
|
||||
create('windows-i386')
|
||||
create('windows-x86_64')
|
||||
}
|
||||
|
||||
dependencies {
|
||||
'windows-i386' "com.readytalk:win32:1.0.0-SNAPSHOT"
|
||||
'windows-x86_64' "com.readytalk:win64:1.0.0-SNAPSHOT"
|
||||
}
|
||||
|
||||
model {
|
||||
platforms {
|
||||
create(platformArch) {
|
||||
operatingSystem SupportedOS.valueOf(platform.toUpperCase())
|
||||
architecture "${arch}"
|
||||
}
|
||||
}
|
||||
|
||||
tasks {
|
||||
buildOptions.each { buildOption ->
|
||||
platforms.each { platform ->
|
||||
if(platform.operatingSystem.name == "windows") {
|
||||
def artifactName = platform.architecture.name == "i386" ? 'win32' : 'win64'
|
||||
|
||||
task "extract${platform.name}${buildOption}"(type: Copy) {
|
||||
from {
|
||||
tarTree(configurations."${platform.name}".find { it.name =~ artifactName })
|
||||
}
|
||||
into "${libDir}/tools"
|
||||
}
|
||||
}
|
||||
|
||||
task "build${platform.name}${buildOption}"(type: Exec) {
|
||||
executable "make"
|
||||
args "platform=${platform.operatingSystem.name}",
|
||||
"arch=${platform.architecture.name}"
|
||||
|
||||
if(buildOption == "-lzma") {
|
||||
dependsOn 'extractLzma'
|
||||
args "lzma=${lzmaDir}"
|
||||
}
|
||||
|
||||
if(platform.operatingSystem.name == "windows") {
|
||||
dependsOn "extract${platform.name}${buildOption}"
|
||||
args "win32=${libDir}/tools/win32",
|
||||
"win64=${libDir}/tools/win64"
|
||||
}
|
||||
environment JAVA_HOME: java_home
|
||||
}
|
||||
|
||||
assemble {
|
||||
dependsOn "build${platform.name}${buildOption}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
sourceCompatibility = "1.6"
|
||||
targetCompatibility = "1.6"
|
||||
|
||||
options.with {
|
||||
encoding = "UTF-8"
|
||||
bootClasspath = sourceSets.main.output.classesDir
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
java {
|
||||
srcDir 'classpath'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
javadoc {
|
||||
title = "Avian v${version} Class Library API"
|
||||
}
|
||||
|
||||
task javadocJar(type: Jar) {
|
||||
dependsOn javadoc
|
||||
classifier = 'javadoc'
|
||||
from {
|
||||
javadoc.destinationDir
|
||||
}
|
||||
}
|
||||
|
||||
jar {
|
||||
baseName "classpath-avian"
|
||||
}
|
||||
|
||||
task downloadLzma(type: Exec) {
|
||||
commandLine "curl"
|
||||
args "--create-dirs", "-o", "${lzmaDir}/lzma920.tar.bz2", "-f", "http://oss.readytalk.com/avian-web/lzma920.tar.bz2"
|
||||
}
|
||||
|
||||
task extractLzma(type: Copy) {
|
||||
dependsOn downloadLzma
|
||||
from {
|
||||
tarTree(resources.bzip2("${lzmaDir}/lzma920.tar.bz2"))
|
||||
}
|
||||
into lzmaDir
|
||||
}
|
||||
|
||||
task install {
|
||||
dependsOn assemble, publish
|
||||
}
|
||||
|
||||
publishing {
|
||||
repositories {
|
||||
add(project.repositories."ivyLocal")
|
||||
}
|
||||
|
||||
publications {
|
||||
|
||||
ivy(IvyPublication) {
|
||||
from components.java
|
||||
|
||||
artifact(javadocJar)
|
||||
|
||||
artifact("vm.pro") {
|
||||
name "vm"
|
||||
type "proguard"
|
||||
extension "pro"
|
||||
}
|
||||
|
||||
module "classpath-avian"
|
||||
}
|
||||
|
||||
create("tools-avian-${currentPlatformArch}", IvyPublication) {
|
||||
module "tools-avian-${currentPlatformArch}"
|
||||
|
||||
def publishBinSuffix = currentPlatform == "windows" ? "exe" : "bin"
|
||||
def binSuffix = currentPlatform == "windows" ? ".exe" : ""
|
||||
artifact("${buildDir}/${currentPlatform}-${currentArch}/binaryToObject/binaryToObject${binSuffix}") {
|
||||
name "binaryToObject"
|
||||
type publishBinSuffix
|
||||
extension publishBinSuffix
|
||||
}
|
||||
}
|
||||
|
||||
buildOptions.each { buildOption ->
|
||||
platforms.each { platform ->
|
||||
def binSuffix=""
|
||||
def publishBinSuffix="bin"
|
||||
|
||||
create("${platform.name}${buildOption}", IvyPublication) {
|
||||
def nativeBuildDir = "${buildDir}/${platform.operatingSystem.name}-${platform.architecture.name}${buildOption}"
|
||||
|
||||
if(platform.operatingSystem.name == "windows") {
|
||||
publishBinSuffix = "exe"
|
||||
binSuffix = ".${publishBinSuffix}"
|
||||
}
|
||||
|
||||
module "runtime-avian${buildOption}-${platform.name}"
|
||||
|
||||
artifact("${nativeBuildDir}/avian${binSuffix}") {
|
||||
name "avian"
|
||||
type publishBinSuffix
|
||||
extension publishBinSuffix
|
||||
}
|
||||
|
||||
artifact("${nativeBuildDir}/libavian.a") {
|
||||
name "libavian"
|
||||
type "a"
|
||||
extension "a"
|
||||
}
|
||||
|
||||
if (buildOption == "-lzma") {
|
||||
artifact("${nativeBuildDir}/libavian-lzma.a") {
|
||||
name "libavian-lzma"
|
||||
type "a"
|
||||
extension "a"
|
||||
}
|
||||
|
||||
artifact("${nativeBuildDir}/lzma/lzma${binSuffix}") {
|
||||
name "lzma"
|
||||
type publishBinSuffix
|
||||
extension publishBinSuffix
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
artifactoryPublish {
|
||||
onlyIf {
|
||||
// TRAVIS_BRANCH reports master if it is a master build or a PR going to master
|
||||
// TRAVIS_PULL_REQUEST reports false if not a pull request and the PR number if it is
|
||||
System.env.'TRAVIS_BRANCH' == "master" && System.env.'TRAVIS_PULL_REQUEST' == "false"
|
||||
}
|
||||
dependsOn assemble
|
||||
}
|
||||
|
||||
artifactory {
|
||||
contextUrl = "http://oss.jfrog.org"
|
||||
|
||||
resolve {
|
||||
repository {
|
||||
repoKey = 'libs-releases'
|
||||
}
|
||||
}
|
||||
|
||||
publish {
|
||||
repository {
|
||||
repoKey = 'oss-snapshot-local'
|
||||
username = System.env.BINTRAY_USER
|
||||
password = System.env.BINTRAY_API_KEY
|
||||
ivy {
|
||||
ivyLayout = "[organisation]/[module]/[revision]/ivy-[revision].xml"
|
||||
}
|
||||
}
|
||||
|
||||
defaults {
|
||||
platforms.each {
|
||||
publications it.name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
distributionUrl = 'http://services.gradle.org/distributions/gradle-2.0-bin.zip'
|
||||
}
|
17
sgx-jvm/avian/classpath/avian/Addendum.java
Normal file
17
sgx-jvm/avian/classpath/avian/Addendum.java
Normal file
@ -0,0 +1,17 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
public class Addendum {
|
||||
public Singleton pool;
|
||||
public Object annotationTable;
|
||||
public Object signature;
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
|
||||
public class AnnotationInvocationHandler implements InvocationHandler {
|
||||
private Object[] data;
|
||||
|
||||
public AnnotationInvocationHandler(Object[] data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public Object invoke(Object proxy, Method method, Object[] arguments) {
|
||||
String name = method.getName();
|
||||
for (int i = 2; i < data.length; i += 2) {
|
||||
if (name.equals(data[i])) {
|
||||
return data[i + 1];
|
||||
}
|
||||
}
|
||||
return method.getDefaultValue();
|
||||
}
|
||||
}
|
135
sgx-jvm/avian/classpath/avian/Assembler.java
Normal file
135
sgx-jvm/avian/classpath/avian/Assembler.java
Normal file
@ -0,0 +1,135 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
import static avian.Stream.write1;
|
||||
import static avian.Stream.write2;
|
||||
import static avian.Stream.write4;
|
||||
|
||||
import avian.ConstantPool.PoolEntry;
|
||||
|
||||
import java.util.List;
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class Assembler {
|
||||
public static final int ACC_PUBLIC = 1 << 0;
|
||||
public static final int ACC_STATIC = 1 << 3;
|
||||
|
||||
public static final int aaload = 0x32;
|
||||
public static final int aastore = 0x53;
|
||||
public static final int aload = 0x19;
|
||||
public static final int aload_0 = 0x2a;
|
||||
public static final int aload_1 = 0x2b;
|
||||
public static final int astore_0 = 0x4b;
|
||||
public static final int anewarray = 0xbd;
|
||||
public static final int areturn = 0xb0;
|
||||
public static final int dload = 0x18;
|
||||
public static final int dreturn = 0xaf;
|
||||
public static final int dup = 0x59;
|
||||
public static final int fload = 0x17;
|
||||
public static final int freturn = 0xae;
|
||||
public static final int getfield = 0xb4;
|
||||
public static final int goto_ = 0xa7;
|
||||
public static final int iload = 0x15;
|
||||
public static final int invokeinterface = 0xb9;
|
||||
public static final int invokespecial = 0xb7;
|
||||
public static final int invokestatic = 0xb8;
|
||||
public static final int invokevirtual = 0xb6;
|
||||
public static final int ireturn = 0xac;
|
||||
public static final int jsr = 0xa8;
|
||||
public static final int ldc_w = 0x13;
|
||||
public static final int lload = 0x16;
|
||||
public static final int lreturn = 0xad;
|
||||
public static final int new_ = 0xbb;
|
||||
public static final int pop = 0x57;
|
||||
public static final int putfield = 0xb5;
|
||||
public static final int ret = 0xa9;
|
||||
public static final int return_ = 0xb1;
|
||||
|
||||
public static void writeClass(OutputStream out,
|
||||
List<PoolEntry> pool,
|
||||
int name,
|
||||
int super_,
|
||||
int[] interfaces,
|
||||
FieldData[] fields,
|
||||
MethodData[] methods)
|
||||
throws IOException
|
||||
{
|
||||
int codeAttributeName = ConstantPool.addUtf8(pool, "Code");
|
||||
|
||||
write4(out, 0xCAFEBABE);
|
||||
write2(out, 0); // minor version
|
||||
write2(out, 50); // major version
|
||||
|
||||
write2(out, pool.size() + 1);
|
||||
for (PoolEntry e: pool) {
|
||||
e.writeTo(out);
|
||||
}
|
||||
|
||||
write2(out, ACC_PUBLIC); // flags
|
||||
write2(out, name + 1);
|
||||
write2(out, super_ + 1);
|
||||
|
||||
write2(out, interfaces.length);
|
||||
for (int i: interfaces) {
|
||||
write2(out, i + 1);
|
||||
}
|
||||
|
||||
write2(out, fields.length);
|
||||
for (FieldData f: fields) {
|
||||
write2(out, f.flags);
|
||||
write2(out, f.nameIndex + 1);
|
||||
write2(out, f.specIndex + 1);
|
||||
write2(out, 0); // attribute count
|
||||
}
|
||||
|
||||
write2(out, methods.length);
|
||||
for (MethodData m: methods) {
|
||||
write2(out, m.flags);
|
||||
write2(out, m.nameIndex + 1);
|
||||
write2(out, m.specIndex + 1);
|
||||
|
||||
write2(out, 1); // attribute count
|
||||
write2(out, codeAttributeName + 1);
|
||||
write4(out, m.code.length);
|
||||
out.write(m.code);
|
||||
}
|
||||
|
||||
write2(out, 0); // attribute count
|
||||
}
|
||||
|
||||
public static class MethodData {
|
||||
public final int flags;
|
||||
public final int nameIndex;
|
||||
public final int specIndex;
|
||||
public final byte[] code;
|
||||
|
||||
public MethodData(int flags, int nameIndex, int specIndex, byte[] code) {
|
||||
this.flags = flags;
|
||||
this.nameIndex = nameIndex;
|
||||
this.specIndex = specIndex;
|
||||
this.code = code;
|
||||
}
|
||||
}
|
||||
|
||||
public static class FieldData {
|
||||
public final int flags;
|
||||
public final int nameIndex;
|
||||
public final int specIndex;
|
||||
|
||||
public FieldData(int flags, int nameIndex, int specIndex) {
|
||||
this.flags = flags;
|
||||
this.nameIndex = nameIndex;
|
||||
this.specIndex = specIndex;
|
||||
}
|
||||
}
|
||||
}
|
20
sgx-jvm/avian/classpath/avian/Atomic.java
Normal file
20
sgx-jvm/avian/classpath/avian/Atomic.java
Normal file
@ -0,0 +1,20 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class Atomic {
|
||||
public static native long getOffset(Field field);
|
||||
|
||||
public static native boolean compareAndSwapObject
|
||||
(Object o, long offset, Object old, Object new_);
|
||||
}
|
16
sgx-jvm/avian/classpath/avian/Callback.java
Normal file
16
sgx-jvm/avian/classpath/avian/Callback.java
Normal file
@ -0,0 +1,16 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
public interface Callback<T> {
|
||||
public void handleResult(T result);
|
||||
public void handleException(Throwable exception);
|
||||
}
|
54
sgx-jvm/avian/classpath/avian/Cell.java
Normal file
54
sgx-jvm/avian/classpath/avian/Cell.java
Normal file
@ -0,0 +1,54 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
public class Cell <T> {
|
||||
public T value;
|
||||
public Cell<T> next;
|
||||
|
||||
public Cell(T value, Cell<T> next) {
|
||||
this.value = value;
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("(");
|
||||
for (Cell c = this; c != null; c = c.next) {
|
||||
sb.append(value);
|
||||
if (c.next != null) {
|
||||
sb.append(" ");
|
||||
}
|
||||
}
|
||||
sb.append(")");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static <Car> Cell<Car> cons(Car car, Cell<Car> cdr) {
|
||||
return new Cell(car, cdr);
|
||||
}
|
||||
|
||||
public static <T> boolean equal(T a, T b) {
|
||||
return (a == null && b == null) || (a != null && a.equals(b));
|
||||
}
|
||||
|
||||
public static <Car> boolean equal(Cell<Car> a, Cell<Car> b) {
|
||||
while (a != null) {
|
||||
if (b == null || (! equal(a.value, b.value))) {
|
||||
return false;
|
||||
}
|
||||
a = a.next;
|
||||
b = b.next;
|
||||
}
|
||||
|
||||
return b == null;
|
||||
}
|
||||
}
|
32
sgx-jvm/avian/classpath/avian/ClassAddendum.java
Normal file
32
sgx-jvm/avian/classpath/avian/ClassAddendum.java
Normal file
@ -0,0 +1,32 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
public class ClassAddendum extends Addendum {
|
||||
public Object[] interfaceTable;
|
||||
public InnerClassReference[] innerClassTable;
|
||||
/**
|
||||
* If this value is negative, all the methods in VMClass.methodTable
|
||||
* were declared in that class. Otherwise, only the first
|
||||
* declaredMethodCount methods in that table were declared in that
|
||||
* class, while the rest were declared in interfaces implemented or
|
||||
* extended by that class.
|
||||
*/
|
||||
public int declaredMethodCount;
|
||||
|
||||
public byte[] enclosingClass;
|
||||
|
||||
public Pair enclosingMethod;
|
||||
|
||||
public VMMethod[] bootstrapMethodTable;
|
||||
|
||||
public VMMethod[] bootstrapLambdaTable;
|
||||
}
|
604
sgx-jvm/avian/classpath/avian/Classes.java
Normal file
604
sgx-jvm/avian/classpath/avian/Classes.java
Normal file
@ -0,0 +1,604 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
import static avian.Stream.read1;
|
||||
import static avian.Stream.read2;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.MalformedURLException;
|
||||
import java.security.CodeSource;
|
||||
import java.security.AllPermission;
|
||||
import java.security.Permissions;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.security.cert.Certificate;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.io.InputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class Classes {
|
||||
private static final int LinkFlag = 1 << 8;
|
||||
|
||||
public static native VMClass defineVMClass
|
||||
(ClassLoader loader, byte[] b, int offset, int length);
|
||||
|
||||
public static native VMClass primitiveClass(char name);
|
||||
|
||||
public static native void initialize(VMClass vmClass);
|
||||
|
||||
public static native boolean isAssignableFrom(VMClass a, VMClass b);
|
||||
|
||||
public static native VMClass getVMClass(Object o);
|
||||
|
||||
public static native VMClass toVMClass(Class c);
|
||||
|
||||
public static native VMMethod toVMMethod(Method m);
|
||||
|
||||
private static native VMClass resolveVMClass(ClassLoader loader, byte[] spec)
|
||||
throws ClassNotFoundException;
|
||||
|
||||
public static VMClass loadVMClass(ClassLoader loader,
|
||||
byte[] nameBytes, int offset, int length)
|
||||
{
|
||||
byte[] spec = new byte[length + 1];
|
||||
System.arraycopy(nameBytes, offset, spec, 0, length);
|
||||
|
||||
try {
|
||||
VMClass c = resolveVMClass(loader, spec);
|
||||
if (c == null) {
|
||||
throw new NoClassDefFoundError();
|
||||
}
|
||||
return c;
|
||||
} catch (ClassNotFoundException e) {
|
||||
NoClassDefFoundError error = new NoClassDefFoundError
|
||||
(new String(nameBytes, offset, length));
|
||||
error.initCause(e);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
private static Object parseAnnotationValue(ClassLoader loader,
|
||||
Object pool,
|
||||
InputStream in)
|
||||
throws IOException
|
||||
{
|
||||
switch (read1(in)) {
|
||||
case 'Z':
|
||||
return Boolean.valueOf(Singleton.getInt(pool, read2(in) - 1) != 0);
|
||||
|
||||
case 'B':
|
||||
return Byte.valueOf((byte) Singleton.getInt(pool, read2(in) - 1));
|
||||
|
||||
case 'C':
|
||||
return Character.valueOf((char) Singleton.getInt(pool, read2(in) - 1));
|
||||
|
||||
case 'S':
|
||||
return Short.valueOf((short) Singleton.getInt(pool, read2(in) - 1));
|
||||
|
||||
case 'I':
|
||||
return Integer.valueOf(Singleton.getInt(pool, read2(in) - 1));
|
||||
|
||||
case 'F':
|
||||
return Float.valueOf
|
||||
(Float.intBitsToFloat(Singleton.getInt(pool, read2(in) - 1)));
|
||||
|
||||
case 'J': {
|
||||
return Long.valueOf(Singleton.getLong(pool, read2(in) - 1));
|
||||
}
|
||||
|
||||
case 'D': {
|
||||
return Double.valueOf
|
||||
(Double.longBitsToDouble(Singleton.getLong(pool, read2(in) - 1)));
|
||||
}
|
||||
|
||||
case 's': {
|
||||
byte[] data = (byte[]) Singleton.getObject(pool, read2(in) - 1);
|
||||
|
||||
return new String(data, 0, data.length - 1);
|
||||
}
|
||||
|
||||
case 'e': {
|
||||
byte[] typeName = (byte[]) Singleton.getObject(pool, read2(in) - 1);
|
||||
byte[] name = (byte[]) Singleton.getObject(pool, read2(in) - 1);
|
||||
|
||||
return Enum.valueOf
|
||||
(SystemClassLoader.getClass
|
||||
(loadVMClass(loader, typeName, 1, typeName.length - 3)),
|
||||
new String(name, 0, name.length - 1));
|
||||
}
|
||||
|
||||
case 'c':{
|
||||
byte[] name = (byte[]) Singleton.getObject(pool, read2(in) - 1);
|
||||
|
||||
return SystemClassLoader.getClass
|
||||
(loadVMClass(loader, name, 1, name.length - 3));
|
||||
}
|
||||
|
||||
case '@':
|
||||
return getAnnotation(loader, parseAnnotation(loader, pool, in));
|
||||
|
||||
case '[': {
|
||||
Object[] array = new Object[read2(in)];
|
||||
for (int i = 0; i < array.length; ++i) {
|
||||
array[i] = parseAnnotationValue(loader, pool, in);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
default: throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
private static Object[] parseAnnotation(ClassLoader loader,
|
||||
Object pool,
|
||||
InputStream in)
|
||||
throws IOException
|
||||
{
|
||||
byte[] typeName = (byte[]) Singleton.getObject(pool, read2(in) - 1);
|
||||
Object[] annotation = new Object[(read2(in) + 1) * 2];
|
||||
annotation[1] = SystemClassLoader.getClass
|
||||
(loadVMClass(loader, typeName, 1, typeName.length - 3));
|
||||
|
||||
for (int i = 2; i < annotation.length; i += 2) {
|
||||
byte[] name = (byte[]) Singleton.getObject(pool, read2(in) - 1);
|
||||
annotation[i] = new String(name, 0, name.length - 1);
|
||||
annotation[i + 1] = parseAnnotationValue(loader, pool, in);
|
||||
}
|
||||
|
||||
return annotation;
|
||||
}
|
||||
|
||||
private static Object[] parseAnnotationTable(ClassLoader loader,
|
||||
Object pool,
|
||||
InputStream in)
|
||||
throws IOException
|
||||
{
|
||||
Object[] table = new Object[read2(in)];
|
||||
for (int i = 0; i < table.length; ++i) {
|
||||
table[i] = parseAnnotation(loader, pool, in);
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
private static void parseAnnotationTable(ClassLoader loader,
|
||||
Addendum addendum)
|
||||
{
|
||||
if (addendum != null && addendum.annotationTable instanceof byte[]) {
|
||||
try {
|
||||
addendum.annotationTable = parseAnnotationTable
|
||||
(loader, addendum.pool, new ByteArrayInputStream
|
||||
((byte[]) addendum.annotationTable));
|
||||
} catch (IOException e) {
|
||||
AssertionError error = new AssertionError();
|
||||
error.initCause(e);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int resolveSpec(ClassLoader loader, byte[] spec, int start) {
|
||||
int result;
|
||||
int end;
|
||||
switch (spec[start]) {
|
||||
case 'L':
|
||||
++ start;
|
||||
end = start;
|
||||
while (spec[end] != ';') ++ end;
|
||||
result = end + 1;
|
||||
break;
|
||||
|
||||
case '[':
|
||||
end = start + 1;
|
||||
while (spec[end] == '[') ++ end;
|
||||
switch (spec[end]) {
|
||||
case 'L':
|
||||
++ end;
|
||||
while (spec[end] != ';') ++ end;
|
||||
++ end;
|
||||
break;
|
||||
|
||||
default:
|
||||
++ end;
|
||||
}
|
||||
result = end;
|
||||
break;
|
||||
|
||||
default:
|
||||
return start + 1;
|
||||
}
|
||||
|
||||
loadVMClass(loader, spec, start, end - start);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int declaredMethodCount(VMClass c) {
|
||||
ClassAddendum a = c.addendum;
|
||||
if (a != null) {
|
||||
int count = a.declaredMethodCount;
|
||||
if (count >= 0) {
|
||||
return count;
|
||||
}
|
||||
}
|
||||
VMMethod[] table = c.methodTable;
|
||||
return table == null ? 0 : table.length;
|
||||
}
|
||||
|
||||
public static void link(VMClass c, ClassLoader loader) {
|
||||
acquireClassLock();
|
||||
try {
|
||||
if ((c.vmFlags & LinkFlag) == 0) {
|
||||
if (c.super_ != null) {
|
||||
link(c.super_, loader);
|
||||
}
|
||||
|
||||
parseAnnotationTable(loader, c.addendum);
|
||||
|
||||
if (c.interfaceTable != null) {
|
||||
int stride = ((c.flags & Modifier.INTERFACE) != 0 ? 1 : 2);
|
||||
for (int i = 0; i < c.interfaceTable.length; i += stride) {
|
||||
link((VMClass) c.interfaceTable[i], loader);
|
||||
}
|
||||
}
|
||||
|
||||
VMMethod[] methodTable = c.methodTable;
|
||||
if (methodTable != null) {
|
||||
for (int i = 0; i < methodTable.length; ++i) {
|
||||
VMMethod m = methodTable[i];
|
||||
|
||||
for (int j = 1; j < m.spec.length;) {
|
||||
j = resolveSpec(loader, m.spec, j);
|
||||
}
|
||||
|
||||
parseAnnotationTable(loader, m.addendum);
|
||||
}
|
||||
}
|
||||
|
||||
if (c.fieldTable != null) {
|
||||
for (int i = 0; i < c.fieldTable.length; ++i) {
|
||||
VMField f = c.fieldTable[i];
|
||||
|
||||
resolveSpec(loader, f.spec, 0);
|
||||
|
||||
parseAnnotationTable(loader, f.addendum);
|
||||
}
|
||||
}
|
||||
|
||||
c.vmFlags |= LinkFlag;
|
||||
}
|
||||
} finally {
|
||||
releaseClassLock();
|
||||
}
|
||||
}
|
||||
|
||||
public static void link(VMClass c) {
|
||||
link(c, c.loader);
|
||||
}
|
||||
|
||||
public static Class forName(String name, boolean initialize,
|
||||
ClassLoader loader)
|
||||
throws ClassNotFoundException
|
||||
{
|
||||
if (loader == null) {
|
||||
loader = Class.class.getClassLoader();
|
||||
}
|
||||
Class c = loader.loadClass(name);
|
||||
VMClass vmc = SystemClassLoader.vmClass(c);
|
||||
link(vmc, loader);
|
||||
if (initialize) {
|
||||
initialize(vmc);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
public static Class forCanonicalName(String name) {
|
||||
return forCanonicalName(null, name);
|
||||
}
|
||||
|
||||
public static Class forCanonicalName(ClassLoader loader, String name) {
|
||||
try {
|
||||
if (name.startsWith("[")) {
|
||||
return forName(name, true, loader);
|
||||
} else if (name.startsWith("L")) {
|
||||
return forName(name.substring(1, name.length() - 1), true, loader);
|
||||
} else {
|
||||
if (name.length() == 1) {
|
||||
return SystemClassLoader.getClass
|
||||
(primitiveClass(name.charAt(0)));
|
||||
} else {
|
||||
throw new ClassNotFoundException(name);
|
||||
}
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static int next(char c, String s, int start) {
|
||||
for (int i = start; i < s.length(); ++i) {
|
||||
if (s.charAt(i) == c) return i;
|
||||
}
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
public static Class[] getParameterTypes(VMMethod vmMethod) {
|
||||
int count = vmMethod.parameterCount;
|
||||
|
||||
Class[] types = new Class[count];
|
||||
int index = 0;
|
||||
|
||||
String spec = new String
|
||||
(vmMethod.spec, 1, vmMethod.spec.length - 2);
|
||||
|
||||
try {
|
||||
for (int i = 0; i < spec.length(); ++i) {
|
||||
char c = spec.charAt(i);
|
||||
if (c == ')') {
|
||||
break;
|
||||
} else if (c == 'L') {
|
||||
int start = i + 1;
|
||||
i = next(';', spec, start);
|
||||
String name = spec.substring(start, i).replace('/', '.');
|
||||
types[index++] = Class.forName(name, true, vmMethod.class_.loader);
|
||||
} else if (c == '[') {
|
||||
int start = i;
|
||||
while (spec.charAt(i) == '[') ++i;
|
||||
|
||||
if (spec.charAt(i) == 'L') {
|
||||
i = next(';', spec, i + 1);
|
||||
String name = spec.substring(start, i).replace('/', '.');
|
||||
types[index++] = Class.forName
|
||||
(name, true, vmMethod.class_.loader);
|
||||
} else {
|
||||
String name = spec.substring(start, i + 1);
|
||||
types[index++] = forCanonicalName(vmMethod.class_.loader, name);
|
||||
}
|
||||
} else {
|
||||
String name = spec.substring(i, i + 1);
|
||||
types[index++] = forCanonicalName(vmMethod.class_.loader, name);
|
||||
}
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
public static int findField(VMClass vmClass, String name) {
|
||||
if (vmClass.fieldTable != null) {
|
||||
link(vmClass);
|
||||
|
||||
for (int i = 0; i < vmClass.fieldTable.length; ++i) {
|
||||
if (toString(vmClass.fieldTable[i].name).equals(name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static String toString(byte[] array) {
|
||||
return new String(array, 0, array.length - 1);
|
||||
}
|
||||
|
||||
private static boolean match(VMClass a, VMClass b) {
|
||||
// TODO: in theory we should be able to just do an == comparison
|
||||
// here instead of recursively comparing array element types.
|
||||
// However, the VM currently can create multiple array classes for
|
||||
// the same element type. We should fix that so that there's only
|
||||
// ever one of each per classloader, eliminating the need for a
|
||||
// recursive comparison. See also the native implementation of
|
||||
// isAssignableFrom.
|
||||
if (a.arrayDimensions > 0) {
|
||||
return match(a.arrayElementClass, b.arrayElementClass);
|
||||
} else {
|
||||
return a == b;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean match(Class[] a, Class[] b) {
|
||||
if (a.length == b.length) {
|
||||
for (int i = 0; i < a.length; ++i) {
|
||||
if (! match(toVMClass(a[i]), toVMClass(b[i]))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static VMMethod findMethod(ClassLoader loader,
|
||||
String class_,
|
||||
String name,
|
||||
String spec)
|
||||
throws ClassNotFoundException
|
||||
{
|
||||
VMClass c = SystemClassLoader.vmClass(loader.loadClass(class_));
|
||||
VMMethod[] methodTable = c.methodTable;
|
||||
if (methodTable != null) {
|
||||
link(c);
|
||||
|
||||
for (int i = 0; i < methodTable.length; ++i) {
|
||||
VMMethod m = methodTable[i];
|
||||
if (toString(m.name).equals(name) && toString(m.spec).equals(spec)) {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int findMethod(VMClass vmClass, String name,
|
||||
Class[] parameterTypes)
|
||||
{
|
||||
VMMethod[] methodTable = vmClass.methodTable;
|
||||
if (methodTable != null) {
|
||||
link(vmClass);
|
||||
|
||||
if (parameterTypes == null) {
|
||||
parameterTypes = new Class[0];
|
||||
}
|
||||
|
||||
for (int i = 0; i < methodTable.length; ++i) {
|
||||
VMMethod m = methodTable[i];
|
||||
if (toString(m.name).equals(name)
|
||||
&& match(parameterTypes, getParameterTypes(m)))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static int countMethods(VMClass vmClass, boolean publicOnly) {
|
||||
int count = 0;
|
||||
VMMethod[] methodTable = vmClass.methodTable;
|
||||
if (methodTable != null) {
|
||||
for (int i = 0, j = declaredMethodCount(vmClass); i < j; ++i) {
|
||||
VMMethod m = methodTable[i];
|
||||
if (((! publicOnly) || ((m.flags & Modifier.PUBLIC)) != 0)
|
||||
&& (! toString(m.name).startsWith("<")))
|
||||
{
|
||||
++ count;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public static Method[] getMethods(VMClass vmClass, boolean publicOnly) {
|
||||
Method[] array = new Method[countMethods(vmClass, publicOnly)];
|
||||
VMMethod[] methodTable = vmClass.methodTable;
|
||||
if (methodTable != null) {
|
||||
link(vmClass);
|
||||
|
||||
int ai = 0;
|
||||
for (int i = 0, j = declaredMethodCount(vmClass); i < j; ++i) {
|
||||
VMMethod m = methodTable[i];
|
||||
if (((! publicOnly) || ((m.flags & Modifier.PUBLIC) != 0))
|
||||
&& ! toString(m.name).startsWith("<"))
|
||||
{
|
||||
array[ai++] = makeMethod(SystemClassLoader.getClass(vmClass), i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
public static int countFields(VMClass vmClass, boolean publicOnly) {
|
||||
int count = 0;
|
||||
if (vmClass.fieldTable != null) {
|
||||
for (int i = 0; i < vmClass.fieldTable.length; ++i) {
|
||||
if ((! publicOnly)
|
||||
|| ((vmClass.fieldTable[i].flags & Modifier.PUBLIC))
|
||||
!= 0)
|
||||
{
|
||||
++ count;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public static Field[] getFields(VMClass vmClass, boolean publicOnly) {
|
||||
Field[] array = new Field[countFields(vmClass, publicOnly)];
|
||||
if (vmClass.fieldTable != null) {
|
||||
link(vmClass);
|
||||
|
||||
int ai = 0;
|
||||
for (int i = 0; i < vmClass.fieldTable.length; ++i) {
|
||||
if (((vmClass.fieldTable[i].flags & Modifier.PUBLIC) != 0)
|
||||
|| (! publicOnly))
|
||||
{
|
||||
array[ai++] = makeField(SystemClassLoader.getClass(vmClass), i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
public static Annotation getAnnotation(ClassLoader loader, Object[] a) {
|
||||
if (a[0] == null) {
|
||||
a[0] = Proxy.newProxyInstance
|
||||
(loader, new Class[] { (Class) a[1] },
|
||||
new AnnotationInvocationHandler(a));
|
||||
}
|
||||
return (Annotation) a[0];
|
||||
}
|
||||
|
||||
public static Object getAnnotationDefaultValue(ClassLoader loader,
|
||||
MethodAddendum addendum) {
|
||||
if (addendum == null) {
|
||||
return null;
|
||||
}
|
||||
byte[] annotationDefault = (byte[]) addendum.annotationDefault;
|
||||
if (annotationDefault == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return parseAnnotationValue(loader, addendum.pool,
|
||||
new ByteArrayInputStream(annotationDefault));
|
||||
} catch (IOException e) {
|
||||
AssertionError error = new AssertionError();
|
||||
error.initCause(e);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
private static int index(VMMethod m) {
|
||||
VMMethod[] table = m.class_.methodTable;
|
||||
for (int i = 0; i < table.length; ++i) {
|
||||
if (m == table[i]) return i;
|
||||
}
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
public static Method makeMethod(VMMethod m) {
|
||||
return makeMethod(SystemClassLoader.getClass(m.class_), index(m));
|
||||
}
|
||||
|
||||
public static ProtectionDomain getProtectionDomain(VMClass c) {
|
||||
CodeSource source = null;
|
||||
if (c.source != null) {
|
||||
try {
|
||||
source = new CodeSource
|
||||
(new URL(new String(c.source, 0, c.source.length - 1)),
|
||||
(Certificate[]) null);
|
||||
} catch (MalformedURLException ignored) { }
|
||||
}
|
||||
|
||||
Permissions p = new Permissions();
|
||||
p.add(new AllPermission());
|
||||
|
||||
return new ProtectionDomain(source, p);
|
||||
}
|
||||
|
||||
public static native Method makeMethod(Class c, int slot);
|
||||
|
||||
public static native Field makeField(Class c, int slot);
|
||||
|
||||
private static native void acquireClassLock();
|
||||
|
||||
private static native void releaseClassLock();
|
||||
|
||||
public static native String makeString(byte[] array, int offset, int length);
|
||||
}
|
5
sgx-jvm/avian/classpath/avian/Code.java
Normal file
5
sgx-jvm/avian/classpath/avian/Code.java
Normal file
@ -0,0 +1,5 @@
|
||||
package avian;
|
||||
|
||||
abstract class Code {
|
||||
// VM-visible fields in types.def
|
||||
}
|
242
sgx-jvm/avian/classpath/avian/ConstantPool.java
Normal file
242
sgx-jvm/avian/classpath/avian/ConstantPool.java
Normal file
@ -0,0 +1,242 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
import static avian.Stream.write1;
|
||||
import static avian.Stream.write2;
|
||||
import static avian.Stream.write4;
|
||||
|
||||
import java.util.List;
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ConstantPool {
|
||||
private static final int CONSTANT_Integer = 3;
|
||||
private static final int CONSTANT_Utf8 = 1;
|
||||
private static final int CONSTANT_String = 8;
|
||||
private static final int CONSTANT_Class = 7;
|
||||
private static final int CONSTANT_NameAndType = 12;
|
||||
private static final int CONSTANT_Fieldref = 9;
|
||||
private static final int CONSTANT_Methodref = 10;
|
||||
|
||||
public static int add(List<PoolEntry> pool, PoolEntry e) {
|
||||
int i = 0;
|
||||
for (PoolEntry existing: pool) {
|
||||
if (existing.equals(e)) {
|
||||
return i;
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
pool.add(e);
|
||||
return pool.size() - 1;
|
||||
}
|
||||
|
||||
public static int addInteger(List<PoolEntry> pool, int value) {
|
||||
return add(pool, new IntegerPoolEntry(value));
|
||||
}
|
||||
|
||||
public static int addUtf8(List<PoolEntry> pool, String value) {
|
||||
return add(pool, new Utf8PoolEntry(value));
|
||||
}
|
||||
|
||||
public static int addString(List<PoolEntry> pool, String value) {
|
||||
return add(pool, new StringPoolEntry(addUtf8(pool, value)));
|
||||
}
|
||||
|
||||
public static int addClass(List<PoolEntry> pool, String name) {
|
||||
return add(pool, new ClassPoolEntry(addUtf8(pool, name)));
|
||||
}
|
||||
|
||||
public static int addNameAndType(List<PoolEntry> pool,
|
||||
String name,
|
||||
String type)
|
||||
{
|
||||
return add(pool, new NameAndTypePoolEntry
|
||||
(addUtf8(pool, name),
|
||||
addUtf8(pool, type)));
|
||||
}
|
||||
|
||||
public static int addFieldRef(List<PoolEntry> pool,
|
||||
String className,
|
||||
String name,
|
||||
String spec)
|
||||
{
|
||||
return add(pool, new FieldRefPoolEntry
|
||||
(addClass(pool, className),
|
||||
addNameAndType(pool, name, spec)));
|
||||
}
|
||||
|
||||
public static int addMethodRef(List<PoolEntry> pool,
|
||||
String className,
|
||||
String name,
|
||||
String spec)
|
||||
{
|
||||
return add(pool, new MethodRefPoolEntry
|
||||
(addClass(pool, className),
|
||||
addNameAndType(pool, name, spec)));
|
||||
}
|
||||
|
||||
public interface PoolEntry {
|
||||
public void writeTo(OutputStream out) throws IOException;
|
||||
}
|
||||
|
||||
private static class IntegerPoolEntry implements PoolEntry {
|
||||
private final int value;
|
||||
|
||||
public IntegerPoolEntry(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void writeTo(OutputStream out) throws IOException {
|
||||
write1(out, CONSTANT_Integer);
|
||||
write4(out, value);
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return o instanceof IntegerPoolEntry
|
||||
&& ((IntegerPoolEntry) o).value == value;
|
||||
}
|
||||
}
|
||||
|
||||
private static class Utf8PoolEntry implements PoolEntry {
|
||||
private final String data;
|
||||
|
||||
public Utf8PoolEntry(String data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public void writeTo(OutputStream out) throws IOException {
|
||||
write1(out, CONSTANT_Utf8);
|
||||
byte[] bytes = data.getBytes();
|
||||
write2(out, bytes.length);
|
||||
out.write(bytes);
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return o instanceof Utf8PoolEntry
|
||||
&& ((Utf8PoolEntry) o).data.equals(data);
|
||||
}
|
||||
}
|
||||
|
||||
private static class StringPoolEntry implements PoolEntry {
|
||||
private final int valueIndex;
|
||||
|
||||
public StringPoolEntry(int valueIndex) {
|
||||
this.valueIndex = valueIndex;
|
||||
}
|
||||
|
||||
public void writeTo(OutputStream out) throws IOException {
|
||||
write1(out, CONSTANT_String);
|
||||
write2(out, valueIndex + 1);
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return o instanceof StringPoolEntry
|
||||
&& ((StringPoolEntry) o).valueIndex == valueIndex;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ClassPoolEntry implements PoolEntry {
|
||||
private final int nameIndex;
|
||||
|
||||
public ClassPoolEntry(int nameIndex) {
|
||||
this.nameIndex = nameIndex;
|
||||
}
|
||||
|
||||
public void writeTo(OutputStream out) throws IOException {
|
||||
write1(out, CONSTANT_Class);
|
||||
write2(out, nameIndex + 1);
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return o instanceof ClassPoolEntry
|
||||
&& ((ClassPoolEntry) o).nameIndex == nameIndex;
|
||||
}
|
||||
}
|
||||
|
||||
private static class NameAndTypePoolEntry implements PoolEntry {
|
||||
private final int nameIndex;
|
||||
private final int typeIndex;
|
||||
|
||||
public NameAndTypePoolEntry(int nameIndex, int typeIndex) {
|
||||
this.nameIndex = nameIndex;
|
||||
this.typeIndex = typeIndex;
|
||||
}
|
||||
|
||||
public void writeTo(OutputStream out) throws IOException {
|
||||
write1(out, CONSTANT_NameAndType);
|
||||
write2(out, nameIndex + 1);
|
||||
write2(out, typeIndex + 1);
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof NameAndTypePoolEntry) {
|
||||
NameAndTypePoolEntry other = (NameAndTypePoolEntry) o;
|
||||
return other.nameIndex == nameIndex && other.typeIndex == typeIndex;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class FieldRefPoolEntry implements PoolEntry {
|
||||
private final int classIndex;
|
||||
private final int nameAndTypeIndex;
|
||||
|
||||
public FieldRefPoolEntry(int classIndex, int nameAndTypeIndex) {
|
||||
this.classIndex = classIndex;
|
||||
this.nameAndTypeIndex = nameAndTypeIndex;
|
||||
}
|
||||
|
||||
public void writeTo(OutputStream out) throws IOException {
|
||||
write1(out, CONSTANT_Fieldref);
|
||||
write2(out, classIndex + 1);
|
||||
write2(out, nameAndTypeIndex + 1);
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof FieldRefPoolEntry) {
|
||||
FieldRefPoolEntry other = (FieldRefPoolEntry) o;
|
||||
return other.classIndex == classIndex
|
||||
&& other.nameAndTypeIndex == nameAndTypeIndex;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class MethodRefPoolEntry implements PoolEntry {
|
||||
private final int classIndex;
|
||||
private final int nameAndTypeIndex;
|
||||
|
||||
public MethodRefPoolEntry(int classIndex, int nameAndTypeIndex) {
|
||||
this.classIndex = classIndex;
|
||||
this.nameAndTypeIndex = nameAndTypeIndex;
|
||||
}
|
||||
|
||||
public void writeTo(OutputStream out) throws IOException {
|
||||
write1(out, CONSTANT_Methodref);
|
||||
write2(out, classIndex + 1);
|
||||
write2(out, nameAndTypeIndex + 1);
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof MethodRefPoolEntry) {
|
||||
MethodRefPoolEntry other = (MethodRefPoolEntry) o;
|
||||
return other.classIndex == classIndex
|
||||
&& other.nameAndTypeIndex == nameAndTypeIndex;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
327
sgx-jvm/avian/classpath/avian/Continuations.java
Normal file
327
sgx-jvm/avian/classpath/avian/Continuations.java
Normal file
@ -0,0 +1,327 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* This class provides methods to capture continuations and manage
|
||||
* control flow when calling continuations.
|
||||
*
|
||||
* <p>A continuation is a snapshot of a thread's call stack which can
|
||||
* be captured via <code>callWithCurrentContinuation</code> and later
|
||||
* restored any number of times. The program may restore this
|
||||
* snapshot by either feeding it a result (to be returned by
|
||||
* <code>callWithCurrentContinuation</code>) or feeding it an
|
||||
* exception (to be thrown by
|
||||
* <code>callWithCurrentContinuation</code>). Continuations may be
|
||||
* used to implement features such as coroutines, generators, and
|
||||
* cooperative multitasking.
|
||||
*
|
||||
* <p>This class provides two static methods,
|
||||
* <code>callWithCurrentContinuation</code> and
|
||||
* <code>dynamicWind</code>, with similar semantics to the Scheme
|
||||
* functions <code>call-with-current-continuation</code> and
|
||||
* <code>dynamic-wind</code>, respectively. In addition, we define
|
||||
* how continuations work with respect to native code, exceptions,
|
||||
* try/finally blocks, synchronized blocks, and multithreading.
|
||||
*
|
||||
* <h3>Continuations and Continuation Contexts</h3>
|
||||
*
|
||||
* <p>A continuation can be thought of as a singly-linked list of
|
||||
* stack frames representing the call trace, where the head of the
|
||||
* list is the frame of the method most recently called (i.e. the top
|
||||
* of the stack). However, this trace only extends as far as the most
|
||||
* recent chain of Java frames - it ends just prior to the most recent
|
||||
* native frame in the stack. The reason for this is that the VM
|
||||
* cannot, in general, safely capture and restore native frames.
|
||||
* Therefore, each call from native code to Java (including the
|
||||
* original invocation of <code>main(String[])</code> or
|
||||
* <code>Thread.run()</code>) represents a new continuation context in
|
||||
* which continuations may be captured, and these will only contain
|
||||
* frames from within that context.
|
||||
*
|
||||
* <p>Calling a continuation (i.e. feeding it a result or exception)
|
||||
* causes the current continuation to be replaced with the called
|
||||
* continuation. When the last method in this new continuation
|
||||
* returns, it returns to the native frame which created the current
|
||||
* context, which may or may not be the same as the context in which
|
||||
* that continuation was created.
|
||||
*
|
||||
* <p>We define the return type of a continuation context as the
|
||||
* return type of the first method called in that context. A
|
||||
* continuation may be called from a different context than the one in
|
||||
* which it was created, provided the return type of the latter is
|
||||
* compatible with the current context.
|
||||
*
|
||||
* <p>Given a thread executing in context "A" which wants to call a
|
||||
* continuation created in context "B", the following rules apply:
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li>If the return type of "A" is <code>void</code>, the return
|
||||
* type of "B" may be anything, including <code>void</code></li>
|
||||
*
|
||||
* <li>If the return type of "A" is a primitive type, the return
|
||||
* type of "B" must match exactly</li>
|
||||
*
|
||||
* <li>If the return type of "A" is an object type, that type must
|
||||
* be assignable from the return type of "B" (i.e. the latter must
|
||||
* either be the same as the former or a superclass or
|
||||
* superinterface of it)</li>
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* <p>A thread may call a continuation created by a different thread
|
||||
* provided the return types are compatible. Multiple threads may
|
||||
* safely call the same continuation simultaneously without
|
||||
* synchronization. Any attempt to call a continuation from a context
|
||||
* with an incompatible return type will throw an {@link
|
||||
* avian.IncompatibleContinuationException}.
|
||||
*
|
||||
* <h3>Winding, Unwinding, and Rewinding</h3>
|
||||
*
|
||||
* <p>Traditionally, Java provides one way to wind the execution stack
|
||||
* (method calls) and two ways to unwind it (normal returns and
|
||||
* exception unwinding). With continuations, we add a new way to
|
||||
* rewind the stack and a new way to unwind it.
|
||||
*
|
||||
* <p>The call stack of a continuation may share frames with other
|
||||
* continuations - in which case they share a common history. When
|
||||
* calling a continuation "B" from the current continuation "A", the
|
||||
* VM must unwind past any frames which are in "A" but not in "B" and
|
||||
* rewind past any frames in "B" but not in "A". During this
|
||||
* unwinding and rewinding, control may pass through synchronized and
|
||||
* try/finally blocks while going down the old stack and up the new
|
||||
* stack.
|
||||
*
|
||||
* <p>However, unlike the traditional processes of winding and
|
||||
* unwinding, the VM will ignore these blocks - monitors will not be
|
||||
* released or acquired and finally blocks will not execute. This is
|
||||
* by design. The purpose of such a block is to acquire a resource,
|
||||
* such as a file handle or monitor, once before executing a task and
|
||||
* release it after the task is finished, regardless of how often the
|
||||
* task might temporarily yield control to other continuations.
|
||||
*
|
||||
* <p>Alternatively, one might wish to acquire and release a resource
|
||||
* each time control (re)winds to or unwinds from a continuation,
|
||||
* respectively. In this case, one may use <code>dynamicWind</code>
|
||||
* to register functions which will run every time that frame is
|
||||
* passed, regardless of how the stack is wound or unwound.
|
||||
*/
|
||||
public class Continuations {
|
||||
private Continuations() { }
|
||||
|
||||
private static final ThreadLocal<Reset> latestReset = new ThreadLocal();
|
||||
|
||||
/**
|
||||
* Captures the current continuation, passing a reference to the
|
||||
* specified receiver.
|
||||
*
|
||||
* <p>This method will either return the result returned by
|
||||
* <code>receiver.call(Callback)</code>, propagate the exception
|
||||
* thrown by that method, return the result passed to the
|
||||
* handleResult(T) method of the continuation, or throw the
|
||||
* exception passed to the handleException(Throwable) method of the
|
||||
* continuation.
|
||||
*/
|
||||
public static native <T> T callWithCurrentContinuation
|
||||
(Function<Callback<T>,T> receiver) throws Exception;
|
||||
|
||||
/**
|
||||
* Calls the specified "before" and "after" tasks each time a
|
||||
* continuation containing the call is wound or unwound,
|
||||
* respectively.
|
||||
*
|
||||
* <p>This method first calls <code>before.run()</code>, then
|
||||
* <code>thunk.call()</code>, and finally <code>after.run()</code>,
|
||||
* returning the result of the second call. If
|
||||
* <code>before.run()</code> does not return normally, the second
|
||||
* and third calls will not happen. If <code>thunk.call()</code>
|
||||
* throws an exception, <code>after.run()</code>, will be called
|
||||
* before the exception is propagated.
|
||||
*
|
||||
* <p>If <code>thunk.call()</code> calls a continuation (directly or
|
||||
* via a subroutine) which does not include the current call to
|
||||
* <code>dynamicWind</code>, <code>after.run()</code> will be called
|
||||
* before control passes to that continuation. If this call throws
|
||||
* an exception, the exception will propagate to the current caller
|
||||
* of <code>dynamicWind</code>.
|
||||
*
|
||||
* <p>If <code>thunk.call()</code> creates a continuation which is
|
||||
* later called from a continuation which does not include the
|
||||
* current call to <code>dynamicWind</code>,
|
||||
* <code>before.run()</code> will be called before control passes to
|
||||
* that continuation. As above, if this call throws an exception,
|
||||
* the exception will propagate to the current caller of
|
||||
* <code>dynamicWind</code>.
|
||||
*/
|
||||
public static <T> T dynamicWind(Runnable before,
|
||||
Callable<T> thunk,
|
||||
Runnable after)
|
||||
throws Exception
|
||||
{
|
||||
UnwindResult result = dynamicWind2(before, thunk, after);
|
||||
if (result.continuation != null) {
|
||||
after.run();
|
||||
if (result.exception != null) {
|
||||
result.continuation.handleException(result.exception);
|
||||
} else {
|
||||
result.continuation.handleResult(result.result);
|
||||
}
|
||||
throw new AssertionError();
|
||||
} else {
|
||||
return (T) result.result;
|
||||
}
|
||||
}
|
||||
|
||||
public static <B,C> C reset(final Callable<B> thunk) throws Exception {
|
||||
final Reset reset = new Reset(latestReset.get());
|
||||
latestReset.set(reset);
|
||||
try {
|
||||
Object result = callWithCurrentContinuation
|
||||
(new Function<Callback<Object>,Object>() {
|
||||
public Object call(Callback continuation) throws Exception {
|
||||
reset.continuation = continuation;
|
||||
return thunk.call();
|
||||
}
|
||||
});
|
||||
|
||||
while (true) {
|
||||
Cell<Function> shift = reset.shifts;
|
||||
if (shift != null) {
|
||||
reset.shifts = shift.next;
|
||||
result = shift.value.call(result);
|
||||
} else {
|
||||
return (C) result;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
latestReset.set(reset.next);
|
||||
}
|
||||
}
|
||||
|
||||
public static <A,B,C> A shift
|
||||
(final Function<Function<A,B>,C> receiver)
|
||||
throws Exception
|
||||
{
|
||||
return (A) callWithCurrentContinuation
|
||||
(new Function<Callback<Object>,Object>() {
|
||||
public Object call(final Callback continuation) {
|
||||
final Reset reset = latestReset.get();
|
||||
reset.shifts = new Cell(new Function() {
|
||||
public Object call(Object ignored) throws Exception {
|
||||
return receiver.call
|
||||
(new Function() {
|
||||
public Object call(final Object argument)
|
||||
throws Exception
|
||||
{
|
||||
return callWithCurrentContinuation
|
||||
(new Function<Callback<Object>,Object>() {
|
||||
public Object call
|
||||
(final Callback shiftContinuation)
|
||||
throws Exception
|
||||
{
|
||||
reset.shifts = new Cell
|
||||
(new Function() {
|
||||
public Object call(Object result)
|
||||
throws Exception
|
||||
{
|
||||
shiftContinuation.handleResult(result);
|
||||
throw new AssertionError();
|
||||
}
|
||||
},
|
||||
reset.shifts);
|
||||
|
||||
continuation.handleResult(argument);
|
||||
throw new AssertionError();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void handleException(Throwable exception) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}, reset.shifts);
|
||||
|
||||
reset.continuation.handleResult(null);
|
||||
throw new AssertionError();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static native UnwindResult dynamicWind2(Runnable before,
|
||||
Callable thunk,
|
||||
Runnable after)
|
||||
throws Exception;
|
||||
|
||||
private static UnwindResult wind(Runnable before,
|
||||
Callable thunk,
|
||||
Runnable after)
|
||||
throws Exception
|
||||
{
|
||||
before.run();
|
||||
|
||||
try {
|
||||
return new UnwindResult(null, thunk.call(), null);
|
||||
} finally {
|
||||
after.run();
|
||||
}
|
||||
}
|
||||
|
||||
private static void rewind(Runnable before,
|
||||
Callback continuation,
|
||||
Object result,
|
||||
Throwable exception)
|
||||
throws Exception
|
||||
{
|
||||
before.run();
|
||||
|
||||
if (exception != null) {
|
||||
continuation.handleException(exception);
|
||||
} else {
|
||||
continuation.handleResult(result);
|
||||
}
|
||||
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
private static class Continuation<T> implements Callback<T> {
|
||||
public native void handleResult(T result);
|
||||
public native void handleException(Throwable exception);
|
||||
}
|
||||
|
||||
private static class UnwindResult {
|
||||
public final Continuation continuation;
|
||||
public final Object result;
|
||||
public final Throwable exception;
|
||||
|
||||
public UnwindResult(Continuation continuation, Object result,
|
||||
Throwable exception)
|
||||
{
|
||||
this.continuation = continuation;
|
||||
this.result = result;
|
||||
this.exception = exception;
|
||||
}
|
||||
}
|
||||
|
||||
private static class Reset {
|
||||
public Callback continuation;
|
||||
public final Reset next;
|
||||
public Cell<Function> shifts;
|
||||
|
||||
public Reset(Reset next) {
|
||||
this.next = next;
|
||||
}
|
||||
}
|
||||
}
|
310
sgx-jvm/avian/classpath/avian/Data.java
Normal file
310
sgx-jvm/avian/classpath/avian/Data.java
Normal file
@ -0,0 +1,310 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.AbstractSet;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Collections;
|
||||
|
||||
public class Data {
|
||||
public static int nextPowerOfTwo(int n) {
|
||||
int r = 1;
|
||||
while (r < n) r <<= 1;
|
||||
return r;
|
||||
}
|
||||
|
||||
public static <V> boolean equal(V a, V b) {
|
||||
return a == null ? b == null : a.equals(b);
|
||||
}
|
||||
|
||||
public static <T> T[] toArray(Collection collection, T[] array) {
|
||||
Class c = array.getClass().getComponentType();
|
||||
|
||||
if (array.length < collection.size()) {
|
||||
array = (T[]) java.lang.reflect.Array.newInstance(c, collection.size());
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (Object o: collection) {
|
||||
if (c.isInstance(o)) {
|
||||
array[i++] = (T) o;
|
||||
} else {
|
||||
throw new ArrayStoreException();
|
||||
}
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
public static String toString(Collection c) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("[");
|
||||
for (Iterator it = c.iterator(); it.hasNext();) {
|
||||
sb.append(it.next());
|
||||
if (it.hasNext()) {
|
||||
sb.append(",");
|
||||
}
|
||||
}
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String toString(Map m) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("{");
|
||||
for (Iterator<Entry> it = m.entrySet().iterator(); it.hasNext();) {
|
||||
Entry e = it.next();
|
||||
sb.append(e.getKey())
|
||||
.append("=")
|
||||
.append(e.getValue());
|
||||
if (it.hasNext()) {
|
||||
sb.append(",");
|
||||
}
|
||||
}
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public interface EntryMap<K,V> {
|
||||
public int size();
|
||||
|
||||
public Entry<K,V> find(Object key);
|
||||
|
||||
public Entry<K,V> remove(Object key);
|
||||
|
||||
public void clear();
|
||||
|
||||
public Iterator<Entry<K,V>> iterator();
|
||||
}
|
||||
|
||||
public static class EntrySet<K, V> extends AbstractSet<Entry<K, V>> {
|
||||
private final EntryMap<K, V> map;
|
||||
|
||||
public EntrySet(EntryMap<K, V> map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return map.size();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return map.size() == 0;
|
||||
}
|
||||
|
||||
public boolean contains(Object o) {
|
||||
return (o instanceof Entry<?,?>)
|
||||
&& map.find(((Entry<?,?>)o).getKey()) != null;
|
||||
}
|
||||
|
||||
public boolean add(Entry<K, V> e) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public boolean remove(Object o) {
|
||||
return (o instanceof Entry<?,?>)
|
||||
&& map.remove(((Entry<?,?>) o).getKey()) != null;
|
||||
}
|
||||
|
||||
public boolean remove(Entry<K, V> e) {
|
||||
return map.remove(e.getKey()) != null;
|
||||
}
|
||||
|
||||
public Object[] toArray() {
|
||||
return toArray(new Object[size()]);
|
||||
}
|
||||
|
||||
public <T> T[] toArray(T[] array) {
|
||||
return Data.toArray(this, array);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
map.clear();
|
||||
}
|
||||
|
||||
public Iterator<Entry<K, V>> iterator() {
|
||||
return map.iterator();
|
||||
}
|
||||
}
|
||||
|
||||
public static class KeySet<K> extends AbstractSet<K> {
|
||||
private final EntryMap<K, ?> map;
|
||||
|
||||
public KeySet(EntryMap<K, ?> map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return map.size();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return map.size() == 0;
|
||||
}
|
||||
|
||||
public boolean contains(Object key) {
|
||||
return map.find(key) != null;
|
||||
}
|
||||
|
||||
public boolean add(K key) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public boolean remove(Object key) {
|
||||
return map.remove(key) != null;
|
||||
}
|
||||
|
||||
public Object[] toArray() {
|
||||
return toArray(new Object[size()]);
|
||||
}
|
||||
|
||||
public <T> T[] toArray(T[] array) {
|
||||
return Data.toArray(this, array);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
map.clear();
|
||||
}
|
||||
|
||||
public Iterator<K> iterator() {
|
||||
return new KeyIterator(map.iterator());
|
||||
}
|
||||
}
|
||||
|
||||
public static class Values<K, V> implements Collection<V> {
|
||||
private final EntryMap<K, V> map;
|
||||
|
||||
public Values(EntryMap<K, V> map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return map.size();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return map.size() == 0;
|
||||
}
|
||||
|
||||
public boolean contains(Object value) {
|
||||
for (Iterator<Entry<K, V>> it = map.iterator(); it.hasNext();) {
|
||||
if (equal(it.next().getValue(), value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean containsAll(Collection<?> c) {
|
||||
if (c == null) {
|
||||
throw new NullPointerException("collection is null");
|
||||
}
|
||||
|
||||
for (Iterator<?> it = c.iterator(); it.hasNext();) {
|
||||
if (! contains(it.next())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean add(V value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public boolean addAll(Collection<? extends V> collection) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public boolean remove(Object value) {
|
||||
for (Iterator<Entry<K, V>> it = map.iterator();
|
||||
it.hasNext();)
|
||||
{
|
||||
if (equal(it.next().getValue(), value)) {
|
||||
it.remove();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean removeAll(Collection<?> c) {
|
||||
boolean changed = false;
|
||||
for (Iterator<Entry<K, V>> it = map.iterator(); it.hasNext();) {
|
||||
if (c.contains(it.next().getValue())) {
|
||||
it.remove();
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
public Object[] toArray() {
|
||||
return toArray(new Object[size()]);
|
||||
}
|
||||
|
||||
public <T> T[] toArray(T[] array) {
|
||||
return Data.toArray(this, array);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
map.clear();
|
||||
}
|
||||
|
||||
public Iterator<V> iterator() {
|
||||
return new ValueIterator(map.iterator());
|
||||
}
|
||||
}
|
||||
|
||||
public static class KeyIterator<K, V> implements Iterator<K> {
|
||||
private final Iterator<Entry<K, V>> it;
|
||||
|
||||
public KeyIterator(Iterator<Entry<K, V>> it) {
|
||||
this.it = it;
|
||||
}
|
||||
|
||||
public K next() {
|
||||
return it.next().getKey();
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return it.hasNext();
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ValueIterator<K, V> implements Iterator<V> {
|
||||
private final Iterator<Entry<K, V>> it;
|
||||
|
||||
public ValueIterator(Iterator<Entry<K, V>> it) {
|
||||
this.it = it;
|
||||
}
|
||||
|
||||
public V next() {
|
||||
return it.next().getValue();
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return it.hasNext();
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
13
sgx-jvm/avian/classpath/avian/FieldAddendum.java
Normal file
13
sgx-jvm/avian/classpath/avian/FieldAddendum.java
Normal file
@ -0,0 +1,13 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
public class FieldAddendum extends Addendum { }
|
992
sgx-jvm/avian/classpath/avian/FormatString.java
Normal file
992
sgx-jvm/avian/classpath/avian/FormatString.java
Normal file
@ -0,0 +1,992 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.IllegalFormatException;
|
||||
import java.util.List;
|
||||
|
||||
// ------------------------------------------------------------------------- //
|
||||
// things that must be done in order to call this semi-complete:
|
||||
// ------------------------------------------------------------------------- //
|
||||
// * get the date formatter working for individual fields at a minimum
|
||||
// ------------------------------------------------------------------------- //
|
||||
|
||||
/**
|
||||
* A Java flavored printf for classpath-challenged JVMs.
|
||||
*
|
||||
* Each instance of this class is a threadsafe pre-parsed format pattern. Refer
|
||||
* to the very detailed class description of java.util.Formatter in the OpenJDK
|
||||
* API documentation for an explanation of the supported formats.
|
||||
*
|
||||
* Should be easily portable to other Java runtimes that do not include the
|
||||
* printf functionality that was introduced in Java 5.
|
||||
*
|
||||
* Aims to be lightweight and reasonably fast, and provide reasonably complete
|
||||
* API compatibility with the OpenJDK implementation. To clarify what
|
||||
* "reasonably complete" means in this context, this implementation should
|
||||
* accept any valid format string that the OpenJDK version accepts. However,
|
||||
* it should not be relied upon to throw an Exception for every format pattern
|
||||
* that the OpenJDK implementation does.
|
||||
*
|
||||
* If your program's behavior relies on the side effects from an Exception
|
||||
* being thrown for an invalid format string, this might not be for you.
|
||||
*
|
||||
* Perhaps more troubling is the fact that the correct localization of numbers
|
||||
* and temporal values is barely even attempted, even though the parser accepts
|
||||
* the flags without even a warning. However, now you have been warned.
|
||||
*
|
||||
* @author bcg
|
||||
*/
|
||||
public final class FormatString {
|
||||
|
||||
/** Parses a format string and returns a compiled representation of it. */
|
||||
public static final FormatString compile(String fmt) {
|
||||
return new FormatString(fmt);
|
||||
}
|
||||
|
||||
/** The original string value that was parsed */
|
||||
public String source() {
|
||||
return _source;
|
||||
}
|
||||
|
||||
/** Processes the supplied arguments through the compiled format string
|
||||
and returns the result as a String. */
|
||||
public final String format(Object... args) {
|
||||
final StringBuilder bldr = new StringBuilder();
|
||||
try {
|
||||
format(bldr, args);
|
||||
return bldr.toString();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(
|
||||
"Should not get IOException when writing to StringBuilder", e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/** Processes the supplied arguments through the compiled format string
|
||||
and writes the result of each component directly to an Appendable */
|
||||
public final void format(final Appendable a, Object... fmt_args)
|
||||
throws IOException {
|
||||
final Object[] args = fmt_args != null ? fmt_args : new Object[0];
|
||||
int cntr = 0;
|
||||
for (final FmtCmpnt cmp : _components) {
|
||||
if (cmp._conversion == CONV_LITRL) {
|
||||
a.append(cmp._source);
|
||||
continue;
|
||||
}
|
||||
final Object arg;
|
||||
if (!acceptsArgument(cmp._conversion)) {
|
||||
arg = null;
|
||||
} else {
|
||||
final int index = cmp._argument_index;
|
||||
switch (index) {
|
||||
case AIDX_NONE:
|
||||
if ((cntr) >= args.length) {
|
||||
throw new IllegalFormatException(
|
||||
"Format specified at least " + (cntr+1) +
|
||||
" arguments, but " + cntr + " were supplied."
|
||||
);
|
||||
}
|
||||
arg = args[cntr++];
|
||||
break;
|
||||
case AIDX_PREV:
|
||||
arg = args[cntr];
|
||||
break;
|
||||
default:
|
||||
if (index < 1) {
|
||||
throw new IllegalArgumentException();
|
||||
} else if (index > args.length) {
|
||||
throw new IllegalArgumentException();
|
||||
} else {
|
||||
arg = args[index - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
convert(a, arg, cmp._conversion, cmp._flags, cmp._width, cmp._precision);
|
||||
}
|
||||
}
|
||||
|
||||
//- conversions
|
||||
static final byte CONV_LITRL = 0x0;
|
||||
static final byte CONV_NLINE = 0x1;
|
||||
static final byte CONV_PRCNT = 0x2;
|
||||
static final byte CONV_BOOLN = 0x3;
|
||||
static final byte CONV_DTIME = 0x4;
|
||||
static final byte CONV_STRNG = 0x5;
|
||||
static final byte CONV_HCODE = 0x6;
|
||||
static final byte CONV_CHRCT = 0x7;
|
||||
static final byte CONV_DECML = 0x8;
|
||||
static final byte CONV_OCTAL = 0x9;
|
||||
static final byte CONV_HXDEC = 0xA;
|
||||
static final byte CONV_CPSCI = 0xB;
|
||||
static final byte CONV_GNSCI = 0xC;
|
||||
static final byte CONV_FLOAT = 0xD;
|
||||
static final byte CONV_HXEXP = 0xE;
|
||||
|
||||
//- format component flags
|
||||
static final byte FLAG_FORCE_UPPER_CASE = (byte)(1<<7);
|
||||
static final byte FLAG_NEGATIVES_IN_PARENS = (byte)(1<<6); // ('(')
|
||||
static final byte FLAG_GROUPING_SEPARATORS = (byte)(1<<5); // (',')
|
||||
static final byte FLAG_LEADING_ZERO_PADDED = (byte)(1<<4); // ('0')
|
||||
static final byte FLAG_LEADING_SPACE_PADDED = (byte)(1<<3); // (' ')
|
||||
static final byte FLAG_ALWAYS_INCLUDES_SIGN = (byte)(1<<2); // ('+')
|
||||
static final byte FLAG_ALTERNATE_FORM = (byte)(1<<1); // ('#')
|
||||
static final byte FLAG_LEFT_JUSTIFIED = (byte)(1<<0); // ('-')
|
||||
|
||||
//- conversion capability flags
|
||||
static final byte CFLG_WDTH_SUPPRT = CONV_PRCNT;
|
||||
static final byte CFLG_ACCEPTS_ARG = CONV_BOOLN;
|
||||
static final byte CFLG_NUMERIC_VAL = CONV_DECML;
|
||||
static final byte CFLG_PREC_SUPPRT = CONV_STRNG;
|
||||
|
||||
//- special argument indices
|
||||
static final int AIDX_PREV = -1;
|
||||
static final int AIDX_NONE = 0;
|
||||
|
||||
/** the original serialized format string */
|
||||
private final String _source;
|
||||
|
||||
/** array of components parsed from the source string */
|
||||
private final FmtCmpnt[] _components;
|
||||
|
||||
/*/ keeping this private for now to encourage access through the static
|
||||
compile method, which might allow caching format string instances if it
|
||||
turns out there is an advantage to that. /*/
|
||||
/** Constructor */
|
||||
private FormatString(final String fmt) {
|
||||
this._source = fmt;
|
||||
final List<FmtCmpnt> cmps = new ArrayList<FmtCmpnt>();
|
||||
for ( int i = 0; (i = next(fmt, cmps, i)) > -1; );
|
||||
this._components = cmps.toArray(new FmtCmpnt[cmps.size()]);
|
||||
}
|
||||
|
||||
/** Iterates over the tokens in an input string to extract the components */
|
||||
private static final int next(
|
||||
final String fmt, final List<FmtCmpnt> cmps, final int startIndex) {
|
||||
final int strln = fmt.length();
|
||||
if (startIndex >= strln) {
|
||||
return -1;
|
||||
}
|
||||
final char c = fmt.charAt(startIndex);
|
||||
if (c == '%') {
|
||||
// this is the start of a specifier
|
||||
final FmtSpecBldr bldr = new FmtSpecBldr();
|
||||
for (int i = startIndex + 1; i < strln; i++) {
|
||||
final char ch = fmt.charAt(i);
|
||||
final FmtCmpnt cmp = bldr.append(ch);
|
||||
if (cmp != null) {
|
||||
cmps.add(cmp);
|
||||
return (i+1);
|
||||
}
|
||||
}
|
||||
throw new IllegalFormatException("Incomplete specifier at end of fmt");
|
||||
} else {
|
||||
// this is the start of a literal
|
||||
final StringBuilder literal = new StringBuilder();
|
||||
literal.append(c);
|
||||
for (int i = startIndex + 1; i < strln; i++) {
|
||||
final char ch = fmt.charAt(i);
|
||||
// write the current buffer if the next character starts a specifier
|
||||
if (ch == '%') {
|
||||
final FmtCmpnt cmp = new FmtCmpnt(literal.toString());
|
||||
cmps.add(cmp);
|
||||
return i;
|
||||
}
|
||||
literal.append(ch);
|
||||
}
|
||||
// write the current buffer if the end of the format has been reached
|
||||
final FmtCmpnt cmp = new FmtCmpnt(literal.toString());
|
||||
cmps.add(cmp);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/** Checks a flag byte to see if a given flag is set. Only FLAG_* constants
|
||||
from the enclosing class should be passed in for toCheck... otherwise the
|
||||
behavior is undefined. */
|
||||
static final boolean checkFlag(final byte flags, final byte toCheck) {
|
||||
return (flags & toCheck) != 0;
|
||||
}
|
||||
|
||||
/** Checks if a given conversion accepts(requires) an argument. Only the CONV_
|
||||
flags from the enclosing class should be passed in, otherwise the result
|
||||
of this method is undefined as should not be used. */
|
||||
static final boolean acceptsArgument(final byte conversion) {
|
||||
return conversion >= CFLG_ACCEPTS_ARG;
|
||||
}
|
||||
|
||||
/** Checks if a given conversion allows specifying a precision. Only the CONV_
|
||||
flags from the enclosing class should be passed in, otherwise the result
|
||||
of this method is undefined as should not be used. */
|
||||
static final boolean precisionSupported(final byte conversion) {
|
||||
return conversion >= CFLG_PREC_SUPPRT;
|
||||
}
|
||||
|
||||
/** Checks if a given conversion allows specifying a width. Only the CONV_
|
||||
flags from the enclosing class should be passed in, otherwise the result
|
||||
of this method is undefined and should not be trusted. */
|
||||
static final boolean widthSupported(final byte conversion) {
|
||||
return conversion >= CFLG_WDTH_SUPPRT;
|
||||
}
|
||||
|
||||
/** Checks if a given conversion expects a numeric value. Only the CONV_
|
||||
flags from the enclosing class should be passed in, otherwise the result
|
||||
of this method is undefined and should not be trusted. */
|
||||
static final boolean isNumeric(final byte conversion) {
|
||||
return conversion >= CFLG_NUMERIC_VAL;
|
||||
}
|
||||
|
||||
/** The newline character for the current platform. */
|
||||
static final String NEWLINE = System.getProperty("line.separator");
|
||||
|
||||
/** Performs conversion on the supplied argument */
|
||||
static final void convert(
|
||||
final Appendable appendable,
|
||||
final Object arg,
|
||||
final byte conversion,
|
||||
final byte flags,
|
||||
final int width,
|
||||
final int precision) throws IOException {
|
||||
int radix = 0;
|
||||
switch (conversion) {
|
||||
case CONV_LITRL:
|
||||
throw new IllegalArgumentException("cannot convert a literal");
|
||||
case CONV_NLINE:
|
||||
appendable.append(NEWLINE);
|
||||
return;
|
||||
case CONV_PRCNT:
|
||||
convertPercent(appendable, arg, flags, width, precision);
|
||||
return;
|
||||
case CONV_BOOLN:
|
||||
convertBoolean(appendable, arg, flags, width, precision);
|
||||
return;
|
||||
case CONV_DTIME:
|
||||
convertDate(appendable, arg, flags, width, precision);
|
||||
return;
|
||||
case CONV_STRNG:
|
||||
convertString(appendable, arg, flags, width, precision);
|
||||
return;
|
||||
case CONV_HCODE:
|
||||
convertHashcode(appendable, arg, flags, width, precision);
|
||||
return;
|
||||
case CONV_CHRCT:
|
||||
convertChar(appendable, arg, flags, width, precision);
|
||||
return;
|
||||
case CONV_DECML: if (radix == 0) { radix = 10; };
|
||||
case CONV_OCTAL: if (radix == 0) { radix = 8; };
|
||||
case CONV_HXDEC: if (radix == 0) { radix = 16; };
|
||||
if (arg instanceof Long) {
|
||||
convertLong(appendable, (Long) arg, flags, width, precision, radix);
|
||||
} else {
|
||||
convertInteger(appendable, arg, flags, width, precision, radix);
|
||||
}
|
||||
return;
|
||||
case CONV_CPSCI:
|
||||
case CONV_GNSCI:
|
||||
case CONV_FLOAT:
|
||||
case CONV_HXEXP:
|
||||
convertFloat(appendable, arg, flags, width, precision, 10);
|
||||
return;
|
||||
}
|
||||
throw new IllegalStateException("not implemented: " + conversion);
|
||||
}
|
||||
|
||||
static void convertPercent(
|
||||
final Appendable a,
|
||||
final Object arg,
|
||||
final byte flags,
|
||||
final int width,
|
||||
final int precision) throws IOException {
|
||||
final String val = "%";
|
||||
appendify(a, val, flags, width, precision);
|
||||
}
|
||||
|
||||
static void convertDate(
|
||||
final Appendable a,
|
||||
final Object arg,
|
||||
final byte flags,
|
||||
final int width,
|
||||
final int precision) throws IOException {
|
||||
final String val = (arg == null) ? "null" : arg.toString();
|
||||
appendify(a, val, flags, width, precision);
|
||||
}
|
||||
|
||||
static void convertString(
|
||||
final Appendable a,
|
||||
final Object arg,
|
||||
final byte flags,
|
||||
final int width,
|
||||
final int precision) throws IOException {
|
||||
final String val = (arg == null) ? "null" : arg.toString();
|
||||
appendify(a, val, flags, width, precision);
|
||||
}
|
||||
|
||||
static void convertHashcode(
|
||||
final Appendable a,
|
||||
final Object arg,
|
||||
final byte flags,
|
||||
final int width,
|
||||
final int precision) throws IOException {
|
||||
final String val = (arg == null)
|
||||
? "null"
|
||||
: Integer.toHexString(arg.hashCode());
|
||||
appendify(a, val, flags, width, precision);
|
||||
}
|
||||
|
||||
static void convertBoolean(
|
||||
final Appendable a,
|
||||
final Object arg,
|
||||
final byte flags,
|
||||
final int width,
|
||||
final int precision) throws IOException {
|
||||
final String val;
|
||||
if (arg == null) {
|
||||
val = "false";
|
||||
} else if (arg instanceof Boolean) {
|
||||
val = String.valueOf(arg);
|
||||
} else {
|
||||
val = "true";
|
||||
}
|
||||
appendify(a, val, flags, width, precision);
|
||||
}
|
||||
|
||||
static void convertChar(
|
||||
final Appendable a,
|
||||
final Object arg,
|
||||
final byte flags,
|
||||
final int width,
|
||||
final int precision) throws IOException {
|
||||
final String val;
|
||||
if (arg instanceof Character) {
|
||||
val = ((Character) arg).toString();
|
||||
} else if ( arg instanceof Byte ||
|
||||
arg instanceof Short ||
|
||||
arg instanceof Integer ){
|
||||
final int codePoint = ((Number) arg).intValue();
|
||||
if (codePoint >= 0 && codePoint <= 0x10FFFF) { //<-- isValidCodePoint()?
|
||||
val = new String(Character.toChars(codePoint));
|
||||
} else {
|
||||
throw new IllegalFormatException("Invalid code point: " + arg);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalFormatException("Cannot do char conversion: " + arg);
|
||||
}
|
||||
appendify(a, val, flags, width, precision);
|
||||
}
|
||||
|
||||
// FIXME: this is broken for octal formats with negative values
|
||||
static void convertLong(
|
||||
final Appendable a,
|
||||
final Long arg,
|
||||
final byte flags,
|
||||
final int width,
|
||||
final int precision,
|
||||
final int radix) throws IOException {
|
||||
final String val;
|
||||
final Long n = arg;
|
||||
final long longValue = n.longValue();
|
||||
if (radix == 10 || longValue > -1) {
|
||||
val = Long.toString(longValue, radix);
|
||||
} else {
|
||||
final long upper = 0xFFFFFFFFL&(longValue>>31);
|
||||
final long lower = 0xFFFFFFFFL&(longValue);
|
||||
val = Long.toString(upper, radix) + Long.toString(lower, radix);
|
||||
}
|
||||
appendify(a, val, flags, width, precision);
|
||||
}
|
||||
|
||||
static void convertInteger(
|
||||
final Appendable a,
|
||||
final Object arg,
|
||||
final byte flags,
|
||||
final int width,
|
||||
final int precision,
|
||||
final int radix) throws IOException {
|
||||
final String val;
|
||||
final Number n = (Number) arg;
|
||||
final long longValue = n.longValue();
|
||||
final long modifier;
|
||||
if (arg instanceof Integer) modifier = 0xFFFFFFFFL+1; else
|
||||
if (arg instanceof Short) modifier = 0xFFFFL+1; else
|
||||
if (arg instanceof Byte) modifier = 0xFFL+1;
|
||||
else throw new IllegalFormatException(
|
||||
"not an integer number: " + (arg != null ? arg.getClass() : null)
|
||||
);
|
||||
if (radix != 10 && longValue < 0) {
|
||||
val = Long.toString(longValue + modifier, radix);
|
||||
} else {
|
||||
val = Long.toString(longValue, radix);
|
||||
}
|
||||
appendify(a, val, flags, width, precision);
|
||||
}
|
||||
|
||||
// FIXME: I'm lazy, so hexidecimal exponential isn't implemented, sorry - bcg
|
||||
static void convertFloat(
|
||||
final Appendable a,
|
||||
final Object arg,
|
||||
final byte flags,
|
||||
final int width,
|
||||
final int precision,
|
||||
final int radix) throws IOException {
|
||||
final String val;
|
||||
final Number n = (Number) arg;
|
||||
if (arg instanceof Float) {
|
||||
val = Float.toString(n.floatValue());
|
||||
} else if (arg instanceof Double) {
|
||||
val = Double.toString(n.doubleValue());
|
||||
} else {
|
||||
throw new IllegalFormatException(
|
||||
"not a floating point number: " + (arg != null ? arg.getClass() : null)
|
||||
);
|
||||
}
|
||||
appendify(a, val, flags, width, precision);
|
||||
}
|
||||
|
||||
static void appendify(
|
||||
final Appendable a,
|
||||
final String val,
|
||||
final byte flags,
|
||||
final int width,
|
||||
final int precision) throws IOException {
|
||||
String result = val;
|
||||
if (checkFlag(flags, FLAG_FORCE_UPPER_CASE)) {
|
||||
result = result.toUpperCase();
|
||||
}
|
||||
// TODO: implement other flags
|
||||
// (+) always include sign
|
||||
// (,) grouping separators
|
||||
// (() negatives in parentheses
|
||||
if (precision > 0) {
|
||||
// FIXME: this behavior should be different for floating point numbers
|
||||
final int difference = result.length() - precision;
|
||||
if (difference > 0) {
|
||||
result = result.substring(0, precision);
|
||||
a.append(result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (width > 0) {
|
||||
final int difference = width - result.length();
|
||||
final boolean leftJustified = checkFlag(flags, FLAG_LEFT_JUSTIFIED);
|
||||
if (!leftJustified && difference > 0) {
|
||||
char fill = checkFlag(flags, FLAG_LEADING_ZERO_PADDED) ? '0' : ' ';
|
||||
fill(a, difference, fill);
|
||||
}
|
||||
a.append(result);
|
||||
if (leftJustified && difference > 0) {
|
||||
fill(a, difference, ' ');
|
||||
}
|
||||
return;
|
||||
}
|
||||
a.append(result);
|
||||
}
|
||||
|
||||
private static void fill(Appendable a, int num, char c) throws IOException {
|
||||
while (num > 0) {
|
||||
a.append(c);
|
||||
num--;
|
||||
}
|
||||
}
|
||||
|
||||
/** Represents a single chunk of the format string, either a literal or one of
|
||||
the specifiers documented in OpenJDK's javadoc for java.util.Formatter.
|
||||
This struct is immutable so can be safely shared across threads. */
|
||||
private static final class FmtCmpnt {
|
||||
|
||||
private final String _source;
|
||||
private final byte _conversion;
|
||||
private final int _argument_index;
|
||||
private final int _width;
|
||||
private final int _precision;
|
||||
private final byte _flags;
|
||||
|
||||
private FmtCmpnt(final String literal) {
|
||||
this(literal, CONV_LITRL, 0, 0, 0, (byte)0);
|
||||
}
|
||||
private FmtCmpnt(
|
||||
final String src,
|
||||
final byte conversion,
|
||||
final int argumentIndex,
|
||||
final int width,
|
||||
final int precision,
|
||||
final byte flags) {
|
||||
this._source = src;
|
||||
this._conversion = conversion;
|
||||
this._argument_index = argumentIndex;
|
||||
this._width = width;
|
||||
this._precision = precision;
|
||||
this._flags = flags;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("{ ")
|
||||
.append("source = '").append(_source).append("', ")
|
||||
.append("conversion = ").append(_conversion).append(", ")
|
||||
.append("flags = ").append(Byte.toString(_flags, 2)).append(", ")
|
||||
.append("arg_index = ").append(_argument_index).append(", ")
|
||||
.append("width = ").append(_width).append(", ")
|
||||
.append("precision = ").append(_precision).append(", ")
|
||||
.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class for parsing a stream of characters into FmtCmpnt objects.
|
||||
*/
|
||||
private static final class FmtSpecBldr {
|
||||
|
||||
private StringBuilder _source;
|
||||
private byte _conversion;
|
||||
private int _argument_index;
|
||||
private int _width;
|
||||
private int _precision;
|
||||
private byte _flags;
|
||||
|
||||
private FmtSpecBldr() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
private final void init() {
|
||||
_argument_index =
|
||||
_width =
|
||||
_precision =
|
||||
_conversion =
|
||||
_flags = 0;
|
||||
_source = null;
|
||||
}
|
||||
|
||||
private final FmtCmpnt build() {
|
||||
final FmtCmpnt result = new FmtCmpnt(
|
||||
_source.toString(),
|
||||
_conversion,
|
||||
_argument_index,
|
||||
_width,
|
||||
_precision,
|
||||
_flags
|
||||
);
|
||||
init();
|
||||
return result;
|
||||
}
|
||||
|
||||
private final FmtCmpnt append(char c) {
|
||||
|
||||
if (_source == null) {
|
||||
_source = new StringBuilder();
|
||||
}
|
||||
_source.append(c);
|
||||
|
||||
// FIXME: none of these date formats are implemented, because lazy
|
||||
// if a datetime is specified, after the conversion character a time
|
||||
// format specifier is expected. This is the only case where a character
|
||||
// is allowed after the conversion character.
|
||||
if (_conversion == CONV_DTIME) switch (c) {
|
||||
|
||||
// Hour of the day for the 24-hour clock, formatted as two digits with a
|
||||
// leading zero as necessary i.e. 00 - 23.
|
||||
case 'H':
|
||||
|
||||
// Hour for the 12-hour clock, formatted as two digits with a leading
|
||||
// zero as necessary, i.e. 01 - 12.
|
||||
case 'I':
|
||||
|
||||
// Hour of the day for the 24-hour clock, i.e. 0 - 23.
|
||||
case 'k':
|
||||
|
||||
// Hour for the 12-hour clock, i.e. 1 - 12.
|
||||
case 'l':
|
||||
|
||||
// Minute within the hour formatted as two digits with a leading zero
|
||||
// as necessary, i.e. 00 - 59.
|
||||
case 'M':
|
||||
|
||||
// Seconds within the minute, formatted as two digits with a leading
|
||||
// zero as necessary, i.e. 00 - 60 ("60" is a special value required to
|
||||
// support leap seconds).
|
||||
case 'S':
|
||||
|
||||
// Millisecond within the second formatted as three digits with leading
|
||||
// zeros as necessary, i.e. 000 - 999.
|
||||
case 'L':
|
||||
|
||||
// Nanosecond within the second, formatted as nine digits with leading
|
||||
// zeros as necessary, i.e. 000000000 - 999999999.
|
||||
case 'N':
|
||||
|
||||
// Locale-specific morning or afternoon marker in lower case,
|
||||
// e.g."am" or "pm". Use of the conversion prefix 'T' forces this
|
||||
// output to upper case.
|
||||
case 'p':
|
||||
|
||||
// RFC 822 style numeric time zone offset from GMT, e.g. -0800.
|
||||
case 'z':
|
||||
|
||||
// A string representing the abbreviation for the time zone. The
|
||||
// Formatter's locale will supersede the locale of the argument
|
||||
// (if any).
|
||||
case 'Z':
|
||||
|
||||
// Seconds since the beginning of the epoch
|
||||
// starting at 1 January 1970 00:00:00 UTC,
|
||||
// i.e. Long.MIN_VALUE/1000 to Long.MAX_VALUE/1000.
|
||||
case 's':
|
||||
|
||||
// Milliseconds since the beginning of the epoch
|
||||
// starting at 1 January 1970 00:00:00 UTC,
|
||||
// i.e. Long.MIN_VALUE to Long.MAX_VALUE.
|
||||
case 'Q':
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// The following conversion characters are used for formatting dates:
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
// Locale-specific full month name, e.g. "January", "February".
|
||||
case 'B':
|
||||
|
||||
// Locale-specific abbreviated month name, e.g. "Jan", "Feb".
|
||||
case 'b':
|
||||
|
||||
// Same as 'b'.
|
||||
case 'h':
|
||||
|
||||
// Locale-specific full name of the day of the week, e.g. "Sunday"
|
||||
case 'A':
|
||||
|
||||
// Locale-specific short name of the day of the week, e.g. "Sun"
|
||||
case 'a':
|
||||
|
||||
// Four-digit year divided by 100, formatted as two digits with leading
|
||||
// zero as necessary, i.e. 00 - 99
|
||||
case 'C':
|
||||
|
||||
// Year, formatted as at least four digits with leading zeros
|
||||
// as necessary, e.g. 0092 equals 92 CE for the Gregorian calendar.
|
||||
case 'Y':
|
||||
|
||||
// Last two digits of the year, formatted with leading zeros
|
||||
// as necessary, i.e. 00 - 99.
|
||||
case 'y':
|
||||
|
||||
// Day of year, formatted as three digits with leading zeros
|
||||
// as necessary, e.g. 001 - 366 for the Gregorian calendar.
|
||||
case 'j':
|
||||
|
||||
// Month, formatted as two digits with leading zeros as necessary,
|
||||
// i.e. 01 - 13.
|
||||
case 'm':
|
||||
|
||||
// Day of month, formatted as two digits with leading zeros as
|
||||
// necessary, i.e. 01 - 31
|
||||
case 'd':
|
||||
|
||||
// Day of month, formatted as two digits, i.e. 1 - 31.
|
||||
case 'e':
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// The following conversion characters are used for formatting common
|
||||
// date/time compositions.
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// Time formatted for the 24-hour clock as "%tH:%tM"
|
||||
case 'R':
|
||||
|
||||
// Time formatted for the 24-hour clock as "%tH:%tM:%tS".
|
||||
case 'T':
|
||||
|
||||
// Time formatted for the 12-hour clock as "%tI:%tM:%tS %Tp". The location
|
||||
// of the morning or afternoon marker ('%Tp') may be locale-dependent.
|
||||
case 'r':
|
||||
|
||||
// Date formatted as "%tm/%td/%ty".
|
||||
case 'D':
|
||||
|
||||
// ISO 8601 complete date formatted as "%tY-%tm-%td".
|
||||
case 'F':
|
||||
|
||||
// Date and time formatted as "%ta %tb %td %tT %tZ %tY", e.g.
|
||||
// "Sun Jul 20 16:17:00 EDT 1969".
|
||||
case 'c':
|
||||
return seal(CONV_DTIME);
|
||||
|
||||
default:
|
||||
throw new IllegalFormatException("Illegal date/time modifier: " + c);
|
||||
}
|
||||
|
||||
// -- Flags and Switches -----------------------------------------------
|
||||
// these are the possible characters for flags, width, etc. if the input
|
||||
// is not one of these characters, it needs to be a valid conversion char.
|
||||
// because the possible flags can vary based on the type of conversion,
|
||||
// it is easiest to just buffer the flags, argument index, etc. until a
|
||||
// conversion character has been reached. The seal() method will then
|
||||
// work out if the specified flags are valid for the given conversion.
|
||||
switch (c) {
|
||||
case '$':
|
||||
case '<':
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case '-':
|
||||
case '+':
|
||||
case '\'':
|
||||
case ' ':
|
||||
case '#':
|
||||
case ',':
|
||||
case '.':
|
||||
case '(':
|
||||
return null;
|
||||
// -- End of Flags and Switches ----------------------------------------
|
||||
|
||||
// -- Conversion characters --------------------------------------------
|
||||
// If this point is reached, then the current character must be a valid
|
||||
// conversion character. If it is not, it should fall through the rest
|
||||
// of the switch statement below and throw an IllegalFormatException
|
||||
|
||||
// string conversion
|
||||
case 'S':
|
||||
setFlagTrue(FLAG_FORCE_UPPER_CASE);
|
||||
case 's':
|
||||
return seal(CONV_STRNG);
|
||||
|
||||
// newline conversion
|
||||
case 'n':
|
||||
return seal(CONV_NLINE);
|
||||
|
||||
// percent conversion
|
||||
case '%':
|
||||
return seal(CONV_PRCNT);
|
||||
|
||||
// decimal numeric conversion
|
||||
case 'd':
|
||||
return seal(CONV_DECML);
|
||||
|
||||
// hexidecimal numeric conversion
|
||||
case 'X':
|
||||
setFlagTrue(FLAG_FORCE_UPPER_CASE);
|
||||
case 'x':
|
||||
return seal(CONV_HXDEC);
|
||||
|
||||
// datetime conversion
|
||||
case 'T':
|
||||
setFlagTrue(FLAG_FORCE_UPPER_CASE);
|
||||
case 't':
|
||||
_conversion = CONV_DTIME;
|
||||
return null;
|
||||
|
||||
// boolean conversion
|
||||
case 'B':
|
||||
setFlagTrue(FLAG_FORCE_UPPER_CASE);
|
||||
case 'b':
|
||||
return seal(CONV_BOOLN);
|
||||
|
||||
// hashcode conversion
|
||||
case 'H':
|
||||
setFlagTrue(FLAG_FORCE_UPPER_CASE);
|
||||
case 'h':
|
||||
return seal(CONV_HCODE);
|
||||
|
||||
// character conversion
|
||||
case 'C':
|
||||
setFlagTrue(FLAG_FORCE_UPPER_CASE);
|
||||
case 'c':
|
||||
return seal(CONV_CHRCT);
|
||||
|
||||
// octal numeric conversion
|
||||
case 'o':
|
||||
return seal(CONV_OCTAL);
|
||||
|
||||
// computerized scientific conversion
|
||||
case 'E':
|
||||
setFlagTrue(FLAG_FORCE_UPPER_CASE);
|
||||
case 'e':
|
||||
return seal(CONV_CPSCI);
|
||||
|
||||
// floating point conversion
|
||||
case 'f':
|
||||
return seal(CONV_FLOAT);
|
||||
|
||||
// general scientific floating point conversion
|
||||
case 'G':
|
||||
setFlagTrue(FLAG_FORCE_UPPER_CASE);
|
||||
case 'g':
|
||||
return seal(CONV_GNSCI);
|
||||
|
||||
// hexidecimal exponential floating point conversion
|
||||
case 'A':
|
||||
setFlagTrue(FLAG_FORCE_UPPER_CASE);
|
||||
case 'a':
|
||||
return seal(CONV_HXEXP);
|
||||
// -- End of Conversion characters --------------------------------------
|
||||
|
||||
default:
|
||||
throw new IllegalFormatException(
|
||||
"Invalid character encountered while parsing specifier: " + c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("{ ")
|
||||
.append("source = '").append(_source).append("', ")
|
||||
.append("conversion = ").append(_conversion).append(", ")
|
||||
.append("flags = ").append(Byte.toString(_flags, 2)).append(", ")
|
||||
.append("arg_index = ").append(_argument_index).append(", ")
|
||||
.append("width = ").append(_width).append(", ")
|
||||
.append("precision = ").append(_precision).append(", ")
|
||||
.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private final FmtCmpnt seal(final byte conversion) {
|
||||
|
||||
// throwing IllegalStateException instead of IllegalFormatException
|
||||
// because this should only occur if there is a bug in the append()
|
||||
// method. In that case I'd prefer to fail fast even if the user is
|
||||
// explicitly trying to catch IllegalFormatException.
|
||||
if (conversion < 0 || conversion > 0xE) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
this._conversion = conversion;
|
||||
|
||||
// if the length is less than 2, it must mean that only the conversion
|
||||
// character was specified. Since a conversion character by itself is a
|
||||
// valid pattern, just build and return
|
||||
if (_source.length() < 2) {
|
||||
return build();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// spec format: [argument_index$][flags][width][.precision]
|
||||
// ---------------------------------------------------------------------
|
||||
// the last character of the spec is the conversion character which has
|
||||
// already been translated the appropriate byte by the append() method,
|
||||
// so the last character gets chopped off before processing
|
||||
final String spec = _source.substring(0, _source.length() - 1);
|
||||
|
||||
// if argument index is supported, it should be followed by a '$' and be
|
||||
// comprised only of digit characters, or it should be a single '<' char
|
||||
final int dollarIndex = spec.indexOf('$');
|
||||
if (dollarIndex > -1) {
|
||||
if (acceptsArgument(conversion)) {
|
||||
if (spec.charAt(dollarIndex - 1) == '<') {
|
||||
_argument_index = AIDX_PREV;
|
||||
} else {
|
||||
_argument_index = Integer.valueOf(spec.substring(0, dollarIndex));
|
||||
}
|
||||
} else {
|
||||
throw new IllegalFormatException(
|
||||
"Formats that do not accept arguments cannot specify an index."
|
||||
);
|
||||
}
|
||||
}
|
||||
if (dollarIndex == (spec.length() - 1)) {
|
||||
return build();
|
||||
}
|
||||
|
||||
// if precision is supported, look for the first period and assume that
|
||||
// everything before is the width and everything after is the precision
|
||||
final int dotIndex = spec.indexOf('.');
|
||||
if (dotIndex > -1) {
|
||||
if (precisionSupported(conversion)) {
|
||||
_precision = Integer.valueOf(spec.substring(dotIndex + 1));
|
||||
} else {
|
||||
throw new IllegalFormatException(
|
||||
"Precision is not supported for " + conversion
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Now loop over the remaining characters to get the width as well as any
|
||||
// applicable flags. Note: 0 is a valid flag so must be handled carefully
|
||||
final String remaining = spec.substring(
|
||||
Math.max(dollarIndex, 0), dotIndex > -1 ? dotIndex : spec.length()
|
||||
);
|
||||
int flagsEnd = -1;
|
||||
for (int i = 0, n = remaining.length(); i < n && (flagsEnd == -1); i++) {
|
||||
final char c = remaining.charAt(i);
|
||||
switch (c) {
|
||||
case '-':
|
||||
ensureLeftJustifySupported();
|
||||
setFlagTrue(FLAG_LEFT_JUSTIFIED);
|
||||
break;
|
||||
case '#':
|
||||
ensureNumeric(c);
|
||||
setFlagTrue(FLAG_ALTERNATE_FORM);
|
||||
break;
|
||||
case '+':
|
||||
ensureNumeric(c);
|
||||
setFlagTrue(FLAG_ALWAYS_INCLUDES_SIGN);
|
||||
break;
|
||||
case ' ':
|
||||
ensureNumeric(c);
|
||||
setFlagTrue(FLAG_LEADING_SPACE_PADDED);
|
||||
break;
|
||||
case ',':
|
||||
ensureNumeric(c);
|
||||
setFlagTrue(FLAG_GROUPING_SEPARATORS);
|
||||
break;
|
||||
case '(':
|
||||
ensureNumeric(c);
|
||||
setFlagTrue(FLAG_NEGATIVES_IN_PARENS);
|
||||
break;
|
||||
case '0':
|
||||
ensureNumeric(c);
|
||||
setFlagTrue(FLAG_LEADING_ZERO_PADDED);
|
||||
break;
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
flagsEnd = i;
|
||||
_width = Integer.valueOf(remaining.substring(flagsEnd));
|
||||
return build();
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
private final void ensureLeftJustifySupported() {
|
||||
if (!widthSupported(_conversion)) {
|
||||
throw new IllegalFormatException(
|
||||
"Conversion must support width if specifying left justified."
|
||||
);
|
||||
}
|
||||
}
|
||||
private final void ensureNumeric(final char c) {
|
||||
if (!isNumeric(_conversion)) {
|
||||
throw new IllegalFormatException(
|
||||
"flag " + c + " only supported on numeric specifiers."
|
||||
);
|
||||
}
|
||||
}
|
||||
private final void setFlagTrue(final byte flag) {
|
||||
_flags |= flag;
|
||||
}/*
|
||||
final void setFlagFalse(final byte flag) {
|
||||
_flags &= ~flag;
|
||||
}*/
|
||||
}
|
||||
}
|
15
sgx-jvm/avian/classpath/avian/Function.java
Normal file
15
sgx-jvm/avian/classpath/avian/Function.java
Normal file
@ -0,0 +1,15 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
public interface Function<A,B> {
|
||||
public B call(A argument) throws Exception;
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
public class IncompatibleContinuationException extends Exception {
|
||||
public IncompatibleContinuationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public IncompatibleContinuationException() {
|
||||
super();
|
||||
}
|
||||
}
|
18
sgx-jvm/avian/classpath/avian/InnerClassReference.java
Normal file
18
sgx-jvm/avian/classpath/avian/InnerClassReference.java
Normal file
@ -0,0 +1,18 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
public class InnerClassReference {
|
||||
public byte[] inner;
|
||||
public byte[] outer;
|
||||
public byte[] name;
|
||||
public short flags;
|
||||
}
|
26
sgx-jvm/avian/classpath/avian/Iso88591.java
Normal file
26
sgx-jvm/avian/classpath/avian/Iso88591.java
Normal file
@ -0,0 +1,26 @@
|
||||
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
public class Iso88591 {
|
||||
|
||||
public static byte[] encode(char[] s16, int offset, int length) {
|
||||
ByteArrayOutputStream buf = new ByteArrayOutputStream();
|
||||
for (int i = offset; i < offset+length; ++i) {
|
||||
// ISO-88591-1/Latin-1 is the same as UTF-16 under 0x100
|
||||
buf.write(s16[i]);
|
||||
}
|
||||
return buf.toByteArray();
|
||||
}
|
||||
}
|
240
sgx-jvm/avian/classpath/avian/LegacyObjectInputStream.java
Normal file
240
sgx-jvm/avian/classpath/avian/LegacyObjectInputStream.java
Normal file
@ -0,0 +1,240 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
import avian.VMClass;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PushbackReader;
|
||||
import java.io.StreamCorruptedException;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
public class LegacyObjectInputStream extends InputStream {
|
||||
private final InputStream in;
|
||||
private final PushbackReader r;
|
||||
|
||||
public LegacyObjectInputStream(InputStream in) {
|
||||
this.in = in;
|
||||
this.r = new PushbackReader(new InputStreamReader(in));
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
return in.read();
|
||||
}
|
||||
|
||||
public int read(byte[] b, int offset, int length) throws IOException {
|
||||
return in.read(b, offset, length);
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
in.close();
|
||||
}
|
||||
|
||||
public Object readObject() throws IOException, ClassNotFoundException {
|
||||
return readObject(new HashMap<Integer, Object>());
|
||||
}
|
||||
|
||||
public boolean readBoolean() throws IOException {
|
||||
read('z');
|
||||
return readLongToken() != 0;
|
||||
}
|
||||
|
||||
public byte readByte() throws IOException {
|
||||
read('b');
|
||||
return (byte) readLongToken();
|
||||
}
|
||||
|
||||
public char readChar() throws IOException {
|
||||
read('c');
|
||||
return (char) readLongToken();
|
||||
}
|
||||
|
||||
public short readShort() throws IOException {
|
||||
read('s');
|
||||
return (short) readLongToken();
|
||||
}
|
||||
|
||||
public int readInt() throws IOException {
|
||||
read('i');
|
||||
return (int) readLongToken();
|
||||
}
|
||||
|
||||
public long readLong() throws IOException {
|
||||
read('j');
|
||||
return readLongToken();
|
||||
}
|
||||
|
||||
public float readFloat() throws IOException {
|
||||
read('f');
|
||||
return (float) readDoubleToken();
|
||||
}
|
||||
|
||||
public double readDouble() throws IOException {
|
||||
read('d');
|
||||
return readDoubleToken();
|
||||
}
|
||||
|
||||
public void defaultReadObject() throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
private void skipSpace() throws IOException {
|
||||
int c;
|
||||
while ((c = r.read()) != -1 && Character.isWhitespace((char) c));
|
||||
if (c != -1) {
|
||||
r.unread(c);
|
||||
}
|
||||
}
|
||||
|
||||
private void read(char v) throws IOException {
|
||||
skipSpace();
|
||||
|
||||
int c = r.read();
|
||||
if (c != v) {
|
||||
if (c == -1) {
|
||||
throw new EOFException();
|
||||
} else {
|
||||
throw new StreamCorruptedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String readStringToken() throws IOException {
|
||||
skipSpace();
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int c;
|
||||
while ((c = r.read()) != -1 && ! Character.isWhitespace((char) c) && c != ')') {
|
||||
sb.append((char) c);
|
||||
}
|
||||
if (c != -1) {
|
||||
r.unread(c);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private long readLongToken() throws IOException {
|
||||
return Long.parseLong(readStringToken());
|
||||
}
|
||||
|
||||
private double readDoubleToken() throws IOException {
|
||||
return Double.parseDouble(readStringToken());
|
||||
}
|
||||
|
||||
private Object readObject(HashMap<Integer, Object> map)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
skipSpace();
|
||||
switch (r.read()) {
|
||||
case 'a':
|
||||
return deserializeArray(map);
|
||||
case 'l':
|
||||
return deserializeObject(map);
|
||||
case 'n':
|
||||
return null;
|
||||
case -1:
|
||||
throw new EOFException();
|
||||
default:
|
||||
throw new StreamCorruptedException();
|
||||
}
|
||||
}
|
||||
|
||||
private Object deserialize(HashMap<Integer, Object> map)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
skipSpace();
|
||||
switch (r.read()) {
|
||||
case 'a':
|
||||
return deserializeArray(map);
|
||||
case 'l':
|
||||
return deserializeObject(map);
|
||||
case 'r':
|
||||
return map.get((int) readLongToken());
|
||||
case 'n':
|
||||
return null;
|
||||
case 'z':
|
||||
return (readLongToken() != 0);
|
||||
case 'b':
|
||||
return (byte) readLongToken();
|
||||
case 'c':
|
||||
return (char) readLongToken();
|
||||
case 's':
|
||||
return (short) readLongToken();
|
||||
case 'i':
|
||||
return (int) readLongToken();
|
||||
case 'j':
|
||||
return readLongToken();
|
||||
case 'f':
|
||||
return (float) readDoubleToken();
|
||||
case 'd':
|
||||
return readDoubleToken();
|
||||
case -1:
|
||||
throw new EOFException();
|
||||
default:
|
||||
throw new StreamCorruptedException();
|
||||
}
|
||||
}
|
||||
|
||||
private Object deserializeArray(HashMap<Integer, Object> map)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
read('(');
|
||||
int id = (int) readLongToken();
|
||||
Class<?> c = Class.forName(readStringToken());
|
||||
int length = (int) readLongToken();
|
||||
Class<?> t = c.getComponentType();
|
||||
Object o = Array.newInstance(t, length);
|
||||
|
||||
map.put(id, o);
|
||||
|
||||
for (int i = 0; i < length; ++i) {
|
||||
Array.set(o, i, deserialize(map));
|
||||
}
|
||||
|
||||
read(')');
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
private static native Object makeInstance(VMClass c);
|
||||
|
||||
private Object deserializeObject(HashMap<Integer, Object> map)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
read('(');
|
||||
int id = (int) readLongToken();
|
||||
Class<?> c = Class.forName(readStringToken());
|
||||
Object o = makeInstance(c.vmClass);
|
||||
|
||||
map.put(id, o);
|
||||
|
||||
for (Field<?> f: c.getAllFields()) {
|
||||
int modifiers = f.getModifiers();
|
||||
if ((modifiers & (Modifier.TRANSIENT | Modifier.STATIC)) == 0) {
|
||||
try {
|
||||
f.set(o, deserialize(map));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
read(')');
|
||||
|
||||
return o;
|
||||
}
|
||||
}
|
211
sgx-jvm/avian/classpath/avian/LegacyObjectOutputStream.java
Normal file
211
sgx-jvm/avian/classpath/avian/LegacyObjectOutputStream.java
Normal file
@ -0,0 +1,211 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
import java.util.IdentityHashMap;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.io.Serializable;
|
||||
import java.io.NotSerializableException;
|
||||
|
||||
public class LegacyObjectOutputStream extends OutputStream {
|
||||
private final PrintStream out;
|
||||
|
||||
public LegacyObjectOutputStream(OutputStream out) {
|
||||
this.out = new PrintStream(out);
|
||||
}
|
||||
|
||||
public void write(int c) throws IOException {
|
||||
out.write(c);
|
||||
}
|
||||
|
||||
public void write(byte[] b, int offset, int length) throws IOException {
|
||||
out.write(b, offset, length);
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
out.flush();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
out.close();
|
||||
}
|
||||
|
||||
public void writeObject(Object o) throws IOException {
|
||||
writeObject(o, new IdentityHashMap(), new int[] {0});
|
||||
}
|
||||
|
||||
public void writeBoolean(boolean v) {
|
||||
out.print("z");
|
||||
out.print((v ? 1 : 0));
|
||||
}
|
||||
|
||||
public void writeByte(byte v) {
|
||||
out.print("b");
|
||||
out.print((int) v);
|
||||
}
|
||||
|
||||
public void writeChar(char v) {
|
||||
out.print("c");
|
||||
out.print((int) v);
|
||||
}
|
||||
|
||||
public void writeShort(short v) {
|
||||
out.print("s");
|
||||
out.print((int) v);
|
||||
}
|
||||
|
||||
public void writeInt(int v) {
|
||||
out.print("i");
|
||||
out.print(v);
|
||||
}
|
||||
|
||||
public void writeLong(long v) {
|
||||
out.print("j");
|
||||
out.print(v);
|
||||
}
|
||||
|
||||
public void writeFloat(float v) {
|
||||
out.print("f");
|
||||
out.print(v);
|
||||
}
|
||||
|
||||
public void writeDouble(double v) {
|
||||
out.print("d");
|
||||
out.print(v);
|
||||
}
|
||||
|
||||
public void defaultWriteObject() throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
private void writeObject(Object o, IdentityHashMap<Object, Integer> map,
|
||||
int[] nextId)
|
||||
throws IOException
|
||||
{
|
||||
if (o == null) {
|
||||
out.print("n");
|
||||
} else {
|
||||
Integer id = map.get(o);
|
||||
if (id == null) {
|
||||
map.put(o, nextId[0]);
|
||||
|
||||
Class c = o.getClass();
|
||||
if (c.isArray()) {
|
||||
serializeArray(o, map, nextId);
|
||||
} else if (Serializable.class.isAssignableFrom(c)) {
|
||||
serializeObject(o, map, nextId);
|
||||
} else {
|
||||
throw new NotSerializableException(c.getName());
|
||||
}
|
||||
} else {
|
||||
out.print("r");
|
||||
out.print(id.intValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void serializeArray(Object o, IdentityHashMap<Object, Integer> map,
|
||||
int[] nextId)
|
||||
throws IOException
|
||||
{
|
||||
Class c = o.getClass();
|
||||
Class t = c.getComponentType();
|
||||
int length = Array.getLength(o);
|
||||
|
||||
out.print("a(");
|
||||
out.print(nextId[0]++);
|
||||
out.print(" ");
|
||||
out.print(c.getName());
|
||||
out.print(" ");
|
||||
out.print(length);
|
||||
|
||||
for (int i = 0; i < length; ++i) {
|
||||
out.print(" ");
|
||||
Object v = Array.get(o, i);
|
||||
if (t.equals(boolean.class)) {
|
||||
writeBoolean((Boolean) v);
|
||||
} else if (t.equals(byte.class)) {
|
||||
writeByte((Byte) v);
|
||||
} else if (t.equals(char.class)) {
|
||||
writeChar((Character) v);
|
||||
} else if (t.equals(short.class)) {
|
||||
writeShort((Short) v);
|
||||
} else if (t.equals(int.class)) {
|
||||
writeInt((Integer) v);
|
||||
} else if (t.equals(long.class)) {
|
||||
writeLong((Long) v);
|
||||
} else if (t.equals(float.class)) {
|
||||
writeFloat((Float) v);
|
||||
} else if (t.equals(double.class)) {
|
||||
writeDouble((Double) v);
|
||||
} else {
|
||||
writeObject(v, map, nextId);
|
||||
}
|
||||
}
|
||||
|
||||
out.print(")");
|
||||
}
|
||||
|
||||
private void serializeObject(Object o, IdentityHashMap<Object, Integer> map,
|
||||
int[] nextId)
|
||||
throws IOException
|
||||
{
|
||||
Class c = o.getClass();
|
||||
|
||||
out.print("l(");
|
||||
out.print(nextId[0]++);
|
||||
out.print(" ");
|
||||
out.print(c.getName());
|
||||
|
||||
for (Field f: c.getAllFields()) {
|
||||
int modifiers = f.getModifiers();
|
||||
if ((modifiers & (Modifier.TRANSIENT | Modifier.STATIC)) == 0) {
|
||||
out.print(" ");
|
||||
Object v;
|
||||
|
||||
try {
|
||||
v = f.get(o);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
Class t = f.getType();
|
||||
if (t.equals(boolean.class)) {
|
||||
writeBoolean((Boolean) v);
|
||||
} else if (t.equals(byte.class)) {
|
||||
writeByte((Byte) v);
|
||||
} else if (t.equals(char.class)) {
|
||||
writeChar((Character) v);
|
||||
} else if (t.equals(short.class)) {
|
||||
writeShort((Short) v);
|
||||
} else if (t.equals(int.class)) {
|
||||
writeInt((Integer) v);
|
||||
} else if (t.equals(long.class)) {
|
||||
writeLong((Long) v);
|
||||
} else if (t.equals(float.class)) {
|
||||
writeFloat((Float) v);
|
||||
} else if (t.equals(double.class)) {
|
||||
writeDouble((Double) v);
|
||||
} else {
|
||||
writeObject(v, map, nextId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out.print(")");
|
||||
}
|
||||
|
||||
}
|
67
sgx-jvm/avian/classpath/avian/Machine.java
Normal file
67
sgx-jvm/avian/classpath/avian/Machine.java
Normal file
@ -0,0 +1,67 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
import sun.misc.Unsafe;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public abstract class Machine {
|
||||
|
||||
private static final Unsafe unsafe;
|
||||
|
||||
static {
|
||||
Unsafe u;
|
||||
try {
|
||||
Field f = Unsafe.class.getDeclaredField("theUnsafe");
|
||||
f.setAccessible(true);
|
||||
u = (Unsafe)f.get(null);
|
||||
} catch (Exception e) {
|
||||
u = null;
|
||||
}
|
||||
unsafe = u;
|
||||
}
|
||||
|
||||
public static native void dumpHeap(String outputFile);
|
||||
|
||||
public static Unsafe getUnsafe() {
|
||||
return unsafe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Short version: Don't use this function -- it's evil.
|
||||
*
|
||||
* Long version: This is kind of a poor man's, cross-platform
|
||||
* version of Microsoft's Structured Exception Handling. The idea
|
||||
* is that you can call a native function with the specified
|
||||
* argument such that any OS signals raised (e.g. SIGSEGV, SIGBUS,
|
||||
* SIGFPE, EXC_ACCESS_VIOLATION, etc.) prior to the function
|
||||
* returning are converted into the appropriate Java exception
|
||||
* (e.g. NullPointerException, ArithmeticException, etc.) and thrown
|
||||
* from this method. This may be useful in very specific
|
||||
* circumstances, e.g. to work around a bug in a library that would
|
||||
* otherwise crash your app. On the other hand, you'd be much
|
||||
* better off just fixing the library if possible.
|
||||
*
|
||||
* Caveats: The specified function should return quickly without
|
||||
* blocking, since it will block critical VM features such as
|
||||
* garbage collection. The implementation is equivalent to using
|
||||
* setjmp/longjmp to achieve a non-local return from the signal
|
||||
* handler, meaning C++ destructors and other cleanup code might not
|
||||
* be run if a signal is raised. It might melt your keyboard and
|
||||
* burn your fingertips. Caveat lector.
|
||||
*
|
||||
* @param function a function pointer of type int64_t (*)(int64_t)
|
||||
* @param argument the argument to pass to the function
|
||||
* @return the return value of the function
|
||||
*/
|
||||
public static native long tryNative(long function, long argument);
|
||||
|
||||
}
|
17
sgx-jvm/avian/classpath/avian/MethodAddendum.java
Normal file
17
sgx-jvm/avian/classpath/avian/MethodAddendum.java
Normal file
@ -0,0 +1,17 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
public class MethodAddendum extends Addendum {
|
||||
public Object exceptionTable;
|
||||
public Object annotationDefault;
|
||||
public Object parameterAnnotationTable;
|
||||
}
|
5
sgx-jvm/avian/classpath/avian/Pair.java
Normal file
5
sgx-jvm/avian/classpath/avian/Pair.java
Normal file
@ -0,0 +1,5 @@
|
||||
package avian;
|
||||
|
||||
abstract class Pair {
|
||||
// VM-visible fields in types.def
|
||||
}
|
594
sgx-jvm/avian/classpath/avian/PersistentSet.java
Normal file
594
sgx-jvm/avian/classpath/avian/PersistentSet.java
Normal file
@ -0,0 +1,594 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
public class PersistentSet <T> implements Iterable <T> {
|
||||
private static final Node NullNode = new Node(null);
|
||||
|
||||
static {
|
||||
NullNode.left = NullNode;
|
||||
NullNode.right = NullNode;
|
||||
}
|
||||
|
||||
private final Node<T> root;
|
||||
private final Comparator<T> comparator;
|
||||
private final int size;
|
||||
|
||||
public PersistentSet() {
|
||||
this(NullNode, new Comparator<T>() {
|
||||
public int compare(T a, T b) {
|
||||
return ((Comparable<T>) a).compareTo(b);
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
|
||||
public PersistentSet(Comparator<T> comparator) {
|
||||
this(NullNode, comparator, 0);
|
||||
}
|
||||
|
||||
private PersistentSet(Node<T> root, Comparator<T> comparator, int size) {
|
||||
this.root = root;
|
||||
this.comparator = comparator;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("{");
|
||||
for (java.util.Iterator it = iterator(); it.hasNext();) {
|
||||
sb.append(it.next());
|
||||
if (it.hasNext()) {
|
||||
sb.append(",");
|
||||
}
|
||||
}
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public Comparator<T> comparator() {
|
||||
return comparator;
|
||||
}
|
||||
|
||||
public PersistentSet<T> add(T value) {
|
||||
return add(value, false);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public PersistentSet<T> add(T value, boolean replaceExisting) {
|
||||
Path<T> p = find(value);
|
||||
if (! p.fresh) {
|
||||
if (replaceExisting) {
|
||||
return p.replaceWith(value);
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
return add(p);
|
||||
}
|
||||
|
||||
private PersistentSet<T> add(Path<T> p) {
|
||||
if (! p.fresh) throw new IllegalArgumentException();
|
||||
|
||||
Node<T> new_ = p.node;
|
||||
Node<T> newRoot = p.root.root;
|
||||
Cell<Node<T>> ancestors = p.ancestors;
|
||||
|
||||
// rebalance
|
||||
new_.red = true;
|
||||
while (ancestors != null && ancestors.value.red) {
|
||||
if (ancestors.value == ancestors.next.value.left) {
|
||||
if (ancestors.next.value.right.red) {
|
||||
ancestors.value.red = false;
|
||||
ancestors.next.value.right = new Node(ancestors.next.value.right);
|
||||
ancestors.next.value.right.red = false;
|
||||
ancestors.next.value.red = true;
|
||||
new_ = ancestors.next.value;
|
||||
ancestors = ancestors.next.next;
|
||||
} else {
|
||||
if (new_ == ancestors.value.right) {
|
||||
new_ = ancestors.value;
|
||||
ancestors = ancestors.next;
|
||||
|
||||
Node<T> n = leftRotate(new_);
|
||||
if (ancestors.value.right == new_) {
|
||||
ancestors.value.right = n;
|
||||
} else {
|
||||
ancestors.value.left = n;
|
||||
}
|
||||
ancestors = new Cell(n, ancestors);
|
||||
}
|
||||
ancestors.value.red = false;
|
||||
ancestors.next.value.red = true;
|
||||
|
||||
Node<T> n = rightRotate(ancestors.next.value);
|
||||
if (ancestors.next.next == null) {
|
||||
newRoot = n;
|
||||
} else if (ancestors.next.next.value.right == ancestors.next.value) {
|
||||
ancestors.next.next.value.right = n;
|
||||
} else {
|
||||
ancestors.next.next.value.left = n;
|
||||
}
|
||||
// done
|
||||
}
|
||||
} else {
|
||||
if (ancestors.next.value.left.red) {
|
||||
ancestors.value.red = false;
|
||||
ancestors.next.value.left = new Node(ancestors.next.value.left);
|
||||
ancestors.next.value.left.red = false;
|
||||
ancestors.next.value.red = true;
|
||||
new_ = ancestors.next.value;
|
||||
ancestors = ancestors.next.next;
|
||||
} else {
|
||||
if (new_ == ancestors.value.left) {
|
||||
new_ = ancestors.value;
|
||||
ancestors = ancestors.next;
|
||||
|
||||
Node<T> n = rightRotate(new_);
|
||||
if (ancestors.value.right == new_) {
|
||||
ancestors.value.right = n;
|
||||
} else {
|
||||
ancestors.value.left = n;
|
||||
}
|
||||
ancestors = new Cell(n, ancestors);
|
||||
}
|
||||
ancestors.value.red = false;
|
||||
ancestors.next.value.red = true;
|
||||
|
||||
Node<T> n = leftRotate(ancestors.next.value);
|
||||
if (ancestors.next.next == null) {
|
||||
newRoot = n;
|
||||
} else if (ancestors.next.next.value.right == ancestors.next.value) {
|
||||
ancestors.next.next.value.right = n;
|
||||
} else {
|
||||
ancestors.next.next.value.left = n;
|
||||
}
|
||||
// done
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newRoot.red = false;
|
||||
|
||||
return new PersistentSet(newRoot, comparator, size + 1);
|
||||
}
|
||||
|
||||
private static <T> Node<T> leftRotate(Node<T> n) {
|
||||
Node<T> child = new Node(n.right);
|
||||
n.right = child.left;
|
||||
child.left = n;
|
||||
return child;
|
||||
}
|
||||
|
||||
private static <T> Node<T> rightRotate(Node<T> n) {
|
||||
Node<T> child = new Node(n.left);
|
||||
n.left = child.right;
|
||||
child.right = n;
|
||||
return child;
|
||||
}
|
||||
|
||||
public PersistentSet<T> remove(T value) {
|
||||
Path<T> p = find(value);
|
||||
if (! p.fresh) {
|
||||
return remove(p);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private PersistentSet<T> remove(Path<T> p) {
|
||||
if (size == 1) {
|
||||
if (p.node != root) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return new PersistentSet(NullNode, comparator, 0);
|
||||
}
|
||||
|
||||
Node<T> new_ = p.node;
|
||||
Node<T> newRoot = p.root.root;
|
||||
Cell<Node<T>> ancestors = p.ancestors;
|
||||
|
||||
Node<T> dead;
|
||||
if (new_.left == NullNode || new_.right == NullNode) {
|
||||
dead = new_;
|
||||
} else {
|
||||
Cell<Node<T>> path = successor(new_, ancestors);
|
||||
dead = path.value;
|
||||
ancestors = path.next;
|
||||
}
|
||||
|
||||
Node<T> child;
|
||||
if (dead.left != NullNode) {
|
||||
child = new Node(dead.left);
|
||||
} else if (dead.right != NullNode) {
|
||||
child = new Node(dead.right);
|
||||
} else {
|
||||
child = NullNode;
|
||||
}
|
||||
|
||||
if (ancestors == null) {
|
||||
child.red = false;
|
||||
return new PersistentSet(child, comparator, 1);
|
||||
} else if (dead == ancestors.value.left) {
|
||||
ancestors.value.left = child;
|
||||
} else {
|
||||
ancestors.value.right = child;
|
||||
}
|
||||
|
||||
if (dead != new_) {
|
||||
new_.value = dead.value;
|
||||
}
|
||||
|
||||
if (! dead.red) {
|
||||
// rebalance
|
||||
while (ancestors != null && ! child.red) {
|
||||
if (child == ancestors.value.left) {
|
||||
Node<T> sibling = ancestors.value.right
|
||||
= new Node(ancestors.value.right);
|
||||
if (sibling.red) {
|
||||
sibling.red = false;
|
||||
ancestors.value.red = true;
|
||||
|
||||
Node<T> n = leftRotate(ancestors.value);
|
||||
if (ancestors.next == null) {
|
||||
newRoot = n;
|
||||
} else if (ancestors.next.value.right == ancestors.value) {
|
||||
ancestors.next.value.right = n;
|
||||
} else {
|
||||
ancestors.next.value.left = n;
|
||||
}
|
||||
ancestors.next = new Cell(n, ancestors.next);
|
||||
|
||||
sibling = ancestors.value.right = new Node(ancestors.value.right);
|
||||
}
|
||||
|
||||
if (! (sibling.left.red || sibling.right.red)) {
|
||||
sibling.red = true;
|
||||
child = ancestors.value;
|
||||
ancestors = ancestors.next;
|
||||
} else {
|
||||
if (! sibling.right.red) {
|
||||
sibling.left = new Node(sibling.left);
|
||||
sibling.left.red = false;
|
||||
|
||||
sibling.red = true;
|
||||
sibling = ancestors.value.right = rightRotate(sibling);
|
||||
}
|
||||
|
||||
sibling.red = ancestors.value.red;
|
||||
ancestors.value.red = false;
|
||||
|
||||
sibling.right = new Node(sibling.right);
|
||||
sibling.right.red = false;
|
||||
|
||||
Node<T> n = leftRotate(ancestors.value);
|
||||
if (ancestors.next == null) {
|
||||
newRoot = n;
|
||||
} else if (ancestors.next.value.right == ancestors.value) {
|
||||
ancestors.next.value.right = n;
|
||||
} else {
|
||||
ancestors.next.value.left = n;
|
||||
}
|
||||
|
||||
child = newRoot;
|
||||
ancestors = null;
|
||||
}
|
||||
} else {
|
||||
Node<T> sibling = ancestors.value.left
|
||||
= new Node(ancestors.value.left);
|
||||
if (sibling.red) {
|
||||
sibling.red = false;
|
||||
ancestors.value.red = true;
|
||||
|
||||
Node<T> n = rightRotate(ancestors.value);
|
||||
if (ancestors.next == null) {
|
||||
newRoot = n;
|
||||
} else if (ancestors.next.value.left == ancestors.value) {
|
||||
ancestors.next.value.left = n;
|
||||
} else {
|
||||
ancestors.next.value.right = n;
|
||||
}
|
||||
ancestors.next = new Cell(n, ancestors.next);
|
||||
|
||||
sibling = ancestors.value.left = new Node(ancestors.value.left);
|
||||
}
|
||||
|
||||
if (! (sibling.right.red || sibling.left.red)) {
|
||||
sibling.red = true;
|
||||
child = ancestors.value;
|
||||
ancestors = ancestors.next;
|
||||
} else {
|
||||
if (! sibling.left.red) {
|
||||
sibling.right = new Node(sibling.right);
|
||||
sibling.right.red = false;
|
||||
|
||||
sibling.red = true;
|
||||
sibling = ancestors.value.left = leftRotate(sibling);
|
||||
}
|
||||
|
||||
sibling.red = ancestors.value.red;
|
||||
ancestors.value.red = false;
|
||||
|
||||
sibling.left = new Node(sibling.left);
|
||||
sibling.left.red = false;
|
||||
|
||||
Node<T> n = rightRotate(ancestors.value);
|
||||
if (ancestors.next == null) {
|
||||
newRoot = n;
|
||||
} else if (ancestors.next.value.left == ancestors.value) {
|
||||
ancestors.next.value.left = n;
|
||||
} else {
|
||||
ancestors.next.value.right = n;
|
||||
}
|
||||
|
||||
child = newRoot;
|
||||
ancestors = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
child.red = false;
|
||||
}
|
||||
|
||||
return new PersistentSet(newRoot, comparator, size - 1);
|
||||
}
|
||||
|
||||
private static <T> Cell<Node<T>> minimum(Node<T> n,
|
||||
Cell<Node<T>> ancestors)
|
||||
{
|
||||
while (n.left != NullNode) {
|
||||
n.left = new Node(n.left);
|
||||
ancestors = new Cell(n, ancestors);
|
||||
n = n.left;
|
||||
}
|
||||
|
||||
return new Cell(n, ancestors);
|
||||
}
|
||||
|
||||
private static <T> Cell<Node<T>> maximum(Node<T> n,
|
||||
Cell<Node<T>> ancestors)
|
||||
{
|
||||
while (n.right != NullNode) {
|
||||
n.right = new Node(n.right);
|
||||
ancestors = new Cell(n, ancestors);
|
||||
n = n.right;
|
||||
}
|
||||
|
||||
return new Cell(n, ancestors);
|
||||
}
|
||||
|
||||
private static <T> Cell<Node<T>> successor(Node<T> n,
|
||||
Cell<Node<T>> ancestors)
|
||||
{
|
||||
if (n.right != NullNode) {
|
||||
n.right = new Node(n.right);
|
||||
return minimum(n.right, new Cell(n, ancestors));
|
||||
}
|
||||
|
||||
while (ancestors != null && n == ancestors.value.right) {
|
||||
n = ancestors.value;
|
||||
ancestors = ancestors.next;
|
||||
}
|
||||
|
||||
return ancestors;
|
||||
}
|
||||
|
||||
private static <T> Cell<Node<T>> predecessor(Node<T> n,
|
||||
Cell<Node<T>> ancestors)
|
||||
{
|
||||
if (n.left != NullNode) {
|
||||
n.left = new Node(n.left);
|
||||
return maximum(n.left, new Cell(n, ancestors));
|
||||
}
|
||||
|
||||
while (ancestors != null && n == ancestors.value.left) {
|
||||
n = ancestors.value;
|
||||
ancestors = ancestors.next;
|
||||
}
|
||||
|
||||
return ancestors;
|
||||
}
|
||||
|
||||
public Path<T> find(T value) {
|
||||
Node<T> newRoot = new Node(root);
|
||||
Cell<Node<T>> ancestors = null;
|
||||
|
||||
Node<T> old = root;
|
||||
Node<T> new_ = newRoot;
|
||||
while (old != NullNode) {
|
||||
ancestors = new Cell(new_, ancestors);
|
||||
|
||||
int difference = comparator.compare(value, old.value);
|
||||
if (difference < 0) {
|
||||
old = old.left;
|
||||
new_ = new_.left = new Node(old);
|
||||
} else if (difference > 0) {
|
||||
old = old.right;
|
||||
new_ = new_.right = new Node(old);
|
||||
} else {
|
||||
return new Path(false, new_,
|
||||
new PersistentSet(newRoot, comparator, size),
|
||||
ancestors.next);
|
||||
}
|
||||
}
|
||||
|
||||
new_.value = value;
|
||||
return new Path(true, new_,
|
||||
new PersistentSet(newRoot, comparator, size),
|
||||
ancestors);
|
||||
}
|
||||
|
||||
public Path<T> first() {
|
||||
if (root == NullNode) return null;
|
||||
|
||||
Node<T> newRoot = new Node(root);
|
||||
Cell<Node<T>> ancestors = null;
|
||||
|
||||
Node<T> old = root;
|
||||
Node<T> new_ = newRoot;
|
||||
while (old.left != NullNode) {
|
||||
ancestors = new Cell(new_, ancestors);
|
||||
|
||||
old = old.left;
|
||||
new_ = new_.left = new Node(old);
|
||||
}
|
||||
|
||||
return new Path(true, new_,
|
||||
new PersistentSet(newRoot, comparator, size),
|
||||
ancestors);
|
||||
}
|
||||
|
||||
public Path<T> last() {
|
||||
if (root == NullNode) return null;
|
||||
|
||||
Node<T> newRoot = new Node(root);
|
||||
Cell<Node<T>> ancestors = null;
|
||||
|
||||
Node<T> old = root;
|
||||
Node<T> new_ = newRoot;
|
||||
while (old.right != NullNode) {
|
||||
ancestors = new Cell(new_, ancestors);
|
||||
|
||||
old = old.right;
|
||||
new_ = new_.right = new Node(old);
|
||||
}
|
||||
|
||||
return new Path(true, new_,
|
||||
new PersistentSet(newRoot, comparator, size),
|
||||
ancestors);
|
||||
}
|
||||
|
||||
public java.util.Iterator<T> iterator() {
|
||||
return new Iterator(first());
|
||||
}
|
||||
|
||||
private Path<T> successor(Path<T> p) {
|
||||
Cell<Node<T>> s = successor(p.node, p.ancestors);
|
||||
if (s == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new Path(false, s.value, p.root, s.next);
|
||||
}
|
||||
}
|
||||
|
||||
private Path<T> predecessor(Path<T> p) {
|
||||
Cell<Node<T>> s = predecessor(p.node, p.ancestors);
|
||||
if (s == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new Path(false, s.value, p.root, s.next);
|
||||
}
|
||||
}
|
||||
|
||||
private static class Node <T> {
|
||||
public T value;
|
||||
public Node left;
|
||||
public Node right;
|
||||
public boolean red;
|
||||
|
||||
public Node(Node<T> basis) {
|
||||
if (basis != null) {
|
||||
value = basis.value;
|
||||
left = basis.left;
|
||||
right = basis.right;
|
||||
red = basis.red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class Path <T> {
|
||||
private final boolean fresh;
|
||||
private final Node<T> node;
|
||||
private final PersistentSet<T> root;
|
||||
private final Cell<Node<T>> ancestors;
|
||||
|
||||
public Path(boolean fresh, Node<T> node, PersistentSet<T> root,
|
||||
Cell<Node<T>> ancestors)
|
||||
{
|
||||
this.fresh = fresh;
|
||||
this.node = node;
|
||||
this.root = root;
|
||||
this.ancestors = ancestors;
|
||||
}
|
||||
|
||||
public T value() {
|
||||
return node.value;
|
||||
}
|
||||
|
||||
public boolean fresh() {
|
||||
return fresh;
|
||||
}
|
||||
|
||||
public PersistentSet<T> root() {
|
||||
return root;
|
||||
}
|
||||
|
||||
public Path<T> successor() {
|
||||
return root.successor(this);
|
||||
}
|
||||
|
||||
public Path<T> predecessor() {
|
||||
return root.predecessor(this);
|
||||
}
|
||||
|
||||
public PersistentSet<T> remove() {
|
||||
if (fresh) throw new IllegalStateException();
|
||||
|
||||
return root.remove(this);
|
||||
}
|
||||
|
||||
public PersistentSet<T> add() {
|
||||
if (! fresh) throw new IllegalStateException();
|
||||
|
||||
return root.add(this);
|
||||
}
|
||||
|
||||
public PersistentSet<T> replaceWith(T value) {
|
||||
if (fresh) throw new IllegalStateException();
|
||||
if (root.comparator.compare(node.value, value) != 0)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
node.value = value;
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
||||
public class Iterator <T> implements java.util.Iterator <T> {
|
||||
private PersistentSet.Path<T> path;
|
||||
|
||||
private Iterator(PersistentSet.Path<T> path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
private Iterator(Iterator<T> start) {
|
||||
path = start.path;
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return path != null;
|
||||
}
|
||||
|
||||
public T next() {
|
||||
PersistentSet.Path<T> p = path;
|
||||
path = path.successor();
|
||||
return p.value();
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
}
|
19
sgx-jvm/avian/classpath/avian/Singleton.java
Normal file
19
sgx-jvm/avian/classpath/avian/Singleton.java
Normal file
@ -0,0 +1,19 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
public abstract class Singleton {
|
||||
public static native int getInt(Object singleton, int offset);
|
||||
public static native long getLong(Object singleton, int offset);
|
||||
public static native Object getObject(Object singleton, int offset);
|
||||
|
||||
// Fields in types.def
|
||||
}
|
80
sgx-jvm/avian/classpath/avian/Stream.java
Normal file
80
sgx-jvm/avian/classpath/avian/Stream.java
Normal file
@ -0,0 +1,80 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.EOFException;
|
||||
|
||||
public abstract class Stream {
|
||||
public static void write1(OutputStream out, int v) throws IOException {
|
||||
out.write(v & 0xFF);
|
||||
}
|
||||
|
||||
public static int read1(InputStream in) throws IOException {
|
||||
return in.read();
|
||||
}
|
||||
|
||||
public static void write2(OutputStream out, int v) throws IOException {
|
||||
out.write((v >>> 8) & 0xFF);
|
||||
out.write((v ) & 0xFF);
|
||||
}
|
||||
|
||||
public static int read2(InputStream in) throws IOException {
|
||||
int b1 = in.read();
|
||||
int b2 = in.read();
|
||||
if (b2 == -1) throw new EOFException();
|
||||
return ((b1 << 8) | (b2 & 0xFF));
|
||||
}
|
||||
|
||||
public static void write4(OutputStream out, int v) throws IOException {
|
||||
out.write((v >>> 24) & 0xFF);
|
||||
out.write((v >>> 16) & 0xFF);
|
||||
out.write((v >>> 8) & 0xFF);
|
||||
out.write((v ) & 0xFF);
|
||||
}
|
||||
|
||||
public static int read4(InputStream in) throws IOException {
|
||||
int b1 = in.read();
|
||||
int b2 = in.read();
|
||||
int b3 = in.read();
|
||||
int b4 = in.read();
|
||||
if (b4 == -1) throw new EOFException();
|
||||
return ((b1 << 24) | (b2 << 16) | (b3 << 8) | (b4));
|
||||
}
|
||||
|
||||
public static void write8(OutputStream out, long v) throws IOException {
|
||||
write4(out, (int) (v >>> 32) & 0xFFFFFFFF);
|
||||
write4(out, (int) (v ) & 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
public static long read8(InputStream in) throws IOException {
|
||||
long b1 = in.read();
|
||||
long b2 = in.read();
|
||||
long b3 = in.read();
|
||||
long b4 = in.read();
|
||||
long b5 = in.read();
|
||||
long b6 = in.read();
|
||||
long b7 = in.read();
|
||||
long b8 = in.read();
|
||||
if (b8 == -1) throw new EOFException();
|
||||
return ((b1 << 56) | (b2 << 48) | (b3 << 40) | (b4 << 32) |
|
||||
(b5 << 24) | (b6 << 16) | (b7 << 8) | (b8));
|
||||
}
|
||||
|
||||
public static void set4(byte[] array, int offset, int v) {
|
||||
array[offset ] = (byte) ((v >>> 24) & 0xFF);
|
||||
array[offset + 1] = (byte) ((v >>> 16) & 0xFF);
|
||||
array[offset + 2] = (byte) ((v >>> 8) & 0xFF);
|
||||
array[offset + 3] = (byte) ((v ) & 0xFF);
|
||||
}
|
||||
}
|
176
sgx-jvm/avian/classpath/avian/SystemClassLoader.java
Normal file
176
sgx-jvm/avian/classpath/avian/SystemClassLoader.java
Normal file
@ -0,0 +1,176 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.MalformedURLException;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
public class SystemClassLoader extends ClassLoader {
|
||||
public static native ClassLoader appLoader();
|
||||
|
||||
private native VMClass findVMClass(String name)
|
||||
throws ClassNotFoundException;
|
||||
|
||||
protected Class findClass(String name) throws ClassNotFoundException {
|
||||
return getClass(findVMClass(name));
|
||||
}
|
||||
|
||||
public static native Class getClass(VMClass vmClass);
|
||||
|
||||
public static native VMClass vmClass(Class jClass);
|
||||
|
||||
private native VMClass findLoadedVMClass(String name);
|
||||
|
||||
protected Class reallyFindLoadedClass(String name){
|
||||
VMClass c = findLoadedVMClass(name);
|
||||
return c == null ? null : getClass(c);
|
||||
}
|
||||
|
||||
protected Class loadClass(String name, boolean resolve)
|
||||
throws ClassNotFoundException
|
||||
{
|
||||
Class c = findLoadedClass(name);
|
||||
if (c == null) {
|
||||
ClassLoader parent = getParent();
|
||||
if (parent != null) {
|
||||
try {
|
||||
c = parent.loadClass(name);
|
||||
} catch (ClassNotFoundException ok) { }
|
||||
}
|
||||
|
||||
if (c == null) {
|
||||
c = findClass(name);
|
||||
}
|
||||
}
|
||||
|
||||
if (resolve) {
|
||||
resolveClass(c);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
private native String resourceURLPrefix(String name);
|
||||
|
||||
protected URL findResource(String name) {
|
||||
String prefix = resourceURLPrefix(name);
|
||||
if (prefix != null) {
|
||||
try {
|
||||
return new URL(prefix + name);
|
||||
} catch (MalformedURLException ignored) { }
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Package getPackage(String name) {
|
||||
Package p = super.getPackage(name);
|
||||
if (p == null) {
|
||||
String source = getPackageSource(name);
|
||||
if (source != null) {
|
||||
// todo: load attributes from JAR manifest
|
||||
definePackage(name, null, null, null, null, null, null, null);
|
||||
} else {
|
||||
definePackage(name, null, null, null, null, null, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
return super.getPackage(name);
|
||||
}
|
||||
|
||||
protected static native String getPackageSource(String name);
|
||||
|
||||
// OpenJDK's java.lang.ClassLoader.getResource makes use of
|
||||
// sun.misc.Launcher to load bootstrap resources, which is not
|
||||
// appropriate for the Avian build, so we override it to ensure we
|
||||
// get the behavior we want. This implementation is the same as
|
||||
// that of Avian's java.lang.ClassLoader.getResource.
|
||||
public URL getResource(String path) {
|
||||
URL url = null;
|
||||
ClassLoader parent = getParent();
|
||||
if (parent != null) {
|
||||
url = parent.getResource(path);
|
||||
}
|
||||
|
||||
if (url == null) {
|
||||
url = findResource(path);
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
// As above, we override this method to avoid inappropriate behavior
|
||||
// in OpenJDK's java.lang.ClassLoader.getResources.
|
||||
public Enumeration<URL> getResources(String name) throws IOException {
|
||||
Collection<URL> urls = new ArrayList<URL>(5);
|
||||
|
||||
ClassLoader parent = getParent();
|
||||
if (parent != null) {
|
||||
for (Enumeration<URL> e = parent.getResources(name);
|
||||
e.hasMoreElements();)
|
||||
{
|
||||
urls.add(e.nextElement());
|
||||
}
|
||||
}
|
||||
|
||||
Enumeration<URL> urls2 = findResources(name);
|
||||
while (urls2.hasMoreElements()) {
|
||||
urls.add(urls2.nextElement());
|
||||
}
|
||||
|
||||
return Collections.enumeration(urls);
|
||||
}
|
||||
|
||||
private class ResourceEnumeration implements Enumeration<URL> {
|
||||
private long[] finderElementPtrPtr;
|
||||
private String name, urlPrefix;
|
||||
|
||||
public ResourceEnumeration(String name) {
|
||||
this.name = name;
|
||||
finderElementPtrPtr = new long[1];
|
||||
urlPrefix = nextResourceURLPrefix();
|
||||
}
|
||||
|
||||
private native String nextResourceURLPrefix(SystemClassLoader loader,
|
||||
String name, long[] finderElementPtrPtr);
|
||||
|
||||
private String nextResourceURLPrefix() {
|
||||
return nextResourceURLPrefix(SystemClassLoader.this, name,
|
||||
finderElementPtrPtr);
|
||||
}
|
||||
|
||||
public boolean hasMoreElements() {
|
||||
return urlPrefix != null;
|
||||
}
|
||||
|
||||
public URL nextElement() {
|
||||
if (urlPrefix == null) throw new NoSuchElementException();
|
||||
URL result;
|
||||
try {
|
||||
result = new URL(urlPrefix + name);
|
||||
} catch (MalformedURLException ignored) {
|
||||
result = null;
|
||||
}
|
||||
if (finderElementPtrPtr[0] == 0l) urlPrefix = null;
|
||||
else urlPrefix = nextResourceURLPrefix();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
protected Enumeration<URL> findResources(String name) {
|
||||
return new ResourceEnumeration(name);
|
||||
}
|
||||
}
|
71
sgx-jvm/avian/classpath/avian/Traces.java
Normal file
71
sgx-jvm/avian/classpath/avian/Traces.java
Normal file
@ -0,0 +1,71 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ServerSocketChannel;
|
||||
import java.nio.channels.SocketChannel;
|
||||
|
||||
public class Traces {
|
||||
private static final String Newline = System.getProperty("line.separator");
|
||||
|
||||
private static String traceAllThreads() {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
|
||||
Thread[] threads = new Thread[Thread.activeCount()];
|
||||
|
||||
int count = Thread.enumerate(threads);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
traceThread(threads[i], buffer);
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
private static String traceThread(Thread thread) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
|
||||
traceThread(thread, buffer);
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
private static void traceThread(Thread thread, StringBuilder buffer) {
|
||||
buffer.append(thread).append(Newline);
|
||||
for (StackTraceElement e: thread.getStackTrace()) {
|
||||
buffer.append("\tat ").append(e).append(Newline);
|
||||
}
|
||||
}
|
||||
|
||||
public static void startTraceListener(final String host, final int port) {
|
||||
Thread t = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
ServerSocketChannel server = ServerSocketChannel.open();
|
||||
server.socket().bind(new InetSocketAddress(host, port));
|
||||
while (true) {
|
||||
SocketChannel c = server.accept();
|
||||
try {
|
||||
c.write(ByteBuffer.wrap(traceAllThreads().getBytes()));
|
||||
} finally {
|
||||
c.close();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
}
|
||||
}
|
118
sgx-jvm/avian/classpath/avian/Utf8.java
Normal file
118
sgx-jvm/avian/classpath/avian/Utf8.java
Normal file
@ -0,0 +1,118 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
public class Utf8 {
|
||||
public static boolean test(Object data) {
|
||||
if (!(data instanceof byte[])) return false;
|
||||
byte[] b = (byte[])data;
|
||||
for (int i = 0; i < b.length; ++i) {
|
||||
if (((int)b[i] & 0x080) != 0) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static byte[] encode(char[] s16, int offset, int length) {
|
||||
ByteArrayOutputStream buf = new ByteArrayOutputStream();
|
||||
for (int i = offset; i < offset+length; ++i) {
|
||||
char c = s16[i];
|
||||
if (c == '\u0000') { // null char
|
||||
buf.write(0);
|
||||
buf.write(0);
|
||||
} else if (c < 0x080) { // 1 byte char
|
||||
buf.write(c);
|
||||
} else if (c < 0x0800) { // 2 byte char
|
||||
buf.write(0x0c0 | (c >>> 6));
|
||||
buf.write(0x080 | (c & 0x03f));
|
||||
} else { // 3 byte char
|
||||
buf.write(0x0e0 | ((c >>> 12) & 0x0f));
|
||||
buf.write(0x080 | ((c >>> 6) & 0x03f));
|
||||
buf.write(0x080 | (c & 0x03f));
|
||||
}
|
||||
}
|
||||
return buf.toByteArray();
|
||||
}
|
||||
|
||||
public static Object decode(byte[] s8, int offset, int length) {
|
||||
Object buf = new byte[length];
|
||||
boolean isMultiByte = false;
|
||||
int i=offset, j=0;
|
||||
while (i < offset+length) {
|
||||
int x = s8[i++];
|
||||
if ((x & 0x080) == 0x0) { // 1 byte char
|
||||
if (x == 0) { // 2 byte null char
|
||||
if (i == offset + length) {
|
||||
return null;
|
||||
}
|
||||
++ i;
|
||||
}
|
||||
cram(buf, j++, x);
|
||||
} else if ((x & 0x0e0) == 0x0c0) { // 2 byte char
|
||||
if (i == offset + length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!isMultiByte) {
|
||||
buf = widen(buf, j, length-1);
|
||||
isMultiByte = true;
|
||||
}
|
||||
int y = s8[i++];
|
||||
cram(buf, j++, ((x & 0x1f) << 6) | (y & 0x3f));
|
||||
} else if ((x & 0x0f0) == 0x0e0) { // 3 byte char
|
||||
if (i + 1 >= offset + length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!isMultiByte) {
|
||||
buf = widen(buf, j, length-2);
|
||||
isMultiByte = true;
|
||||
}
|
||||
int y = s8[i++]; int z = s8[i++];
|
||||
cram(buf, j++, ((x & 0xf) << 12) | ((y & 0x3f) << 6) | (z & 0x3f));
|
||||
}
|
||||
}
|
||||
|
||||
return trim(buf, j);
|
||||
}
|
||||
|
||||
public static char[] decode16(byte[] s8, int offset, int length) {
|
||||
Object decoded = decode(s8, offset, length);
|
||||
if (decoded == null) {
|
||||
return null;
|
||||
} else if (decoded instanceof char[]) {
|
||||
return (char[])decoded;
|
||||
} else {
|
||||
return (char[])widen(decoded, length, length);
|
||||
}
|
||||
}
|
||||
|
||||
private static void cram(Object data, int index, int val) {
|
||||
if (data instanceof byte[]) ((byte[])data)[index] = (byte)val;
|
||||
else ((char[])data)[index] = (char)val;
|
||||
}
|
||||
|
||||
private static Object widen(Object data, int length, int capacity) {
|
||||
byte[] src = (byte[])data;
|
||||
char[] result = new char[capacity];
|
||||
for (int i = 0; i < length; ++i) result[i] = (char)((int)src[i] & 0x0ff);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Object trim(Object data, int length) {
|
||||
if (data instanceof byte[]) return data;
|
||||
if (((char[])data).length == length) return data;
|
||||
char[] result = new char[length];
|
||||
System.arraycopy(data, 0, result, 0, length);
|
||||
return result;
|
||||
}
|
||||
}
|
42
sgx-jvm/avian/classpath/avian/VMClass.java
Normal file
42
sgx-jvm/avian/classpath/avian/VMClass.java
Normal file
@ -0,0 +1,42 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
public class VMClass {
|
||||
public short flags;
|
||||
public short vmFlags;
|
||||
public short fixedSize;
|
||||
public byte arrayElementSize;
|
||||
public byte arrayDimensions;
|
||||
public VMClass arrayElementClass;
|
||||
public int runtimeDataIndex;
|
||||
public int[] objectMask;
|
||||
public byte[] name;
|
||||
public byte[] sourceFile;
|
||||
public VMClass super_;
|
||||
public Object[] interfaceTable;
|
||||
public VMMethod[] virtualTable;
|
||||
public VMField[] fieldTable;
|
||||
/**
|
||||
* Methods declared in this class, plus any abstract virtual methods
|
||||
* inherited from implemented or extended interfaces. If addendum
|
||||
* is non-null and addendum.declaredMethodCount is non-negative,
|
||||
* then the first addendum.declaredMethodCount methods are declared
|
||||
* methods, while the rest are abstract virtual methods. If
|
||||
* addendum is null or addendum.declaredMethodCount is negative, all
|
||||
* are declared methods.
|
||||
*/
|
||||
public VMMethod[] methodTable;
|
||||
public ClassAddendum addendum;
|
||||
public Singleton staticTable;
|
||||
public ClassLoader loader;
|
||||
public byte[] source;
|
||||
}
|
23
sgx-jvm/avian/classpath/avian/VMField.java
Normal file
23
sgx-jvm/avian/classpath/avian/VMField.java
Normal file
@ -0,0 +1,23 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
public class VMField {
|
||||
public byte vmFlags;
|
||||
public byte code;
|
||||
public short flags;
|
||||
public short offset;
|
||||
public int nativeID;
|
||||
public byte[] name;
|
||||
public byte[] spec;
|
||||
public FieldAddendum addendum;
|
||||
public VMClass class_;
|
||||
}
|
31
sgx-jvm/avian/classpath/avian/VMMethod.java
Normal file
31
sgx-jvm/avian/classpath/avian/VMMethod.java
Normal file
@ -0,0 +1,31 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
public class VMMethod {
|
||||
public byte vmFlags;
|
||||
public byte returnCode;
|
||||
public byte parameterCount;
|
||||
public byte parameterFootprint;
|
||||
public short flags;
|
||||
public short offset;
|
||||
public int nativeID;
|
||||
public int runtimeDataIndex;
|
||||
public byte[] name;
|
||||
public byte[] spec;
|
||||
public MethodAddendum addendum;
|
||||
public VMClass class_;
|
||||
public Code code;
|
||||
|
||||
public boolean hasAnnotations() {
|
||||
return addendum != null && addendum.annotationTable != null;
|
||||
}
|
||||
}
|
111
sgx-jvm/avian/classpath/avian/avianvmresource/Handler.java
Normal file
111
sgx-jvm/avian/classpath/avian/avianvmresource/Handler.java
Normal file
@ -0,0 +1,111 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian.avianvmresource;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.URLStreamHandler;
|
||||
import java.net.URLConnection;
|
||||
import java.io.IOException;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class Handler extends URLStreamHandler {
|
||||
protected URLConnection openConnection(URL url) {
|
||||
return new ResourceConnection(url);
|
||||
}
|
||||
|
||||
private static class ResourceConnection extends URLConnection {
|
||||
public ResourceConnection(URL url) {
|
||||
super(url);
|
||||
}
|
||||
|
||||
public int getContentLength() {
|
||||
return ResourceInputStream.getContentLength(url.getFile());
|
||||
}
|
||||
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return new ResourceInputStream(url.getFile());
|
||||
}
|
||||
|
||||
public void connect() {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
private static class ResourceInputStream extends InputStream {
|
||||
private long peer;
|
||||
private int position;
|
||||
|
||||
public ResourceInputStream(String path) throws IOException {
|
||||
peer = open(path);
|
||||
if (peer == 0) {
|
||||
throw new FileNotFoundException(path);
|
||||
}
|
||||
}
|
||||
|
||||
private static native int getContentLength(String path);
|
||||
|
||||
private static native long open(String path) throws IOException;
|
||||
|
||||
private static native int read(long peer, int position) throws IOException;
|
||||
|
||||
private static native int read(long peer, int position,
|
||||
byte[] b, int offset, int length)
|
||||
throws IOException;
|
||||
|
||||
public static native void close(long peer) throws IOException;
|
||||
|
||||
public static native int available(long peer, int position);
|
||||
|
||||
public int available() {
|
||||
return available(peer, position);
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
if (peer != 0) {
|
||||
int c = read(peer, position);
|
||||
if (c >= 0) {
|
||||
++ position;
|
||||
}
|
||||
return c;
|
||||
} else {
|
||||
throw new IOException();
|
||||
}
|
||||
}
|
||||
|
||||
public int read(byte[] b, int offset, int length) throws IOException {
|
||||
if (peer != 0) {
|
||||
if (b == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
if (offset < 0 || offset + length > b.length) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
int c = read(peer, position, b, offset, length);
|
||||
if (c >= 0) {
|
||||
position += c;
|
||||
}
|
||||
return c;
|
||||
} else {
|
||||
throw new IOException();
|
||||
}
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
if (peer != 0) {
|
||||
close(peer);
|
||||
peer = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
44
sgx-jvm/avian/classpath/avian/file/Handler.java
Normal file
44
sgx-jvm/avian/classpath/avian/file/Handler.java
Normal file
@ -0,0 +1,44 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian.file;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.URLStreamHandler;
|
||||
import java.net.URLConnection;
|
||||
import java.io.IOException;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class Handler extends URLStreamHandler {
|
||||
protected URLConnection openConnection(URL url) {
|
||||
return new FileURLConnection(url);
|
||||
}
|
||||
|
||||
private static class FileURLConnection extends URLConnection {
|
||||
public FileURLConnection(URL url) {
|
||||
super(url);
|
||||
}
|
||||
|
||||
public int getContentLength() {
|
||||
return (int) new File(url.getFile()).length();
|
||||
}
|
||||
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return new FileInputStream(new File(url.getFile()));
|
||||
}
|
||||
|
||||
public void connect() {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
120
sgx-jvm/avian/classpath/avian/http/Handler.java
Normal file
120
sgx-jvm/avian/classpath/avian/http/Handler.java
Normal file
@ -0,0 +1,120 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian.http;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.Socket;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLStreamHandler;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Handler extends URLStreamHandler
|
||||
{
|
||||
public URLConnection openConnection(URL url) throws IOException
|
||||
{
|
||||
return new HttpURLConnection(url);
|
||||
}
|
||||
|
||||
class HttpURLConnection extends URLConnection
|
||||
{
|
||||
Socket socket;
|
||||
private BufferedWriter writer;
|
||||
private InputStream bin;
|
||||
private Map<String,String> header = new HashMap<String, String>();
|
||||
private int status;
|
||||
|
||||
protected HttpURLConnection(URL url)
|
||||
{
|
||||
super(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect() throws IOException
|
||||
{
|
||||
if(socket == null)
|
||||
{
|
||||
URLConnection con = null;
|
||||
String host = url.getHost();
|
||||
int port =url.getPort();
|
||||
if(port < 0) port = 80;
|
||||
socket = new Socket(host, port);
|
||||
OutputStream out = socket.getOutputStream();
|
||||
writer = new BufferedWriter(new OutputStreamWriter(out));
|
||||
writer.write("GET " + url.getPath() + " HTTP/1.1");
|
||||
writer.write("\r\nHost: " + host);
|
||||
writer.write("\r\n\r\n");
|
||||
writer.flush();
|
||||
bin = new BufferedInputStream(socket.getInputStream());
|
||||
readHeader();
|
||||
// System.out.println("Status: " + status);
|
||||
// System.out.println("Headers: " + header);
|
||||
}
|
||||
}
|
||||
|
||||
private void readHeader() throws IOException
|
||||
{
|
||||
byte[] buf = new byte[8192];
|
||||
int b = 0;
|
||||
int index = 0;
|
||||
while(b >= 0)
|
||||
{
|
||||
if(index >= 4 && buf[index-4] == '\r' && buf[index-3] == '\n' && buf[index-2] == '\r' && buf[index-1] == '\n')
|
||||
{
|
||||
break;
|
||||
}
|
||||
b = bin.read();
|
||||
buf[index] = (byte) b;
|
||||
index++;
|
||||
if(index >= buf.length)
|
||||
{
|
||||
throw new IOException("Header exceeded maximum size of 8k.");
|
||||
}
|
||||
}
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(buf, 0, index)));
|
||||
String line = reader.readLine();
|
||||
int x = line.indexOf(' ');
|
||||
status = Integer.parseInt(line.substring(x + 1 , line.indexOf(' ', x+1)));
|
||||
while(line != null)
|
||||
{
|
||||
int i = line.indexOf(':');
|
||||
if(i > 0)
|
||||
{
|
||||
header.put(line.substring(0, i), line.substring(i + 1) .trim());
|
||||
}
|
||||
line = reader.readLine();
|
||||
}
|
||||
reader.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() throws IOException
|
||||
{
|
||||
connect();
|
||||
return bin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream getOutputStream() throws IOException
|
||||
{
|
||||
throw new UnsupportedOperationException("Can' write to HTTP Connection");
|
||||
}
|
||||
}
|
||||
}
|
84
sgx-jvm/avian/classpath/avian/jar/Handler.java
Normal file
84
sgx-jvm/avian/classpath/avian/jar/Handler.java
Normal file
@ -0,0 +1,84 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian.jar;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URLStreamHandler;
|
||||
import java.net.JarURLConnection;
|
||||
import java.net.URLConnection;
|
||||
import java.io.IOException;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.JarEntry;
|
||||
|
||||
public class Handler extends URLStreamHandler {
|
||||
protected URLConnection openConnection(URL url) {
|
||||
return new MyJarURLConnection(url);
|
||||
}
|
||||
|
||||
protected void parseURL(URL url, String s, int start, int end)
|
||||
throws MalformedURLException
|
||||
{
|
||||
// skip "jar:"
|
||||
s = s.toString().substring(4);
|
||||
int index = s.indexOf("!/");
|
||||
if (index < 0) {
|
||||
throw new MalformedURLException();
|
||||
}
|
||||
|
||||
URL file = new URL(s.substring(0, index));
|
||||
if (! "file".equals(file.getProtocol())) {
|
||||
throw new RuntimeException
|
||||
("protocol " + file.getProtocol() + " not yet supported");
|
||||
}
|
||||
|
||||
url.set("jar", null, -1, s, null);
|
||||
}
|
||||
|
||||
private static class MyJarURLConnection extends JarURLConnection {
|
||||
private final JarFile file;
|
||||
private final JarEntry entry;
|
||||
|
||||
public MyJarURLConnection(URL url) {
|
||||
super(url);
|
||||
|
||||
String s = url.getFile();
|
||||
int index = s.indexOf("!/");
|
||||
|
||||
try {
|
||||
this.file = new JarFile(new URL(s.substring(0, index)).getFile());
|
||||
this.entry = this.file.getJarEntry(s.substring(index + 2));
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public JarFile getJarFile() throws IOException {
|
||||
return file;
|
||||
}
|
||||
|
||||
public int getContentLength() {
|
||||
return (int)entry.getSize();
|
||||
}
|
||||
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return file.getInputStream(entry);
|
||||
}
|
||||
|
||||
public void connect() {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package dalvik.system;
|
||||
|
||||
public class BaseDexClassLoader extends ClassLoader {
|
||||
public native String getLdLibraryPath();
|
||||
}
|
1015
sgx-jvm/avian/classpath/java-io.cpp
Normal file
1015
sgx-jvm/avian/classpath/java-io.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1253
sgx-jvm/avian/classpath/java-lang.cpp
Normal file
1253
sgx-jvm/avian/classpath/java-lang.cpp
Normal file
File diff suppressed because it is too large
Load Diff
145
sgx-jvm/avian/classpath/java-net.cpp
Normal file
145
sgx-jvm/avian/classpath/java-net.cpp
Normal file
@ -0,0 +1,145 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
#ifndef SGX
|
||||
|
||||
#include "jni.h"
|
||||
#include "avian/machine.h"
|
||||
#include "sockets.h"
|
||||
#include "jni-util.h"
|
||||
|
||||
using namespace avian::classpath::sockets;
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL Java_java_net_Socket_init(JNIEnv* e, jclass)
|
||||
{
|
||||
init(e);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT SOCKET JNICALL
|
||||
Java_java_net_Socket_create(JNIEnv* e, jclass)
|
||||
{
|
||||
return create(e);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL Java_java_net_Socket_connect(JNIEnv* e,
|
||||
jclass,
|
||||
jlong sock,
|
||||
jlong addr,
|
||||
jshort port)
|
||||
{
|
||||
connect(e, static_cast<SOCKET>(sock), addr, port);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL Java_java_net_Socket_bind(JNIEnv* e,
|
||||
jclass,
|
||||
jlong sock,
|
||||
jlong addr,
|
||||
jshort port)
|
||||
{
|
||||
bind(e, static_cast<SOCKET>(sock), addr, port);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_java_net_Socket_abort(JNIEnv* e, jclass, jlong sock)
|
||||
{
|
||||
abort(e, static_cast<SOCKET>(sock));
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_java_net_Socket_close(JNIEnv* e, jclass, jlong sock)
|
||||
{
|
||||
close(e, static_cast<SOCKET>(sock));
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_java_net_Socket_closeOutput(JNIEnv* e, jclass, jlong sock)
|
||||
{
|
||||
close_output(e, static_cast<SOCKET>(sock));
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_java_net_Socket_closeInput(JNIEnv* e, jclass, jlong sock)
|
||||
{
|
||||
close_input(e, static_cast<SOCKET>(sock));
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Avian_java_net_Socket_send(vm::Thread* t, vm::object, uintptr_t* arguments)
|
||||
{ /* SOCKET s, object buffer_obj, int start_pos, int count */
|
||||
SOCKET& s = *(reinterpret_cast<SOCKET*>(&arguments[0]));
|
||||
vm::GcByteArray* buffer_obj = vm::cast<vm::GcByteArray>(
|
||||
t, reinterpret_cast<vm::object>(arguments[2]));
|
||||
int32_t& start_pos = *(reinterpret_cast<int32_t*>(&arguments[3]));
|
||||
int32_t& count = *(reinterpret_cast<int32_t*>(&arguments[4]));
|
||||
char* buffer = reinterpret_cast<char*>(&buffer_obj->body()[start_pos]);
|
||||
avian::classpath::sockets::send((JNIEnv*)t, s, buffer, count);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT int64_t JNICALL
|
||||
Avian_java_net_Socket_recv(vm::Thread* t, vm::object, uintptr_t* arguments)
|
||||
{ /* SOCKET s, object buffer_obj, int start_pos, int count */
|
||||
SOCKET& s = *(reinterpret_cast<SOCKET*>(&arguments[0]));
|
||||
vm::GcByteArray* buffer_obj = vm::cast<vm::GcByteArray>(
|
||||
t, reinterpret_cast<vm::object>(arguments[2]));
|
||||
int32_t& start_pos = *(reinterpret_cast<int32_t*>(&arguments[3]));
|
||||
int32_t& count = *(reinterpret_cast<int32_t*>(&arguments[4]));
|
||||
char* buffer = reinterpret_cast<char*>(&buffer_obj->body()[start_pos]);
|
||||
return avian::classpath::sockets::recv((JNIEnv*)t, s, buffer, count);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_java_net_InetAddress_ipv4AddressForName(JNIEnv* e,
|
||||
jclass,
|
||||
jstring name)
|
||||
{
|
||||
if(!name) {
|
||||
throwNew(e, "java/lang/NullPointerException", 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* chars = e->GetStringUTFChars(name, 0);
|
||||
if (chars) {
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
hostent* host = gethostbyname(chars);
|
||||
e->ReleaseStringUTFChars(name, chars);
|
||||
if (host) {
|
||||
return ntohl(reinterpret_cast<in_addr*>(host->h_addr_list[0])->s_addr);
|
||||
} else {
|
||||
throwNew(e, "java/net/UnknownHostException", 0);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
addrinfo hints;
|
||||
memset(&hints, 0, sizeof(addrinfo));
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
addrinfo* result;
|
||||
int r = getaddrinfo(chars, 0, &hints, &result);
|
||||
e->ReleaseStringUTFChars(name, chars);
|
||||
|
||||
if (r != 0) {
|
||||
throwNew(e, "java/net/UnknownHostException", 0);
|
||||
return 0;
|
||||
} else {
|
||||
int address = ntohl(
|
||||
reinterpret_cast<sockaddr_in*>(result->ai_addr)->sin_addr.s_addr);
|
||||
|
||||
freeaddrinfo(result);
|
||||
return address;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
throwNew(e, "java/lang/OutOfMemoryError", 0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !SGX
|
1102
sgx-jvm/avian/classpath/java-nio.cpp
Normal file
1102
sgx-jvm/avian/classpath/java-nio.cpp
Normal file
File diff suppressed because it is too large
Load Diff
172
sgx-jvm/avian/classpath/java-util-zip.cpp
Normal file
172
sgx-jvm/avian/classpath/java-util-zip.cpp
Normal file
@ -0,0 +1,172 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
#include "avian/zlib-custom.h"
|
||||
|
||||
#include "jni.h"
|
||||
#include "jni-util.h"
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_java_util_zip_Inflater_make(JNIEnv* e, jclass, jboolean nowrap)
|
||||
{
|
||||
z_stream* s = static_cast<z_stream*>(malloc(sizeof(z_stream)));
|
||||
if (s == 0) {
|
||||
throwNew(e, "java/lang/OutOfMemoryError", 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(s, 0, sizeof(z_stream));
|
||||
|
||||
int r = inflateInit2(s, (nowrap ? -15 : 15));
|
||||
if (r != Z_OK) {
|
||||
free(s);
|
||||
throwNew(e, "java/lang/RuntimeException", zError(r));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return reinterpret_cast<jlong>(s);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_java_util_zip_Inflater_dispose(JNIEnv*, jclass, jlong peer)
|
||||
{
|
||||
z_stream* s = reinterpret_cast<z_stream*>(peer);
|
||||
inflateEnd(s);
|
||||
free(s);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_java_util_zip_Inflater_inflate(JNIEnv* e,
|
||||
jclass,
|
||||
jlong peer,
|
||||
jbyteArray input,
|
||||
jint inputOffset,
|
||||
jint inputLength,
|
||||
jbyteArray output,
|
||||
jint outputOffset,
|
||||
jint outputLength,
|
||||
jintArray results)
|
||||
{
|
||||
z_stream* s = reinterpret_cast<z_stream*>(peer);
|
||||
|
||||
jbyte* in = static_cast<jbyte*>(malloc(inputLength));
|
||||
if (in == 0) {
|
||||
throwNew(e, "java/lang/OutOfMemoryError", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
jbyte* out = static_cast<jbyte*>(malloc(outputLength));
|
||||
if (out == 0) {
|
||||
free(in);
|
||||
throwNew(e, "java/lang/OutOfMemoryError", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
e->GetByteArrayRegion(input, inputOffset, inputLength, in);
|
||||
|
||||
s->next_in = reinterpret_cast<Bytef*>(in);
|
||||
s->avail_in = inputLength;
|
||||
s->next_out = reinterpret_cast<Bytef*>(out);
|
||||
s->avail_out = outputLength;
|
||||
|
||||
int r = inflate(s, Z_SYNC_FLUSH);
|
||||
jint resultArray[3] = {r,
|
||||
static_cast<jint>(inputLength - s->avail_in),
|
||||
static_cast<jint>(outputLength - s->avail_out)};
|
||||
|
||||
free(in);
|
||||
|
||||
e->SetByteArrayRegion(output, outputOffset, resultArray[2], out);
|
||||
free(out);
|
||||
|
||||
e->SetIntArrayRegion(results, 0, 3, resultArray);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_java_util_zip_Deflater_make(JNIEnv* e,
|
||||
jclass,
|
||||
jboolean nowrap,
|
||||
jint level)
|
||||
{
|
||||
z_stream* s = static_cast<z_stream*>(malloc(sizeof(z_stream)));
|
||||
if (s == 0) {
|
||||
throwNew(e, "java/lang/OutOfMemoryError", 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(s, 0, sizeof(z_stream));
|
||||
|
||||
int r = deflateInit2(s, level, (nowrap ? -15 : 15));
|
||||
if (r != Z_OK) {
|
||||
free(s);
|
||||
throwNew(e, "java/lang/RuntimeException", zError(r));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return reinterpret_cast<jlong>(s);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_java_util_zip_Deflater_dispose(JNIEnv*, jclass, jlong peer)
|
||||
{
|
||||
z_stream* s = reinterpret_cast<z_stream*>(peer);
|
||||
deflateEnd(s);
|
||||
free(s);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_java_util_zip_Deflater_deflate(JNIEnv* e,
|
||||
jclass,
|
||||
jlong peer,
|
||||
jbyteArray input,
|
||||
jint inputOffset,
|
||||
jint inputLength,
|
||||
jbyteArray output,
|
||||
jint outputOffset,
|
||||
jint outputLength,
|
||||
jboolean finish,
|
||||
jintArray results)
|
||||
{
|
||||
z_stream* s = reinterpret_cast<z_stream*>(peer);
|
||||
|
||||
jbyte* in = static_cast<jbyte*>(malloc(inputLength));
|
||||
if (in == 0) {
|
||||
throwNew(e, "java/lang/OutOfMemoryError", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
jbyte* out = static_cast<jbyte*>(malloc(outputLength));
|
||||
if (out == 0) {
|
||||
free(in);
|
||||
throwNew(e, "java/lang/OutOfMemoryError", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
e->GetByteArrayRegion(input, inputOffset, inputLength, in);
|
||||
|
||||
s->next_in = reinterpret_cast<Bytef*>(in);
|
||||
s->avail_in = inputLength;
|
||||
s->next_out = reinterpret_cast<Bytef*>(out);
|
||||
s->avail_out = outputLength;
|
||||
|
||||
int r = deflate(s, finish ? Z_FINISH : Z_NO_FLUSH);
|
||||
jint resultArray[3] = {r,
|
||||
static_cast<jint>(inputLength - s->avail_in),
|
||||
static_cast<jint>(outputLength - s->avail_out)};
|
||||
|
||||
free(in);
|
||||
|
||||
e->SetByteArrayRegion(output, outputOffset, resultArray[2], out);
|
||||
free(out);
|
||||
|
||||
e->SetIntArrayRegion(results, 0, 3, resultArray);
|
||||
}
|
58
sgx-jvm/avian/classpath/java-util.cpp
Normal file
58
sgx-jvm/avian/classpath/java-util.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
#include "time.h"
|
||||
#include "jni.h"
|
||||
#include "jni-util.h"
|
||||
|
||||
namespace {
|
||||
|
||||
#if (!defined PLATFORM_WINDOWS) || (defined _MSC_VER)
|
||||
|
||||
void removeNewline(char* s)
|
||||
{
|
||||
for (; s; ++s) {
|
||||
if (*s == '\n') {
|
||||
*s = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
extern "C" JNIEXPORT jstring JNICALL
|
||||
Java_java_util_Date_toString(JNIEnv* e, jclass c UNUSED, jlong when)
|
||||
{
|
||||
const unsigned BufferSize UNUSED = 27;
|
||||
|
||||
time_t time = when / 1000;
|
||||
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
e->MonitorEnter(c);
|
||||
#ifdef _MSC_VER
|
||||
char buffer[BufferSize];
|
||||
ctime_s(buffer, BufferSize, &time);
|
||||
removeNewline(buffer);
|
||||
#else
|
||||
char* buffer = ctime(&time);
|
||||
#endif
|
||||
jstring r = e->NewStringUTF(buffer);
|
||||
e->MonitorExit(c);
|
||||
return r;
|
||||
#else
|
||||
char buffer[BufferSize];
|
||||
ctime_r(&time, buffer);
|
||||
removeNewline(buffer);
|
||||
return e->NewStringUTF(buffer);
|
||||
#endif
|
||||
}
|
88
sgx-jvm/avian/classpath/java/io/BufferedInputStream.java
Normal file
88
sgx-jvm/avian/classpath/java/io/BufferedInputStream.java
Normal file
@ -0,0 +1,88 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
package java.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class BufferedInputStream extends InputStream {
|
||||
private final InputStream in;
|
||||
private final byte[] buffer;
|
||||
private int position;
|
||||
private int limit;
|
||||
|
||||
public BufferedInputStream(InputStream in, int size) {
|
||||
this.in = in;
|
||||
this.buffer = new byte[size];
|
||||
}
|
||||
|
||||
public BufferedInputStream(InputStream in) {
|
||||
this(in, 4096);
|
||||
}
|
||||
|
||||
private int fill() throws IOException {
|
||||
position = 0;
|
||||
limit = in.read(buffer);
|
||||
|
||||
return limit;
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
if (position >= limit && fill() == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return buffer[position++] & 0xFF;
|
||||
}
|
||||
|
||||
public int read(byte[] b, int offset, int length) throws IOException {
|
||||
int count = 0;
|
||||
if (position >= limit && fill() == -1) {
|
||||
return -1;
|
||||
}
|
||||
if (position < limit) {
|
||||
int remaining = limit - position;
|
||||
if (remaining > length) {
|
||||
remaining = length;
|
||||
}
|
||||
|
||||
System.arraycopy(buffer, position, b, offset, remaining);
|
||||
|
||||
count += remaining;
|
||||
position += remaining;
|
||||
offset += remaining;
|
||||
length -= remaining;
|
||||
}
|
||||
while (length > 0 && in.available() > 0)
|
||||
{
|
||||
int c = in.read(b, offset, length);
|
||||
if (c == -1) {
|
||||
if (count == 0) {
|
||||
count = -1;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
offset += c;
|
||||
count += c;
|
||||
length -= c;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public int available() throws IOException {
|
||||
return in.available() + (limit - position);
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
61
sgx-jvm/avian/classpath/java/io/BufferedOutputStream.java
Normal file
61
sgx-jvm/avian/classpath/java/io/BufferedOutputStream.java
Normal file
@ -0,0 +1,61 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class BufferedOutputStream extends OutputStream {
|
||||
private final OutputStream out;
|
||||
private final byte[] buffer;
|
||||
private int position;
|
||||
|
||||
public BufferedOutputStream(OutputStream out, int size) {
|
||||
this.out = out;
|
||||
this.buffer = new byte[size];
|
||||
}
|
||||
|
||||
public BufferedOutputStream(OutputStream out) {
|
||||
this(out, 4096);
|
||||
}
|
||||
|
||||
private void drain() throws IOException {
|
||||
if (position > 0) {
|
||||
out.write(buffer, 0, position);
|
||||
position = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void write(int c) throws IOException {
|
||||
if (position >= buffer.length) {
|
||||
drain();
|
||||
}
|
||||
|
||||
buffer[position++] = (byte) (c & 0xFF);
|
||||
}
|
||||
|
||||
public void write(byte[] b, int offset, int length) throws IOException {
|
||||
if (length > buffer.length - position) {
|
||||
drain();
|
||||
out.write(b, offset, length);
|
||||
} else {
|
||||
System.arraycopy(b, offset, buffer, position, length);
|
||||
position += length;
|
||||
}
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
drain();
|
||||
out.flush();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
flush();
|
||||
out.close();
|
||||
}
|
||||
}
|
101
sgx-jvm/avian/classpath/java/io/BufferedReader.java
Normal file
101
sgx-jvm/avian/classpath/java/io/BufferedReader.java
Normal file
@ -0,0 +1,101 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class BufferedReader extends Reader {
|
||||
private final Reader in;
|
||||
private final char[] buffer;
|
||||
private int position;
|
||||
private int limit;
|
||||
|
||||
public BufferedReader(Reader in, int bufferSize) {
|
||||
this.in = in;
|
||||
this.buffer = new char[bufferSize];
|
||||
}
|
||||
|
||||
public BufferedReader(Reader in) {
|
||||
this(in, 32);
|
||||
}
|
||||
|
||||
private void fill() throws IOException {
|
||||
position = 0;
|
||||
limit = in.read(buffer);
|
||||
}
|
||||
|
||||
public String readLine() throws IOException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (true) {
|
||||
if (position >= limit) {
|
||||
fill();
|
||||
}
|
||||
|
||||
if (position >= limit) {
|
||||
return sb.length() == 0 ? null : sb.toString();
|
||||
}
|
||||
|
||||
for (int i = position; i < limit; ++i) {
|
||||
if(buffer[i] == '\r') {
|
||||
sb.append(buffer, position, i - position);
|
||||
position = i + 1;
|
||||
if(i+1 < limit && buffer[i+1] == '\n') {
|
||||
position = i + 2;
|
||||
}
|
||||
return sb.toString();
|
||||
} else if (buffer[i] == '\n') {
|
||||
sb.append(buffer, position, i - position);
|
||||
position = i + 1;
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
sb.append(buffer, position, limit-position);
|
||||
position = limit;
|
||||
}
|
||||
}
|
||||
|
||||
public int read(char[] b, int offset, int length) throws IOException {
|
||||
int count = 0;
|
||||
|
||||
if (position >= limit && length < buffer.length) {
|
||||
fill();
|
||||
}
|
||||
|
||||
if (position < limit) {
|
||||
int remaining = limit - position;
|
||||
if (remaining > length) {
|
||||
remaining = length;
|
||||
}
|
||||
|
||||
System.arraycopy(buffer, position, b, offset, remaining);
|
||||
|
||||
count += remaining;
|
||||
position += remaining;
|
||||
offset += remaining;
|
||||
length -= remaining;
|
||||
}
|
||||
|
||||
if (length > 0) {
|
||||
int c = in.read(b, offset, length);
|
||||
if (c == -1) {
|
||||
if (count == 0) {
|
||||
count = -1;
|
||||
}
|
||||
} else {
|
||||
count += c;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
in.close();
|
||||
}
|
||||
}
|
53
sgx-jvm/avian/classpath/java/io/BufferedWriter.java
Normal file
53
sgx-jvm/avian/classpath/java/io/BufferedWriter.java
Normal file
@ -0,0 +1,53 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class BufferedWriter extends Writer {
|
||||
private final Writer out;
|
||||
private final char[] buffer;
|
||||
private int position;
|
||||
|
||||
public BufferedWriter(Writer out, int size) {
|
||||
this.out = out;
|
||||
this.buffer = new char[size];
|
||||
}
|
||||
|
||||
public BufferedWriter(Writer out) {
|
||||
this(out, 4096);
|
||||
}
|
||||
|
||||
private void drain() throws IOException {
|
||||
if (position > 0) {
|
||||
out.write(buffer, 0, position);
|
||||
position = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void write(char[] b, int offset, int length) throws IOException {
|
||||
if (length > buffer.length - position) {
|
||||
drain();
|
||||
out.write(b, offset, length);
|
||||
} else {
|
||||
System.arraycopy(b, offset, buffer, position, length);
|
||||
position += length;
|
||||
}
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
drain();
|
||||
out.flush();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
flush();
|
||||
out.close();
|
||||
}
|
||||
}
|
55
sgx-jvm/avian/classpath/java/io/ByteArrayInputStream.java
Normal file
55
sgx-jvm/avian/classpath/java/io/ByteArrayInputStream.java
Normal file
@ -0,0 +1,55 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class ByteArrayInputStream extends InputStream {
|
||||
private final byte[] array;
|
||||
private int position;
|
||||
private final int limit;
|
||||
|
||||
public ByteArrayInputStream(byte[] array, int offset, int length) {
|
||||
this.array = array;
|
||||
position = offset;
|
||||
this.limit = offset + length;
|
||||
}
|
||||
|
||||
public ByteArrayInputStream(byte[] array) {
|
||||
this(array, 0, array.length);
|
||||
}
|
||||
|
||||
public int read() {
|
||||
if (position < limit) {
|
||||
return array[position++] & 0xff;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public int read(byte[] buffer, int offset, int bufferLength) {
|
||||
if (bufferLength == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (position >= limit) {
|
||||
return -1;
|
||||
}
|
||||
int remaining = limit-position;
|
||||
if (remaining < bufferLength) {
|
||||
bufferLength = remaining;
|
||||
}
|
||||
System.arraycopy(array, position, buffer, offset, bufferLength);
|
||||
position += bufferLength;
|
||||
return bufferLength;
|
||||
}
|
||||
|
||||
public int available() {
|
||||
return limit - position;
|
||||
}
|
||||
}
|
148
sgx-jvm/avian/classpath/java/io/ByteArrayOutputStream.java
Normal file
148
sgx-jvm/avian/classpath/java/io/ByteArrayOutputStream.java
Normal file
@ -0,0 +1,148 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class ByteArrayOutputStream extends OutputStream {
|
||||
private static final int BufferSize = 32;
|
||||
|
||||
private Cell firstCell;
|
||||
private Cell curCell;
|
||||
private int length;
|
||||
private byte[] buffer;
|
||||
private int position;
|
||||
|
||||
public ByteArrayOutputStream(int capacity) { }
|
||||
|
||||
public ByteArrayOutputStream() {
|
||||
this(0);
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
firstCell = null;
|
||||
curCell = null;
|
||||
length = 0;
|
||||
buffer = null;
|
||||
position = 0;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public void write(int c) {
|
||||
if (buffer == null) {
|
||||
buffer = new byte[BufferSize];
|
||||
} else if (position >= buffer.length) {
|
||||
flushBuffer();
|
||||
buffer = new byte[BufferSize];
|
||||
}
|
||||
|
||||
buffer[position++] = (byte) (c & 0xFF);
|
||||
++ length;
|
||||
}
|
||||
|
||||
private byte[] copy(byte[] b, int offset, int length) {
|
||||
byte[] array = new byte[length];
|
||||
System.arraycopy(b, offset, array, 0, length);
|
||||
return array;
|
||||
}
|
||||
|
||||
public void write(byte[] b, int offset, int length) {
|
||||
if (b == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
if (offset < 0 || offset + length > b.length) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
if (length == 0) return;
|
||||
|
||||
if (buffer != null && length <= buffer.length - position) {
|
||||
System.arraycopy(b, offset, buffer, position, length);
|
||||
position += length;
|
||||
} else {
|
||||
flushBuffer();
|
||||
chainCell( new Cell(copy(b, offset, length), 0, length) );
|
||||
}
|
||||
|
||||
this.length += length;
|
||||
}
|
||||
|
||||
private void chainCell(Cell cell){
|
||||
if (curCell == null){
|
||||
firstCell = cell;
|
||||
curCell = cell;
|
||||
}else{
|
||||
curCell.next = cell;
|
||||
curCell = cell;
|
||||
}
|
||||
}
|
||||
|
||||
private void flushBuffer() {
|
||||
if (position > 0) {
|
||||
byte[] b = buffer;
|
||||
int p = position;
|
||||
buffer = null;
|
||||
position = 0;
|
||||
|
||||
chainCell( new Cell(b, 0, p) );
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] toByteArray() {
|
||||
flushBuffer();
|
||||
|
||||
byte[] array = new byte[length];
|
||||
int pos = 0;
|
||||
for (Cell c = firstCell; c != null; c = c.next) {
|
||||
System.arraycopy(c.array, c.offset, array, pos, c.length);
|
||||
pos += c.length;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public synchronized void writeTo(OutputStream out) throws IOException {
|
||||
if (length==0) return;
|
||||
|
||||
if (out == null){
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
flushBuffer();
|
||||
|
||||
for (Cell c = firstCell; c != null; c = c.next) {
|
||||
out.write(c.array, c.offset, c.length);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new String(toByteArray());
|
||||
}
|
||||
|
||||
public String toString(String encoding) throws UnsupportedEncodingException {
|
||||
return new String(toByteArray(), encoding);
|
||||
}
|
||||
|
||||
private static class Cell {
|
||||
public byte[] array;
|
||||
public int offset;
|
||||
public int length;
|
||||
public Cell next = null;
|
||||
|
||||
public Cell(byte[] array, int offset, int length) {
|
||||
this.array = array;
|
||||
this.offset = offset;
|
||||
this.length = length;
|
||||
}
|
||||
}
|
||||
}
|
16
sgx-jvm/avian/classpath/java/io/Closeable.java
Normal file
16
sgx-jvm/avian/classpath/java/io/Closeable.java
Normal file
@ -0,0 +1,16 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public interface Closeable extends AutoCloseable {
|
||||
void close()
|
||||
throws IOException;
|
||||
}
|
29
sgx-jvm/avian/classpath/java/io/DataInput.java
Normal file
29
sgx-jvm/avian/classpath/java/io/DataInput.java
Normal file
@ -0,0 +1,29 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public interface DataInput {
|
||||
boolean readBoolean() throws IOException;
|
||||
byte readByte() throws IOException;
|
||||
char readChar() throws IOException;
|
||||
double readDouble() throws IOException;
|
||||
float readFloat() throws IOException;
|
||||
void readFully(byte[] b) throws IOException;
|
||||
void readFully(byte[] b, int off, int len) throws IOException;
|
||||
int readInt() throws IOException;
|
||||
String readLine() throws IOException;
|
||||
long readLong() throws IOException;
|
||||
short readShort() throws IOException;
|
||||
int readUnsignedByte() throws IOException;
|
||||
int readUnsignedShort() throws IOException;
|
||||
String readUTF() throws IOException;
|
||||
int skipBytes(int n) throws IOException;
|
||||
}
|
132
sgx-jvm/avian/classpath/java/io/DataInputStream.java
Normal file
132
sgx-jvm/avian/classpath/java/io/DataInputStream.java
Normal file
@ -0,0 +1,132 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class DataInputStream extends InputStream implements DataInput {
|
||||
private InputStream in;
|
||||
|
||||
public DataInputStream(InputStream in) {
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
in.close();
|
||||
}
|
||||
|
||||
public int read(byte[] buffer) throws IOException {
|
||||
return in.read(buffer);
|
||||
}
|
||||
|
||||
public int read(byte[] buffer, int offset, int length) throws IOException {
|
||||
return in.read(buffer, offset, length);
|
||||
}
|
||||
|
||||
public void readFully(byte[] b) throws IOException {
|
||||
readFully(b, 0, b.length);
|
||||
}
|
||||
|
||||
public void readFully(byte[] b, int offset, int length) throws IOException {
|
||||
while (length > 0) {
|
||||
int count = read(b, offset, length);
|
||||
if (count < 0) {
|
||||
throw new EOFException("Reached EOF " + length + " bytes too early");
|
||||
}
|
||||
offset += count;
|
||||
length -= count;
|
||||
}
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
return in.read();
|
||||
}
|
||||
|
||||
private int read0() throws IOException {
|
||||
int b = in.read();
|
||||
if (b < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
public boolean readBoolean() throws IOException {
|
||||
return read0() != 0;
|
||||
}
|
||||
|
||||
public byte readByte() throws IOException {
|
||||
return (byte)read0();
|
||||
}
|
||||
|
||||
public short readShort() throws IOException {
|
||||
return (short)((read0() << 8) | read0());
|
||||
}
|
||||
|
||||
public int readInt() throws IOException {
|
||||
return ((read0() << 24) | (read0() << 16) | (read0() << 8) | read0());
|
||||
}
|
||||
|
||||
public float readFloat() throws IOException {
|
||||
return Float.floatToIntBits(readInt());
|
||||
}
|
||||
|
||||
public double readDouble() throws IOException {
|
||||
return Double.doubleToLongBits(readLong());
|
||||
}
|
||||
|
||||
public long readLong() throws IOException {
|
||||
return ((readInt() & 0xffffffffl) << 32) | (readInt() & 0xffffffffl);
|
||||
}
|
||||
|
||||
public char readChar() throws IOException {
|
||||
return (char)readShort();
|
||||
}
|
||||
|
||||
public int readUnsignedByte() throws IOException {
|
||||
return readByte() & 0xff;
|
||||
}
|
||||
|
||||
public int readUnsignedShort() throws IOException {
|
||||
return readShort() & 0xffff;
|
||||
}
|
||||
|
||||
public String readUTF() throws IOException {
|
||||
int length = readUnsignedShort();
|
||||
byte[] bytes = new byte[length];
|
||||
readFully(bytes);
|
||||
return new String(bytes, "UTF-8");
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String readLine() throws IOException {
|
||||
int c = read();
|
||||
if (c < 0) {
|
||||
return null;
|
||||
} else if (c == '\n') {
|
||||
return "";
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (;;) {
|
||||
builder.append((char)c);
|
||||
c = read();
|
||||
if (c < 0 || c == '\n') {
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int skipBytes(int n) throws IOException {
|
||||
for (int count = 0; count < n; ++count) {
|
||||
if (read() < 0) {;
|
||||
return count;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
}
|
28
sgx-jvm/avian/classpath/java/io/DataOutput.java
Normal file
28
sgx-jvm/avian/classpath/java/io/DataOutput.java
Normal file
@ -0,0 +1,28 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public interface DataOutput {
|
||||
void write(byte[] b) throws IOException;
|
||||
void write(byte[] b, int off, int len) throws IOException;
|
||||
void write(int b) throws IOException;
|
||||
void writeBoolean(boolean v) throws IOException;
|
||||
void writeByte(int v) throws IOException;
|
||||
void writeBytes(String s) throws IOException;
|
||||
void writeChar(int v) throws IOException;
|
||||
void writeChars(String s) throws IOException;
|
||||
void writeDouble(double v) throws IOException;
|
||||
void writeFloat(float v) throws IOException;
|
||||
void writeInt(int v) throws IOException;
|
||||
void writeLong(long v) throws IOException;
|
||||
void writeShort(int v) throws IOException;
|
||||
void writeUTF(String s) throws IOException;
|
||||
}
|
99
sgx-jvm/avian/classpath/java/io/DataOutputStream.java
Normal file
99
sgx-jvm/avian/classpath/java/io/DataOutputStream.java
Normal file
@ -0,0 +1,99 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class DataOutputStream extends OutputStream implements DataOutput {
|
||||
private OutputStream out;
|
||||
|
||||
public DataOutputStream(OutputStream out) {
|
||||
this.out = out;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
out.close();
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
out.flush();
|
||||
}
|
||||
|
||||
public void write(byte[] buffer) throws IOException {
|
||||
out.write(buffer);
|
||||
}
|
||||
|
||||
public void write(byte[] buffer, int offset, int length) throws IOException {
|
||||
out.write(buffer, offset, length);
|
||||
}
|
||||
|
||||
public void write(int b) throws IOException {
|
||||
out.write(b);
|
||||
}
|
||||
|
||||
public void writeBoolean(boolean b) throws IOException {
|
||||
writeByte(b ? 1 : 0);
|
||||
}
|
||||
|
||||
public void writeByte(int b) throws IOException {
|
||||
out.write(b);
|
||||
}
|
||||
|
||||
public void writeShort(int s) throws IOException {
|
||||
write((byte)(s >> 8));
|
||||
write((byte)s);
|
||||
}
|
||||
|
||||
public void writeInt(int i) throws IOException {
|
||||
write((byte)(i >> 24));
|
||||
write((byte)(i >> 16));
|
||||
write((byte)(i >> 8));
|
||||
write((byte)i);
|
||||
}
|
||||
|
||||
public void writeFloat(float f) throws IOException {
|
||||
writeInt(Float.floatToIntBits(f));
|
||||
}
|
||||
|
||||
public void writeDouble(double d) throws IOException {
|
||||
writeLong(Double.doubleToLongBits(d));
|
||||
}
|
||||
|
||||
public void writeLong(long l) throws IOException {
|
||||
write((byte)(l >> 56));
|
||||
write((byte)(l >> 48));
|
||||
write((byte)(l >> 40));
|
||||
write((byte)(l >> 32));
|
||||
write((byte)(l >> 24));
|
||||
write((byte)(l >> 16));
|
||||
write((byte)(l >> 8));
|
||||
write((byte)l);
|
||||
}
|
||||
|
||||
public void writeChar(int ch) throws IOException {
|
||||
write((byte)(ch >> 8));
|
||||
write((byte)ch);
|
||||
}
|
||||
|
||||
public void writeChars(String s) throws IOException {
|
||||
for (char ch : s.toCharArray()) {
|
||||
writeChar(ch & 0xffff);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeBytes(String s) throws IOException {
|
||||
out.write(s.getBytes());
|
||||
}
|
||||
|
||||
public void writeUTF(String s) throws IOException {
|
||||
byte[] bytes = s.getBytes("UTF-8");
|
||||
writeShort((short)bytes.length);
|
||||
out.write(bytes);
|
||||
}
|
||||
}
|
21
sgx-jvm/avian/classpath/java/io/EOFException.java
Normal file
21
sgx-jvm/avian/classpath/java/io/EOFException.java
Normal file
@ -0,0 +1,21 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class EOFException extends IOException {
|
||||
public EOFException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public EOFException() {
|
||||
this(null);
|
||||
}
|
||||
}
|
16
sgx-jvm/avian/classpath/java/io/Externalizable.java
Normal file
16
sgx-jvm/avian/classpath/java/io/Externalizable.java
Normal file
@ -0,0 +1,16 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public interface Externalizable {
|
||||
public void readExternal(ObjectInput in);
|
||||
public void writeExternal(ObjectOutput out);
|
||||
}
|
335
sgx-jvm/avian/classpath/java/io/File.java
Normal file
335
sgx-jvm/avian/classpath/java/io/File.java
Normal file
@ -0,0 +1,335 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class File implements Serializable {
|
||||
private static final String FileSeparator
|
||||
= System.getProperty("file.separator");
|
||||
|
||||
private static final boolean IsWindows
|
||||
= System.getProperty("os.name").equals("Windows");
|
||||
|
||||
public static final String separator = FileSeparator;
|
||||
|
||||
public static final char separatorChar = FileSeparator.charAt(0);
|
||||
|
||||
private static final String PathSeparator
|
||||
= System.getProperty("path.separator");
|
||||
|
||||
public static final String pathSeparator = PathSeparator;
|
||||
|
||||
public static final char pathSeparatorChar = PathSeparator.charAt(0);
|
||||
|
||||
// static {
|
||||
// System.loadLibrary("natives");
|
||||
// }
|
||||
|
||||
private final String path;
|
||||
|
||||
public File(String path) {
|
||||
if (path == null) throw new NullPointerException();
|
||||
this.path = normalize(path);
|
||||
}
|
||||
|
||||
public File(String parent, String child) {
|
||||
this(parent + FileSeparator + child);
|
||||
}
|
||||
|
||||
public File(File parent, String child) {
|
||||
this(parent.getPath() + FileSeparator + child);
|
||||
}
|
||||
|
||||
public static File createTempFile(String prefix, String suffix)
|
||||
throws IOException
|
||||
{
|
||||
return createTempFile(prefix, suffix, null);
|
||||
}
|
||||
|
||||
public static File createTempFile(String prefix, String suffix,
|
||||
File directory)
|
||||
throws IOException
|
||||
{
|
||||
if(directory == null) {
|
||||
directory = new File(System.getProperty("java.io.tmpdir"));
|
||||
}
|
||||
if(suffix == null) {
|
||||
suffix = ".tmp";
|
||||
}
|
||||
File ret;
|
||||
long state = System.currentTimeMillis();
|
||||
|
||||
do {
|
||||
ret = generateFile(directory, prefix, state, suffix);
|
||||
state *= 7;
|
||||
state += 3;
|
||||
} while(ret == null);
|
||||
ret.createNewFile();
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static File generateFile(File directory, String prefix, long state, String suffix) {
|
||||
File ret = new File(directory, prefix + state + suffix);
|
||||
if(ret.exists()) {
|
||||
return null;
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
private static String stripSeparators(String p) {
|
||||
while (p.endsWith(FileSeparator)) {
|
||||
p = p.substring(0, p.length() - 1);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
private static String normalize(String path) {
|
||||
if(IsWindows
|
||||
&& path.length() > 2
|
||||
&& path.charAt(0) == '/'
|
||||
&& path.charAt(2) == ':')
|
||||
{
|
||||
// remove a leading slash on Windows
|
||||
path = path.substring(1);
|
||||
}
|
||||
return stripSeparators
|
||||
("\\".equals(FileSeparator) ? path.replace('/', '\\') : path);
|
||||
}
|
||||
|
||||
public static native boolean rename(String old, String new_);
|
||||
|
||||
public boolean renameTo(File newName) {
|
||||
return rename(path, newName.path);
|
||||
}
|
||||
|
||||
private static native boolean isDirectory(String path);
|
||||
|
||||
public boolean isDirectory() {
|
||||
return isDirectory(path);
|
||||
}
|
||||
|
||||
private static native boolean isFile(String path);
|
||||
|
||||
public boolean isFile() {
|
||||
return isFile(path);
|
||||
}
|
||||
|
||||
public boolean isAbsolute() {
|
||||
return path.equals(toAbsolutePath(path));
|
||||
}
|
||||
|
||||
private static native boolean canRead(String path);
|
||||
|
||||
public boolean canRead() {
|
||||
return canRead(path);
|
||||
}
|
||||
|
||||
private static native boolean canWrite(String path);
|
||||
|
||||
public boolean canWrite() {
|
||||
return canWrite(path);
|
||||
}
|
||||
|
||||
private static native boolean canExecute(String path);
|
||||
|
||||
public boolean canExecute() {
|
||||
return canExecute(path);
|
||||
}
|
||||
|
||||
private static native boolean setExecutable(String path, boolean executable, boolean ownerOnly);
|
||||
|
||||
public boolean setExecutable(boolean executable) {
|
||||
return setExecutable(executable, true);
|
||||
}
|
||||
|
||||
public boolean setExecutable(boolean executable, boolean ownerOnly) {
|
||||
return setExecutable(path, executable, ownerOnly);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
int index = path.lastIndexOf(FileSeparator);
|
||||
if (index >= 0) {
|
||||
return path.substring(index + 1);
|
||||
} else {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getPath();
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public String getParent() {
|
||||
int index = path.lastIndexOf(FileSeparator);
|
||||
if (index >= 0) {
|
||||
return normalize(path.substring(0, index));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public File getParentFile() {
|
||||
String s = getParent();
|
||||
return (s == null ? null : new File(s));
|
||||
}
|
||||
|
||||
private static native String toCanonicalPath(String path);
|
||||
|
||||
public String getCanonicalPath() {
|
||||
return toCanonicalPath(path);
|
||||
}
|
||||
|
||||
public File getCanonicalFile() {
|
||||
return new File(getCanonicalPath());
|
||||
}
|
||||
|
||||
private static native String toAbsolutePath(String path);
|
||||
|
||||
public String getAbsolutePath() {
|
||||
return toAbsolutePath(path);
|
||||
}
|
||||
|
||||
public File getAbsoluteFile() {
|
||||
return new File(getAbsolutePath());
|
||||
}
|
||||
|
||||
private static native long length(String path);
|
||||
|
||||
public long length() {
|
||||
return length(path);
|
||||
}
|
||||
|
||||
private static native boolean exists(String path);
|
||||
|
||||
public boolean exists() {
|
||||
return exists(path);
|
||||
}
|
||||
|
||||
private static native void mkdir(String path) throws IOException;
|
||||
|
||||
public boolean mkdir() {
|
||||
try {
|
||||
mkdir(path);
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static native boolean createNewFile(String path) throws IOException;
|
||||
|
||||
public boolean createNewFile() throws IOException {
|
||||
return createNewFile(path);
|
||||
}
|
||||
|
||||
public static native void delete(String path) throws IOException;
|
||||
|
||||
public boolean delete() {
|
||||
try {
|
||||
delete(path);
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean mkdirs() {
|
||||
File parent = getParentFile();
|
||||
if (parent != null) {
|
||||
if (!parent.exists()) {
|
||||
if (!parent.mkdirs()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return mkdir();
|
||||
}
|
||||
|
||||
public File[] listFiles() {
|
||||
return listFiles(null);
|
||||
}
|
||||
|
||||
public File[] listFiles(FilenameFilter filter) {
|
||||
String[] list = list(filter);
|
||||
if (list != null) {
|
||||
File[] result = new File[list.length];
|
||||
for (int i = 0; i < list.length; ++i) {
|
||||
result[i] = new File(this, list[i]);
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String[] list() {
|
||||
return list(null);
|
||||
}
|
||||
|
||||
public String[] list(FilenameFilter filter) {
|
||||
long handle = 0;
|
||||
try {
|
||||
handle = openDir(path);
|
||||
if (handle != 0) {
|
||||
Pair list = null;
|
||||
int count = 0;
|
||||
for (String s = readDir(handle); s != null; s = readDir(handle)) {
|
||||
if (filter == null || filter.accept(this, s)) {
|
||||
list = new Pair(s, list);
|
||||
++ count;
|
||||
}
|
||||
}
|
||||
|
||||
String[] result = new String[count];
|
||||
for (int i = count - 1; i >= 0; --i) {
|
||||
result[i] = list.value;
|
||||
list = list.next;
|
||||
}
|
||||
|
||||
return result;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} finally {
|
||||
if (handle != 0) {
|
||||
closeDir(handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public long lastModified() {
|
||||
return lastModified(path);
|
||||
}
|
||||
private static native long openDir(String path);
|
||||
|
||||
private static native long lastModified(String path);
|
||||
|
||||
private static native String readDir(long handle);
|
||||
|
||||
private static native void closeDir(long handle);
|
||||
|
||||
|
||||
|
||||
private static class Pair {
|
||||
public final String value;
|
||||
public final Pair next;
|
||||
|
||||
public Pair(String value, Pair next) {
|
||||
this.value = value;
|
||||
this.next = next;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
27
sgx-jvm/avian/classpath/java/io/FileDescriptor.java
Normal file
27
sgx-jvm/avian/classpath/java/io/FileDescriptor.java
Normal file
@ -0,0 +1,27 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class FileDescriptor {
|
||||
public static final FileDescriptor in = new FileDescriptor(0);
|
||||
public static final FileDescriptor out = new FileDescriptor(1);
|
||||
public static final FileDescriptor err = new FileDescriptor(2);
|
||||
|
||||
final int value;
|
||||
|
||||
public FileDescriptor(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public FileDescriptor() {
|
||||
this(-1);
|
||||
}
|
||||
}
|
77
sgx-jvm/avian/classpath/java/io/FileInputStream.java
Normal file
77
sgx-jvm/avian/classpath/java/io/FileInputStream.java
Normal file
@ -0,0 +1,77 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class FileInputStream extends InputStream {
|
||||
// static {
|
||||
// System.loadLibrary("natives");
|
||||
// }
|
||||
|
||||
private int fd;
|
||||
private int remaining;
|
||||
|
||||
public FileInputStream(FileDescriptor fd) {
|
||||
this.fd = fd.value;
|
||||
}
|
||||
|
||||
public FileInputStream(String path) throws IOException {
|
||||
fd = open(path);
|
||||
remaining = (int) new File(path).length();
|
||||
}
|
||||
|
||||
public FileInputStream(File file) throws IOException {
|
||||
this(file.getPath());
|
||||
}
|
||||
|
||||
public int available() throws IOException {
|
||||
return remaining;
|
||||
}
|
||||
|
||||
private static native int open(String path) throws IOException;
|
||||
|
||||
private static native int read(int fd) throws IOException;
|
||||
|
||||
private static native int read(int fd, byte[] b, int offset, int length)
|
||||
throws IOException;
|
||||
|
||||
public static native void close(int fd) throws IOException;
|
||||
|
||||
public int read() throws IOException {
|
||||
int c = read(fd);
|
||||
if (c >= 0 && remaining > 0) {
|
||||
-- remaining;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
public int read(byte[] b, int offset, int length) throws IOException {
|
||||
if (b == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
if (offset < 0 || offset + length > b.length) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
int c = read(fd, b, offset, length);
|
||||
if (c > 0 && remaining > 0) {
|
||||
remaining -= c;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
if (fd != -1) {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
}
|
||||
}
|
21
sgx-jvm/avian/classpath/java/io/FileNotFoundException.java
Normal file
21
sgx-jvm/avian/classpath/java/io/FileNotFoundException.java
Normal file
@ -0,0 +1,21 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class FileNotFoundException extends IOException {
|
||||
public FileNotFoundException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public FileNotFoundException() {
|
||||
this(null);
|
||||
}
|
||||
}
|
68
sgx-jvm/avian/classpath/java/io/FileOutputStream.java
Normal file
68
sgx-jvm/avian/classpath/java/io/FileOutputStream.java
Normal file
@ -0,0 +1,68 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class FileOutputStream extends OutputStream {
|
||||
// static {
|
||||
// System.loadLibrary("natives");
|
||||
// }
|
||||
|
||||
private int fd;
|
||||
|
||||
public FileOutputStream(FileDescriptor fd) {
|
||||
this.fd = fd.value;
|
||||
}
|
||||
|
||||
public FileOutputStream(String path) throws IOException {
|
||||
this(path, false);
|
||||
}
|
||||
|
||||
public FileOutputStream(String path, boolean append) throws IOException {
|
||||
fd = open(path, append);
|
||||
}
|
||||
|
||||
|
||||
public FileOutputStream(File file) throws IOException {
|
||||
this(file.getPath());
|
||||
}
|
||||
|
||||
private static native int open(String path, boolean append) throws IOException;
|
||||
|
||||
private static native void write(int fd, int c) throws IOException;
|
||||
|
||||
private static native void write(int fd, byte[] b, int offset, int length)
|
||||
throws IOException;
|
||||
|
||||
private static native void close(int fd) throws IOException;
|
||||
|
||||
public void write(int c) throws IOException {
|
||||
write(fd, c);
|
||||
}
|
||||
|
||||
public void write(byte[] b, int offset, int length) throws IOException {
|
||||
if (b == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
if (offset < 0 || offset + length > b.length) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
write(fd, b, offset, length);
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
if (fd != -1) {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
}
|
||||
}
|
39
sgx-jvm/avian/classpath/java/io/FileReader.java
Normal file
39
sgx-jvm/avian/classpath/java/io/FileReader.java
Normal file
@ -0,0 +1,39 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class FileReader extends Reader {
|
||||
private final Reader in;
|
||||
|
||||
public FileReader(FileInputStream in) {
|
||||
this.in = new InputStreamReader(in);
|
||||
}
|
||||
|
||||
public FileReader(FileDescriptor fd) {
|
||||
this(new FileInputStream(fd));
|
||||
}
|
||||
|
||||
public FileReader(String path) throws IOException {
|
||||
this(new FileInputStream(path));
|
||||
}
|
||||
|
||||
public FileReader(File file) throws IOException {
|
||||
this(new FileInputStream(file));
|
||||
}
|
||||
|
||||
public int read(char[] b, int offset, int length) throws IOException {
|
||||
return in.read(b, offset, length);
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
in.close();
|
||||
}
|
||||
}
|
43
sgx-jvm/avian/classpath/java/io/FileWriter.java
Normal file
43
sgx-jvm/avian/classpath/java/io/FileWriter.java
Normal file
@ -0,0 +1,43 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class FileWriter extends Writer {
|
||||
private final Writer out;
|
||||
|
||||
private FileWriter(FileOutputStream out) {
|
||||
this.out = new OutputStreamWriter(out);
|
||||
}
|
||||
|
||||
public FileWriter(FileDescriptor fd) {
|
||||
this(new FileOutputStream(fd));
|
||||
}
|
||||
|
||||
public FileWriter(String path) throws IOException {
|
||||
this(new FileOutputStream(path));
|
||||
}
|
||||
|
||||
public FileWriter(File file) throws IOException {
|
||||
this(new FileOutputStream(file));
|
||||
}
|
||||
|
||||
public void write(char[] b, int offset, int length) throws IOException {
|
||||
out.write(b, offset, length);
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
out.flush();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
out.close();
|
||||
}
|
||||
}
|
17
sgx-jvm/avian/classpath/java/io/FilenameFilter.java
Normal file
17
sgx-jvm/avian/classpath/java/io/FilenameFilter.java
Normal file
@ -0,0 +1,17 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public interface FilenameFilter {
|
||||
|
||||
boolean accept(File dir, String name);
|
||||
|
||||
}
|
35
sgx-jvm/avian/classpath/java/io/FilterInputStream.java
Normal file
35
sgx-jvm/avian/classpath/java/io/FilterInputStream.java
Normal file
@ -0,0 +1,35 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class FilterInputStream extends InputStream {
|
||||
protected InputStream in;
|
||||
|
||||
public FilterInputStream(InputStream in) {
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
in.close();
|
||||
}
|
||||
|
||||
public int read(byte[] b) throws IOException {
|
||||
return in.read(b);
|
||||
}
|
||||
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
return in.read(b, off, len);
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
return in.read();
|
||||
}
|
||||
}
|
40
sgx-jvm/avian/classpath/java/io/FilterOutputStream.java
Normal file
40
sgx-jvm/avian/classpath/java/io/FilterOutputStream.java
Normal file
@ -0,0 +1,40 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class FilterOutputStream extends OutputStream {
|
||||
protected OutputStream out;
|
||||
|
||||
public FilterOutputStream(OutputStream out) {
|
||||
this.out = out;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
out.close();
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
out.flush();
|
||||
}
|
||||
|
||||
public void write(byte[] b) throws IOException {
|
||||
out.write(b);
|
||||
}
|
||||
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
out.write(b, off, len);
|
||||
}
|
||||
|
||||
public void write(int b) throws IOException {
|
||||
out.write(b);
|
||||
}
|
||||
|
||||
}
|
51
sgx-jvm/avian/classpath/java/io/FilterReader.java
Normal file
51
sgx-jvm/avian/classpath/java/io/FilterReader.java
Normal file
@ -0,0 +1,51 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public abstract class FilterReader extends Reader {
|
||||
protected Reader in;
|
||||
|
||||
protected FilterReader(Reader in) {
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
return in.read();
|
||||
}
|
||||
|
||||
public int read(char[] buffer, int offset, int length) throws IOException {
|
||||
return in.read(buffer, offset, length);
|
||||
}
|
||||
|
||||
public boolean ready() throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public long skip(long n) throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
in.close();
|
||||
}
|
||||
|
||||
public boolean markSupported() {
|
||||
return in.markSupported();
|
||||
}
|
||||
|
||||
public void mark(int readAheadLimit) throws IOException {
|
||||
in.mark(readAheadLimit);
|
||||
}
|
||||
|
||||
public void reset() throws IOException {
|
||||
in.reset();
|
||||
}
|
||||
}
|
16
sgx-jvm/avian/classpath/java/io/Flushable.java
Normal file
16
sgx-jvm/avian/classpath/java/io/Flushable.java
Normal file
@ -0,0 +1,16 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public interface Flushable {
|
||||
void flush()
|
||||
throws IOException;
|
||||
}
|
29
sgx-jvm/avian/classpath/java/io/IOException.java
Normal file
29
sgx-jvm/avian/classpath/java/io/IOException.java
Normal file
@ -0,0 +1,29 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class IOException extends Exception {
|
||||
public IOException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public IOException(String message) {
|
||||
this(message, null);
|
||||
}
|
||||
|
||||
public IOException(Throwable cause) {
|
||||
this(null, cause);
|
||||
}
|
||||
|
||||
public IOException() {
|
||||
this(null, null);
|
||||
}
|
||||
}
|
67
sgx-jvm/avian/classpath/java/io/InputStream.java
Normal file
67
sgx-jvm/avian/classpath/java/io/InputStream.java
Normal file
@ -0,0 +1,67 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public abstract class InputStream implements Closeable {
|
||||
public abstract int read() throws IOException;
|
||||
|
||||
public int read(byte[] buffer) throws IOException {
|
||||
return read(buffer, 0, buffer.length);
|
||||
}
|
||||
|
||||
public int read(byte[] buffer, int offset, int length) throws IOException {
|
||||
for (int i = 0; i < length; ++i) {
|
||||
int c = read();
|
||||
if (c == -1) {
|
||||
if (i == 0) {
|
||||
return -1;
|
||||
} else {
|
||||
return i;
|
||||
}
|
||||
} else {
|
||||
buffer[offset + i] = (byte) (c & 0xFF);
|
||||
}
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
public long skip(long count) throws IOException {
|
||||
final long Max = 8 * 1024;
|
||||
int size = (int) (count < Max ? count : Max);
|
||||
byte[] buffer = new byte[size];
|
||||
long remaining = count;
|
||||
int c;
|
||||
while ((c = read(buffer, 0, (int) (size < remaining ? size : remaining)))
|
||||
>= 0
|
||||
&& remaining > 0) {
|
||||
remaining -= c;
|
||||
}
|
||||
return count - remaining;
|
||||
}
|
||||
|
||||
public int available() throws IOException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void mark(int limit) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
public void reset() throws IOException {
|
||||
throw new IOException("mark/reset not supported");
|
||||
}
|
||||
|
||||
public boolean markSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void close() throws IOException { }
|
||||
}
|
92
sgx-jvm/avian/classpath/java/io/InputStreamReader.java
Normal file
92
sgx-jvm/avian/classpath/java/io/InputStreamReader.java
Normal file
@ -0,0 +1,92 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
import avian.Utf8;
|
||||
|
||||
public class InputStreamReader extends Reader {
|
||||
private static final int MultibytePadding = 4;
|
||||
|
||||
private final InputStream in;
|
||||
|
||||
public InputStreamReader(InputStream in) {
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
public InputStreamReader(InputStream in, String encoding)
|
||||
throws UnsupportedEncodingException
|
||||
{
|
||||
this(in);
|
||||
|
||||
if (! encoding.equals("UTF-8")) {
|
||||
throw new UnsupportedEncodingException(encoding);
|
||||
}
|
||||
}
|
||||
|
||||
public int read(char[] b, int offset, int length) throws IOException {
|
||||
if (length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
byte[] buffer = new byte[length + MultibytePadding];
|
||||
int bufferLength = length;
|
||||
int bufferOffset = 0;
|
||||
while (true) {
|
||||
int c = in.read(buffer, bufferOffset, bufferLength);
|
||||
|
||||
if (c <= 0) {
|
||||
if (bufferOffset > 0) {
|
||||
// if we've reached the end of the stream while trying to
|
||||
// read a multibyte character, we still need to return any
|
||||
// competely-decoded characters, plus \ufffd to indicate an
|
||||
// unknown character
|
||||
c = 1;
|
||||
while (bufferOffset > 0) {
|
||||
char[] buffer16 = Utf8.decode16(buffer, 0, bufferOffset);
|
||||
|
||||
if (buffer16 != null) {
|
||||
System.arraycopy(buffer16, 0, b, offset, buffer16.length);
|
||||
|
||||
c = buffer16.length + 1;
|
||||
break;
|
||||
} else {
|
||||
-- bufferOffset;
|
||||
}
|
||||
}
|
||||
|
||||
b[offset + c - 1] = '\ufffd';
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
bufferOffset += c;
|
||||
|
||||
char[] buffer16 = Utf8.decode16(buffer, 0, bufferOffset);
|
||||
|
||||
if (buffer16 != null) {
|
||||
bufferOffset = 0;
|
||||
|
||||
System.arraycopy(buffer16, 0, b, offset, buffer16.length);
|
||||
|
||||
return buffer16.length;
|
||||
} else {
|
||||
// the buffer ended in an incomplete multibyte character, so
|
||||
// we try to read a another byte at a time until it's complete
|
||||
bufferLength = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
in.close();
|
||||
}
|
||||
}
|
41
sgx-jvm/avian/classpath/java/io/LineNumberReader.java
Normal file
41
sgx-jvm/avian/classpath/java/io/LineNumberReader.java
Normal file
@ -0,0 +1,41 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class LineNumberReader extends BufferedReader {
|
||||
private int line;
|
||||
|
||||
public LineNumberReader(Reader in, int bufferSize) {
|
||||
super(in, bufferSize);
|
||||
}
|
||||
|
||||
public LineNumberReader(Reader in) {
|
||||
super(in);
|
||||
}
|
||||
|
||||
public int getLineNumber() {
|
||||
return line;
|
||||
}
|
||||
|
||||
public void setLineNumber(int v) {
|
||||
line = v;
|
||||
}
|
||||
|
||||
public int read(char[] b, int offset, int length) throws IOException {
|
||||
int c = super.read(b, offset, length);
|
||||
for (int i = 0; i < c; ++i) {
|
||||
if (b[i] == '\n') {
|
||||
++ line;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class NotSerializableException extends ObjectStreamException {
|
||||
public NotSerializableException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public NotSerializableException() {
|
||||
this(null);
|
||||
}
|
||||
}
|
21
sgx-jvm/avian/classpath/java/io/ObjectInput.java
Normal file
21
sgx-jvm/avian/classpath/java/io/ObjectInput.java
Normal file
@ -0,0 +1,21 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public interface ObjectInput {
|
||||
public int available();
|
||||
public void close();
|
||||
public void read();
|
||||
public void read(byte[] b);
|
||||
public void read(byte[] b, int off, int len);
|
||||
public Object readObject();
|
||||
public long skip(long n);
|
||||
}
|
443
sgx-jvm/avian/classpath/java/io/ObjectInputStream.java
Normal file
443
sgx-jvm/avian/classpath/java/io/ObjectInputStream.java
Normal file
@ -0,0 +1,443 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
import static java.io.ObjectOutputStream.STREAM_MAGIC;
|
||||
import static java.io.ObjectOutputStream.STREAM_VERSION;
|
||||
import static java.io.ObjectOutputStream.TC_NULL;
|
||||
import static java.io.ObjectOutputStream.TC_REFERENCE;
|
||||
import static java.io.ObjectOutputStream.TC_CLASSDESC;
|
||||
import static java.io.ObjectOutputStream.TC_OBJECT;
|
||||
import static java.io.ObjectOutputStream.TC_STRING;
|
||||
import static java.io.ObjectOutputStream.TC_ARRAY;
|
||||
import static java.io.ObjectOutputStream.TC_CLASS;
|
||||
import static java.io.ObjectOutputStream.TC_BLOCKDATA;
|
||||
import static java.io.ObjectOutputStream.TC_ENDBLOCKDATA;
|
||||
import static java.io.ObjectOutputStream.TC_RESET;
|
||||
import static java.io.ObjectOutputStream.TC_BLOCKDATALONG;
|
||||
import static java.io.ObjectOutputStream.TC_EXCEPTION;
|
||||
import static java.io.ObjectOutputStream.TC_LONGSTRING;
|
||||
import static java.io.ObjectOutputStream.TC_PROXYCLASSDESC;
|
||||
import static java.io.ObjectOutputStream.TC_ENUM;
|
||||
import static java.io.ObjectOutputStream.SC_WRITE_METHOD;
|
||||
import static java.io.ObjectOutputStream.SC_BLOCK_DATA;
|
||||
import static java.io.ObjectOutputStream.SC_SERIALIZABLE;
|
||||
import static java.io.ObjectOutputStream.SC_EXTERNALIZABLE;
|
||||
import static java.io.ObjectOutputStream.SC_ENUM;
|
||||
import static java.io.ObjectOutputStream.getReadOrWriteMethod;
|
||||
|
||||
import avian.VMClass;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
public class ObjectInputStream extends InputStream implements DataInput {
|
||||
private final static int HANDLE_OFFSET = 0x7e0000;
|
||||
|
||||
private final InputStream in;
|
||||
private final ArrayList references;
|
||||
|
||||
public ObjectInputStream(InputStream in) throws IOException {
|
||||
this.in = in;
|
||||
short signature = (short)rawShort();
|
||||
if (signature != STREAM_MAGIC) {
|
||||
throw new IOException("Unrecognized signature: 0x"
|
||||
+ Integer.toHexString(signature));
|
||||
}
|
||||
int version = rawShort();
|
||||
if (version != STREAM_VERSION) {
|
||||
throw new IOException("Unsupported version: " + version);
|
||||
}
|
||||
references = new ArrayList();
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
return in.read();
|
||||
}
|
||||
|
||||
private int rawByte() throws IOException {
|
||||
int c = read();
|
||||
if (c < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
private int rawShort() throws IOException {
|
||||
return (rawByte() << 8) | rawByte();
|
||||
}
|
||||
|
||||
private int rawInt() throws IOException {
|
||||
return (rawShort() << 16) | rawShort();
|
||||
}
|
||||
|
||||
private long rawLong() throws IOException {
|
||||
return ((rawInt() & 0xffffffffl) << 32) | rawInt();
|
||||
}
|
||||
|
||||
private String rawString() throws IOException {
|
||||
int length = rawShort();
|
||||
byte[] array = new byte[length];
|
||||
readFully(array);
|
||||
return new String(array);
|
||||
}
|
||||
|
||||
public int read(byte[] b, int offset, int length) throws IOException {
|
||||
return in.read(b, offset, length);
|
||||
}
|
||||
|
||||
public void readFully(byte[] b) throws IOException {
|
||||
readFully(b, 0, b.length);
|
||||
}
|
||||
|
||||
public void readFully(byte[] b, int offset, int length) throws IOException {
|
||||
while (length > 0) {
|
||||
int count = read(b, offset, length);
|
||||
if (count < 0) {
|
||||
throw new EOFException("Reached EOF " + length + " bytes too early");
|
||||
}
|
||||
offset += count;
|
||||
length -= count;
|
||||
}
|
||||
}
|
||||
|
||||
public String readLine() throws IOException {
|
||||
int c = read();
|
||||
if (c < 0) {
|
||||
return null;
|
||||
} else if (c == '\n') {
|
||||
return "";
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (;;) {
|
||||
builder.append((char)c);
|
||||
c = read();
|
||||
if (c < 0 || c == '\n') {
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
in.close();
|
||||
}
|
||||
|
||||
private int remainingBlockData;
|
||||
|
||||
private int rawBlockDataByte() throws IOException {
|
||||
while (remainingBlockData <= 0) {
|
||||
int b = rawByte();
|
||||
if (b == TC_BLOCKDATA) {
|
||||
remainingBlockData = rawByte();
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Unknown token: 0x"
|
||||
+ Integer.toHexString(b));
|
||||
}
|
||||
}
|
||||
--remainingBlockData;
|
||||
return rawByte();
|
||||
}
|
||||
|
||||
private int rawBlockDataShort() throws IOException {
|
||||
return (rawBlockDataByte() << 8) | rawBlockDataByte();
|
||||
}
|
||||
|
||||
private int rawBlockDataInt() throws IOException {
|
||||
return (rawBlockDataShort() << 16) | rawBlockDataShort();
|
||||
}
|
||||
|
||||
private long rawBlockDataLong() throws IOException {
|
||||
return ((rawBlockDataInt() & 0xffffffffl) << 32) | rawBlockDataInt();
|
||||
}
|
||||
|
||||
public boolean readBoolean() throws IOException {
|
||||
return rawBlockDataByte() != 0;
|
||||
}
|
||||
|
||||
public byte readByte() throws IOException {
|
||||
return (byte)rawBlockDataByte();
|
||||
}
|
||||
|
||||
public char readChar() throws IOException {
|
||||
return (char)rawBlockDataShort();
|
||||
}
|
||||
|
||||
public short readShort() throws IOException {
|
||||
return (short)rawBlockDataShort();
|
||||
}
|
||||
|
||||
public int readInt() throws IOException {
|
||||
return rawBlockDataInt();
|
||||
}
|
||||
|
||||
public long readLong() throws IOException {
|
||||
return rawBlockDataLong();
|
||||
}
|
||||
|
||||
public float readFloat() throws IOException {
|
||||
return Float.intBitsToFloat(rawBlockDataInt());
|
||||
}
|
||||
|
||||
public double readDouble() throws IOException {
|
||||
return Double.longBitsToDouble(rawBlockDataLong());
|
||||
}
|
||||
|
||||
public int readUnsignedByte() throws IOException {
|
||||
return rawBlockDataByte();
|
||||
}
|
||||
|
||||
public int readUnsignedShort() throws IOException {
|
||||
return rawBlockDataShort();
|
||||
}
|
||||
|
||||
public String readUTF() throws IOException {
|
||||
int length = rawBlockDataShort();
|
||||
if (remainingBlockData < length) {
|
||||
throw new IOException("Short block data: "
|
||||
+ remainingBlockData + " < " + length);
|
||||
}
|
||||
byte[] bytes = new byte[length];
|
||||
readFully(bytes);
|
||||
remainingBlockData -= length;
|
||||
return new String(bytes, "UTF-8");
|
||||
}
|
||||
|
||||
public int skipBytes(int count) throws IOException {
|
||||
int i = 0;
|
||||
while (i < count) {
|
||||
if (read() < 0) {
|
||||
return i;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
private static Class charToPrimitiveType(int c) {
|
||||
if (c == 'B') {
|
||||
return Byte.TYPE;
|
||||
} else if (c == 'C') {
|
||||
return Character.TYPE;
|
||||
} else if (c == 'D') {
|
||||
return Double.TYPE;
|
||||
} else if (c == 'F') {
|
||||
return Float.TYPE;
|
||||
} else if (c == 'I') {
|
||||
return Integer.TYPE;
|
||||
} else if (c == 'J') {
|
||||
return Long.TYPE;
|
||||
} else if (c == 'S') {
|
||||
return Short.TYPE;
|
||||
} else if (c == 'Z') {
|
||||
return Boolean.TYPE;
|
||||
}
|
||||
throw new RuntimeException("Unhandled char: " + (char)c);
|
||||
}
|
||||
|
||||
private void expectToken(int token) throws IOException {
|
||||
int c = rawByte();
|
||||
if (c != token) {
|
||||
throw new UnsupportedOperationException("Unexpected token: 0x"
|
||||
+ Integer.toHexString(c));
|
||||
}
|
||||
}
|
||||
|
||||
private void field(Field field, Object o)
|
||||
throws IOException, IllegalArgumentException, IllegalAccessException,
|
||||
ClassNotFoundException
|
||||
{
|
||||
Class type = field.getType();
|
||||
if (!type.isPrimitive()) {
|
||||
field.set(o, readObject());
|
||||
} else {
|
||||
if (type == Byte.TYPE) {
|
||||
field.setByte(o, (byte)rawByte());
|
||||
} else if (type == Character.TYPE) {
|
||||
field.setChar(o, (char)rawShort());
|
||||
} else if (type == Double.TYPE) {
|
||||
field.setDouble(o, Double.longBitsToDouble(rawLong()));
|
||||
} else if (type == Float.TYPE) {
|
||||
field.setFloat(o, Float.intBitsToFloat(rawInt()));
|
||||
} else if (type == Integer.TYPE) {
|
||||
field.setInt(o, rawInt());
|
||||
} else if (type == Long.TYPE) {
|
||||
field.setLong(o, rawLong());
|
||||
} else if (type == Short.TYPE) {
|
||||
field.setShort(o, (short)rawShort());
|
||||
} else if (type == Boolean.TYPE) {
|
||||
field.setBoolean(o, rawByte() != 0);
|
||||
} else {
|
||||
throw new IOException("Unhandled type: " + type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Object readObject() throws IOException, ClassNotFoundException {
|
||||
int c = rawByte();
|
||||
if (c == TC_NULL) {
|
||||
return null;
|
||||
}
|
||||
if (c == TC_STRING) {
|
||||
int length = rawShort();
|
||||
byte[] bytes = new byte[length];
|
||||
readFully(bytes);
|
||||
String s = new String(bytes, "UTF-8");
|
||||
references.add(s);
|
||||
return s;
|
||||
}
|
||||
if (c == TC_REFERENCE) {
|
||||
int handle = rawInt();
|
||||
return references.get(handle - HANDLE_OFFSET);
|
||||
}
|
||||
if (c != TC_OBJECT) {
|
||||
throw new IOException("Unexpected token: 0x"
|
||||
+ Integer.toHexString(c));
|
||||
}
|
||||
|
||||
// class desc
|
||||
c = rawByte();
|
||||
ClassDesc classDesc;
|
||||
if (c == TC_REFERENCE) {
|
||||
int handle = rawInt() - HANDLE_OFFSET;
|
||||
classDesc = (ClassDesc)references.get(handle);
|
||||
} else if (c == TC_CLASSDESC) {
|
||||
classDesc = classDesc();
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Unexpected token: 0x"
|
||||
+ Integer.toHexString(c));
|
||||
}
|
||||
|
||||
try {
|
||||
Object o = makeInstance(classDesc.clazz.vmClass);
|
||||
references.add(o);
|
||||
|
||||
do {
|
||||
Object o1 = classDesc.clazz.cast(o);
|
||||
boolean customized = (classDesc.flags & SC_WRITE_METHOD) != 0;
|
||||
Method readMethod = customized ?
|
||||
getReadOrWriteMethod(o, "readObject") : null;
|
||||
if (readMethod == null) {
|
||||
if (customized) {
|
||||
throw new IOException("Could not find required readObject method "
|
||||
+ "in " + classDesc.clazz);
|
||||
}
|
||||
defaultReadObject(o, classDesc.fields);
|
||||
} else {
|
||||
current = o1;
|
||||
currentFields = classDesc.fields;
|
||||
readMethod.invoke(o, this);
|
||||
current = null;
|
||||
currentFields = null;
|
||||
expectToken(TC_ENDBLOCKDATA);
|
||||
}
|
||||
} while ((classDesc = classDesc.superClassDesc) != null);
|
||||
|
||||
return o;
|
||||
} catch (IOException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ClassDesc {
|
||||
Class clazz;
|
||||
int flags;
|
||||
Field[] fields;
|
||||
ClassDesc superClassDesc;
|
||||
}
|
||||
|
||||
private ClassDesc classDesc() throws ClassNotFoundException, IOException {
|
||||
ClassDesc result = new ClassDesc();
|
||||
String className = rawString();
|
||||
ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
||||
result.clazz = loader.loadClass(className);
|
||||
long serialVersionUID = rawLong();
|
||||
try {
|
||||
Field field = result.clazz.getField("serialVersionUID");
|
||||
long expected = field.getLong(null);
|
||||
if (expected != serialVersionUID) {
|
||||
throw new IOException("Incompatible serial version UID: 0x"
|
||||
+ Long.toHexString(serialVersionUID) + " != 0x"
|
||||
+ Long.toHexString(expected));
|
||||
}
|
||||
} catch (Exception ignored) { }
|
||||
references.add(result);
|
||||
|
||||
result.flags = rawByte();
|
||||
if ((result.flags & ~(SC_SERIALIZABLE | SC_WRITE_METHOD)) != 0) {
|
||||
throw new UnsupportedOperationException("Cannot handle flags: 0x"
|
||||
+ Integer.toHexString(result.flags));
|
||||
}
|
||||
|
||||
int fieldCount = rawShort();
|
||||
result.fields = new Field[fieldCount];
|
||||
for (int i = 0; i < result.fields.length; i++) {
|
||||
int typeChar = rawByte();
|
||||
String fieldName = rawString();
|
||||
try {
|
||||
result.fields[i] = result.clazz.getDeclaredField(fieldName);
|
||||
} catch (Exception e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
Class type;
|
||||
if (typeChar == '[' || typeChar == 'L') {
|
||||
String typeName = (String)readObject();
|
||||
if (typeName.startsWith("L") && typeName.endsWith(";")) {
|
||||
typeName = typeName.substring(1, typeName.length() - 1)
|
||||
.replace('/', '.');
|
||||
}
|
||||
type = loader.loadClass(typeName);
|
||||
} else {
|
||||
type = charToPrimitiveType(typeChar);
|
||||
}
|
||||
if (result.fields[i].getType() != type) {
|
||||
throw new IOException("Unexpected type of field " + fieldName
|
||||
+ ": expected " + result.fields[i].getType() + " but got " + type);
|
||||
}
|
||||
}
|
||||
expectToken(TC_ENDBLOCKDATA);
|
||||
int c = rawByte();
|
||||
if (c == TC_CLASSDESC) {
|
||||
result.superClassDesc = classDesc();
|
||||
} else if (c != TC_NULL) {
|
||||
throw new UnsupportedOperationException("Unexpected token: 0x"
|
||||
+ Integer.toHexString(c));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private Object current;
|
||||
private Field[] currentFields;
|
||||
|
||||
public void defaultReadObject() throws IOException {
|
||||
defaultReadObject(current, currentFields);
|
||||
}
|
||||
|
||||
private void defaultReadObject(Object o, Field[] fields) throws IOException {
|
||||
try {
|
||||
for (Field field : fields) {
|
||||
field(field, o);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static native Object makeInstance(VMClass c);
|
||||
}
|
20
sgx-jvm/avian/classpath/java/io/ObjectOutput.java
Normal file
20
sgx-jvm/avian/classpath/java/io/ObjectOutput.java
Normal file
@ -0,0 +1,20 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public interface ObjectOutput {
|
||||
public void close();
|
||||
public void flush();
|
||||
public void write(byte[] b);
|
||||
public void write(byte[] b, int off, int len);
|
||||
public void write(int b);
|
||||
public void writeObject(Object obj);
|
||||
}
|
337
sgx-jvm/avian/classpath/java/io/ObjectOutputStream.java
Normal file
337
sgx-jvm/avian/classpath/java/io/ObjectOutputStream.java
Normal file
@ -0,0 +1,337 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
public class ObjectOutputStream extends OutputStream implements DataOutput {
|
||||
final static short STREAM_MAGIC = (short)0xaced;
|
||||
final static short STREAM_VERSION = 5;
|
||||
final static byte TC_NULL = (byte)0x70;
|
||||
final static byte TC_REFERENCE = (byte)0x71;
|
||||
final static byte TC_CLASSDESC = (byte)0x72;
|
||||
final static byte TC_OBJECT = (byte)0x73;
|
||||
final static byte TC_STRING = (byte)0x74;
|
||||
final static byte TC_ARRAY = (byte)0x75;
|
||||
final static byte TC_CLASS = (byte)0x76;
|
||||
final static byte TC_BLOCKDATA = (byte)0x77;
|
||||
final static byte TC_ENDBLOCKDATA = (byte)0x78;
|
||||
final static byte TC_RESET = (byte)0x79;
|
||||
final static byte TC_BLOCKDATALONG = (byte)0x7a;
|
||||
final static byte TC_EXCEPTION = (byte)0x7b;
|
||||
final static byte TC_LONGSTRING = (byte)0x7c;
|
||||
final static byte TC_PROXYCLASSDESC = (byte)0x7d;
|
||||
final static byte TC_ENUM = (byte)0x7e;
|
||||
final static byte SC_WRITE_METHOD = 0x01; //if SC_SERIALIZABLE
|
||||
final static byte SC_BLOCK_DATA = 0x08; //if SC_EXTERNALIZABLE
|
||||
final static byte SC_SERIALIZABLE = 0x02;
|
||||
final static byte SC_EXTERNALIZABLE = 0x04;
|
||||
final static byte SC_ENUM = 0x10;
|
||||
|
||||
private final OutputStream out;
|
||||
|
||||
public ObjectOutputStream(OutputStream out) throws IOException {
|
||||
this.out = out;
|
||||
rawShort(STREAM_MAGIC);
|
||||
rawShort(STREAM_VERSION);
|
||||
}
|
||||
|
||||
public void write(int c) throws IOException {
|
||||
out.write(c);
|
||||
}
|
||||
|
||||
public void write(byte[] b, int offset, int length) throws IOException {
|
||||
out.write(b, offset, length);
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
out.flush();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
out.close();
|
||||
}
|
||||
|
||||
private void rawByte(int v) throws IOException {
|
||||
out.write((byte)(v & 0xff));
|
||||
}
|
||||
|
||||
private void rawShort(int v) throws IOException {
|
||||
rawByte(v >> 8);
|
||||
rawByte(v);
|
||||
}
|
||||
|
||||
private void rawInt(int v) throws IOException {
|
||||
rawShort(v >> 16);
|
||||
rawShort(v);
|
||||
}
|
||||
|
||||
private void rawLong(long v) throws IOException {
|
||||
rawInt((int)(v >> 32));
|
||||
rawInt((int)(v & 0xffffffffl));
|
||||
}
|
||||
|
||||
private void blockData(int... bytes) throws IOException {
|
||||
blockData(bytes, null, null);
|
||||
}
|
||||
|
||||
private void blockData(int[] bytes, byte[] bytes2, char[] chars) throws IOException {
|
||||
int count = (bytes == null ? 0 : bytes.length)
|
||||
+ (bytes2 == null ? 0 : bytes2.length)
|
||||
+ (chars == null ? 0 : chars.length * 2);
|
||||
if (count < 0x100) {
|
||||
rawByte(TC_BLOCKDATA);
|
||||
rawByte(count);
|
||||
} else {
|
||||
rawByte(TC_BLOCKDATALONG);
|
||||
rawInt(count);
|
||||
}
|
||||
if (bytes != null) {
|
||||
for (int b : bytes) {
|
||||
rawByte(b);
|
||||
}
|
||||
}
|
||||
if (bytes2 != null) {
|
||||
for (byte b : bytes2) {
|
||||
rawByte(b & 0xff);
|
||||
}
|
||||
}
|
||||
if (chars != null) {
|
||||
for (char c : chars) {
|
||||
rawShort((short)c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void writeBoolean(boolean v) throws IOException {
|
||||
blockData(v ? 1 : 0);
|
||||
}
|
||||
|
||||
public void writeByte(int v) throws IOException {
|
||||
blockData(v);
|
||||
}
|
||||
|
||||
public void writeShort(int v) throws IOException {
|
||||
blockData(v >> 8, v);
|
||||
}
|
||||
|
||||
public void writeChar(int v) throws IOException {
|
||||
blockData(v >> 8, v);
|
||||
}
|
||||
|
||||
public void writeInt(int v) throws IOException {
|
||||
blockData(v >> 24, v >> 16, v >> 8, v);
|
||||
}
|
||||
|
||||
public void writeLong(long v) throws IOException {
|
||||
int u = (int)(v >> 32), l = (int)(v & 0xffffffff);
|
||||
blockData(u >> 24, u >> 16, u >> 8, u, l >> 24, l >> 16, l >> 8, l);
|
||||
}
|
||||
|
||||
public void writeFloat(float v) throws IOException {
|
||||
writeInt(Float.floatToIntBits(v));
|
||||
}
|
||||
|
||||
public void writeDouble(double v) throws IOException {
|
||||
writeLong(Double.doubleToLongBits(v));
|
||||
}
|
||||
|
||||
public void writeBytes(String s) throws IOException {
|
||||
blockData(null, s.getBytes(), null);
|
||||
}
|
||||
|
||||
public void writeChars(String s) throws IOException {
|
||||
blockData(null, null, s.toCharArray());
|
||||
}
|
||||
|
||||
public void writeUTF(String s) throws IOException {
|
||||
byte[] bytes = s.getBytes();
|
||||
int length = bytes.length;
|
||||
blockData(new int[] { length >> 8, length }, bytes, null);
|
||||
}
|
||||
|
||||
private int classHandle;
|
||||
|
||||
private void string(String s) throws IOException {
|
||||
int length = s.length();
|
||||
rawShort(length);
|
||||
for (byte b : s.getBytes()) {
|
||||
rawByte(b);
|
||||
}
|
||||
}
|
||||
|
||||
private static char primitiveTypeChar(Class type) {
|
||||
if (type == Byte.TYPE) {
|
||||
return 'B';
|
||||
} else if (type == Character.TYPE) {
|
||||
return 'C';
|
||||
} else if (type == Double.TYPE) {
|
||||
return 'D';
|
||||
} else if (type == Float.TYPE) {
|
||||
return 'F';
|
||||
} else if (type == Integer.TYPE) {
|
||||
return 'I';
|
||||
} else if (type == Long.TYPE) {
|
||||
return 'J';
|
||||
} else if (type == Short.TYPE) {
|
||||
return 'S';
|
||||
} else if (type == Boolean.TYPE) {
|
||||
return 'Z';
|
||||
}
|
||||
throw new RuntimeException("Unhandled primitive type: " + type);
|
||||
}
|
||||
|
||||
private void classDesc(Class clazz, int scFlags) throws IOException {
|
||||
rawByte(TC_CLASSDESC);
|
||||
|
||||
// class name
|
||||
string(clazz.getName());
|
||||
|
||||
// serial version UID
|
||||
long serialVersionUID = 1l;
|
||||
try {
|
||||
Field field = clazz.getField("serialVersionUID");
|
||||
serialVersionUID = field.getLong(null);
|
||||
} catch (Exception ignored) {}
|
||||
rawLong(serialVersionUID);
|
||||
|
||||
// handle
|
||||
rawByte(SC_SERIALIZABLE | scFlags);
|
||||
|
||||
Field[] fields = getFields(clazz);
|
||||
rawShort(fields.length);
|
||||
for (Field field : fields) {
|
||||
Class fieldType = field.getType();
|
||||
if (fieldType.isPrimitive()) {
|
||||
rawByte(primitiveTypeChar(fieldType));
|
||||
string(field.getName());
|
||||
} else {
|
||||
rawByte(fieldType.isArray() ? '[' : 'L');
|
||||
string(field.getName());
|
||||
rawByte(TC_STRING);
|
||||
string("L" + fieldType.getName().replace('.', '/') + ";");
|
||||
}
|
||||
}
|
||||
rawByte(TC_ENDBLOCKDATA); // TODO: write annotation
|
||||
rawByte(TC_NULL); // super class desc
|
||||
}
|
||||
|
||||
private void field(Object o, Field field) throws IOException {
|
||||
try {
|
||||
field.setAccessible(true);
|
||||
Class type = field.getType();
|
||||
if (!type.isPrimitive()) {
|
||||
writeObject(field.get(o));
|
||||
} else if (type == Byte.TYPE) {
|
||||
rawByte(field.getByte(o));
|
||||
} else if (type == Character.TYPE) {
|
||||
char c = field.getChar(o);
|
||||
rawShort((short)c);
|
||||
} else if (type == Double.TYPE) {
|
||||
double d = field.getDouble(o);
|
||||
rawLong(Double.doubleToLongBits(d));
|
||||
} else if (type == Float.TYPE) {
|
||||
float f = field.getFloat(o);
|
||||
rawInt(Float.floatToIntBits(f));
|
||||
} else if (type == Integer.TYPE) {
|
||||
int i = field.getInt(o);
|
||||
rawInt(i);
|
||||
} else if (type == Long.TYPE) {
|
||||
long l = field.getLong(o);
|
||||
rawLong(l);
|
||||
} else if (type == Short.TYPE) {
|
||||
short s = field.getShort(o);
|
||||
rawShort(s);
|
||||
} else if (type == Boolean.TYPE) {
|
||||
boolean b = field.getBoolean(o);
|
||||
rawByte(b ? 1 : 0);
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Field '" + field.getName()
|
||||
+ "' has unsupported type: " + type);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static Field[] getFields(Class clazz) {
|
||||
ArrayList<Field> list = new ArrayList<Field>();
|
||||
Field[] fields = clazz.getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
if (0 == (field.getModifiers() &
|
||||
(Modifier.STATIC | Modifier.TRANSIENT))) {
|
||||
list.add(field);
|
||||
}
|
||||
}
|
||||
return list.toArray(new Field[list.size()]);
|
||||
}
|
||||
|
||||
public void writeObject(Object o) throws IOException {
|
||||
if (o == null) {
|
||||
rawByte(TC_NULL);
|
||||
return;
|
||||
}
|
||||
if (o instanceof String) {
|
||||
byte[] bytes = ((String)o).getBytes("UTF-8");
|
||||
rawByte(TC_STRING);
|
||||
rawShort(bytes.length);
|
||||
write(bytes);
|
||||
return;
|
||||
}
|
||||
rawByte(TC_OBJECT);
|
||||
Method writeObject = getReadOrWriteMethod(o, "writeObject");
|
||||
if (writeObject == null) {
|
||||
classDesc(o.getClass(), 0);
|
||||
defaultWriteObject(o);
|
||||
} else try {
|
||||
classDesc(o.getClass(), SC_WRITE_METHOD);
|
||||
current = o;
|
||||
writeObject.invoke(o, this);
|
||||
current = null;
|
||||
rawByte(TC_ENDBLOCKDATA);
|
||||
} catch (Exception e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
static Method getReadOrWriteMethod(Object o, String methodName) {
|
||||
try {
|
||||
Method method = o.getClass().getDeclaredMethod(methodName,
|
||||
new Class[] { methodName.startsWith("write") ?
|
||||
ObjectOutputStream.class : ObjectInputStream.class });
|
||||
method.setAccessible(true);
|
||||
int modifiers = method.getModifiers();
|
||||
if ((modifiers & Modifier.STATIC) == 0 ||
|
||||
(modifiers & Modifier.PRIVATE) != 0) {
|
||||
return method;
|
||||
}
|
||||
} catch (NoSuchMethodException ignored) { }
|
||||
return null;
|
||||
}
|
||||
|
||||
private Object current;
|
||||
|
||||
public void defaultWriteObject() throws IOException {
|
||||
defaultWriteObject(current);
|
||||
}
|
||||
|
||||
private void defaultWriteObject(Object o) throws IOException {
|
||||
for (Field field : getFields(o.getClass())) {
|
||||
field(o, field);
|
||||
}
|
||||
}
|
||||
}
|
21
sgx-jvm/avian/classpath/java/io/ObjectStreamException.java
Normal file
21
sgx-jvm/avian/classpath/java/io/ObjectStreamException.java
Normal file
@ -0,0 +1,21 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class ObjectStreamException extends IOException {
|
||||
public ObjectStreamException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ObjectStreamException() {
|
||||
this(null);
|
||||
}
|
||||
}
|
29
sgx-jvm/avian/classpath/java/io/OutputStream.java
Normal file
29
sgx-jvm/avian/classpath/java/io/OutputStream.java
Normal file
@ -0,0 +1,29 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public abstract class OutputStream implements Closeable, Flushable {
|
||||
public abstract void write(int c) throws IOException;
|
||||
|
||||
public void write(byte[] buffer) throws IOException {
|
||||
write(buffer, 0, buffer.length);
|
||||
}
|
||||
|
||||
public void write(byte[] buffer, int offset, int length) throws IOException {
|
||||
for (int i = 0; i < length; ++i) {
|
||||
write(buffer[offset + i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void flush() throws IOException { }
|
||||
|
||||
public void close() throws IOException { }
|
||||
}
|
33
sgx-jvm/avian/classpath/java/io/OutputStreamWriter.java
Normal file
33
sgx-jvm/avian/classpath/java/io/OutputStreamWriter.java
Normal file
@ -0,0 +1,33 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
import avian.Utf8;
|
||||
|
||||
public class OutputStreamWriter extends Writer {
|
||||
private final OutputStream out;
|
||||
|
||||
public OutputStreamWriter(OutputStream out) {
|
||||
this.out = out;
|
||||
}
|
||||
|
||||
public void write(char[] b, int offset, int length) throws IOException {
|
||||
out.write(Utf8.encode(b, offset, length));
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
out.flush();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
out.close();
|
||||
}
|
||||
}
|
170
sgx-jvm/avian/classpath/java/io/PrintStream.java
Normal file
170
sgx-jvm/avian/classpath/java/io/PrintStream.java
Normal file
@ -0,0 +1,170 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class PrintStream extends OutputStream {
|
||||
private final OutputStream out;
|
||||
private final boolean autoFlush;
|
||||
|
||||
private static class Static {
|
||||
private static final byte[] newline
|
||||
= System.getProperty("line.separator").getBytes();
|
||||
}
|
||||
|
||||
public PrintStream(OutputStream out, boolean autoFlush) {
|
||||
this.out = out;
|
||||
this.autoFlush = autoFlush;
|
||||
}
|
||||
|
||||
public PrintStream(OutputStream out, boolean autoFlush, String encoding)
|
||||
throws UnsupportedEncodingException
|
||||
{
|
||||
this.out = out;
|
||||
this.autoFlush = autoFlush;
|
||||
|
||||
if (! (encoding.equals("UTF-8") || encoding.equals("ISO-8859-1"))) {
|
||||
throw new UnsupportedEncodingException(encoding);
|
||||
}
|
||||
}
|
||||
|
||||
public PrintStream(OutputStream out) {
|
||||
this(out, false);
|
||||
}
|
||||
|
||||
public synchronized void print(String s) {
|
||||
try {
|
||||
out.write(s.getBytes());
|
||||
if (autoFlush) flush();
|
||||
} catch (IOException e) { }
|
||||
}
|
||||
|
||||
public void print(Object o) {
|
||||
print(String.valueOf(o));
|
||||
}
|
||||
|
||||
public void print(boolean v) {
|
||||
print(String.valueOf(v));
|
||||
}
|
||||
|
||||
public void print(char c) {
|
||||
print(String.valueOf(c));
|
||||
}
|
||||
|
||||
public void print(int v) {
|
||||
print(String.valueOf(v));
|
||||
}
|
||||
|
||||
public void print(long v) {
|
||||
print(String.valueOf(v));
|
||||
}
|
||||
|
||||
public void print(float v) {
|
||||
print(String.valueOf(v));
|
||||
}
|
||||
|
||||
public void print(double v) {
|
||||
print(String.valueOf(v));
|
||||
}
|
||||
|
||||
public void print(char[] s) {
|
||||
print(String.valueOf(s));
|
||||
}
|
||||
|
||||
public synchronized PrintStream printf(java.util.Locale locale, String format, Object... args) {
|
||||
// should this be cached in an instance variable??
|
||||
final java.util.Formatter formatter = new java.util.Formatter(this);
|
||||
formatter.format(locale, format, args);
|
||||
return this;
|
||||
}
|
||||
|
||||
public synchronized PrintStream printf(String format, Object... args) {
|
||||
final java.util.Formatter formatter = new java.util.Formatter(this);
|
||||
formatter.format(format, args);
|
||||
return this;
|
||||
}
|
||||
|
||||
public PrintStream format(String format, Object... args) {
|
||||
return printf(format, args);
|
||||
}
|
||||
|
||||
public PrintStream format(java.util.Locale locale, String format, Object... args) {
|
||||
return printf(locale, format, args);
|
||||
}
|
||||
|
||||
public synchronized void println(String s) {
|
||||
try {
|
||||
out.write(s.getBytes());
|
||||
out.write(Static.newline);
|
||||
if (autoFlush) flush();
|
||||
} catch (IOException e) { }
|
||||
}
|
||||
|
||||
public synchronized void println() {
|
||||
try {
|
||||
out.write(Static.newline);
|
||||
if (autoFlush) flush();
|
||||
} catch (IOException e) { }
|
||||
}
|
||||
|
||||
public void println(Object o) {
|
||||
println(String.valueOf(o));
|
||||
}
|
||||
|
||||
public void println(boolean v) {
|
||||
println(String.valueOf(v));
|
||||
}
|
||||
|
||||
public void println(char c) {
|
||||
println(String.valueOf(c));
|
||||
}
|
||||
|
||||
public void println(int v) {
|
||||
println(String.valueOf(v));
|
||||
}
|
||||
|
||||
public void println(long v) {
|
||||
println(String.valueOf(v));
|
||||
}
|
||||
|
||||
public void println(float v) {
|
||||
println(String.valueOf(v));
|
||||
}
|
||||
|
||||
public void println(double v) {
|
||||
println(String.valueOf(v));
|
||||
}
|
||||
|
||||
public void println(char[] s) {
|
||||
println(String.valueOf(s));
|
||||
}
|
||||
|
||||
public void write(int c) throws IOException {
|
||||
out.write(c);
|
||||
if (autoFlush && c == '\n') flush();
|
||||
}
|
||||
|
||||
public void write(byte[] buffer, int offset, int length) throws IOException {
|
||||
out.write(buffer, offset, length);
|
||||
if (autoFlush) flush();
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
try {
|
||||
out.flush();
|
||||
} catch (IOException e) { }
|
||||
}
|
||||
|
||||
public void close() {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException e) { }
|
||||
}
|
||||
}
|
90
sgx-jvm/avian/classpath/java/io/PrintWriter.java
Normal file
90
sgx-jvm/avian/classpath/java/io/PrintWriter.java
Normal file
@ -0,0 +1,90 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class PrintWriter extends Writer {
|
||||
private static final char[] newline
|
||||
= System.getProperty("line.separator").toCharArray();
|
||||
|
||||
private final Writer out;
|
||||
private final boolean autoFlush;
|
||||
|
||||
public PrintWriter(Writer out, boolean autoFlush) {
|
||||
this.out = out;
|
||||
this.autoFlush = autoFlush;
|
||||
}
|
||||
|
||||
public PrintWriter(Writer out) {
|
||||
this(out, false);
|
||||
}
|
||||
|
||||
public PrintWriter(OutputStream out, boolean autoFlush) {
|
||||
this(new OutputStreamWriter(out), autoFlush);
|
||||
}
|
||||
|
||||
public PrintWriter(OutputStream out) {
|
||||
this(out, false);
|
||||
}
|
||||
|
||||
public synchronized void print(String s) {
|
||||
try {
|
||||
out.write(s.toCharArray());
|
||||
} catch (IOException e) { }
|
||||
}
|
||||
|
||||
public void print(Object o) {
|
||||
print(o.toString());
|
||||
}
|
||||
|
||||
public void print(char c) {
|
||||
print(String.valueOf(c));
|
||||
}
|
||||
|
||||
public synchronized void println(String s) {
|
||||
try {
|
||||
out.write(s.toCharArray());
|
||||
out.write(newline);
|
||||
if (autoFlush) flush();
|
||||
} catch (IOException e) { }
|
||||
}
|
||||
|
||||
public synchronized void println() {
|
||||
try {
|
||||
out.write(newline);
|
||||
if (autoFlush) flush();
|
||||
} catch (IOException e) { }
|
||||
}
|
||||
|
||||
public void println(Object o) {
|
||||
println(o.toString());
|
||||
}
|
||||
|
||||
public void println(char c) {
|
||||
println(String.valueOf(c));
|
||||
}
|
||||
|
||||
public void write(char[] buffer, int offset, int length) throws IOException {
|
||||
out.write(buffer, offset, length);
|
||||
if (autoFlush) flush();
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
try {
|
||||
out.flush();
|
||||
} catch (IOException e) { }
|
||||
}
|
||||
|
||||
public void close() {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException e) { }
|
||||
}
|
||||
}
|
74
sgx-jvm/avian/classpath/java/io/PushbackReader.java
Normal file
74
sgx-jvm/avian/classpath/java/io/PushbackReader.java
Normal file
@ -0,0 +1,74 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class PushbackReader extends Reader {
|
||||
private final Reader in;
|
||||
private char savedChar;
|
||||
private boolean hasSavedChar;
|
||||
|
||||
public PushbackReader(Reader in, int bufferSize) {
|
||||
if (bufferSize > 1) {
|
||||
throw new IllegalArgumentException(bufferSize + " > 1");
|
||||
}
|
||||
this.in = in;
|
||||
this.hasSavedChar = false;
|
||||
}
|
||||
|
||||
public PushbackReader(Reader in) {
|
||||
this(in, 1);
|
||||
}
|
||||
|
||||
public int read(char[] b, int offset, int length) throws IOException {
|
||||
int count = 0;
|
||||
if (hasSavedChar && length > 0) {
|
||||
length--;
|
||||
b[offset++] = savedChar;
|
||||
hasSavedChar = false;
|
||||
count = 1;
|
||||
}
|
||||
if (length > 0) {
|
||||
int c = in.read(b, offset, length);
|
||||
if (c == -1) {
|
||||
if (count == 0) {
|
||||
count = -1;
|
||||
}
|
||||
} else {
|
||||
count += c;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public void unread(char[] b, int offset, int length) throws IOException {
|
||||
if (length != 1) {
|
||||
throw new IOException("Can only push back 1 char, not " + length);
|
||||
} else if (hasSavedChar) {
|
||||
throw new IOException("Already have a saved char");
|
||||
} else {
|
||||
hasSavedChar = true;
|
||||
savedChar = b[offset];
|
||||
}
|
||||
}
|
||||
|
||||
public void unread(char[] b) throws IOException {
|
||||
unread(b, 0, b.length);
|
||||
}
|
||||
|
||||
public void unread(int c) throws IOException {
|
||||
unread(new char[] { (char) c });
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
in.close();
|
||||
}
|
||||
}
|
282
sgx-jvm/avian/classpath/java/io/RandomAccessFile.java
Normal file
282
sgx-jvm/avian/classpath/java/io/RandomAccessFile.java
Normal file
@ -0,0 +1,282 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
import java.lang.IllegalArgumentException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
|
||||
public class RandomAccessFile implements DataInput, Closeable {
|
||||
|
||||
private long peer;
|
||||
private File file;
|
||||
private long position = 0;
|
||||
private long length;
|
||||
private boolean allowWrite;
|
||||
|
||||
public RandomAccessFile(String name, String mode)
|
||||
throws FileNotFoundException
|
||||
{
|
||||
this(new File(name), mode);
|
||||
}
|
||||
|
||||
public RandomAccessFile(File file, String mode)
|
||||
throws FileNotFoundException
|
||||
{
|
||||
if (file == null) throw new NullPointerException();
|
||||
if (mode.equals("rw")) allowWrite = true;
|
||||
else if (! mode.equals("r")) throw new IllegalArgumentException();
|
||||
this.file = file;
|
||||
open();
|
||||
}
|
||||
|
||||
private void open() throws FileNotFoundException {
|
||||
long[] result = new long[2];
|
||||
open(file.getPath(), allowWrite, result);
|
||||
peer = result[0];
|
||||
length = result[1];
|
||||
}
|
||||
|
||||
private static native void open(String name, boolean allowWrite, long[] result)
|
||||
throws FileNotFoundException;
|
||||
|
||||
private void refresh() throws IOException {
|
||||
if (file.length() != length) {
|
||||
close();
|
||||
open();
|
||||
}
|
||||
}
|
||||
|
||||
public long length() throws IOException {
|
||||
refresh();
|
||||
return length;
|
||||
}
|
||||
|
||||
public long getFilePointer() throws IOException {
|
||||
return position;
|
||||
}
|
||||
|
||||
public void seek(long position) throws IOException {
|
||||
if (position < 0 || (!allowWrite && position > length())) throw new IOException();
|
||||
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public int skipBytes(int count) throws IOException {
|
||||
if (position + count > length()) throw new IOException();
|
||||
this.position = position + count;
|
||||
return count;
|
||||
}
|
||||
|
||||
public int read(byte b[], int off, int len) throws IOException {
|
||||
if(b == null)
|
||||
throw new IllegalArgumentException();
|
||||
if (peer == 0)
|
||||
throw new IOException();
|
||||
if(len == 0)
|
||||
return 0;
|
||||
if (position + len > this.length)
|
||||
throw new EOFException();
|
||||
if (off < 0 || off + len > b.length)
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
int bytesRead = readBytes(peer, position, b, off, len);
|
||||
position += bytesRead;
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
public int read(byte b[]) throws IOException {
|
||||
if(b == null)
|
||||
throw new IllegalArgumentException();
|
||||
if (peer == 0)
|
||||
throw new IOException();
|
||||
if(b.length == 0)
|
||||
return 0;
|
||||
if (position + b.length > this.length)
|
||||
throw new EOFException();
|
||||
int bytesRead = readBytes(peer, position, b, 0, b.length);
|
||||
position += bytesRead;
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
public void readFully(byte b[], int off, int len) throws IOException {
|
||||
if (b == null)
|
||||
throw new IllegalArgumentException();
|
||||
if (peer == 0)
|
||||
throw new IOException();
|
||||
if(len == 0)
|
||||
return;
|
||||
if (position + len > this.length)
|
||||
throw new EOFException();
|
||||
if (off < 0 || off + len > b.length)
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
int n = 0;
|
||||
do {
|
||||
int count = readBytes(peer, position, b, off + n, len - n);
|
||||
position += count;
|
||||
if (count == 0)
|
||||
throw new EOFException();
|
||||
n += count;
|
||||
} while (n < len);
|
||||
}
|
||||
|
||||
public void readFully(byte b[]) throws IOException {
|
||||
readFully(b, 0, b.length);
|
||||
}
|
||||
|
||||
private static native int readBytes(long peer, long position, byte[] buffer,
|
||||
int offset, int length);
|
||||
|
||||
public boolean readBoolean() throws IOException {
|
||||
return readByte() != 0;
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
try {
|
||||
return readByte() & 0xff;
|
||||
} catch (final EOFException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public byte readByte() throws IOException {
|
||||
final byte[] buffer = new byte[1];
|
||||
readFully(buffer);
|
||||
return buffer[0];
|
||||
}
|
||||
|
||||
public short readShort() throws IOException {
|
||||
final byte[] buffer = new byte[2];
|
||||
readFully(buffer);
|
||||
return (short)((buffer[0] << 8) | buffer[1]);
|
||||
}
|
||||
|
||||
public int readInt() throws IOException {
|
||||
byte[] buf = new byte[4];
|
||||
readFully(buf);
|
||||
return ((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]);
|
||||
}
|
||||
|
||||
public float readFloat() throws IOException {
|
||||
return Float.floatToIntBits(readInt());
|
||||
}
|
||||
|
||||
public double readDouble() throws IOException {
|
||||
return Double.doubleToLongBits(readLong());
|
||||
}
|
||||
|
||||
public long readLong() throws IOException {
|
||||
return ((readInt() & 0xffffffffl) << 32) | (readInt() & 0xffffffffl);
|
||||
}
|
||||
|
||||
public char readChar() throws IOException {
|
||||
return (char)readShort();
|
||||
}
|
||||
|
||||
public int readUnsignedByte() throws IOException {
|
||||
return readByte() & 0xff;
|
||||
}
|
||||
|
||||
public int readUnsignedShort() throws IOException {
|
||||
return readShort() & 0xffff;
|
||||
}
|
||||
|
||||
public String readUTF() throws IOException {
|
||||
int length = readUnsignedShort();
|
||||
byte[] bytes = new byte[length];
|
||||
readFully(bytes);
|
||||
return new String(bytes, "UTF-8");
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String readLine() throws IOException {
|
||||
int c = read();
|
||||
if (c < 0) {
|
||||
return null;
|
||||
} else if (c == '\n') {
|
||||
return "";
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (;;) {
|
||||
builder.append((char)c);
|
||||
c = read();
|
||||
if (c < 0 || c == '\n') {
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void write(int b) throws IOException {
|
||||
int count = writeBytes(peer, position, new byte[] { (byte)b }, 0, 1);
|
||||
if (count > 0) position += count;
|
||||
}
|
||||
|
||||
private static native int writeBytes(long peer, long position, byte[] buffer,
|
||||
int offset, int length);
|
||||
|
||||
public void close() throws IOException {
|
||||
if (peer != 0) {
|
||||
close(peer);
|
||||
peer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static native void close(long peer);
|
||||
|
||||
public FileChannel getChannel() {
|
||||
return new FileChannel() {
|
||||
public void close() {
|
||||
if (peer != 0) RandomAccessFile.close(peer);
|
||||
}
|
||||
|
||||
public boolean isOpen() {
|
||||
return peer != 0;
|
||||
}
|
||||
|
||||
public int read(ByteBuffer dst, long position) throws IOException {
|
||||
if (!dst.hasArray()) throw new IOException("Cannot handle " + dst.getClass());
|
||||
// TODO: this needs to be synchronized on the Buffer, no?
|
||||
byte[] array = dst.array();
|
||||
return readBytes(peer, position, array, dst.position(), dst.remaining());
|
||||
}
|
||||
|
||||
public int read(ByteBuffer dst) throws IOException {
|
||||
int count = read(dst, position);
|
||||
if (count > 0) position += count;
|
||||
return count;
|
||||
}
|
||||
|
||||
public int write(ByteBuffer src, long position) throws IOException {
|
||||
if (!src.hasArray()) throw new IOException("Cannot handle " + src.getClass());
|
||||
byte[] array = src.array();
|
||||
return writeBytes(peer, position, array, src.position(), src.remaining());
|
||||
}
|
||||
|
||||
public int write(ByteBuffer src) throws IOException {
|
||||
int count = write(src, position);
|
||||
if (count > 0) position += count;
|
||||
return count;
|
||||
}
|
||||
|
||||
public long position() throws IOException {
|
||||
return getFilePointer();
|
||||
}
|
||||
|
||||
public FileChannel position(long position) throws IOException {
|
||||
seek(position);
|
||||
return this;
|
||||
}
|
||||
|
||||
public long size() throws IOException {
|
||||
return length();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
58
sgx-jvm/avian/classpath/java/io/Reader.java
Normal file
58
sgx-jvm/avian/classpath/java/io/Reader.java
Normal file
@ -0,0 +1,58 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
import java.nio.CharBuffer;
|
||||
|
||||
public abstract class Reader implements Closeable, Readable {
|
||||
public int read(CharBuffer buffer) throws IOException {
|
||||
int c = read(buffer.array(),
|
||||
buffer.arrayOffset() + buffer.position(),
|
||||
buffer.remaining());
|
||||
|
||||
if (c > 0) {
|
||||
buffer.position(buffer.position() + c);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
char[] buffer = new char[1];
|
||||
int c = read(buffer);
|
||||
if (c <= 0) {
|
||||
return -1;
|
||||
} else {
|
||||
return (int) buffer[0];
|
||||
}
|
||||
}
|
||||
|
||||
public int read(char[] buffer) throws IOException {
|
||||
return read(buffer, 0, buffer.length);
|
||||
}
|
||||
|
||||
public abstract int read(char[] buffer, int offset, int length)
|
||||
throws IOException;
|
||||
|
||||
public boolean markSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void mark(int readAheadLimit) throws IOException {
|
||||
throw new IOException("mark not supported");
|
||||
}
|
||||
|
||||
public void reset() throws IOException {
|
||||
throw new IOException("reset not supported");
|
||||
}
|
||||
|
||||
public abstract void close() throws IOException;
|
||||
}
|
13
sgx-jvm/avian/classpath/java/io/Serializable.java
Normal file
13
sgx-jvm/avian/classpath/java/io/Serializable.java
Normal file
@ -0,0 +1,13 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public interface Serializable { }
|
@ -0,0 +1,21 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class StreamCorruptedException extends IOException {
|
||||
public StreamCorruptedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public StreamCorruptedException() {
|
||||
this(null);
|
||||
}
|
||||
}
|
34
sgx-jvm/avian/classpath/java/io/StringReader.java
Normal file
34
sgx-jvm/avian/classpath/java/io/StringReader.java
Normal file
@ -0,0 +1,34 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class StringReader extends Reader {
|
||||
private final String in;
|
||||
private int position = 0;
|
||||
|
||||
public StringReader(String in) {
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
public int read(char[] b, int offset, int length) throws IOException {
|
||||
if (length > in.length() - position) {
|
||||
length = in.length() - position;
|
||||
if (length <= 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
in.getChars(position, position+length, b, offset);
|
||||
position += length;
|
||||
return length;
|
||||
}
|
||||
|
||||
public void close() throws IOException { }
|
||||
}
|
31
sgx-jvm/avian/classpath/java/io/StringWriter.java
Normal file
31
sgx-jvm/avian/classpath/java/io/StringWriter.java
Normal file
@ -0,0 +1,31 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class StringWriter extends Writer {
|
||||
private final StringBuffer out = new StringBuffer();
|
||||
|
||||
public void write(char[] b, int offset, int length) throws IOException {
|
||||
out.append(b, offset, length);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
public void flush() throws IOException { }
|
||||
|
||||
public void close() throws IOException { }
|
||||
|
||||
public StringBuffer getBuffer() {
|
||||
return out;
|
||||
}
|
||||
}
|
21
sgx-jvm/avian/classpath/java/io/UTFDataFormatException.java
Normal file
21
sgx-jvm/avian/classpath/java/io/UTFDataFormatException.java
Normal file
@ -0,0 +1,21 @@
|
||||
/* Copyright (c) 2008-2015, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
public class UTFDataFormatException extends IOException {
|
||||
public UTFDataFormatException(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
public UTFDataFormatException() {
|
||||
super();
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user