mirror of
https://github.com/moparisthebest/mailiverse
synced 2024-11-24 17:42:16 -05:00
adds GWT code
This commit is contained in:
parent
25dcdeed44
commit
55b423621f
21
gwt/.classpath
Normal file
21
gwt/.classpath
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<classpath>
|
||||||
|
<classpathentry kind="src" path="src"/>
|
||||||
|
<classpathentry including="*.xml" kind="src" path="jre-gwt"/>
|
||||||
|
<classpathentry kind="src" path="jre"/>
|
||||||
|
<classpathentry kind="lib" path="/Applications/eclipse/plugins/com.google.gwt.eclipse.sdkbundle_2.5.1/gwt-2.5.1/gwt-user.jar">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="javadoc_location" value="file:/Applications/eclipse/plugins/com.google.gwt.eclipse.sdkbundle_2.5.1/gwt-2.5.1/doc/javadoc/"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="lib" path="/Applications/eclipse/plugins/com.google.gwt.eclipse.sdkbundle_2.5.1/gwt-2.5.1/gwt-dev.jar">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="javadoc_location" value="file:/Applications/eclipse/plugins/com.google.gwt.eclipse.sdkbundle_2.5.1/gwt-2.5.1/doc/javadoc/"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="lib" path="/Applications/eclipse/plugins/com.google.gwt.eclipse.sdkbundle_2.5.1/gwt-2.5.1/validation-api-1.0.0.GA-sources.jar"/>
|
||||||
|
<classpathentry kind="lib" path="/Applications/eclipse/plugins/com.google.gwt.eclipse.sdkbundle_2.5.1/gwt-2.5.1/validation-api-1.0.0.GA.jar" sourcepath="/Applications/eclipse/plugins/com.google.gwt.eclipse.sdkbundle_2.5.1/gwt-2.5.1/validation-api-1.0.0.GA-sources.jar"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||||
|
<classpathentry kind="lib" path="lib/gwtexporter-2.5.0-SNAPSHOT.jar"/>
|
||||||
|
<classpathentry kind="output" path="war/WEB-INF/classes"/>
|
||||||
|
</classpath>
|
8
gwt/.gitignore
vendored
Normal file
8
gwt/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
.gwt
|
||||||
|
gwt-unitCache
|
||||||
|
war/WEB-INF
|
||||||
|
war/mailiverse_gwt
|
||||||
|
war/*.html
|
||||||
|
war/*.js
|
||||||
|
war/*.css
|
||||||
|
war/rev/
|
34
gwt/.project
Normal file
34
gwt/.project
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>Mailiverse-GWT</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.wst.common.project.facet.core.builder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>com.google.gdt.eclipse.core.webAppProjectValidator</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>com.google.gwt.eclipse.core.gwtProjectValidator</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
|
||||||
|
<nature>com.google.gwt.eclipse.core.gwtNature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
4
gwt/.settings/com.google.appengine.eclipse.core.prefs
Normal file
4
gwt/.settings/com.google.appengine.eclipse.core.prefs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
eclipse.preferences.version=1
|
||||||
|
filesCopiedToWebInfLib=
|
||||||
|
googleCloudSqlEnabled=false
|
||||||
|
localDevMySqlEnabled=true
|
5
gwt/.settings/com.google.gdt.eclipse.core.prefs
Normal file
5
gwt/.settings/com.google.gdt.eclipse.core.prefs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
eclipse.preferences.version=1
|
||||||
|
jarsExcludedFromWebInfLib=
|
||||||
|
launchConfigExternalUrlPrefix=
|
||||||
|
warSrcDir=war
|
||||||
|
warSrcDirIsOutput=true
|
4
gwt/.settings/com.google.gwt.eclipse.core.prefs
Normal file
4
gwt/.settings/com.google.gwt.eclipse.core.prefs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
eclipse.preferences.version=1
|
||||||
|
entryPointModules=
|
||||||
|
filesCopiedToWebInfLib=gwt-servlet.jar
|
||||||
|
gwtCompileSettings=PGd3dC1jb21waWxlLXNldHRpbmdzPjxsb2ctbGV2ZWw+SU5GTzwvbG9nLWxldmVsPjxvdXRwdXQtc3R5bGU+T0JGVVNDQVRFRDwvb3V0cHV0LXN0eWxlPjxleHRyYS1hcmdzPjwhW0NEQVRBW11dPjwvZXh0cmEtYXJncz48dm0tYXJncz48IVtDREFUQVstWG14NTEybSAtRGd3dC51c2VhcmNoaXZlcz1mYWxzZV1dPjwvdm0tYXJncz48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5tYWlsaXZlcnNlLmd3dC5NYWlsaXZlcnNlX0dXVDwvZW50cnktcG9pbnQtbW9kdWxlPjwvZ3d0LWNvbXBpbGUtc2V0dGluZ3M+
|
11
gwt/.settings/org.eclipse.jdt.core.prefs
Normal file
11
gwt/.settings/org.eclipse.jdt.core.prefs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
eclipse.preferences.version=1
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||||
|
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||||
|
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||||
|
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||||
|
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||||
|
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||||
|
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||||
|
org.eclipse.jdt.core.compiler.source=1.7
|
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<faceted-project>
|
||||||
|
<installed facet="java" version="1.7"/>
|
||||||
|
</faceted-project>
|
4
gwt/Notes.txt
Normal file
4
gwt/Notes.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
Todo:
|
||||||
|
|
||||||
|
Make random come from javascript secure random.
|
||||||
|
Make login pages not be black.
|
5
gwt/clean
Executable file
5
gwt/clean
Executable file
@ -0,0 +1,5 @@
|
|||||||
|
rm -rf gwt-unitCache
|
||||||
|
rm -rf war/WEB-INF/classes/
|
||||||
|
rm -rf war/WEB-INF/deploy/
|
||||||
|
|
||||||
|
rm war/mailiverse_gwt/*.cache.html
|
5
gwt/jre-gwt/JRE.gwt.xml
Normal file
5
gwt/jre-gwt/JRE.gwt.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.4.0//EN" "http://google-web-toolkit.googlecode.com/svn/tags/2.4.0/distro-source/core/src/gwt-module.dtd">
|
||||||
|
<module>
|
||||||
|
<super-source path='jre'/>
|
||||||
|
</module>
|
1
gwt/jre-gwt/jre
Symbolic link
1
gwt/jre-gwt/jre
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../jre
|
375
gwt/jre/java/io/BufferedInputStream.java
Normal file
375
gwt/jre/java/io/BufferedInputStream.java
Normal file
@ -0,0 +1,375 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package java.io;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <code>BufferedInputStream</code> is a class which takes an input stream and
|
||||||
|
* <em>buffers</em> the input. In this way, costly interaction with the
|
||||||
|
* original input stream can be minimized by reading buffered amounts of data
|
||||||
|
* infrequently. The drawback is that extra space is required to hold the buffer
|
||||||
|
* and that copying takes place when reading that buffer.
|
||||||
|
*
|
||||||
|
* @see BufferedOutputStream
|
||||||
|
*/
|
||||||
|
public class BufferedInputStream extends FilterInputStream {
|
||||||
|
/**
|
||||||
|
* The buffer containing the current bytes read from the target InputStream.
|
||||||
|
*/
|
||||||
|
protected byte[] buf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The total number of bytes inside the byte array <code>buf</code>.
|
||||||
|
*/
|
||||||
|
protected int count;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current limit, which when passed, invalidates the current mark.
|
||||||
|
*/
|
||||||
|
protected int marklimit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The currently marked position. -1 indicates no mark has been set or the
|
||||||
|
* mark has been invalidated.
|
||||||
|
*/
|
||||||
|
protected int markpos = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current position within the byte array <code>buf</code>.
|
||||||
|
*/
|
||||||
|
protected int pos;
|
||||||
|
|
||||||
|
private boolean closed = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new <code>BufferedInputStream</code> on the InputStream
|
||||||
|
* <code>in</code>. The default buffer size (8Kb) is allocated and all
|
||||||
|
* reads can now be filtered through this stream.
|
||||||
|
*
|
||||||
|
* @param in
|
||||||
|
* the InputStream to buffer reads on.
|
||||||
|
*/
|
||||||
|
public BufferedInputStream(InputStream in) {
|
||||||
|
super(in);
|
||||||
|
buf = new byte[8192];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new BufferedInputStream on the InputStream <code>in</code>.
|
||||||
|
* The buffer size is specified by the parameter <code>size</code> and all
|
||||||
|
* reads can now be filtered through this BufferedInputStream.
|
||||||
|
*
|
||||||
|
* @param in
|
||||||
|
* the InputStream to buffer reads on.
|
||||||
|
* @param size
|
||||||
|
* the size of buffer to allocate.
|
||||||
|
*/
|
||||||
|
public BufferedInputStream(InputStream in, int size) {
|
||||||
|
super(in);
|
||||||
|
if (size <= 0) {
|
||||||
|
// K0058=size must be > 0
|
||||||
|
throw new IllegalArgumentException(Msg.getString("K0058")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
buf = new byte[size];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Answers an int representing the number of bytes that are available before
|
||||||
|
* this BufferedInputStream will block. This method returns the number of
|
||||||
|
* bytes available in the buffer plus those available in the target stream.
|
||||||
|
*
|
||||||
|
* @return the number of bytes available before blocking.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If an error occurs in this stream.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public synchronized int available() throws IOException {
|
||||||
|
if (buf == null) {
|
||||||
|
// K0059=Stream is closed
|
||||||
|
throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
return count - pos + in.available();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close this BufferedInputStream. This implementation closes the target
|
||||||
|
* stream and releases any resources associated with it.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If an error occurs attempting to close this stream.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public synchronized void close() throws IOException {
|
||||||
|
if (null != in) {
|
||||||
|
super.close();
|
||||||
|
in = null;
|
||||||
|
}
|
||||||
|
buf = null;
|
||||||
|
closed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int fillbuf() throws IOException {
|
||||||
|
if (markpos == -1 || (pos - markpos >= marklimit)) {
|
||||||
|
/* Mark position not set or exceeded readlimit */
|
||||||
|
int result = in.read(buf);
|
||||||
|
if (result > 0) {
|
||||||
|
markpos = -1;
|
||||||
|
pos = 0;
|
||||||
|
count = result == -1 ? 0 : result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (markpos == 0 && marklimit > buf.length) {
|
||||||
|
/* Increase buffer size to accomodate the readlimit */
|
||||||
|
int newLength = buf.length * 2;
|
||||||
|
if (newLength > marklimit) {
|
||||||
|
newLength = marklimit;
|
||||||
|
}
|
||||||
|
byte[] newbuf = new byte[newLength];
|
||||||
|
System.arraycopy(buf, 0, newbuf, 0, buf.length);
|
||||||
|
buf = newbuf;
|
||||||
|
} else if (markpos > 0) {
|
||||||
|
System.arraycopy(buf, markpos, buf, 0, buf.length - markpos);
|
||||||
|
}
|
||||||
|
/* Set the new position and mark position */
|
||||||
|
pos -= markpos;
|
||||||
|
count = markpos = 0;
|
||||||
|
int bytesread = in.read(buf, pos, buf.length - pos);
|
||||||
|
count = bytesread <= 0 ? pos : pos + bytesread;
|
||||||
|
return bytesread;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a Mark position in this BufferedInputStream. The parameter
|
||||||
|
* <code>readLimit</code> indicates how many bytes can be read before a
|
||||||
|
* mark is invalidated. Sending reset() will reposition the Stream back to
|
||||||
|
* the marked position provided <code>readLimit</code> has not been
|
||||||
|
* surpassed. The underlying buffer may be increased in size to allow
|
||||||
|
* <code>readlimit</code> number of bytes to be supported.
|
||||||
|
*
|
||||||
|
* @param readlimit
|
||||||
|
* the number of bytes to be able to read before invalidating the
|
||||||
|
* mark.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public synchronized void mark(int readlimit) {
|
||||||
|
marklimit = readlimit;
|
||||||
|
markpos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Answers a boolean indicating whether or not this BufferedInputStream
|
||||||
|
* supports mark() and reset(). This implementation answers
|
||||||
|
* <code>true</code>.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> for BufferedInputStreams.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean markSupported() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a single byte from this BufferedInputStream and returns the result
|
||||||
|
* as an int. The low-order byte is returned or -1 of the end of stream was
|
||||||
|
* encountered. If the underlying buffer does not contain any available
|
||||||
|
* bytes then it is filled and the first byte is returned.
|
||||||
|
*
|
||||||
|
* @return the byte read or -1 if end of stream.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If the stream is already closed or another IOException
|
||||||
|
* occurs.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public synchronized int read() throws IOException {
|
||||||
|
if (in == null) {
|
||||||
|
// K0059=Stream is closed
|
||||||
|
throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Are there buffered bytes available? */
|
||||||
|
if (pos >= count && fillbuf() == -1) {
|
||||||
|
return -1; /* no, fill buffer */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Did filling the buffer fail with -1 (EOF)? */
|
||||||
|
if (count - pos > 0) {
|
||||||
|
return buf[pos++] & 0xFF;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads at most <code>length</code> bytes from this BufferedInputStream
|
||||||
|
* and stores them in byte array <code>buffer</code> starting at offset
|
||||||
|
* <code>offset</code>. Answer the number of bytes actually read or -1 if
|
||||||
|
* no bytes were read and end of stream was encountered. If all the buffered
|
||||||
|
* bytes have been used, a mark has not been set, and the requested number
|
||||||
|
* of bytes is larger than the receiver's buffer size, this implementation
|
||||||
|
* bypasses the buffer and simply places the results directly into
|
||||||
|
* <code>buffer</code>.
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* the byte array in which to store the read bytes.
|
||||||
|
* @param offset
|
||||||
|
* the offset in <code>buffer</code> to store the read bytes.
|
||||||
|
* @param length
|
||||||
|
* the maximum number of bytes to store in <code>buffer</code>.
|
||||||
|
* @return the number of bytes actually read or -1 if end of stream.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If the stream is already closed or another IOException
|
||||||
|
* occurs.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public synchronized int read(byte[] buffer, int offset, int length)
|
||||||
|
throws IOException {
|
||||||
|
if (closed) {
|
||||||
|
// K0059=Stream is closed
|
||||||
|
throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
// avoid int overflow
|
||||||
|
if (offset > buffer.length - length || offset < 0 || length < 0) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
if (length == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (null == buf) {
|
||||||
|
throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
int required;
|
||||||
|
if (pos < count) {
|
||||||
|
/* There are bytes available in the buffer. */
|
||||||
|
int copylength = count - pos >= length ? length : count - pos;
|
||||||
|
System.arraycopy(buf, pos, buffer, offset, copylength);
|
||||||
|
pos += copylength;
|
||||||
|
if (copylength == length || in.available() == 0) {
|
||||||
|
return copylength;
|
||||||
|
}
|
||||||
|
offset += copylength;
|
||||||
|
required = length - copylength;
|
||||||
|
} else {
|
||||||
|
required = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
int read;
|
||||||
|
/*
|
||||||
|
* If we're not marked and the required size is greater than the
|
||||||
|
* buffer, simply read the bytes directly bypassing the buffer.
|
||||||
|
*/
|
||||||
|
if (markpos == -1 && required >= buf.length) {
|
||||||
|
read = in.read(buffer, offset, required);
|
||||||
|
if (read == -1) {
|
||||||
|
return required == length ? -1 : length - required;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (fillbuf() == -1) {
|
||||||
|
return required == length ? -1 : length - required;
|
||||||
|
}
|
||||||
|
read = count - pos >= required ? required : count - pos;
|
||||||
|
System.arraycopy(buf, pos, buffer, offset, read);
|
||||||
|
pos += read;
|
||||||
|
}
|
||||||
|
required -= read;
|
||||||
|
if (required == 0) {
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
if (in.available() == 0) {
|
||||||
|
return length - required;
|
||||||
|
}
|
||||||
|
offset += read;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset this BufferedInputStream to the last marked location. If the
|
||||||
|
* <code>readlimit</code> has been passed or no <code>mark</code> has
|
||||||
|
* been set, throw IOException. This implementation resets the target
|
||||||
|
* stream.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If the stream is already closed or another IOException
|
||||||
|
* occurs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void reset() throws IOException {
|
||||||
|
if (closed) {
|
||||||
|
// K0059=Stream is closed
|
||||||
|
throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (-1 == markpos) {
|
||||||
|
// K005a=Mark has been invalidated.
|
||||||
|
throw new IOException(Msg.getString("K005a")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
pos = markpos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skips <code>amount</code> number of bytes in this BufferedInputStream.
|
||||||
|
* Subsequent <code>read()</code>'s will not return these bytes unless
|
||||||
|
* <code>reset()</code> is used.
|
||||||
|
*
|
||||||
|
* @param amount
|
||||||
|
* the number of bytes to skip.
|
||||||
|
* @return the number of bytes actually skipped.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If the stream is already closed or another IOException
|
||||||
|
* occurs.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public synchronized long skip(long amount) throws IOException {
|
||||||
|
if (null == in) {
|
||||||
|
// K0059=Stream is closed
|
||||||
|
throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (amount < 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count - pos >= amount) {
|
||||||
|
pos += amount;
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
long read = count - pos;
|
||||||
|
pos = count;
|
||||||
|
|
||||||
|
if (markpos != -1) {
|
||||||
|
if (amount <= marklimit) {
|
||||||
|
if (fillbuf() == -1) {
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
if (count - pos >= amount - read) {
|
||||||
|
pos += amount - read;
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
// Couldn't get all the bytes, skip what we read
|
||||||
|
read += (count - pos);
|
||||||
|
pos = count;
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
markpos = -1;
|
||||||
|
}
|
||||||
|
return read + in.skip(amount - read);
|
||||||
|
}
|
||||||
|
}
|
485
gwt/jre/java/io/BufferedReader.java
Normal file
485
gwt/jre/java/io/BufferedReader.java
Normal file
@ -0,0 +1,485 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package java.io;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BufferedReader is a buffered character input reader. Buffering allows reading
|
||||||
|
* from character streams more efficiently. If the default size of the buffer is
|
||||||
|
* not practical, another size may be specified. Reading a character from a
|
||||||
|
* Reader class usually involves reading a character from its Stream or
|
||||||
|
* subsequent Reader. It is advisable to wrap a BufferedReader around those
|
||||||
|
* Readers whose read operations may have high latency. For example, the
|
||||||
|
* following code
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* BufferedReader inReader = new BufferedReader(new FileReader("file.java"));
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* will buffer input for the file <code>file.java</code>.
|
||||||
|
*
|
||||||
|
* @see BufferedWriter
|
||||||
|
* @since 1.1
|
||||||
|
*/
|
||||||
|
public class BufferedReader extends Reader {
|
||||||
|
|
||||||
|
private Reader in;
|
||||||
|
|
||||||
|
private char[] buf;
|
||||||
|
|
||||||
|
private int marklimit = -1;
|
||||||
|
|
||||||
|
private int count;
|
||||||
|
|
||||||
|
private int markpos = -1;
|
||||||
|
|
||||||
|
private int pos;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new BufferedReader on the Reader <code>in</code>. The
|
||||||
|
* default buffer size (8K) is allocated and all reads can now be filtered
|
||||||
|
* through this BufferedReader.
|
||||||
|
*
|
||||||
|
* @param in
|
||||||
|
* the Reader to buffer reads on.
|
||||||
|
*/
|
||||||
|
public BufferedReader(Reader in) {
|
||||||
|
super(in);
|
||||||
|
this.in = in;
|
||||||
|
buf = new char[8192];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new BufferedReader on the Reader <code>in</code>. The
|
||||||
|
* buffer size is specified by the parameter <code>size</code> and all
|
||||||
|
* reads can now be filtered through this BufferedReader.
|
||||||
|
*
|
||||||
|
* @param in
|
||||||
|
* the Reader to buffer reads on.
|
||||||
|
* @param size
|
||||||
|
* the size of buffer to allocate.
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
* if the size is <= 0
|
||||||
|
*/
|
||||||
|
public BufferedReader(Reader in, int size) {
|
||||||
|
super(in);
|
||||||
|
if (size <= 0) {
|
||||||
|
throw new IllegalArgumentException(Msg.getString("K0058")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
this.in = in;
|
||||||
|
buf = new char[size];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the Reader. This implementation closes the Reader being filtered
|
||||||
|
* and releases the buffer used by this reader. If this BufferedReader has
|
||||||
|
* already been closed, nothing is done.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If an error occurs attempting to close this BufferedReader.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
synchronized (lock) {
|
||||||
|
if (!isClosed()) {
|
||||||
|
in.close();
|
||||||
|
buf = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int fillbuf() throws IOException {
|
||||||
|
if (markpos == -1 || (pos - markpos >= marklimit)) {
|
||||||
|
/* Mark position not set or exceeded readlimit */
|
||||||
|
int result = in.read(buf, 0, buf.length);
|
||||||
|
if (result > 0) {
|
||||||
|
markpos = -1;
|
||||||
|
pos = 0;
|
||||||
|
count = result == -1 ? 0 : result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (markpos == 0 && marklimit > buf.length) {
|
||||||
|
/* Increase buffer size to accommodate the readlimit */
|
||||||
|
int newLength = buf.length * 2;
|
||||||
|
if (newLength > marklimit) {
|
||||||
|
newLength = marklimit;
|
||||||
|
}
|
||||||
|
char[] newbuf = new char[newLength];
|
||||||
|
System.arraycopy(buf, 0, newbuf, 0, buf.length);
|
||||||
|
buf = newbuf;
|
||||||
|
} else if (markpos > 0) {
|
||||||
|
System.arraycopy(buf, markpos, buf, 0, buf.length - markpos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the new position and mark position */
|
||||||
|
pos -= markpos;
|
||||||
|
count = markpos = 0;
|
||||||
|
int charsread = in.read(buf, pos, buf.length - pos);
|
||||||
|
count = charsread == -1 ? pos : pos + charsread;
|
||||||
|
return charsread;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Answer a boolean indicating whether or not this BufferedReader is closed.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if this reader is closed, <code>false</code>
|
||||||
|
* otherwise
|
||||||
|
*/
|
||||||
|
private boolean isClosed() {
|
||||||
|
return buf == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a Mark position in this BufferedReader. The parameter
|
||||||
|
* <code>readLimit</code> indicates how many characters can be read before
|
||||||
|
* a mark is invalidated. Sending reset() will reposition the reader back to
|
||||||
|
* the marked position provided <code>readLimit</code> has not been
|
||||||
|
* surpassed.
|
||||||
|
*
|
||||||
|
* @param readlimit
|
||||||
|
* an int representing how many characters must be read before
|
||||||
|
* invalidating the mark.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If an error occurs attempting mark this BufferedReader.
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
* If readlimit is < 0
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void mark(int readlimit) throws IOException {
|
||||||
|
if (readlimit < 0) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
synchronized (lock) {
|
||||||
|
if (isClosed()) {
|
||||||
|
throw new IOException(Msg.getString("K005b")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
marklimit = readlimit;
|
||||||
|
markpos = pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Answers a boolean indicating whether or not this Reader supports mark()
|
||||||
|
* and reset(). This implementation answers <code>true</code>.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if mark() and reset() are supported,
|
||||||
|
* <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean markSupported() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a single character from this reader and returns the result as an
|
||||||
|
* int. The 2 higher-order characters are set to 0. If the end of reader was
|
||||||
|
* encountered then return -1. This implementation either returns a
|
||||||
|
* character from the buffer or if there are no characters available, fill
|
||||||
|
* the buffer then return a character or -1.
|
||||||
|
*
|
||||||
|
* @return the character read or -1 if end of reader.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If the BufferedReader is already closed or some other IO
|
||||||
|
* error occurs.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int read() throws IOException {
|
||||||
|
synchronized (lock) {
|
||||||
|
if (isClosed()) {
|
||||||
|
throw new IOException(Msg.getString("K005b")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
/* Are there buffered characters available? */
|
||||||
|
if (pos < count || fillbuf() != -1) {
|
||||||
|
return buf[pos++];
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads at most <code>length</code> characters from this BufferedReader
|
||||||
|
* and stores them at <code>offset</code> in the character array
|
||||||
|
* <code>buffer</code>. Returns the number of characters actually read or
|
||||||
|
* -1 if the end of reader was encountered. If all the buffered characters
|
||||||
|
* have been used, a mark has not been set, and the requested number of
|
||||||
|
* characters is larger than this Readers buffer size, this implementation
|
||||||
|
* bypasses the buffer and simply places the results directly into
|
||||||
|
* <code>buffer</code>.
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* character array to store the read characters
|
||||||
|
* @param offset
|
||||||
|
* offset in buf to store the read characters
|
||||||
|
* @param length
|
||||||
|
* maximum number of characters to read
|
||||||
|
* @return number of characters read or -1 if end of reader.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If the BufferedReader is already closed or some other IO
|
||||||
|
* error occurs.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int read(char[] buffer, int offset, int length) throws IOException {
|
||||||
|
synchronized (lock) {
|
||||||
|
if (isClosed()) {
|
||||||
|
throw new IOException(Msg.getString("K005b")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (offset < 0 || offset > buffer.length - length || length < 0) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
if (length == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int required;
|
||||||
|
if (pos < count) {
|
||||||
|
/* There are bytes available in the buffer. */
|
||||||
|
int copylength = count - pos >= length ? length : count - pos;
|
||||||
|
System.arraycopy(buf, pos, buffer, offset, copylength);
|
||||||
|
pos += copylength;
|
||||||
|
if (copylength == length || !in.ready()) {
|
||||||
|
return copylength;
|
||||||
|
}
|
||||||
|
offset += copylength;
|
||||||
|
required = length - copylength;
|
||||||
|
} else {
|
||||||
|
required = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
int read;
|
||||||
|
/*
|
||||||
|
* If we're not marked and the required size is greater than the
|
||||||
|
* buffer, simply read the bytes directly bypassing the buffer.
|
||||||
|
*/
|
||||||
|
if (markpos == -1 && required >= buf.length) {
|
||||||
|
read = in.read(buffer, offset, required);
|
||||||
|
if (read == -1) {
|
||||||
|
return required == length ? -1 : length - required;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (fillbuf() == -1) {
|
||||||
|
return required == length ? -1 : length - required;
|
||||||
|
}
|
||||||
|
read = count - pos >= required ? required : count - pos;
|
||||||
|
System.arraycopy(buf, pos, buffer, offset, read);
|
||||||
|
pos += read;
|
||||||
|
}
|
||||||
|
required -= read;
|
||||||
|
if (required == 0) {
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
if (!in.ready()) {
|
||||||
|
return length - required;
|
||||||
|
}
|
||||||
|
offset += read;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Answers a <code>String</code> representing the next line of text
|
||||||
|
* available in this BufferedReader. A line is represented by 0 or more
|
||||||
|
* characters followed by <code>'\n'</code>, <code>'\r'</code>,
|
||||||
|
* <code>'\r\n'</code> or end of stream. The <code>String</code> does
|
||||||
|
* not include the newline sequence.
|
||||||
|
*
|
||||||
|
* @return the contents of the line or null if no characters were read
|
||||||
|
* before end of stream.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If the BufferedReader is already closed or some other IO
|
||||||
|
* error occurs.
|
||||||
|
*/
|
||||||
|
public String readLine() throws IOException {
|
||||||
|
synchronized (lock) {
|
||||||
|
if (isClosed()) {
|
||||||
|
throw new IOException(Msg.getString("K005b")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
/* Are there buffered characters available? */
|
||||||
|
if ((pos >= count) && (fillbuf() == -1)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (int charPos = pos; charPos < count; charPos++) {
|
||||||
|
char ch = buf[charPos];
|
||||||
|
if (ch > '\r') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ch == '\n') {
|
||||||
|
String res = new String(buf, pos, charPos - pos);
|
||||||
|
pos = charPos + 1;
|
||||||
|
return res;
|
||||||
|
} else if (ch == '\r') {
|
||||||
|
String res = new String(buf, pos, charPos - pos);
|
||||||
|
pos = charPos + 1;
|
||||||
|
if (((pos < count) || (fillbuf() != -1))
|
||||||
|
&& (buf[pos] == '\n')) {
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char eol = '\0';
|
||||||
|
StringBuilder result = new StringBuilder(80);
|
||||||
|
/* Typical Line Length */
|
||||||
|
|
||||||
|
result.append(buf, pos, count - pos);
|
||||||
|
pos = count;
|
||||||
|
while (true) {
|
||||||
|
/* Are there buffered characters available? */
|
||||||
|
if (pos >= count) {
|
||||||
|
if (eol == '\n') {
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
// attempt to fill buffer
|
||||||
|
if (fillbuf() == -1) {
|
||||||
|
// characters or null.
|
||||||
|
return result.length() > 0 || eol != '\0' ? result
|
||||||
|
.toString() : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int charPos = pos; charPos < count; charPos++) {
|
||||||
|
if (eol == '\0') {
|
||||||
|
if ((buf[charPos] == '\n' || buf[charPos] == '\r')) {
|
||||||
|
eol = buf[charPos];
|
||||||
|
}
|
||||||
|
} else if (eol == '\r' && (buf[charPos] == '\n')) {
|
||||||
|
if (charPos > pos) {
|
||||||
|
result.append(buf, pos, charPos - pos - 1);
|
||||||
|
}
|
||||||
|
pos = charPos + 1;
|
||||||
|
return result.toString();
|
||||||
|
} else if (eol != '\0') {
|
||||||
|
if (charPos > pos) {
|
||||||
|
result.append(buf, pos, charPos - pos - 1);
|
||||||
|
}
|
||||||
|
pos = charPos;
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (eol == '\0') {
|
||||||
|
result.append(buf, pos, count - pos);
|
||||||
|
} else {
|
||||||
|
result.append(buf, pos, count - pos - 1);
|
||||||
|
}
|
||||||
|
pos = count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Answers a <code>boolean</code> indicating whether or not this Reader is
|
||||||
|
* ready to be read without blocking. If the result is <code>true</code>,
|
||||||
|
* the next <code>read()</code> will not block. If the result is
|
||||||
|
* <code>false</code> this Reader may or may not block when
|
||||||
|
* <code>read()</code> is sent.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if the receiver will not block when
|
||||||
|
* <code>read()</code> is called, <code>false</code> if unknown
|
||||||
|
* or blocking will occur.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If the BufferedReader is already closed or some other IO
|
||||||
|
* error occurs.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean ready() throws IOException {
|
||||||
|
synchronized (lock) {
|
||||||
|
if (isClosed()) {
|
||||||
|
throw new IOException(Msg.getString("K005b")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
return ((count - pos) > 0) || in.ready();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset this BufferedReader's position to the last <code>mark()</code>
|
||||||
|
* location. Invocations of <code>read()/skip()</code> will occur from
|
||||||
|
* this new location. If this Reader was not marked, throw IOException.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If a problem occurred, the receiver does not support
|
||||||
|
* <code>mark()/reset()</code>, or no mark has been set.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void reset() throws IOException {
|
||||||
|
synchronized (lock) {
|
||||||
|
if (isClosed()) {
|
||||||
|
throw new IOException(Msg.getString("K005b")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (markpos == -1) {
|
||||||
|
throw new IOException(Msg.getString("K005c")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
pos = markpos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skips <code>amount</code> number of characters in this Reader.
|
||||||
|
* Subsequent <code>read()</code>'s will not return these characters
|
||||||
|
* unless <code>reset()</code> is used. Skipping characters may invalidate
|
||||||
|
* a mark if marklimit is surpassed.
|
||||||
|
*
|
||||||
|
* @param amount
|
||||||
|
* the maximum number of characters to skip.
|
||||||
|
* @return the number of characters actually skipped.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If the BufferedReader is already closed or some other IO
|
||||||
|
* error occurs.
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
* If amount is negative
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public long skip(long amount) throws IOException {
|
||||||
|
if (amount < 0) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
synchronized (lock) {
|
||||||
|
if (isClosed()) {
|
||||||
|
throw new IOException(Msg.getString("K005b")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (amount < 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (count - pos >= amount) {
|
||||||
|
pos += amount;
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
long read = count - pos;
|
||||||
|
pos = count;
|
||||||
|
while (read < amount) {
|
||||||
|
if (fillbuf() == -1) {
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
if (count - pos >= amount - read) {
|
||||||
|
pos += amount - read;
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
// Couldn't get all the characters, skip what we read
|
||||||
|
read += (count - pos);
|
||||||
|
pos = count;
|
||||||
|
}
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
69
gwt/jre/java/io/ByteArrayInputStream.java
Normal file
69
gwt/jre/java/io/ByteArrayInputStream.java
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010 Google Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
package java.io;
|
||||||
|
|
||||||
|
public class ByteArrayInputStream extends InputStream {
|
||||||
|
|
||||||
|
protected byte[] buf;
|
||||||
|
protected int pos = 0;
|
||||||
|
protected int start = 0;
|
||||||
|
protected int mark = 0;
|
||||||
|
protected int count;
|
||||||
|
|
||||||
|
public ByteArrayInputStream(byte[] data) {
|
||||||
|
this.buf = data;
|
||||||
|
this.count = data.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteArrayInputStream(byte[] data, int offset, int len) {
|
||||||
|
this.buf = data;
|
||||||
|
count = offset + len;
|
||||||
|
this.mark = this.start = this.pos = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read() {
|
||||||
|
return pos < count ? (buf[pos++] & 0xFF) : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int available() {
|
||||||
|
return count - pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long skip(long n) throws IOException, IllegalArgumentException {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
pos += n;
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset() throws IOException {
|
||||||
|
pos = mark;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mark(int readAheadLimit) {
|
||||||
|
mark = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean markSupported() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
67
gwt/jre/java/io/ByteArrayOutputStream.java
Normal file
67
gwt/jre/java/io/ByteArrayOutputStream.java
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010 Google Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
package java.io;
|
||||||
|
|
||||||
|
import core.util.Arrays;
|
||||||
|
|
||||||
|
public class ByteArrayOutputStream extends OutputStream {
|
||||||
|
|
||||||
|
protected int count = 0;
|
||||||
|
protected byte[] buf;
|
||||||
|
|
||||||
|
public ByteArrayOutputStream() {
|
||||||
|
this(16);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteArrayOutputStream(int initialSize) {
|
||||||
|
buf = new byte[initialSize];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(int b) {
|
||||||
|
if (buf.length == count) {
|
||||||
|
byte[] newBuf = new byte[buf.length * 3 / 2];
|
||||||
|
Arrays.copyFromTo(buf, 0, newBuf, 0, count);
|
||||||
|
buf = newBuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[count++] = (byte)b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(byte[] ba, int start, int len) {
|
||||||
|
int end = start + len;
|
||||||
|
for (int i = start; i < end; i++) {
|
||||||
|
write(ba[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(byte[] ba)
|
||||||
|
{
|
||||||
|
write(ba,0, ba.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] toByteArray() {
|
||||||
|
return Arrays.copyOf(buf,count);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset () {
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
}
|
79
gwt/jre/java/io/DataInputStream.java
Normal file
79
gwt/jre/java/io/DataInputStream.java
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
package java.io;
|
||||||
|
|
||||||
|
public class DataInputStream extends FilterInputStream
|
||||||
|
{
|
||||||
|
public DataInputStream(InputStream in)
|
||||||
|
{
|
||||||
|
super(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads bytes from the source stream into the byte array
|
||||||
|
* <code>buffer</code>. The number of bytes actually read is returned.
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* the buffer to read bytes into
|
||||||
|
* @return the number of bytes actually read or -1 if end of stream.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If a problem occurs reading from this DataInputStream.
|
||||||
|
*
|
||||||
|
* @see DataOutput#write(byte[])
|
||||||
|
* @see DataOutput#write(byte[], int, int)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final int read(byte[] buffer) throws IOException {
|
||||||
|
return in.read(buffer, 0, buffer.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a 32-bit integer value from this stream.
|
||||||
|
*
|
||||||
|
* @return the next <code>int</code> value from the source stream.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If a problem occurs reading from this DataInputStream.
|
||||||
|
*
|
||||||
|
* @see DataOutput#writeInt(int)
|
||||||
|
*/
|
||||||
|
public final int readInt() throws IOException {
|
||||||
|
int b1 = in.read();
|
||||||
|
int b2 = in.read();
|
||||||
|
int b3 = in.read();
|
||||||
|
int b4 = in.read();
|
||||||
|
|
||||||
|
if ((b1 | b2 | b3 | b4) < 0) {
|
||||||
|
throw new EOFException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((b1 << 24) + (b2 << 16) + (b3 << 8) + b4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read at most <code>length</code> bytes from this DataInputStream and
|
||||||
|
* stores them in byte array <code>buffer</code> starting at
|
||||||
|
* <code>offset</code>. Answer the number of bytes actually read or -1 if
|
||||||
|
* no bytes were read and end of stream was encountered.
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* the byte array in which to store the read bytes.
|
||||||
|
* @param offset
|
||||||
|
* the offset in <code>buffer</code> to store the read bytes.
|
||||||
|
* @param length
|
||||||
|
* the maximum number of bytes to store in <code>buffer</code>.
|
||||||
|
* @return the number of bytes actually read or -1 if end of stream.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If a problem occurs reading from this DataInputStream.
|
||||||
|
*
|
||||||
|
* @see DataOutput#write(byte[])
|
||||||
|
* @see DataOutput#write(byte[], int, int)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final int read(byte[] buffer, int offset, int length)
|
||||||
|
throws IOException {
|
||||||
|
return in.read(buffer, offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
49
gwt/jre/java/io/DataOutputStream.java
Normal file
49
gwt/jre/java/io/DataOutputStream.java
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package java.io;
|
||||||
|
|
||||||
|
public class DataOutputStream extends FilterOutputStream {
|
||||||
|
|
||||||
|
protected int written;
|
||||||
|
|
||||||
|
public DataOutputStream(OutputStream out) {
|
||||||
|
super(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() throws IOException
|
||||||
|
{
|
||||||
|
super.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(byte buffer[], int offset, int count) throws IOException {
|
||||||
|
if (buffer == null) {
|
||||||
|
throw new NullPointerException(); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
out.write(buffer, offset, count);
|
||||||
|
written += count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(byte buffer[]) throws IOException
|
||||||
|
{
|
||||||
|
write(buffer, 0, buffer.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a 32-bit int to this output stream. The resulting output is the 4
|
||||||
|
* bytes, highest order first, of val.
|
||||||
|
*
|
||||||
|
* @param val
|
||||||
|
* the int to be written.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If an error occurs attempting to write to this
|
||||||
|
* DataOutputStream.
|
||||||
|
*
|
||||||
|
* @see DataInput#readInt()
|
||||||
|
*/
|
||||||
|
public final void writeInt(int val) throws IOException {
|
||||||
|
out.write((byte)(val >> 24));
|
||||||
|
out.write((byte)(val >> 16));
|
||||||
|
out.write((byte)(val >> 8));
|
||||||
|
out.write((byte)(val));
|
||||||
|
written += 4;
|
||||||
|
}
|
||||||
|
}
|
46
gwt/jre/java/io/EOFException.java
Normal file
46
gwt/jre/java/io/EOFException.java
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package java.io;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This End Of File (EOF) exception is thrown when a program encounters the end
|
||||||
|
* of a file or stream during an operation.
|
||||||
|
*/
|
||||||
|
public class EOFException extends IOException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 6433858223774886977L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new instance of this class with its walkback filled in.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public EOFException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new instance of this class with its walkback and message
|
||||||
|
* filled in.
|
||||||
|
*
|
||||||
|
* @param detailMessage
|
||||||
|
* The detail message for the exception.
|
||||||
|
*/
|
||||||
|
public EOFException(String detailMessage) {
|
||||||
|
super(detailMessage);
|
||||||
|
}
|
||||||
|
}
|
197
gwt/jre/java/io/FilterInputStream.java
Normal file
197
gwt/jre/java/io/FilterInputStream.java
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package java.io;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FilteredInputStream is a class which takes an input stream and
|
||||||
|
* <em>filters</em> the input in some way. The filtered view may be a buffered
|
||||||
|
* view or one which uncompresses data before returning bytes read.
|
||||||
|
* FilterInputStreams are meant for byte streams.
|
||||||
|
*
|
||||||
|
* @see FilterOutputStream
|
||||||
|
*/
|
||||||
|
public class FilterInputStream extends InputStream {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The target InputStream which is being filtered.
|
||||||
|
*/
|
||||||
|
protected InputStream in;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new FilterInputStream on the InputStream <code>in</code>.
|
||||||
|
* All reads are now filtered through this stream.
|
||||||
|
*
|
||||||
|
* @param in
|
||||||
|
* The non-null InputStream to filter reads on.
|
||||||
|
*/
|
||||||
|
protected FilterInputStream(InputStream in) {
|
||||||
|
super();
|
||||||
|
this.in = in;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Answers a int representing the number of bytes that are available before
|
||||||
|
* this FilterInputStream will block. This method returns the number of
|
||||||
|
* bytes available in the target stream.
|
||||||
|
*
|
||||||
|
* @return the number of bytes available before blocking.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If an error occurs in this stream.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int available() throws IOException {
|
||||||
|
return in.available();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close this FilterInputStream. This implementation closes the target
|
||||||
|
* stream.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If an error occurs attempting to close this stream.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a Mark position in this FilterInputStream. The parameter
|
||||||
|
* <code>readLimit</code> indicates how many bytes can be read before a
|
||||||
|
* mark is invalidated. Sending reset() will reposition the Stream back to
|
||||||
|
* the marked position provided <code>readLimit</code> has not been
|
||||||
|
* surpassed.
|
||||||
|
* <p>
|
||||||
|
* This implementation sets a mark in the target stream.
|
||||||
|
*
|
||||||
|
* @param readlimit
|
||||||
|
* the number of bytes to be able to read before invalidating the
|
||||||
|
* mark.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public synchronized void mark(int readlimit) {
|
||||||
|
in.mark(readlimit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Answers a boolean indicating whether or not this FilterInputStream
|
||||||
|
* supports mark() and reset(). This implementation answers whether or not
|
||||||
|
* the target stream supports marking.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if mark() and reset() are supported,
|
||||||
|
* <code>false</code> otherwise.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean markSupported() {
|
||||||
|
return in.markSupported();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a single byte from this FilterInputStream and returns the result as
|
||||||
|
* an int. The low-order byte is returned or -1 of the end of stream was
|
||||||
|
* encountered. This implementation returns a byte from the target stream.
|
||||||
|
*
|
||||||
|
* @return the byte read or -1 if end of stream.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If the stream is already closed or another IOException
|
||||||
|
* occurs.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int read() throws IOException {
|
||||||
|
return in.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads bytes from this FilterInputStream and stores them in byte array
|
||||||
|
* <code>buffer</code>. Answer the number of bytes actually read or -1 if
|
||||||
|
* no bytes were read and end of stream was encountered. This implementation
|
||||||
|
* reads bytes from the target stream.
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* the byte array in which to store the read bytes.
|
||||||
|
* @return the number of bytes actually read or -1 if end of stream.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If the stream is already closed or another IOException
|
||||||
|
* occurs.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int read(byte[] buffer) throws IOException {
|
||||||
|
return read(buffer, 0, buffer.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads at most <code>count</code> bytes from this FilterInputStream and
|
||||||
|
* stores them in byte array <code>buffer</code> starting at
|
||||||
|
* <code>offset</code>. Answer the number of bytes actually read or -1 if
|
||||||
|
* no bytes were read and end of stream was encountered. This implementation
|
||||||
|
* reads bytes from the target stream.
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* the byte array in which to store the read bytes.
|
||||||
|
* @param offset
|
||||||
|
* the offset in <code>buffer</code> to store the read bytes.
|
||||||
|
* @param count
|
||||||
|
* the maximum number of bytes to store in <code>buffer</code>.
|
||||||
|
* @return the number of bytes actually read or -1 if end of stream.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If the stream is already closed or another IOException
|
||||||
|
* occurs.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int read(byte[] buffer, int offset, int count) throws IOException {
|
||||||
|
return in.read(buffer, offset, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset this FilterInputStream to the last marked location. If the
|
||||||
|
* <code>readlimit</code> has been passed or no <code>mark</code> has
|
||||||
|
* been set, throw IOException. This implementation resets the target
|
||||||
|
* stream.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If the stream is already closed or another IOException
|
||||||
|
* occurs.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public synchronized void reset() throws IOException {
|
||||||
|
in.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skips <code>count</code> number of bytes in this InputStream.
|
||||||
|
* Subsequent <code>read()</code>'s will not return these bytes unless
|
||||||
|
* <code>reset()</code> is used. This implementation skips
|
||||||
|
* <code>count</code> number of bytes in the target stream.
|
||||||
|
*
|
||||||
|
* @param count
|
||||||
|
* the number of bytes to skip.
|
||||||
|
* @return the number of bytes actually skipped.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If the stream is already closed or another IOException
|
||||||
|
* occurs.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public long skip(long count) throws IOException {
|
||||||
|
return in.skip(count);
|
||||||
|
}
|
||||||
|
}
|
144
gwt/jre/java/io/FilterOutputStream.java
Normal file
144
gwt/jre/java/io/FilterOutputStream.java
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package java.io;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FilteredOutputStream is a class which takes an output stream and
|
||||||
|
* <em>filters</em> the output in some way. The filtered view may be a
|
||||||
|
* buffered output or one which compresses data before actually writing the
|
||||||
|
* bytes. FilterOutputStreams are meant for byte streams.
|
||||||
|
*
|
||||||
|
* @see FilterInputStream
|
||||||
|
*/
|
||||||
|
public class FilterOutputStream extends OutputStream {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The target OutputStream for this filter.
|
||||||
|
*/
|
||||||
|
protected OutputStream out;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new FilterOutputStream on the OutputStream <code>out</code>.
|
||||||
|
* All writes are now filtered through this stream.
|
||||||
|
*
|
||||||
|
* @param out
|
||||||
|
* the target OutputStream to filter writes on.
|
||||||
|
*/
|
||||||
|
public FilterOutputStream(OutputStream out) {
|
||||||
|
this.out = out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close this FilterOutputStream. This implementation closes the target
|
||||||
|
* stream.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If an error occurs attempting to close this stream.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
try {
|
||||||
|
flush();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// Ignored
|
||||||
|
}
|
||||||
|
/* Make sure we clean up this stream if exception fires */
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flush this FilterOutputStream to ensure all pending data is sent out to
|
||||||
|
* the target OutputStream. This implementation flushes the target
|
||||||
|
* OutputStream.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If an error occurs attempting to flush this
|
||||||
|
* FilterOutputStream.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void flush() throws IOException {
|
||||||
|
out.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the entire contents of the byte array <code>buffer</code> to
|
||||||
|
* this FilterOutputStream. This implementation writes the
|
||||||
|
* <code>buffer</code> to the target stream.
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* the buffer to be written
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If an error occurs attempting to write to this
|
||||||
|
* FilterOutputStream.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void write(byte buffer[]) throws IOException {
|
||||||
|
write(buffer, 0, buffer.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes <code>count</code> <code>bytes</code> from the byte array
|
||||||
|
* <code>buffer</code> starting at <code>offset</code> to this
|
||||||
|
* FilterOutputStream. This implementation writes the <code>buffer</code>
|
||||||
|
* to the target OutputStream.
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* the buffer to be written
|
||||||
|
* @param offset
|
||||||
|
* offset in buffer to get bytes
|
||||||
|
* @param count
|
||||||
|
* number of bytes in buffer to write
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If an error occurs attempting to write to this
|
||||||
|
* FilterOutputStream.
|
||||||
|
* @throws IndexOutOfBoundsException
|
||||||
|
* If offset or count are outside of bounds.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void write(byte buffer[], int offset, int count) throws IOException {
|
||||||
|
// avoid int overflow, force null buffer check first
|
||||||
|
if (offset > buffer.length || offset < 0 || count < 0
|
||||||
|
|| count > buffer.length - offset) {
|
||||||
|
throw new ArrayIndexOutOfBoundsException(); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
// Call write() instead of out.write() since subclasses could
|
||||||
|
// override the write() method.
|
||||||
|
write(buffer[offset + i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the specified byte <code>oneByte</code> to this
|
||||||
|
* FilterOutputStream. Only the low order byte of <code>oneByte</code> is
|
||||||
|
* written. This implementation writes the byte to the target OutputStream.
|
||||||
|
*
|
||||||
|
* @param oneByte
|
||||||
|
* the byte to be written
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If an error occurs attempting to write to this
|
||||||
|
* FilterOutputStream.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void write(int oneByte) throws IOException {
|
||||||
|
out.write(oneByte);
|
||||||
|
}
|
||||||
|
}
|
31
gwt/jre/java/io/IOException.java
Normal file
31
gwt/jre/java/io/IOException.java
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010 Google Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
package java.io;
|
||||||
|
|
||||||
|
public class IOException extends Exception {
|
||||||
|
|
||||||
|
public IOException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IOException(String s) {
|
||||||
|
super(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IOException(Exception e) {
|
||||||
|
super(e);
|
||||||
|
}
|
||||||
|
}
|
57
gwt/jre/java/io/InputStream.java
Normal file
57
gwt/jre/java/io/InputStream.java
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010 Google Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
package java.io;
|
||||||
|
|
||||||
|
public abstract class InputStream {
|
||||||
|
public abstract int read() throws IOException;
|
||||||
|
|
||||||
|
public int read(byte[]buf, int start, int len) throws IOException {
|
||||||
|
|
||||||
|
int end = start + len;
|
||||||
|
for (int i = start; i < end; i++) {
|
||||||
|
int r = read();
|
||||||
|
if (r == -1) {
|
||||||
|
return i == start ? -1 : i - start;
|
||||||
|
}
|
||||||
|
buf[i] = (byte) r;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int read(byte[] buf) throws IOException {
|
||||||
|
return read(buf, 0, buf.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() throws IOException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public int available() throws IOException
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mark(int readAheadLimit){
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean markSupported() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long skip(long n) throws IOException, IllegalArgumentException { return 0; }
|
||||||
|
|
||||||
|
public void reset() throws IOException {}
|
||||||
|
}
|
53
gwt/jre/java/io/InputStreamReader.java
Normal file
53
gwt/jre/java/io/InputStreamReader.java
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package java.io;
|
||||||
|
|
||||||
|
import core.util.Streams;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* InputStreamReader is class for turning a byte Stream into a character Stream.
|
||||||
|
* Data read from the source input stream is converted into characters by either
|
||||||
|
* a default or provided character converter. By default, the encoding is
|
||||||
|
* assumed to ISO8859_1. The InputStreamReader contains a buffer of bytes read
|
||||||
|
* from the source input stream and converts these into characters as needed.
|
||||||
|
* The buffer size is 8K.
|
||||||
|
*
|
||||||
|
* @see OutputStreamWriter
|
||||||
|
*/
|
||||||
|
public class InputStreamReader extends StringReader {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new InputStreamReader on the InputStream <code>in</code>.
|
||||||
|
* Now character reading can be filtered through this InputStreamReader.
|
||||||
|
* This constructor assumes the default conversion of ISO8859_1
|
||||||
|
* (ISO-Latin-1).
|
||||||
|
*
|
||||||
|
* @param in
|
||||||
|
* the InputStream to convert to characters.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public InputStreamReader(InputStream in) throws IOException {
|
||||||
|
super(Streams.readFullyString(in, "UTF-8"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public InputStreamReader(InputStream in, String enc) throws IOException
|
||||||
|
{
|
||||||
|
super(Streams.readFullyString(in, enc));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
15
gwt/jre/java/io/Msg.java
Normal file
15
gwt/jre/java/io/Msg.java
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package java.io;
|
||||||
|
|
||||||
|
public class Msg {
|
||||||
|
|
||||||
|
public static String getString(String string) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getString(String string, int offset) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
41
gwt/jre/java/io/OutputStream.java
Normal file
41
gwt/jre/java/io/OutputStream.java
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010 Google Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package java.io;
|
||||||
|
|
||||||
|
public abstract class OutputStream {
|
||||||
|
|
||||||
|
// not abstact because of some gwt strangeness
|
||||||
|
public abstract void write(int b) throws IOException;
|
||||||
|
|
||||||
|
public void write(byte[] ba) throws IOException {
|
||||||
|
write(ba, 0, ba.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(byte[] ba, int start, int len) throws IOException {
|
||||||
|
int end = start + len;
|
||||||
|
for (int i = start; i < end; i++) {
|
||||||
|
write(ba[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() throws IOException {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void flush() throws IOException {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
207
gwt/jre/java/io/OutputStreamWriter.java
Normal file
207
gwt/jre/java/io/OutputStreamWriter.java
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package java.io;
|
||||||
|
|
||||||
|
import core.util.Strings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OutputStreamWriter is a class for turning a character output stream into a
|
||||||
|
* byte output stream. The conversion of Unicode characters to their byte
|
||||||
|
* equivalents is determined by the converter used. By default, the encoding is
|
||||||
|
* ISO8859_1 (ISO-Latin-1) but can be changed by calling the constructor which
|
||||||
|
* takes an encoding.
|
||||||
|
*
|
||||||
|
* @see InputStreamReader
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class OutputStreamWriter extends Writer {
|
||||||
|
|
||||||
|
private OutputStream out;
|
||||||
|
String enc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new OutputStreamWriter using <code>out</code> as the
|
||||||
|
* OutputStream to write converted characters to. The default character
|
||||||
|
* encoding is used (see class description).
|
||||||
|
*
|
||||||
|
* @param out
|
||||||
|
* the non-null OutputStream to write converted bytes to.
|
||||||
|
*/
|
||||||
|
public OutputStreamWriter(OutputStream out) {
|
||||||
|
super(out);
|
||||||
|
this.out = out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new OutputStreamWriter using <code>out</code> as the
|
||||||
|
* OutputStream to write converted characters to and <code>enc</code> as
|
||||||
|
* the character encoding. If the encoding cannot be found, an
|
||||||
|
* UnsupportedEncodingException error is thrown.
|
||||||
|
*
|
||||||
|
* @param out
|
||||||
|
* the non-null OutputStream to write converted bytes to.
|
||||||
|
* @param enc
|
||||||
|
* the non-null String describing the desired character encoding.
|
||||||
|
*
|
||||||
|
* @throws UnsupportedEncodingException
|
||||||
|
* if the encoding cannot be found.
|
||||||
|
*/
|
||||||
|
public OutputStreamWriter(OutputStream out, final String enc)
|
||||||
|
throws UnsupportedEncodingException {
|
||||||
|
super(out);
|
||||||
|
if (enc == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
this.out = out;
|
||||||
|
this.enc = enc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close this OutputStreamWriter. This implementation first flushes the
|
||||||
|
* buffer and the target OutputStream. The OutputStream is then closed and
|
||||||
|
* the resources for the buffer and converter are freed.
|
||||||
|
* <p>
|
||||||
|
* Only the first invocation of this method has any effect. Subsequent calls
|
||||||
|
* do no work.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If an error occurs attempting to close this
|
||||||
|
* OutputStreamWriter.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
synchronized (lock) {
|
||||||
|
out.flush();
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flush this OutputStreamWriter. This implementation ensures all buffered
|
||||||
|
* bytes are written to the target OutputStream. After writing the bytes,
|
||||||
|
* the target OutputStream is then flushed.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If an error occurs attempting to flush this
|
||||||
|
* OutputStreamWriter.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void flush() throws IOException {
|
||||||
|
synchronized (lock) {
|
||||||
|
out.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkStatus() throws IOException {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Answer the String which identifies the encoding used to convert
|
||||||
|
* characters to bytes. The value <code>null</code> is returned if this
|
||||||
|
* Writer has been closed.
|
||||||
|
*
|
||||||
|
* @return the String describing the converter or null if this Writer is
|
||||||
|
* closed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public String getEncoding() {
|
||||||
|
return enc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes <code>count</code> characters starting at <code>offset</code>
|
||||||
|
* in <code>buf</code> to this Writer. The characters are immediately
|
||||||
|
* converted to bytes by the character converter and stored in a local
|
||||||
|
* buffer. If the buffer becomes full as a result of this write, this Writer
|
||||||
|
* is flushed.
|
||||||
|
*
|
||||||
|
* @param buf
|
||||||
|
* the non-null array containing characters to write.
|
||||||
|
* @param offset
|
||||||
|
* offset in buf to retrieve characters
|
||||||
|
* @param count
|
||||||
|
* maximum number of characters to write
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If this OutputStreamWriter has already been closed or some
|
||||||
|
* other IOException occurs.
|
||||||
|
* @throws IndexOutOfBoundsException
|
||||||
|
* If offset or count is outside of bounds.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void write(char[] buf, int offset, int count) throws IOException {
|
||||||
|
char[] sb = new char[count];
|
||||||
|
for (int i=0; i<count; ++i)
|
||||||
|
sb[i] = buf[i+offset];
|
||||||
|
|
||||||
|
String s = Strings.toString(buf);
|
||||||
|
|
||||||
|
out.write(s.getBytes(enc));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes out the character <code>oneChar</code> to this Writer. The
|
||||||
|
* low-order 2 bytes are immediately converted to bytes by the character
|
||||||
|
* converter and stored in a local buffer. If the buffer becomes full as a
|
||||||
|
* result of this write, this Writer is flushed.
|
||||||
|
*
|
||||||
|
* @param oneChar
|
||||||
|
* the character to write
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If this OutputStreamWriter has already been closed or some
|
||||||
|
* other IOException occurs.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void write(int oneChar) throws IOException {
|
||||||
|
char[] cs = new char[] { (char)oneChar };
|
||||||
|
write(cs, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes <code>count</code> characters starting at <code>offset</code>
|
||||||
|
* in <code>str</code> to this Writer. The characters are immediately
|
||||||
|
* converted to bytes by the character converter and stored in a local
|
||||||
|
* buffer. If the buffer becomes full as a result of this write, this Writer
|
||||||
|
* is flushed.
|
||||||
|
*
|
||||||
|
* @param str
|
||||||
|
* the non-null String containing characters to write.
|
||||||
|
* @param offset
|
||||||
|
* offset in str to retrieve characters
|
||||||
|
* @param count
|
||||||
|
* maximum number of characters to write
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If this OutputStreamWriter has already been closed or some
|
||||||
|
* other IOException occurs.
|
||||||
|
* @throws IndexOutOfBoundsException
|
||||||
|
* If count is negative
|
||||||
|
* @throws StringIndexOutOfBoundsException
|
||||||
|
* If offset is negative or offset + count is outside of bounds
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void write(String str, int offset, int count) throws IOException {
|
||||||
|
synchronized (lock) {
|
||||||
|
char[] chars = new char[count];
|
||||||
|
str.getChars(0, count, chars, 0);
|
||||||
|
|
||||||
|
write(chars);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
335
gwt/jre/java/io/PushbackInputStream.java
Normal file
335
gwt/jre/java/io/PushbackInputStream.java
Normal file
@ -0,0 +1,335 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package java.io;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PushbackInputStream is a filter class which allows bytes read to be pushed
|
||||||
|
* back into the stream so that they can be reread. Parsers may find this
|
||||||
|
* useful. There is a progammable limit to the number of bytes which may be
|
||||||
|
* pushed back. If the buffer of pushed back bytes is empty, bytes are read from
|
||||||
|
* the source input stream.
|
||||||
|
*/
|
||||||
|
public class PushbackInputStream extends FilterInputStream {
|
||||||
|
/**
|
||||||
|
* The <code>byte</code> array containing the bytes to read.
|
||||||
|
*/
|
||||||
|
protected byte[] buf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current position within the byte array <code>buf</code>. A value
|
||||||
|
* equal to buf.length indicates no bytes available. A value of 0 indicates
|
||||||
|
* the buffer is full.
|
||||||
|
*/
|
||||||
|
protected int pos;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new PushbackInputStream on the InputStream <code>in</code>.
|
||||||
|
* The size of the pushback buffer is set to the default, or 1 byte.
|
||||||
|
*
|
||||||
|
* @param in
|
||||||
|
* the InputStream to allow pushback operations on.
|
||||||
|
*/
|
||||||
|
public PushbackInputStream(InputStream in) {
|
||||||
|
super(in);
|
||||||
|
buf = (in == null) ? null : new byte[1];
|
||||||
|
pos = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new PushbackInputStream on the InputStream <code>in</code>.
|
||||||
|
* The size of the pushback buffer is set to <code>size</code>.
|
||||||
|
*
|
||||||
|
* @param in
|
||||||
|
* the InputStream to allow pushback operations on.
|
||||||
|
* @param size
|
||||||
|
* the size of the pushback buffer (<code>size>=0</code>).
|
||||||
|
*/
|
||||||
|
public PushbackInputStream(InputStream in, int size) {
|
||||||
|
super(in);
|
||||||
|
if (size <= 0) {
|
||||||
|
throw new IllegalArgumentException(Msg.getString("K0058")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
buf = (in == null) ? null : new byte[size];
|
||||||
|
pos = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Answers a int representing then number of bytes that are available before
|
||||||
|
* this PushbackInputStream will block. This method returns the number of
|
||||||
|
* bytes available in the pushback buffer plus those available in the target
|
||||||
|
* stream.
|
||||||
|
*
|
||||||
|
* @return int the number of bytes available before blocking.
|
||||||
|
*
|
||||||
|
* @throws java.io.IOException
|
||||||
|
* If an error occurs in this stream.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int available() throws IOException {
|
||||||
|
if (buf == null) {
|
||||||
|
throw new IOException();
|
||||||
|
}
|
||||||
|
return buf.length - pos + in.available();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close this PushbackInputStream. This implementation closes the target
|
||||||
|
* stream.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If an error occurs attempting to close this stream.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
if (in != null) {
|
||||||
|
in.close();
|
||||||
|
in = null;
|
||||||
|
buf = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Answers a boolean indicating whether or not this PushbackInputStream
|
||||||
|
* supports mark() and reset(). This implementation always answers false
|
||||||
|
* since PushbackInputStreams do not support mark/reset.
|
||||||
|
*
|
||||||
|
* @return boolean indicates whether or not mark() and reset() are
|
||||||
|
* supported.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean markSupported() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a single byte from this PushbackInputStream and returns the result
|
||||||
|
* as an int. The low-order byte is returned or -1 of the end of stream was
|
||||||
|
* encountered. If the pushback buffer does not contain any available bytes
|
||||||
|
* then a byte from the target input stream is returned.
|
||||||
|
*
|
||||||
|
* @return int The byte read or -1 if end of stream.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If an IOException occurs.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int read() throws IOException {
|
||||||
|
if (buf == null) {
|
||||||
|
throw new IOException();
|
||||||
|
}
|
||||||
|
// Is there a pushback byte available?
|
||||||
|
if (pos < buf.length) {
|
||||||
|
return (buf[pos++] & 0xFF);
|
||||||
|
}
|
||||||
|
// Assume read() in the InputStream will return low-order byte or -1
|
||||||
|
// if end of stream.
|
||||||
|
return in.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads at most <code>length</code> bytes from this PushbackInputStream
|
||||||
|
* and stores them in byte array <code>buffer</code> starting at
|
||||||
|
* <code>offset</code>. Answer the number of bytes actually read or -1 if
|
||||||
|
* no bytes were read and end of stream was encountered. This implementation
|
||||||
|
* reads bytes from the pushback buffer first, then the target stream if
|
||||||
|
* more bytes are required to satisfy <code>count</code>.
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* the byte array in which to store the read bytes.
|
||||||
|
* @param offset
|
||||||
|
* the offset in <code>buffer</code> to store the read bytes.
|
||||||
|
* @param length
|
||||||
|
* the maximum number of bytes to store in <code>buffer</code>.
|
||||||
|
* @return the number of bytes actually read or -1 if end of stream.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If an IOException occurs.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int read(byte[] buffer, int offset, int length) throws IOException {
|
||||||
|
if (buf == null) {
|
||||||
|
throw new IOException();
|
||||||
|
}
|
||||||
|
if (buffer == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
// avoid int overflow
|
||||||
|
if (offset < 0 || offset > buffer.length || length < 0
|
||||||
|
|| length > buffer.length - offset) {
|
||||||
|
throw new ArrayIndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
int copiedBytes = 0, copyLength = 0, newOffset = offset;
|
||||||
|
// Are there pushback bytes available?
|
||||||
|
if (pos < buf.length) {
|
||||||
|
copyLength = (buf.length - pos >= length) ? length : buf.length
|
||||||
|
- pos;
|
||||||
|
System.arraycopy(buf, pos, buffer, newOffset, copyLength);
|
||||||
|
newOffset += copyLength;
|
||||||
|
copiedBytes += copyLength;
|
||||||
|
// Use up the bytes in the local buffer
|
||||||
|
pos += copyLength;
|
||||||
|
}
|
||||||
|
// Have we copied enough?
|
||||||
|
if (copyLength == length) {
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
int inCopied = in.read(buffer, newOffset, length - copiedBytes);
|
||||||
|
if (inCopied > 0) {
|
||||||
|
return inCopied + copiedBytes;
|
||||||
|
}
|
||||||
|
if (copiedBytes == 0) {
|
||||||
|
return inCopied;
|
||||||
|
}
|
||||||
|
return copiedBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skips <code>count</code> number of bytes in this PushbackInputStream.
|
||||||
|
* Subsequent <code>read()</code>'s will not return these bytes unless
|
||||||
|
* <code>reset()</code> is used. This implementation skips
|
||||||
|
* <code>count</code> number of bytes in the buffer and/or the target
|
||||||
|
* stream.
|
||||||
|
*
|
||||||
|
* @param count
|
||||||
|
* the number of bytes to skip.
|
||||||
|
* @return the number of bytes actually skipped.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If the stream is already closed or another IOException
|
||||||
|
* occurs.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public long skip(long count) throws IOException {
|
||||||
|
if (in == null) {
|
||||||
|
throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (count <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int numSkipped = 0;
|
||||||
|
if (pos < buf.length) {
|
||||||
|
numSkipped += (count < buf.length - pos) ? count : buf.length - pos;
|
||||||
|
pos += numSkipped;
|
||||||
|
}
|
||||||
|
if (numSkipped < count) {
|
||||||
|
numSkipped += in.skip(count - numSkipped);
|
||||||
|
}
|
||||||
|
return numSkipped;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Push back all the bytes in <code>buffer</code>. The bytes are pushed
|
||||||
|
* so that they would be read back buffer[0], buffer[1], etc. If the push
|
||||||
|
* back buffer cannot handle the entire contents of <code>buffer</code>,
|
||||||
|
* an IOException will be thrown. Some of the buffer may already be in the
|
||||||
|
* buffer after the exception is thrown.
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* the byte array containing bytes to push back into the stream.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If the pushback buffer becomes, or is, full.
|
||||||
|
*/
|
||||||
|
public void unread(byte[] buffer) throws IOException {
|
||||||
|
unread(buffer, 0, buffer.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Push back <code>length</code> number of bytes in <code>buffer</code>
|
||||||
|
* starting at <code>offset</code>. The bytes are pushed so that they
|
||||||
|
* would be read back buffer[offset], buffer[offset+1], etc. If the push
|
||||||
|
* back buffer cannot handle the bytes copied from <code>buffer</code>,
|
||||||
|
* an IOException will be thrown. Some of the bytes may already be in the
|
||||||
|
* buffer after the exception is thrown.
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* the byte array containing bytes to push back into the stream.
|
||||||
|
* @param offset
|
||||||
|
* the location to start taking bytes to push back.
|
||||||
|
* @param length
|
||||||
|
* the number of bytes to push back.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If the pushback buffer becomes, or is, full.
|
||||||
|
*/
|
||||||
|
public void unread(byte[] buffer, int offset, int length)
|
||||||
|
throws IOException {
|
||||||
|
if (length > pos) {
|
||||||
|
// Pushback buffer full
|
||||||
|
throw new IOException(Msg.getString("K007e")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
// avoid int overflow
|
||||||
|
if (offset < 0 || offset > buffer.length || length < 0
|
||||||
|
|| length > buffer.length - offset) {
|
||||||
|
throw new ArrayIndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = offset + length - 1; i >= offset; i--) {
|
||||||
|
unread(buffer[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Push back one <code>byte</code>. Takes the byte <code>oneByte</code>
|
||||||
|
* and puts in in the local buffer of bytes to read back before accessing
|
||||||
|
* the target input stream.
|
||||||
|
*
|
||||||
|
* @param oneByte
|
||||||
|
* the byte to push back into the stream.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If the pushback buffer is already full.
|
||||||
|
*/
|
||||||
|
public void unread(int oneByte) throws IOException {
|
||||||
|
if (buf == null) {
|
||||||
|
throw new IOException();
|
||||||
|
}
|
||||||
|
if (pos == 0) {
|
||||||
|
throw new IOException(Msg.getString("K007e")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
buf[--pos] = (byte) oneByte;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make a mark of the current position in the stream but the mark method
|
||||||
|
* does nothing.
|
||||||
|
*
|
||||||
|
* @param readlimit
|
||||||
|
* the maximum number of bytes that are able to be read before
|
||||||
|
* the mark becomes invalid
|
||||||
|
* @override the method mark in FilterInputStream
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void mark(int readlimit) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset current position to the mark made previously int the stream, but
|
||||||
|
* the reset method will throw IOException and do nothing else if called.
|
||||||
|
*
|
||||||
|
* @override the method reset in FilterInputStream
|
||||||
|
* @throws IOException
|
||||||
|
* If the method is called
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void reset() throws IOException {
|
||||||
|
throw new IOException();
|
||||||
|
}
|
||||||
|
}
|
234
gwt/jre/java/io/Reader.java
Normal file
234
gwt/jre/java/io/Reader.java
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package java.io;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reader is an Abstract class for reading Character Streams. Subclasses of
|
||||||
|
* Reader must implement the methods <code>read(char[], int, int)</code> and
|
||||||
|
* <code>close()</code>.
|
||||||
|
*
|
||||||
|
* @see Writer
|
||||||
|
*/
|
||||||
|
public abstract class Reader {
|
||||||
|
/**
|
||||||
|
* The object used to synchronize access to the reader.
|
||||||
|
*/
|
||||||
|
protected Object lock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new character stream Reader using <code>this</code> as the
|
||||||
|
* Object to synchronize critical regions around.
|
||||||
|
*/
|
||||||
|
protected Reader() {
|
||||||
|
super();
|
||||||
|
lock = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new character stream Reader using <code>lock</code> as the
|
||||||
|
* Object to synchronize critical regions around.
|
||||||
|
*
|
||||||
|
* @param lock
|
||||||
|
* the <code>Object</code> to synchronize critical regions
|
||||||
|
* around.
|
||||||
|
*/
|
||||||
|
protected Reader(Object lock) {
|
||||||
|
if (lock == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
this.lock = lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close this Reader. This must be implemented by any concrete subclasses.
|
||||||
|
* The implementation should free any resources associated with the Reader.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If an error occurs attempting to close this Reader.
|
||||||
|
*/
|
||||||
|
public abstract void close() throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a Mark position in this Reader. The parameter <code>readLimit</code>
|
||||||
|
* indicates how many characters can be read before a mark is invalidated.
|
||||||
|
* Sending reset() will reposition the reader back to the marked position
|
||||||
|
* provided <code>readLimit</code> has not been surpassed.
|
||||||
|
* <p>
|
||||||
|
* This default implementation simply throws IOException and concrete
|
||||||
|
* subclasses must provide their own implementations.
|
||||||
|
*
|
||||||
|
* @param readLimit
|
||||||
|
* an int representing how many characters must be read before
|
||||||
|
* invalidating the mark.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If an error occurs attempting mark this Reader.
|
||||||
|
*/
|
||||||
|
public void mark(int readLimit) throws IOException {
|
||||||
|
throw new IOException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Answers a boolean indicating whether or not this Reader supports mark()
|
||||||
|
* and reset(). This class a default implementation which answers false.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if mark() and reset() are supported,
|
||||||
|
* <code>false</code> otherwise. This implementation returns
|
||||||
|
* <code>false</code>.
|
||||||
|
*/
|
||||||
|
public boolean markSupported() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a single character from this reader and returns the result as an
|
||||||
|
* int. The 2 higher-order characters are set to 0. If the end of reader was
|
||||||
|
* encountered then return -1.
|
||||||
|
*
|
||||||
|
* @return the character read or -1 if end of reader.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If the Reader is already closed or some other IO error
|
||||||
|
* occurs.
|
||||||
|
*/
|
||||||
|
public int read() throws IOException {
|
||||||
|
synchronized (lock) {
|
||||||
|
char charArray[] = new char[1];
|
||||||
|
if (read(charArray, 0, 1) != -1) {
|
||||||
|
return charArray[0];
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads characters from this Reader and stores them in the character array
|
||||||
|
* <code>buf</code> starting at offset 0. Returns the number of characters
|
||||||
|
* actually read or -1 if the end of reader was encountered.
|
||||||
|
*
|
||||||
|
* @param buf
|
||||||
|
* character array to store the read characters
|
||||||
|
* @return how many characters were successfully read in or else -1 if the
|
||||||
|
* end of the reader was detected.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If the Reader is already closed or some other IO error
|
||||||
|
* occurs.
|
||||||
|
*/
|
||||||
|
public int read(char buf[]) throws IOException {
|
||||||
|
return read(buf, 0, buf.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads at most <code>count</code> characters from this Reader and stores
|
||||||
|
* them at <code>offset</code> in the character array <code>buf</code>.
|
||||||
|
* Returns the number of characters actually read or -1 if the end of reader
|
||||||
|
* was encountered.
|
||||||
|
*
|
||||||
|
* @param buf
|
||||||
|
* character array to store the read characters
|
||||||
|
* @param offset
|
||||||
|
* offset in buf to store the read characters
|
||||||
|
* @param count
|
||||||
|
* how many characters should be read in
|
||||||
|
* @return how many characters were successfully read in or else -1 if the
|
||||||
|
* end of the reader was detected.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If the Reader is already closed or some other IO error
|
||||||
|
* occurs.
|
||||||
|
*/
|
||||||
|
public abstract int read(char buf[], int offset, int count)
|
||||||
|
throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Answers a <code>boolean</code> indicating whether or not this Reader is
|
||||||
|
* ready to be read without blocking. If the result is <code>true</code>,
|
||||||
|
* the next <code>read()</code> will not block. If the result is
|
||||||
|
* <code>false</code> this Reader may or may not block when
|
||||||
|
* <code>read()</code> is sent.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if the receiver will not block when
|
||||||
|
* <code>read()</code> is called, <code>false</code> if unknown
|
||||||
|
* or blocking will occur.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If the Reader is already closed or some other IO error
|
||||||
|
* occurs.
|
||||||
|
*/
|
||||||
|
public boolean ready() throws IOException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset this Readers position to the last <code>mark()</code> location.
|
||||||
|
* Invocations of <code>read()/skip()</code> will occur from this new
|
||||||
|
* location. If this Reader was not marked, the implementation of
|
||||||
|
* <code>reset()</code> is implementation specific. See the comment for
|
||||||
|
* the specific Reader subclass for implementation details. The default
|
||||||
|
* action is to throw <code>IOException</code>.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If a problem occured or the receiver does not support
|
||||||
|
* <code>mark()/reset()</code>.
|
||||||
|
*/
|
||||||
|
public void reset() throws IOException {
|
||||||
|
throw new IOException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skips <code>count</code> number of characters in this Reader.
|
||||||
|
* Subsequent <code>read()</code>'s will not return these characters
|
||||||
|
* unless <code>reset()</code> is used. This method may perform multiple
|
||||||
|
* reads to read <code>count</code> characters.
|
||||||
|
*
|
||||||
|
* @param count
|
||||||
|
* how many characters should be passed over
|
||||||
|
* @return how many characters were successfully passed over
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If the Reader is closed when the call is made or if an IO
|
||||||
|
* error occurs during the operation.
|
||||||
|
*/
|
||||||
|
public long skip(long count) throws IOException {
|
||||||
|
if (count < 0) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
synchronized (lock) {
|
||||||
|
long skipped = 0;
|
||||||
|
int toRead = count < 512 ? (int) count : 512;
|
||||||
|
char charsSkipped[] = new char[toRead];
|
||||||
|
while (skipped < count) {
|
||||||
|
int read = read(charsSkipped, 0, toRead);
|
||||||
|
if (read == -1) {
|
||||||
|
return skipped;
|
||||||
|
}
|
||||||
|
skipped += read;
|
||||||
|
if (read < toRead) {
|
||||||
|
return skipped;
|
||||||
|
}
|
||||||
|
if (count - skipped < toRead) {
|
||||||
|
toRead = (int) (count - skipped);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return skipped;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
261
gwt/jre/java/io/StringReader.java
Normal file
261
gwt/jre/java/io/StringReader.java
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package java.io;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A specialized {@link Reader} that reads characters from a {@code String} in
|
||||||
|
* a sequential manner.
|
||||||
|
*
|
||||||
|
* @see StringWriter
|
||||||
|
*/
|
||||||
|
public class StringReader extends Reader {
|
||||||
|
private String str;
|
||||||
|
|
||||||
|
private int markpos = -1;
|
||||||
|
|
||||||
|
private int pos;
|
||||||
|
|
||||||
|
private int count;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new {@code StringReader} with {@code str} as source. The size
|
||||||
|
* of the reader is set to the {@code length()} of the string and the Object
|
||||||
|
* to synchronize access through is set to {@code str}.
|
||||||
|
*
|
||||||
|
* @param str
|
||||||
|
* the source string for this reader.
|
||||||
|
*/
|
||||||
|
public StringReader(String str) {
|
||||||
|
super();
|
||||||
|
this.str = str;
|
||||||
|
this.count = str.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes this reader. Once it is closed, read operations on this reader
|
||||||
|
* will throw an {@code IOException}. Only the first invocation of this
|
||||||
|
* method has any effect.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
str = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a boolean indicating whether this reader is closed.
|
||||||
|
*
|
||||||
|
* @return {@code true} if closed, otherwise {@code false}.
|
||||||
|
*/
|
||||||
|
private boolean isClosed() {
|
||||||
|
return str == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a mark position in this reader. The parameter {@code readLimit} is
|
||||||
|
* ignored for this class. Calling {@code reset()} will reposition the
|
||||||
|
* reader back to the marked position.
|
||||||
|
*
|
||||||
|
* @param readLimit
|
||||||
|
* ignored for {@code StringReader} instances.
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
* if {@code readLimit < 0}.
|
||||||
|
* @throws IOException
|
||||||
|
* if this reader is closed.
|
||||||
|
* @see #markSupported()
|
||||||
|
* @see #reset()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void mark(int readLimit) throws IOException {
|
||||||
|
if (readLimit < 0) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (lock) {
|
||||||
|
if (isClosed()) {
|
||||||
|
throw new IOException(Msg.getString("K0083")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
markpos = pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether this reader supports the {@code mark()} and {@code
|
||||||
|
* reset()} methods. This implementation returns {@code true}.
|
||||||
|
*
|
||||||
|
* @return always {@code true}.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean markSupported() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a single character from the source string and returns it as an
|
||||||
|
* integer with the two higher-order bytes set to 0. Returns -1 if the end
|
||||||
|
* of the source string has been reached.
|
||||||
|
*
|
||||||
|
* @return the character read or -1 if the end of the source string has been
|
||||||
|
* reached.
|
||||||
|
* @throws IOException
|
||||||
|
* if this reader is closed.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int read() throws IOException {
|
||||||
|
synchronized (lock) {
|
||||||
|
if (isClosed()) {
|
||||||
|
throw new IOException(Msg.getString("K0083")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (pos != count) {
|
||||||
|
return str.charAt(pos++);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads at most {@code len} characters from the source string and stores
|
||||||
|
* them at {@code offset} in the character array {@code buf}. Returns the
|
||||||
|
* number of characters actually read or -1 if the end of the source string
|
||||||
|
* has been reached.
|
||||||
|
*
|
||||||
|
* @param buf
|
||||||
|
* the character array to store the characters read.
|
||||||
|
* @param offset
|
||||||
|
* the initial position in {@code buffer} to store the characters
|
||||||
|
* read from this reader.
|
||||||
|
* @param len
|
||||||
|
* the maximum number of characters to read.
|
||||||
|
* @return the number of characters read or -1 if the end of the reader has
|
||||||
|
* been reached.
|
||||||
|
* @throws IndexOutOfBoundsException
|
||||||
|
* if {@code offset < 0} or {@code len < 0}, or if
|
||||||
|
* {@code offset + len} is greater than the size of {@code buf}.
|
||||||
|
* @throws IOException
|
||||||
|
* if this reader is closed.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int read(char buf[], int offset, int len) throws IOException {
|
||||||
|
synchronized (lock) {
|
||||||
|
if (isClosed()) {
|
||||||
|
// K0083=StringReader is closed.
|
||||||
|
throw new IOException(Msg.getString("K0083")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (offset < 0 || offset > buf.length) {
|
||||||
|
// K002e=Offset out of bounds \: {0}
|
||||||
|
throw new ArrayIndexOutOfBoundsException(Msg.getString("K002e", offset)); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (len < 0 || len > buf.length - offset) {
|
||||||
|
// K0031=Length out of bounds \: {0}
|
||||||
|
throw new ArrayIndexOutOfBoundsException(Msg.getString("K0031", len)); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (len == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (pos == this.count) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int end = pos + len > this.count ? this.count : pos + len;
|
||||||
|
str.getChars(pos, end, buf, offset);
|
||||||
|
int read = end - pos;
|
||||||
|
pos = end;
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether this reader is ready to be read without blocking. This
|
||||||
|
* implementation always returns {@code true}.
|
||||||
|
*
|
||||||
|
* @return always {@code true}.
|
||||||
|
* @throws IOException
|
||||||
|
* if this reader is closed.
|
||||||
|
* @see #read()
|
||||||
|
* @see #read(char[], int, int)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean ready() throws IOException {
|
||||||
|
synchronized (lock) {
|
||||||
|
if (isClosed()) {
|
||||||
|
throw new IOException(Msg.getString("K0083")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets this reader's position to the last {@code mark()} location.
|
||||||
|
* Invocations of {@code read()} and {@code skip()} will occur from this new
|
||||||
|
* location. If this reader has not been marked, it is reset to the
|
||||||
|
* beginning of the source string.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* if this reader is closed.
|
||||||
|
* @see #mark(int)
|
||||||
|
* @see #markSupported()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void reset() throws IOException {
|
||||||
|
synchronized (lock) {
|
||||||
|
if (isClosed()) {
|
||||||
|
throw new IOException(Msg.getString("K0083")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
pos = markpos != -1 ? markpos : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves {@code ns} characters in the source string. Unlike the {@link
|
||||||
|
* Reader#skip(long) overridden method}, this method may skip negative skip
|
||||||
|
* distances: this rewinds the input so that characters may be read again.
|
||||||
|
* When the end of the source string has been reached, the input cannot be
|
||||||
|
* rewound.
|
||||||
|
*
|
||||||
|
* @param ns
|
||||||
|
* the maximum number of characters to skip. Positive values skip
|
||||||
|
* forward; negative values skip backward.
|
||||||
|
* @return the number of characters actually skipped. This is bounded below
|
||||||
|
* by the number of characters already read and above by the
|
||||||
|
* number of characters remaining:<br> {@code -(num chars already
|
||||||
|
* read) <= distance skipped <= num chars remaining}.
|
||||||
|
* @throws IOException
|
||||||
|
* if this reader is closed.
|
||||||
|
* @see #mark(int)
|
||||||
|
* @see #markSupported()
|
||||||
|
* @see #reset()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public long skip(long ns) throws IOException {
|
||||||
|
synchronized (lock) {
|
||||||
|
if (isClosed()) {
|
||||||
|
throw new IOException(Msg.getString("K0083")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
int minSkip = -pos;
|
||||||
|
int maxSkip = count - pos;
|
||||||
|
|
||||||
|
if (maxSkip == 0 || ns > maxSkip) {
|
||||||
|
ns = maxSkip; // no rewinding if we're at the end
|
||||||
|
} else if (ns < minSkip) {
|
||||||
|
ns = minSkip;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += ns;
|
||||||
|
return ns;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
250
gwt/jre/java/io/StringWriter.java
Normal file
250
gwt/jre/java/io/StringWriter.java
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package java.io;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StringWriter is an class for writing Character Streams to a StringBuffer. The
|
||||||
|
* characters written can then be returned as a String. This is used for
|
||||||
|
* capturing output sent to a Writer by substituting a StringWriter.
|
||||||
|
*
|
||||||
|
* @see StringReader
|
||||||
|
*/
|
||||||
|
public class StringWriter extends Writer {
|
||||||
|
|
||||||
|
private StringBuffer buf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new StringWriter which has a StringBuffer allocated with the
|
||||||
|
* default size of 16 characters. The StringBuffer is also the
|
||||||
|
* <code>lock</code> used to synchronize access to this Writer.
|
||||||
|
*/
|
||||||
|
public StringWriter() {
|
||||||
|
super();
|
||||||
|
buf = new StringBuffer(16);
|
||||||
|
lock = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new StringWriter which has a StringBuffer allocated with the
|
||||||
|
* size of <code>initialSize</code> characters. The StringBuffer is also
|
||||||
|
* the <code>lock</code> used to synchronize access to this Writer.
|
||||||
|
*
|
||||||
|
* @param initialSize
|
||||||
|
* the intial number of characters
|
||||||
|
*/
|
||||||
|
public StringWriter(int initialSize) {
|
||||||
|
if (initialSize < 0) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
buf = new StringBuffer(initialSize);
|
||||||
|
lock = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close this Writer. This is the concrete implementation required. This
|
||||||
|
* particular implementation does nothing.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If an IO error occurs closing this StringWriter.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
/* empty */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flush this Writer. This is the concrete implementation required. This
|
||||||
|
* particular implementation does nothing.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void flush() {
|
||||||
|
/* empty */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Answer the contents of this StringWriter as a StringBuffer. Any changes
|
||||||
|
* made to the StringBuffer by the receiver or the caller are reflected in
|
||||||
|
* this StringWriter.
|
||||||
|
*
|
||||||
|
* @return this StringWriters local StringBuffer.
|
||||||
|
*/
|
||||||
|
public StringBuffer getBuffer() {
|
||||||
|
synchronized (lock) {
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Answer the contents of this StringWriter as a String. Any changes made to
|
||||||
|
* the StringBuffer by the receiver after returning will not be reflected in
|
||||||
|
* the String returned to the caller.
|
||||||
|
*
|
||||||
|
* @return this StringWriters current contents as a String.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
synchronized (lock) {
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes <code>count</code> characters starting at <code>offset</code>
|
||||||
|
* in <code>cbuf</code> to this StringWriter.
|
||||||
|
*
|
||||||
|
* @param cbuf
|
||||||
|
* the non-null array containing characters to write.
|
||||||
|
* @param offset
|
||||||
|
* offset in buf to retrieve characters
|
||||||
|
* @param count
|
||||||
|
* maximum number of characters to write
|
||||||
|
*
|
||||||
|
* @throws ArrayIndexOutOfBoundsException
|
||||||
|
* If offset or count are outside of bounds.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void write(char[] cbuf, int offset, int count) {
|
||||||
|
// avoid int overflow
|
||||||
|
if (offset < 0 || offset > cbuf.length || count < 0
|
||||||
|
|| count > cbuf.length - offset) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
synchronized (lock) {
|
||||||
|
this.buf.append(cbuf, offset, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the specified character <code>oneChar</code> to this
|
||||||
|
* StringWriter. This implementation writes the low order two bytes to the
|
||||||
|
* Stream.
|
||||||
|
*
|
||||||
|
* @param oneChar
|
||||||
|
* The character to write
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void write(int oneChar) {
|
||||||
|
synchronized (lock) {
|
||||||
|
buf.append((char) oneChar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the characters from the String <code>str</code> to this
|
||||||
|
* StringWriter.
|
||||||
|
*
|
||||||
|
* @param str
|
||||||
|
* the non-null String containing the characters to write.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void write(String str) {
|
||||||
|
synchronized (lock) {
|
||||||
|
buf.append(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes <code>count</code> number of characters starting at
|
||||||
|
* <code>offset</code> from the String <code>str</code> to this
|
||||||
|
* StringWriter.
|
||||||
|
*
|
||||||
|
* @param str
|
||||||
|
* the non-null String containing the characters to write.
|
||||||
|
* @param offset
|
||||||
|
* the starting point to retrieve characters.
|
||||||
|
* @param count
|
||||||
|
* the number of characters to retrieve and write.
|
||||||
|
*
|
||||||
|
* @throws ArrayIndexOutOfBoundsException
|
||||||
|
* If offset or count are outside of bounds.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void write(String str, int offset, int count) {
|
||||||
|
String sub = str.substring(offset, offset + count);
|
||||||
|
synchronized (lock) {
|
||||||
|
buf.append(sub);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append a char <code>c</code>to the StringWriter. The
|
||||||
|
* StringWriter.append(<code>c</code>) works the same way as
|
||||||
|
* StringWriter.write(<code>c</code>).
|
||||||
|
*
|
||||||
|
* @param c
|
||||||
|
* The character appended to the StringWriter.
|
||||||
|
* @return The StringWriter.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public StringWriter append(char c) {
|
||||||
|
write(c);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append a CharSequence <code>csq</code> to the StringWriter. The
|
||||||
|
* StringWriter.append(<code>csq</code>) works the same way as
|
||||||
|
* StringWriter.write(<code>csq</code>.toString()). If <code>csq</code>
|
||||||
|
* is null, then "null" will be substituted for <code>csq</code>.
|
||||||
|
*
|
||||||
|
* @param csq
|
||||||
|
* The CharSequence appended to the StringWriter.
|
||||||
|
* @return The StringWriter
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public StringWriter append(CharSequence csq) {
|
||||||
|
if (null == csq) {
|
||||||
|
append(TOKEN_NULL, 0, TOKEN_NULL.length());
|
||||||
|
} else {
|
||||||
|
append(csq, 0, csq.length());
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append a subsequence of a CharSequence <code>csq</code> to the
|
||||||
|
* StringWriter. The first char and the last char of the subsequnce is
|
||||||
|
* specified by the parameter <code>start</code> and <code>end</code>.
|
||||||
|
* The StringWriter.append(<code>csq</code>) works the same way as
|
||||||
|
* StringWriter.write(<code>csq</code>.subSequence(<code>start</code>,<code>end</code>).toString).If
|
||||||
|
* <code>csq</code> is null, then "null" will be substituted for
|
||||||
|
* <code>csq</code>. s
|
||||||
|
*
|
||||||
|
* @param csq
|
||||||
|
* The CharSequence appended to the StringWriter.
|
||||||
|
* @param start
|
||||||
|
* The index of the first char in the CharSequence appended to
|
||||||
|
* the StringWriter.
|
||||||
|
* @param end
|
||||||
|
* The index of the char after the last one in the CharSequence
|
||||||
|
* appended to the StringWriter.
|
||||||
|
* @return The StringWriter.
|
||||||
|
* @throws IndexOutOfBoundsException
|
||||||
|
* If start is less than end, end is greater than the length of
|
||||||
|
* the CharSequence, or start or end is negative.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public StringWriter append(CharSequence csq, int start, int end) {
|
||||||
|
if (null == csq) {
|
||||||
|
csq = TOKEN_NULL;
|
||||||
|
}
|
||||||
|
String output = csq.subSequence(start, end).toString();
|
||||||
|
write(output, 0, output.length());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
241
gwt/jre/java/io/Writer.java
Normal file
241
gwt/jre/java/io/Writer.java
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package java.io;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writer is an Abstract class for writing Character Streams. Subclasses of
|
||||||
|
* writer must implement the methods <code>write(char[], int, int)</code>,
|
||||||
|
* <code>close()</code> and <code>flush()</code>.
|
||||||
|
*
|
||||||
|
* @see Reader
|
||||||
|
*/
|
||||||
|
public abstract class Writer {
|
||||||
|
|
||||||
|
static final String TOKEN_NULL = "null"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The object used to synchronize access to the writer.
|
||||||
|
*/
|
||||||
|
protected Object lock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new character stream Writer using <code>this</code> as the
|
||||||
|
* Object to synchronize critical regions around.
|
||||||
|
*/
|
||||||
|
protected Writer() {
|
||||||
|
super();
|
||||||
|
lock = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new character stream Writer using <code>lock</code> as the
|
||||||
|
* Object to synchronize critical regions around.
|
||||||
|
*
|
||||||
|
* @param lock
|
||||||
|
* the Object to synchronize critical regions around.
|
||||||
|
*/
|
||||||
|
protected Writer(Object lock) {
|
||||||
|
if (lock == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
this.lock = lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close this Writer. This must be implemented by any concrete subclasses.
|
||||||
|
* The implementation should free any resources associated with the Writer.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If an error occurs attempting to close this Writer.
|
||||||
|
*/
|
||||||
|
public abstract void close() throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flush this Writer. This must be implemented by any concrete subclasses.
|
||||||
|
* The implementation should ensure all buffered characters are written out.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If an error occurs attempting to flush this Writer.
|
||||||
|
*/
|
||||||
|
public abstract void flush() throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the entire character buffer <code>buf</code> to this Writer.
|
||||||
|
*
|
||||||
|
* @param buf
|
||||||
|
* the non-null array containing characters to write.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If this Writer has already been closed or some other
|
||||||
|
* IOException occurs.
|
||||||
|
*/
|
||||||
|
public void write(char buf[]) throws IOException {
|
||||||
|
write(buf, 0, buf.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes <code>count</code> characters starting at <code>offset<code> in
|
||||||
|
* <code>buf</code> to this Writer. This abstract method must be implemented
|
||||||
|
* by concrete subclasses.
|
||||||
|
*
|
||||||
|
* @param buf the non-null array containing characters to write.
|
||||||
|
* @param offset offset in buf to retrieve characters
|
||||||
|
* @param count maximum number of characters to write
|
||||||
|
*
|
||||||
|
* @throws IOException If this Writer has already been closed or some other IOException occurs.
|
||||||
|
* @throws ArrayIndexOutOfBoundsException If offset or count are outside of bounds.
|
||||||
|
*/
|
||||||
|
public abstract void write(char buf[], int offset, int count)
|
||||||
|
throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the specified character <code>oneChar</code> to this Writer.
|
||||||
|
* This implementation writes the low order two bytes of
|
||||||
|
* <code>oneChar</code> to the Stream.
|
||||||
|
*
|
||||||
|
* @param oneChar
|
||||||
|
* The character to write
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If this Writer has already been closed or some other
|
||||||
|
* IOException occurs.
|
||||||
|
*/
|
||||||
|
public void write(int oneChar) throws IOException {
|
||||||
|
synchronized (lock) {
|
||||||
|
char oneCharArray[] = new char[1];
|
||||||
|
oneCharArray[0] = (char) oneChar;
|
||||||
|
write(oneCharArray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the characters from the String <code>str</code> to this Writer.
|
||||||
|
*
|
||||||
|
* @param str
|
||||||
|
* the non-null String containing the characters to write.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If this Writer has already been closed or some other
|
||||||
|
* IOException occurs.
|
||||||
|
*/
|
||||||
|
public void write(String str) throws IOException {
|
||||||
|
char buf[] = new char[str.length()];
|
||||||
|
str.getChars(0, buf.length, buf, 0);
|
||||||
|
synchronized (lock) {
|
||||||
|
write(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes <code>count</code> number of characters starting at
|
||||||
|
* <code>offset</code> from the String <code>str</code> to this Writer.
|
||||||
|
*
|
||||||
|
* @param str
|
||||||
|
* the non-null String containing the characters to write.
|
||||||
|
* @param offset
|
||||||
|
* the starting point to retrieve characters.
|
||||||
|
* @param count
|
||||||
|
* the number of characters to retrieve and write.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* If this Writer has already been closed or some other
|
||||||
|
* IOException occurs.
|
||||||
|
* @throws ArrayIndexOutOfBoundsException
|
||||||
|
* If offset or count are outside of bounds.
|
||||||
|
*/
|
||||||
|
public void write(String str, int offset, int count) throws IOException {
|
||||||
|
if (count < 0) { // other cases tested by getChars()
|
||||||
|
throw new StringIndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
char buf[] = new char[count];
|
||||||
|
str.getChars(offset, offset + count, buf, 0);
|
||||||
|
|
||||||
|
synchronized (lock) {
|
||||||
|
write(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append a char <code>c</code>to the Writer. The Writer.append(<code>c</code>)
|
||||||
|
* works the same as Writer.write(<code>c</code>).
|
||||||
|
*
|
||||||
|
* @param c
|
||||||
|
* The character appended to the Writer.
|
||||||
|
* @return The Writer.
|
||||||
|
* @throws IOException
|
||||||
|
* If any IOException raises during the procedure.
|
||||||
|
*/
|
||||||
|
public Writer append(char c) throws IOException {
|
||||||
|
write(c);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append a CharSequence <code>csq</code> to the Writer. The
|
||||||
|
* Writer.append(<code>csq</code>) works the same way as Writer.write(<code>csq</code>.toString()).
|
||||||
|
* If <code>csq</code> is null, then "null" will be substituted for
|
||||||
|
* <code>csq</code>.
|
||||||
|
*
|
||||||
|
* @param csq
|
||||||
|
* The CharSequence appended to the Writer.
|
||||||
|
* @return The Writer.
|
||||||
|
* @throws IOException
|
||||||
|
* If any IOException raises during the procedure.
|
||||||
|
*/
|
||||||
|
public Writer append(CharSequence csq) throws IOException {
|
||||||
|
if (null == csq) {
|
||||||
|
write(TOKEN_NULL);
|
||||||
|
} else {
|
||||||
|
write(csq.toString());
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append a subsequence of a CharSequence <code>csq</code> to the Writer.
|
||||||
|
* The first char and the last char of the subsequnce is specified by the
|
||||||
|
* parameter <code>start</code> and <code>end</code>. The
|
||||||
|
* Writer.append(<code>csq</code>) works the same way as Writer.write (<code>csq</code>csq.subSequence(<code>start</code>,<code>end</code>).toString).
|
||||||
|
* If <code>csq</code> is null, then "null" will be substituted for
|
||||||
|
* <code>csq</code>.
|
||||||
|
*
|
||||||
|
* @param csq
|
||||||
|
* The CharSequence appended to the Writaer.
|
||||||
|
* @param start
|
||||||
|
* The index of the first char in the CharSequence appended to
|
||||||
|
* the Writer.
|
||||||
|
* @param end
|
||||||
|
* The index of the char after the last one in the CharSequence
|
||||||
|
* appended to the Writer.
|
||||||
|
* @return The Writer.
|
||||||
|
* @throws IndexOutOfBoundsException
|
||||||
|
* If start is less than end, end is greater than the length of
|
||||||
|
* the CharSequence, or start or end is negative.
|
||||||
|
* @throws IOException
|
||||||
|
* If any IOException raises during the procedure.
|
||||||
|
*/
|
||||||
|
public Writer append(CharSequence csq, int start, int end)
|
||||||
|
throws IOException {
|
||||||
|
if (null == csq) {
|
||||||
|
write(TOKEN_NULL.substring(start, end));
|
||||||
|
} else {
|
||||||
|
write(csq.subSequence(start, end).toString());
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
18
gwt/jre/java/lang/ClassNotFoundException.java
Normal file
18
gwt/jre/java/lang/ClassNotFoundException.java
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package java.lang;
|
||||||
|
|
||||||
|
public class ClassNotFoundException extends Exception {
|
||||||
|
|
||||||
|
public ClassNotFoundException()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClassNotFoundException(String s)
|
||||||
|
{
|
||||||
|
super(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClassNotFoundException(String s, Throwable ex)
|
||||||
|
{
|
||||||
|
super(s,ex);
|
||||||
|
}
|
||||||
|
}
|
48
gwt/jre/java/lang/CloneNotSupportedException.java
Normal file
48
gwt/jre/java/lang/CloneNotSupportedException.java
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package java.lang;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This exception is thrown when a program attempts to clone an object which
|
||||||
|
* does not support the Cloneable interface.
|
||||||
|
*
|
||||||
|
* @see Cloneable
|
||||||
|
*/
|
||||||
|
public class CloneNotSupportedException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 5195511250079656443L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new instance of this class with its walkback filled in.
|
||||||
|
*/
|
||||||
|
public CloneNotSupportedException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new instance of this class with its walkback and message
|
||||||
|
* filled in.
|
||||||
|
*
|
||||||
|
* @param detailMessage
|
||||||
|
* String The detail message for the exception.
|
||||||
|
*/
|
||||||
|
public CloneNotSupportedException(String detailMessage) {
|
||||||
|
super(detailMessage);
|
||||||
|
}
|
||||||
|
}
|
46
gwt/jre/java/lang/InternalError.java
Normal file
46
gwt/jre/java/lang/InternalError.java
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package java.lang;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This error is thrown when the VM notices that it has gotten into a state
|
||||||
|
* which it does not understand.
|
||||||
|
*/
|
||||||
|
public class InternalError extends RuntimeException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -9062593416125562365L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new instance of this class with its walkback filled in.
|
||||||
|
*/
|
||||||
|
public InternalError() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new instance of this class with its walkback and message
|
||||||
|
* filled in.
|
||||||
|
*
|
||||||
|
* @param detailMessage
|
||||||
|
* String The detail message for the exception.
|
||||||
|
*/
|
||||||
|
public InternalError(String detailMessage) {
|
||||||
|
super(detailMessage);
|
||||||
|
}
|
||||||
|
}
|
2845
gwt/jre/java/math/BigDecimal.java
Normal file
2845
gwt/jre/java/math/BigDecimal.java
Normal file
File diff suppressed because it is too large
Load Diff
1553
gwt/jre/java/math/BigInteger.java
Normal file
1553
gwt/jre/java/math/BigInteger.java
Normal file
File diff suppressed because it is too large
Load Diff
379
gwt/jre/java/math/BitLevel.java
Normal file
379
gwt/jre/java/math/BitLevel.java
Normal file
@ -0,0 +1,379 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Google Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with this
|
||||||
|
* work for additional information regarding copyright ownership. The ASF
|
||||||
|
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*
|
||||||
|
* INCLUDES MODIFICATIONS BY RICHARD ZSCHECH AS WELL AS GOOGLE.
|
||||||
|
*/
|
||||||
|
package java.math;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static library that provides all the <b>bit level</b> operations for
|
||||||
|
* {@link BigInteger}. The operations are: <ul type="circle"> <li>Left Shifting</li>
|
||||||
|
* <li>Right Shifting</li> <li>Bit clearing</li> <li>Bit setting</li> <li>Bit
|
||||||
|
* counting</li> <li>Bit testing</li> <li>Getting of the lowest bit set</li>
|
||||||
|
* </ul> All operations are provided in immutable way, and some in both mutable
|
||||||
|
* and immutable.
|
||||||
|
*/
|
||||||
|
class BitLevel {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see BigInteger#bitCount()
|
||||||
|
* @param val
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static int bitCount(BigInteger val) {
|
||||||
|
int bCount = 0;
|
||||||
|
|
||||||
|
if (val.sign == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = val.getFirstNonzeroDigit();
|
||||||
|
if (val.sign > 0) {
|
||||||
|
for (; i < val.numberLength; i++) {
|
||||||
|
bCount += Integer.bitCount(val.digits[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// (sign < 0)
|
||||||
|
// this digit absorbs the carry
|
||||||
|
bCount += Integer.bitCount(-val.digits[i]);
|
||||||
|
for (i++; i < val.numberLength; i++) {
|
||||||
|
bCount += Integer.bitCount(~val.digits[i]);
|
||||||
|
}
|
||||||
|
// We take the complement sum:
|
||||||
|
bCount = (val.numberLength << 5) - bCount;
|
||||||
|
}
|
||||||
|
return bCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see BigInteger#bitLength()
|
||||||
|
* @param val
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static int bitLength(BigInteger val) {
|
||||||
|
if (val.sign == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int bLength = (val.numberLength << 5);
|
||||||
|
int highDigit = val.digits[val.numberLength - 1];
|
||||||
|
|
||||||
|
if (val.sign < 0) {
|
||||||
|
int i = val.getFirstNonzeroDigit();
|
||||||
|
// We reduce the problem to the positive case.
|
||||||
|
if (i == val.numberLength - 1) {
|
||||||
|
// ~~ is to handle int overflow
|
||||||
|
highDigit = ~~(highDigit - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Subtracting all sign bits
|
||||||
|
bLength -= Integer.numberOfLeadingZeros(highDigit);
|
||||||
|
return bLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs a flipBit on the BigInteger, returning a BigInteger with the the
|
||||||
|
* specified bit flipped.
|
||||||
|
*
|
||||||
|
* @param val BigInteger to operate on
|
||||||
|
* @param n the bit to flip
|
||||||
|
*/
|
||||||
|
static BigInteger flipBit(BigInteger val, int n) {
|
||||||
|
int resSign = (val.sign == 0) ? 1 : val.sign;
|
||||||
|
int intCount = n >> 5;
|
||||||
|
int bitN = n & 31;
|
||||||
|
int resLength = Math.max(intCount + 1, val.numberLength) + 1;
|
||||||
|
int resDigits[] = new int[resLength];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
int bitNumber = 1 << bitN;
|
||||||
|
System.arraycopy(val.digits, 0, resDigits, 0, val.numberLength);
|
||||||
|
|
||||||
|
if (val.sign < 0) {
|
||||||
|
if (intCount >= val.numberLength) {
|
||||||
|
resDigits[intCount] = bitNumber;
|
||||||
|
} else {
|
||||||
|
// val.sign<0 y intCount < val.numberLength
|
||||||
|
int firstNonZeroDigit = val.getFirstNonzeroDigit();
|
||||||
|
if (intCount > firstNonZeroDigit) {
|
||||||
|
resDigits[intCount] ^= bitNumber;
|
||||||
|
} else if (intCount < firstNonZeroDigit) {
|
||||||
|
resDigits[intCount] = -bitNumber;
|
||||||
|
for (i = intCount + 1; i < firstNonZeroDigit; i++) {
|
||||||
|
resDigits[i] = -1;
|
||||||
|
}
|
||||||
|
resDigits[i] = resDigits[i]--;
|
||||||
|
} else {
|
||||||
|
i = intCount;
|
||||||
|
resDigits[i] = -((-resDigits[intCount]) ^ bitNumber);
|
||||||
|
if (resDigits[i] == 0) {
|
||||||
|
for (i++; resDigits[i] == -1; i++) {
|
||||||
|
resDigits[i] = 0;
|
||||||
|
}
|
||||||
|
resDigits[i]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// case where val is positive
|
||||||
|
resDigits[intCount] ^= bitNumber;
|
||||||
|
}
|
||||||
|
BigInteger result = new BigInteger(resSign, resLength, resDigits);
|
||||||
|
result.cutOffLeadingZeroes();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs {@code val <<= count}.
|
||||||
|
*/
|
||||||
|
// val should have enough place (and one digit more)
|
||||||
|
static void inplaceShiftLeft(BigInteger val, int count) {
|
||||||
|
int intCount = count >> 5; // count of integers
|
||||||
|
val.numberLength += intCount
|
||||||
|
+ (Integer.numberOfLeadingZeros(val.digits[val.numberLength - 1])
|
||||||
|
- (count & 31) >= 0 ? 0 : 1);
|
||||||
|
shiftLeft(val.digits, val.digits, intCount, count & 31);
|
||||||
|
val.cutOffLeadingZeroes();
|
||||||
|
val.unCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs {@code val >>= count} where {@code val} is a positive number.
|
||||||
|
*/
|
||||||
|
static void inplaceShiftRight(BigInteger val, int count) {
|
||||||
|
int sign = val.signum();
|
||||||
|
if (count == 0 || val.signum() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int intCount = count >> 5; // count of integers
|
||||||
|
val.numberLength -= intCount;
|
||||||
|
if (!shiftRight(val.digits, val.numberLength, val.digits, intCount,
|
||||||
|
count & 31)
|
||||||
|
&& sign < 0) {
|
||||||
|
// remainder not zero: add one to the result
|
||||||
|
int i;
|
||||||
|
for (i = 0; (i < val.numberLength) && (val.digits[i] == -1); i++) {
|
||||||
|
val.digits[i] = 0;
|
||||||
|
}
|
||||||
|
if (i == val.numberLength) {
|
||||||
|
val.numberLength++;
|
||||||
|
}
|
||||||
|
val.digits[i]++;
|
||||||
|
}
|
||||||
|
val.cutOffLeadingZeroes();
|
||||||
|
val.unCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if there are 1s in the lowest bits of this BigInteger.
|
||||||
|
*
|
||||||
|
* @param numberOfBits the number of the lowest bits to check
|
||||||
|
* @return false if all bits are 0s, true otherwise
|
||||||
|
*/
|
||||||
|
static boolean nonZeroDroppedBits(int numberOfBits, int digits[]) {
|
||||||
|
int intCount = numberOfBits >> 5;
|
||||||
|
int bitCount = numberOfBits & 31;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; (i < intCount) && (digits[i] == 0); i++) {
|
||||||
|
}
|
||||||
|
return ((i != intCount) || (digits[i] << (32 - bitCount) != 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see BigInteger#shiftLeft(int)
|
||||||
|
* @param source
|
||||||
|
* @param count
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static BigInteger shiftLeft(BigInteger source, int count) {
|
||||||
|
int intCount = count >> 5;
|
||||||
|
count &= 31; // %= 32
|
||||||
|
int resLength = source.numberLength + intCount + ((count == 0) ? 0 : 1);
|
||||||
|
int resDigits[] = new int[resLength];
|
||||||
|
|
||||||
|
shiftLeft(resDigits, source.digits, intCount, count);
|
||||||
|
BigInteger result = new BigInteger(source.sign, resLength, resDigits);
|
||||||
|
result.cutOffLeadingZeroes();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstractly shifts left an array of integers in little endian (i.e.,
|
||||||
|
* shift it right). Total shift distance in bits is intCount * 32 + count
|
||||||
|
*
|
||||||
|
* @param result the destination array
|
||||||
|
* @param source the source array
|
||||||
|
* @param intCount the shift distance in integers
|
||||||
|
* @param count an additional shift distance in bits
|
||||||
|
*/
|
||||||
|
static void shiftLeft(int result[], int source[], int intCount, int count) {
|
||||||
|
if (count == 0) {
|
||||||
|
System.arraycopy(source, 0, result, intCount, result.length - intCount);
|
||||||
|
} else {
|
||||||
|
int rightShiftCount = 32 - count;
|
||||||
|
|
||||||
|
result[result.length - 1] = 0;
|
||||||
|
for (int i = result.length - 1; i > intCount; i--) {
|
||||||
|
result[i] |= source[i - intCount - 1] >>> rightShiftCount;
|
||||||
|
result[i - 1] = source[i - intCount - 1] << count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < intCount; i++) {
|
||||||
|
result[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static BigInteger shiftLeftOneBit(BigInteger source) {
|
||||||
|
int srcLen = source.numberLength;
|
||||||
|
int resLen = srcLen + 1;
|
||||||
|
int resDigits[] = new int[resLen];
|
||||||
|
shiftLeftOneBit(resDigits, source.digits, srcLen);
|
||||||
|
BigInteger result = new BigInteger(source.sign, resLen, resDigits);
|
||||||
|
result.cutOffLeadingZeroes();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shifts the source digits left one bit, creating a value whose magnitude is
|
||||||
|
* doubled.
|
||||||
|
*
|
||||||
|
* @param result an array of digits that will hold the computed result when
|
||||||
|
* this method returns. The size of this array is {@code srcLen + 1},
|
||||||
|
* and the format is the same as {@link BigInteger#digits}.
|
||||||
|
* @param source the array of digits to shift left, in the same format as
|
||||||
|
* {@link BigInteger#digits}.
|
||||||
|
* @param srcLen the length of {@code source}; may be less than {@code
|
||||||
|
* source.length}
|
||||||
|
*/
|
||||||
|
static void shiftLeftOneBit(int result[], int source[], int srcLen) {
|
||||||
|
int carry = 0;
|
||||||
|
for (int i = 0; i < srcLen; i++) {
|
||||||
|
int val = source[i];
|
||||||
|
result[i] = (val << 1) | carry;
|
||||||
|
carry = val >>> 31;
|
||||||
|
}
|
||||||
|
if (carry != 0) {
|
||||||
|
result[srcLen] = carry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see BigInteger#shiftRight(int)
|
||||||
|
* @param source
|
||||||
|
* @param count
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static BigInteger shiftRight(BigInteger source, int count) {
|
||||||
|
int intCount = count >> 5; // count of integers
|
||||||
|
count &= 31; // count of remaining bits
|
||||||
|
if (intCount >= source.numberLength) {
|
||||||
|
return ((source.sign < 0) ? BigInteger.MINUS_ONE : BigInteger.ZERO);
|
||||||
|
}
|
||||||
|
int i;
|
||||||
|
int resLength = source.numberLength - intCount;
|
||||||
|
int resDigits[] = new int[resLength + 1];
|
||||||
|
|
||||||
|
shiftRight(resDigits, resLength, source.digits, intCount, count);
|
||||||
|
if (source.sign < 0) {
|
||||||
|
// Checking if the dropped bits are zeros (the remainder equals to
|
||||||
|
// 0)
|
||||||
|
for (i = 0; (i < intCount) && (source.digits[i] == 0); i++) {
|
||||||
|
}
|
||||||
|
// If the remainder is not zero, add 1 to the result
|
||||||
|
if ((i < intCount)
|
||||||
|
|| ((count > 0) && ((source.digits[i] << (32 - count)) != 0))) {
|
||||||
|
for (i = 0; (i < resLength) && (resDigits[i] == -1); i++) {
|
||||||
|
resDigits[i] = 0;
|
||||||
|
}
|
||||||
|
if (i == resLength) {
|
||||||
|
resLength++;
|
||||||
|
}
|
||||||
|
resDigits[i]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BigInteger result = new BigInteger(source.sign, resLength, resDigits);
|
||||||
|
result.cutOffLeadingZeroes();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shifts right an array of integers. Total shift distance in bits is intCount
|
||||||
|
* * 32 + count.
|
||||||
|
*
|
||||||
|
* @param result the destination array
|
||||||
|
* @param resultLen the destination array's length
|
||||||
|
* @param source the source array
|
||||||
|
* @param intCount the number of elements to be shifted
|
||||||
|
* @param count the number of bits to be shifted
|
||||||
|
* @return dropped bit's are all zero (i.e. remaider is zero)
|
||||||
|
*/
|
||||||
|
static boolean shiftRight(int result[], int resultLen, int source[],
|
||||||
|
int intCount, int count) {
|
||||||
|
int i;
|
||||||
|
boolean allZero = true;
|
||||||
|
for (i = 0; i < intCount; i++) {
|
||||||
|
allZero &= source[i] == 0;
|
||||||
|
}
|
||||||
|
if (count == 0) {
|
||||||
|
System.arraycopy(source, intCount, result, 0, resultLen);
|
||||||
|
i = resultLen;
|
||||||
|
} else {
|
||||||
|
int leftShiftCount = 32 - count;
|
||||||
|
|
||||||
|
allZero &= (source[i] << leftShiftCount) == 0;
|
||||||
|
for (i = 0; i < resultLen - 1; i++) {
|
||||||
|
result[i] = (source[i + intCount] >>> count)
|
||||||
|
| (source[i + intCount + 1] << leftShiftCount);
|
||||||
|
}
|
||||||
|
result[i] = (source[i + intCount] >>> count);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return allZero;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs a fast bit testing for positive numbers. The bit to to be tested
|
||||||
|
* must be in the range {@code [0, val.bitLength()-1]}
|
||||||
|
*/
|
||||||
|
static boolean testBit(BigInteger val, int n) {
|
||||||
|
// PRE: 0 <= n < val.bitLength()
|
||||||
|
return ((val.digits[n >> 5] & (1 << (n & 31))) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Just to denote that this class can't be instantiated.
|
||||||
|
*/
|
||||||
|
private BitLevel() {
|
||||||
|
}
|
||||||
|
}
|
488
gwt/jre/java/math/Conversion.java
Normal file
488
gwt/jre/java/math/Conversion.java
Normal file
@ -0,0 +1,488 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Google Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with this
|
||||||
|
* work for additional information regarding copyright ownership. The ASF
|
||||||
|
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*
|
||||||
|
* INCLUDES MODIFICATIONS BY RICHARD ZSCHECH AS WELL AS GOOGLE.
|
||||||
|
*/
|
||||||
|
package java.math;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static library that provides {@link BigInteger} base conversion from/to any
|
||||||
|
* integer represented in a {@link java.lang.String} Object.
|
||||||
|
*/
|
||||||
|
class Conversion {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bigRadices values are precomputed maximal powers of radices (integer
|
||||||
|
* numbers from 2 to 36) that fit into unsigned int (32 bits). bigRadices[0] =
|
||||||
|
* 2 ^ 31, bigRadices[8] = 10 ^ 9, etc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static final int bigRadices[] = {
|
||||||
|
-2147483648, 1162261467, 1073741824, 1220703125, 362797056, 1977326743,
|
||||||
|
1073741824, 387420489, 1000000000, 214358881, 429981696, 815730721,
|
||||||
|
1475789056, 170859375, 268435456, 410338673, 612220032, 893871739,
|
||||||
|
1280000000, 1801088541, 113379904, 148035889, 191102976, 244140625,
|
||||||
|
308915776, 387420489, 481890304, 594823321, 729000000, 887503681,
|
||||||
|
1073741824, 1291467969, 1544804416, 1838265625, 60466176};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds the maximal exponent for each radix, so that
|
||||||
|
* radix<sup>digitFitInInt[radix]</sup> fit in an {@code int} (32 bits).
|
||||||
|
*/
|
||||||
|
static final int[] digitFitInInt = {
|
||||||
|
-1, -1, 31, 19, 15, 13, 11, 11, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7,
|
||||||
|
7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see BigInteger#toString(int)
|
||||||
|
* @param val
|
||||||
|
* @param radix
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static String bigInteger2String(BigInteger val, int radix) {
|
||||||
|
int sign = val.sign;
|
||||||
|
int numberLength = val.numberLength;
|
||||||
|
int digits[] = val.digits;
|
||||||
|
|
||||||
|
if (sign == 0) {
|
||||||
|
return "0"; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (numberLength == 1) {
|
||||||
|
int highDigit = digits[numberLength - 1];
|
||||||
|
long v = highDigit & 0xFFFFFFFFL;
|
||||||
|
if (sign < 0) {
|
||||||
|
v = -v;
|
||||||
|
}
|
||||||
|
return Long.toString(v, radix);
|
||||||
|
}
|
||||||
|
if ((radix == 10) || (radix < Character.MIN_RADIX)
|
||||||
|
|| (radix > Character.MAX_RADIX)) {
|
||||||
|
return val.toString();
|
||||||
|
}
|
||||||
|
double bitsForRadixDigit;
|
||||||
|
bitsForRadixDigit = Math.log(radix) / Math.log(2);
|
||||||
|
int resLengthInChars = (int) (val.abs().bitLength() / bitsForRadixDigit + ((sign < 0)
|
||||||
|
? 1 : 0)) + 1;
|
||||||
|
|
||||||
|
char result[] = new char[resLengthInChars];
|
||||||
|
int currentChar = resLengthInChars;
|
||||||
|
int resDigit;
|
||||||
|
if (radix != 16) {
|
||||||
|
int temp[] = new int[numberLength];
|
||||||
|
System.arraycopy(digits, 0, temp, 0, numberLength);
|
||||||
|
int tempLen = numberLength;
|
||||||
|
int charsPerInt = digitFitInInt[radix];
|
||||||
|
int i;
|
||||||
|
// get the maximal power of radix that fits in int
|
||||||
|
int bigRadix = bigRadices[radix - 2];
|
||||||
|
while (true) {
|
||||||
|
// divide the array of digits by bigRadix and convert remainders
|
||||||
|
// to characters collecting them in the char array
|
||||||
|
resDigit = Division.divideArrayByInt(temp, temp, tempLen, bigRadix);
|
||||||
|
int previous = currentChar;
|
||||||
|
do {
|
||||||
|
result[--currentChar] = Character.forDigit(resDigit % radix, radix);
|
||||||
|
} while (((resDigit /= radix) != 0) && (currentChar != 0));
|
||||||
|
int delta = charsPerInt - previous + currentChar;
|
||||||
|
for (i = 0; i < delta && currentChar > 0; i++) {
|
||||||
|
result[--currentChar] = '0';
|
||||||
|
}
|
||||||
|
for (i = tempLen - 1; (i > 0) && (temp[i] == 0); i--) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
tempLen = i + 1;
|
||||||
|
if ((tempLen == 1) && (temp[0] == 0)) { // the quotient is 0
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// radix == 16
|
||||||
|
for (int i = 0; i < numberLength; i++) {
|
||||||
|
for (int j = 0; (j < 8) && (currentChar > 0); j++) {
|
||||||
|
resDigit = digits[i] >> (j << 2) & 0xf;
|
||||||
|
result[--currentChar] = Character.forDigit(resDigit, 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (result[currentChar] == '0') {
|
||||||
|
currentChar++;
|
||||||
|
}
|
||||||
|
if (sign == -1) {
|
||||||
|
result[--currentChar] = '-';
|
||||||
|
}
|
||||||
|
return new String(result, currentChar, resLengthInChars - currentChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
static long divideLongByBillion(long a) {
|
||||||
|
long quot;
|
||||||
|
long rem;
|
||||||
|
|
||||||
|
if (a >= 0) {
|
||||||
|
long bLong = 1000000000L;
|
||||||
|
quot = (a / bLong);
|
||||||
|
rem = (a % bLong);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Make the dividend positive shifting it right by 1 bit then get the
|
||||||
|
* quotient an remainder and correct them properly
|
||||||
|
*/
|
||||||
|
long aPos = a >>> 1;
|
||||||
|
long bPos = 1000000000L >>> 1;
|
||||||
|
quot = aPos / bPos;
|
||||||
|
rem = aPos % bPos;
|
||||||
|
// double the remainder and add 1 if 'a' is odd
|
||||||
|
rem = (rem << 1) + (a & 1);
|
||||||
|
}
|
||||||
|
return ((rem << 32) | (quot & 0xFFFFFFFFL));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the correspondent {@code String} representation of {@code val} being
|
||||||
|
* scaled by {@code scale}.
|
||||||
|
*
|
||||||
|
* @see BigInteger#toString()
|
||||||
|
* @see BigDecimal#toString()
|
||||||
|
*/
|
||||||
|
static String toDecimalScaledString(BigInteger val, int scale) {
|
||||||
|
int sign = val.sign;
|
||||||
|
int numberLength = val.numberLength;
|
||||||
|
int digits[] = val.digits;
|
||||||
|
int resLengthInChars;
|
||||||
|
int currentChar;
|
||||||
|
char result[];
|
||||||
|
|
||||||
|
if (sign == 0) {
|
||||||
|
switch (scale) {
|
||||||
|
case 0:
|
||||||
|
return "0"; //$NON-NLS-1$
|
||||||
|
case 1:
|
||||||
|
return "0.0"; //$NON-NLS-1$
|
||||||
|
case 2:
|
||||||
|
return "0.00"; //$NON-NLS-1$
|
||||||
|
case 3:
|
||||||
|
return "0.000"; //$NON-NLS-1$
|
||||||
|
case 4:
|
||||||
|
return "0.0000"; //$NON-NLS-1$
|
||||||
|
case 5:
|
||||||
|
return "0.00000"; //$NON-NLS-1$
|
||||||
|
case 6:
|
||||||
|
return "0.000000"; //$NON-NLS-1$
|
||||||
|
default:
|
||||||
|
StringBuilder result1 = new StringBuilder();
|
||||||
|
if (scale < 0) {
|
||||||
|
result1.append("0E+"); //$NON-NLS-1$
|
||||||
|
} else {
|
||||||
|
result1.append("0E"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
result1.append(-scale);
|
||||||
|
return result1.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// one 32-bit unsigned value may contains 10 decimal digits
|
||||||
|
resLengthInChars = numberLength * 10 + 1 + 7;
|
||||||
|
// Explanation why +1+7:
|
||||||
|
// +1 - one char for sign if needed.
|
||||||
|
// +7 - For "special case 2" (see below) we have 7 free chars for
|
||||||
|
// inserting necessary scaled digits.
|
||||||
|
result = new char[resLengthInChars + 1];
|
||||||
|
// allocated [resLengthInChars+1] characters.
|
||||||
|
// a free latest character may be used for "special case 1" (see
|
||||||
|
// below)
|
||||||
|
currentChar = resLengthInChars;
|
||||||
|
if (numberLength == 1) {
|
||||||
|
int highDigit = digits[0];
|
||||||
|
if (highDigit < 0) {
|
||||||
|
long v = highDigit & 0xFFFFFFFFL;
|
||||||
|
do {
|
||||||
|
long prev = v;
|
||||||
|
v /= 10;
|
||||||
|
result[--currentChar] = (char) (0x0030 + ((int) (prev - v * 10)));
|
||||||
|
} while (v != 0);
|
||||||
|
} else {
|
||||||
|
int v = highDigit;
|
||||||
|
do {
|
||||||
|
int prev = v;
|
||||||
|
v /= 10;
|
||||||
|
result[--currentChar] = (char) (0x0030 + (prev - v * 10));
|
||||||
|
} while (v != 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int temp[] = new int[numberLength];
|
||||||
|
int tempLen = numberLength;
|
||||||
|
System.arraycopy(digits, 0, temp, 0, tempLen);
|
||||||
|
BIG_LOOP : while (true) {
|
||||||
|
// divide the array of digits by bigRadix and convert
|
||||||
|
// remainders
|
||||||
|
// to characters collecting them in the char array
|
||||||
|
long result11 = 0;
|
||||||
|
for (int i1 = tempLen - 1; i1 >= 0; i1--) {
|
||||||
|
long temp1 = (result11 << 32) + (temp[i1] & 0xFFFFFFFFL);
|
||||||
|
long res = divideLongByBillion(temp1);
|
||||||
|
temp[i1] = (int) res;
|
||||||
|
result11 = (int) (res >> 32);
|
||||||
|
}
|
||||||
|
int resDigit = (int) result11;
|
||||||
|
int previous = currentChar;
|
||||||
|
do {
|
||||||
|
result[--currentChar] = (char) (0x0030 + (resDigit % 10));
|
||||||
|
} while (((resDigit /= 10) != 0) && (currentChar != 0));
|
||||||
|
int delta = 9 - previous + currentChar;
|
||||||
|
for (int i = 0; (i < delta) && (currentChar > 0); i++) {
|
||||||
|
result[--currentChar] = '0';
|
||||||
|
}
|
||||||
|
int j = tempLen - 1;
|
||||||
|
for (; temp[j] == 0; j--) {
|
||||||
|
if (j == 0) { // means temp[0] == 0
|
||||||
|
break BIG_LOOP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tempLen = j + 1;
|
||||||
|
}
|
||||||
|
while (result[currentChar] == '0') {
|
||||||
|
currentChar++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
boolean negNumber = (sign < 0);
|
||||||
|
int exponent = resLengthInChars - currentChar - scale - 1;
|
||||||
|
if (scale == 0) {
|
||||||
|
if (negNumber) {
|
||||||
|
result[--currentChar] = '-';
|
||||||
|
}
|
||||||
|
return new String(result, currentChar, resLengthInChars - currentChar);
|
||||||
|
}
|
||||||
|
if ((scale > 0) && (exponent >= -6)) {
|
||||||
|
if (exponent >= 0) {
|
||||||
|
// special case 1
|
||||||
|
int insertPoint = currentChar + exponent;
|
||||||
|
for (int j = resLengthInChars - 1; j >= insertPoint; j--) {
|
||||||
|
result[j + 1] = result[j];
|
||||||
|
}
|
||||||
|
result[++insertPoint] = '.';
|
||||||
|
if (negNumber) {
|
||||||
|
result[--currentChar] = '-';
|
||||||
|
}
|
||||||
|
return new String(result, currentChar, resLengthInChars - currentChar
|
||||||
|
+ 1);
|
||||||
|
}
|
||||||
|
// special case 2
|
||||||
|
for (int j = 2; j < -exponent + 1; j++) {
|
||||||
|
result[--currentChar] = '0';
|
||||||
|
}
|
||||||
|
result[--currentChar] = '.';
|
||||||
|
result[--currentChar] = '0';
|
||||||
|
if (negNumber) {
|
||||||
|
result[--currentChar] = '-';
|
||||||
|
}
|
||||||
|
return new String(result, currentChar, resLengthInChars - currentChar);
|
||||||
|
}
|
||||||
|
int startPoint = currentChar + 1;
|
||||||
|
int endPoint = resLengthInChars;
|
||||||
|
StringBuilder result1 = new StringBuilder(16 + endPoint - startPoint);
|
||||||
|
if (negNumber) {
|
||||||
|
result1.append('-');
|
||||||
|
}
|
||||||
|
if (endPoint - startPoint >= 1) {
|
||||||
|
result1.append(result[currentChar]);
|
||||||
|
result1.append('.');
|
||||||
|
result1.append(result, currentChar + 1, resLengthInChars - currentChar
|
||||||
|
- 1);
|
||||||
|
} else {
|
||||||
|
result1.append(result, currentChar, resLengthInChars - currentChar);
|
||||||
|
}
|
||||||
|
result1.append('E');
|
||||||
|
if (exponent > 0) {
|
||||||
|
result1.append('+');
|
||||||
|
}
|
||||||
|
result1.append(Integer.toString(exponent));
|
||||||
|
return result1.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* can process only 32-bit numbers */
|
||||||
|
static String toDecimalScaledString(long value, int scale) {
|
||||||
|
int resLengthInChars;
|
||||||
|
int currentChar;
|
||||||
|
char result[];
|
||||||
|
boolean negNumber = value < 0;
|
||||||
|
if (negNumber) {
|
||||||
|
value = -value;
|
||||||
|
}
|
||||||
|
if (value == 0) {
|
||||||
|
switch (scale) {
|
||||||
|
case 0:
|
||||||
|
return "0"; //$NON-NLS-1$
|
||||||
|
case 1:
|
||||||
|
return "0.0"; //$NON-NLS-1$
|
||||||
|
case 2:
|
||||||
|
return "0.00"; //$NON-NLS-1$
|
||||||
|
case 3:
|
||||||
|
return "0.000"; //$NON-NLS-1$
|
||||||
|
case 4:
|
||||||
|
return "0.0000"; //$NON-NLS-1$
|
||||||
|
case 5:
|
||||||
|
return "0.00000"; //$NON-NLS-1$
|
||||||
|
case 6:
|
||||||
|
return "0.000000"; //$NON-NLS-1$
|
||||||
|
default:
|
||||||
|
StringBuilder result1 = new StringBuilder();
|
||||||
|
if (scale < 0) {
|
||||||
|
result1.append("0E+"); //$NON-NLS-1$
|
||||||
|
} else {
|
||||||
|
result1.append("0E"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
result1.append((scale == Integer.MIN_VALUE)
|
||||||
|
? "2147483648" : Integer.toString(-scale)); //$NON-NLS-1$
|
||||||
|
return result1.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// one 32-bit unsigned value may contains 10 decimal digits
|
||||||
|
resLengthInChars = 18;
|
||||||
|
// Explanation why +1+7:
|
||||||
|
// +1 - one char for sign if needed.
|
||||||
|
// +7 - For "special case 2" (see below) we have 7 free chars for
|
||||||
|
// inserting necessary scaled digits.
|
||||||
|
result = new char[resLengthInChars + 1];
|
||||||
|
// Allocated [resLengthInChars+1] characters.
|
||||||
|
// a free latest character may be used for "special case 1" (see below)
|
||||||
|
currentChar = resLengthInChars;
|
||||||
|
long v = value;
|
||||||
|
do {
|
||||||
|
long prev = v;
|
||||||
|
v /= 10;
|
||||||
|
result[--currentChar] = (char) (0x0030 + (prev - v * 10));
|
||||||
|
} while (v != 0);
|
||||||
|
|
||||||
|
long exponent = (long) resLengthInChars - (long) currentChar - scale - 1L;
|
||||||
|
if (scale == 0) {
|
||||||
|
if (negNumber) {
|
||||||
|
result[--currentChar] = '-';
|
||||||
|
}
|
||||||
|
return new String(result, currentChar, resLengthInChars - currentChar);
|
||||||
|
}
|
||||||
|
if (scale > 0 && exponent >= -6) {
|
||||||
|
if (exponent >= 0) {
|
||||||
|
// special case 1
|
||||||
|
int insertPoint = currentChar + (int) exponent;
|
||||||
|
for (int j = resLengthInChars - 1; j >= insertPoint; j--) {
|
||||||
|
result[j + 1] = result[j];
|
||||||
|
}
|
||||||
|
result[++insertPoint] = '.';
|
||||||
|
if (negNumber) {
|
||||||
|
result[--currentChar] = '-';
|
||||||
|
}
|
||||||
|
return new String(result, currentChar, resLengthInChars - currentChar
|
||||||
|
+ 1);
|
||||||
|
}
|
||||||
|
// special case 2
|
||||||
|
for (int j = 2; j < -exponent + 1; j++) {
|
||||||
|
result[--currentChar] = '0';
|
||||||
|
}
|
||||||
|
result[--currentChar] = '.';
|
||||||
|
result[--currentChar] = '0';
|
||||||
|
if (negNumber) {
|
||||||
|
result[--currentChar] = '-';
|
||||||
|
}
|
||||||
|
return new String(result, currentChar, resLengthInChars - currentChar);
|
||||||
|
}
|
||||||
|
int startPoint = currentChar + 1;
|
||||||
|
int endPoint = resLengthInChars;
|
||||||
|
StringBuilder result1 = new StringBuilder(16 + endPoint - startPoint);
|
||||||
|
if (negNumber) {
|
||||||
|
result1.append('-');
|
||||||
|
}
|
||||||
|
if (endPoint - startPoint >= 1) {
|
||||||
|
result1.append(result[currentChar]);
|
||||||
|
result1.append('.');
|
||||||
|
result1.append(result, currentChar + 1, resLengthInChars - currentChar
|
||||||
|
- 1);
|
||||||
|
} else {
|
||||||
|
result1.append(result, currentChar, resLengthInChars - currentChar);
|
||||||
|
}
|
||||||
|
result1.append('E');
|
||||||
|
if (exponent > 0) {
|
||||||
|
result1.append('+');
|
||||||
|
}
|
||||||
|
result1.append(Long.toString(exponent));
|
||||||
|
return result1.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Just to denote that this class can't be instantiated.
|
||||||
|
*/
|
||||||
|
private Conversion() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @see BigInteger#doubleValue()
|
||||||
|
// */
|
||||||
|
// static double bigInteger2Double(BigInteger val) {
|
||||||
|
// // val.bitLength() < 64
|
||||||
|
// if ((val.numberLength < 2)
|
||||||
|
// || ((val.numberLength == 2) && (val.digits[1] > 0))) {
|
||||||
|
// return val.longValue();
|
||||||
|
// }
|
||||||
|
// // val.bitLength() >= 33 * 32 > 1024
|
||||||
|
// if (val.numberLength > 32) {
|
||||||
|
// return ((val.sign > 0) ? Double.POSITIVE_INFINITY
|
||||||
|
// : Double.NEGATIVE_INFINITY);
|
||||||
|
// }
|
||||||
|
// int bitLen = val.abs().bitLength();
|
||||||
|
// long exponent = bitLen - 1;
|
||||||
|
// int delta = bitLen - 54;
|
||||||
|
// // We need 54 top bits from this, the 53th bit is always 1 in lVal.
|
||||||
|
// long lVal = val.abs().shiftRight(delta).longValue();
|
||||||
|
// /*
|
||||||
|
// * Take 53 bits from lVal to mantissa. The least significant bit is
|
||||||
|
// * needed for rounding.
|
||||||
|
// */
|
||||||
|
// long mantissa = lVal & 0x1FFFFFFFFFFFFFL;
|
||||||
|
// if (exponent == 1023) {
|
||||||
|
// if (mantissa == 0X1FFFFFFFFFFFFFL) {
|
||||||
|
// return ((val.sign > 0) ? Double.POSITIVE_INFINITY
|
||||||
|
// : Double.NEGATIVE_INFINITY);
|
||||||
|
// }
|
||||||
|
// if (mantissa == 0x1FFFFFFFFFFFFEL) {
|
||||||
|
// return ((val.sign > 0) ? Double.MAX_VALUE : -Double.MAX_VALUE);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// // Round the mantissa
|
||||||
|
// if (((mantissa & 1) == 1)
|
||||||
|
// && (((mantissa & 2) == 2) || BitLevel.nonZeroDroppedBits(delta,
|
||||||
|
// val.digits))) {
|
||||||
|
// mantissa += 2;
|
||||||
|
// }
|
||||||
|
// mantissa >>= 1; // drop the rounding bit
|
||||||
|
// long resSign = (val.sign < 0) ? 0x8000000000000000L : 0;
|
||||||
|
// exponent = ((1023 + exponent) << 52) & 0x7FF0000000000000L;
|
||||||
|
// long result = resSign | exponent | mantissa;
|
||||||
|
// return Double.longBitsToDouble(result);
|
||||||
|
// }
|
||||||
|
}
|
1013
gwt/jre/java/math/Division.java
Normal file
1013
gwt/jre/java/math/Division.java
Normal file
File diff suppressed because it is too large
Load Diff
457
gwt/jre/java/math/Elementary.java
Normal file
457
gwt/jre/java/math/Elementary.java
Normal file
@ -0,0 +1,457 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Google Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with this
|
||||||
|
* work for additional information regarding copyright ownership. The ASF
|
||||||
|
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*
|
||||||
|
* INCLUDES MODIFICATIONS BY RICHARD ZSCHECH AS WELL AS GOOGLE.
|
||||||
|
*/
|
||||||
|
package java.math;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static library that provides the basic arithmetic mutable operations for
|
||||||
|
* {@link BigInteger}. The operations provided are listed below. <ul
|
||||||
|
* type="circle"> <li>Addition.</li> <li>Subtraction.</li> <li>Comparison.</li>
|
||||||
|
* </ul> In addition to this, some <i><b>Inplace</b></i> (mutable) methods are
|
||||||
|
* provided.
|
||||||
|
*/
|
||||||
|
class Elementary {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see BigInteger#add(BigInteger) .
|
||||||
|
* @param op1
|
||||||
|
* @param op2
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static BigInteger add(BigInteger op1, BigInteger op2) {
|
||||||
|
int resDigits[];
|
||||||
|
int resSign;
|
||||||
|
int op1Sign = op1.sign;
|
||||||
|
int op2Sign = op2.sign;
|
||||||
|
|
||||||
|
if (op1Sign == 0) {
|
||||||
|
return op2;
|
||||||
|
}
|
||||||
|
if (op2Sign == 0) {
|
||||||
|
return op1;
|
||||||
|
}
|
||||||
|
int op1Len = op1.numberLength;
|
||||||
|
int op2Len = op2.numberLength;
|
||||||
|
|
||||||
|
if (op1Len + op2Len == 2) {
|
||||||
|
long a = (op1.digits[0] & 0xFFFFFFFFL);
|
||||||
|
long b = (op2.digits[0] & 0xFFFFFFFFL);
|
||||||
|
long res;
|
||||||
|
int valueLo;
|
||||||
|
int valueHi;
|
||||||
|
|
||||||
|
if (op1Sign == op2Sign) {
|
||||||
|
res = a + b;
|
||||||
|
valueLo = (int) res;
|
||||||
|
valueHi = (int) (res >>> 32);
|
||||||
|
return ((valueHi == 0) ? new BigInteger(op1Sign, valueLo)
|
||||||
|
: new BigInteger(op1Sign, 2, new int[] {valueLo, valueHi}));
|
||||||
|
}
|
||||||
|
return BigInteger.valueOf((op1Sign < 0) ? (b - a) : (a - b));
|
||||||
|
} else if (op1Sign == op2Sign) {
|
||||||
|
resSign = op1Sign;
|
||||||
|
// an augend should not be shorter than addend
|
||||||
|
resDigits = (op1Len >= op2Len) ? add(op1.digits, op1Len, op2.digits,
|
||||||
|
op2Len) : add(op2.digits, op2Len, op1.digits, op1Len);
|
||||||
|
} else { // signs are different
|
||||||
|
int cmp = ((op1Len != op2Len) ? ((op1Len > op2Len) ? 1 : -1)
|
||||||
|
: compareArrays(op1.digits, op2.digits, op1Len));
|
||||||
|
|
||||||
|
if (cmp == BigInteger.EQUALS) {
|
||||||
|
return BigInteger.ZERO;
|
||||||
|
}
|
||||||
|
// a minuend should not be shorter than subtrahend
|
||||||
|
if (cmp == BigInteger.GREATER) {
|
||||||
|
resSign = op1Sign;
|
||||||
|
resDigits = subtract(op1.digits, op1Len, op2.digits, op2Len);
|
||||||
|
} else {
|
||||||
|
resSign = op2Sign;
|
||||||
|
resDigits = subtract(op2.digits, op2Len, op1.digits, op1Len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BigInteger res = new BigInteger(resSign, resDigits.length, resDigits);
|
||||||
|
res.cutOffLeadingZeroes();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares two arrays. All elements are treated as unsigned integers. The
|
||||||
|
* magnitude is the bit chain of elements in big-endian order.
|
||||||
|
*
|
||||||
|
* @param a the first array
|
||||||
|
* @param b the second array
|
||||||
|
* @param size the size of arrays
|
||||||
|
* @return 1 if a > b, -1 if a < b, 0 if a == b
|
||||||
|
*/
|
||||||
|
static int compareArrays(final int[] a, final int[] b, final int size) {
|
||||||
|
int i;
|
||||||
|
for (i = size - 1; (i >= 0) && (a[i] == b[i]); i--) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
return ((i < 0) ? BigInteger.EQUALS
|
||||||
|
: (a[i] & 0xFFFFFFFFL) < (b[i] & 0xFFFFFFFFL) ? BigInteger.LESS
|
||||||
|
: BigInteger.GREATER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same as @link #inplaceAdd(BigInteger, BigInteger), but without the
|
||||||
|
* restriction of non-positive values.
|
||||||
|
*
|
||||||
|
* @param op1 any number
|
||||||
|
* @param op2 any number
|
||||||
|
*/
|
||||||
|
static void completeInPlaceAdd(BigInteger op1, BigInteger op2) {
|
||||||
|
if (op1.sign == 0) {
|
||||||
|
System.arraycopy(op2.digits, 0, op1.digits, 0, op2.numberLength);
|
||||||
|
} else if (op2.sign == 0) {
|
||||||
|
return;
|
||||||
|
} else if (op1.sign == op2.sign) {
|
||||||
|
add(op1.digits, op1.digits, op1.numberLength, op2.digits,
|
||||||
|
op2.numberLength);
|
||||||
|
} else {
|
||||||
|
int sign = unsignedArraysCompare(op1.digits, op2.digits,
|
||||||
|
op1.numberLength, op2.numberLength);
|
||||||
|
if (sign > 0) {
|
||||||
|
subtract(op1.digits, op1.digits, op1.numberLength, op2.digits,
|
||||||
|
op2.numberLength);
|
||||||
|
} else {
|
||||||
|
inverseSubtract(op1.digits, op1.digits, op1.numberLength, op2.digits,
|
||||||
|
op2.numberLength);
|
||||||
|
op1.sign = -op1.sign;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
op1.numberLength = Math.max(op1.numberLength, op2.numberLength) + 1;
|
||||||
|
op1.cutOffLeadingZeroes();
|
||||||
|
op1.unCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same as @link #inplaceSubtract(BigInteger, BigInteger), but without the
|
||||||
|
* restriction of non-positive values.
|
||||||
|
*
|
||||||
|
* @param op1 should have enough space to save the result
|
||||||
|
* @param op2
|
||||||
|
*/
|
||||||
|
static void completeInPlaceSubtract(BigInteger op1, BigInteger op2) {
|
||||||
|
int resultSign = op1.compareTo(op2);
|
||||||
|
if (op1.sign == 0) {
|
||||||
|
System.arraycopy(op2.digits, 0, op1.digits, 0, op2.numberLength);
|
||||||
|
op1.sign = -op2.sign;
|
||||||
|
} else if (op1.sign != op2.sign) {
|
||||||
|
add(op1.digits, op1.digits, op1.numberLength, op2.digits,
|
||||||
|
op2.numberLength);
|
||||||
|
op1.sign = resultSign;
|
||||||
|
} else {
|
||||||
|
int sign = unsignedArraysCompare(op1.digits, op2.digits,
|
||||||
|
op1.numberLength, op2.numberLength);
|
||||||
|
if (sign > 0) {
|
||||||
|
subtract(op1.digits, op1.digits, op1.numberLength, op2.digits,
|
||||||
|
op2.numberLength); // op1 = op1 - op2
|
||||||
|
// op1.sign remains equal
|
||||||
|
} else {
|
||||||
|
inverseSubtract(op1.digits, op1.digits, op1.numberLength, op2.digits,
|
||||||
|
op2.numberLength); // op1 = op2 - op1
|
||||||
|
op1.sign = -op1.sign;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
op1.numberLength = Math.max(op1.numberLength, op2.numberLength) + 1;
|
||||||
|
op1.cutOffLeadingZeroes();
|
||||||
|
op1.unCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs {@code op1 += op2}. {@code op1} must have enough place to store
|
||||||
|
* the result (i.e. {@code op1.bitLength() >= op2.bitLength()}). Both should
|
||||||
|
* be positive (i.e. {@code op1 >= op2}).
|
||||||
|
*
|
||||||
|
* @param op1 the input minuend, and the output result.
|
||||||
|
* @param op2 the addend
|
||||||
|
*/
|
||||||
|
static void inplaceAdd(BigInteger op1, BigInteger op2) {
|
||||||
|
// PRE: op1 >= op2 > 0
|
||||||
|
add(op1.digits, op1.digits, op1.numberLength, op2.digits, op2.numberLength);
|
||||||
|
op1.numberLength = Math.min(
|
||||||
|
Math.max(op1.numberLength, op2.numberLength) + 1, op1.digits.length);
|
||||||
|
op1.cutOffLeadingZeroes();
|
||||||
|
op1.unCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs: {@code op1 += addend}. The number must to have place to hold a
|
||||||
|
* possible carry.
|
||||||
|
*/
|
||||||
|
static void inplaceAdd(BigInteger op1, final int addend) {
|
||||||
|
int carry = inplaceAdd(op1.digits, op1.numberLength, addend);
|
||||||
|
if (carry == 1) {
|
||||||
|
op1.digits[op1.numberLength] = 1;
|
||||||
|
op1.numberLength++;
|
||||||
|
}
|
||||||
|
op1.unCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an integer value to the array of integers remembering carry.
|
||||||
|
*
|
||||||
|
* @return a possible generated carry (0 or 1)
|
||||||
|
*/
|
||||||
|
static int inplaceAdd(int a[], final int aSize, final int addend) {
|
||||||
|
long carry = addend & 0xFFFFFFFFL;
|
||||||
|
|
||||||
|
for (int i = 0; (carry != 0) && (i < aSize); i++) {
|
||||||
|
carry += a[i] & 0xFFFFFFFFL;
|
||||||
|
a[i] = (int) carry;
|
||||||
|
carry >>= 32;
|
||||||
|
}
|
||||||
|
return (int) carry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs {@code op1 -= op2}. {@code op1} must have enough place to store
|
||||||
|
* the result (i.e. {@code op1.bitLength() >= op2.bitLength()}). Both should
|
||||||
|
* be positive (what implies that {@code op1 >= op2}).
|
||||||
|
*
|
||||||
|
* @param op1 the input minuend, and the output result.
|
||||||
|
* @param op2 the subtrahend
|
||||||
|
*/
|
||||||
|
static void inplaceSubtract(BigInteger op1, BigInteger op2) {
|
||||||
|
// PRE: op1 >= op2 > 0
|
||||||
|
subtract(op1.digits, op1.digits, op1.numberLength, op2.digits,
|
||||||
|
op2.numberLength);
|
||||||
|
op1.cutOffLeadingZeroes();
|
||||||
|
op1.unCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see BigInteger#subtract(BigInteger) .
|
||||||
|
* @param op1
|
||||||
|
* @param op2
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static BigInteger subtract(BigInteger op1, BigInteger op2) {
|
||||||
|
int resSign;
|
||||||
|
int resDigits[];
|
||||||
|
int op1Sign = op1.sign;
|
||||||
|
int op2Sign = op2.sign;
|
||||||
|
|
||||||
|
if (op2Sign == 0) {
|
||||||
|
return op1;
|
||||||
|
}
|
||||||
|
if (op1Sign == 0) {
|
||||||
|
return op2.negate();
|
||||||
|
}
|
||||||
|
int op1Len = op1.numberLength;
|
||||||
|
int op2Len = op2.numberLength;
|
||||||
|
if (op1Len + op2Len == 2) {
|
||||||
|
long a = (op1.digits[0] & 0xFFFFFFFFL);
|
||||||
|
long b = (op2.digits[0] & 0xFFFFFFFFL);
|
||||||
|
if (op1Sign < 0) {
|
||||||
|
a = -a;
|
||||||
|
}
|
||||||
|
if (op2Sign < 0) {
|
||||||
|
b = -b;
|
||||||
|
}
|
||||||
|
return BigInteger.valueOf(a - b);
|
||||||
|
}
|
||||||
|
int cmp = ((op1Len != op2Len) ? ((op1Len > op2Len) ? 1 : -1)
|
||||||
|
: Elementary.compareArrays(op1.digits, op2.digits, op1Len));
|
||||||
|
|
||||||
|
if (cmp == BigInteger.LESS) {
|
||||||
|
resSign = -op2Sign;
|
||||||
|
resDigits = (op1Sign == op2Sign) ? subtract(op2.digits, op2Len,
|
||||||
|
op1.digits, op1Len) : add(op2.digits, op2Len, op1.digits, op1Len);
|
||||||
|
} else {
|
||||||
|
resSign = op1Sign;
|
||||||
|
if (op1Sign == op2Sign) {
|
||||||
|
if (cmp == BigInteger.EQUALS) {
|
||||||
|
return BigInteger.ZERO;
|
||||||
|
}
|
||||||
|
resDigits = subtract(op1.digits, op1Len, op2.digits, op2Len);
|
||||||
|
} else {
|
||||||
|
resDigits = add(op1.digits, op1Len, op2.digits, op2Len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BigInteger res = new BigInteger(resSign, resDigits.length, resDigits);
|
||||||
|
res.cutOffLeadingZeroes();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Addss the value represented by {@code b} to the value represented by
|
||||||
|
* {@code a}. It is assumed the magnitude of a is not less than the magnitude
|
||||||
|
* of b.
|
||||||
|
*
|
||||||
|
* @return {@code a + b}
|
||||||
|
*/
|
||||||
|
private static int[] add(int a[], int aSize, int b[], int bSize) {
|
||||||
|
// PRE: a[] >= b[]
|
||||||
|
int res[] = new int[aSize + 1];
|
||||||
|
add(res, a, aSize, b, bSize);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs {@code res = a + b}.
|
||||||
|
*/
|
||||||
|
private static void add(int res[], int a[], int aSize, int b[], int bSize) {
|
||||||
|
// PRE: a.length < max(aSize, bSize)
|
||||||
|
|
||||||
|
int i;
|
||||||
|
long carry = (a[0] & 0xFFFFFFFFL) + (b[0] & 0xFFFFFFFFL);
|
||||||
|
|
||||||
|
res[0] = (int) carry;
|
||||||
|
carry >>= 32;
|
||||||
|
|
||||||
|
if (aSize >= bSize) {
|
||||||
|
for (i = 1; i < bSize; i++) {
|
||||||
|
carry += (a[i] & 0xFFFFFFFFL) + (b[i] & 0xFFFFFFFFL);
|
||||||
|
res[i] = (int) carry;
|
||||||
|
carry >>= 32;
|
||||||
|
}
|
||||||
|
for (; i < aSize; i++) {
|
||||||
|
carry += a[i] & 0xFFFFFFFFL;
|
||||||
|
res[i] = (int) carry;
|
||||||
|
carry >>= 32;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (i = 1; i < aSize; i++) {
|
||||||
|
carry += (a[i] & 0xFFFFFFFFL) + (b[i] & 0xFFFFFFFFL);
|
||||||
|
res[i] = (int) carry;
|
||||||
|
carry >>= 32;
|
||||||
|
}
|
||||||
|
for (; i < bSize; i++) {
|
||||||
|
carry += b[i] & 0xFFFFFFFFL;
|
||||||
|
res[i] = (int) carry;
|
||||||
|
carry >>= 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (carry != 0) {
|
||||||
|
res[i] = (int) carry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs {@code res = b - a}.
|
||||||
|
*/
|
||||||
|
private static void inverseSubtract(int res[], int a[], int aSize, int b[],
|
||||||
|
int bSize) {
|
||||||
|
int i;
|
||||||
|
long borrow = 0;
|
||||||
|
if (aSize < bSize) {
|
||||||
|
for (i = 0; i < aSize; i++) {
|
||||||
|
borrow += (b[i] & 0xFFFFFFFFL) - (a[i] & 0xFFFFFFFFL);
|
||||||
|
res[i] = (int) borrow;
|
||||||
|
borrow >>= 32; // -1 or 0
|
||||||
|
}
|
||||||
|
for (; i < bSize; i++) {
|
||||||
|
borrow += b[i] & 0xFFFFFFFFL;
|
||||||
|
res[i] = (int) borrow;
|
||||||
|
borrow >>= 32; // -1 or 0
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (i = 0; i < bSize; i++) {
|
||||||
|
borrow += (b[i] & 0xFFFFFFFFL) - (a[i] & 0xFFFFFFFFL);
|
||||||
|
res[i] = (int) borrow;
|
||||||
|
borrow >>= 32; // -1 or 0
|
||||||
|
}
|
||||||
|
for (; i < aSize; i++) {
|
||||||
|
borrow -= a[i] & 0xFFFFFFFFL;
|
||||||
|
res[i] = (int) borrow;
|
||||||
|
borrow >>= 32; // -1 or 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subtracts the value represented by {@code b} from the value represented by
|
||||||
|
* {@code a}. It is assumed the magnitude of a is not less than the magnitude
|
||||||
|
* of b.
|
||||||
|
*
|
||||||
|
* @return {@code a - b}
|
||||||
|
*/
|
||||||
|
private static int[] subtract(int a[], int aSize, int b[], int bSize) {
|
||||||
|
// PRE: a[] >= b[]
|
||||||
|
int res[] = new int[aSize];
|
||||||
|
subtract(res, a, aSize, b, bSize);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs {@code res = a - b}. It is assumed the magnitude of a is not less
|
||||||
|
* than the magnitude of b.
|
||||||
|
*/
|
||||||
|
private static void subtract(int res[], int a[], int aSize, int b[], int bSize) {
|
||||||
|
// PRE: a[] >= b[]
|
||||||
|
int i;
|
||||||
|
long borrow = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < bSize; i++) {
|
||||||
|
borrow += (a[i] & 0xFFFFFFFFL) - (b[i] & 0xFFFFFFFFL);
|
||||||
|
res[i] = (int) borrow;
|
||||||
|
borrow >>= 32; // -1 or 0
|
||||||
|
}
|
||||||
|
for (; i < aSize; i++) {
|
||||||
|
borrow += a[i] & 0xFFFFFFFFL;
|
||||||
|
res[i] = (int) borrow;
|
||||||
|
borrow >>= 32; // -1 or 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares two arrays, representing unsigned integer in little-endian order.
|
||||||
|
* Returns +1,0,-1 if a is - respective - greater, equal or lesser then b
|
||||||
|
*/
|
||||||
|
private static int unsignedArraysCompare(int[] a, int[] b, int aSize,
|
||||||
|
int bSize) {
|
||||||
|
if (aSize > bSize) {
|
||||||
|
return 1;
|
||||||
|
} else if (aSize < bSize) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
int i;
|
||||||
|
for (i = aSize - 1; i >= 0 && a[i] == b[i]; i--) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
return i < 0 ? BigInteger.EQUALS
|
||||||
|
: ((a[i] & 0xFFFFFFFFL) < (b[i] & 0xFFFFFFFFL) ? BigInteger.LESS
|
||||||
|
: BigInteger.GREATER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Just to denote that this class can't be instantiated.
|
||||||
|
*/
|
||||||
|
private Elementary() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
926
gwt/jre/java/math/Logical.java
Normal file
926
gwt/jre/java/math/Logical.java
Normal file
@ -0,0 +1,926 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Google Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with this
|
||||||
|
* work for additional information regarding copyright ownership. The ASF
|
||||||
|
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*
|
||||||
|
* INCLUDES MODIFICATIONS BY RICHARD ZSCHECH AS WELL AS GOOGLE.
|
||||||
|
*/
|
||||||
|
package java.math;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The library implements some logical operations over {@code BigInteger}. The
|
||||||
|
* operations provided are listed below. <ul type="circle"> <li>not</li> <li>and
|
||||||
|
* </li> <li>andNot</li> <li>or</li> <li>xor</li> </ul>
|
||||||
|
*/
|
||||||
|
class Logical {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see BigInteger#and(BigInteger)
|
||||||
|
* @param val
|
||||||
|
* @param that
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static BigInteger and(BigInteger val, BigInteger that) {
|
||||||
|
if (that.sign == 0 || val.sign == 0) {
|
||||||
|
return BigInteger.ZERO;
|
||||||
|
}
|
||||||
|
if (that.equals(BigInteger.MINUS_ONE)) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
if (val.equals(BigInteger.MINUS_ONE)) {
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val.sign > 0) {
|
||||||
|
if (that.sign > 0) {
|
||||||
|
return andPositive(val, that);
|
||||||
|
} else {
|
||||||
|
return andDiffSigns(val, that);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (that.sign > 0) {
|
||||||
|
return andDiffSigns(that, val);
|
||||||
|
} else if (val.numberLength > that.numberLength) {
|
||||||
|
return andNegative(val, that);
|
||||||
|
} else {
|
||||||
|
return andNegative(that, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return sign = positive.magnitude & magnitude = -negative.magnitude.
|
||||||
|
* @param positive
|
||||||
|
* @param negative
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static BigInteger andDiffSigns(BigInteger positive, BigInteger negative) {
|
||||||
|
// PRE: positive is positive and negative is negative
|
||||||
|
int iPos = positive.getFirstNonzeroDigit();
|
||||||
|
int iNeg = negative.getFirstNonzeroDigit();
|
||||||
|
|
||||||
|
// Look if the trailing zeros of the negative will "blank" all
|
||||||
|
// the positive digits
|
||||||
|
if (iNeg >= positive.numberLength) {
|
||||||
|
return BigInteger.ZERO;
|
||||||
|
}
|
||||||
|
int resLength = positive.numberLength;
|
||||||
|
int resDigits[] = new int[resLength];
|
||||||
|
|
||||||
|
// Must start from max(iPos, iNeg)
|
||||||
|
int i = Math.max(iPos, iNeg);
|
||||||
|
if (i == iNeg) {
|
||||||
|
resDigits[i] = -negative.digits[i] & positive.digits[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
int limit = Math.min(negative.numberLength, positive.numberLength);
|
||||||
|
for (; i < limit; i++) {
|
||||||
|
resDigits[i] = ~negative.digits[i] & positive.digits[i];
|
||||||
|
}
|
||||||
|
// if the negative was shorter must copy the remaining digits
|
||||||
|
// from positive
|
||||||
|
if (i >= negative.numberLength) {
|
||||||
|
for (; i < positive.numberLength; i++) {
|
||||||
|
resDigits[i] = positive.digits[i];
|
||||||
|
}
|
||||||
|
} // else positive ended and must "copy" virtual 0's, do nothing then
|
||||||
|
|
||||||
|
BigInteger result = new BigInteger(1, resLength, resDigits);
|
||||||
|
result.cutOffLeadingZeroes();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return sign = -1, magnitude = -(-longer.magnitude & -shorter.magnitude).
|
||||||
|
* @param longer
|
||||||
|
* @param shorter
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static BigInteger andNegative(BigInteger longer, BigInteger shorter) {
|
||||||
|
// PRE: longer and shorter are negative
|
||||||
|
// PRE: longer has at least as many digits as shorter
|
||||||
|
int iLonger = longer.getFirstNonzeroDigit();
|
||||||
|
int iShorter = shorter.getFirstNonzeroDigit();
|
||||||
|
|
||||||
|
// Does shorter matter?
|
||||||
|
if (iLonger >= shorter.numberLength) {
|
||||||
|
return longer;
|
||||||
|
}
|
||||||
|
|
||||||
|
int resLength;
|
||||||
|
int resDigits[];
|
||||||
|
int i = Math.max(iShorter, iLonger);
|
||||||
|
int digit;
|
||||||
|
if (iShorter > iLonger) {
|
||||||
|
digit = -shorter.digits[i] & ~longer.digits[i];
|
||||||
|
} else if (iShorter < iLonger) {
|
||||||
|
digit = ~shorter.digits[i] & -longer.digits[i];
|
||||||
|
} else {
|
||||||
|
digit = -shorter.digits[i] & -longer.digits[i];
|
||||||
|
}
|
||||||
|
if (digit == 0) {
|
||||||
|
for (i++; i < shorter.numberLength
|
||||||
|
&& (digit = ~(longer.digits[i] | shorter.digits[i])) == 0; i++) {
|
||||||
|
// digit
|
||||||
|
}
|
||||||
|
// = ~longer.digits[i] & ~shorter.digits[i]
|
||||||
|
if (digit == 0) {
|
||||||
|
// shorter has only the remaining virtual sign bits
|
||||||
|
for (; i < longer.numberLength && (digit = ~longer.digits[i]) == 0; i++) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
if (digit == 0) {
|
||||||
|
resLength = longer.numberLength + 1;
|
||||||
|
resDigits = new int[resLength];
|
||||||
|
resDigits[resLength - 1] = 1;
|
||||||
|
|
||||||
|
BigInteger result = new BigInteger(-1, resLength, resDigits);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resLength = longer.numberLength;
|
||||||
|
resDigits = new int[resLength];
|
||||||
|
resDigits[i] = -digit;
|
||||||
|
for (i++; i < shorter.numberLength; i++) {
|
||||||
|
// resDigits[i] = ~(~longer.digits[i] & ~shorter.digits[i];)
|
||||||
|
resDigits[i] = longer.digits[i] | shorter.digits[i];
|
||||||
|
}
|
||||||
|
// shorter has only the remaining virtual sign bits
|
||||||
|
for (; i < longer.numberLength; i++) {
|
||||||
|
resDigits[i] = longer.digits[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInteger result = new BigInteger(-1, resLength, resDigits);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see BigInteger#andNot(BigInteger)
|
||||||
|
* @param val
|
||||||
|
* @param that
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static BigInteger andNot(BigInteger val, BigInteger that) {
|
||||||
|
if (that.sign == 0) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
if (val.sign == 0) {
|
||||||
|
return BigInteger.ZERO;
|
||||||
|
}
|
||||||
|
if (val.equals(BigInteger.MINUS_ONE)) {
|
||||||
|
return that.not();
|
||||||
|
}
|
||||||
|
if (that.equals(BigInteger.MINUS_ONE)) {
|
||||||
|
return BigInteger.ZERO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if val == that, return 0
|
||||||
|
|
||||||
|
if (val.sign > 0) {
|
||||||
|
if (that.sign > 0) {
|
||||||
|
return andNotPositive(val, that);
|
||||||
|
} else {
|
||||||
|
return andNotPositiveNegative(val, that);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (that.sign > 0) {
|
||||||
|
return andNotNegativePositive(val, that);
|
||||||
|
} else {
|
||||||
|
return andNotNegative(val, that);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return sign = 1, magnitude = -val.magnitude & ~(-that.magnitude).
|
||||||
|
* @param val
|
||||||
|
* @param that
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static BigInteger andNotNegative(BigInteger val, BigInteger that) {
|
||||||
|
// PRE: val < 0 && that < 0
|
||||||
|
int iVal = val.getFirstNonzeroDigit();
|
||||||
|
int iThat = that.getFirstNonzeroDigit();
|
||||||
|
|
||||||
|
if (iVal >= that.numberLength) {
|
||||||
|
return BigInteger.ZERO;
|
||||||
|
}
|
||||||
|
|
||||||
|
int resLength = that.numberLength;
|
||||||
|
int resDigits[] = new int[resLength];
|
||||||
|
int limit;
|
||||||
|
int i = iVal;
|
||||||
|
if (iVal < iThat) {
|
||||||
|
// resDigits[i] = -val.digits[i] & -1;
|
||||||
|
resDigits[i] = -val.digits[i];
|
||||||
|
limit = Math.min(val.numberLength, iThat);
|
||||||
|
for (i++; i < limit; i++) {
|
||||||
|
// resDigits[i] = ~val.digits[i] & -1;
|
||||||
|
resDigits[i] = ~val.digits[i];
|
||||||
|
}
|
||||||
|
if (i == val.numberLength) {
|
||||||
|
for (; i < iThat; i++) {
|
||||||
|
// resDigits[i] = -1 & -1;
|
||||||
|
resDigits[i] = -1;
|
||||||
|
}
|
||||||
|
// resDigits[i] = -1 & ~-that.digits[i];
|
||||||
|
resDigits[i] = that.digits[i] - 1;
|
||||||
|
} else {
|
||||||
|
// resDigits[i] = ~val.digits[i] & ~-that.digits[i];
|
||||||
|
resDigits[i] = ~val.digits[i] & (that.digits[i] - 1);
|
||||||
|
}
|
||||||
|
} else if (iThat < iVal) {
|
||||||
|
// resDigits[i] = -val.digits[i] & ~~that.digits[i];
|
||||||
|
resDigits[i] = -val.digits[i] & that.digits[i];
|
||||||
|
} else {
|
||||||
|
// resDigits[i] = -val.digits[i] & ~-that.digits[i];
|
||||||
|
resDigits[i] = -val.digits[i] & (that.digits[i] - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
limit = Math.min(val.numberLength, that.numberLength);
|
||||||
|
for (i++; i < limit; i++) {
|
||||||
|
// resDigits[i] = ~val.digits[i] & ~~that.digits[i];
|
||||||
|
resDigits[i] = ~val.digits[i] & that.digits[i];
|
||||||
|
}
|
||||||
|
for (; i < that.numberLength; i++) {
|
||||||
|
// resDigits[i] = -1 & ~~that.digits[i];
|
||||||
|
resDigits[i] = that.digits[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInteger result = new BigInteger(1, resLength, resDigits);
|
||||||
|
result.cutOffLeadingZeroes();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return sign = -1, magnitude = -(-negative.magnitude & ~positive.magnitude).
|
||||||
|
* @param negative
|
||||||
|
* @param positive
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static BigInteger andNotNegativePositive(BigInteger negative,
|
||||||
|
BigInteger positive) {
|
||||||
|
// PRE: negative < 0 && positive > 0
|
||||||
|
int resLength;
|
||||||
|
int resDigits[];
|
||||||
|
int limit;
|
||||||
|
int digit;
|
||||||
|
|
||||||
|
int iNeg = negative.getFirstNonzeroDigit();
|
||||||
|
int iPos = positive.getFirstNonzeroDigit();
|
||||||
|
|
||||||
|
if (iNeg >= positive.numberLength) {
|
||||||
|
return negative;
|
||||||
|
}
|
||||||
|
|
||||||
|
resLength = Math.max(negative.numberLength, positive.numberLength);
|
||||||
|
int i = iNeg;
|
||||||
|
if (iPos > iNeg) {
|
||||||
|
resDigits = new int[resLength];
|
||||||
|
limit = Math.min(negative.numberLength, iPos);
|
||||||
|
for (; i < limit; i++) {
|
||||||
|
// 1st case: resDigits [i] = -(-negative.digits[i] & (~0))
|
||||||
|
// otherwise: resDigits[i] = ~(~negative.digits[i] & ~0) ;
|
||||||
|
resDigits[i] = negative.digits[i];
|
||||||
|
}
|
||||||
|
if (i == negative.numberLength) {
|
||||||
|
for (i = iPos; i < positive.numberLength; i++) {
|
||||||
|
// resDigits[i] = ~(~positive.digits[i] & -1);
|
||||||
|
resDigits[i] = positive.digits[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
digit = -negative.digits[i] & ~positive.digits[i];
|
||||||
|
if (digit == 0) {
|
||||||
|
limit = Math.min(positive.numberLength, negative.numberLength);
|
||||||
|
for (i++; i < limit
|
||||||
|
&& (digit = ~(negative.digits[i] | positive.digits[i])) == 0; i++) {
|
||||||
|
// digit
|
||||||
|
}
|
||||||
|
// = ~negative.digits[i] & ~positive.digits[i]
|
||||||
|
if (digit == 0) {
|
||||||
|
// the shorter has only the remaining virtual sign bits
|
||||||
|
for (; i < positive.numberLength
|
||||||
|
&& (digit = ~positive.digits[i]) == 0; i++) {
|
||||||
|
// digit = -1 & ~positive.digits[i]
|
||||||
|
}
|
||||||
|
for (; i < negative.numberLength
|
||||||
|
&& (digit = ~negative.digits[i]) == 0; i++) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
// digit = ~negative.digits[i] & ~0
|
||||||
|
if (digit == 0) {
|
||||||
|
resLength++;
|
||||||
|
resDigits = new int[resLength];
|
||||||
|
resDigits[resLength - 1] = 1;
|
||||||
|
|
||||||
|
BigInteger result = new BigInteger(-1, resLength, resDigits);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resDigits = new int[resLength];
|
||||||
|
resDigits[i] = -digit;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
limit = Math.min(positive.numberLength, negative.numberLength);
|
||||||
|
for (; i < limit; i++) {
|
||||||
|
// resDigits[i] = ~(~negative.digits[i] & ~positive.digits[i]);
|
||||||
|
resDigits[i] = negative.digits[i] | positive.digits[i];
|
||||||
|
}
|
||||||
|
// Actually one of the next two cycles will be executed
|
||||||
|
for (; i < negative.numberLength; i++) {
|
||||||
|
resDigits[i] = negative.digits[i];
|
||||||
|
}
|
||||||
|
for (; i < positive.numberLength; i++) {
|
||||||
|
resDigits[i] = positive.digits[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInteger result = new BigInteger(-1, resLength, resDigits);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return sign = 1, magnitude = val.magnitude & ~that.magnitude.
|
||||||
|
* @param val
|
||||||
|
* @param that
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static BigInteger andNotPositive(BigInteger val, BigInteger that) {
|
||||||
|
// PRE: both arguments are positive
|
||||||
|
int resDigits[] = new int[val.numberLength];
|
||||||
|
|
||||||
|
int limit = Math.min(val.numberLength, that.numberLength);
|
||||||
|
int i;
|
||||||
|
for (i = val.getFirstNonzeroDigit(); i < limit; i++) {
|
||||||
|
resDigits[i] = val.digits[i] & ~that.digits[i];
|
||||||
|
}
|
||||||
|
for (; i < val.numberLength; i++) {
|
||||||
|
resDigits[i] = val.digits[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInteger result = new BigInteger(1, val.numberLength, resDigits);
|
||||||
|
result.cutOffLeadingZeroes();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return sign = 1, magnitude = positive.magnitude & ~(-negative.magnitude).
|
||||||
|
* @param positive
|
||||||
|
* @param negative
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static BigInteger andNotPositiveNegative(BigInteger positive,
|
||||||
|
BigInteger negative) {
|
||||||
|
// PRE: positive > 0 && negative < 0
|
||||||
|
int iNeg = negative.getFirstNonzeroDigit();
|
||||||
|
int iPos = positive.getFirstNonzeroDigit();
|
||||||
|
|
||||||
|
if (iNeg >= positive.numberLength) {
|
||||||
|
return positive;
|
||||||
|
}
|
||||||
|
|
||||||
|
int resLength = Math.min(positive.numberLength, negative.numberLength);
|
||||||
|
int resDigits[] = new int[resLength];
|
||||||
|
|
||||||
|
// Always start from first non zero of positive
|
||||||
|
int i = iPos;
|
||||||
|
for (; i < iNeg; i++) {
|
||||||
|
// resDigits[i] = positive.digits[i] & -1 (~0)
|
||||||
|
resDigits[i] = positive.digits[i];
|
||||||
|
}
|
||||||
|
if (i == iNeg) {
|
||||||
|
resDigits[i] = positive.digits[i] & (negative.digits[i] - 1);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
for (; i < resLength; i++) {
|
||||||
|
// resDigits[i] = positive.digits[i] & ~(~negative.digits[i]);
|
||||||
|
resDigits[i] = positive.digits[i] & negative.digits[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInteger result = new BigInteger(1, resLength, resDigits);
|
||||||
|
result.cutOffLeadingZeroes();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return sign = 1, magnitude = val.magnitude & that.magnitude.
|
||||||
|
* @param val
|
||||||
|
* @param that
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static BigInteger andPositive(BigInteger val, BigInteger that) {
|
||||||
|
// PRE: both arguments are positive
|
||||||
|
int resLength = Math.min(val.numberLength, that.numberLength);
|
||||||
|
int i = Math.max(val.getFirstNonzeroDigit(), that.getFirstNonzeroDigit());
|
||||||
|
|
||||||
|
if (i >= resLength) {
|
||||||
|
return BigInteger.ZERO;
|
||||||
|
}
|
||||||
|
|
||||||
|
int resDigits[] = new int[resLength];
|
||||||
|
for (; i < resLength; i++) {
|
||||||
|
resDigits[i] = val.digits[i] & that.digits[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInteger result = new BigInteger(1, resLength, resDigits);
|
||||||
|
result.cutOffLeadingZeroes();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see BigInteger#not()
|
||||||
|
* @param val
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static BigInteger not(BigInteger val) {
|
||||||
|
if (val.sign == 0) {
|
||||||
|
return BigInteger.MINUS_ONE;
|
||||||
|
}
|
||||||
|
if (val.equals(BigInteger.MINUS_ONE)) {
|
||||||
|
return BigInteger.ZERO;
|
||||||
|
}
|
||||||
|
int resDigits[] = new int[val.numberLength + 1];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (val.sign > 0) {
|
||||||
|
// ~val = -val + 1
|
||||||
|
if (val.digits[val.numberLength - 1] != -1) {
|
||||||
|
for (i = 0; val.digits[i] == -1; i++) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (i = 0; (i < val.numberLength) && (val.digits[i] == -1); i++) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
if (i == val.numberLength) {
|
||||||
|
resDigits[i] = 1;
|
||||||
|
return new BigInteger(-val.sign, i + 1, resDigits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Here a carry 1 was generated
|
||||||
|
} else {
|
||||||
|
// (val.sign < 0)
|
||||||
|
// ~val = -val - 1
|
||||||
|
for (i = 0; val.digits[i] == 0; i++) {
|
||||||
|
resDigits[i] = -1;
|
||||||
|
}
|
||||||
|
// Here a borrow -1 was generated
|
||||||
|
}
|
||||||
|
// Now, the carry/borrow can be absorbed
|
||||||
|
resDigits[i] = val.digits[i] + val.sign;
|
||||||
|
// Copying the remaining unchanged digit
|
||||||
|
for (i++; i < val.numberLength; i++) {
|
||||||
|
resDigits[i] = val.digits[i];
|
||||||
|
}
|
||||||
|
return new BigInteger(-val.sign, i, resDigits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see BigInteger#or(BigInteger).
|
||||||
|
* @param val
|
||||||
|
* @param that
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static BigInteger or(BigInteger val, BigInteger that) {
|
||||||
|
if (that.equals(BigInteger.MINUS_ONE) || val.equals(BigInteger.MINUS_ONE)) {
|
||||||
|
return BigInteger.MINUS_ONE;
|
||||||
|
}
|
||||||
|
if (that.sign == 0) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
if (val.sign == 0) {
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val.sign > 0) {
|
||||||
|
if (that.sign > 0) {
|
||||||
|
if (val.numberLength > that.numberLength) {
|
||||||
|
return orPositive(val, that);
|
||||||
|
} else {
|
||||||
|
return orPositive(that, val);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return orDiffSigns(val, that);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (that.sign > 0) {
|
||||||
|
return orDiffSigns(that, val);
|
||||||
|
} else if (that.getFirstNonzeroDigit() > val.getFirstNonzeroDigit()) {
|
||||||
|
return orNegative(that, val);
|
||||||
|
} else {
|
||||||
|
return orNegative(val, that);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return sign = -1, magnitude = -(positive.magnitude | -negative.magnitude).
|
||||||
|
* @param positive
|
||||||
|
* @param negative
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static BigInteger orDiffSigns(BigInteger positive, BigInteger negative) {
|
||||||
|
// Jumping over the least significant zero bits
|
||||||
|
int iNeg = negative.getFirstNonzeroDigit();
|
||||||
|
int iPos = positive.getFirstNonzeroDigit();
|
||||||
|
int i;
|
||||||
|
int limit;
|
||||||
|
|
||||||
|
// Look if the trailing zeros of the positive will "copy" all
|
||||||
|
// the negative digits
|
||||||
|
if (iPos >= negative.numberLength) {
|
||||||
|
return negative;
|
||||||
|
}
|
||||||
|
int resLength = negative.numberLength;
|
||||||
|
int resDigits[] = new int[resLength];
|
||||||
|
|
||||||
|
if (iNeg < iPos) {
|
||||||
|
// We know for sure that this will
|
||||||
|
// be the first non zero digit in the result
|
||||||
|
for (i = iNeg; i < iPos; i++) {
|
||||||
|
resDigits[i] = negative.digits[i];
|
||||||
|
}
|
||||||
|
} else if (iPos < iNeg) {
|
||||||
|
i = iPos;
|
||||||
|
resDigits[i] = -positive.digits[i];
|
||||||
|
limit = Math.min(positive.numberLength, iNeg);
|
||||||
|
for (i++; i < limit; i++) {
|
||||||
|
resDigits[i] = ~positive.digits[i];
|
||||||
|
}
|
||||||
|
if (i != positive.numberLength) {
|
||||||
|
resDigits[i] = ~(-negative.digits[i] | positive.digits[i]);
|
||||||
|
} else {
|
||||||
|
for (; i < iNeg; i++) {
|
||||||
|
resDigits[i] = -1;
|
||||||
|
}
|
||||||
|
// resDigits[i] = ~(-negative.digits[i] | 0);
|
||||||
|
resDigits[i] = negative.digits[i] - 1;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
// iNeg == iPos
|
||||||
|
// Applying two complement to negative and to result
|
||||||
|
i = iPos;
|
||||||
|
resDigits[i] = -(-negative.digits[i] | positive.digits[i]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
limit = Math.min(negative.numberLength, positive.numberLength);
|
||||||
|
for (; i < limit; i++) {
|
||||||
|
// Applying two complement to negative and to result
|
||||||
|
// resDigits[i] = ~(~negative.digits[i] | positive.digits[i] );
|
||||||
|
resDigits[i] = negative.digits[i] & ~positive.digits[i];
|
||||||
|
}
|
||||||
|
for (; i < negative.numberLength; i++) {
|
||||||
|
resDigits[i] = negative.digits[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInteger result = new BigInteger(-1, resLength, resDigits);
|
||||||
|
result.cutOffLeadingZeroes();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return sign = -1, magnitude = -(-val.magnitude | -that.magnitude).
|
||||||
|
* @param val
|
||||||
|
* @param that
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static BigInteger orNegative(BigInteger val, BigInteger that) {
|
||||||
|
// PRE: val and that are negative;
|
||||||
|
// PRE: val has at least as many trailing zeros digits as that
|
||||||
|
int iThat = that.getFirstNonzeroDigit();
|
||||||
|
int iVal = val.getFirstNonzeroDigit();
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (iVal >= that.numberLength) {
|
||||||
|
return that;
|
||||||
|
} else if (iThat >= val.numberLength) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
int resLength = Math.min(val.numberLength, that.numberLength);
|
||||||
|
int resDigits[] = new int[resLength];
|
||||||
|
|
||||||
|
// Looking for the first non-zero digit of the result
|
||||||
|
if (iThat == iVal) {
|
||||||
|
resDigits[iVal] = -(-val.digits[iVal] | -that.digits[iVal]);
|
||||||
|
i = iVal;
|
||||||
|
} else {
|
||||||
|
for (i = iThat; i < iVal; i++) {
|
||||||
|
resDigits[i] = that.digits[i];
|
||||||
|
}
|
||||||
|
resDigits[i] = that.digits[i] & (val.digits[i] - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i++; i < resLength; i++) {
|
||||||
|
resDigits[i] = val.digits[i] & that.digits[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInteger result = new BigInteger(-1, resLength, resDigits);
|
||||||
|
result.cutOffLeadingZeroes();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return sign = 1, magnitude = longer.magnitude | shorter.magnitude.
|
||||||
|
* @param longer
|
||||||
|
* @param shorter
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static BigInteger orPositive(BigInteger longer, BigInteger shorter) {
|
||||||
|
// PRE: longer and shorter are positive;
|
||||||
|
// PRE: longer has at least as many digits as shorter
|
||||||
|
int resLength = longer.numberLength;
|
||||||
|
int resDigits[] = new int[resLength];
|
||||||
|
|
||||||
|
int i = Math.min(longer.getFirstNonzeroDigit(),
|
||||||
|
shorter.getFirstNonzeroDigit());
|
||||||
|
for (i = 0; i < shorter.numberLength; i++) {
|
||||||
|
resDigits[i] = longer.digits[i] | shorter.digits[i];
|
||||||
|
}
|
||||||
|
for (; i < resLength; i++) {
|
||||||
|
resDigits[i] = longer.digits[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInteger result = new BigInteger(1, resLength, resDigits);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see BigInteger#xor(BigInteger)
|
||||||
|
* @param val
|
||||||
|
* @param that
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static BigInteger xor(BigInteger val, BigInteger that) {
|
||||||
|
if (that.sign == 0) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
if (val.sign == 0) {
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
if (that.equals(BigInteger.MINUS_ONE)) {
|
||||||
|
return val.not();
|
||||||
|
}
|
||||||
|
if (val.equals(BigInteger.MINUS_ONE)) {
|
||||||
|
return that.not();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val.sign > 0) {
|
||||||
|
if (that.sign > 0) {
|
||||||
|
if (val.numberLength > that.numberLength) {
|
||||||
|
return xorPositive(val, that);
|
||||||
|
} else {
|
||||||
|
return xorPositive(that, val);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return xorDiffSigns(val, that);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (that.sign > 0) {
|
||||||
|
return xorDiffSigns(that, val);
|
||||||
|
} else if (that.getFirstNonzeroDigit() > val.getFirstNonzeroDigit()) {
|
||||||
|
return xorNegative(that, val);
|
||||||
|
} else {
|
||||||
|
return xorNegative(val, that);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return sign = 1, magnitude = -(positive.magnitude ^ -negative.magnitude).
|
||||||
|
* @param positive
|
||||||
|
* @param negative
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static BigInteger xorDiffSigns(BigInteger positive, BigInteger negative) {
|
||||||
|
int resLength = Math.max(negative.numberLength, positive.numberLength);
|
||||||
|
int resDigits[];
|
||||||
|
int iNeg = negative.getFirstNonzeroDigit();
|
||||||
|
int iPos = positive.getFirstNonzeroDigit();
|
||||||
|
int i;
|
||||||
|
int limit;
|
||||||
|
|
||||||
|
// The first
|
||||||
|
if (iNeg < iPos) {
|
||||||
|
resDigits = new int[resLength];
|
||||||
|
i = iNeg;
|
||||||
|
// resDigits[i] = -(-negative.digits[i]);
|
||||||
|
resDigits[i] = negative.digits[i];
|
||||||
|
limit = Math.min(negative.numberLength, iPos);
|
||||||
|
// Skip the positive digits while they are zeros
|
||||||
|
for (i++; i < limit; i++) {
|
||||||
|
// resDigits[i] = ~(~negative.digits[i]);
|
||||||
|
resDigits[i] = negative.digits[i];
|
||||||
|
}
|
||||||
|
// if the negative has no more elements, must fill the
|
||||||
|
// result with the remaining digits of the positive
|
||||||
|
if (i == negative.numberLength) {
|
||||||
|
for (; i < positive.numberLength; i++) {
|
||||||
|
// resDigits[i] = ~(positive.digits[i] ^ -1) -> ~(~positive.digits[i])
|
||||||
|
resDigits[i] = positive.digits[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (iPos < iNeg) {
|
||||||
|
resDigits = new int[resLength];
|
||||||
|
i = iPos;
|
||||||
|
// Applying two complement to the first non-zero digit of the result
|
||||||
|
resDigits[i] = -positive.digits[i];
|
||||||
|
limit = Math.min(positive.numberLength, iNeg);
|
||||||
|
for (i++; i < limit; i++) {
|
||||||
|
// Continue applying two complement the result
|
||||||
|
resDigits[i] = ~positive.digits[i];
|
||||||
|
}
|
||||||
|
// When the first non-zero digit of the negative is reached, must apply
|
||||||
|
// two complement (arithmetic negation) to it, and then operate
|
||||||
|
if (i == iNeg) {
|
||||||
|
resDigits[i] = ~(positive.digits[i] ^ -negative.digits[i]);
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
// if the positive has no more elements must fill the remaining digits
|
||||||
|
// with
|
||||||
|
// the negative ones
|
||||||
|
for (; i < iNeg; i++) {
|
||||||
|
// resDigits[i] = ~(0 ^ 0)
|
||||||
|
resDigits[i] = -1;
|
||||||
|
}
|
||||||
|
for (; i < negative.numberLength; i++) {
|
||||||
|
// resDigits[i] = ~(~negative.digits[i] ^ 0)
|
||||||
|
resDigits[i] = negative.digits[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int digit;
|
||||||
|
// The first non-zero digit of the positive and negative are the same
|
||||||
|
i = iNeg;
|
||||||
|
digit = positive.digits[i] ^ -negative.digits[i];
|
||||||
|
if (digit == 0) {
|
||||||
|
limit = Math.min(positive.numberLength, negative.numberLength);
|
||||||
|
for (i++; i < limit
|
||||||
|
&& (digit = positive.digits[i] ^ ~negative.digits[i]) == 0; i++) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
if (digit == 0) {
|
||||||
|
// shorter has only the remaining virtual sign bits
|
||||||
|
for (; i < positive.numberLength
|
||||||
|
&& (digit = ~positive.digits[i]) == 0; i++) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
for (; i < negative.numberLength
|
||||||
|
&& (digit = ~negative.digits[i]) == 0; i++) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
if (digit == 0) {
|
||||||
|
resLength = resLength + 1;
|
||||||
|
resDigits = new int[resLength];
|
||||||
|
resDigits[resLength - 1] = 1;
|
||||||
|
|
||||||
|
BigInteger result = new BigInteger(-1, resLength, resDigits);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resDigits = new int[resLength];
|
||||||
|
resDigits[i] = -digit;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
limit = Math.min(negative.numberLength, positive.numberLength);
|
||||||
|
for (; i < limit; i++) {
|
||||||
|
resDigits[i] = ~(~negative.digits[i] ^ positive.digits[i]);
|
||||||
|
}
|
||||||
|
for (; i < positive.numberLength; i++) {
|
||||||
|
// resDigits[i] = ~(positive.digits[i] ^ -1)
|
||||||
|
resDigits[i] = positive.digits[i];
|
||||||
|
}
|
||||||
|
for (; i < negative.numberLength; i++) {
|
||||||
|
// resDigits[i] = ~(0 ^ ~negative.digits[i])
|
||||||
|
resDigits[i] = negative.digits[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInteger result = new BigInteger(-1, resLength, resDigits);
|
||||||
|
result.cutOffLeadingZeroes();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return sign = 0, magnitude = -val.magnitude ^ -that.magnitude.
|
||||||
|
* @param val
|
||||||
|
* @param that
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static BigInteger xorNegative(BigInteger val, BigInteger that) {
|
||||||
|
// PRE: val and that are negative
|
||||||
|
// PRE: val has at least as many trailing zero digits as that
|
||||||
|
int resLength = Math.max(val.numberLength, that.numberLength);
|
||||||
|
int resDigits[] = new int[resLength];
|
||||||
|
int iVal = val.getFirstNonzeroDigit();
|
||||||
|
int iThat = that.getFirstNonzeroDigit();
|
||||||
|
int i = iThat;
|
||||||
|
int limit;
|
||||||
|
|
||||||
|
if (iVal == iThat) {
|
||||||
|
resDigits[i] = -val.digits[i] ^ -that.digits[i];
|
||||||
|
} else {
|
||||||
|
resDigits[i] = -that.digits[i];
|
||||||
|
limit = Math.min(that.numberLength, iVal);
|
||||||
|
for (i++; i < limit; i++) {
|
||||||
|
resDigits[i] = ~that.digits[i];
|
||||||
|
}
|
||||||
|
// Remains digits in that?
|
||||||
|
if (i == that.numberLength) {
|
||||||
|
// Jumping over the remaining zero to the first non one
|
||||||
|
for (; i < iVal; i++) {
|
||||||
|
// resDigits[i] = 0 ^ -1;
|
||||||
|
resDigits[i] = -1;
|
||||||
|
}
|
||||||
|
// resDigits[i] = -val.digits[i] ^ -1;
|
||||||
|
resDigits[i] = val.digits[i] - 1;
|
||||||
|
} else {
|
||||||
|
resDigits[i] = -val.digits[i] ^ ~that.digits[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
limit = Math.min(val.numberLength, that.numberLength);
|
||||||
|
// Perform ^ between that al val until that ends
|
||||||
|
for (i++; i < limit; i++) {
|
||||||
|
// resDigits[i] = ~val.digits[i] ^ ~that.digits[i];
|
||||||
|
resDigits[i] = val.digits[i] ^ that.digits[i];
|
||||||
|
}
|
||||||
|
// Perform ^ between val digits and -1 until val ends
|
||||||
|
for (; i < val.numberLength; i++) {
|
||||||
|
// resDigits[i] = ~val.digits[i] ^ -1 ;
|
||||||
|
resDigits[i] = val.digits[i];
|
||||||
|
}
|
||||||
|
for (; i < that.numberLength; i++) {
|
||||||
|
// resDigits[i] = -1 ^ ~that.digits[i] ;
|
||||||
|
resDigits[i] = that.digits[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInteger result = new BigInteger(1, resLength, resDigits);
|
||||||
|
result.cutOffLeadingZeroes();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return sign = 0, magnitude = longer.magnitude | shorter.magnitude.
|
||||||
|
*
|
||||||
|
* @param longer
|
||||||
|
* @param shorter
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static BigInteger xorPositive(BigInteger longer, BigInteger shorter) {
|
||||||
|
// PRE: longer and shorter are positive;
|
||||||
|
// PRE: longer has at least as many digits as shorter
|
||||||
|
int resLength = longer.numberLength;
|
||||||
|
int resDigits[] = new int[resLength];
|
||||||
|
int i = Math.min(longer.getFirstNonzeroDigit(),
|
||||||
|
shorter.getFirstNonzeroDigit());
|
||||||
|
for (; i < shorter.numberLength; i++) {
|
||||||
|
resDigits[i] = longer.digits[i] ^ shorter.digits[i];
|
||||||
|
}
|
||||||
|
for (; i < longer.numberLength; i++) {
|
||||||
|
resDigits[i] = longer.digits[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInteger result = new BigInteger(1, resLength, resDigits);
|
||||||
|
result.cutOffLeadingZeroes();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Just to denote that this class can't be instantiated.
|
||||||
|
*/
|
||||||
|
private Logical() {
|
||||||
|
}
|
||||||
|
}
|
313
gwt/jre/java/math/MathContext.java
Normal file
313
gwt/jre/java/math/MathContext.java
Normal file
@ -0,0 +1,313 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Google Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with this
|
||||||
|
* work for additional information regarding copyright ownership. The ASF
|
||||||
|
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*
|
||||||
|
* INCLUDES MODIFICATIONS BY RICHARD ZSCHECH AS WELL AS GOOGLE.
|
||||||
|
*/
|
||||||
|
package java.math;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Immutable objects describing settings such as rounding mode and digit
|
||||||
|
* precision for the numerical operations provided by class {@link BigDecimal}.
|
||||||
|
*/
|
||||||
|
public final class MathContext implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@code MathContext} which corresponds to the IEEE 754r quadruple decimal
|
||||||
|
* precision format: 34 digit precision and {@link RoundingMode#HALF_EVEN}
|
||||||
|
* rounding.
|
||||||
|
*/
|
||||||
|
public static final MathContext DECIMAL128 = new MathContext(34,
|
||||||
|
RoundingMode.HALF_EVEN);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@code MathContext} which corresponds to the IEEE 754r single decimal
|
||||||
|
* precision format: 7 digit precision and {@link RoundingMode#HALF_EVEN}
|
||||||
|
* rounding.
|
||||||
|
*/
|
||||||
|
public static final MathContext DECIMAL32 = new MathContext(7,
|
||||||
|
RoundingMode.HALF_EVEN);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@code MathContext} which corresponds to the IEEE 754r double decimal
|
||||||
|
* precision format: 16 digit precision and {@link RoundingMode#HALF_EVEN}
|
||||||
|
* rounding.
|
||||||
|
*/
|
||||||
|
public static final MathContext DECIMAL64 = new MathContext(16,
|
||||||
|
RoundingMode.HALF_EVEN);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@code MathContext} for unlimited precision with
|
||||||
|
* {@link RoundingMode#HALF_UP} rounding.
|
||||||
|
*/
|
||||||
|
public static final MathContext UNLIMITED = new MathContext(0,
|
||||||
|
RoundingMode.HALF_UP);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array of {@code char} containing: {@code
|
||||||
|
* 'p','r','e','c','i','s','i','o','n','='}. It's used to improve the methods
|
||||||
|
* related to {@code String} conversion.
|
||||||
|
*
|
||||||
|
* @see #MathContext(String)
|
||||||
|
* @see #toString()
|
||||||
|
*/
|
||||||
|
private static final char[] chPrecision = {
|
||||||
|
'p', 'r', 'e', 'c', 'i', 's', 'i', 'o', 'n', '='};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array of {@code char} containing: {@code
|
||||||
|
* 'r','o','u','n','d','i','n','g','M','o','d','e','='}. It's used to improve
|
||||||
|
* the methods related to {@code String} conversion.
|
||||||
|
*
|
||||||
|
* @see #MathContext(String)
|
||||||
|
* @see #toString()
|
||||||
|
*/
|
||||||
|
private static final char[] chRoundingMode = {
|
||||||
|
'r', 'o', 'u', 'n', 'd', 'i', 'n', 'g', 'M', 'o', 'd', 'e', '='};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the serialVersionUID used by the sun implementation.
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 5579720004786848255L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of digits to be used for an operation; results are rounded to
|
||||||
|
* this precision.
|
||||||
|
*/
|
||||||
|
private int precision;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@code RoundingMode} object which specifies the algorithm to be used for
|
||||||
|
* rounding.
|
||||||
|
*/
|
||||||
|
private RoundingMode roundingMode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@code MathContext} with the specified precision and with
|
||||||
|
* the rounding mode {@link RoundingMode#HALF_UP HALF_UP}. If the precision
|
||||||
|
* passed is zero, then this implies that the computations have to be
|
||||||
|
* performed exact, the rounding mode in this case is irrelevant.
|
||||||
|
*
|
||||||
|
* @param precision the precision for the new {@code MathContext}.
|
||||||
|
* @throws IllegalArgumentException if {@code precision < 0}.
|
||||||
|
*/
|
||||||
|
public MathContext(int precision) {
|
||||||
|
this(precision, RoundingMode.HALF_UP);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@code MathContext} with the specified precision and with
|
||||||
|
* the specified rounding mode. If the precision passed is zero, then this
|
||||||
|
* implies that the computations have to be performed exact, the rounding mode
|
||||||
|
* in this case is irrelevant.
|
||||||
|
*
|
||||||
|
* @param precision the precision for the new {@code MathContext}.
|
||||||
|
* @param roundingMode the rounding mode for the new {@code MathContext}.
|
||||||
|
* @throws IllegalArgumentException if {@code precision < 0}.
|
||||||
|
* @throws NullPointerException if {@code roundingMode} is {@code null}.
|
||||||
|
*/
|
||||||
|
public MathContext(int precision, RoundingMode roundingMode) {
|
||||||
|
if (precision < 0) {
|
||||||
|
// math.0C=Digits < 0
|
||||||
|
throw new IllegalArgumentException("Digits < 0"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (roundingMode == null) {
|
||||||
|
// math.0D=null RoundingMode
|
||||||
|
throw new NullPointerException("null RoundingMode"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
this.precision = precision;
|
||||||
|
this.roundingMode = roundingMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@code MathContext} from a string. The string has to
|
||||||
|
* specify the precision and the rounding mode to be used and has to follow
|
||||||
|
* the following syntax:
|
||||||
|
* "precision=<precision> roundingMode=<roundingMode>" This is the
|
||||||
|
* same form as the one returned by the {@link #toString} method.
|
||||||
|
*
|
||||||
|
* @param val a string describing the precision and rounding mode for the new
|
||||||
|
* {@code MathContext}.
|
||||||
|
* @throws IllegalArgumentException if the string is not in the correct format
|
||||||
|
* or if the precision specified is < 0.
|
||||||
|
*/
|
||||||
|
public MathContext(String val) {
|
||||||
|
if (val == null) {
|
||||||
|
throw new NullPointerException("null string");
|
||||||
|
}
|
||||||
|
char[] charVal = val.toCharArray();
|
||||||
|
int i; // Index of charVal
|
||||||
|
int j; // Index of chRoundingMode
|
||||||
|
int digit; // It will contain the digit parsed
|
||||||
|
|
||||||
|
if ((charVal.length < 27) || (charVal.length > 45)) {
|
||||||
|
// math.0E=bad string format
|
||||||
|
throw new IllegalArgumentException("bad string format"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
// Parsing "precision=" String
|
||||||
|
for (i = 0; (i < chPrecision.length) && (charVal[i] == chPrecision[i]); i++) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < chPrecision.length) {
|
||||||
|
// math.0E=bad string format
|
||||||
|
throw new IllegalArgumentException("bad string format"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
// Parsing the value for "precision="...
|
||||||
|
digit = Character.digit(charVal[i], 10);
|
||||||
|
if (digit == -1) {
|
||||||
|
// math.0E=bad string format
|
||||||
|
throw new IllegalArgumentException("bad string format"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
this.precision = this.precision * 10 + digit;
|
||||||
|
i++;
|
||||||
|
|
||||||
|
do {
|
||||||
|
digit = Character.digit(charVal[i], 10);
|
||||||
|
if (digit == -1) {
|
||||||
|
if (charVal[i] == ' ') {
|
||||||
|
// It parsed all the digits
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// It isn't a valid digit, and isn't a white space
|
||||||
|
// math.0E=bad string format
|
||||||
|
throw new IllegalArgumentException("bad string format"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
// Accumulating the value parsed
|
||||||
|
this.precision = this.precision * 10 + digit;
|
||||||
|
if (this.precision < 0) {
|
||||||
|
// math.0E=bad string format
|
||||||
|
throw new IllegalArgumentException("bad string format"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
} while (true);
|
||||||
|
// Parsing "roundingMode="
|
||||||
|
for (j = 0; (j < chRoundingMode.length)
|
||||||
|
&& (charVal[i] == chRoundingMode[j]); i++, j++) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j < chRoundingMode.length) {
|
||||||
|
// math.0E=bad string format
|
||||||
|
throw new IllegalArgumentException("bad string format"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parsing the value for "roundingMode"...
|
||||||
|
/*
|
||||||
|
* don't use implicit calls to RoundingMode.valueOf here, since it will break
|
||||||
|
* if enum name obfuscation is enabled.
|
||||||
|
*/
|
||||||
|
this.roundingMode = RoundingMode.valueOfExplicit(String.valueOf(charVal, i,
|
||||||
|
charVal.length - i));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Public Methods */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if x is a {@code MathContext} with the same precision setting
|
||||||
|
* and the same rounding mode as this {@code MathContext} instance.
|
||||||
|
*
|
||||||
|
* @param x object to be compared.
|
||||||
|
* @return {@code true} if this {@code MathContext} instance is equal to the
|
||||||
|
* {@code x} argument; {@code false} otherwise.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object x) {
|
||||||
|
return ((x instanceof MathContext)
|
||||||
|
&& (((MathContext) x).getPrecision() == precision)
|
||||||
|
&& (((MathContext) x).getRoundingMode() == roundingMode));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the precision. The precision is the number of digits used for an
|
||||||
|
* operation. Results are rounded to this precision. The precision is
|
||||||
|
* guaranteed to be non negative. If the precision is zero, then the
|
||||||
|
* computations have to be performed exact, results are not rounded in this
|
||||||
|
* case.
|
||||||
|
*
|
||||||
|
* @return the precision.
|
||||||
|
*/
|
||||||
|
public int getPrecision() {
|
||||||
|
return precision;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the rounding mode. The rounding mode is the strategy to be used to
|
||||||
|
* round results.
|
||||||
|
* <p>
|
||||||
|
* The rounding mode is one of {@link RoundingMode#UP},
|
||||||
|
* {@link RoundingMode#DOWN}, {@link RoundingMode#CEILING},
|
||||||
|
* {@link RoundingMode#FLOOR}, {@link RoundingMode#HALF_UP},
|
||||||
|
* {@link RoundingMode#HALF_DOWN}, {@link RoundingMode#HALF_EVEN}, or
|
||||||
|
* {@link RoundingMode#UNNECESSARY}.
|
||||||
|
*
|
||||||
|
* @return the rounding mode.
|
||||||
|
*/
|
||||||
|
public RoundingMode getRoundingMode() {
|
||||||
|
return roundingMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the hash code for this {@code MathContext} instance.
|
||||||
|
*
|
||||||
|
* @return the hash code for this {@code MathContext}.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
// Make place for the necessary bits to represent 8 rounding modes
|
||||||
|
return ((precision << 3) | roundingMode.ordinal());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the string representation for this {@code MathContext} instance.
|
||||||
|
* The string has the form {@code
|
||||||
|
* "precision=<precision> roundingMode=<roundingMode>" * } where
|
||||||
|
* {@code <precision>} is an integer describing the number of digits
|
||||||
|
* used for operations and {@code <roundingMode>} is the string
|
||||||
|
* representation of the rounding mode.
|
||||||
|
*
|
||||||
|
* @return a string representation for this {@code MathContext} instance
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb = new StringBuilder(45);
|
||||||
|
|
||||||
|
sb.append(chPrecision);
|
||||||
|
sb.append(precision);
|
||||||
|
sb.append(' ');
|
||||||
|
sb.append(chRoundingMode);
|
||||||
|
sb.append(roundingMode);
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
534
gwt/jre/java/math/Multiplication.java
Normal file
534
gwt/jre/java/math/Multiplication.java
Normal file
@ -0,0 +1,534 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Google Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with this
|
||||||
|
* work for additional information regarding copyright ownership. The ASF
|
||||||
|
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*
|
||||||
|
* INCLUDES MODIFICATIONS BY RICHARD ZSCHECH AS WELL AS GOOGLE.
|
||||||
|
*/
|
||||||
|
package java.math;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static library that provides all multiplication of {@link BigInteger}
|
||||||
|
* methods.
|
||||||
|
*/
|
||||||
|
class Multiplication {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array with the first powers of five in {@code BigInteger} version. (
|
||||||
|
* {@code 5^0,5^1,...,5^31})
|
||||||
|
*/
|
||||||
|
static final BigInteger bigFivePows[] = new BigInteger[32];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array with the first powers of ten in {@code BigInteger} version. (
|
||||||
|
* {@code 10^0,10^1,...,10^31})
|
||||||
|
*/
|
||||||
|
static final BigInteger[] bigTenPows = new BigInteger[32];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array with powers of five that fit in the type {@code int}. ({@code
|
||||||
|
* 5^0,5^1,...,5^13})
|
||||||
|
*/
|
||||||
|
static final int fivePows[] = {
|
||||||
|
1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625,
|
||||||
|
48828125, 244140625, 1220703125};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array with powers of ten that fit in the type {@code int}. ({@code
|
||||||
|
* 10^0,10^1,...,10^9})
|
||||||
|
*/
|
||||||
|
static final int tenPows[] = {
|
||||||
|
1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Break point in digits (number of {@code int} elements) between Karatsuba
|
||||||
|
* and Pencil and Paper multiply.
|
||||||
|
*/
|
||||||
|
static final int whenUseKaratsuba = 63; // an heuristic value
|
||||||
|
|
||||||
|
static {
|
||||||
|
int i;
|
||||||
|
long fivePow = 1L;
|
||||||
|
|
||||||
|
for (i = 0; i <= 18; i++) {
|
||||||
|
bigFivePows[i] = BigInteger.valueOf(fivePow);
|
||||||
|
bigTenPows[i] = BigInteger.valueOf(fivePow << i);
|
||||||
|
fivePow *= 5;
|
||||||
|
}
|
||||||
|
for (; i < bigTenPows.length; i++) {
|
||||||
|
bigFivePows[i] = bigFivePows[i - 1].multiply(bigFivePows[1]);
|
||||||
|
bigTenPows[i] = bigTenPows[i - 1].multiply(BigInteger.TEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the multiplication with the Karatsuba's algorithm. <b>Karatsuba's
|
||||||
|
* algorithm:</b> <tt>
|
||||||
|
* u = u<sub>1</sub> * B + u<sub>0</sub><br>
|
||||||
|
* v = v<sub>1</sub> * B + v<sub>0</sub><br>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* u*v = (u<sub>1</sub> * v<sub>1</sub>) * B<sub>2</sub> + ((u<sub>1</sub> - u<sub>0</sub>) * (v<sub>0</sub> - v<sub>1</sub>) + u<sub>1</sub> * v<sub>1</sub> +
|
||||||
|
* u<sub>0</sub> * v<sub>0</sub> ) * B + u<sub>0</sub> * v<sub>0</sub><br>
|
||||||
|
*</tt>
|
||||||
|
*
|
||||||
|
* @param op1 first factor of the product
|
||||||
|
* @param op2 second factor of the product
|
||||||
|
* @return {@code op1 * op2}
|
||||||
|
* @see #multiply(BigInteger, BigInteger)
|
||||||
|
*/
|
||||||
|
static BigInteger karatsuba(BigInteger op1, BigInteger op2) {
|
||||||
|
BigInteger temp;
|
||||||
|
if (op2.numberLength > op1.numberLength) {
|
||||||
|
temp = op1;
|
||||||
|
op1 = op2;
|
||||||
|
op2 = temp;
|
||||||
|
}
|
||||||
|
if (op2.numberLength < whenUseKaratsuba) {
|
||||||
|
return multiplyPAP(op1, op2);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Karatsuba: u = u1*B + u0 v = v1*B + v0 u*v = (u1*v1)*B^2 +
|
||||||
|
* ((u1-u0)*(v0-v1) + u1*v1 + u0*v0)*B + u0*v0
|
||||||
|
*/
|
||||||
|
// ndiv2 = (op1.numberLength / 2) * 32
|
||||||
|
int ndiv2 = (op1.numberLength & 0xFFFFFFFE) << 4;
|
||||||
|
BigInteger upperOp1 = op1.shiftRight(ndiv2);
|
||||||
|
BigInteger upperOp2 = op2.shiftRight(ndiv2);
|
||||||
|
BigInteger lowerOp1 = op1.subtract(upperOp1.shiftLeft(ndiv2));
|
||||||
|
BigInteger lowerOp2 = op2.subtract(upperOp2.shiftLeft(ndiv2));
|
||||||
|
|
||||||
|
BigInteger upper = karatsuba(upperOp1, upperOp2);
|
||||||
|
BigInteger lower = karatsuba(lowerOp1, lowerOp2);
|
||||||
|
BigInteger middle = karatsuba(upperOp1.subtract(lowerOp1),
|
||||||
|
lowerOp2.subtract(upperOp2));
|
||||||
|
middle = middle.add(upper).add(lower);
|
||||||
|
middle = middle.shiftLeft(ndiv2);
|
||||||
|
upper = upper.shiftLeft(ndiv2 << 1);
|
||||||
|
|
||||||
|
return upper.add(middle).add(lower);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void multArraysPAP(int[] aDigits, int aLen, int[] bDigits, int bLen,
|
||||||
|
int[] resDigits) {
|
||||||
|
if (aLen == 0 || bLen == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aLen == 1) {
|
||||||
|
resDigits[bLen] = multiplyByInt(resDigits, bDigits, bLen, aDigits[0]);
|
||||||
|
} else if (bLen == 1) {
|
||||||
|
resDigits[aLen] = multiplyByInt(resDigits, aDigits, aLen, bDigits[0]);
|
||||||
|
} else {
|
||||||
|
multPAP(aDigits, bDigits, resDigits, aLen, bLen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs a multiplication of two BigInteger and hides the algorithm used.
|
||||||
|
*
|
||||||
|
* @see BigInteger#multiply(BigInteger)
|
||||||
|
*/
|
||||||
|
static BigInteger multiply(BigInteger x, BigInteger y) {
|
||||||
|
return karatsuba(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiplies a number by a power of five. This method is used in {@code
|
||||||
|
* BigDecimal} class.
|
||||||
|
*
|
||||||
|
* @param val the number to be multiplied
|
||||||
|
* @param exp a positive {@code int} exponent
|
||||||
|
* @return {@code val * 5<sup>exp</sup>}
|
||||||
|
*/
|
||||||
|
static BigInteger multiplyByFivePow(BigInteger val, int exp) {
|
||||||
|
// PRE: exp >= 0
|
||||||
|
if (exp < fivePows.length) {
|
||||||
|
return multiplyByPositiveInt(val, fivePows[exp]);
|
||||||
|
} else if (exp < bigFivePows.length) {
|
||||||
|
return val.multiply(bigFivePows[exp]);
|
||||||
|
} else {
|
||||||
|
// Large powers of five
|
||||||
|
return val.multiply(bigFivePows[1].pow(exp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiplies an array of integers by an integer value.
|
||||||
|
*
|
||||||
|
* @param a the array of integers
|
||||||
|
* @param aSize the number of elements of intArray to be multiplied
|
||||||
|
* @param factor the multiplier
|
||||||
|
* @return the top digit of production
|
||||||
|
*/
|
||||||
|
static int multiplyByInt(int a[], final int aSize, final int factor) {
|
||||||
|
return multiplyByInt(a, a, aSize, factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiplies a number by a positive integer.
|
||||||
|
*
|
||||||
|
* @param val an arbitrary {@code BigInteger}
|
||||||
|
* @param factor a positive {@code int} number
|
||||||
|
* @return {@code val * factor}
|
||||||
|
*/
|
||||||
|
static BigInteger multiplyByPositiveInt(BigInteger val, int factor) {
|
||||||
|
int resSign = val.sign;
|
||||||
|
if (resSign == 0) {
|
||||||
|
return BigInteger.ZERO;
|
||||||
|
}
|
||||||
|
int aNumberLength = val.numberLength;
|
||||||
|
int[] aDigits = val.digits;
|
||||||
|
|
||||||
|
if (aNumberLength == 1) {
|
||||||
|
long res = unsignedMultAddAdd(aDigits[0], factor, 0, 0);
|
||||||
|
int resLo = (int) res;
|
||||||
|
int resHi = (int) (res >>> 32);
|
||||||
|
return ((resHi == 0) ? new BigInteger(resSign, resLo) : new BigInteger(
|
||||||
|
resSign, 2, new int[] {resLo, resHi}));
|
||||||
|
}
|
||||||
|
// Common case
|
||||||
|
int resLength = aNumberLength + 1;
|
||||||
|
int resDigits[] = new int[resLength];
|
||||||
|
|
||||||
|
resDigits[aNumberLength] = multiplyByInt(resDigits, aDigits, aNumberLength,
|
||||||
|
factor);
|
||||||
|
BigInteger result = new BigInteger(resSign, resLength, resDigits);
|
||||||
|
result.cutOffLeadingZeroes();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiplies a number by a power of ten. This method is used in {@code
|
||||||
|
* BigDecimal} class.
|
||||||
|
*
|
||||||
|
* @param val the number to be multiplied
|
||||||
|
* @param exp a positive {@code long} exponent
|
||||||
|
* @return {@code val * 10<sup>exp</sup>}
|
||||||
|
*/
|
||||||
|
static BigInteger multiplyByTenPow(BigInteger val, int exp) {
|
||||||
|
// PRE: exp >= 0
|
||||||
|
return ((exp < tenPows.length) ? multiplyByPositiveInt(val,
|
||||||
|
tenPows[(int) exp]) : val.multiply(powerOf10(exp)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiplies two BigIntegers. Implements traditional scholar algorithm
|
||||||
|
* described by Knuth.
|
||||||
|
*
|
||||||
|
* <br>
|
||||||
|
* <tt>
|
||||||
|
* <table border="0">
|
||||||
|
* <tbody>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* <tr>
|
||||||
|
* <td align="center">A=</td>
|
||||||
|
* <td>a<sub>3</sub></td>
|
||||||
|
* <td>a<sub>2</sub></td>
|
||||||
|
* <td>a<sub>1</sub></td>
|
||||||
|
* <td>a<sub>0</sub></td>
|
||||||
|
* <td></td>
|
||||||
|
* <td></td>
|
||||||
|
* </tr>
|
||||||
|
*
|
||||||
|
* <tr>
|
||||||
|
* <td align="center">B=</td>
|
||||||
|
* <td></td>
|
||||||
|
* <td>b<sub>2</sub></td>
|
||||||
|
* <td>b<sub>1</sub></td>
|
||||||
|
* <td>b<sub>1</sub></td>
|
||||||
|
* <td></td>
|
||||||
|
* <td></td>
|
||||||
|
* </tr>
|
||||||
|
*
|
||||||
|
* <tr>
|
||||||
|
* <td></td>
|
||||||
|
* <td></td>
|
||||||
|
* <td></td>
|
||||||
|
* <td>b<sub>0</sub>*a<sub>3</sub></td>
|
||||||
|
* <td>b<sub>0</sub>*a<sub>2</sub></td>
|
||||||
|
* <td>b<sub>0</sub>*a<sub>1</sub></td>
|
||||||
|
* <td>b<sub>0</sub>*a<sub>0</sub></td>
|
||||||
|
* </tr>
|
||||||
|
*
|
||||||
|
* <tr>
|
||||||
|
* <td></td>
|
||||||
|
* <td></td>
|
||||||
|
* <td>b<sub>1</sub>*a<sub>3</sub></td>
|
||||||
|
* <td>b<sub>1</sub>*a<sub>2</sub></td>
|
||||||
|
* <td>b<sub>1</sub>*a1</td>
|
||||||
|
* <td>b<sub>1</sub>*a0</td>
|
||||||
|
* </tr>
|
||||||
|
*
|
||||||
|
* <tr>
|
||||||
|
* <td>+</td>
|
||||||
|
* <td>b<sub>2</sub>*a<sub>3</sub></td>
|
||||||
|
* <td>b<sub>2</sub>*a<sub>2</sub></td>
|
||||||
|
* <td>b<sub>2</sub>*a<sub>1</sub></td>
|
||||||
|
* <td>b<sub>2</sub>*a<sub>0</sub></td>
|
||||||
|
* </tr>
|
||||||
|
*
|
||||||
|
* <tr>
|
||||||
|
* <td></td>
|
||||||
|
* <td>______</td>
|
||||||
|
* <td>______</td>
|
||||||
|
* <td>______</td>
|
||||||
|
* <td>______</td>
|
||||||
|
* <td>______</td>
|
||||||
|
* <td>______</td>
|
||||||
|
* </tr>
|
||||||
|
*
|
||||||
|
* <tr>
|
||||||
|
*
|
||||||
|
* <td align="center">A*B=R=</td>
|
||||||
|
* <td align="center">r<sub>5</sub></td>
|
||||||
|
* <td align="center">r<sub>4</sub></td>
|
||||||
|
* <td align="center">r<sub>3</sub></td>
|
||||||
|
* <td align="center">r<sub>2</sub></td>
|
||||||
|
* <td align="center">r<sub>1</sub></td>
|
||||||
|
* <td align="center">r<sub>0</sub></td>
|
||||||
|
* <td></td>
|
||||||
|
* </tr>
|
||||||
|
*
|
||||||
|
* </tbody>
|
||||||
|
* </table>
|
||||||
|
*
|
||||||
|
*</tt>
|
||||||
|
*
|
||||||
|
* @param op1 first factor of the multiplication {@code op1 >= 0}
|
||||||
|
* @param op2 second factor of the multiplication {@code op2 >= 0}
|
||||||
|
* @return a {@code BigInteger} of value {@code op1 * op2}
|
||||||
|
*/
|
||||||
|
static BigInteger multiplyPAP(BigInteger a, BigInteger b) {
|
||||||
|
// PRE: a >= b
|
||||||
|
int aLen = a.numberLength;
|
||||||
|
int bLen = b.numberLength;
|
||||||
|
int resLength = aLen + bLen;
|
||||||
|
int resSign = (a.sign != b.sign) ? -1 : 1;
|
||||||
|
// A special case when both numbers don't exceed int
|
||||||
|
if (resLength == 2) {
|
||||||
|
long val = unsignedMultAddAdd(a.digits[0], b.digits[0], 0, 0);
|
||||||
|
int valueLo = (int) val;
|
||||||
|
int valueHi = (int) (val >>> 32);
|
||||||
|
return ((valueHi == 0) ? new BigInteger(resSign, valueLo)
|
||||||
|
: new BigInteger(resSign, 2, new int[] {valueLo, valueHi}));
|
||||||
|
}
|
||||||
|
int[] aDigits = a.digits;
|
||||||
|
int[] bDigits = b.digits;
|
||||||
|
int resDigits[] = new int[resLength];
|
||||||
|
// Common case
|
||||||
|
multArraysPAP(aDigits, aLen, bDigits, bLen, resDigits);
|
||||||
|
BigInteger result = new BigInteger(resSign, resLength, resDigits);
|
||||||
|
result.cutOffLeadingZeroes();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void multPAP(int a[], int b[], int t[], int aLen, int bLen) {
|
||||||
|
if (a == b && aLen == bLen) {
|
||||||
|
square(a, aLen, t);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < aLen; i++) {
|
||||||
|
long carry = 0;
|
||||||
|
int aI = a[i];
|
||||||
|
for (int j = 0; j < bLen; j++) {
|
||||||
|
carry = unsignedMultAddAdd(aI, b[j], t[i + j], (int) carry);
|
||||||
|
t[i + j] = (int) carry;
|
||||||
|
carry >>>= 32;
|
||||||
|
}
|
||||||
|
t[i + bLen] = (int) carry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static BigInteger pow(BigInteger base, int exponent) {
|
||||||
|
// PRE: exp > 0
|
||||||
|
BigInteger res = BigInteger.ONE;
|
||||||
|
BigInteger acc = base;
|
||||||
|
|
||||||
|
for (; exponent > 1; exponent >>= 1) {
|
||||||
|
if ((exponent & 1) != 0) {
|
||||||
|
// if odd, multiply one more time by acc
|
||||||
|
res = res.multiply(acc);
|
||||||
|
}
|
||||||
|
// acc = base^(2^i)
|
||||||
|
// a limit where karatsuba performs a faster square than the square
|
||||||
|
// algorithm
|
||||||
|
if (acc.numberLength == 1) {
|
||||||
|
acc = acc.multiply(acc); // square
|
||||||
|
} else {
|
||||||
|
acc = new BigInteger(1, square(acc.digits, acc.numberLength,
|
||||||
|
new int[acc.numberLength << 1]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// exponent == 1, multiply one more time
|
||||||
|
res = res.multiply(acc);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* It calculates a power of ten, which exponent could be out of 32-bit range.
|
||||||
|
* Note that internally this method will be used in the worst case with an
|
||||||
|
* exponent equals to: {@code Integer.MAX_VALUE - Integer.MIN_VALUE}.
|
||||||
|
*
|
||||||
|
* @param exp the exponent of power of ten, it must be positive.
|
||||||
|
* @return a {@code BigInteger} with value {@code 10<sup>exp</sup>}.
|
||||||
|
*/
|
||||||
|
static BigInteger powerOf10(double exp) {
|
||||||
|
// PRE: exp >= 0
|
||||||
|
int intExp = (int) exp;
|
||||||
|
// "SMALL POWERS"
|
||||||
|
if (exp < bigTenPows.length) {
|
||||||
|
// The largest power that fit in 'long' type
|
||||||
|
return bigTenPows[intExp];
|
||||||
|
} else if (exp <= 50) {
|
||||||
|
// To calculate: 10^exp
|
||||||
|
return BigInteger.TEN.pow(intExp);
|
||||||
|
} else if (exp <= 1000) {
|
||||||
|
// To calculate: 5^exp * 2^exp
|
||||||
|
return bigFivePows[1].pow(intExp).shiftLeft(intExp);
|
||||||
|
}
|
||||||
|
// "LARGE POWERS"
|
||||||
|
/*
|
||||||
|
* To check if there is free memory to allocate a BigInteger of the
|
||||||
|
* estimated size, measured in bytes: 1 + [exp / log10(2)]
|
||||||
|
*/
|
||||||
|
if (exp > 1000000) {
|
||||||
|
throw new ArithmeticException("power of ten too big"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exp <= Integer.MAX_VALUE) {
|
||||||
|
// To calculate: 5^exp * 2^exp
|
||||||
|
return bigFivePows[1].pow(intExp).shiftLeft(intExp);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* "HUGE POWERS"
|
||||||
|
*
|
||||||
|
* This branch probably won't be executed since the power of ten is too big.
|
||||||
|
*/
|
||||||
|
// To calculate: 5^exp
|
||||||
|
BigInteger powerOfFive = bigFivePows[1].pow(Integer.MAX_VALUE);
|
||||||
|
BigInteger res = powerOfFive;
|
||||||
|
long longExp = (long) (exp - Integer.MAX_VALUE);
|
||||||
|
|
||||||
|
intExp = (int) (exp % Integer.MAX_VALUE);
|
||||||
|
while (longExp > Integer.MAX_VALUE) {
|
||||||
|
res = res.multiply(powerOfFive);
|
||||||
|
longExp -= Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
res = res.multiply(bigFivePows[1].pow(intExp));
|
||||||
|
// To calculate: 5^exp << exp
|
||||||
|
res = res.shiftLeft(Integer.MAX_VALUE);
|
||||||
|
longExp = (long) (exp - Integer.MAX_VALUE);
|
||||||
|
while (longExp > Integer.MAX_VALUE) {
|
||||||
|
res = res.shiftLeft(Integer.MAX_VALUE);
|
||||||
|
longExp -= Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
res = res.shiftLeft(intExp);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs a<sup>2</sup>.
|
||||||
|
*
|
||||||
|
* @param a The number to square.
|
||||||
|
* @param aLen The length of the number to square.
|
||||||
|
*/
|
||||||
|
static int[] square(int[] a, int aLen, int[] res) {
|
||||||
|
long carry;
|
||||||
|
|
||||||
|
for (int i = 0; i < aLen; i++) {
|
||||||
|
carry = 0;
|
||||||
|
for (int j = i + 1; j < aLen; j++) {
|
||||||
|
carry = unsignedMultAddAdd(a[i], a[j], res[i + j], (int) carry);
|
||||||
|
res[i + j] = (int) carry;
|
||||||
|
carry >>>= 32;
|
||||||
|
}
|
||||||
|
res[i + aLen] = (int) carry;
|
||||||
|
}
|
||||||
|
|
||||||
|
BitLevel.shiftLeftOneBit(res, res, aLen << 1);
|
||||||
|
|
||||||
|
carry = 0;
|
||||||
|
for (int i = 0, index = 0; i < aLen; i++, index++) {
|
||||||
|
carry = unsignedMultAddAdd(a[i], a[i], res[index], (int) carry);
|
||||||
|
res[index] = (int) carry;
|
||||||
|
carry >>>= 32;
|
||||||
|
index++;
|
||||||
|
carry += res[index] & 0xFFFFFFFFL;
|
||||||
|
res[index] = (int) carry;
|
||||||
|
carry >>>= 32;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the value unsigned ((uint)a*(uint)b + (uint)c + (uint)d). This
|
||||||
|
* method could improve the readability and performance of the code.
|
||||||
|
*
|
||||||
|
* @param a parameter 1
|
||||||
|
* @param b parameter 2
|
||||||
|
* @param c parameter 3
|
||||||
|
* @param d parameter 4
|
||||||
|
* @return value of expression
|
||||||
|
*/
|
||||||
|
static long unsignedMultAddAdd(int a, int b, int c, int d) {
|
||||||
|
return (a & 0xFFFFFFFFL) * (b & 0xFFFFFFFFL) + (c & 0xFFFFFFFFL)
|
||||||
|
+ (d & 0xFFFFFFFFL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiplies an array of integers by an integer value and saves the result in
|
||||||
|
* {@code res}.
|
||||||
|
*
|
||||||
|
* @param a the array of integers
|
||||||
|
* @param aSize the number of elements of intArray to be multiplied
|
||||||
|
* @param factor the multiplier
|
||||||
|
* @return the top digit of production
|
||||||
|
*/
|
||||||
|
private static int multiplyByInt(int res[], int a[], final int aSize,
|
||||||
|
final int factor) {
|
||||||
|
long carry = 0;
|
||||||
|
for (int i = 0; i < aSize; i++) {
|
||||||
|
carry = unsignedMultAddAdd(a[i], factor, (int) carry, 0);
|
||||||
|
res[i] = (int) carry;
|
||||||
|
carry >>>= 32;
|
||||||
|
}
|
||||||
|
return (int) carry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Just to denote that this class can't be instantiated.
|
||||||
|
*/
|
||||||
|
private Multiplication() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
303
gwt/jre/java/math/Primality.java
Normal file
303
gwt/jre/java/math/Primality.java
Normal file
@ -0,0 +1,303 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Google Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with this
|
||||||
|
* work for additional information regarding copyright ownership. The ASF
|
||||||
|
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*
|
||||||
|
* INCLUDES MODIFICATIONS BY RICHARD ZSCHECH AS WELL AS GOOGLE.
|
||||||
|
*/
|
||||||
|
package java.math;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides primality probabilistic methods.
|
||||||
|
*/
|
||||||
|
class Primality {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* It encodes how many iterations of Miller-Rabin test are need to get an
|
||||||
|
* error bound not greater than {@code 2<sup>(-100)</sup>}. For example: for a
|
||||||
|
* {@code 1000}-bit number we need {@code 4} iterations, since {@code BITS[3]
|
||||||
|
* < 1000 <= BITS[4]}.
|
||||||
|
*/
|
||||||
|
private static final int[] BITS = {
|
||||||
|
0, 0, 1854, 1233, 927, 747, 627, 543, 480, 431, 393, 361, 335, 314, 295,
|
||||||
|
279, 265, 253, 242, 232, 223, 216, 181, 169, 158, 150, 145, 140, 136,
|
||||||
|
132, 127, 123, 119, 114, 110, 105, 101, 96, 92, 87, 83, 78, 73, 69, 64,
|
||||||
|
59, 54, 49, 44, 38, 32, 26, 1};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* It encodes how many i-bit primes there are in the table for {@code
|
||||||
|
* i=2,...,10}. For example {@code offsetPrimes[6]} says that from index
|
||||||
|
* {@code 11} exists {@code 7} consecutive {@code 6}-bit prime numbers in the
|
||||||
|
* array.
|
||||||
|
*/
|
||||||
|
private static final int[][] offsetPrimes = {
|
||||||
|
null, null, {0, 2}, {2, 2}, {4, 2}, {6, 5}, {11, 7}, {18, 13}, {31, 23},
|
||||||
|
{54, 43}, {97, 75}};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All prime numbers with bit length lesser than 10 bits.
|
||||||
|
*/
|
||||||
|
private static final int primes[] = {
|
||||||
|
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67,
|
||||||
|
71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149,
|
||||||
|
151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227,
|
||||||
|
229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307,
|
||||||
|
311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389,
|
||||||
|
397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467,
|
||||||
|
479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571,
|
||||||
|
577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653,
|
||||||
|
659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751,
|
||||||
|
757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853,
|
||||||
|
857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947,
|
||||||
|
953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All {@code BigInteger} prime numbers with bit length lesser than 8 bits.
|
||||||
|
*/
|
||||||
|
private static final BigInteger BIprimes[] = new BigInteger[primes.length];
|
||||||
|
|
||||||
|
static {
|
||||||
|
// To initialize the dual table of BigInteger primes
|
||||||
|
for (int i = 0; i < primes.length; i++) {
|
||||||
|
BIprimes[i] = BigInteger.valueOf(primes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A random number is generated until a probable prime number is found.
|
||||||
|
*
|
||||||
|
* @see BigInteger#BigInteger(int,int,Random)
|
||||||
|
* @see BigInteger#probablePrime(int,Random)
|
||||||
|
* @see #isProbablePrime(BigInteger, int)
|
||||||
|
*/
|
||||||
|
static BigInteger consBigInteger(int bitLength, int certainty, Random rnd) {
|
||||||
|
// PRE: bitLength >= 2;
|
||||||
|
// For small numbers get a random prime from the prime table
|
||||||
|
if (bitLength <= 10) {
|
||||||
|
int rp[] = offsetPrimes[bitLength];
|
||||||
|
return BIprimes[rp[0] + rnd.nextInt(rp[1])];
|
||||||
|
}
|
||||||
|
int shiftCount = (-bitLength) & 31;
|
||||||
|
int last = (bitLength + 31) >> 5;
|
||||||
|
BigInteger n = new BigInteger(1, last, new int[last]);
|
||||||
|
|
||||||
|
last--;
|
||||||
|
do {
|
||||||
|
// To fill the array with random integers
|
||||||
|
for (int i = 0; i < n.numberLength; i++) {
|
||||||
|
n.digits[i] = rnd.nextInt();
|
||||||
|
}
|
||||||
|
// To fix to the correct bitLength
|
||||||
|
n.digits[last] |= 0x80000000;
|
||||||
|
n.digits[last] >>>= shiftCount;
|
||||||
|
// To create an odd number
|
||||||
|
n.digits[0] |= 1;
|
||||||
|
} while (!isProbablePrime(n, certainty));
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see BigInteger#isProbablePrime(int)
|
||||||
|
* @see #millerRabin(BigInteger, int)
|
||||||
|
* @ar.org.fitc.ref Optimizations: "A. Menezes - Handbook of applied
|
||||||
|
* Cryptography, Chapter 4".
|
||||||
|
*/
|
||||||
|
static boolean isProbablePrime(BigInteger n, int certainty) {
|
||||||
|
// PRE: n >= 0;
|
||||||
|
if ((certainty <= 0) || ((n.numberLength == 1) && (n.digits[0] == 2))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// To discard all even numbers
|
||||||
|
if (!n.testBit(0)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// To check if 'n' exists in the table (it fit in 10 bits)
|
||||||
|
if ((n.numberLength == 1) && ((n.digits[0] & 0XFFFFFC00) == 0)) {
|
||||||
|
return (Arrays.binarySearch(primes, n.digits[0]) >= 0);
|
||||||
|
}
|
||||||
|
// To check if 'n' is divisible by some prime of the table
|
||||||
|
for (int i = 1; i < primes.length; i++) {
|
||||||
|
if (Division.remainderArrayByInt(n.digits, n.numberLength, primes[i]) == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// To set the number of iterations necessary for Miller-Rabin test
|
||||||
|
int i;
|
||||||
|
int bitLength = n.bitLength();
|
||||||
|
|
||||||
|
for (i = 2; bitLength < BITS[i]; i++) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
certainty = Math.min(i, 1 + ((certainty - 1) >> 1));
|
||||||
|
|
||||||
|
return millerRabin(n, certainty);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* It uses the sieve of Eratosthenes to discard several composite numbers in
|
||||||
|
* some appropriate range (at the moment {@code [this, this + 1024]}). After
|
||||||
|
* this process it applies the Miller-Rabin test to the numbers that were not
|
||||||
|
* discarded in the sieve.
|
||||||
|
*
|
||||||
|
* @see BigInteger#nextProbablePrime()
|
||||||
|
* @see #millerRabin(BigInteger, int)
|
||||||
|
*/
|
||||||
|
static BigInteger nextProbablePrime(BigInteger n) {
|
||||||
|
// PRE: n >= 0
|
||||||
|
int i, j;
|
||||||
|
int certainty;
|
||||||
|
int gapSize = 1024; // for searching of the next probable prime number
|
||||||
|
int modules[] = new int[primes.length];
|
||||||
|
boolean isDivisible[] = new boolean[gapSize];
|
||||||
|
BigInteger startPoint;
|
||||||
|
BigInteger probPrime;
|
||||||
|
// If n < "last prime of table" searches next prime in the table
|
||||||
|
if ((n.numberLength == 1) && (n.digits[0] >= 0)
|
||||||
|
&& (n.digits[0] < primes[primes.length - 1])) {
|
||||||
|
for (i = 0; n.digits[0] >= primes[i]; i++) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
return BIprimes[i];
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Creates a "N" enough big to hold the next probable prime Note that: N <
|
||||||
|
* "next prime" < 2*N
|
||||||
|
*/
|
||||||
|
startPoint = new BigInteger(1, n.numberLength, new int[n.numberLength + 1]);
|
||||||
|
System.arraycopy(n.digits, 0, startPoint.digits, 0, n.numberLength);
|
||||||
|
// To fix N to the "next odd number"
|
||||||
|
if (n.testBit(0)) {
|
||||||
|
Elementary.inplaceAdd(startPoint, 2);
|
||||||
|
} else {
|
||||||
|
startPoint.digits[0] |= 1;
|
||||||
|
}
|
||||||
|
// To set the improved certainly of Miller-Rabin
|
||||||
|
j = startPoint.bitLength();
|
||||||
|
for (certainty = 2; j < BITS[certainty]; certainty++) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
// To calculate modules: N mod p1, N mod p2, ... for first primes.
|
||||||
|
for (i = 0; i < primes.length; i++) {
|
||||||
|
modules[i] = Division.remainder(startPoint, primes[i]) - gapSize;
|
||||||
|
}
|
||||||
|
while (true) {
|
||||||
|
// At this point, all numbers in the gap are initialized as
|
||||||
|
// probably primes
|
||||||
|
Arrays.fill(isDivisible, false);
|
||||||
|
// To discard multiples of first primes
|
||||||
|
for (i = 0; i < primes.length; i++) {
|
||||||
|
modules[i] = (modules[i] + gapSize) % primes[i];
|
||||||
|
j = (modules[i] == 0) ? 0 : (primes[i] - modules[i]);
|
||||||
|
for (; j < gapSize; j += primes[i]) {
|
||||||
|
isDivisible[j] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// To execute Miller-Rabin for non-divisible numbers by all first
|
||||||
|
// primes
|
||||||
|
for (j = 0; j < gapSize; j++) {
|
||||||
|
if (!isDivisible[j]) {
|
||||||
|
probPrime = startPoint.copy();
|
||||||
|
Elementary.inplaceAdd(probPrime, j);
|
||||||
|
|
||||||
|
if (millerRabin(probPrime, certainty)) {
|
||||||
|
return probPrime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Elementary.inplaceAdd(startPoint, gapSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Miller-Rabin primality test.
|
||||||
|
*
|
||||||
|
* @param n the input number to be tested.
|
||||||
|
* @param t the number of trials.
|
||||||
|
* @return {@code false} if the number is definitely compose, otherwise
|
||||||
|
* {@code true} with probability {@code 1 - 4<sup>(-t)</sup>}.
|
||||||
|
* @ar.org.fitc.ref "D. Knuth, The Art of Computer Programming Vo.2, Section
|
||||||
|
* 4.5.4., Algorithm P"
|
||||||
|
*/
|
||||||
|
private static boolean millerRabin(BigInteger n, int t) {
|
||||||
|
// PRE: n >= 0, t >= 0
|
||||||
|
BigInteger x; // x := UNIFORM{2...n-1}
|
||||||
|
BigInteger y; // y := x^(q * 2^j) mod n
|
||||||
|
BigInteger nMinus1 = n.subtract(BigInteger.ONE); // n-1
|
||||||
|
int bitLength = nMinus1.bitLength(); // ~ log2(n-1)
|
||||||
|
// (q,k) such that: n-1 = q * 2^k and q is odd
|
||||||
|
int k = nMinus1.getLowestSetBit();
|
||||||
|
BigInteger q = nMinus1.shiftRight(k);
|
||||||
|
Random rnd = new Random();
|
||||||
|
|
||||||
|
for (int i = 0; i < t; i++) {
|
||||||
|
// To generate a witness 'x', first it use the primes of table
|
||||||
|
if (i < primes.length) {
|
||||||
|
x = BIprimes[i];
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* It generates random witness only if it's necesssary. Note that all
|
||||||
|
* methods would call Miller-Rabin with t <= 50 so this part is only to
|
||||||
|
* do more robust the algorithm
|
||||||
|
*/
|
||||||
|
do {
|
||||||
|
x = new BigInteger(bitLength, rnd);
|
||||||
|
} while ((x.compareTo(n) >= BigInteger.EQUALS) || (x.sign == 0)
|
||||||
|
|| x.isOne());
|
||||||
|
}
|
||||||
|
y = x.modPow(q, n);
|
||||||
|
if (y.isOne() || y.equals(nMinus1)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (int j = 1; j < k; j++) {
|
||||||
|
if (y.equals(nMinus1)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
y = y.multiply(y).mod(n);
|
||||||
|
if (y.isOne()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!y.equals(nMinus1)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Just to denote that this class can't be instantiated.
|
||||||
|
*/
|
||||||
|
private Primality() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
214
gwt/jre/java/math/RoundingMode.java
Normal file
214
gwt/jre/java/math/RoundingMode.java
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Google Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with this
|
||||||
|
* work for additional information regarding copyright ownership. The ASF
|
||||||
|
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*
|
||||||
|
* INCLUDES MODIFICATIONS BY RICHARD ZSCHECH AS WELL AS GOOGLE.
|
||||||
|
*/
|
||||||
|
package java.math;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the rounding behavior for operations whose results cannot be
|
||||||
|
* represented exactly.
|
||||||
|
*/
|
||||||
|
public enum RoundingMode {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rounding mode where positive values are rounded towards positive infinity
|
||||||
|
* and negative values towards negative infinity. <br>
|
||||||
|
* Rule: {@code x.round().abs() >= x.abs()}
|
||||||
|
*/
|
||||||
|
UP(BigDecimal.ROUND_UP),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rounding mode where the values are rounded towards zero. <br>
|
||||||
|
* Rule: {@code x.round().abs() <= x.abs()}
|
||||||
|
*/
|
||||||
|
DOWN(BigDecimal.ROUND_DOWN),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rounding mode to round towards positive infinity. For positive values this
|
||||||
|
* rounding mode behaves as {@link #UP}, for negative values as {@link #DOWN}. <br>
|
||||||
|
* Rule: {@code x.round() >= x}
|
||||||
|
*/
|
||||||
|
CEILING(BigDecimal.ROUND_CEILING),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rounding mode to round towards negative infinity. For positive values this
|
||||||
|
* rounding mode behaves as {@link #DOWN}, for negative values as {@link #UP}. <br>
|
||||||
|
* Rule: {@code x.round() <= x}
|
||||||
|
*/
|
||||||
|
FLOOR(BigDecimal.ROUND_FLOOR),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rounding mode where values are rounded towards the nearest neighbor. Ties
|
||||||
|
* are broken by rounding up.
|
||||||
|
*/
|
||||||
|
HALF_UP(BigDecimal.ROUND_HALF_UP),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rounding mode where values are rounded towards the nearest neighbor. Ties
|
||||||
|
* are broken by rounding down.
|
||||||
|
*/
|
||||||
|
HALF_DOWN(BigDecimal.ROUND_HALF_DOWN),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rounding mode where values are rounded towards the nearest neighbor. Ties
|
||||||
|
* are broken by rounding to the even neighbor.
|
||||||
|
*/
|
||||||
|
HALF_EVEN(BigDecimal.ROUND_HALF_EVEN),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rounding mode where the rounding operations throws an ArithmeticException
|
||||||
|
* for the case that rounding is necessary, i.e. for the case that the value
|
||||||
|
* cannot be represented exactly.
|
||||||
|
*/
|
||||||
|
UNNECESSARY(BigDecimal.ROUND_UNNECESSARY);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some constant char arrays for optimized comparisons
|
||||||
|
*/
|
||||||
|
private static final char[] chCEILING = {'C','E','I','L','I','N','G'};
|
||||||
|
private static final char[] chDOWN = {'D','O','W','N'};
|
||||||
|
private static final char[] chFLOOR = {'F','L','O','O','R'};
|
||||||
|
private static final char[] chHALF_DOWN = {'H','A','L','F','_','D','O','W','N'};
|
||||||
|
private static final char[] chHALF_EVEN = {'H','A','L','F','_','E','V','E','N'};
|
||||||
|
private static final char[] chHALF_UP = {'H','A','L','F','_','U','P'};
|
||||||
|
private static final char[] chUNNECESSARY = {'U','N','N','E','C','E','S','S','A','R','Y'};
|
||||||
|
private static final char[] chUP = {'U','P'};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts rounding mode constants from class {@code BigDecimal} into {@code
|
||||||
|
* RoundingMode} values.
|
||||||
|
*
|
||||||
|
* @param mode rounding mode constant as defined in class {@code BigDecimal}
|
||||||
|
* @return corresponding rounding mode object
|
||||||
|
*/
|
||||||
|
public static RoundingMode valueOf(int mode) {
|
||||||
|
switch (mode) {
|
||||||
|
case BigDecimal.ROUND_CEILING:
|
||||||
|
return CEILING;
|
||||||
|
case BigDecimal.ROUND_DOWN:
|
||||||
|
return DOWN;
|
||||||
|
case BigDecimal.ROUND_FLOOR:
|
||||||
|
return FLOOR;
|
||||||
|
case BigDecimal.ROUND_HALF_DOWN:
|
||||||
|
return HALF_DOWN;
|
||||||
|
case BigDecimal.ROUND_HALF_EVEN:
|
||||||
|
return HALF_EVEN;
|
||||||
|
case BigDecimal.ROUND_HALF_UP:
|
||||||
|
return HALF_UP;
|
||||||
|
case BigDecimal.ROUND_UNNECESSARY:
|
||||||
|
return UNNECESSARY;
|
||||||
|
case BigDecimal.ROUND_UP:
|
||||||
|
return UP;
|
||||||
|
default:
|
||||||
|
// math.00=Invalid rounding mode
|
||||||
|
throw new IllegalArgumentException("Invalid rounding mode"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bypasses calls to the implicit valueOf(String) method, which will break
|
||||||
|
* if enum name obfuscation is enabled. This should be package visible only.
|
||||||
|
*
|
||||||
|
* @param mode rounding mode string as defined in class {@code BigDecimal}
|
||||||
|
* @return corresponding rounding mode object
|
||||||
|
*/
|
||||||
|
static RoundingMode valueOfExplicit(String mode) {
|
||||||
|
/*
|
||||||
|
* Note this is optimized to avoid multiple String compares,
|
||||||
|
* using specific knowledge of the set of allowed enum constants.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (mode == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
|
||||||
|
char[] modeChars = mode.toCharArray();
|
||||||
|
int len = modeChars.length;
|
||||||
|
if (len < chUP.length || len > chUNNECESSARY.length) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
char[] targetChars = null;
|
||||||
|
RoundingMode target = null;
|
||||||
|
if (modeChars[0] == 'C') {
|
||||||
|
target = RoundingMode.CEILING;
|
||||||
|
targetChars = chCEILING;
|
||||||
|
} else if (modeChars[0] == 'D') {
|
||||||
|
target = RoundingMode.DOWN;
|
||||||
|
targetChars = chDOWN;
|
||||||
|
} else if (modeChars[0] == 'F') {
|
||||||
|
target = RoundingMode.FLOOR;
|
||||||
|
targetChars = chFLOOR;
|
||||||
|
} else if (modeChars[0] == 'H') {
|
||||||
|
if (len > 6) {
|
||||||
|
if (modeChars[5] == 'D') {
|
||||||
|
target = RoundingMode.HALF_DOWN;
|
||||||
|
targetChars = chHALF_DOWN;
|
||||||
|
} else if (modeChars[5] == 'E') {
|
||||||
|
target = RoundingMode.HALF_EVEN;
|
||||||
|
targetChars = chHALF_EVEN;
|
||||||
|
} else if (modeChars[5] == 'U') {
|
||||||
|
target = RoundingMode.HALF_UP;
|
||||||
|
targetChars = chHALF_UP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (modeChars[0] == 'U') {
|
||||||
|
if (modeChars[1] == 'P') {
|
||||||
|
target = RoundingMode.UP;
|
||||||
|
targetChars = chUP;
|
||||||
|
} else if (modeChars[1] == 'N') {
|
||||||
|
target = RoundingMode.UNNECESSARY;
|
||||||
|
targetChars = chUNNECESSARY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target != null && len == targetChars.length) {
|
||||||
|
int i;
|
||||||
|
for (i = 1; i < len && modeChars[i] == targetChars[i]; i++) {
|
||||||
|
}
|
||||||
|
if (i == len) {
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the old constant.
|
||||||
|
* @param rm unused
|
||||||
|
*/
|
||||||
|
RoundingMode(int rm) {
|
||||||
|
// Note that we do not need the old-style rounding mode, so we ignore it.
|
||||||
|
}
|
||||||
|
}
|
21
gwt/jre/java/net/UnknownServiceException.java
Normal file
21
gwt/jre/java/net/UnknownServiceException.java
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package java.net;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class UnknownServiceException extends IOException {
|
||||||
|
|
||||||
|
public UnknownServiceException() {
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnknownServiceException(String s) {
|
||||||
|
super(s);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnknownServiceException(Exception e) {
|
||||||
|
super(e);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
121
gwt/jre/java/security/SecureRandom.java
Normal file
121
gwt/jre/java/security/SecureRandom.java
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
package java.security;
|
||||||
|
|
||||||
|
import com.google.gwt.core.client.JsArrayInteger;
|
||||||
|
|
||||||
|
public class SecureRandom extends java.util.Random
|
||||||
|
{
|
||||||
|
private static final double twoToThe24 = 16777216.0;
|
||||||
|
private static final double twoToThe31 = 2147483648.0;
|
||||||
|
private static final double twoToThe32 = 4294967296.0;
|
||||||
|
private static final double twoToTheMinus24 =
|
||||||
|
5.9604644775390625e-8;
|
||||||
|
private static final double twoToTheMinus26 =
|
||||||
|
1.490116119384765625e-8;
|
||||||
|
private static final double twoToTheMinus31 =
|
||||||
|
4.656612873077392578125e-10;
|
||||||
|
private static final double twoToTheMinus53 =
|
||||||
|
1.1102230246251565404236316680908203125e-16;
|
||||||
|
|
||||||
|
protected native JsArrayInteger jsNextChunk() /*-{
|
||||||
|
var words = $wnd.sjcl.random.randomWords(4);
|
||||||
|
return words;
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
public int next(int numBits)
|
||||||
|
{
|
||||||
|
int numBytes = (numBits+7)/8;
|
||||||
|
byte[] bytes = new byte[numBytes];
|
||||||
|
nextBytes(bytes);
|
||||||
|
|
||||||
|
int result=0;
|
||||||
|
for (int i=0; i<numBytes; ++i)
|
||||||
|
{
|
||||||
|
result |= bytes[i] << (8 * i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void nextBytes(byte[] bytes)
|
||||||
|
{
|
||||||
|
final int chunkSize = 4;
|
||||||
|
int chunks = (bytes.length+(chunkSize-1)) / chunkSize;
|
||||||
|
|
||||||
|
int j=0;
|
||||||
|
for (int i=0; i<chunks; ++i)
|
||||||
|
{
|
||||||
|
JsArrayInteger a = jsNextChunk();
|
||||||
|
int k=0;
|
||||||
|
while (j < bytes.length && k < chunkSize)
|
||||||
|
bytes[j++] = (byte)(a.get(k++));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean nextBoolean ()
|
||||||
|
{
|
||||||
|
return next(1) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int nextInt(int max)
|
||||||
|
{
|
||||||
|
return (int) next(32) % max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long nextLong()
|
||||||
|
{
|
||||||
|
return ((long) next(32) << 32) + (long) next(32);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double nextDouble() {
|
||||||
|
return
|
||||||
|
next(26) * twoToTheMinus26 +
|
||||||
|
next(27) * twoToTheMinus53;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float nextFloat() {
|
||||||
|
return (float) (next(24) * twoToTheMinus24);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Test {
|
||||||
|
public static double test() {
|
||||||
|
// create random number generators
|
||||||
|
SecureRandom rand = new SecureRandom();
|
||||||
|
|
||||||
|
// total number of sample points to take
|
||||||
|
int numPoints = 10000;
|
||||||
|
|
||||||
|
int inRandCircle = 0;
|
||||||
|
double xr, yr, zr;
|
||||||
|
// xr and yr will be the random point
|
||||||
|
// zr will be the calculated distance to the center
|
||||||
|
|
||||||
|
for(int i=0; i < numPoints; ++i)
|
||||||
|
{
|
||||||
|
xr = rand.nextDouble();
|
||||||
|
yr = rand.nextDouble();
|
||||||
|
|
||||||
|
zr = (xr * xr) + (yr * yr);
|
||||||
|
if(zr <= 1.0)
|
||||||
|
inRandCircle++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate the Pi approximations
|
||||||
|
double randomPi = approxPi(inRandCircle, numPoints);
|
||||||
|
|
||||||
|
// calculate the % error
|
||||||
|
double randomError = calcError(randomPi);
|
||||||
|
|
||||||
|
return randomError;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double approxPi(int inCircle, int totalPoints)
|
||||||
|
{
|
||||||
|
return (double)inCircle / totalPoints * 4.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double calcError(double pi)
|
||||||
|
{
|
||||||
|
return (pi - Math.PI)/Math.PI * 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
109
gwt/jre/java/util/Hashtable.java
Normal file
109
gwt/jre/java/util/Hashtable.java
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2007 Google Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
package java.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements a hash table, which maps non-null keys to non-null values.
|
||||||
|
*
|
||||||
|
* @deprecated use @see{java.util.HashMap} instead
|
||||||
|
* @link http://java.sun.com/j2se/1.5.0/docs/api/java/util/Hashtable.html
|
||||||
|
*
|
||||||
|
* @param <K> key type.
|
||||||
|
* @param <V> value type.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public class Hashtable<K,V> implements Map<K,V>,
|
||||||
|
Cloneable {
|
||||||
|
/*
|
||||||
|
* This implementation simply delegates to HashMap.
|
||||||
|
*/
|
||||||
|
|
||||||
|
private HashMap<K,V> map;
|
||||||
|
|
||||||
|
public Hashtable() {
|
||||||
|
map = new HashMap<K,V>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Hashtable clone ()
|
||||||
|
{
|
||||||
|
Hashtable<K,V> c = new Hashtable<K,V>();
|
||||||
|
for (Map.Entry<K,V> e : map.entrySet())
|
||||||
|
c.put(e.getKey(), e.getValue());
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Hashtable(int initialSize) {
|
||||||
|
map = new HashMap<K,V>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
map.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsKey(Object key) {
|
||||||
|
return map.containsKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsValue(Object value) {
|
||||||
|
return map.containsValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Enumeration<V> elements() {
|
||||||
|
return Collections.enumeration(map.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Map.Entry<K, V>> entrySet() {
|
||||||
|
return map.entrySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public V get(Object key) {
|
||||||
|
return map.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return map.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Enumeration<K> keys() {
|
||||||
|
return Collections.enumeration(map.keySet());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<K> keySet() {
|
||||||
|
return map.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public V put(K key, V value) {
|
||||||
|
return map.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void putAll(Map<? extends K,? extends V> otherMap) {
|
||||||
|
map.putAll(otherMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
public V remove(Object key) {
|
||||||
|
return map.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return map.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<V> values() {
|
||||||
|
return map.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
5
gwt/jre/java/util/Properties.java
Normal file
5
gwt/jre/java/util/Properties.java
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package java.util;
|
||||||
|
|
||||||
|
public class Properties {
|
||||||
|
|
||||||
|
}
|
201
gwt/jre/java/util/StringTokenizer.java
Normal file
201
gwt/jre/java/util/StringTokenizer.java
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package java.util;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String tokenizer is used to break a string apart into tokens.
|
||||||
|
*
|
||||||
|
* If returnDelimiters is false, successive calls to nextToken() return maximal
|
||||||
|
* blocks of characters that do not contain a delimiter.
|
||||||
|
*
|
||||||
|
* If returnDelimiters is true, delimiters are considered to be tokens, and
|
||||||
|
* successive calls to nextToken() return either a one character delimiter, or a
|
||||||
|
* maximal block of text between delimiters.
|
||||||
|
*/
|
||||||
|
public class StringTokenizer {
|
||||||
|
|
||||||
|
private String string;
|
||||||
|
|
||||||
|
private String delimiters;
|
||||||
|
|
||||||
|
private boolean returnDelimiters;
|
||||||
|
|
||||||
|
private int position;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new StringTokenizer for string using whitespace as the
|
||||||
|
* delimiter, returnDelimiters is false.
|
||||||
|
*
|
||||||
|
* @param string
|
||||||
|
* the string to be tokenized
|
||||||
|
*/
|
||||||
|
public StringTokenizer(String string) {
|
||||||
|
this(string, " \t\n\r\f", false); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new StringTokenizer for string using the specified
|
||||||
|
* delimiters, returnDelimiters is false.
|
||||||
|
*
|
||||||
|
* @param string
|
||||||
|
* the string to be tokenized
|
||||||
|
* @param delimiters
|
||||||
|
* the delimiters to use
|
||||||
|
*/
|
||||||
|
public StringTokenizer(String string, String delimiters) {
|
||||||
|
this(string, delimiters, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new StringTokenizer for string using the specified
|
||||||
|
* delimiters and returning delimiters as tokens when specified.
|
||||||
|
*
|
||||||
|
* @param string
|
||||||
|
* the string to be tokenized
|
||||||
|
* @param delimiters
|
||||||
|
* the delimiters to use
|
||||||
|
* @param returnDelimiters
|
||||||
|
* true to return each delimiter as a token
|
||||||
|
*/
|
||||||
|
public StringTokenizer(String string, String delimiters,
|
||||||
|
boolean returnDelimiters) {
|
||||||
|
if (string != null) {
|
||||||
|
this.string = string;
|
||||||
|
this.delimiters = delimiters;
|
||||||
|
this.returnDelimiters = returnDelimiters;
|
||||||
|
this.position = 0;
|
||||||
|
} else
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of unprocessed tokens remaining in the string.
|
||||||
|
*
|
||||||
|
* @return number of tokens that can be retreived before an exception will
|
||||||
|
* result
|
||||||
|
*/
|
||||||
|
public int countTokens() {
|
||||||
|
int count = 0;
|
||||||
|
boolean inToken = false;
|
||||||
|
for (int i = position, length = string.length(); i < length; i++) {
|
||||||
|
if (delimiters.indexOf(string.charAt(i), 0) >= 0) {
|
||||||
|
if (returnDelimiters)
|
||||||
|
count++;
|
||||||
|
if (inToken) {
|
||||||
|
count++;
|
||||||
|
inToken = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
inToken = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (inToken)
|
||||||
|
count++;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if unprocessed tokens remain.
|
||||||
|
*
|
||||||
|
* @return true if unprocessed tokens remain
|
||||||
|
*/
|
||||||
|
public boolean hasMoreElements() {
|
||||||
|
return hasMoreTokens();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if unprocessed tokens remain.
|
||||||
|
*
|
||||||
|
* @return true if unprocessed tokens remain
|
||||||
|
*/
|
||||||
|
public boolean hasMoreTokens() {
|
||||||
|
int length = string.length();
|
||||||
|
if (position < length) {
|
||||||
|
if (returnDelimiters)
|
||||||
|
return true; // there is at least one character and even if
|
||||||
|
// it is a delimiter it is a token
|
||||||
|
|
||||||
|
// otherwise find a character which is not a delimiter
|
||||||
|
for (int i = position; i < length; i++)
|
||||||
|
if (delimiters.indexOf(string.charAt(i), 0) == -1)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the next token in the string as an Object.
|
||||||
|
*
|
||||||
|
* @return next token in the string as an Object
|
||||||
|
* @exception NoSuchElementException
|
||||||
|
* if no tokens remain
|
||||||
|
*/
|
||||||
|
public Object nextElement() {
|
||||||
|
return nextToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the next token in the string as a String.
|
||||||
|
*
|
||||||
|
* @return next token in the string as a String
|
||||||
|
* @exception NoSuchElementException
|
||||||
|
* if no tokens remain
|
||||||
|
*/
|
||||||
|
public String nextToken() {
|
||||||
|
int i = position;
|
||||||
|
int length = string.length();
|
||||||
|
|
||||||
|
if (i < length) {
|
||||||
|
if (returnDelimiters) {
|
||||||
|
if (delimiters.indexOf(string.charAt(position), 0) >= 0)
|
||||||
|
return String.valueOf(string.charAt(position++));
|
||||||
|
for (position++; position < length; position++)
|
||||||
|
if (delimiters.indexOf(string.charAt(position), 0) >= 0)
|
||||||
|
return string.substring(i, position);
|
||||||
|
return string.substring(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i < length && delimiters.indexOf(string.charAt(i), 0) >= 0)
|
||||||
|
i++;
|
||||||
|
position = i;
|
||||||
|
if (i < length) {
|
||||||
|
for (position++; position < length; position++)
|
||||||
|
if (delimiters.indexOf(string.charAt(position), 0) >= 0)
|
||||||
|
return string.substring(i, position);
|
||||||
|
return string.substring(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new NoSuchElementException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the next token in the string as a String. The delimiters used are
|
||||||
|
* changed to the specified delimiters.
|
||||||
|
*
|
||||||
|
* @param delims
|
||||||
|
* the new delimiters to use
|
||||||
|
* @return next token in the string as a String
|
||||||
|
* @exception NoSuchElementException
|
||||||
|
* if no tokens remain
|
||||||
|
*/
|
||||||
|
public String nextToken(String delims) {
|
||||||
|
this.delimiters = delims;
|
||||||
|
return nextToken();
|
||||||
|
}
|
||||||
|
}
|
12
gwt/src/app/GWT.gwt.xml
Normal file
12
gwt/src/app/GWT.gwt.xml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
When updating your version of GWT, you should also update this DTD reference,
|
||||||
|
so that your app can take advantage of the latest GWT module capabilities.
|
||||||
|
-->
|
||||||
|
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.5.0//EN"
|
||||||
|
"http://google-web-toolkit.googlecode.com/svn/tags/2.5.0/distro-source/core/src/gwt-module.dtd">
|
||||||
|
<module>
|
||||||
|
<!-- Specify the paths for translatable code -->
|
||||||
|
<source path=''/>
|
||||||
|
|
||||||
|
</module>
|
21
gwt/src/app/service/AsyncException.java
Normal file
21
gwt/src/app/service/AsyncException.java
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* Author: Timothy Prepscius
|
||||||
|
* License: GPLv3 Affero + keep my name in the code!
|
||||||
|
*/
|
||||||
|
package app.service;
|
||||||
|
|
||||||
|
import org.timepedia.exporter.client.Export;
|
||||||
|
import org.timepedia.exporter.client.Exportable;
|
||||||
|
|
||||||
|
@Export()
|
||||||
|
public class AsyncException extends Exception implements Exportable {
|
||||||
|
|
||||||
|
public AsyncException() {
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncException(String message) {
|
||||||
|
super(message);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
}
|
19
gwt/src/app/service/JSApplet.java
Normal file
19
gwt/src/app/service/JSApplet.java
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* Author: Timothy Prepscius
|
||||||
|
* License: GPLv3 Affero + keep my name in the code!
|
||||||
|
*/
|
||||||
|
package app.service;
|
||||||
|
|
||||||
|
import com.google.gwt.core.client.JavaScriptObject;
|
||||||
|
|
||||||
|
public class JSApplet {
|
||||||
|
|
||||||
|
// public void paint( Graphics g ) {
|
||||||
|
// g.drawString(VERSION_STRING,4,15);
|
||||||
|
// }
|
||||||
|
|
||||||
|
static public native JavaScriptObject getWindow(Object o) /*-{
|
||||||
|
return $wnd;
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
}
|
1
gwt/src/app/service/JSClient.java
Symbolic link
1
gwt/src/app/service/JSClient.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/app/service/src/app/service/JSClient.java
|
103
gwt/src/app/service/JSDelete.java
Normal file
103
gwt/src/app/service/JSDelete.java
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/**
|
||||||
|
* Author: Timothy Prepscius
|
||||||
|
* License: GPLv3 Affero + keep my name in the code!
|
||||||
|
*/
|
||||||
|
package app.service;
|
||||||
|
|
||||||
|
import org.timepedia.exporter.client.Export;
|
||||||
|
import org.timepedia.exporter.client.Exportable;
|
||||||
|
|
||||||
|
import mail.auth.MailServerAuthenticatorNoThread;
|
||||||
|
import mail.client.EventPropagator;
|
||||||
|
import core.callback.CallbackChain;
|
||||||
|
import core.callback.CallbackDefault;
|
||||||
|
import core.callback.CallbackWithVariables;
|
||||||
|
import core.constants.ConstantsClient;
|
||||||
|
import core.crypt.KeyPairFromPassword;
|
||||||
|
import core.srp.client.SRPClientListener;
|
||||||
|
import core.util.LogNull;
|
||||||
|
|
||||||
|
@Export
|
||||||
|
public class JSDelete implements Exportable, SRPClientListener
|
||||||
|
{
|
||||||
|
static LogNull log = new LogNull(JSDelete.class);
|
||||||
|
|
||||||
|
Main main;
|
||||||
|
|
||||||
|
JSDelete (Main main)
|
||||||
|
{
|
||||||
|
this.main = main;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class DeleteInfo
|
||||||
|
{
|
||||||
|
String name, password;
|
||||||
|
KeyPairFromPassword keyPair;
|
||||||
|
JSResult<Boolean> callback;
|
||||||
|
|
||||||
|
public DeleteInfo(String name, String password, JSResult<Boolean> callback)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
this.password = password;
|
||||||
|
this.callback = callback;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doDelete (
|
||||||
|
String name, String password,
|
||||||
|
Object callback
|
||||||
|
)
|
||||||
|
{
|
||||||
|
log.debug("delete", name, password);
|
||||||
|
|
||||||
|
CallbackChain chain = new CallbackChain();
|
||||||
|
|
||||||
|
DeleteInfo info = new DeleteInfo(name, password, new JSResult<Boolean>(callback));
|
||||||
|
|
||||||
|
chain.addCallback(new CallbackDefault(info) {
|
||||||
|
public void onSuccess(Object... arguments) throws Exception {
|
||||||
|
log.debug("delete_step_genKeyPair");
|
||||||
|
|
||||||
|
DeleteInfo info = (DeleteInfo)V(0);
|
||||||
|
JSInvoker.invoke(info.callback.getCallback(), "progress", new Object[] { "Creating verification key pair." });
|
||||||
|
info.keyPair = new KeyPairFromPassword(info.password);
|
||||||
|
info.keyPair.generate_().addCallback(callback).invoke();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
chain.addCallback(new CallbackDefault(info) {
|
||||||
|
public void onSuccess(Object... arguments) throws Exception {
|
||||||
|
log.debug("delete_step_doDelete");
|
||||||
|
|
||||||
|
DeleteInfo info = (DeleteInfo)V(0);
|
||||||
|
JSInvoker.invoke(info.callback.getCallback(), "progress", new Object[] { "Deleting account." });
|
||||||
|
|
||||||
|
call(
|
||||||
|
MailServerAuthenticatorNoThread.delete_(
|
||||||
|
info.name, info.keyPair,
|
||||||
|
new JSStreamSessionWebSocket(ConstantsClient.MAIL_SERVER_WEBSOCKET, main.delegate),
|
||||||
|
JSDelete.this
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
chain.addCallback(new CallbackWithVariables(info) {
|
||||||
|
@Override
|
||||||
|
public void invoke(Object... arguments) {
|
||||||
|
DeleteInfo info = (DeleteInfo)V(0);
|
||||||
|
info.callback.invoke(arguments);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
main.eventPropagator.signal(
|
||||||
|
EventPropagator.INVOKE,
|
||||||
|
chain
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onSRPStep (String event)
|
||||||
|
{
|
||||||
|
main.eventPropagator.signal("onAuthenticationStep", event);
|
||||||
|
}
|
||||||
|
}
|
1
gwt/src/app/service/JSEventPropagator.java
Symbolic link
1
gwt/src/app/service/JSEventPropagator.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/app/service/src/app/service/JSEventPropagator.java
|
1
gwt/src/app/service/JSHttpDelegate.java
Symbolic link
1
gwt/src/app/service/JSHttpDelegate.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/app/service/src/app/service/JSHttpDelegate.java
|
377
gwt/src/app/service/JSInvoker.java
Normal file
377
gwt/src/app/service/JSInvoker.java
Normal file
@ -0,0 +1,377 @@
|
|||||||
|
/**
|
||||||
|
* Author: Timothy Prepscius
|
||||||
|
* License: GPLv3 Affero + keep my name in the code!
|
||||||
|
*/
|
||||||
|
package app.service;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import mail.client.model.Mail;
|
||||||
|
|
||||||
|
import org.timepedia.exporter.client.Export;
|
||||||
|
import org.timepedia.exporter.client.Exportable;
|
||||||
|
import org.timepedia.exporter.client.ExporterUtil;
|
||||||
|
|
||||||
|
import com.google.gwt.core.client.GWT;
|
||||||
|
import com.google.gwt.core.client.JavaScriptObject;
|
||||||
|
import com.google.gwt.core.client.JsArray;
|
||||||
|
|
||||||
|
import core.util.LogNull;
|
||||||
|
import core.util.LogOut;
|
||||||
|
|
||||||
|
@Export
|
||||||
|
public class JSInvoker implements Exportable
|
||||||
|
{
|
||||||
|
static LogNull log = new LogNull(JSInvoker.class);
|
||||||
|
|
||||||
|
private static native JavaScriptObject _wrap(boolean o) /*-{
|
||||||
|
return o;
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
private static native JavaScriptObject _wrap(int o) /*-{
|
||||||
|
return o;
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
private static native JavaScriptObject _wrap(String o) /*-{
|
||||||
|
return o;
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
private static JsArray<JavaScriptObject> _wrap(Object[] o)
|
||||||
|
{
|
||||||
|
JsArray<JavaScriptObject> a = JavaScriptObject.createArray().cast();
|
||||||
|
for (Object i : o)
|
||||||
|
a.push(wrap(i));
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
static public JavaScriptObject wrap(Object o)
|
||||||
|
{
|
||||||
|
if (o instanceof Boolean)
|
||||||
|
return _wrap((boolean)(Boolean)o);
|
||||||
|
else
|
||||||
|
if (o instanceof Integer)
|
||||||
|
return _wrap((int)(Integer)o);
|
||||||
|
else
|
||||||
|
if (o instanceof String)
|
||||||
|
return _wrap((String)o);
|
||||||
|
else
|
||||||
|
if (o instanceof Object[])
|
||||||
|
return _wrap((Object[])o);
|
||||||
|
else
|
||||||
|
if (o instanceof Collection)
|
||||||
|
return _wrap(((Collection<?>)o).toArray());
|
||||||
|
else
|
||||||
|
if (o instanceof Mail)
|
||||||
|
return wrap(new MailI((Mail)o));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return ExporterUtil.wrap(o);
|
||||||
|
}
|
||||||
|
catch (Throwable e)
|
||||||
|
{
|
||||||
|
log.debug(e);
|
||||||
|
return (JavaScriptObject)o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static JavaScriptObject invoke (Object oo, String f, Object[] p) throws Exception
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return doInvoke(oo, f, p);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
catch (Throwable t)
|
||||||
|
{
|
||||||
|
throw new Exception(t.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static JavaScriptObject doInvoke (Object oo, String f, Object[] p) throws Throwable
|
||||||
|
{
|
||||||
|
JavaScriptObject o = (JavaScriptObject)oo;
|
||||||
|
|
||||||
|
if (p == null || p.length == 0)
|
||||||
|
return invoke0(o,f);
|
||||||
|
else
|
||||||
|
if (p.length == 1)
|
||||||
|
return invoke1(o,f,
|
||||||
|
wrap(p[0])
|
||||||
|
);
|
||||||
|
else
|
||||||
|
if (p.length == 2)
|
||||||
|
return invoke2(o,f,
|
||||||
|
wrap(p[0]),
|
||||||
|
wrap(p[1])
|
||||||
|
);
|
||||||
|
else
|
||||||
|
if (p.length == 3)
|
||||||
|
return invoke3(o,f,
|
||||||
|
wrap(p[0]),
|
||||||
|
wrap(p[1]),
|
||||||
|
wrap(p[2])
|
||||||
|
);
|
||||||
|
else
|
||||||
|
if (p.length == 4)
|
||||||
|
return invoke4(o,f,
|
||||||
|
wrap(p[0]),
|
||||||
|
wrap(p[1]),
|
||||||
|
wrap(p[2]),
|
||||||
|
wrap(p[3])
|
||||||
|
);
|
||||||
|
else
|
||||||
|
if (p.length == 5)
|
||||||
|
return invoke5(o,f,
|
||||||
|
wrap(p[0]),
|
||||||
|
wrap(p[1]),
|
||||||
|
wrap(p[2]),
|
||||||
|
wrap(p[3]),
|
||||||
|
wrap(p[4])
|
||||||
|
);
|
||||||
|
else
|
||||||
|
if (p.length == 6)
|
||||||
|
return invoke6(o,f,
|
||||||
|
wrap(p[0]),
|
||||||
|
wrap(p[1]),
|
||||||
|
wrap(p[2]),
|
||||||
|
wrap(p[3]),
|
||||||
|
wrap(p[4]),
|
||||||
|
wrap(p[5])
|
||||||
|
);
|
||||||
|
else
|
||||||
|
if (p.length == 7)
|
||||||
|
return invoke7(o,f,
|
||||||
|
wrap(p[0]),
|
||||||
|
wrap(p[1]),
|
||||||
|
wrap(p[2]),
|
||||||
|
wrap(p[3]),
|
||||||
|
wrap(p[4]),
|
||||||
|
wrap(p[5]),
|
||||||
|
wrap(p[6])
|
||||||
|
);
|
||||||
|
else
|
||||||
|
if (p.length == 8)
|
||||||
|
return invoke8(o,f,
|
||||||
|
wrap(p[0]),
|
||||||
|
wrap(p[1]),
|
||||||
|
wrap(p[2]),
|
||||||
|
wrap(p[3]),
|
||||||
|
wrap(p[4]),
|
||||||
|
wrap(p[5]),
|
||||||
|
wrap(p[6]),
|
||||||
|
wrap(p[7])
|
||||||
|
);
|
||||||
|
else
|
||||||
|
if (p.length == 9)
|
||||||
|
return invoke9(o,f,
|
||||||
|
wrap(p[0]),
|
||||||
|
wrap(p[1]),
|
||||||
|
wrap(p[2]),
|
||||||
|
wrap(p[3]),
|
||||||
|
wrap(p[4]),
|
||||||
|
wrap(p[5]),
|
||||||
|
wrap(p[6]),
|
||||||
|
wrap(p[7]),
|
||||||
|
wrap(p[8])
|
||||||
|
);
|
||||||
|
else
|
||||||
|
if (p.length == 10)
|
||||||
|
return invoke10(o,f,
|
||||||
|
wrap(p[0]),
|
||||||
|
wrap(p[1]),
|
||||||
|
wrap(p[2]),
|
||||||
|
wrap(p[3]),
|
||||||
|
wrap(p[4]),
|
||||||
|
wrap(p[5]),
|
||||||
|
wrap(p[6]),
|
||||||
|
wrap(p[7]),
|
||||||
|
wrap(p[8]),
|
||||||
|
wrap(p[9])
|
||||||
|
);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static native JavaScriptObject invoke0 (JavaScriptObject o, String f) /*-{
|
||||||
|
return o[f].call(o);
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
static native JavaScriptObject invoke1 (JavaScriptObject o, String f,
|
||||||
|
JavaScriptObject p0
|
||||||
|
) /*-{
|
||||||
|
return o[f].call(o,
|
||||||
|
p0
|
||||||
|
);
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
static native JavaScriptObject invoke2 (JavaScriptObject o, String f,
|
||||||
|
JavaScriptObject p0,
|
||||||
|
JavaScriptObject p1
|
||||||
|
) /*-{
|
||||||
|
return o[f].call(o,
|
||||||
|
p0,
|
||||||
|
p1
|
||||||
|
);
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
static native JavaScriptObject invoke3 (JavaScriptObject o, String f,
|
||||||
|
JavaScriptObject p0,
|
||||||
|
JavaScriptObject p1,
|
||||||
|
JavaScriptObject p2
|
||||||
|
) /*-{
|
||||||
|
return o[f].call(o,
|
||||||
|
p0,
|
||||||
|
p1,
|
||||||
|
p2
|
||||||
|
);
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
static native JavaScriptObject invoke4 (JavaScriptObject o, String f,
|
||||||
|
JavaScriptObject p0,
|
||||||
|
JavaScriptObject p1,
|
||||||
|
JavaScriptObject p2,
|
||||||
|
JavaScriptObject p3
|
||||||
|
) /*-{
|
||||||
|
return o[f].call(o,
|
||||||
|
p0,
|
||||||
|
p1,
|
||||||
|
p2,
|
||||||
|
p3
|
||||||
|
);
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
static native JavaScriptObject invoke5 (JavaScriptObject o, String f,
|
||||||
|
JavaScriptObject p0,
|
||||||
|
JavaScriptObject p1,
|
||||||
|
JavaScriptObject p2,
|
||||||
|
JavaScriptObject p3,
|
||||||
|
JavaScriptObject p4
|
||||||
|
) /*-{
|
||||||
|
return o[f].call(o,
|
||||||
|
p0,
|
||||||
|
p1,
|
||||||
|
p2,
|
||||||
|
p3,
|
||||||
|
p4
|
||||||
|
);
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
static native JavaScriptObject invoke6 (JavaScriptObject o, String f,
|
||||||
|
JavaScriptObject p0,
|
||||||
|
JavaScriptObject p1,
|
||||||
|
JavaScriptObject p2,
|
||||||
|
JavaScriptObject p3,
|
||||||
|
JavaScriptObject p4,
|
||||||
|
JavaScriptObject p5
|
||||||
|
) /*-{
|
||||||
|
return o[f].call(o,
|
||||||
|
p0,
|
||||||
|
p1,
|
||||||
|
p2,
|
||||||
|
p3,
|
||||||
|
p4,
|
||||||
|
p5
|
||||||
|
);
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
static native JavaScriptObject invoke7 (JavaScriptObject o, String f,
|
||||||
|
JavaScriptObject p0,
|
||||||
|
JavaScriptObject p1,
|
||||||
|
JavaScriptObject p2,
|
||||||
|
JavaScriptObject p3,
|
||||||
|
JavaScriptObject p4,
|
||||||
|
JavaScriptObject p5,
|
||||||
|
JavaScriptObject p6
|
||||||
|
) /*-{
|
||||||
|
return o[f].call(o,
|
||||||
|
p0,
|
||||||
|
p1,
|
||||||
|
p2,
|
||||||
|
p3,
|
||||||
|
p4,
|
||||||
|
p5,
|
||||||
|
p6
|
||||||
|
);
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
static native JavaScriptObject invoke8 (JavaScriptObject o, String f,
|
||||||
|
JavaScriptObject p0,
|
||||||
|
JavaScriptObject p1,
|
||||||
|
JavaScriptObject p2,
|
||||||
|
JavaScriptObject p3,
|
||||||
|
JavaScriptObject p4,
|
||||||
|
JavaScriptObject p5,
|
||||||
|
JavaScriptObject p6,
|
||||||
|
JavaScriptObject p7
|
||||||
|
) /*-{
|
||||||
|
return o[f].call(o,
|
||||||
|
p0,
|
||||||
|
p1,
|
||||||
|
p2,
|
||||||
|
p3,
|
||||||
|
p4,
|
||||||
|
p5,
|
||||||
|
p6,
|
||||||
|
p7
|
||||||
|
);
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
static native JavaScriptObject invoke9 (JavaScriptObject o, String f,
|
||||||
|
JavaScriptObject p0,
|
||||||
|
JavaScriptObject p1,
|
||||||
|
JavaScriptObject p2,
|
||||||
|
JavaScriptObject p3,
|
||||||
|
JavaScriptObject p4,
|
||||||
|
JavaScriptObject p5,
|
||||||
|
JavaScriptObject p6,
|
||||||
|
JavaScriptObject p7,
|
||||||
|
JavaScriptObject p8
|
||||||
|
) /*-{
|
||||||
|
return o[f].call(o,
|
||||||
|
p0,
|
||||||
|
p1,
|
||||||
|
p2,
|
||||||
|
p3,
|
||||||
|
p4,
|
||||||
|
p5,
|
||||||
|
p6,
|
||||||
|
p7,
|
||||||
|
p8
|
||||||
|
);
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
static native JavaScriptObject invoke10 (JavaScriptObject o, String f,
|
||||||
|
JavaScriptObject p0,
|
||||||
|
JavaScriptObject p1,
|
||||||
|
JavaScriptObject p2,
|
||||||
|
JavaScriptObject p3,
|
||||||
|
JavaScriptObject p4,
|
||||||
|
JavaScriptObject p5,
|
||||||
|
JavaScriptObject p6,
|
||||||
|
JavaScriptObject p7,
|
||||||
|
JavaScriptObject p8,
|
||||||
|
JavaScriptObject p9
|
||||||
|
) /*-{
|
||||||
|
return o[f].call(o,
|
||||||
|
p0,
|
||||||
|
p1,
|
||||||
|
p2,
|
||||||
|
p3,
|
||||||
|
p4,
|
||||||
|
p5,
|
||||||
|
p6,
|
||||||
|
p7,
|
||||||
|
p8,
|
||||||
|
p9
|
||||||
|
);
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
public native static JavaScriptObject getMember(Object o, String s) /*-{
|
||||||
|
return o[s];
|
||||||
|
}-*/;
|
||||||
|
}
|
323
gwt/src/app/service/JSInvokerNo.java
Normal file
323
gwt/src/app/service/JSInvokerNo.java
Normal file
@ -0,0 +1,323 @@
|
|||||||
|
/**
|
||||||
|
* Author: Timothy Prepscius
|
||||||
|
* License: GPLv3 Affero + keep my name in the code!
|
||||||
|
*/
|
||||||
|
package app.service;
|
||||||
|
|
||||||
|
import com.google.gwt.core.client.JavaScriptObject;
|
||||||
|
|
||||||
|
import core.util.Characters;
|
||||||
|
import core.util.LogNull;
|
||||||
|
import core.util.LogOut;
|
||||||
|
|
||||||
|
public class JSInvokerNo
|
||||||
|
{
|
||||||
|
static LogNull log = new LogNull(JSInvokerNo.class);
|
||||||
|
|
||||||
|
static String className(Class<?> c)
|
||||||
|
{
|
||||||
|
String name = c.getName();
|
||||||
|
|
||||||
|
int d = name.lastIndexOf('$');
|
||||||
|
|
||||||
|
if (d != -1)
|
||||||
|
{
|
||||||
|
if (d+1 < name.length())
|
||||||
|
{
|
||||||
|
if (Characters.isNumber(name.charAt(d+1)))
|
||||||
|
return className(c.getSuperclass());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String classOf(Object p)
|
||||||
|
{
|
||||||
|
if (p == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return className(p.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
static JavaScriptObject invoke (Object oo, String f, Object[] p)
|
||||||
|
{
|
||||||
|
JavaScriptObject o = (JavaScriptObject)oo;
|
||||||
|
|
||||||
|
if (p == null || p.length == 0)
|
||||||
|
return invoke0(o,f);
|
||||||
|
else
|
||||||
|
if (p.length == 1)
|
||||||
|
return invoke1(o,f,classOf(p[0]), p[0]);
|
||||||
|
else
|
||||||
|
if (p.length == 2)
|
||||||
|
return invoke2(o,f,
|
||||||
|
classOf(p[0]), p[0],
|
||||||
|
classOf(p[1]), p[1]
|
||||||
|
);
|
||||||
|
else
|
||||||
|
if (p.length == 3)
|
||||||
|
return invoke3(o,f,
|
||||||
|
classOf(p[0]), p[0],
|
||||||
|
classOf(p[1]), p[1],
|
||||||
|
classOf(p[2]), p[2]
|
||||||
|
);
|
||||||
|
else
|
||||||
|
if (p.length == 4)
|
||||||
|
return invoke4(o,f,
|
||||||
|
classOf(p[0]), p[0],
|
||||||
|
classOf(p[1]), p[1],
|
||||||
|
classOf(p[2]), p[2],
|
||||||
|
classOf(p[3]), p[3]
|
||||||
|
);
|
||||||
|
else
|
||||||
|
if (p.length == 5)
|
||||||
|
return invoke5(o,f,
|
||||||
|
classOf(p[0]), p[0],
|
||||||
|
classOf(p[1]), p[1],
|
||||||
|
classOf(p[2]), p[2],
|
||||||
|
classOf(p[3]), p[3],
|
||||||
|
classOf(p[4]), p[4]
|
||||||
|
);
|
||||||
|
else
|
||||||
|
if (p.length == 6)
|
||||||
|
return invoke6(o,f,
|
||||||
|
classOf(p[0]), p[0],
|
||||||
|
classOf(p[1]), p[1],
|
||||||
|
classOf(p[2]), p[2],
|
||||||
|
classOf(p[3]), p[3],
|
||||||
|
classOf(p[4]), p[4],
|
||||||
|
classOf(p[5]), p[5]
|
||||||
|
);
|
||||||
|
else
|
||||||
|
if (p.length == 7)
|
||||||
|
return invoke7(o,f,
|
||||||
|
classOf(p[0]), p[0],
|
||||||
|
classOf(p[1]), p[1],
|
||||||
|
classOf(p[2]), p[2],
|
||||||
|
classOf(p[3]), p[3],
|
||||||
|
classOf(p[4]), p[4],
|
||||||
|
classOf(p[5]), p[5],
|
||||||
|
classOf(p[6]), p[6]
|
||||||
|
);
|
||||||
|
else
|
||||||
|
if (p.length == 8)
|
||||||
|
return invoke8(o,f,
|
||||||
|
classOf(p[0]), p[0],
|
||||||
|
classOf(p[1]), p[1],
|
||||||
|
classOf(p[2]), p[2],
|
||||||
|
classOf(p[3]), p[3],
|
||||||
|
classOf(p[4]), p[4],
|
||||||
|
classOf(p[5]), p[5],
|
||||||
|
classOf(p[6]), p[6],
|
||||||
|
classOf(p[7]), p[7]
|
||||||
|
);
|
||||||
|
else
|
||||||
|
if (p.length == 9)
|
||||||
|
return invoke9(o,f,
|
||||||
|
classOf(p[0]), p[0],
|
||||||
|
classOf(p[1]), p[1],
|
||||||
|
classOf(p[2]), p[2],
|
||||||
|
classOf(p[3]), p[3],
|
||||||
|
classOf(p[4]), p[4],
|
||||||
|
classOf(p[5]), p[5],
|
||||||
|
classOf(p[6]), p[6],
|
||||||
|
classOf(p[7]), p[7],
|
||||||
|
classOf(p[8]), p[8]
|
||||||
|
);
|
||||||
|
else
|
||||||
|
if (p.length == 10)
|
||||||
|
return invoke10(o,f,
|
||||||
|
classOf(p[0]), p[0],
|
||||||
|
classOf(p[1]), p[1],
|
||||||
|
classOf(p[2]), p[2],
|
||||||
|
classOf(p[3]), p[3],
|
||||||
|
classOf(p[4]), p[4],
|
||||||
|
classOf(p[5]), p[5],
|
||||||
|
classOf(p[6]), p[6],
|
||||||
|
classOf(p[7]), p[7],
|
||||||
|
classOf(p[8]), p[8],
|
||||||
|
classOf(p[9]), p[9]
|
||||||
|
);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static native JavaScriptObject invoke0 (JavaScriptObject o, String f) /*-{
|
||||||
|
return o[f].call(o);
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
static native JavaScriptObject invoke1 (JavaScriptObject o, String f,
|
||||||
|
String c0, Object p0
|
||||||
|
) /*-{
|
||||||
|
return o[f].call(o,
|
||||||
|
$wnd.bindExportable(p0, c0)
|
||||||
|
);
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
static native JavaScriptObject invoke2 (JavaScriptObject o, String f,
|
||||||
|
String c0, Object p0,
|
||||||
|
String c1, Object p1
|
||||||
|
) /*-{
|
||||||
|
return o[f].call(o,
|
||||||
|
$wnd.bindExportable(p0, c0),
|
||||||
|
$wnd.bindExportable(p1, c1)
|
||||||
|
);
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
static native JavaScriptObject invoke3 (JavaScriptObject o, String f,
|
||||||
|
String c0, Object p0,
|
||||||
|
String c1, Object p1,
|
||||||
|
String c2, Object p2
|
||||||
|
) /*-{
|
||||||
|
return o[f].call(o,
|
||||||
|
$wnd.bindExportable(p0, c0),
|
||||||
|
$wnd.bindExportable(p1, c1),
|
||||||
|
$wnd.bindExportable(p2, c2)
|
||||||
|
);
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
static native JavaScriptObject invoke4 (JavaScriptObject o, String f,
|
||||||
|
String c0, Object p0,
|
||||||
|
String c1, Object p1,
|
||||||
|
String c2, Object p2,
|
||||||
|
String c3, Object p3
|
||||||
|
) /*-{
|
||||||
|
return o[f].call(o,
|
||||||
|
$wnd.bindExportable(p0, c0),
|
||||||
|
$wnd.bindExportable(p1, c1),
|
||||||
|
$wnd.bindExportable(p2, c2),
|
||||||
|
$wnd.bindExportable(p3, c3)
|
||||||
|
);
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
static native JavaScriptObject invoke5 (JavaScriptObject o, String f,
|
||||||
|
String c0, Object p0,
|
||||||
|
String c1, Object p1,
|
||||||
|
String c2, Object p2,
|
||||||
|
String c3, Object p3,
|
||||||
|
String c4, Object p4
|
||||||
|
) /*-{
|
||||||
|
return o[f].call(o,
|
||||||
|
$wnd.bindExportable(p0, c0),
|
||||||
|
$wnd.bindExportable(p1, c1),
|
||||||
|
$wnd.bindExportable(p2, c2),
|
||||||
|
$wnd.bindExportable(p3, c3),
|
||||||
|
$wnd.bindExportable(p4, c4)
|
||||||
|
);
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
static native JavaScriptObject invoke6 (JavaScriptObject o, String f,
|
||||||
|
String c0, Object p0,
|
||||||
|
String c1, Object p1,
|
||||||
|
String c2, Object p2,
|
||||||
|
String c3, Object p3,
|
||||||
|
String c4, Object p4,
|
||||||
|
String c5, Object p5
|
||||||
|
) /*-{
|
||||||
|
return o[f].call(o,
|
||||||
|
$wnd.bindExportable(p0, c0),
|
||||||
|
$wnd.bindExportable(p1, c1),
|
||||||
|
$wnd.bindExportable(p2, c2),
|
||||||
|
$wnd.bindExportable(p3, c3),
|
||||||
|
$wnd.bindExportable(p4, c4),
|
||||||
|
$wnd.bindExportable(p5, c5)
|
||||||
|
);
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
static native JavaScriptObject invoke7 (JavaScriptObject o, String f,
|
||||||
|
String c0, Object p0,
|
||||||
|
String c1, Object p1,
|
||||||
|
String c2, Object p2,
|
||||||
|
String c3, Object p3,
|
||||||
|
String c4, Object p4,
|
||||||
|
String c5, Object p5,
|
||||||
|
String c6, Object p6
|
||||||
|
) /*-{
|
||||||
|
return o[f].call(o,
|
||||||
|
$wnd.bindExportable(p0, c0),
|
||||||
|
$wnd.bindExportable(p1, c1),
|
||||||
|
$wnd.bindExportable(p2, c2),
|
||||||
|
$wnd.bindExportable(p3, c3),
|
||||||
|
$wnd.bindExportable(p4, c4),
|
||||||
|
$wnd.bindExportable(p5, c5),
|
||||||
|
$wnd.bindExportable(p6, c6)
|
||||||
|
);
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
static native JavaScriptObject invoke8 (JavaScriptObject o, String f,
|
||||||
|
String c0, Object p0,
|
||||||
|
String c1, Object p1,
|
||||||
|
String c2, Object p2,
|
||||||
|
String c3, Object p3,
|
||||||
|
String c4, Object p4,
|
||||||
|
String c5, Object p5,
|
||||||
|
String c6, Object p6,
|
||||||
|
String c7, Object p7
|
||||||
|
) /*-{
|
||||||
|
return o[f].call(o,
|
||||||
|
$wnd.bindExportable(p0, c0),
|
||||||
|
$wnd.bindExportable(p1, c1),
|
||||||
|
$wnd.bindExportable(p2, c2),
|
||||||
|
$wnd.bindExportable(p3, c3),
|
||||||
|
$wnd.bindExportable(p4, c4),
|
||||||
|
$wnd.bindExportable(p5, c5),
|
||||||
|
$wnd.bindExportable(p6, c6),
|
||||||
|
$wnd.bindExportable(p7, c7)
|
||||||
|
);
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
static native JavaScriptObject invoke9 (JavaScriptObject o, String f,
|
||||||
|
String c0, Object p0,
|
||||||
|
String c1, Object p1,
|
||||||
|
String c2, Object p2,
|
||||||
|
String c3, Object p3,
|
||||||
|
String c4, Object p4,
|
||||||
|
String c5, Object p5,
|
||||||
|
String c6, Object p6,
|
||||||
|
String c7, Object p7,
|
||||||
|
String c8, Object p8
|
||||||
|
) /*-{
|
||||||
|
return o[f].call(o,
|
||||||
|
$wnd.bindExportable(p0, c0),
|
||||||
|
$wnd.bindExportable(p1, c1),
|
||||||
|
$wnd.bindExportable(p2, c2),
|
||||||
|
$wnd.bindExportable(p3, c3),
|
||||||
|
$wnd.bindExportable(p4, c4),
|
||||||
|
$wnd.bindExportable(p5, c5),
|
||||||
|
$wnd.bindExportable(p6, c6),
|
||||||
|
$wnd.bindExportable(p7, c7),
|
||||||
|
$wnd.bindExportable(p8, c8)
|
||||||
|
);
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
static native JavaScriptObject invoke10 (JavaScriptObject o, String f,
|
||||||
|
String c0, Object p0,
|
||||||
|
String c1, Object p1,
|
||||||
|
String c2, Object p2,
|
||||||
|
String c3, Object p3,
|
||||||
|
String c4, Object p4,
|
||||||
|
String c5, Object p5,
|
||||||
|
String c6, Object p6,
|
||||||
|
String c7, Object p7,
|
||||||
|
String c8, Object p8,
|
||||||
|
String c9, Object p9
|
||||||
|
) /*-{
|
||||||
|
return o[f].call(o,
|
||||||
|
$wnd.bindExportable(p0, c0),
|
||||||
|
$wnd.bindExportable(p1, c1),
|
||||||
|
$wnd.bindExportable(p2, c2),
|
||||||
|
$wnd.bindExportable(p3, c3),
|
||||||
|
$wnd.bindExportable(p4, c4),
|
||||||
|
$wnd.bindExportable(p5, c5),
|
||||||
|
$wnd.bindExportable(p6, c6),
|
||||||
|
$wnd.bindExportable(p7, c7),
|
||||||
|
$wnd.bindExportable(p8, c8),
|
||||||
|
$wnd.bindExportable(p9, c9)
|
||||||
|
);
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
public native static JavaScriptObject getMember(Object o, String s) /*-{
|
||||||
|
return o[s];
|
||||||
|
}-*/;
|
||||||
|
}
|
1
gwt/src/app/service/JSRefill.java
Symbolic link
1
gwt/src/app/service/JSRefill.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/app/service/src/app/service/JSRefill.java
|
1
gwt/src/app/service/JSResult.java
Symbolic link
1
gwt/src/app/service/JSResult.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/app/service/src/app/service/JSResult.java
|
1
gwt/src/app/service/JSSignUp.java
Symbolic link
1
gwt/src/app/service/JSSignUp.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/app/service/src/app/service/JSSignUp.java
|
1
gwt/src/app/service/JSStreamSessionWebSocket.java
Symbolic link
1
gwt/src/app/service/JSStreamSessionWebSocket.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/app/service/src/app/service/JSStreamSessionWebSocket.java
|
1
gwt/src/app/service/MailI.java
Symbolic link
1
gwt/src/app/service/MailI.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/app/service/src/app/service/MailI.java
|
1
gwt/src/app/service/Main.java
Symbolic link
1
gwt/src/app/service/Main.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/app/service/src/app/service/Main.java
|
1
gwt/src/app/service/ServiceAppletRunnable.java
Symbolic link
1
gwt/src/app/service/ServiceAppletRunnable.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/app/service/src/app/service/ServiceAppletRunnable.java
|
12
gwt/src/com/jordanzimmerman/GWT.gwt.xml
Normal file
12
gwt/src/com/jordanzimmerman/GWT.gwt.xml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
When updating your version of GWT, you should also update this DTD reference,
|
||||||
|
so that your app can take advantage of the latest GWT module capabilities.
|
||||||
|
-->
|
||||||
|
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.5.0//EN"
|
||||||
|
"http://google-web-toolkit.googlecode.com/svn/tags/2.5.0/distro-source/core/src/gwt-module.dtd">
|
||||||
|
<module>
|
||||||
|
<!-- Specify the paths for translatable code -->
|
||||||
|
<source path=''/>
|
||||||
|
|
||||||
|
</module>
|
17
gwt/src/com/jordanzimmerman/Hash256i.java
Normal file
17
gwt/src/com/jordanzimmerman/Hash256i.java
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/**
|
||||||
|
* Author: Timothy Prepscius
|
||||||
|
* License: GPLv3 Affero + keep my name in the code!
|
||||||
|
*/
|
||||||
|
package com.jordanzimmerman;
|
||||||
|
|
||||||
|
import core.crypt.HashSha256;
|
||||||
|
|
||||||
|
public class Hash256i
|
||||||
|
{
|
||||||
|
HashSha256 hash = new HashSha256();
|
||||||
|
|
||||||
|
public byte[] hash(byte[] bytes)
|
||||||
|
{
|
||||||
|
return hash.hash(bytes);
|
||||||
|
}
|
||||||
|
}
|
13
gwt/src/com/jordanzimmerman/Logz.java
Normal file
13
gwt/src/com/jordanzimmerman/Logz.java
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* Author: Timothy Prepscius
|
||||||
|
* License: GPLv3 Affero + keep my name in the code!
|
||||||
|
*/
|
||||||
|
package com.jordanzimmerman;
|
||||||
|
|
||||||
|
public class Logz {
|
||||||
|
|
||||||
|
public static void println(String string) {
|
||||||
|
System.out.println(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
../../../../java/ext/jordanzimmerman/src/com/jordanzimmerman/SRPAuthenticationFailedException.java
|
1
gwt/src/com/jordanzimmerman/SRPClientSession.java
Symbolic link
1
gwt/src/com/jordanzimmerman/SRPClientSession.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/ext/jordanzimmerman/src/com/jordanzimmerman/SRPClientSession.java
|
12
gwt/src/com/jordanzimmerman/SRPClientSessionInterface.java
Normal file
12
gwt/src/com/jordanzimmerman/SRPClientSessionInterface.java
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package com.jordanzimmerman;
|
||||||
|
|
||||||
|
public interface SRPClientSessionInterface {
|
||||||
|
|
||||||
|
public void setSalt_s(byte[] bs);
|
||||||
|
public void setServerPublicKey_B(byte[] publicKey) throws SRPAuthenticationFailedException;
|
||||||
|
public byte[] getSessionKey_K();
|
||||||
|
public byte[] getPublicKey_A();
|
||||||
|
public byte[] getEvidenceValue_M1();
|
||||||
|
public void validateServerEvidenceValue_M2(byte[] evidence) throws SRPAuthenticationFailedException;
|
||||||
|
|
||||||
|
}
|
1
gwt/src/com/jordanzimmerman/SRPConstants.java
Symbolic link
1
gwt/src/com/jordanzimmerman/SRPConstants.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/ext/jordanzimmerman/src/com/jordanzimmerman/SRPConstants.java
|
1
gwt/src/com/jordanzimmerman/SRPFactory.java
Symbolic link
1
gwt/src/com/jordanzimmerman/SRPFactory.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/ext/jordanzimmerman/src/com/jordanzimmerman/SRPFactory.java
|
1
gwt/src/com/jordanzimmerman/SRPRunner.java
Symbolic link
1
gwt/src/com/jordanzimmerman/SRPRunner.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/ext/jordanzimmerman/src/com/jordanzimmerman/SRPRunner.java
|
1
gwt/src/com/jordanzimmerman/SRPServerSession.java
Symbolic link
1
gwt/src/com/jordanzimmerman/SRPServerSession.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/ext/jordanzimmerman/src/com/jordanzimmerman/SRPServerSession.java
|
1
gwt/src/com/jordanzimmerman/SRPUtils.java
Symbolic link
1
gwt/src/com/jordanzimmerman/SRPUtils.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/ext/jordanzimmerman/src/com/jordanzimmerman/SRPUtils.java
|
1
gwt/src/com/jordanzimmerman/SRPVerifier.java
Symbolic link
1
gwt/src/com/jordanzimmerman/SRPVerifier.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/ext/jordanzimmerman/src/com/jordanzimmerman/SRPVerifier.java
|
9
gwt/src/com/jordanzimmerman/SecureRandomi.java
Normal file
9
gwt/src/com/jordanzimmerman/SecureRandomi.java
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/**
|
||||||
|
* Author: Timothy Prepscius
|
||||||
|
* License: GPLv3 Affero + keep my name in the code!
|
||||||
|
*/
|
||||||
|
package com.jordanzimmerman;
|
||||||
|
|
||||||
|
public class SecureRandomi extends java.security.SecureRandom {
|
||||||
|
|
||||||
|
}
|
38
gwt/src/com/mailiverse/gwt/Mailiverse_GWT.gwt.xml
Normal file
38
gwt/src/com/mailiverse/gwt/Mailiverse_GWT.gwt.xml
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
When updating your version of GWT, you should also update this DTD reference,
|
||||||
|
so that your app can take advantage of the latest GWT module capabilities.
|
||||||
|
-->
|
||||||
|
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.5.0//EN"
|
||||||
|
"http://google-web-toolkit.googlecode.com/svn/tags/2.5.0/distro-source/core/src/gwt-module.dtd">
|
||||||
|
<module rename-to='mailiverse_gwt'>
|
||||||
|
<inherits name='com.google.gwt.user.User'/>
|
||||||
|
<inherits name='com.google.gwt.xml.XML'/>
|
||||||
|
<inherits name='com.google.gwt.json.JSON'/>
|
||||||
|
|
||||||
|
<inherits name='com.jordanzimmerman.GWT'/>
|
||||||
|
<inherits name='org.json.GWT'/>
|
||||||
|
<inherits name='core.GWT'/>
|
||||||
|
<inherits name='key.GWT'/>
|
||||||
|
<inherits name='mail.GWT'/>
|
||||||
|
<inherits name='app.GWT'/>
|
||||||
|
<inherits name='JRE'/>
|
||||||
|
|
||||||
|
<inherits name='org.timepedia.exporter.Exporter'/>
|
||||||
|
<set-property name="export" value="yes"/>
|
||||||
|
|
||||||
|
<!-- Specify the app entry point class. -->
|
||||||
|
<entry-point class='com.mailiverse.gwt.client.Mailiverse_GWT'/>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<add-linker name="xsiframe" />
|
||||||
|
<set-configuration-property name="devModeRedirectEnabled" value="true" />
|
||||||
|
<set-property name="user.agent" value="safari" />
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Specify the paths for translatable code -->
|
||||||
|
<source path='client'/>
|
||||||
|
<source path='shared'/>
|
||||||
|
|
||||||
|
</module>
|
48
gwt/src/com/mailiverse/gwt/client/Mailiverse_GWT.java
Normal file
48
gwt/src/com/mailiverse/gwt/client/Mailiverse_GWT.java
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/**
|
||||||
|
* Author: Timothy Prepscius
|
||||||
|
* License: GPLv3 Affero + keep my name in the code!
|
||||||
|
*/
|
||||||
|
package com.mailiverse.gwt.client;
|
||||||
|
|
||||||
|
import org.timepedia.exporter.client.ExporterUtil;
|
||||||
|
|
||||||
|
import mail.client.model.Original;
|
||||||
|
|
||||||
|
import app.service.Main;
|
||||||
|
|
||||||
|
import com.google.gwt.core.client.EntryPoint;
|
||||||
|
import com.google.gwt.core.client.GWT;
|
||||||
|
import com.google.gwt.core.client.JavaScriptObject;
|
||||||
|
import com.google.gwt.event.dom.client.ClickEvent;
|
||||||
|
import com.google.gwt.event.dom.client.ClickHandler;
|
||||||
|
import com.google.gwt.event.dom.client.KeyCodes;
|
||||||
|
import com.google.gwt.event.dom.client.KeyUpEvent;
|
||||||
|
import com.google.gwt.event.dom.client.KeyUpHandler;
|
||||||
|
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||||
|
import com.google.gwt.user.client.ui.Button;
|
||||||
|
import com.google.gwt.user.client.ui.DialogBox;
|
||||||
|
import com.google.gwt.user.client.ui.HTML;
|
||||||
|
import com.google.gwt.user.client.ui.Label;
|
||||||
|
import com.google.gwt.user.client.ui.RootPanel;
|
||||||
|
import com.google.gwt.user.client.ui.TextBox;
|
||||||
|
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entry point classes define <code>onModuleLoad()</code>.
|
||||||
|
*/
|
||||||
|
public class Mailiverse_GWT implements EntryPoint {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the entry point method.
|
||||||
|
*/
|
||||||
|
public native void propagateLoad (JavaScriptObject main) /*-{
|
||||||
|
$wnd.onMailiverseBootstrapGWT(main);
|
||||||
|
}-*/;
|
||||||
|
|
||||||
|
|
||||||
|
public void onModuleLoad()
|
||||||
|
{
|
||||||
|
ExporterUtil.exportAll();
|
||||||
|
propagateLoad(ExporterUtil.wrap(new Main()));
|
||||||
|
}
|
||||||
|
}
|
12
gwt/src/core/GWT.gwt.xml
Normal file
12
gwt/src/core/GWT.gwt.xml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
When updating your version of GWT, you should also update this DTD reference,
|
||||||
|
so that your app can take advantage of the latest GWT module capabilities.
|
||||||
|
-->
|
||||||
|
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.5.0//EN"
|
||||||
|
"http://google-web-toolkit.googlecode.com/svn/tags/2.5.0/distro-source/core/src/gwt-module.dtd">
|
||||||
|
<module>
|
||||||
|
<!-- Specify the paths for translatable code -->
|
||||||
|
<source path=''/>
|
||||||
|
|
||||||
|
</module>
|
1
gwt/src/core/callback/Callback.java
Symbolic link
1
gwt/src/core/callback/Callback.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/core/src/core/callback/Callback.java
|
1
gwt/src/core/callback/CallbackChain.java
Symbolic link
1
gwt/src/core/callback/CallbackChain.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/core/src/core/callback/CallbackChain.java
|
1
gwt/src/core/callback/CallbackDefault.java
Symbolic link
1
gwt/src/core/callback/CallbackDefault.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/core/src/core/callback/CallbackDefault.java
|
1
gwt/src/core/callback/CallbackEmpty.java
Symbolic link
1
gwt/src/core/callback/CallbackEmpty.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/core/src/core/callback/CallbackEmpty.java
|
1
gwt/src/core/callback/CallbackInterface.java
Symbolic link
1
gwt/src/core/callback/CallbackInterface.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/core/src/core/callback/CallbackInterface.java
|
1
gwt/src/core/callback/CallbackSync.java
Symbolic link
1
gwt/src/core/callback/CallbackSync.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/core/src/core/callback/CallbackSync.java
|
1
gwt/src/core/callback/CallbackWithVariables.java
Symbolic link
1
gwt/src/core/callback/CallbackWithVariables.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/core/src/core/callback/CallbackWithVariables.java
|
1
gwt/src/core/callbacks/CountDown.java
Symbolic link
1
gwt/src/core/callbacks/CountDown.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/core/src/core/callbacks/CountDown.java
|
1
gwt/src/core/callbacks/IoOnReceive.java
Symbolic link
1
gwt/src/core/callbacks/IoOnReceive.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/core/src/core/callbacks/IoOnReceive.java
|
1
gwt/src/core/callbacks/IoOpen.java
Symbolic link
1
gwt/src/core/callbacks/IoOpen.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/core/src/core/callbacks/IoOpen.java
|
1
gwt/src/core/callbacks/IoSend.java
Symbolic link
1
gwt/src/core/callbacks/IoSend.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/core/src/core/callbacks/IoSend.java
|
1
gwt/src/core/callbacks/IoStop.java
Symbolic link
1
gwt/src/core/callbacks/IoStop.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/core/src/core/callbacks/IoStop.java
|
1
gwt/src/core/callbacks/JSONDeserialize.java
Symbolic link
1
gwt/src/core/callbacks/JSONDeserialize.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/core/src/core/callbacks/JSONDeserialize.java
|
1
gwt/src/core/callbacks/JSONSerialize.java
Symbolic link
1
gwt/src/core/callbacks/JSONSerialize.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/core/src/core/callbacks/JSONSerialize.java
|
1
gwt/src/core/callbacks/Memory.java
Symbolic link
1
gwt/src/core/callbacks/Memory.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/core/src/core/callbacks/Memory.java
|
1
gwt/src/core/callbacks/SaveArguments.java
Symbolic link
1
gwt/src/core/callbacks/SaveArguments.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/core/src/core/callbacks/SaveArguments.java
|
1
gwt/src/core/callbacks/Single.java
Symbolic link
1
gwt/src/core/callbacks/Single.java
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../java/core/src/core/callbacks/Single.java
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user