Initial commit from SVN.
This commit is contained in:
6
Common/.classpath
Normal file
6
Common/.classpath
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
17
Common/.project
Normal file
17
Common/.project
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>Common</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
122
Common/build.xml
Normal file
122
Common/build.xml
Normal file
@@ -0,0 +1,122 @@
|
||||
<!--
|
||||
Builds the common project.
|
||||
-->
|
||||
<project xmlns:ivy="antlib:org.apache.ivy.ant" name="Common Project" default="build-common" basedir=".">
|
||||
<property name="compress" value="true"/>
|
||||
<property name="build" value="./build"/>
|
||||
|
||||
<!-- BEGIN: ivy library -->
|
||||
<property name="ivy" value="${build}/Ivy"/>
|
||||
<property name="ivy.version" value="2.3.0"/>
|
||||
|
||||
<target name="check-ivy">
|
||||
<available file="${ivy.jar.file}" property="skip.download.ivy"/>
|
||||
</target>
|
||||
<target name="download-ivy" depends="check-ivy" unless="skip.download.ivy">
|
||||
<mkdir dir="${ivy}"/>
|
||||
<echo message="installing ivy..."/>
|
||||
<get src="http://repo1.maven.org/maven2/org/apache/ivy/ivy/${ivy.version}/ivy-${ivy.version}.jar" dest="${ivy}/ivy-${ivy.version}.jar" usetimestamp="true"/>
|
||||
</target>
|
||||
<target name="load-ivy" depends="download-ivy">
|
||||
<path id="ivy.classpath">
|
||||
<fileset dir="${ivy}">
|
||||
<include name="*.jar"/>
|
||||
</fileset>
|
||||
</path>
|
||||
<taskdef resource="org/apache/ivy/ant/antlib.xml" uri="antlib:org.apache.ivy.ant" classpathref="ivy.classpath"/>
|
||||
</target>
|
||||
<!-- END: ivy library -->
|
||||
|
||||
<!-- BEGIN: svnant library -->
|
||||
<property name="svnant" value="${build}/SvnAnt"/>
|
||||
<property name="svnant-version" value='1.4dev-5544'/>
|
||||
<property name="svnant-folder-version" value='1.4dev'/>
|
||||
|
||||
<target name="check-svnant">
|
||||
<available file="${svnant}/svnant-${svnant-version}.zip" property="skip-download-svnant"/>
|
||||
</target>
|
||||
<target name="download-svnant" depends="check-svnant" unless="skip-download-svnant">
|
||||
<delete dir="${svnant}" quiet="true" failonerror="false"/>
|
||||
<mkdir dir="${svnant}"/>
|
||||
<echo message="Installing SvnAnt..."/>
|
||||
|
||||
<get src="http://media:8081/artifactory/simple/libs-release-local/svnant-${svnant-version}.zip" dest="${svnant}" usetimestamp="true"/>
|
||||
<unzip src="${svnant}/svnant-${svnant-version}.zip" dest="${build}/SvnAnt">
|
||||
</unzip>
|
||||
</target>
|
||||
<target name="load-svnant" depends="download-svnant">
|
||||
<path id="svnant.classpath">
|
||||
<fileset dir="${build}/SvnAnt/"> <!--${build}/SvnAnt/svnant-${svnant-folder-version}/lib-->
|
||||
<include name="**/*.jar"/>
|
||||
</fileset>
|
||||
</path>
|
||||
<typedef resource="org/tigris/subversion/svnant/svnantlib.xml" classpathref="svnant.classpath"/>
|
||||
</target>
|
||||
<!-- END: svnant library -->
|
||||
|
||||
<target name="ivy-setup" depends="load-ivy">
|
||||
<property name="ivy.default.ivy.user.dir" location="./.ivy/"/>
|
||||
<ivy:configure id="ivy.settings" file="ivysettings.xml" username="jenkins" passwd="1qaz2wsx"/>
|
||||
<ivy:resolve file="ivy.xml"/>
|
||||
</target>
|
||||
|
||||
<target name="download-dependancies" depends="ivy-setup" description="Downloads the dependancies defined by the ivy.xml file from Artifactory.">
|
||||
<ivy:retrieve />
|
||||
</target>
|
||||
|
||||
<target name="upload-artifacts" depends="ivy-setup" description="Uploads artifacts defined by the ivy.xml file to Artifactory.">
|
||||
<ivy:publish revision="${build-version}" status="incremental" resolver="libs-release-resolver" overwrite="true">
|
||||
<artifacts pattern="[artifact]-[revision].[type].[ext]"/>
|
||||
</ivy:publish>
|
||||
</target>
|
||||
|
||||
<target name="load-svn-version">
|
||||
<svn>
|
||||
<wcVersion path="."/>
|
||||
</svn>
|
||||
<tstamp>
|
||||
<format property="build-time" pattern="yyyyMMddkkmm" timezone="PST"/>
|
||||
</tstamp>
|
||||
</target>
|
||||
<target name="get-dateversion" if="modified">
|
||||
<property name="build-version" value="SNAPSHOT-${committed.max}-${build-time}"/>
|
||||
</target>
|
||||
<target name="get-svnversion" unless="modified">
|
||||
<property name="build-version" value="SNAPSHOT-${committed.max}"/>
|
||||
</target>
|
||||
<target name="get-version" depends="load-svnant, load-svn-version, get-dateversion, get-svnversion">
|
||||
<echo message="Project's SVN version: ${committed.max}; is modified source: ${modified}"/>
|
||||
<echo message="Version used: ${build-version}"/>
|
||||
</target>
|
||||
|
||||
<target name="init">
|
||||
<mkdir dir="${build}/lib"/>
|
||||
</target>
|
||||
<target name="build-common" depends="build-common-src, build-common-bin" description="Builds the source zip and binary jar and places them in the ./build/lib directory.">
|
||||
</target>
|
||||
<target name="build-common-src" depends="init, get-version">
|
||||
<zip destfile="${build}/lib/DE Common-${build-version}.src.zip" basedir="./src" compress="${compress}" includes="**/*.java, **/*.properties"/>
|
||||
</target>
|
||||
<target name="build-common-bin" depends="init, get-version">
|
||||
<!-- Debug Build -->
|
||||
<mkdir dir="${build}/bin"/>
|
||||
<javac destdir="${build}/bin" target="1.4" source="1.4" encoding="utf-8" nowarn="true" verbose="no" fork="true" classpath="" debug="true" debuglevel="source" includeantruntime="false">
|
||||
<compilerarg value="-XDignore.symbol.file"/>
|
||||
<src path="./src"/>
|
||||
</javac>
|
||||
<jar destfile="${build}/lib/DE Common-${build-version}.bin.jar" basedir="./bin" compress="${compress}" includes="**/*.class, **/*.properties"/>
|
||||
<delete dir="${build}/bin"/>
|
||||
|
||||
<!-- Release Build
|
||||
<mkdir dir="${build}/bin"/>
|
||||
<javac destdir="${build}/bin" target="1.4" source="1.4" encoding="utf-8" nowarn="true" verbose="no" fork="true" classpath="" debug="off" includeantruntime="false">
|
||||
<compilerarg value="-XDignore.symbol.file"/>
|
||||
<src path="./src"/>
|
||||
</javac>
|
||||
<jar destfile="${build}/lib/DE Common-${build-version}.jar" basedir="./bin" compress="${compress}" includes="**/*.class, **/*.properties"/>
|
||||
<delete dir="${build}/bin"/>-->
|
||||
</target>
|
||||
<target name="clean" description="Cleans the old build files from disk.">
|
||||
<delete dir="${build}"/>
|
||||
</target>
|
||||
</project>
|
||||
16
Common/ivy.xml
Normal file
16
Common/ivy.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ivy-module version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
|
||||
<!-- status is one of "release", "milestone", or "integration" -->
|
||||
<info organisation="com.declarativeengineering" module="Common" status="integration">
|
||||
<repository name="ibiblio" url="http://media:8081/artifactory/libs-release" pattern="[organization]/[module]/[revision]/[module]-[revision](-[classifier]).[ext]" artifacts="true"/>
|
||||
</info>
|
||||
<!--
|
||||
<dependancies>
|
||||
<dependancy org="org.tigris.subversion" name="svnant" rev="latest.release"/>
|
||||
</dependancies>
|
||||
-->
|
||||
<publications>
|
||||
<artifact name="DE Common" type="bin" ext="jar"/>
|
||||
<artifact name="DE Common" type="src" ext="zip"/>
|
||||
</publications>
|
||||
</ivy-module>
|
||||
14
Common/ivysettings.xml
Normal file
14
Common/ivysettings.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ivy-settings>
|
||||
<settings defaultResolver="main"/>
|
||||
<!--<caches defaultCacheDir="./cache/" checkUpToDate="false"/>-->
|
||||
<resolvers>
|
||||
<chain name="main">
|
||||
<ibiblio name="remote-repos-resolver" m2compatible="true" root="http://media:8081/artifactory/remote-repos"/>
|
||||
<url name="libs-release-resolver" m2compatible="true">
|
||||
<artifact pattern="http://media:8081/artifactory/libs-release/[organization]/[module]/[revision]/[module]-[revision](-[classifier]).[ext]"/>
|
||||
<ivy pattern="http://media:8081/artifactory/libs-release/[organization]/[module]/[revision]/[module]-[revision](-[classifier]).pom"/>
|
||||
</url>
|
||||
</chain>
|
||||
</resolvers>
|
||||
</ivy-settings>
|
||||
416
Common/src/com/common/comparison/Comparator.java
Normal file
416
Common/src/com/common/comparison/Comparator.java
Normal file
@@ -0,0 +1,416 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.comparison;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.text.Collator;
|
||||
|
||||
/**
|
||||
* Defines utility methods and the basic structure of a comparator which compares two objects for equality and/or ordering.
|
||||
*/
|
||||
public abstract class Comparator implements IComparator {
|
||||
private static final IComparator identityComparator = new IdentityComparator();
|
||||
private static final IComparator logicalComparator = new LogicalComparator();
|
||||
private static final IComparator stringComparator = new StringComparator();
|
||||
private static final IComparator numericStringComparator = new NumericStringComparator();
|
||||
|
||||
/**
|
||||
* A simple identity comparitor which uses the equals operator for comparison. The results will only reflect equality.
|
||||
*/
|
||||
public static class IdentityComparator extends Comparator {
|
||||
/**
|
||||
* IdentityComparator constructor.
|
||||
*/
|
||||
public IdentityComparator() {
|
||||
}//IdentityComparator()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.comparison.IComparator#compare(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
public int compare(Object value1, Object value2) {
|
||||
if(value1 instanceof IComparable) {
|
||||
return ((IComparable) value1).equalsEquals(value2) ? EQUAL : NOT_EQUAL;
|
||||
}//if//
|
||||
else {
|
||||
return value1 == value2 ? EQUAL : NOT_EQUAL;
|
||||
}//else//
|
||||
}//compare//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.comparison.Comparator#hash(java.lang.Object)
|
||||
*/
|
||||
public int hash(Object value) {
|
||||
return System.identityHashCode(value);
|
||||
}//hash()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object object) {
|
||||
return object instanceof IdentityComparator;
|
||||
}//equals()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return IdentityComparator.class.hashCode();
|
||||
}//hashCode()//
|
||||
}//IdentityComparator//
|
||||
/**
|
||||
* A simple logical comparator using the built in equals method for comparison. The results will only reflect equality.
|
||||
*/
|
||||
public static class LogicalComparator extends Comparator {
|
||||
/**
|
||||
* LogicalComparator constructor.
|
||||
*/
|
||||
public LogicalComparator() {
|
||||
}//LogicalComparator()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.comparison.IComparator#compare(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
public int compare(Object value1, Object value2) {
|
||||
return (value1 == null ? (value2 == null ? EQUAL : NOT_EQUAL) : (value1.equals(value2) ? EQUAL : NOT_EQUAL));
|
||||
}//compare//
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object object) {
|
||||
return object instanceof LogicalComparator;
|
||||
}//equals()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return LogicalComparator.class.hashCode();
|
||||
}//hashCode()//
|
||||
}//LogicalComparator//
|
||||
/**
|
||||
* A basic string logical comparator.
|
||||
*/
|
||||
public static class StringComparator extends Comparator {
|
||||
/** Whether the comparator only needs to test for equality and can ignore which is greater or less. This optimizes the string comparison since equals(..) is far faster than compare(..) for text. This is ignored if a collator is specified since a collator takes fancy text conversions into account, rendering a length test useless. */
|
||||
private boolean checkEqualityOnly = false;
|
||||
/** Whether to check case. This is ignored if a collator is used. */
|
||||
private boolean caseSensitive = true;
|
||||
/** The collator used when searching. */
|
||||
private Collator collator = null;
|
||||
|
||||
/**
|
||||
* StringComparator constructor.
|
||||
*/
|
||||
public StringComparator() {
|
||||
}//StringComparator()//
|
||||
/**
|
||||
* StringComparator constructor.
|
||||
* @param caseSensitive Whether the strings are case sensitive.
|
||||
*/
|
||||
public StringComparator(boolean caseSensitive) {
|
||||
this.caseSensitive = caseSensitive;
|
||||
}//StringComparator()//
|
||||
/**
|
||||
* StringComparator constructor.
|
||||
* @param caseSensitive Whether the strings are case sensitive.
|
||||
* @param checkEqualityOnly Optimizes the comparator since testing a string for equality is far faster (10x) than testing to see which is greater or less than the other.
|
||||
*/
|
||||
public StringComparator(boolean caseSensitive, boolean checkEqualityOnly) {
|
||||
this.caseSensitive = caseSensitive;
|
||||
this.checkEqualityOnly = checkEqualityOnly;
|
||||
}//StringComparator()//
|
||||
/**
|
||||
* StringComparator constructor.
|
||||
* @param collator The custom collator to use for comparing strings. This provides maximum multi-ligual capabilities.
|
||||
*/
|
||||
public StringComparator(Collator collator) {
|
||||
this.collator = collator;
|
||||
}//StringComparator()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.comparison.IComparator#compare(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
public int compare(Object value1, Object value2) {
|
||||
if(value1 == null) {
|
||||
return value2 == null ? EQUAL : LESS_THAN;
|
||||
}//if//
|
||||
else if(value2 == null) {
|
||||
return GREATER_THAN;
|
||||
}//else if//
|
||||
else {
|
||||
if(collator != null) {
|
||||
return collator.compare((String) value1, (String) value2);
|
||||
}//if//
|
||||
else if(checkEqualityOnly) {
|
||||
return (caseSensitive ? ((String) value1).equals((String) value2) : ((String) value1).equalsIgnoreCase((String) value2)) ? EQUAL : NOT_EQUAL;
|
||||
}//else if//
|
||||
else {
|
||||
int value = caseSensitive ? ((String) value1).compareTo((String) value2) : ((String) value1).compareToIgnoreCase((String) value2);
|
||||
|
||||
return (value < 0 ? LESS_THAN : (value > 0 ? GREATER_THAN : EQUAL));
|
||||
}//else//
|
||||
}//else//
|
||||
}//compare//
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object object) {
|
||||
return object instanceof StringComparator;
|
||||
}//equals()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return StringComparator.class.hashCode();
|
||||
}//hashCode()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.comparison.Comparator#hash(java.lang.Object)
|
||||
*/
|
||||
public int hash(Object value) {
|
||||
return ((String) value).toLowerCase().hashCode();
|
||||
}//hash()//
|
||||
}//StringComparator//
|
||||
/**
|
||||
* A more complex string comparator which recognizes numbers embedded in the string and compares them as numbers, not as characters.
|
||||
*/
|
||||
public static class NumericStringComparator extends Comparator {
|
||||
private boolean placeNumbersBeforeText = true;
|
||||
|
||||
/**
|
||||
* NumericStringComparator constructor.
|
||||
*/
|
||||
public NumericStringComparator() {
|
||||
}//NumericStringComparator()//
|
||||
/**
|
||||
* NumericStringComparator constructor.
|
||||
* @param placeNumbersBeforeText Whether numbers should preceed text in ordering.
|
||||
*/
|
||||
public NumericStringComparator(boolean placeNumbersBeforeText) {
|
||||
this.placeNumbersBeforeText = placeNumbersBeforeText;
|
||||
}//NumericStringComparator()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.comparison.IComparator#compare(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
public int compare(Object value1, Object value2) {
|
||||
int result = EQUAL;
|
||||
|
||||
if(value1 == null) {
|
||||
result = value2 == null ? EQUAL : LESS_THAN;
|
||||
}//if//
|
||||
else if(value2 == null) {
|
||||
result = GREATER_THAN;
|
||||
}//else if//
|
||||
else if((value1 instanceof String) && (value2 instanceof String)) {
|
||||
String text1 = (String) value1;
|
||||
String text2 = (String) value2;
|
||||
|
||||
for(int index1 = 0, index2 = 0; result == 0; index1++, index2++) {
|
||||
char ch1 = 0;
|
||||
char ch2 = 0;
|
||||
|
||||
if(index1 >= text1.length() && index2 >= text2.length()) {
|
||||
break;
|
||||
}//if//
|
||||
else if(index1 >= text1.length()) {
|
||||
result = LESS_THAN;
|
||||
}//else if//
|
||||
else if(index2 >= text2.length()) {
|
||||
result = GREATER_THAN;
|
||||
}//else if//
|
||||
|
||||
if(result == 0) {
|
||||
boolean ch1IsDigit = false;
|
||||
boolean ch2IsDigit = false;
|
||||
|
||||
ch1 = text1.charAt(index1);
|
||||
ch2 = text2.charAt(index2);
|
||||
|
||||
//Allow a number to begin with a decimal point.//
|
||||
if(ch1 == '.') {
|
||||
ch1IsDigit = (text1.length() > index1 + 1) && (Character.isDigit(text1.charAt(index1 + 1)));
|
||||
}//if//
|
||||
else {
|
||||
ch1IsDigit = Character.isDigit(ch1);
|
||||
}//else//
|
||||
|
||||
if(ch2 == '.') {
|
||||
ch2IsDigit = (text2.length() > index2 + 1) && (Character.isDigit(text2.charAt(index2 + 1)));
|
||||
}//if//
|
||||
else {
|
||||
ch2IsDigit = Character.isDigit(ch2);
|
||||
}//else//
|
||||
|
||||
//If they are both numbers then compare them.//
|
||||
if(ch1IsDigit && ch2IsDigit) {
|
||||
int endIndex1 = getLastDigitIndex(text1, index1);
|
||||
int endIndex2 = getLastDigitIndex(text2, index2);
|
||||
//int number1 = Integer.parseInt(text1.substring(index1, endIndex1 + 1));
|
||||
//int number2 = Integer.parseInt(text2.substring(index2, endIndex2 + 1));
|
||||
BigDecimal number1 = new BigDecimal(text1.substring(index1, endIndex1 + 1));
|
||||
BigDecimal number2 = new BigDecimal(text2.substring(index2, endIndex2 + 1));
|
||||
|
||||
//if(number1 != number2) {
|
||||
// result = number1 < number2 ? LESS_THAN : GREATER_THAN;
|
||||
//}//if//
|
||||
if(!number1.equals(number2)) {
|
||||
result = number1.compareTo(number2) < 0 ? LESS_THAN : GREATER_THAN;
|
||||
}//if//
|
||||
|
||||
index1 = endIndex1;
|
||||
index2 = endIndex2;
|
||||
}//if//
|
||||
else if(ch1IsDigit) {
|
||||
result = placeNumbersBeforeText ? LESS_THAN : GREATER_THAN;
|
||||
}//else if//
|
||||
else if(ch2IsDigit) {
|
||||
result = placeNumbersBeforeText ? GREATER_THAN : LESS_THAN;
|
||||
}//else if//
|
||||
else {
|
||||
if(ch1 != ch2) {
|
||||
result = ch1 < ch2 ? LESS_THAN : GREATER_THAN;
|
||||
}//if//
|
||||
}//else//
|
||||
}//if//
|
||||
}//for//
|
||||
}//else if//
|
||||
else if(value1 instanceof String) {
|
||||
result = LESS_THAN;
|
||||
}//else if//
|
||||
else if(value2 instanceof String) {
|
||||
result = GREATER_THAN;
|
||||
}//else if//
|
||||
else {
|
||||
result = EQUAL;
|
||||
}//else//
|
||||
|
||||
return result;
|
||||
}//compare//
|
||||
/**
|
||||
* Gets the last index that is a digit.
|
||||
* @param text The text to search.
|
||||
* @param startIndex The index to start from.
|
||||
* @return The last index that is a digit (inclusive).
|
||||
*/
|
||||
private int getLastDigitIndex(String text, int startIndex) {
|
||||
int result = startIndex + 1;
|
||||
|
||||
while((result < text.length()) && (Character.isDigit(text.charAt(result)))) {
|
||||
result++;
|
||||
}//while//
|
||||
|
||||
return result - 1;
|
||||
}//getLastDigitIndex()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object object) {
|
||||
return object instanceof StringComparator;
|
||||
}//equals()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return NumericStringComparator.class.hashCode();
|
||||
}//hashCode()//
|
||||
}//NumericStringComparator//
|
||||
/**
|
||||
* Comparator constructor.
|
||||
*/
|
||||
public Comparator() {
|
||||
super();
|
||||
}//Comparator()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.comparison.IComparator#compare(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
public abstract int compare(Object value1, Object value2);
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.comparison.IComparator#hash(java.lang.Object)
|
||||
*/
|
||||
public int hash(Object value) {
|
||||
return value.hashCode();
|
||||
}//hash()//
|
||||
/**
|
||||
* Gets the common identity comparator which can be used to check for two identical objects.
|
||||
* @return A commonly used comparator used to check for exact equality.
|
||||
*/
|
||||
public static IComparator getIdentityComparator() {
|
||||
return identityComparator;
|
||||
}//getIdentityComparator()//
|
||||
/**
|
||||
* Gets the common identity comparator which can be used to check for two identical objects.
|
||||
* @return A commonly used comparator used to check for aproximate equality.
|
||||
*/
|
||||
public static IComparator getLogicalComparator() {
|
||||
return logicalComparator;
|
||||
}//getLogicalComparator()//
|
||||
/**
|
||||
* Gets the common string comparator which can be used to check for two logically equal strings.
|
||||
* @return A commonly used comparator used to check for aproximate equality of two strings.
|
||||
*/
|
||||
public static IComparator getStringComparator() {
|
||||
return stringComparator;
|
||||
}//getStringComparator()//
|
||||
/**
|
||||
* Gets the common string comparator which can be used to check for two logically equal strings.
|
||||
* @return A commonly used comparator used to check for aproximate equality of two strings.
|
||||
*/
|
||||
public static IComparator getNumericStringComparator() {
|
||||
return numericStringComparator;
|
||||
}//getStringComparator()//
|
||||
/**
|
||||
* Checks a value returned by the compare method to see if it represents equality.
|
||||
* @param comparisonValue The value returned by the compare method.
|
||||
* @return Will be true if the comparison value indicates equality.
|
||||
*/
|
||||
public static boolean isEqual(int comparisonValue) {
|
||||
return comparisonValue == EQUAL;
|
||||
}//isEqual()//
|
||||
/**
|
||||
* Checks a value returned by the compare method to see if the method indicated that value1 was less than value2.
|
||||
* @param comparisonValue The value returned by the compare method.
|
||||
* @return Will be true if the comparison value indicates value1 is greater than value2.
|
||||
*/
|
||||
public static boolean isGreaterThan(int comparisonValue) {
|
||||
return comparisonValue > EQUAL;
|
||||
}//isGreaterThan()//
|
||||
/**
|
||||
* Checks a value returned by the compare method to see if the method indicated that value1 was less than value2.
|
||||
* @param comparisonValue The value returned by the compare method.
|
||||
* @return Will be true if the comparison value indicates value1 is less than value2.
|
||||
*/
|
||||
public static boolean isLessThan(int comparisonValue) {
|
||||
return comparisonValue < EQUAL;
|
||||
}//isLessThan()//
|
||||
/**
|
||||
* Determines whether the two objects are logically equal by using the java.lang.Object.equals(java.lang.Object) method.
|
||||
* This method is useful because it accepts null parameters.
|
||||
* @param object1 The first object to compare. This value may be null.
|
||||
* @param object2 The second object to compare. This value may be null.
|
||||
* @return Whether the two objects are logically equal (not necessarily the exact same object).
|
||||
*/
|
||||
public static boolean equals(Object object1, Object object2) {
|
||||
boolean result = false;
|
||||
|
||||
if(object1 != null) {
|
||||
if((object2 instanceof Comparable) && (object2.getClass().equals(object1.getClass()))) {
|
||||
result = ((Comparable) object2).compareTo(object1) == 0;
|
||||
}//if//
|
||||
else {
|
||||
result = object1.equals(object2);
|
||||
}//else//
|
||||
}//else if//
|
||||
else {
|
||||
result = object2 == null;
|
||||
}//else//
|
||||
|
||||
return result;
|
||||
}//equals()//
|
||||
/**
|
||||
* Allows the serialization of this type.
|
||||
*/
|
||||
public void readExternal(java.io.ObjectInput in) throws java.io.IOException, ClassNotFoundException {
|
||||
}//readExternal()//
|
||||
/**
|
||||
* Allows the serialization of this type.
|
||||
*/
|
||||
public void writeExternal(java.io.ObjectOutput out) throws java.io.IOException {
|
||||
}//writeExternal()//
|
||||
}//Comparator//
|
||||
33
Common/src/com/common/comparison/IComparable.java
Normal file
33
Common/src/com/common/comparison/IComparable.java
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.comparison;
|
||||
|
||||
public interface IComparable extends Comparable {
|
||||
public static final int EQUAL = IComparator.EQUAL;
|
||||
public static final int NOT_EQUAL = IComparator.NOT_EQUAL;
|
||||
public static final int LESS_THAN = IComparator.LESS_THAN;
|
||||
public static final int GREATER_THAN = IComparator.GREATER_THAN;
|
||||
/**
|
||||
* Compares the object with another object for the purpose of determining order.
|
||||
* @param object The object to compare this object with.
|
||||
* @return A number greater than zero if this object is greater than the passed object, or less than zero if it is less than, or zero if they are equal.
|
||||
*/
|
||||
public int compareTo(Object object);
|
||||
/**
|
||||
* Checks to see if the two objects are similar enough to be considered equal.
|
||||
* @param object The object to compare this object with.
|
||||
* @return Will be true if the objects are logically equivalent.
|
||||
*/
|
||||
public boolean equals(Object object);
|
||||
/**
|
||||
* Checks to see if the two objects are exactly equal, that is to say that they occupy the same memory space.
|
||||
* @param object The object to compare this object with.
|
||||
* @return Will be true if the objects are identical, otherwise false.
|
||||
*/
|
||||
public boolean equalsEquals(Object object);
|
||||
}//IComparable//
|
||||
34
Common/src/com/common/comparison/IComparator.java
Normal file
34
Common/src/com/common/comparison/IComparator.java
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2008 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.comparison;
|
||||
|
||||
public interface IComparator extends java.io.Externalizable, java.util.Comparator {
|
||||
public static final int EQUAL = 0;
|
||||
public static final int NOT_EQUAL = -1;
|
||||
public static final int LESS_THAN = -1;
|
||||
public static final int GREATER_THAN = 1;
|
||||
/**
|
||||
* Gets a relative comparison of the two values.
|
||||
* <p>If value1 < value2 then a negative integer will be returned.
|
||||
* <p>If value1 = value2 then zero will be returned.
|
||||
* <p>If value1 > value2 then a positive integer will be returned.
|
||||
* @param value1 The first value to compare. This value is to the left of the operator.
|
||||
* @param value2 The second value to compare. This value is to the right of the operator.
|
||||
* @return A number representing the operator that accuratly compares the two values. The value will be greater than zero if value1 > value2; less than zero if value1 < value2; and zero if the values are equal.
|
||||
* @see Comparator.isEqaul(int)
|
||||
* @see Comparator.isLessThan(int)
|
||||
* @see Comparator.isGreaterThan(int)
|
||||
*/
|
||||
public int compare(Object value1, Object value2);
|
||||
/**
|
||||
* Hashes the value using the comparator's hash mechanism.
|
||||
* @param value The value to be hashed.
|
||||
* @return The resulting hash.
|
||||
*/
|
||||
public int hash(Object value);
|
||||
}//IComparator//
|
||||
60
Common/src/com/common/debug/ConsoleLog.java
Normal file
60
Common/src/com/common/debug/ConsoleLog.java
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.debug;
|
||||
|
||||
/**
|
||||
* This should be the base class for application specific logs.
|
||||
*/
|
||||
public class ConsoleLog implements ILog {
|
||||
private String lineSeparator = System.getProperty("line.separator");
|
||||
/**
|
||||
* DefaultLog constructor.
|
||||
*/
|
||||
public ConsoleLog() {
|
||||
super();
|
||||
}//ConsoleLog()//
|
||||
/**
|
||||
* Allows for common application specific handling of some exceptions.
|
||||
* The default log's behavior is to rethrow ThreadDeath exceptions and InterruptedExceptions so that threads can properly terminate.
|
||||
*/
|
||||
public void handle(Throwable exception) {
|
||||
if(exception instanceof ThreadDeath) {
|
||||
throw (ThreadDeath) exception;
|
||||
}//if//
|
||||
else if(exception instanceof InterruptedException) {
|
||||
Thread.currentThread().interrupt();
|
||||
}//else if//
|
||||
}//handle()//
|
||||
/**
|
||||
* The default is to print the stack trace to the standard output stream.
|
||||
*/
|
||||
public synchronized void log(String note, Throwable exception, int type, boolean display) {
|
||||
if(note != null && note.trim().length() > 0 && !note.equals("null")) {
|
||||
System.out.print(note + lineSeparator);
|
||||
}//if//
|
||||
|
||||
if(exception != null) {
|
||||
printException(exception);
|
||||
}//if//
|
||||
}//log()//
|
||||
/**
|
||||
* Recursively prints the exceptions in order of occurance.
|
||||
* @param exception The exception to print.
|
||||
*/
|
||||
private void printException(Throwable exception) {
|
||||
if(exception.getCause() != null) {
|
||||
printException(exception.getCause());
|
||||
}//if//
|
||||
|
||||
// if(exception.getMessage() != null && exception.getMessage().trim().length() > 0) {
|
||||
// System.out.println(exception.getMessage());
|
||||
// }//if//
|
||||
|
||||
exception.printStackTrace();
|
||||
}//printException()//
|
||||
}//DefaultLog//
|
||||
144
Common/src/com/common/debug/Debug.java
Normal file
144
Common/src/com/common/debug/Debug.java
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 2009,2007 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt */
|
||||
package com.common.debug;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* This is where all the orb debug information gets sent to.
|
||||
* A custom log can be specified by overriding DefaultDebugLog or implementing IDebugLog & calling OrbDebugLog.getSingleton().setDebugLog(myDebugLog);
|
||||
*/
|
||||
public final class Debug {
|
||||
public static final int TYPE_ERROR = ILog.TYPE_ERROR;
|
||||
public static final int TYPE_WARNING = ILog.TYPE_WARNING;
|
||||
public static final int TYPE_INFORMATION = ILog.TYPE_INFORMATION;
|
||||
|
||||
private static ILog log = null;
|
||||
/**
|
||||
* OrbDebugLog constructor.
|
||||
*/
|
||||
private Debug() {
|
||||
super();
|
||||
}//OrbDebugLog()//
|
||||
/**
|
||||
* Creates a string containing the full stack for the exception.
|
||||
* @param e The exception.
|
||||
* @return The stack text.
|
||||
*/
|
||||
public static String getExceptionStack(Throwable e) {
|
||||
StringWriter stringWriter = new StringWriter();
|
||||
|
||||
e.printStackTrace(new PrintWriter(stringWriter));
|
||||
|
||||
return stringWriter.toString();
|
||||
}//getExceptionStack()//
|
||||
/**
|
||||
* Gets the current debug log.
|
||||
*/
|
||||
public static ILog getLog() {
|
||||
if(log == null) {
|
||||
//setLog(new FrameLog());
|
||||
//((com.common.debug.FrameLog) getLog()).setVisible(true);
|
||||
setLog(new DefaultLog());
|
||||
}//if//
|
||||
|
||||
return log;
|
||||
}//getLog()//
|
||||
public static void halt() {
|
||||
try {
|
||||
Class debugSupportClass = Class.forName("com.ibm.uvm.tools.DebugSupport");
|
||||
Method haltMethod = debugSupportClass.getMethod("halt", new Class[0]);
|
||||
|
||||
haltMethod.invoke(null, new Object[0]);
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
}//catch//
|
||||
}//halt()//
|
||||
/**
|
||||
* Allows for common application specific handling of some exceptions.
|
||||
* The default log's behavior is to rethrow ThreadDeath exceptions and InterruptedExceptions so that threads can properly terminate.
|
||||
*/
|
||||
public static void handle(Throwable exception) {
|
||||
getLog().handle(exception);
|
||||
}//handle()//
|
||||
/**
|
||||
* Determines if a log has been set yet.
|
||||
*/
|
||||
public static boolean hasLog() {
|
||||
return log != null;
|
||||
}//hasLog()//
|
||||
public static void log(String note) {
|
||||
getLog().log(note, null, ILog.TYPE_INFORMATION, false);
|
||||
}//log()//
|
||||
public static void log(String note, boolean forceDisplay) {
|
||||
getLog().log(note, null, ILog.TYPE_INFORMATION, forceDisplay);
|
||||
}//log()//
|
||||
public static void log(Throwable exception) {
|
||||
getLog().log(null, exception, ILog.TYPE_ERROR, true);
|
||||
}//log()//
|
||||
public static void log(String note, Throwable exception) {
|
||||
getLog().log(note, exception, exception == null ? ILog.TYPE_INFORMATION : ILog.TYPE_ERROR, true);
|
||||
}//log()//
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public static void log(Throwable exception, String note) {
|
||||
getLog().log(note, exception, exception == null ? ILog.TYPE_INFORMATION : ILog.TYPE_ERROR, true);
|
||||
}//log()//
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public static void log(Throwable exception, String note, boolean forceDisplay) {
|
||||
getLog().log(note, exception, exception == null ? ILog.TYPE_INFORMATION : ILog.TYPE_ERROR, forceDisplay);
|
||||
}//log()//
|
||||
public static void log(String note, Throwable exception, boolean forceDisplay) {
|
||||
getLog().log(note, exception, exception == null ? ILog.TYPE_INFORMATION : ILog.TYPE_ERROR, forceDisplay);
|
||||
}//log()//
|
||||
public static void log(Throwable exception, boolean forceDisplay) {
|
||||
getLog().log(null, exception, ILog.TYPE_ERROR, forceDisplay);
|
||||
}//log()//
|
||||
public static void log(Object location, String note) {
|
||||
log(ILog.TYPE_INFORMATION, location, note);
|
||||
}//log()//
|
||||
public static void log(int type, String note) {
|
||||
getLog().log(note, null, type, false);
|
||||
}//log()//
|
||||
public static void log(int type, String note, boolean forceDisplay) {
|
||||
getLog().log(note, null, type, forceDisplay);
|
||||
}//log()//
|
||||
public static void log(int type, Throwable exception) {
|
||||
getLog().log(null, exception, type, true);
|
||||
}//log()//
|
||||
public static void log(int type, Throwable exception, boolean forceDisplay) {
|
||||
getLog().log(null, exception, type, forceDisplay);
|
||||
}//log()//
|
||||
public static void log(int type, String note, Throwable exception) {
|
||||
getLog().log(note, exception, type, true);
|
||||
}//log()//
|
||||
public static void log(int type, String note, Throwable exception, boolean forceDisplay) {
|
||||
getLog().log(note, exception, type, forceDisplay);
|
||||
}//log()//
|
||||
public static void log(int type, Object location, String note) {
|
||||
if(location != null) {
|
||||
String completeNote = "\r\n" + location.toString() + "\r\n" + note;
|
||||
|
||||
getLog().log(completeNote, null, type, true);
|
||||
}//if//
|
||||
else {
|
||||
log(note);
|
||||
}//else//
|
||||
}//log()//
|
||||
/**
|
||||
* Sets an application defined debug log object.
|
||||
* @param log ILog A log object that handles debug logging for the application.
|
||||
*/
|
||||
public static void setLog(ILog _log) {
|
||||
log = _log;
|
||||
}//setLog()//
|
||||
}//DebugSupport//
|
||||
20
Common/src/com/common/debug/DefaultLog.java
Normal file
20
Common/src/com/common/debug/DefaultLog.java
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.debug;
|
||||
|
||||
/**
|
||||
* This should be the base class for application specific logs.
|
||||
*/
|
||||
public class DefaultLog extends ConsoleLog {
|
||||
/**
|
||||
* DefaultLog constructor.
|
||||
*/
|
||||
public DefaultLog() {
|
||||
super();
|
||||
}//DefaultLog()//
|
||||
}//DefaultLog//
|
||||
110
Common/src/com/common/debug/FileLog.java
Normal file
110
Common/src/com/common/debug/FileLog.java
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 2003,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.debug;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Date;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
/**
|
||||
* Logs all output to a single log file.
|
||||
*/
|
||||
public class FileLog extends ConsoleLog {
|
||||
private DateFormat dateFormat = new SimpleDateFormat("MM/dd hh:mm:ss:SSS a");
|
||||
private File file = null;
|
||||
private File path = null;
|
||||
private String lineSeparator = System.getProperty("line.separator");
|
||||
/**
|
||||
* DefaultLog constructor.
|
||||
*/
|
||||
public FileLog() {
|
||||
this(new File('.' + System.getProperty("path.separator") + "log.txt"));
|
||||
}//FileLog()//
|
||||
/**
|
||||
* DefaultLog constructor.
|
||||
*/
|
||||
public FileLog(File file) {
|
||||
super();
|
||||
|
||||
this.path = new File(file.getParent());
|
||||
this.file = file;
|
||||
|
||||
//Clear previous log data.//
|
||||
if(file.exists()) {
|
||||
try {
|
||||
file.delete();
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
//Ignore.//
|
||||
}//catch//
|
||||
}//if//
|
||||
}//FileLog()//
|
||||
/**
|
||||
* The default is to print the stack trace to the standard output stream.
|
||||
* @param note The note to be logged.
|
||||
* @param exception The exception to be logged.
|
||||
* @param display Whether to force the log output. This is currently ignored.
|
||||
*/
|
||||
public synchronized void log(String note, Throwable exception, int type, boolean display) {
|
||||
try {
|
||||
PrintWriter writer = null;
|
||||
|
||||
if(!path.exists()) {
|
||||
if(!path.mkdirs()) {
|
||||
System.out.println("Unable to create the required log directory.");
|
||||
}//if//
|
||||
}//if//
|
||||
|
||||
if(path.exists()) {
|
||||
writer = new PrintWriter(new FileWriter(file.toString(), file.exists()));
|
||||
}//if//
|
||||
|
||||
writer.write(dateFormat.format(new Date()));
|
||||
writer.write('\t');
|
||||
|
||||
//Write the note if there is one.//
|
||||
if(note != null && note.trim().length() > 0) {
|
||||
writer.write(note);
|
||||
}//if//
|
||||
|
||||
//Write the exception if there is one.//
|
||||
if(exception != null) {
|
||||
if(note != null) {
|
||||
writer.write(lineSeparator);
|
||||
}//if//
|
||||
|
||||
printException(writer, exception);
|
||||
}//if//
|
||||
|
||||
writer.write(lineSeparator);
|
||||
writer.close();
|
||||
}//try//
|
||||
catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
}//catch//
|
||||
}//log()//
|
||||
/**
|
||||
* Recursively prints the exceptions in order of occurance.
|
||||
* @param writer The writer to use for printing.
|
||||
* @param exception The exception to print.
|
||||
*/
|
||||
private void printException(PrintWriter writer, Throwable exception) {
|
||||
if(exception.getCause() != null) {
|
||||
printException(writer, exception.getCause());
|
||||
}//if//
|
||||
|
||||
if(exception.getMessage() != null && exception.getMessage().trim().length() > 0) {
|
||||
writer.write(exception.getMessage());
|
||||
writer.write(lineSeparator);
|
||||
}//if//
|
||||
|
||||
exception.printStackTrace(writer);
|
||||
writer.write(lineSeparator);
|
||||
}//printException()//
|
||||
}//FileLog//
|
||||
31
Common/src/com/common/debug/ILog.java
Normal file
31
Common/src/com/common/debug/ILog.java
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.debug;
|
||||
|
||||
/**
|
||||
* The ILog interface defines the basic structure of an application specific logging class.
|
||||
* This class will handle exceptions and debug notes for the application in an application specific way.
|
||||
*/
|
||||
public interface ILog {
|
||||
public static final int TYPE_ERROR = 0;
|
||||
public static final int TYPE_WARNING = 1;
|
||||
public static final int TYPE_INFORMATION = 2;
|
||||
/**
|
||||
* Allows for common application specific handling of some exceptions.
|
||||
* The default log's behavior is to rethrow ThreadDeath exceptions and InterruptedExceptions so that threads can properly terminate.
|
||||
*/
|
||||
public void handle(Throwable exception);
|
||||
/**
|
||||
* Handles logging a note and/or exception.
|
||||
* @param note String An optional note to be logged. If an exception is also specified, then the note should be bundled with the exception in the log output.
|
||||
* @param exception Throwable An optional exception to be logged.
|
||||
* @param type The type of log entry this is. One of the type codes.
|
||||
* @param forceDisplay boolean A flag indicating whether the note/exception should be displayed. The log may treat this how ever it desires.
|
||||
*/
|
||||
public void log(String note, Throwable exception, int type, boolean forceDisplay);
|
||||
}//ILog//
|
||||
171
Common/src/com/common/debug/QueuedLog.java
Normal file
171
Common/src/com/common/debug/QueuedLog.java
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.debug;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Date;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import com.common.util.IReversableIterator;
|
||||
import com.common.util.CircularQueue;
|
||||
|
||||
/**
|
||||
* Queues log entries and writes log files containing the queued entries when a display is requested.
|
||||
*/
|
||||
public class QueuedLog extends ConsoleLog {
|
||||
private DateFormat dateFormat = new SimpleDateFormat("MM/dd hh:mm:ss:SSS a");
|
||||
private File path = null;
|
||||
private String logFileNamePrefix = null;
|
||||
private String countFileName = null;
|
||||
private String lineSeparator = System.getProperty("line.separator");
|
||||
private CircularQueue queue = null;
|
||||
private boolean useTimestamps = false;
|
||||
private int fileIndex = 0;
|
||||
/** Whether to display the log content in order of descending time (newest to oldest log entry). */
|
||||
private boolean descendingTimeOrder = true;
|
||||
/**
|
||||
* QueuedLog constructor.
|
||||
*/
|
||||
public QueuedLog() {
|
||||
this(new File("."), 100, true);
|
||||
}//QueuedLog()//
|
||||
/**
|
||||
* QueuedLog constructor.
|
||||
* @param path The path where log files will be located.
|
||||
* @param queueSize The size of the circular queue.
|
||||
*/
|
||||
public QueuedLog(File path, int queueSize) {
|
||||
this(path, queueSize, true);
|
||||
}//QueuedLog()//
|
||||
/**
|
||||
* QueuedLog constructor.
|
||||
* @param path The path where log files will be located.
|
||||
* @param queueSize The size of the circular queue.
|
||||
* @param descendingTimeOrder Whether to display the log content in order of descending time (newest to oldest log entry).
|
||||
*/
|
||||
public QueuedLog(File path, int queueSize, boolean descendingTimeOrder) {
|
||||
super();
|
||||
|
||||
this.queue = new CircularQueue(queueSize);
|
||||
this.path = path == null ? new File(".") : path;
|
||||
this.countFileName = "count.txt";
|
||||
this.logFileNamePrefix = "log";
|
||||
this.descendingTimeOrder = descendingTimeOrder;
|
||||
}//QueuedLog()//
|
||||
/**
|
||||
* The default is to print the stack trace to the standard output stream.
|
||||
*/
|
||||
public synchronized void log(String note, Throwable exception, int type, boolean display) {
|
||||
StringWriter writer = new StringWriter((useTimestamps ? 9 : 0) + (note != null ? note.length() : 0) + (exception != null ? 400 : 0));
|
||||
|
||||
if(useTimestamps) {
|
||||
writer.write(dateFormat.format(new Date()));
|
||||
writer.write('\t');
|
||||
}//if//
|
||||
|
||||
if(note != null && note.trim().length() > 0) {
|
||||
writer.write(note);
|
||||
}//if//
|
||||
|
||||
if(exception != null) {
|
||||
PrintWriter printWriter = new PrintWriter(writer, true);
|
||||
|
||||
printException(printWriter, exception);
|
||||
}//if//
|
||||
|
||||
queue.enqueue(writer.getBuffer().toString());
|
||||
|
||||
if(display) {
|
||||
writeLogFile();
|
||||
}//if//
|
||||
}//log()//
|
||||
/**
|
||||
* Writes the a log file.
|
||||
*/
|
||||
public synchronized void writeLogFile() {
|
||||
try {
|
||||
PrintWriter writer = null;
|
||||
|
||||
if(!path.exists()) {
|
||||
if(!path.mkdirs()) {
|
||||
System.out.println("Unable to create the required log directory.");
|
||||
}//if//
|
||||
}//if//
|
||||
|
||||
if(path.exists()) {
|
||||
StringBuffer buffer = new StringBuffer(logFileNamePrefix.length() + 4);
|
||||
IReversableIterator iterator = null;
|
||||
|
||||
//Create the log file name.//
|
||||
buffer.append(logFileNamePrefix);
|
||||
|
||||
//Prefix the number with zero padding.//
|
||||
for(int count = Integer.toString(fileIndex).length(); count < 4; count++) {
|
||||
buffer.append('0');
|
||||
}//for//
|
||||
|
||||
buffer.append(fileIndex);
|
||||
buffer.append(".txt");
|
||||
//Write the log file.//
|
||||
writer = new PrintWriter(new FileWriter(new File(path, buffer.toString()), false));
|
||||
|
||||
writer.write("Below are the queued log entries beginning with the " + (descendingTimeOrder ? "most recent log and ending with the least recent" : "least recent log and ending with the most recent") + "...");
|
||||
writer.write(lineSeparator);
|
||||
writer.write("_______________________________________________________________________________________________________");
|
||||
writer.write(lineSeparator);
|
||||
iterator = queue.iterator();
|
||||
|
||||
if(descendingTimeOrder) {
|
||||
iterator.resetToBack();
|
||||
|
||||
//Write the log entries.//
|
||||
while(iterator.hasPrevious()) {
|
||||
writer.write(iterator.previous().toString());
|
||||
writer.write(lineSeparator);
|
||||
}//while//
|
||||
}//if//
|
||||
else {
|
||||
iterator.resetToFront();
|
||||
|
||||
//Write the log entries.//
|
||||
while(iterator.hasNext()) {
|
||||
writer.write(iterator.next().toString());
|
||||
writer.write(lineSeparator);
|
||||
}//while//
|
||||
}//else//
|
||||
|
||||
writer.close();
|
||||
//Write the count file.//
|
||||
writer = new PrintWriter(new FileWriter(new File(path, countFileName), false));
|
||||
writer.write("" + ++fileIndex);
|
||||
writer.close();
|
||||
}//if//
|
||||
}//try//
|
||||
catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
}//catch//
|
||||
}//writeLogFile()//
|
||||
/**
|
||||
* Recursively prints the exceptions in order of occurance.
|
||||
* @param writer The writer to use for printing.
|
||||
* @param exception The exception to print.
|
||||
*/
|
||||
private void printException(PrintWriter writer, Throwable exception) {
|
||||
if(exception.getCause() != null) {
|
||||
printException(writer, exception.getCause());
|
||||
}//if//
|
||||
|
||||
if(exception.getMessage() != null && exception.getMessage().trim().length() > 0) {
|
||||
writer.write(exception.getMessage());
|
||||
writer.write(lineSeparator);
|
||||
}//if//
|
||||
|
||||
exception.printStackTrace(writer);
|
||||
writer.write(lineSeparator);
|
||||
}//printException()//
|
||||
}//QueuedLog//
|
||||
113
Common/src/com/common/development/security/ElGamal.java
Normal file
113
Common/src/com/common/development/security/ElGamal.java
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2005,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
/*
|
||||
* TODO: Determine original source.
|
||||
*/
|
||||
package com.common.development.security;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import com.common.debug.*;
|
||||
import com.common.security.Random;
|
||||
|
||||
/**
|
||||
* This class contains the ElGamel Asymmetric algorithm's development time code.
|
||||
* This includes constant generation and testing algorithms.
|
||||
*/
|
||||
public class ElGamal {
|
||||
/** Use probable-primes with no more than a 2^-80 chance of being composite. */
|
||||
private static final int CONFIDENCE = 80;
|
||||
/** A reusable buffer to optimize memory useage. */
|
||||
private static final BigInteger ONE = BigInteger.valueOf(1L);
|
||||
/**
|
||||
* ElGamel constructor.
|
||||
*/
|
||||
public ElGamal() {
|
||||
super();
|
||||
}//ElGamel()//
|
||||
/**
|
||||
* Gets a generator mod <i>p</i>.
|
||||
* <i>q</i> is an array containing all the prime factors of <i>p-1</i>.
|
||||
* <p> This algorithm is based on Schneier page 254.
|
||||
* @param p
|
||||
* @param q
|
||||
* @param random The random number generator to use in the algorithm.
|
||||
* @return The g that fits the p and q parameters.
|
||||
*/
|
||||
private BigInteger findG(BigInteger p, BigInteger[] q, Random random) {
|
||||
BigInteger p_minus_1 = p.subtract(ONE);
|
||||
BigInteger[] z = new BigInteger[q.length];
|
||||
BigInteger g;
|
||||
int length = p.bitLength() - 1;
|
||||
|
||||
//z_i = (p-1)/q_i for each factor q_i//
|
||||
for(int i = 0; i < q.length; i++) {
|
||||
z[i] = p_minus_1.divide(q[i]);
|
||||
}//for//
|
||||
|
||||
while(true) {
|
||||
g = new BigInteger(length, random).setBit(length);
|
||||
|
||||
if(PrimeNumberGenerator.isGeneratorModP(g, p, z)) {
|
||||
return g;
|
||||
}//if//
|
||||
}//while//
|
||||
}//findG()//
|
||||
/**
|
||||
* Generates a prime number for use by ElGamal.
|
||||
* @param primeLength Must be greater than 256. Common values are: 512, 768, 1024, 2048, 4096.
|
||||
* @param random Any good random number generator.
|
||||
* @param primeType The type of prime number to use. Valid values are: Prime.NORMAL, Prime.STRONG, Prime.GERMAIN.
|
||||
*/
|
||||
public BigInteger[] generatePrime(int primeLength, Random random, int primeType) {
|
||||
Object[] result = PrimeNumberGenerator.getElGamal(primeLength, CONFIDENCE, random, primeType);
|
||||
BigInteger newP = (BigInteger) result[0];
|
||||
BigInteger[] q = (BigInteger[]) result[1];
|
||||
BigInteger newG = findG(newP, q, random);
|
||||
|
||||
return new BigInteger[] {newP, newG};
|
||||
}//generatePrime()//
|
||||
/**
|
||||
* Generates a prime length pair (elgamal constants)
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
int primeLength = 1024;
|
||||
BigInteger[] pg = new ElGamal().generatePrime(primeLength, new com.common.security.Random(), PrimeNumberGenerator.STRONG);
|
||||
|
||||
testPrime(primeLength, pg[0], pg[1]);
|
||||
Debug.log("p=");
|
||||
Debug.log(pg[0].toString(16));
|
||||
Debug.log("g=");
|
||||
Debug.log(pg[1].toString(16));
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
e.printStackTrace();
|
||||
}//catch//
|
||||
|
||||
System.exit(0);
|
||||
}//main()//
|
||||
/**
|
||||
* Tests the prime number values to ensure they are correct.
|
||||
* @param primeLength The number of bits in the prime number.
|
||||
* @param p The P prime number.
|
||||
* @param g The G prime number.
|
||||
*/
|
||||
public static void testPrime(int primeLength, BigInteger p, BigInteger g) {
|
||||
if(p.bitLength() < primeLength) {
|
||||
throw new SecurityException(p + " has incorrect bit length");
|
||||
}//if//
|
||||
|
||||
if(!p.isProbablePrime(80)) {
|
||||
throw new SecurityException(p + " is not prime");
|
||||
}//if//
|
||||
|
||||
if(g.compareTo(p) >= 0) {
|
||||
throw new SecurityException("g >= p");
|
||||
}//if//
|
||||
}//testPrime()//
|
||||
}//ElGamel//
|
||||
@@ -0,0 +1,903 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
/*
|
||||
* TODO: Determine original source.
|
||||
*/
|
||||
package com.common.development.security;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import com.common.util.LiteList;
|
||||
import com.common.security.Random;
|
||||
|
||||
/**
|
||||
* This class houses a number of methods for generating prime numbers using different algorithms.
|
||||
*/
|
||||
public class PrimeNumberGenerator {
|
||||
private static final BigInteger ZERO = BigInteger.valueOf(0L);
|
||||
private static final BigInteger ONE = BigInteger.valueOf(1L);
|
||||
private static final BigInteger TWO = BigInteger.valueOf(2L);
|
||||
|
||||
/**
|
||||
* Identifies a plain prime number.
|
||||
*/
|
||||
public static final int PLAIN = 0;
|
||||
/**
|
||||
* Identifies a cryptographically strong prime number.
|
||||
*/
|
||||
public static final int STRONG = 1;
|
||||
/**
|
||||
* Identifies a Germain prime number.
|
||||
*/
|
||||
public static final int GERMAIN = 2;
|
||||
|
||||
/**
|
||||
* Maintains a collection of small prime numbers so as to optmize things.
|
||||
*/
|
||||
private static BigInteger[] SMALL_PRIMES;
|
||||
|
||||
private static byte[] PRIME_BITMAP;
|
||||
private static final int PRIME_BITMAP_SIZE = 30030; // 2*3*5*7*11*13 //
|
||||
private static final BigInteger PRIME_BITMAP_MOD = BigInteger.valueOf(PRIME_BITMAP_SIZE);
|
||||
|
||||
private static final int SMALL_PRIME_THRESHOLD = 100;
|
||||
private static BigInteger SMALL_PRIME_MOD;
|
||||
|
||||
static {
|
||||
//This array was generated by "java cryptix.examples.math.ListPrimes 50000".//
|
||||
int[] sp = {
|
||||
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, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069,
|
||||
1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
|
||||
1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223,
|
||||
1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291,
|
||||
1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373,
|
||||
1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
|
||||
1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511,
|
||||
1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583,
|
||||
1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657,
|
||||
1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,
|
||||
1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811,
|
||||
1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889,
|
||||
1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987,
|
||||
1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053,
|
||||
2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129,
|
||||
2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213,
|
||||
2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287,
|
||||
2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357,
|
||||
2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423,
|
||||
2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531,
|
||||
2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617,
|
||||
2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687,
|
||||
2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741,
|
||||
2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819,
|
||||
2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903,
|
||||
2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999,
|
||||
3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079,
|
||||
3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181,
|
||||
3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257,
|
||||
3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331,
|
||||
3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413,
|
||||
3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511,
|
||||
3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571,
|
||||
3581, 3583, 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643,
|
||||
3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727,
|
||||
3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821,
|
||||
3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907,
|
||||
3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989,
|
||||
4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057,
|
||||
4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139,
|
||||
4153, 4157, 4159, 4177, 4201, 4211, 4217, 4219, 4229, 4231,
|
||||
4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297,
|
||||
4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409,
|
||||
4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493,
|
||||
4507, 4513, 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583,
|
||||
4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657,
|
||||
4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751,
|
||||
4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831,
|
||||
4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937,
|
||||
4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003,
|
||||
5009, 5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087,
|
||||
5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179,
|
||||
5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279,
|
||||
5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387,
|
||||
5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443,
|
||||
5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521,
|
||||
5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591, 5623, 5639,
|
||||
5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693,
|
||||
5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791,
|
||||
5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857,
|
||||
5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939,
|
||||
5953, 5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053,
|
||||
6067, 6073, 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133,
|
||||
6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221,
|
||||
6229, 6247, 6257, 6263, 6269, 6271, 6277, 6287, 6299, 6301,
|
||||
6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367,
|
||||
6373, 6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473,
|
||||
6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, 6569, 6571,
|
||||
6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, 6673,
|
||||
6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737, 6761,
|
||||
6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833,
|
||||
6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917,
|
||||
6947, 6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997,
|
||||
7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103,
|
||||
7109, 7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207,
|
||||
7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, 7283, 7297,
|
||||
7307, 7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 7411,
|
||||
7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487, 7489, 7499,
|
||||
7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561,
|
||||
7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, 7643,
|
||||
7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723,
|
||||
7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829,
|
||||
7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919,
|
||||
7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017,
|
||||
8039, 8053, 8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111,
|
||||
8117, 8123, 8147, 8161, 8167, 8171, 8179, 8191, 8209, 8219,
|
||||
8221, 8231, 8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291,
|
||||
8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369, 8377, 8387,
|
||||
8389, 8419, 8423, 8429, 8431, 8443, 8447, 8461, 8467, 8501,
|
||||
8513, 8521, 8527, 8537, 8539, 8543, 8563, 8573, 8581, 8597,
|
||||
8599, 8609, 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677,
|
||||
8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, 8737, 8741,
|
||||
8747, 8753, 8761, 8779, 8783, 8803, 8807, 8819, 8821, 8831,
|
||||
8837, 8839, 8849, 8861, 8863, 8867, 8887, 8893, 8923, 8929,
|
||||
8933, 8941, 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011,
|
||||
9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091, 9103, 9109,
|
||||
9127, 9133, 9137, 9151, 9157, 9161, 9173, 9181, 9187, 9199,
|
||||
9203, 9209, 9221, 9227, 9239, 9241, 9257, 9277, 9281, 9283,
|
||||
9293, 9311, 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377,
|
||||
9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433, 9437, 9439,
|
||||
9461, 9463, 9467, 9473, 9479, 9491, 9497, 9511, 9521, 9533,
|
||||
9539, 9547, 9551, 9587, 9601, 9613, 9619, 9623, 9629, 9631,
|
||||
9643, 9649, 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733,
|
||||
9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, 9803, 9811,
|
||||
9817, 9829, 9833, 9839, 9851, 9857, 9859, 9871, 9883, 9887,
|
||||
9901, 9907, 9923, 9929, 9931, 9941, 9949, 9967, 9973, 10007,
|
||||
10009, 10037, 10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099,
|
||||
10103, 10111, 10133, 10139, 10141, 10151, 10159, 10163, 10169, 10177,
|
||||
10181, 10193, 10211, 10223, 10243, 10247, 10253, 10259, 10267, 10271,
|
||||
10273, 10289, 10301, 10303, 10313, 10321, 10331, 10333, 10337, 10343,
|
||||
10357, 10369, 10391, 10399, 10427, 10429, 10433, 10453, 10457, 10459,
|
||||
10463, 10477, 10487, 10499, 10501, 10513, 10529, 10531, 10559, 10567,
|
||||
10589, 10597, 10601, 10607, 10613, 10627, 10631, 10639, 10651, 10657,
|
||||
10663, 10667, 10687, 10691, 10709, 10711, 10723, 10729, 10733, 10739,
|
||||
10753, 10771, 10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859,
|
||||
10861, 10867, 10883, 10889, 10891, 10903, 10909, 10937, 10939, 10949,
|
||||
10957, 10973, 10979, 10987, 10993, 11003, 11027, 11047, 11057, 11059,
|
||||
11069, 11071, 11083, 11087, 11093, 11113, 11117, 11119, 11131, 11149,
|
||||
11159, 11161, 11171, 11173, 11177, 11197, 11213, 11239, 11243, 11251,
|
||||
11257, 11261, 11273, 11279, 11287, 11299, 11311, 11317, 11321, 11329,
|
||||
11351, 11353, 11369, 11383, 11393, 11399, 11411, 11423, 11437, 11443,
|
||||
11447, 11467, 11471, 11483, 11489, 11491, 11497, 11503, 11519, 11527,
|
||||
11549, 11551, 11579, 11587, 11593, 11597, 11617, 11621, 11633, 11657,
|
||||
11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731, 11743, 11777,
|
||||
11779, 11783, 11789, 11801, 11807, 11813, 11821, 11827, 11831, 11833,
|
||||
11839, 11863, 11867, 11887, 11897, 11903, 11909, 11923, 11927, 11933,
|
||||
11939, 11941, 11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011,
|
||||
12037, 12041, 12043, 12049, 12071, 12073, 12097, 12101, 12107, 12109,
|
||||
12113, 12119, 12143, 12149, 12157, 12161, 12163, 12197, 12203, 12211,
|
||||
12227, 12239, 12241, 12251, 12253, 12263, 12269, 12277, 12281, 12289,
|
||||
12301, 12323, 12329, 12343, 12347, 12373, 12377, 12379, 12391, 12401,
|
||||
12409, 12413, 12421, 12433, 12437, 12451, 12457, 12473, 12479, 12487,
|
||||
12491, 12497, 12503, 12511, 12517, 12527, 12539, 12541, 12547, 12553,
|
||||
12569, 12577, 12583, 12589, 12601, 12611, 12613, 12619, 12637, 12641,
|
||||
12647, 12653, 12659, 12671, 12689, 12697, 12703, 12713, 12721, 12739,
|
||||
12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821, 12823, 12829,
|
||||
12841, 12853, 12889, 12893, 12899, 12907, 12911, 12917, 12919, 12923,
|
||||
12941, 12953, 12959, 12967, 12973, 12979, 12983, 13001, 13003, 13007,
|
||||
13009, 13033, 13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109,
|
||||
13121, 13127, 13147, 13151, 13159, 13163, 13171, 13177, 13183, 13187,
|
||||
13217, 13219, 13229, 13241, 13249, 13259, 13267, 13291, 13297, 13309,
|
||||
13313, 13327, 13331, 13337, 13339, 13367, 13381, 13397, 13399, 13411,
|
||||
13417, 13421, 13441, 13451, 13457, 13463, 13469, 13477, 13487, 13499,
|
||||
13513, 13523, 13537, 13553, 13567, 13577, 13591, 13597, 13613, 13619,
|
||||
13627, 13633, 13649, 13669, 13679, 13681, 13687, 13691, 13693, 13697,
|
||||
13709, 13711, 13721, 13723, 13729, 13751, 13757, 13759, 13763, 13781,
|
||||
13789, 13799, 13807, 13829, 13831, 13841, 13859, 13873, 13877, 13879,
|
||||
13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933, 13963, 13967,
|
||||
13997, 13999, 14009, 14011, 14029, 14033, 14051, 14057, 14071, 14081,
|
||||
14083, 14087, 14107, 14143, 14149, 14153, 14159, 14173, 14177, 14197,
|
||||
14207, 14221, 14243, 14249, 14251, 14281, 14293, 14303, 14321, 14323,
|
||||
14327, 14341, 14347, 14369, 14387, 14389, 14401, 14407, 14411, 14419,
|
||||
14423, 14431, 14437, 14447, 14449, 14461, 14479, 14489, 14503, 14519,
|
||||
14533, 14537, 14543, 14549, 14551, 14557, 14561, 14563, 14591, 14593,
|
||||
14621, 14627, 14629, 14633, 14639, 14653, 14657, 14669, 14683, 14699,
|
||||
14713, 14717, 14723, 14731, 14737, 14741, 14747, 14753, 14759, 14767,
|
||||
14771, 14779, 14783, 14797, 14813, 14821, 14827, 14831, 14843, 14851,
|
||||
14867, 14869, 14879, 14887, 14891, 14897, 14923, 14929, 14939, 14947,
|
||||
14951, 14957, 14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073,
|
||||
15077, 15083, 15091, 15101, 15107, 15121, 15131, 15137, 15139, 15149,
|
||||
15161, 15173, 15187, 15193, 15199, 15217, 15227, 15233, 15241, 15259,
|
||||
15263, 15269, 15271, 15277, 15287, 15289, 15299, 15307, 15313, 15319,
|
||||
15329, 15331, 15349, 15359, 15361, 15373, 15377, 15383, 15391, 15401,
|
||||
15413, 15427, 15439, 15443, 15451, 15461, 15467, 15473, 15493, 15497,
|
||||
15511, 15527, 15541, 15551, 15559, 15569, 15581, 15583, 15601, 15607,
|
||||
15619, 15629, 15641, 15643, 15647, 15649, 15661, 15667, 15671, 15679,
|
||||
15683, 15727, 15731, 15733, 15737, 15739, 15749, 15761, 15767, 15773,
|
||||
15787, 15791, 15797, 15803, 15809, 15817, 15823, 15859, 15877, 15881,
|
||||
15887, 15889, 15901, 15907, 15913, 15919, 15923, 15937, 15959, 15971,
|
||||
15973, 15991, 16001, 16007, 16033, 16057, 16061, 16063, 16067, 16069,
|
||||
16073, 16087, 16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183,
|
||||
16187, 16189, 16193, 16217, 16223, 16229, 16231, 16249, 16253, 16267,
|
||||
16273, 16301, 16319, 16333, 16339, 16349, 16361, 16363, 16369, 16381,
|
||||
16411, 16417, 16421, 16427, 16433, 16447, 16451, 16453, 16477, 16481,
|
||||
16487, 16493, 16519, 16529, 16547, 16553, 16561, 16567, 16573, 16603,
|
||||
16607, 16619, 16631, 16633, 16649, 16651, 16657, 16661, 16673, 16691,
|
||||
16693, 16699, 16703, 16729, 16741, 16747, 16759, 16763, 16787, 16811,
|
||||
16823, 16829, 16831, 16843, 16871, 16879, 16883, 16889, 16901, 16903,
|
||||
16921, 16927, 16931, 16937, 16943, 16963, 16979, 16981, 16987, 16993,
|
||||
17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053, 17077, 17093,
|
||||
17099, 17107, 17117, 17123, 17137, 17159, 17167, 17183, 17189, 17191,
|
||||
17203, 17207, 17209, 17231, 17239, 17257, 17291, 17293, 17299, 17317,
|
||||
17321, 17327, 17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389,
|
||||
17393, 17401, 17417, 17419, 17431, 17443, 17449, 17467, 17471, 17477,
|
||||
17483, 17489, 17491, 17497, 17509, 17519, 17539, 17551, 17569, 17573,
|
||||
17579, 17581, 17597, 17599, 17609, 17623, 17627, 17657, 17659, 17669,
|
||||
17681, 17683, 17707, 17713, 17729, 17737, 17747, 17749, 17761, 17783,
|
||||
17789, 17791, 17807, 17827, 17837, 17839, 17851, 17863, 17881, 17891,
|
||||
17903, 17909, 17911, 17921, 17923, 17929, 17939, 17957, 17959, 17971,
|
||||
17977, 17981, 17987, 17989, 18013, 18041, 18043, 18047, 18049, 18059,
|
||||
18061, 18077, 18089, 18097, 18119, 18121, 18127, 18131, 18133, 18143,
|
||||
18149, 18169, 18181, 18191, 18199, 18211, 18217, 18223, 18229, 18233,
|
||||
18251, 18253, 18257, 18269, 18287, 18289, 18301, 18307, 18311, 18313,
|
||||
18329, 18341, 18353, 18367, 18371, 18379, 18397, 18401, 18413, 18427,
|
||||
18433, 18439, 18443, 18451, 18457, 18461, 18481, 18493, 18503, 18517,
|
||||
18521, 18523, 18539, 18541, 18553, 18583, 18587, 18593, 18617, 18637,
|
||||
18661, 18671, 18679, 18691, 18701, 18713, 18719, 18731, 18743, 18749,
|
||||
18757, 18773, 18787, 18793, 18797, 18803, 18839, 18859, 18869, 18899,
|
||||
18911, 18913, 18917, 18919, 18947, 18959, 18973, 18979, 19001, 19009,
|
||||
19013, 19031, 19037, 19051, 19069, 19073, 19079, 19081, 19087, 19121,
|
||||
19139, 19141, 19157, 19163, 19181, 19183, 19207, 19211, 19213, 19219,
|
||||
19231, 19237, 19249, 19259, 19267, 19273, 19289, 19301, 19309, 19319,
|
||||
19333, 19373, 19379, 19381, 19387, 19391, 19403, 19417, 19421, 19423,
|
||||
19427, 19429, 19433, 19441, 19447, 19457, 19463, 19469, 19471, 19477,
|
||||
19483, 19489, 19501, 19507, 19531, 19541, 19543, 19553, 19559, 19571,
|
||||
19577, 19583, 19597, 19603, 19609, 19661, 19681, 19687, 19697, 19699,
|
||||
19709, 19717, 19727, 19739, 19751, 19753, 19759, 19763, 19777, 19793,
|
||||
19801, 19813, 19819, 19841, 19843, 19853, 19861, 19867, 19889, 19891,
|
||||
19913, 19919, 19927, 19937, 19949, 19961, 19963, 19973, 19979, 19991,
|
||||
19993, 19997, 20011, 20021, 20023, 20029, 20047, 20051, 20063, 20071,
|
||||
20089, 20101, 20107, 20113, 20117, 20123, 20129, 20143, 20147, 20149,
|
||||
20161, 20173, 20177, 20183, 20201, 20219, 20231, 20233, 20249, 20261,
|
||||
20269, 20287, 20297, 20323, 20327, 20333, 20341, 20347, 20353, 20357,
|
||||
20359, 20369, 20389, 20393, 20399, 20407, 20411, 20431, 20441, 20443,
|
||||
20477, 20479, 20483, 20507, 20509, 20521, 20533, 20543, 20549, 20551,
|
||||
20563, 20593, 20599, 20611, 20627, 20639, 20641, 20663, 20681, 20693,
|
||||
20707, 20717, 20719, 20731, 20743, 20747, 20749, 20753, 20759, 20771,
|
||||
20773, 20789, 20807, 20809, 20849, 20857, 20873, 20879, 20887, 20897,
|
||||
20899, 20903, 20921, 20929, 20939, 20947, 20959, 20963, 20981, 20983,
|
||||
21001, 21011, 21013, 21017, 21019, 21023, 21031, 21059, 21061, 21067,
|
||||
21089, 21101, 21107, 21121, 21139, 21143, 21149, 21157, 21163, 21169,
|
||||
21179, 21187, 21191, 21193, 21211, 21221, 21227, 21247, 21269, 21277,
|
||||
21283, 21313, 21317, 21319, 21323, 21341, 21347, 21377, 21379, 21383,
|
||||
21391, 21397, 21401, 21407, 21419, 21433, 21467, 21481, 21487, 21491,
|
||||
21493, 21499, 21503, 21517, 21521, 21523, 21529, 21557, 21559, 21563,
|
||||
21569, 21577, 21587, 21589, 21599, 21601, 21611, 21613, 21617, 21647,
|
||||
21649, 21661, 21673, 21683, 21701, 21713, 21727, 21737, 21739, 21751,
|
||||
21757, 21767, 21773, 21787, 21799, 21803, 21817, 21821, 21839, 21841,
|
||||
21851, 21859, 21863, 21871, 21881, 21893, 21911, 21929, 21937, 21943,
|
||||
21961, 21977, 21991, 21997, 22003, 22013, 22027, 22031, 22037, 22039,
|
||||
22051, 22063, 22067, 22073, 22079, 22091, 22093, 22109, 22111, 22123,
|
||||
22129, 22133, 22147, 22153, 22157, 22159, 22171, 22189, 22193, 22229,
|
||||
22247, 22259, 22271, 22273, 22277, 22279, 22283, 22291, 22303, 22307,
|
||||
22343, 22349, 22367, 22369, 22381, 22391, 22397, 22409, 22433, 22441,
|
||||
22447, 22453, 22469, 22481, 22483, 22501, 22511, 22531, 22541, 22543,
|
||||
22549, 22567, 22571, 22573, 22613, 22619, 22621, 22637, 22639, 22643,
|
||||
22651, 22669, 22679, 22691, 22697, 22699, 22709, 22717, 22721, 22727,
|
||||
22739, 22741, 22751, 22769, 22777, 22783, 22787, 22807, 22811, 22817,
|
||||
22853, 22859, 22861, 22871, 22877, 22901, 22907, 22921, 22937, 22943,
|
||||
22961, 22963, 22973, 22993, 23003, 23011, 23017, 23021, 23027, 23029,
|
||||
23039, 23041, 23053, 23057, 23059, 23063, 23071, 23081, 23087, 23099,
|
||||
23117, 23131, 23143, 23159, 23167, 23173, 23189, 23197, 23201, 23203,
|
||||
23209, 23227, 23251, 23269, 23279, 23291, 23293, 23297, 23311, 23321,
|
||||
23327, 23333, 23339, 23357, 23369, 23371, 23399, 23417, 23431, 23447,
|
||||
23459, 23473, 23497, 23509, 23531, 23537, 23539, 23549, 23557, 23561,
|
||||
23563, 23567, 23581, 23593, 23599, 23603, 23609, 23623, 23627, 23629,
|
||||
23633, 23663, 23669, 23671, 23677, 23687, 23689, 23719, 23741, 23743,
|
||||
23747, 23753, 23761, 23767, 23773, 23789, 23801, 23813, 23819, 23827,
|
||||
23831, 23833, 23857, 23869, 23873, 23879, 23887, 23893, 23899, 23909,
|
||||
23911, 23917, 23929, 23957, 23971, 23977, 23981, 23993, 24001, 24007,
|
||||
24019, 24023, 24029, 24043, 24049, 24061, 24071, 24077, 24083, 24091,
|
||||
24097, 24103, 24107, 24109, 24113, 24121, 24133, 24137, 24151, 24169,
|
||||
24179, 24181, 24197, 24203, 24223, 24229, 24239, 24247, 24251, 24281,
|
||||
24317, 24329, 24337, 24359, 24371, 24373, 24379, 24391, 24407, 24413,
|
||||
24419, 24421, 24439, 24443, 24469, 24473, 24481, 24499, 24509, 24517,
|
||||
24527, 24533, 24547, 24551, 24571, 24593, 24611, 24623, 24631, 24659,
|
||||
24671, 24677, 24683, 24691, 24697, 24709, 24733, 24749, 24763, 24767,
|
||||
24781, 24793, 24799, 24809, 24821, 24841, 24847, 24851, 24859, 24877,
|
||||
24889, 24907, 24917, 24919, 24923, 24943, 24953, 24967, 24971, 24977,
|
||||
24979, 24989, 25013, 25031, 25033, 25037, 25057, 25073, 25087, 25097,
|
||||
25111, 25117, 25121, 25127, 25147, 25153, 25163, 25169, 25171, 25183,
|
||||
25189, 25219, 25229, 25237, 25243, 25247, 25253, 25261, 25301, 25303,
|
||||
25307, 25309, 25321, 25339, 25343, 25349, 25357, 25367, 25373, 25391,
|
||||
25409, 25411, 25423, 25439, 25447, 25453, 25457, 25463, 25469, 25471,
|
||||
25523, 25537, 25541, 25561, 25577, 25579, 25583, 25589, 25601, 25603,
|
||||
25609, 25621, 25633, 25639, 25643, 25657, 25667, 25673, 25679, 25693,
|
||||
25703, 25717, 25733, 25741, 25747, 25759, 25763, 25771, 25793, 25799,
|
||||
25801, 25819, 25841, 25847, 25849, 25867, 25873, 25889, 25903, 25913,
|
||||
25919, 25931, 25933, 25939, 25943, 25951, 25969, 25981, 25997, 25999,
|
||||
26003, 26017, 26021, 26029, 26041, 26053, 26083, 26099, 26107, 26111,
|
||||
26113, 26119, 26141, 26153, 26161, 26171, 26177, 26183, 26189, 26203,
|
||||
26209, 26227, 26237, 26249, 26251, 26261, 26263, 26267, 26293, 26297,
|
||||
26309, 26317, 26321, 26339, 26347, 26357, 26371, 26387, 26393, 26399,
|
||||
26407, 26417, 26423, 26431, 26437, 26449, 26459, 26479, 26489, 26497,
|
||||
26501, 26513, 26539, 26557, 26561, 26573, 26591, 26597, 26627, 26633,
|
||||
26641, 26647, 26669, 26681, 26683, 26687, 26693, 26699, 26701, 26711,
|
||||
26713, 26717, 26723, 26729, 26731, 26737, 26759, 26777, 26783, 26801,
|
||||
26813, 26821, 26833, 26839, 26849, 26861, 26863, 26879, 26881, 26891,
|
||||
26893, 26903, 26921, 26927, 26947, 26951, 26953, 26959, 26981, 26987,
|
||||
26993, 27011, 27017, 27031, 27043, 27059, 27061, 27067, 27073, 27077,
|
||||
27091, 27103, 27107, 27109, 27127, 27143, 27179, 27191, 27197, 27211,
|
||||
27239, 27241, 27253, 27259, 27271, 27277, 27281, 27283, 27299, 27329,
|
||||
27337, 27361, 27367, 27397, 27407, 27409, 27427, 27431, 27437, 27449,
|
||||
27457, 27479, 27481, 27487, 27509, 27527, 27529, 27539, 27541, 27551,
|
||||
27581, 27583, 27611, 27617, 27631, 27647, 27653, 27673, 27689, 27691,
|
||||
27697, 27701, 27733, 27737, 27739, 27743, 27749, 27751, 27763, 27767,
|
||||
27773, 27779, 27791, 27793, 27799, 27803, 27809, 27817, 27823, 27827,
|
||||
27847, 27851, 27883, 27893, 27901, 27917, 27919, 27941, 27943, 27947,
|
||||
27953, 27961, 27967, 27983, 27997, 28001, 28019, 28027, 28031, 28051,
|
||||
28057, 28069, 28081, 28087, 28097, 28099, 28109, 28111, 28123, 28151,
|
||||
28163, 28181, 28183, 28201, 28211, 28219, 28229, 28277, 28279, 28283,
|
||||
28289, 28297, 28307, 28309, 28319, 28349, 28351, 28387, 28393, 28403,
|
||||
28409, 28411, 28429, 28433, 28439, 28447, 28463, 28477, 28493, 28499,
|
||||
28513, 28517, 28537, 28541, 28547, 28549, 28559, 28571, 28573, 28579,
|
||||
28591, 28597, 28603, 28607, 28619, 28621, 28627, 28631, 28643, 28649,
|
||||
28657, 28661, 28663, 28669, 28687, 28697, 28703, 28711, 28723, 28729,
|
||||
28751, 28753, 28759, 28771, 28789, 28793, 28807, 28813, 28817, 28837,
|
||||
28843, 28859, 28867, 28871, 28879, 28901, 28909, 28921, 28927, 28933,
|
||||
28949, 28961, 28979, 29009, 29017, 29021, 29023, 29027, 29033, 29059,
|
||||
29063, 29077, 29101, 29123, 29129, 29131, 29137, 29147, 29153, 29167,
|
||||
29173, 29179, 29191, 29201, 29207, 29209, 29221, 29231, 29243, 29251,
|
||||
29269, 29287, 29297, 29303, 29311, 29327, 29333, 29339, 29347, 29363,
|
||||
29383, 29387, 29389, 29399, 29401, 29411, 29423, 29429, 29437, 29443,
|
||||
29453, 29473, 29483, 29501, 29527, 29531, 29537, 29567, 29569, 29573,
|
||||
29581, 29587, 29599, 29611, 29629, 29633, 29641, 29663, 29669, 29671,
|
||||
29683, 29717, 29723, 29741, 29753, 29759, 29761, 29789, 29803, 29819,
|
||||
29833, 29837, 29851, 29863, 29867, 29873, 29879, 29881, 29917, 29921,
|
||||
29927, 29947, 29959, 29983, 29989, 30011, 30013, 30029, 30047, 30059,
|
||||
30071, 30089, 30091, 30097, 30103, 30109, 30113, 30119, 30133, 30137,
|
||||
30139, 30161, 30169, 30181, 30187, 30197, 30203, 30211, 30223, 30241,
|
||||
30253, 30259, 30269, 30271, 30293, 30307, 30313, 30319, 30323, 30341,
|
||||
30347, 30367, 30389, 30391, 30403, 30427, 30431, 30449, 30467, 30469,
|
||||
30491, 30493, 30497, 30509, 30517, 30529, 30539, 30553, 30557, 30559,
|
||||
30577, 30593, 30631, 30637, 30643, 30649, 30661, 30671, 30677, 30689,
|
||||
30697, 30703, 30707, 30713, 30727, 30757, 30763, 30773, 30781, 30803,
|
||||
30809, 30817, 30829, 30839, 30841, 30851, 30853, 30859, 30869, 30871,
|
||||
30881, 30893, 30911, 30931, 30937, 30941, 30949, 30971, 30977, 30983,
|
||||
31013, 31019, 31033, 31039, 31051, 31063, 31069, 31079, 31081, 31091,
|
||||
31121, 31123, 31139, 31147, 31151, 31153, 31159, 31177, 31181, 31183,
|
||||
31189, 31193, 31219, 31223, 31231, 31237, 31247, 31249, 31253, 31259,
|
||||
31267, 31271, 31277, 31307, 31319, 31321, 31327, 31333, 31337, 31357,
|
||||
31379, 31387, 31391, 31393, 31397, 31469, 31477, 31481, 31489, 31511,
|
||||
31513, 31517, 31531, 31541, 31543, 31547, 31567, 31573, 31583, 31601,
|
||||
31607, 31627, 31643, 31649, 31657, 31663, 31667, 31687, 31699, 31721,
|
||||
31723, 31727, 31729, 31741, 31751, 31769, 31771, 31793, 31799, 31817,
|
||||
31847, 31849, 31859, 31873, 31883, 31891, 31907, 31957, 31963, 31973,
|
||||
31981, 31991, 32003, 32009, 32027, 32029, 32051, 32057, 32059, 32063,
|
||||
32069, 32077, 32083, 32089, 32099, 32117, 32119, 32141, 32143, 32159,
|
||||
32173, 32183, 32189, 32191, 32203, 32213, 32233, 32237, 32251, 32257,
|
||||
32261, 32297, 32299, 32303, 32309, 32321, 32323, 32327, 32341, 32353,
|
||||
32359, 32363, 32369, 32371, 32377, 32381, 32401, 32411, 32413, 32423,
|
||||
32429, 32441, 32443, 32467, 32479, 32491, 32497, 32503, 32507, 32531,
|
||||
32533, 32537, 32561, 32563, 32569, 32573, 32579, 32587, 32603, 32609,
|
||||
32611, 32621, 32633, 32647, 32653, 32687, 32693, 32707, 32713, 32717,
|
||||
32719, 32749, 32771, 32779, 32783, 32789, 32797, 32801, 32803, 32831,
|
||||
32833, 32839, 32843, 32869, 32887, 32909, 32911, 32917, 32933, 32939,
|
||||
32941, 32957, 32969, 32971, 32983, 32987, 32993, 32999, 33013, 33023,
|
||||
33029, 33037, 33049, 33053, 33071, 33073, 33083, 33091, 33107, 33113,
|
||||
33119, 33149, 33151, 33161, 33179, 33181, 33191, 33199, 33203, 33211,
|
||||
33223, 33247, 33287, 33289, 33301, 33311, 33317, 33329, 33331, 33343,
|
||||
33347, 33349, 33353, 33359, 33377, 33391, 33403, 33409, 33413, 33427,
|
||||
33457, 33461, 33469, 33479, 33487, 33493, 33503, 33521, 33529, 33533,
|
||||
33547, 33563, 33569, 33577, 33581, 33587, 33589, 33599, 33601, 33613,
|
||||
33617, 33619, 33623, 33629, 33637, 33641, 33647, 33679, 33703, 33713,
|
||||
33721, 33739, 33749, 33751, 33757, 33767, 33769, 33773, 33791, 33797,
|
||||
33809, 33811, 33827, 33829, 33851, 33857, 33863, 33871, 33889, 33893,
|
||||
33911, 33923, 33931, 33937, 33941, 33961, 33967, 33997, 34019, 34031,
|
||||
34033, 34039, 34057, 34061, 34123, 34127, 34129, 34141, 34147, 34157,
|
||||
34159, 34171, 34183, 34211, 34213, 34217, 34231, 34253, 34259, 34261,
|
||||
34267, 34273, 34283, 34297, 34301, 34303, 34313, 34319, 34327, 34337,
|
||||
34351, 34361, 34367, 34369, 34381, 34403, 34421, 34429, 34439, 34457,
|
||||
34469, 34471, 34483, 34487, 34499, 34501, 34511, 34513, 34519, 34537,
|
||||
34543, 34549, 34583, 34589, 34591, 34603, 34607, 34613, 34631, 34649,
|
||||
34651, 34667, 34673, 34679, 34687, 34693, 34703, 34721, 34729, 34739,
|
||||
34747, 34757, 34759, 34763, 34781, 34807, 34819, 34841, 34843, 34847,
|
||||
34849, 34871, 34877, 34883, 34897, 34913, 34919, 34939, 34949, 34961,
|
||||
34963, 34981, 35023, 35027, 35051, 35053, 35059, 35069, 35081, 35083,
|
||||
35089, 35099, 35107, 35111, 35117, 35129, 35141, 35149, 35153, 35159,
|
||||
35171, 35201, 35221, 35227, 35251, 35257, 35267, 35279, 35281, 35291,
|
||||
35311, 35317, 35323, 35327, 35339, 35353, 35363, 35381, 35393, 35401,
|
||||
35407, 35419, 35423, 35437, 35447, 35449, 35461, 35491, 35507, 35509,
|
||||
35521, 35527, 35531, 35533, 35537, 35543, 35569, 35573, 35591, 35593,
|
||||
35597, 35603, 35617, 35671, 35677, 35729, 35731, 35747, 35753, 35759,
|
||||
35771, 35797, 35801, 35803, 35809, 35831, 35837, 35839, 35851, 35863,
|
||||
35869, 35879, 35897, 35899, 35911, 35923, 35933, 35951, 35963, 35969,
|
||||
35977, 35983, 35993, 35999, 36007, 36011, 36013, 36017, 36037, 36061,
|
||||
36067, 36073, 36083, 36097, 36107, 36109, 36131, 36137, 36151, 36161,
|
||||
36187, 36191, 36209, 36217, 36229, 36241, 36251, 36263, 36269, 36277,
|
||||
36293, 36299, 36307, 36313, 36319, 36341, 36343, 36353, 36373, 36383,
|
||||
36389, 36433, 36451, 36457, 36467, 36469, 36473, 36479, 36493, 36497,
|
||||
36523, 36527, 36529, 36541, 36551, 36559, 36563, 36571, 36583, 36587,
|
||||
36599, 36607, 36629, 36637, 36643, 36653, 36671, 36677, 36683, 36691,
|
||||
36697, 36709, 36713, 36721, 36739, 36749, 36761, 36767, 36779, 36781,
|
||||
36787, 36791, 36793, 36809, 36821, 36833, 36847, 36857, 36871, 36877,
|
||||
36887, 36899, 36901, 36913, 36919, 36923, 36929, 36931, 36943, 36947,
|
||||
36973, 36979, 36997, 37003, 37013, 37019, 37021, 37039, 37049, 37057,
|
||||
37061, 37087, 37097, 37117, 37123, 37139, 37159, 37171, 37181, 37189,
|
||||
37199, 37201, 37217, 37223, 37243, 37253, 37273, 37277, 37307, 37309,
|
||||
37313, 37321, 37337, 37339, 37357, 37361, 37363, 37369, 37379, 37397,
|
||||
37409, 37423, 37441, 37447, 37463, 37483, 37489, 37493, 37501, 37507,
|
||||
37511, 37517, 37529, 37537, 37547, 37549, 37561, 37567, 37571, 37573,
|
||||
37579, 37589, 37591, 37607, 37619, 37633, 37643, 37649, 37657, 37663,
|
||||
37691, 37693, 37699, 37717, 37747, 37781, 37783, 37799, 37811, 37813,
|
||||
37831, 37847, 37853, 37861, 37871, 37879, 37889, 37897, 37907, 37951,
|
||||
37957, 37963, 37967, 37987, 37991, 37993, 37997, 38011, 38039, 38047,
|
||||
38053, 38069, 38083, 38113, 38119, 38149, 38153, 38167, 38177, 38183,
|
||||
38189, 38197, 38201, 38219, 38231, 38237, 38239, 38261, 38273, 38281,
|
||||
38287, 38299, 38303, 38317, 38321, 38327, 38329, 38333, 38351, 38371,
|
||||
38377, 38393, 38431, 38447, 38449, 38453, 38459, 38461, 38501, 38543,
|
||||
38557, 38561, 38567, 38569, 38593, 38603, 38609, 38611, 38629, 38639,
|
||||
38651, 38653, 38669, 38671, 38677, 38693, 38699, 38707, 38711, 38713,
|
||||
38723, 38729, 38737, 38747, 38749, 38767, 38783, 38791, 38803, 38821,
|
||||
38833, 38839, 38851, 38861, 38867, 38873, 38891, 38903, 38917, 38921,
|
||||
38923, 38933, 38953, 38959, 38971, 38977, 38993, 39019, 39023, 39041,
|
||||
39043, 39047, 39079, 39089, 39097, 39103, 39107, 39113, 39119, 39133,
|
||||
39139, 39157, 39161, 39163, 39181, 39191, 39199, 39209, 39217, 39227,
|
||||
39229, 39233, 39239, 39241, 39251, 39293, 39301, 39313, 39317, 39323,
|
||||
39341, 39343, 39359, 39367, 39371, 39373, 39383, 39397, 39409, 39419,
|
||||
39439, 39443, 39451, 39461, 39499, 39503, 39509, 39511, 39521, 39541,
|
||||
39551, 39563, 39569, 39581, 39607, 39619, 39623, 39631, 39659, 39667,
|
||||
39671, 39679, 39703, 39709, 39719, 39727, 39733, 39749, 39761, 39769,
|
||||
39779, 39791, 39799, 39821, 39827, 39829, 39839, 39841, 39847, 39857,
|
||||
39863, 39869, 39877, 39883, 39887, 39901, 39929, 39937, 39953, 39971,
|
||||
39979, 39983, 39989, 40009, 40013, 40031, 40037, 40039, 40063, 40087,
|
||||
40093, 40099, 40111, 40123, 40127, 40129, 40151, 40153, 40163, 40169,
|
||||
40177, 40189, 40193, 40213, 40231, 40237, 40241, 40253, 40277, 40283,
|
||||
40289, 40343, 40351, 40357, 40361, 40387, 40423, 40427, 40429, 40433,
|
||||
40459, 40471, 40483, 40487, 40493, 40499, 40507, 40519, 40529, 40531,
|
||||
40543, 40559, 40577, 40583, 40591, 40597, 40609, 40627, 40637, 40639,
|
||||
40693, 40697, 40699, 40709, 40739, 40751, 40759, 40763, 40771, 40787,
|
||||
40801, 40813, 40819, 40823, 40829, 40841, 40847, 40849, 40853, 40867,
|
||||
40879, 40883, 40897, 40903, 40927, 40933, 40939, 40949, 40961, 40973,
|
||||
40993, 41011, 41017, 41023, 41039, 41047, 41051, 41057, 41077, 41081,
|
||||
41113, 41117, 41131, 41141, 41143, 41149, 41161, 41177, 41179, 41183,
|
||||
41189, 41201, 41203, 41213, 41221, 41227, 41231, 41233, 41243, 41257,
|
||||
41263, 41269, 41281, 41299, 41333, 41341, 41351, 41357, 41381, 41387,
|
||||
41389, 41399, 41411, 41413, 41443, 41453, 41467, 41479, 41491, 41507,
|
||||
41513, 41519, 41521, 41539, 41543, 41549, 41579, 41593, 41597, 41603,
|
||||
41609, 41611, 41617, 41621, 41627, 41641, 41647, 41651, 41659, 41669,
|
||||
41681, 41687, 41719, 41729, 41737, 41759, 41761, 41771, 41777, 41801,
|
||||
41809, 41813, 41843, 41849, 41851, 41863, 41879, 41887, 41893, 41897,
|
||||
41903, 41911, 41927, 41941, 41947, 41953, 41957, 41959, 41969, 41981,
|
||||
41983, 41999, 42013, 42017, 42019, 42023, 42043, 42061, 42071, 42073,
|
||||
42083, 42089, 42101, 42131, 42139, 42157, 42169, 42179, 42181, 42187,
|
||||
42193, 42197, 42209, 42221, 42223, 42227, 42239, 42257, 42281, 42283,
|
||||
42293, 42299, 42307, 42323, 42331, 42337, 42349, 42359, 42373, 42379,
|
||||
42391, 42397, 42403, 42407, 42409, 42433, 42437, 42443, 42451, 42457,
|
||||
42461, 42463, 42467, 42473, 42487, 42491, 42499, 42509, 42533, 42557,
|
||||
42569, 42571, 42577, 42589, 42611, 42641, 42643, 42649, 42667, 42677,
|
||||
42683, 42689, 42697, 42701, 42703, 42709, 42719, 42727, 42737, 42743,
|
||||
42751, 42767, 42773, 42787, 42793, 42797, 42821, 42829, 42839, 42841,
|
||||
42853, 42859, 42863, 42899, 42901, 42923, 42929, 42937, 42943, 42953,
|
||||
42961, 42967, 42979, 42989, 43003, 43013, 43019, 43037, 43049, 43051,
|
||||
43063, 43067, 43093, 43103, 43117, 43133, 43151, 43159, 43177, 43189,
|
||||
43201, 43207, 43223, 43237, 43261, 43271, 43283, 43291, 43313, 43319,
|
||||
43321, 43331, 43391, 43397, 43399, 43403, 43411, 43427, 43441, 43451,
|
||||
43457, 43481, 43487, 43499, 43517, 43541, 43543, 43573, 43577, 43579,
|
||||
43591, 43597, 43607, 43609, 43613, 43627, 43633, 43649, 43651, 43661,
|
||||
43669, 43691, 43711, 43717, 43721, 43753, 43759, 43777, 43781, 43783,
|
||||
43787, 43789, 43793, 43801, 43853, 43867, 43889, 43891, 43913, 43933,
|
||||
43943, 43951, 43961, 43963, 43969, 43973, 43987, 43991, 43997, 44017,
|
||||
44021, 44027, 44029, 44041, 44053, 44059, 44071, 44087, 44089, 44101,
|
||||
44111, 44119, 44123, 44129, 44131, 44159, 44171, 44179, 44189, 44201,
|
||||
44203, 44207, 44221, 44249, 44257, 44263, 44267, 44269, 44273, 44279,
|
||||
44281, 44293, 44351, 44357, 44371, 44381, 44383, 44389, 44417, 44449,
|
||||
44453, 44483, 44491, 44497, 44501, 44507, 44519, 44531, 44533, 44537,
|
||||
44543, 44549, 44563, 44579, 44587, 44617, 44621, 44623, 44633, 44641,
|
||||
44647, 44651, 44657, 44683, 44687, 44699, 44701, 44711, 44729, 44741,
|
||||
44753, 44771, 44773, 44777, 44789, 44797, 44809, 44819, 44839, 44843,
|
||||
44851, 44867, 44879, 44887, 44893, 44909, 44917, 44927, 44939, 44953,
|
||||
44959, 44963, 44971, 44983, 44987, 45007, 45013, 45053, 45061, 45077,
|
||||
45083, 45119, 45121, 45127, 45131, 45137, 45139, 45161, 45179, 45181,
|
||||
45191, 45197, 45233, 45247, 45259, 45263, 45281, 45289, 45293, 45307,
|
||||
45317, 45319, 45329, 45337, 45341, 45343, 45361, 45377, 45389, 45403,
|
||||
45413, 45427, 45433, 45439, 45481, 45491, 45497, 45503, 45523, 45533,
|
||||
45541, 45553, 45557, 45569, 45587, 45589, 45599, 45613, 45631, 45641,
|
||||
45659, 45667, 45673, 45677, 45691, 45697, 45707, 45737, 45751, 45757,
|
||||
45763, 45767, 45779, 45817, 45821, 45823, 45827, 45833, 45841, 45853,
|
||||
45863, 45869, 45887, 45893, 45943, 45949, 45953, 45959, 45971, 45979,
|
||||
45989, 46021, 46027, 46049, 46051, 46061, 46073, 46091, 46093, 46099,
|
||||
46103, 46133, 46141, 46147, 46153, 46171, 46181, 46183, 46187, 46199,
|
||||
46219, 46229, 46237, 46261, 46271, 46273, 46279, 46301, 46307, 46309,
|
||||
46327, 46337, 46349, 46351, 46381, 46399, 46411, 46439, 46441, 46447,
|
||||
46451, 46457, 46471, 46477, 46489, 46499, 46507, 46511, 46523, 46549,
|
||||
46559, 46567, 46573, 46589, 46591, 46601, 46619, 46633, 46639, 46643,
|
||||
46649, 46663, 46679, 46681, 46687, 46691, 46703, 46723, 46727, 46747,
|
||||
46751, 46757, 46769, 46771, 46807, 46811, 46817, 46819, 46829, 46831,
|
||||
46853, 46861, 46867, 46877, 46889, 46901, 46919, 46933, 46957, 46993,
|
||||
46997, 47017, 47041, 47051, 47057, 47059, 47087, 47093, 47111, 47119,
|
||||
47123, 47129, 47137, 47143, 47147, 47149, 47161, 47189, 47207, 47221,
|
||||
47237, 47251, 47269, 47279, 47287, 47293, 47297, 47303, 47309, 47317,
|
||||
47339, 47351, 47353, 47363, 47381, 47387, 47389, 47407, 47417, 47419,
|
||||
47431, 47441, 47459, 47491, 47497, 47501, 47507, 47513, 47521, 47527,
|
||||
47533, 47543, 47563, 47569, 47581, 47591, 47599, 47609, 47623, 47629,
|
||||
47639, 47653, 47657, 47659, 47681, 47699, 47701, 47711, 47713, 47717,
|
||||
47737, 47741, 47743, 47777, 47779, 47791, 47797, 47807, 47809, 47819,
|
||||
47837, 47843, 47857, 47869, 47881, 47903, 47911, 47917, 47933, 47939,
|
||||
47947, 47951, 47963, 47969, 47977, 47981, 48017, 48023, 48029, 48049,
|
||||
48073, 48079, 48091, 48109, 48119, 48121, 48131, 48157, 48163, 48179,
|
||||
48187, 48193, 48197, 48221, 48239, 48247, 48259, 48271, 48281, 48299,
|
||||
48311, 48313, 48337, 48341, 48353, 48371, 48383, 48397, 48407, 48409,
|
||||
48413, 48437, 48449, 48463, 48473, 48479, 48481, 48487, 48491, 48497,
|
||||
48523, 48527, 48533, 48539, 48541, 48563, 48571, 48589, 48593, 48611,
|
||||
48619, 48623, 48647, 48649, 48661, 48673, 48677, 48679, 48731, 48733,
|
||||
48751, 48757, 48761, 48767, 48779, 48781, 48787, 48799, 48809, 48817,
|
||||
48821, 48823, 48847, 48857, 48859, 48869, 48871, 48883, 48889, 48907,
|
||||
48947, 48953, 48973, 48989, 48991, 49003, 49009, 49019, 49031, 49033,
|
||||
49037, 49043, 49057, 49069, 49081, 49103, 49109, 49117, 49121, 49123,
|
||||
49139, 49157, 49169, 49171, 49177, 49193, 49199, 49201, 49207, 49211,
|
||||
49223, 49253, 49261, 49277, 49279, 49297, 49307, 49331, 49333, 49339,
|
||||
49363, 49367, 49369, 49391, 49393, 49409, 49411, 49417, 49429, 49433,
|
||||
49451, 49459, 49463, 49477, 49481, 49499, 49523, 49529, 49531, 49537,
|
||||
49547, 49549, 49559, 49597, 49603, 49613, 49627, 49633, 49639, 49663,
|
||||
49667, 49669, 49681, 49697, 49711, 49727, 49739, 49741, 49747, 49757,
|
||||
49783, 49787, 49789, 49801, 49807, 49811, 49823, 49831, 49843, 49853,
|
||||
49871, 49877, 49891, 49919, 49921, 49927, 49937, 49939, 49943, 49957,
|
||||
49991, 49993, 49999,
|
||||
};
|
||||
|
||||
try {
|
||||
SMALL_PRIMES = new BigInteger[sp.length];
|
||||
|
||||
for(int i = 0; i < sp.length; i++) {
|
||||
SMALL_PRIMES[i] = BigInteger.valueOf(sp[i]);
|
||||
}//for//
|
||||
|
||||
PRIME_BITMAP = new byte[(PRIME_BITMAP_SIZE+15)/16];
|
||||
|
||||
for(int i = 1; i <= 5; i++) {
|
||||
int p = sp[i]; // 3, 5, 7, 11 or 13
|
||||
|
||||
for(int j = p; j < PRIME_BITMAP_SIZE; j += p+p) {
|
||||
int x = j >> 1;
|
||||
PRIME_BITMAP[x >> 3] |= (1 << (x & 0x07));
|
||||
}//for//
|
||||
}//for//
|
||||
|
||||
BigInteger x = ONE;
|
||||
|
||||
for(int i = 0; i < SMALL_PRIME_THRESHOLD; i++) {
|
||||
x = x.multiply(SMALL_PRIMES[i]);
|
||||
}//for//
|
||||
|
||||
SMALL_PRIME_MOD = x;
|
||||
}//try//
|
||||
catch(RuntimeException e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}//catch//
|
||||
}//static//
|
||||
/**
|
||||
* PrimeNumberGenerator constructor.
|
||||
*/
|
||||
private PrimeNumberGenerator() {
|
||||
super();
|
||||
}//PrimeNumberGenerator()//
|
||||
/**
|
||||
* Generates a random probable-prime, <i>p</i>, of the given length, such that all the factors of <i>p</i> - 1 are known.
|
||||
* @param bitlength An approximate number of bits that the returned prime integer must have.
|
||||
* @param certainty A measure of the probability that the returned integer <i>p</i>, and the largest factor of <i>p</i> - 1 are primes. The Miller-Rabin test used ensures that these values are prime with a probability that exceeds 1 - (1/2)<sup><i>certainty</i></sup>.
|
||||
* @param random A source of randomness for the bits to use in building the prime.
|
||||
* @param prime_type What type of prime to build: PLAIN, STRONG or GERMAIN.
|
||||
* @return An array of two Objects: the first being the found prime itself, say <i>p</i>, and the second Object is an array of the known distinct prime factors of the value (<i>p</i> - 1).
|
||||
*/
|
||||
public static Object[] getElGamal(int bitlength, int certainty, Random random, int prime_type) {
|
||||
BigInteger p = null;
|
||||
BigInteger[] q = null;
|
||||
|
||||
switch(prime_type) {
|
||||
case PLAIN:
|
||||
//Alternative-1: replicate what we had before.//
|
||||
while(q == null) {
|
||||
p = new BigInteger(bitlength, certainty, random);
|
||||
q = getSmallFactors(p.subtract(ONE), certainty);
|
||||
|
||||
//If input has only small factors it is insecure (see Pohlig and Hellman reference). Make sure that the last prime factor; i.e. the largest, is at least half the length of the input.//
|
||||
if(q != null && q[q.length - 1].bitLength() <= p.bitLength() / 2) {
|
||||
q = null;
|
||||
}//if//
|
||||
}//while//
|
||||
break;
|
||||
|
||||
case STRONG:
|
||||
//Alternative-2: use GORDON-built strong primes.//
|
||||
BigInteger[] result;
|
||||
BigInteger r;
|
||||
|
||||
while(q == null) {
|
||||
result = getGordon(bitlength, certainty, random);
|
||||
p = result[0];
|
||||
r = result[1];
|
||||
q = PrimeNumberGenerator.getSmallFactors(p.subtract(ONE), certainty, r);
|
||||
}//while//
|
||||
break;
|
||||
|
||||
case GERMAIN:
|
||||
//Alternative-3: use GERMAIN primes.//
|
||||
p = getGermain(bitlength, certainty, random);
|
||||
q = new BigInteger[] {TWO, p.subtract(ONE).divide(TWO)};
|
||||
break;
|
||||
}//switch//
|
||||
|
||||
Object[] result = {p, q};
|
||||
|
||||
return result;
|
||||
}//getElGamal()//
|
||||
/**
|
||||
* Gets a Germain (Sophie) probable-prime with an approximate specified <i>bitlength</i>, that is prime with a probability exceeding 1 - (1/2)<sup><i>certainty</i></sup>.
|
||||
* <p> An integer <i>p</i> is a GERMAIN prime iff it is a prime, and <i>p</i> = 2<i>q</i> + 1 where <i>q</i> is also a prime.
|
||||
* @param bitlength An approximate number of bits that the returned prime integer must have.
|
||||
* @param certainty A measure of the probability that the returned integer is a prime. The Miller-Rabin test used ensures that the returned value is a prime with a probability that exceeds 1 - (1/2)<sup><i>certainty</i></sup>.
|
||||
* @param random A source of randomness for the bits to use in building the prime.
|
||||
* @return A Germain prime: a prime of the form 2q + 1 where q is also a prime.
|
||||
*/
|
||||
public static BigInteger getGermain(int bitlength, int certainty, Random random) {
|
||||
BigInteger q, p;
|
||||
|
||||
//Generating a GERMAIN prime.//
|
||||
while(true) {
|
||||
q = new BigInteger(bitlength, certainty, random);
|
||||
p = TWO.multiply(q).add(ONE);
|
||||
|
||||
if(isProbablePrimeFast(p, certainty)) {
|
||||
break;
|
||||
}//if//
|
||||
}//while//
|
||||
|
||||
return p;
|
||||
}//getGermain()//
|
||||
/**
|
||||
* Gets a Gordon <b>strong</b> probable-prime with an approximate specified <i>bitlength</i>, that is prime with a probability exceeding 1 - (1/2)<sup><i>certainty</i></sup>.
|
||||
* <p> A prime is said to be <b>strong</b> iff integers <i>r</i>, <i>s</i>, and <i>t</i> exist such that the following three conditions are satisfied:
|
||||
* <ol>
|
||||
* <li> <i>p</i> - 1 has a large prime factor, denoted <i>r</i>,
|
||||
* <li> <i>p</i> + 1 has a large prime factor, denoted <i>s</i>, and
|
||||
* <li> <i>r</i> - 1 has a large prime factor, denoted <i>t</i>.
|
||||
* </ol>
|
||||
* <p>
|
||||
* GORDON's algorithm is described in [HAC] p.150 as follows:
|
||||
* <ol>
|
||||
* <li> generate 2 random primes <i>s</i> and <i>t</i> of roughly
|
||||
* equal bit-length.
|
||||
* <li> select an integer i0. Find the first prime in the
|
||||
* sequence <i>2it + 1</i>, for <i>i = i0, i0+1, i0+2,...</i>
|
||||
* Denote this prime by <i>r = 2it + 1</i>.
|
||||
* <li> compute <i>p0 = 2(s<sup>(r-2)</sup> mod r)s - 1</i> --See errata
|
||||
* on [HAC] web site.
|
||||
* <li> select an integer j0. Find the first prime in the sequence
|
||||
* <i>p0 + 2jrs</i>, for <i>j = j0, j0 + 1, j0 + 2, ...</i>
|
||||
* Denote this prime by <i>p = p0 + 2jrs</i>.
|
||||
* <li> return <i>p</i>.
|
||||
* </ol>
|
||||
* @param bitlength An approximate number of bits that the returned prime integer must have.
|
||||
* @param certainty A measure of the probability that the returned integer is a prime. The Miller-Rabin test used ensures that the returned value is a prime with a probability that exceeds 1 - (1/2)<sup><i>certainty</i></sup>.
|
||||
* @param random A source of randomness for the bits to use in building the prime.
|
||||
* @return An array whose elements are respectively p, r, s and t.
|
||||
*/
|
||||
public static BigInteger[] getGordon(int bitLength, int certainty, Random random) {
|
||||
//1. generate 2 random primes s and t of roughly equal bitlength
|
||||
BigInteger s = new BigInteger(bitLength / 2, certainty, random);
|
||||
BigInteger t = new BigInteger(bitLength / 2, certainty, random);
|
||||
|
||||
//2. select an integer i0. Find the first prime in the sequence
|
||||
// 2it + 1, for i = i0, i0+1, i0+2,... Denote this prime by
|
||||
// r = 2it + 1
|
||||
BigInteger t2 = t.multiply(TWO);
|
||||
BigInteger r = t2.add(ONE);
|
||||
|
||||
//Generating a strong prime (GORDON algorithm)...//
|
||||
while(!isProbablePrimeFast(r, certainty)) {
|
||||
r = r.add(t2);
|
||||
}//while//
|
||||
|
||||
//3. compute p0 = 2(s**(r-2) mod r)s - 1.
|
||||
// See errata on [HAC] web site.
|
||||
BigInteger p0 = s.modPow(r.subtract(TWO), r).multiply(s).multiply(TWO).subtract(ONE);
|
||||
|
||||
//4. select an integer j0. Find the first prime in the sequence
|
||||
// p0 + 2jrs, for j = j0, j0+1, j0+2,... Denote this prime by
|
||||
// p = p0 + 2jrs
|
||||
BigInteger rs2 = r.multiply(s).multiply(TWO);
|
||||
BigInteger p = p0.add(rs2);
|
||||
|
||||
//if(DEBUG && debuglevel >= 4) progress("<p>");
|
||||
while(!isProbablePrimeFast(p, certainty)) {
|
||||
p = p.add(rs2);
|
||||
//if(DEBUG && debuglevel >= 5) progress(".");
|
||||
}//while//
|
||||
|
||||
return new BigInteger[] {p, r, s, t};
|
||||
}//getGordon()//
|
||||
/**
|
||||
* Gets a BigInteger array whose elements are the prime factors of a designated BigInteger value, or null if the value could not easily be factorised.
|
||||
* @param r A BigInteger to factor.
|
||||
* @param certainty A measure of the probability that the largest returned factor is a prime. The Miller-Rabin test used ensures that this factor is a prime with a probability that exceeds 1 - (1/2)<sup><i>certainty</i></sup>.
|
||||
* @return A BigInteger array whose elements are the distinct prime factors of <i>p</i> when the latter can be written as: <pre> S_1 * S_2 * ... * S_n * L </pre>
|
||||
* Where S_i are small prime factors found in SMALL_PRIMES and L is a large prime factor. Return null otherwise.
|
||||
*/
|
||||
public static BigInteger[] getSmallFactors (BigInteger r, int certainty) {
|
||||
BigInteger[] result;
|
||||
BigInteger s;
|
||||
LiteList factors = new LiteList(100, 100);
|
||||
|
||||
for(int i = 0; i < SMALL_PRIMES.length; i++) {
|
||||
s = SMALL_PRIMES[i];
|
||||
result = r.divideAndRemainder(s);
|
||||
|
||||
if(result[1].equals(ZERO)) {
|
||||
factors.add(s); //SMALL_PRIMES[i] is a factor.//
|
||||
r = result[0]; //The quotient.//
|
||||
|
||||
//It may be a factor more than once; divide out from r.//
|
||||
while(true) {
|
||||
result = r.divideAndRemainder(s);
|
||||
|
||||
if(!result[1].equals(ZERO)) {
|
||||
break;
|
||||
}//if//
|
||||
|
||||
r = result[0]; // the quotient
|
||||
}//while//
|
||||
}//if//
|
||||
}//for//
|
||||
|
||||
if(!r.equals(ONE)) {
|
||||
//if(DEBUG && debuglevel >= 5) progress("(" + r.bitLength() + "-bit ");
|
||||
if(!r.isProbablePrime(certainty)) { // check that r is prime.
|
||||
//if(DEBUG && debuglevel >= 5) err.println("composite)");
|
||||
return null;
|
||||
}//if//
|
||||
//if(DEBUG && debuglevel >= 5) err.println("prime)");
|
||||
factors.add(r);
|
||||
}//if//
|
||||
else {
|
||||
//if(DEBUG && debuglevel >= 5) err.println("1");
|
||||
}//else//
|
||||
|
||||
BigInteger[] z = new BigInteger[factors.getSize()];
|
||||
|
||||
factors.toArray(z);
|
||||
|
||||
return z;
|
||||
}//getSmallFactors()//
|
||||
/**
|
||||
* Gets a BigInteger array whose elements are the prime factors of a designated BigInteger value, for which we already have one large prime factor.<p>
|
||||
* The returned array conatins all the distinct factors including the one we gave on input. The returned array is not guaranteed to be in any specific order.
|
||||
* @param r A BigInteger to factor.
|
||||
* @param certainty A measure of the probability that the returned integers are primes. The Miller-Rabin test used ensures that each array element is a prime with a probability that exceeds 1 - (1/2)<sup><i>certainty</i></sup>.
|
||||
* @param q A known prime factor of r.
|
||||
* @return If all the prime factors, except two (one of which is <i>q</i>), can be found in the list of pre-computed small primes the method returns an
|
||||
* array whose elements are the distinct prime factors of <i>r</i>. On the other hand if not all the prime factors, except two, can be found in the
|
||||
* list of pre-computed small primes the method returns null.
|
||||
*/
|
||||
public static BigInteger[] getSmallFactors(BigInteger r, int certainty, BigInteger q) {
|
||||
BigInteger[] result = r.divideAndRemainder(q);
|
||||
|
||||
if(!result[1].equals(ZERO)) {
|
||||
throw new ArithmeticException("q is not a factor of r");
|
||||
}//if//
|
||||
|
||||
BigInteger t = result[0]; //The quotient.//
|
||||
|
||||
while(true) {
|
||||
result = t.divideAndRemainder(q);
|
||||
|
||||
if(!result[1].equals(ZERO)) {
|
||||
break;
|
||||
}//if//
|
||||
|
||||
t = result[0]; //The quotient.//
|
||||
}//while//
|
||||
|
||||
BigInteger s;
|
||||
LiteList factors = new LiteList(100, 100);
|
||||
|
||||
for(int i = 0; i < SMALL_PRIMES.length; i++) {
|
||||
s = SMALL_PRIMES[i];
|
||||
result = t.divideAndRemainder(s);
|
||||
|
||||
if(result[1].equals(ZERO)) {
|
||||
factors.add(s); //SMALL_PRIMES[i] is a factor.//
|
||||
t = result[0]; //The quotient.//
|
||||
|
||||
//It may be a factor more than once; reduce t.//
|
||||
while (true) {
|
||||
result = t.divideAndRemainder(s);
|
||||
|
||||
if(!result[1].equals(ZERO)) {
|
||||
break;
|
||||
}//if//
|
||||
|
||||
t = result[0]; //The quotient.//
|
||||
}//while//
|
||||
}//if//
|
||||
}//for//
|
||||
|
||||
if(!t.equals(ONE)) {
|
||||
if(!t.isProbablePrime(certainty)) { // check that t is prime.
|
||||
//if(DEBUG && debuglevel >= 5) err.println("composite)");
|
||||
return null;
|
||||
}//if//
|
||||
//if(DEBUG && debuglevel >= 5) err.println("prime)");
|
||||
factors.add(t);
|
||||
}//if//
|
||||
else {
|
||||
//if(DEBUG && debuglevel >= 5) err.println("1");
|
||||
}//else//
|
||||
|
||||
factors.add(q); //The one we started with.//
|
||||
|
||||
BigInteger[] z = new BigInteger[factors.getSize()];
|
||||
|
||||
factors.toArray(z);
|
||||
|
||||
return z;
|
||||
}//getSmallFactors()//
|
||||
/**
|
||||
* ?
|
||||
* @param g
|
||||
* @param p
|
||||
* @param z An array containing (p-1)/q for each unique prime factor q of p-1.
|
||||
* @return Will be true if <i>g</i> is a generator mod <i>p</i>.
|
||||
*/
|
||||
public static boolean isGeneratorModP(BigInteger g, BigInteger p, BigInteger[] z) {
|
||||
for(int i = 0; i < z.length; i++) {
|
||||
if(g.modPow(z[i], p).equals(ONE)) {
|
||||
return false;
|
||||
}//if//
|
||||
}//for//
|
||||
|
||||
return true;
|
||||
}//isGeneratorModP()//
|
||||
/**
|
||||
* Implements a faster (on average) primality check than <code>BigInteger.isProbablePrime(r, certainty)</code>.
|
||||
* @param r The number to check.
|
||||
* @param certainty The level of certainty required.
|
||||
* @return Whether the integer is a probable prime number.
|
||||
*/
|
||||
public static boolean isProbablePrimeFast(BigInteger r, int certainty) {
|
||||
int x = r.mod(PRIME_BITMAP_MOD).intValue() >> 1;
|
||||
|
||||
if((PRIME_BITMAP[x >> 3] & (1 << (x & 0x07))) != 0) {
|
||||
return false;
|
||||
}//if//
|
||||
|
||||
BigInteger q = r.mod(SMALL_PRIME_MOD);
|
||||
|
||||
for(int i = 0; i < SMALL_PRIME_THRESHOLD; i++) {
|
||||
if (q.mod(SMALL_PRIMES[i]).equals(ZERO)) return false;
|
||||
}//for//
|
||||
|
||||
return r.isProbablePrime(certainty);
|
||||
}//isProbablePrimeFast()//
|
||||
}//PrimeNumberGenerator()//
|
||||
38
Common/src/com/common/event/BooleanHandler.java
Normal file
38
Common/src/com/common/event/BooleanHandler.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.event;
|
||||
|
||||
/**
|
||||
* Performs some task using the passed parameters and returns a value of Boolean type.
|
||||
*/
|
||||
public abstract class BooleanHandler implements java.io.Externalizable {
|
||||
/**
|
||||
* BooleanHandler constructor.
|
||||
*/
|
||||
public BooleanHandler() {
|
||||
super();
|
||||
}//BooleanHandler()//
|
||||
/**
|
||||
* Performs what ever the handler is coded to do when called.
|
||||
* @param parameters Object[] The parameters passed to the handler when it is invoked.
|
||||
* @return The return value of the handler which must either be a Boolean.TRUE or Boolean.FALSE value and should not be null.
|
||||
*/
|
||||
public abstract Boolean evaluate(Object[] parameters);
|
||||
/**
|
||||
* Will handle reading the handler from an input stream.
|
||||
* @param in java.io.ObjectInput The input stream to read the data from.
|
||||
*/
|
||||
public void readExternal(java.io.ObjectInput in) throws java.io.IOException, ClassNotFoundException {
|
||||
}//readExternal()//
|
||||
/**
|
||||
* Will handle writing the handler to an output stream.
|
||||
* @param out java.io.ObjectOutput The output stream to write the data to.
|
||||
*/
|
||||
public void writeExternal(java.io.ObjectOutput out) throws java.io.IOException {
|
||||
}//writeExternal()//
|
||||
}//BooleanHandler//
|
||||
34
Common/src/com/common/event/BooleanHandler1.java
Normal file
34
Common/src/com/common/event/BooleanHandler1.java
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.event;
|
||||
|
||||
/**
|
||||
* Performs some task using the passed parameters and returns a value of Boolean type.
|
||||
*/
|
||||
public abstract class BooleanHandler1 extends BooleanHandler {
|
||||
/**
|
||||
* BooleanHandler1 constructor.
|
||||
*/
|
||||
public BooleanHandler1() {
|
||||
super();
|
||||
}//BooleanHandler1()//
|
||||
/**
|
||||
* Calls the evaluate method that takes one parameter.
|
||||
* @param parameters Object[] The parameters passed to the handler when it is invoked.
|
||||
* @return The return value of the handler which must either be a Boolean.TRUE or Boolean.FALSE value and should not be null.
|
||||
*/
|
||||
public final Boolean evaluate(Object[] parameters) {
|
||||
return evaluate(((parameters != null) && (parameters.length > 0)) ? parameters[0] : null);
|
||||
}//evaluate()//
|
||||
/**
|
||||
* Performs what ever the handler is coded to do when called.
|
||||
* @param param1 The parameter passed to the handler when it is invoked.
|
||||
* @return The return value of the handler which must either be a Boolean.TRUE or Boolean.FALSE value and should not be null.
|
||||
*/
|
||||
public abstract Boolean evaluate(Object param1);
|
||||
}//BooleanHandler1//
|
||||
35
Common/src/com/common/event/BooleanHandler2.java
Normal file
35
Common/src/com/common/event/BooleanHandler2.java
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.event;
|
||||
|
||||
/**
|
||||
* Performs some task using the passed parameters and returns a value of Boolean type.
|
||||
*/
|
||||
public abstract class BooleanHandler2 extends BooleanHandler {
|
||||
/**
|
||||
* BooleanHandler2 constructor.
|
||||
*/
|
||||
public BooleanHandler2() {
|
||||
super();
|
||||
}//BooleanHandler2()//
|
||||
/**
|
||||
* Calls the evaluate method that takes two parameters.
|
||||
* @param parameters The parameters passed to the handler when it is invoked.
|
||||
* @return The return value of the handler which must either be a Boolean.TRUE or Boolean.FALSE value and should not be null.
|
||||
*/
|
||||
public final Boolean evaluate(Object[] parameters) {
|
||||
return evaluate(((parameters != null) && (parameters.length > 0)) ? parameters[0] : null, ((parameters != null) && (parameters.length > 1)) ? parameters[1] : null);
|
||||
}//evaluate()//
|
||||
/**
|
||||
* Performs what ever the handler is coded to do when called.
|
||||
* @param param1 The first parameter passed to the handler when it is invoked.
|
||||
* @param param2 The second parameter passed to the handler when it is invoked.
|
||||
* @return The return value of the handler which must either be a Boolean.TRUE or Boolean.FALSE value and should not be null.
|
||||
*/
|
||||
public abstract Boolean evaluate(Object param1, Object param2);
|
||||
}//BooleanHandler2//
|
||||
38
Common/src/com/common/event/ObjectHandler.java
Normal file
38
Common/src/com/common/event/ObjectHandler.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.event;
|
||||
|
||||
/**
|
||||
* Performs some task using the passed parameters and returns a value of Object type.
|
||||
*/
|
||||
public abstract class ObjectHandler implements java.io.Externalizable {
|
||||
/**
|
||||
* BooleanHandler constructor.
|
||||
*/
|
||||
public ObjectHandler() {
|
||||
super();
|
||||
}//BooleanHandler()//
|
||||
/**
|
||||
* Performs some action when the handler is invoked.
|
||||
* @param parameters The parameters passed to the handler when it is invoked.
|
||||
* @return The object value that is the result of the task handling.
|
||||
*/
|
||||
public abstract Object evaluate(Object[] parameters);
|
||||
/**
|
||||
* Will handle reading the handler from an input stream.
|
||||
* @param in java.io.ObjectInput The input stream to read the data from.
|
||||
*/
|
||||
public void readExternal(java.io.ObjectInput in) throws java.io.IOException, ClassNotFoundException {
|
||||
}//readExternal()//
|
||||
/**
|
||||
* Will handle writing the handler to an output stream.
|
||||
* @param out java.io.ObjectOutput The output stream to write the data to.
|
||||
*/
|
||||
public void writeExternal(java.io.ObjectOutput out) throws java.io.IOException {
|
||||
}//writeExternal()//
|
||||
}//ObjectHandler//
|
||||
34
Common/src/com/common/event/ObjectHandler1.java
Normal file
34
Common/src/com/common/event/ObjectHandler1.java
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.event;
|
||||
|
||||
/**
|
||||
* Performs some task using the passed parameters and returns a value of Object type.
|
||||
*/
|
||||
public abstract class ObjectHandler1 extends ObjectHandler {
|
||||
/**
|
||||
* ObjectHandler1 constructor.
|
||||
*/
|
||||
public ObjectHandler1() {
|
||||
super();
|
||||
}//ObjectHandler1()//
|
||||
/**
|
||||
* Calls the evaluate method that takes one parameter.
|
||||
* @param parameters The parameters passed to the handler when it is invoked.
|
||||
* @return The object value that is the result of the task handling.
|
||||
*/
|
||||
public final Object evaluate(Object[] parameters) {
|
||||
return evaluate(((parameters != null) && (parameters.length > 0)) ? parameters[0] : null);
|
||||
}//evaluate()//
|
||||
/**
|
||||
* Performs some action when the handler is invoked.
|
||||
* @param param1 The parameter passed to the handler when it is invoked.
|
||||
* @return The object value that is the result of the task handling.
|
||||
*/
|
||||
public abstract Object evaluate(Object param1);
|
||||
}//ObjectHandler1//
|
||||
35
Common/src/com/common/event/ObjectHandler2.java
Normal file
35
Common/src/com/common/event/ObjectHandler2.java
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.event;
|
||||
|
||||
/**
|
||||
* Performs some task using the passed parameters and returns a value of Object type.
|
||||
*/
|
||||
public abstract class ObjectHandler2 extends ObjectHandler {
|
||||
/**
|
||||
* ObjectHandler2 constructor.
|
||||
*/
|
||||
public ObjectHandler2() {
|
||||
super();
|
||||
}//ObjectHandler2()//
|
||||
/**
|
||||
* Calls the evaluate method that takes two parameters.
|
||||
* @param parameters The parameters passed to the handler when it is invoked.
|
||||
* @return The object value that is the result of the task handling.
|
||||
*/
|
||||
public final Object evaluate(Object[] parameters) {
|
||||
return evaluate(((parameters != null) && (parameters.length > 0)) ? parameters[0] : null, ((parameters != null) && (parameters.length > 1)) ? parameters[1] : null);
|
||||
}//evaluate()//
|
||||
/**
|
||||
* Performs some action when the handler is invoked.
|
||||
* @param param1 The first parameter passed to the handler when it is invoked.
|
||||
* @param param2 The second parameter passed to the handler when it is invoked.
|
||||
* @return The object value that is the result of the task handling.
|
||||
*/
|
||||
public abstract Object evaluate(Object param1, Object param2);
|
||||
}//ObjectHandler2//
|
||||
38
Common/src/com/common/event/VoidHandler.java
Normal file
38
Common/src/com/common/event/VoidHandler.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.event;
|
||||
|
||||
/**
|
||||
* Performs some task using the passed array of parameters.
|
||||
* <p>NOTE: If you want a handler that takes three or less parameters then use on of the HandlerN classes where N is the number of parameters the handler takes.
|
||||
*/
|
||||
public abstract class VoidHandler implements java.io.Externalizable {
|
||||
/**
|
||||
* Handler constructor.
|
||||
*/
|
||||
public VoidHandler() {
|
||||
super();
|
||||
}//Handler()//
|
||||
/**
|
||||
* Performs what ever the handler is coded to do when called.
|
||||
* @param parameters The parameters passed to the handler when it is invoked.
|
||||
*/
|
||||
public abstract void evaluate(Object[] parameters);
|
||||
/**
|
||||
* Handles reading the handler from an input stream.
|
||||
* @param in The input stream to read the data from.
|
||||
*/
|
||||
public void readExternal(java.io.ObjectInput in) throws java.io.IOException, ClassNotFoundException {
|
||||
}//readExternal()//
|
||||
/**
|
||||
* Handles writing the handler to an output stream.
|
||||
* @param out The output stream to write the data to.
|
||||
*/
|
||||
public void writeExternal(java.io.ObjectOutput out) throws java.io.IOException {
|
||||
}//writeExternal()//
|
||||
}//Handler//
|
||||
31
Common/src/com/common/event/VoidHandler0.java
Normal file
31
Common/src/com/common/event/VoidHandler0.java
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.event;
|
||||
|
||||
/**
|
||||
* Performs some task.
|
||||
*/
|
||||
public abstract class VoidHandler0 extends VoidHandler {
|
||||
/**
|
||||
* Handler0 constructor.
|
||||
*/
|
||||
public VoidHandler0() {
|
||||
super();
|
||||
}//Handler0()//
|
||||
/**
|
||||
* Performs what ever the handler is coded to do when called.
|
||||
*/
|
||||
public abstract void evaluate();
|
||||
/**
|
||||
* Calls the evaluate method that takes no parameters.
|
||||
* @param parameters The parameters passed to the handler when it is invoked.
|
||||
*/
|
||||
public void evaluate(Object[] parameters) {
|
||||
evaluate();
|
||||
}//evaluate()//
|
||||
}//Handler0//
|
||||
32
Common/src/com/common/event/VoidHandler1.java
Normal file
32
Common/src/com/common/event/VoidHandler1.java
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.event;
|
||||
|
||||
/**
|
||||
* Performs some task using the passed parameter.
|
||||
*/
|
||||
public abstract class VoidHandler1 extends VoidHandler {
|
||||
/**
|
||||
* Handler1 constructor.
|
||||
*/
|
||||
public VoidHandler1() {
|
||||
super();
|
||||
}//Handler1()//
|
||||
/**
|
||||
* Calls the evaluate method that takes one parameter.
|
||||
* @param parameters The parameters passed to the handler when it is invoked.
|
||||
*/
|
||||
public final void evaluate(Object[] parameters) {
|
||||
evaluate(((parameters != null) && (parameters.length > 0)) ? parameters[0] : null);
|
||||
}//evaluate()//
|
||||
/**
|
||||
* Performs what ever the handler is coded to do when called.
|
||||
* @param param1 The parameter passed to the handler when it is invoked.
|
||||
*/
|
||||
public abstract void evaluate(Object param1);
|
||||
}//Handler1//
|
||||
33
Common/src/com/common/event/VoidHandler2.java
Normal file
33
Common/src/com/common/event/VoidHandler2.java
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.event;
|
||||
|
||||
/**
|
||||
* Performs some task using the passed parameters.
|
||||
*/
|
||||
public abstract class VoidHandler2 extends VoidHandler {
|
||||
/**
|
||||
* Handler2 constructor.
|
||||
*/
|
||||
public VoidHandler2() {
|
||||
super();
|
||||
}//Handler2()//
|
||||
/**
|
||||
* Calls the evaluate method that takes two parameters.
|
||||
* @param parameters The parameters passed to the handler when it is invoked.
|
||||
*/
|
||||
public final void evaluate(Object[] parameters) {
|
||||
evaluate(((parameters != null) && (parameters.length > 0)) ? parameters[0] : null, ((parameters != null) && (parameters.length > 1)) ? parameters[1] : null);
|
||||
}//evaluate()//
|
||||
/**
|
||||
* Performs what ever the handler is coded to do when called.
|
||||
* @param param1 The first parameter passed to the handler when it is invoked.
|
||||
* @param param2 The second parameter passed to the handler when it is invoked.
|
||||
*/
|
||||
public abstract void evaluate(Object param1, Object param2);
|
||||
}//Handler2//
|
||||
24
Common/src/com/common/exception/CommonRuntimeException.java
Normal file
24
Common/src/com/common/exception/CommonRuntimeException.java
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.exception;
|
||||
|
||||
public class CommonRuntimeException extends RuntimeException {
|
||||
/**
|
||||
* CommonRuntimeException constructor.
|
||||
*/
|
||||
public CommonRuntimeException() {
|
||||
super();
|
||||
}//CommonRuntimeException()//
|
||||
/**
|
||||
* CommonRuntimeException constructor.
|
||||
* @param description String The exception description.
|
||||
*/
|
||||
public CommonRuntimeException(String description) {
|
||||
super(description);
|
||||
}//CommonRuntimeException()//
|
||||
}//CommonRuntimeException//
|
||||
24
Common/src/com/common/exception/EventException.java
Normal file
24
Common/src/com/common/exception/EventException.java
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.exception;
|
||||
|
||||
public class EventException extends CommonRuntimeException {
|
||||
/**
|
||||
* EventException constructor.
|
||||
*/
|
||||
public EventException() {
|
||||
super();
|
||||
}//EventException()//
|
||||
/**
|
||||
* EventException constructor.
|
||||
* @param description String The exception description.
|
||||
*/
|
||||
public EventException(String description) {
|
||||
super(description);
|
||||
}//EventException()//
|
||||
}//EventException//
|
||||
24
Common/src/com/common/exception/IOSecurityException.java
Normal file
24
Common/src/com/common/exception/IOSecurityException.java
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.exception;
|
||||
|
||||
public class IOSecurityException extends java.io.IOException {
|
||||
/**
|
||||
* IOSecurityException constructor.
|
||||
*/
|
||||
public IOSecurityException() {
|
||||
super();
|
||||
}//IOSecurityException()//
|
||||
/**
|
||||
* IOSecurityException constructor.
|
||||
* @param description The exception's description.
|
||||
*/
|
||||
public IOSecurityException(String description) {
|
||||
super(description);
|
||||
}//IOSecurityException()//
|
||||
}//IOSecurityException//
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.exception;
|
||||
|
||||
public class IllegalOperationException extends CommonRuntimeException {
|
||||
/**
|
||||
* IllegalOperationException constructor.
|
||||
*/
|
||||
public IllegalOperationException() {
|
||||
super();
|
||||
}//IllegalOperationException()//
|
||||
/**
|
||||
* IllegalOperationException constructor.
|
||||
* @param description String The exception description.
|
||||
*/
|
||||
public IllegalOperationException(String description) {
|
||||
super(description);
|
||||
}//IllegalOperationException()//
|
||||
}//IllegalOperationException//
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.exception;
|
||||
|
||||
/**
|
||||
* Thrown when a method has determined that one of its' arguments has an invalid or unexpected value.
|
||||
*/
|
||||
public class InvalidArgumentException extends CommonRuntimeException {
|
||||
/**
|
||||
* InvalidArgumentException constructor.
|
||||
*/
|
||||
public InvalidArgumentException() {
|
||||
super();
|
||||
}//InvalidArgumentException()//
|
||||
/**
|
||||
* InvalidArgumentException constructor.
|
||||
* @param description String The exception description.
|
||||
*/
|
||||
public InvalidArgumentException(String description) {
|
||||
super(description);
|
||||
}//InvalidArgumentException()//
|
||||
}//InvalidArgumentException//
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.exception;
|
||||
|
||||
/**
|
||||
* Thrown when a method that the user called is not being supported at all or under some circumstances.
|
||||
*/
|
||||
public class MethodNotSupportedException extends CommonRuntimeException {
|
||||
/**
|
||||
* MethodNotSupportedException constructor.
|
||||
*/
|
||||
public MethodNotSupportedException() {
|
||||
super();
|
||||
}//MethodNotSupportedException()//
|
||||
/**
|
||||
* MethodNotSupportedException constructor.
|
||||
* @param description The exception description.
|
||||
*/
|
||||
public MethodNotSupportedException(String description) {
|
||||
super(description);
|
||||
}//MethodNotSupportedException()//
|
||||
}//MethodNotSupportedException//
|
||||
24
Common/src/com/common/exception/ThreadException.java
Normal file
24
Common/src/com/common/exception/ThreadException.java
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.exception;
|
||||
|
||||
public class ThreadException extends CommonRuntimeException {
|
||||
/**
|
||||
* ThreadException constructor.
|
||||
*/
|
||||
public ThreadException() {
|
||||
super();
|
||||
}//ThreadException()//
|
||||
/**
|
||||
* ThreadException constructor.
|
||||
* @param description String The exception description.
|
||||
*/
|
||||
public ThreadException(String description) {
|
||||
super(description);
|
||||
}//ThreadException()//
|
||||
}//ThreadException//
|
||||
929
Common/src/com/common/io/AbstractObjectInputStream.java
Normal file
929
Common/src/com/common/io/AbstractObjectInputStream.java
Normal file
@@ -0,0 +1,929 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Externalizable;
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
import com.common.orb.Orb;
|
||||
import com.common.util.*;
|
||||
import com.common.debug.*;
|
||||
import com.common.exception.*;
|
||||
|
||||
/**
|
||||
* Defines a basic object input stream which can be subclassed as needed.
|
||||
*/
|
||||
public abstract class AbstractObjectInputStream extends AbstractStandardInputStream implements IObjectStream, java.io.ObjectInput, IObjectInputStream {
|
||||
/** A factory that will produce an instance of the given class. If provided, this will be used instead of calling Class.newInstance(). */
|
||||
private IInstanceFactory instanceFactory = null;
|
||||
/** The class tracker is notified every time a class is referenced by the stream. It allows the application to track what classes are utilized by the streams. */
|
||||
private IClassTracker classTracker = null;
|
||||
/** The list of classes that were serialized indexed by the number the stream will use to reference them in the future. */
|
||||
private IList classList = null;
|
||||
/** The optional class loader which is used if provided to lookup the class names. */
|
||||
private ClassLoader loader = null;
|
||||
/** The collection of objects deserialized in order of deserialization. Used to reference previously deserialized values by number in the stream to prevent recursive references from bloating the stream. */
|
||||
private IList deserializedValues = null;
|
||||
/** Called prior to looking up the deserialized class name - allows replacement of the class name. */
|
||||
private IClassReplacementHandler classReplacementHandler = null;
|
||||
/** Allows the input stream to replace one class with another <b>if the original class cannot be found</b>. */
|
||||
private IStreamManager streamManager = null;
|
||||
|
||||
/**
|
||||
* Provides customized deserialization of streamed application objects.
|
||||
* <p><b>WARNING: Circular reference to this serialized object may not occur within its deserialization.</b>
|
||||
* <p>The deserialize method will receive the object's class object and the stream reference. It should determine whether it can deserialize that type and either pass the request to the encapsulated handler, or return null indicating that the default action should occur within the stream.</p>
|
||||
* <p>The encapsulated handler allows the handlers to be chained together such that the stream calls the first handler in the chain and it will call the next handler until a handler deserializes the object, or all handlers return null.</p>
|
||||
* <p>TODO: Allow for circular references in the deserialized object.
|
||||
*/
|
||||
public static class CustomDeserializationHandler {
|
||||
private CustomDeserializationHandler encapsulatedHandler = null;
|
||||
|
||||
public CustomDeserializationHandler() {
|
||||
}//CustomDeserializationHandler()//
|
||||
public CustomDeserializationHandler(CustomDeserializationHandler encapsulatedHandler) {
|
||||
this.encapsulatedHandler = encapsulatedHandler;
|
||||
}//CustomDeserializationHandler()//
|
||||
/**
|
||||
* Gets the encapsulated handler providing deserialization services.
|
||||
* @return The handler that will be called if this handler cannot deserialize the object.
|
||||
*/
|
||||
public CustomDeserializationHandler getEncapsulatedHandler() {
|
||||
return encapsulatedHandler;
|
||||
}//getEncapsulatedHandler()//
|
||||
/**
|
||||
* Sets the encapsulated handler providing deserialization services.
|
||||
* @param encapsulatedHandler The handler that will be called if this handler cannot deserialize the object.
|
||||
*/
|
||||
public void setEncapsulatedHandler(CustomDeserializationHandler encapsulatedHandler) {
|
||||
this.encapsulatedHandler = encapsulatedHandler;
|
||||
}//setEncapsulatedHandler()//
|
||||
/**
|
||||
* Receives the object's class object and the stream reference and determines whether it can deserialize that type, either passing the request to the encapsulated handler, or returning null indicating that the default action should occur within the stream.
|
||||
* <p><b>WARNING: Circular reference to this serialized object may not occur within its deserialization.</b>
|
||||
* @param type The class for the object needing deserialization.
|
||||
* @param in The input stream containing the serialized object's bytes.
|
||||
* @return The object deserialized or null indicating that the stream should deserialize the object using the default deserialization algorithms.
|
||||
*/
|
||||
public Object deserialize(Class type, AbstractObjectInputStream in) {
|
||||
return encapsulatedHandler == null ? null : encapsulatedHandler.deserialize(type, in);
|
||||
}//deserialize()//
|
||||
}//CustomDeserializationHandler//
|
||||
/**
|
||||
* Adds a custom serialization handler to the mapping for use by the object input and output streams.
|
||||
* @param type The class the handler will be used to serialize and deserialize.
|
||||
* @param handler The handler used to serialize and deserialize instances of the given class.
|
||||
*/
|
||||
public static final void addCustomSerializationHandler(Class type, ISerializationHandler handler) {
|
||||
ObjectStream.serializationHandlersMap.put(type, handler);
|
||||
}//addCustomSerializationHandler()//
|
||||
/**
|
||||
* AbstractObjectInputStream constructor.
|
||||
* @param loader The class loader to use when it is necessary to load classes when creating objects read from the stream.
|
||||
* @param classList An optional list used to maintain the order classes were recognized by the stream. This allows class indexes to be streamed in place of the class name. This list is passed so that it may be reused if multiple streams from the same source are read.
|
||||
*/
|
||||
public AbstractObjectInputStream(ClassLoader loader, IList classList) throws IOException {
|
||||
this(loader, null, classList, null, null, null);
|
||||
}//AbstractObjectInputStream()//
|
||||
/**
|
||||
* AbstractObjectInputStream constructor.
|
||||
* @param loader The class loader to use when it is necessary to load classes when creating objects read from the stream.
|
||||
* @param classList An optional list used to maintain the order classes were recognized by the stream. This allows class indexes to be streamed in place of the class name. This list is passed so that it may be reused if multiple streams from the same source are read.
|
||||
* @param instanceFactory The instance factory to be used to generate instances of classes read from the stream.
|
||||
*/
|
||||
public AbstractObjectInputStream(ClassLoader loader, IList classList, IInstanceFactory instanceFactory) throws IOException {
|
||||
this(loader, null, classList, instanceFactory, null, null);
|
||||
}//AbstractObjectInputStream()//
|
||||
/**
|
||||
* AbstractObjectInputStream constructor.
|
||||
* @param loader The class loader to use when it is necessary to load classes when creating objects read from the stream.
|
||||
* @param classReplacementHandler The optional handler called when the stream loads a class. Allows the stream to replace one class name with another.
|
||||
* @param classList An optional list used to maintain the order classes were recognized by the stream. This allows class indexes to be streamed in place of the class name. This list is passed so that it may be reused if multiple streams from the same source are read.
|
||||
* @param instanceFactory The instance factory to be used to generate instances of classes read from the stream.
|
||||
* @param classTracker This optional handler is notified if a class is instantiated, allowing applications to track which classes are being streamed and instantiated.
|
||||
*/
|
||||
public AbstractObjectInputStream(ClassLoader loader, IClassReplacementHandler classReplacementHandler, IList classList, IInstanceFactory instanceFactory, IClassTracker classTracker) throws IOException {
|
||||
this(loader, classReplacementHandler, classList, instanceFactory, classTracker, null);
|
||||
}//AbstractObjectInputStream()//
|
||||
/**
|
||||
* AbstractObjectInputStream constructor.
|
||||
* @param loader The class loader to use when it is necessary to load classes when creating objects read from the stream.
|
||||
* @param classReplacementHandler The optional handler called when the stream loads a class. Allows the stream to replace one class name with another.
|
||||
* @param classList An optional list used to maintain the order classes were recognized by the stream. This allows class indexes to be streamed in place of the class name. This list is passed so that it may be reused if multiple streams from the same source are read.
|
||||
* @param instanceFactory The instance factory to be used to generate instances of classes read from the stream.
|
||||
* @param classTracker This optional handler is notified if a class is instantiated, allowing applications to track which classes are being streamed and instantiated.
|
||||
* @param deserializedValues The previously deserialized values.
|
||||
*/
|
||||
protected AbstractObjectInputStream(ClassLoader loader, IClassReplacementHandler classReplacementHandler, IList classList, IInstanceFactory instanceFactory, IClassTracker classTracker, IList deserializedValues) throws IOException {
|
||||
super();
|
||||
|
||||
this.classReplacementHandler = classReplacementHandler;
|
||||
this.classTracker = classTracker;
|
||||
this.loader = loader;
|
||||
this.classList = classList;
|
||||
this.deserializedValues = deserializedValues == null ? new LiteList(30, 10) : deserializedValues;
|
||||
this.instanceFactory = instanceFactory;
|
||||
}//AbstractObjectInputStream()//
|
||||
/**
|
||||
* AbstractObjectInputStream constructor.
|
||||
* @param loader The class loader to use when it is necessary to load classes when creating objects read from the stream.
|
||||
* @param classList An optional list used to maintain the order classes were recognized by the stream. This allows class indexes to be streamed in place of the class name. This list is passed so that it may be reused if multiple streams from the same source are read.
|
||||
* @param defaultNumberStyle One of the STYLE_xx identifiers. This defaults to most significant byte first.
|
||||
*/
|
||||
public AbstractObjectInputStream(ClassLoader loader, IList classList, int defaultNumberStyle) throws IOException {
|
||||
this(loader, null, classList, null, null, null, defaultNumberStyle);
|
||||
}//AbstractObjectInputStream()//
|
||||
/**
|
||||
* AbstractObjectInputStream constructor.
|
||||
* @param loader The class loader to use when it is necessary to load classes when creating objects read from the stream.
|
||||
* @param classList An optional list used to maintain the order classes were recognized by the stream. This allows class indexes to be streamed in place of the class name. This list is passed so that it may be reused if multiple streams from the same source are read.
|
||||
* @param instanceFactory The instance factory to be used to generate instances of classes read from the stream.
|
||||
* @param defaultNumberStyle One of the STYLE_xx identifiers. This defaults to most significant byte first.
|
||||
*/
|
||||
public AbstractObjectInputStream(ClassLoader loader, IList classList, IInstanceFactory instanceFactory, int defaultNumberStyle) throws IOException {
|
||||
this(loader, null, classList, instanceFactory, null, null, defaultNumberStyle);
|
||||
}//AbstractObjectInputStream()//
|
||||
/**
|
||||
* AbstractObjectInputStream constructor.
|
||||
* @param loader The class loader to use when it is necessary to load classes when creating objects read from the stream.
|
||||
* @param classReplacementHandler The optional handler called when the stream loads a class. Allows the stream to replace one class name with another.
|
||||
* @param classList An optional list used to maintain the order classes were recognized by the stream. This allows class indexes to be streamed in place of the class name. This list is passed so that it may be reused if multiple streams from the same source are read.
|
||||
* @param instanceFactory The instance factory to be used to generate instances of classes read from the stream.
|
||||
* @param classTracker This optional handler is notified if a class is instantiated, allowing applications to track which classes are being streamed and instantiated.
|
||||
* @param defaultNumberStyle One of the STYLE_xx identifiers. This defaults to most significant byte first.
|
||||
*/
|
||||
public AbstractObjectInputStream(ClassLoader loader, IClassReplacementHandler classReplacementHandler, IList classList, IInstanceFactory instanceFactory, IClassTracker classTracker, int defaultNumberStyle) throws IOException {
|
||||
this(loader, classReplacementHandler, classList, instanceFactory, classTracker, null, defaultNumberStyle);
|
||||
}//AbstractObjectInputStream()//
|
||||
/**
|
||||
* AbstractObjectInputStream constructor.
|
||||
* @param loader The class loader to use when it is necessary to load classes when creating objects read from the stream.
|
||||
* @param classReplacementHandler The optional handler called when the stream loads a class. Allows the stream to replace one class name with another.
|
||||
* @param classList An optional list used to maintain the order classes were recognized by the stream. This allows class indexes to be streamed in place of the class name. This list is passed so that it may be reused if multiple streams from the same source are read.
|
||||
* @param instanceFactory The instance factory to be used to generate instances of classes read from the stream.
|
||||
* @param classTracker This optional handler is notified if a class is instantiated, allowing applications to track which classes are being streamed and instantiated.
|
||||
* @param deserializedValues The previously deserialized values.
|
||||
* @param defaultNumberStyle One of the STYLE_xx identifiers. This defaults to most significant byte first.
|
||||
*/
|
||||
protected AbstractObjectInputStream(ClassLoader loader, IClassReplacementHandler classReplacementHandler, IList classList, IInstanceFactory instanceFactory, IClassTracker classTracker, IList deserializedValues, int defaultNumberStyle) throws IOException {
|
||||
super(defaultNumberStyle);
|
||||
|
||||
this.classReplacementHandler = classReplacementHandler;
|
||||
this.classTracker = classTracker;
|
||||
this.loader = loader;
|
||||
this.classList = classList;
|
||||
this.deserializedValues = deserializedValues == null ? new LiteList(30, 10) : deserializedValues;
|
||||
this.instanceFactory = instanceFactory;
|
||||
}//AbstractObjectInputStream()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IObjectInputStream#getInstanceFactory()
|
||||
*/
|
||||
public IInstanceFactory getInstanceFactory() {
|
||||
return instanceFactory;
|
||||
}//()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IObjectInputStream#getClassTracker()
|
||||
*/
|
||||
public IClassTracker getClassTracker() {
|
||||
return classTracker;
|
||||
}//getClassTracker()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IObjectInputStream#getClassList()
|
||||
*/
|
||||
public IList getClassList() {
|
||||
return classList;
|
||||
}//getClassList()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IObjectInputStream#getLoader()
|
||||
*/
|
||||
public ClassLoader getLoader() {
|
||||
return loader;
|
||||
}//getLoader()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IObjectInputStream#getDeserializedValues()
|
||||
*/
|
||||
public IList getDeserializedValues() {
|
||||
return deserializedValues;
|
||||
}//getDeserializedValues()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IObjectInputStream#getClassReplacementHandler()
|
||||
*/
|
||||
public IClassReplacementHandler getClassReplacementHandler() {
|
||||
return classReplacementHandler;
|
||||
}//getClassReplacementHandler()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IObjectInputStream#getStreamManager()
|
||||
*/
|
||||
public IStreamManager getStreamManager() {
|
||||
return streamManager;
|
||||
}//getStreamManager()//
|
||||
/**
|
||||
* Allocates memory for a new object of the given type.
|
||||
* <p>WARNING: At this time, proper initialization of the object may not occur.
|
||||
* @param type The class to create a new object for.
|
||||
* @return The new initialized object.
|
||||
*/
|
||||
private Object allocateNewObject(Class type) throws InstantiationException, IllegalAccessException {
|
||||
Object result = null;
|
||||
|
||||
if(type == null) {
|
||||
throw new InstantiationException("Received a null class reference in ObjectInputStream.allocateNewObject(Class).");
|
||||
}//if//
|
||||
|
||||
if(classTracker != null) {
|
||||
classTracker.add(type.getName());
|
||||
}//if//
|
||||
|
||||
//First try to use the instance factory.//
|
||||
if(instanceFactory != null) {
|
||||
result = instanceFactory.createInstance(type);
|
||||
}//if/
|
||||
|
||||
//Second try using a default constructor.//
|
||||
if(result == null) {
|
||||
try {
|
||||
result = type.newInstance();
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
//Ignore.//
|
||||
}//catch//
|
||||
}//if//
|
||||
|
||||
//Last try the native system call.//
|
||||
if(result == null) {
|
||||
//TODO: Should make sure that this fails gracefully if the library is not available.//
|
||||
result = com.common.system.SystemManager.instantiateObject(type);
|
||||
}//if//
|
||||
|
||||
return result;
|
||||
}//allocateNewObject()//
|
||||
/**
|
||||
* Closes this input stream. Will also close the wrappered stream.
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
if(deserializedValues != null) {
|
||||
deserializedValues.removeAll();
|
||||
deserializedValues = null;
|
||||
}//if//
|
||||
}//close()//
|
||||
/**
|
||||
* Deserailizes an object from this stream.
|
||||
* @return The object that was deserialized.
|
||||
*/
|
||||
protected Object deserialize(Class type) throws IOException, ClassNotFoundException {
|
||||
Object result = null;
|
||||
ISerializationHandler handler = null;
|
||||
|
||||
if((ObjectStream.serializationHandlersMap != null) && ((handler = (ISerializationHandler) ObjectStream.serializationHandlersMap.get(type)) != null)) {
|
||||
result = handler.deserialize(this);
|
||||
}//if//
|
||||
else if(Throwable.class.isAssignableFrom(type)) {
|
||||
//Allow the exceptions to be deserialized, although we will be unable to set the message of stack.//
|
||||
}//else if//
|
||||
else {
|
||||
throw new IOException("Unable to deserialize the object of type: " + type.getName());
|
||||
}//else//
|
||||
|
||||
return result;
|
||||
}//deserialize()//
|
||||
/**
|
||||
* Deserializes an object from this stream.
|
||||
* @param object The object to deserialize.
|
||||
* @return The deserialized object. May differ from the passed object.
|
||||
*/
|
||||
protected Object deserialize(Object object) throws ClassNotFoundException, IOException {
|
||||
//Note: The proxy class can't implement IExternalizable, but the proxied class can. To avoid trying to make a remote call to the IExternalizable readExternal method, we need to ensure this isn't a proxy.//
|
||||
if(object instanceof IExternalizable/* && !Orb.isProxy(object)*/) {
|
||||
Object result = ((IExternalizable) object).readExternal(this);
|
||||
|
||||
if(result != null) {
|
||||
if(result == IExternalizable.NULL_VALUE) {
|
||||
object = null;
|
||||
}//if//
|
||||
else {
|
||||
object = result;
|
||||
}//else//
|
||||
}//if//
|
||||
}//if//
|
||||
else if(object instanceof Externalizable) {
|
||||
((Externalizable) object).readExternal(this);
|
||||
}//else if//
|
||||
else if(object instanceof Throwable) {
|
||||
//Allow the exceptions to be deserialized, although we will be unable to set the message of stack.//
|
||||
}//else if//
|
||||
else {
|
||||
throw new IOException("Unable to deserialize the object of type: " + object.getClass().getName());
|
||||
}//else//
|
||||
|
||||
return object;
|
||||
}//deserialize()//
|
||||
/**
|
||||
* Loads a class using what ever class loader has been specified.
|
||||
* @param className The name of the class to load.
|
||||
* @return The loaded class.
|
||||
*/
|
||||
private Class loadClass(String className) throws ClassNotFoundException {
|
||||
try {
|
||||
if(classReplacementHandler != null) {
|
||||
className = classReplacementHandler.getReplacementClassName(className);
|
||||
}//if//
|
||||
|
||||
return Class.forName(className, true, loader == null ? getClass().getClassLoader() : loader);
|
||||
}//try//
|
||||
catch(IncompatibleClassChangeError e) {
|
||||
Debug.log(e);
|
||||
throw new ClassNotFoundException("The class " + className + " was not loadable.");
|
||||
}//catch//
|
||||
catch(NoClassDefFoundError e) {
|
||||
Debug.log(e);
|
||||
throw new ClassNotFoundException("The class " + className + " definition was not found.");
|
||||
}//catch//
|
||||
}//loadClass()//
|
||||
/**
|
||||
* Will allow the user of the stream to peek at a byte in the stream.
|
||||
* @param offset The offset from the current location in the stream.
|
||||
* @return Will return the byte at that offset.
|
||||
*/
|
||||
public byte peekByte(int offset) throws IOException {
|
||||
/* if((position + offset < count) && (position + offset >= 0)) {
|
||||
return buffer[position + offset];
|
||||
}//if//
|
||||
|
||||
throw new IOException("Invalid offset.");
|
||||
*/
|
||||
throw new IOException("ObjectInputStream.peakByte(int) not yet implemented.");
|
||||
}//peekByte()//
|
||||
/**
|
||||
* Reads an array from the stream.
|
||||
* @param isPrimitive Whether the array is of a primitive type.
|
||||
* @return The array object.
|
||||
*/
|
||||
private Object readArray() throws IOException, ClassNotFoundException {
|
||||
int deserializedValueIndex = deserializedValues.getSize();
|
||||
Object array = null;
|
||||
String typeName;
|
||||
Class type;
|
||||
int typeNumber;
|
||||
int dimensionCount;
|
||||
int dimensionSize;
|
||||
boolean isNative = readBoolean();
|
||||
|
||||
deserializedValues.add(null);
|
||||
|
||||
if(isNative) {
|
||||
switch(readByte()) {
|
||||
case BOOLEAN: {
|
||||
type = Boolean.TYPE;
|
||||
break;
|
||||
}//case//
|
||||
case BYTE: {
|
||||
type = Byte.TYPE;
|
||||
break;
|
||||
}//case//
|
||||
case SHORT: {
|
||||
type = Short.TYPE;
|
||||
break;
|
||||
}//case//
|
||||
case INTEGER: {
|
||||
type = Integer.TYPE;
|
||||
break;
|
||||
}//case//
|
||||
case FLOAT: {
|
||||
type = Float.TYPE;
|
||||
break;
|
||||
}//case//
|
||||
case LONG: {
|
||||
type = Long.TYPE;
|
||||
break;
|
||||
}//case//
|
||||
case DOUBLE: {
|
||||
type = Double.TYPE;
|
||||
break;
|
||||
}//case//
|
||||
case CHARACTER: {
|
||||
type = Character.TYPE;
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
Debug.log("Error: Unidentified primitive type.");
|
||||
type = null;
|
||||
break;
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
typeName = type.getName();
|
||||
}//if//
|
||||
else {
|
||||
typeName = readString();
|
||||
type = loadClass(typeName);
|
||||
}//else//
|
||||
|
||||
typeNumber = readByte();
|
||||
dimensionCount = readInt();
|
||||
//Read the first dimension's size so that we can create the array.//
|
||||
dimensionSize = readInt();
|
||||
|
||||
if(dimensionSize != -1) {
|
||||
//Create the array with a size for only the first dimension.//
|
||||
try {
|
||||
array = Array.newInstance(type, dimensionSize);
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
Debug.log(e, "Caught while trying to instantiate an instance of [" + typeName);
|
||||
throw new IOException("Error instantiating array.");
|
||||
}//catch//
|
||||
|
||||
deserializedValues.replace(deserializedValueIndex, array);
|
||||
readArray(array, typeName, typeNumber, 0, dimensionCount, dimensionSize);
|
||||
|
||||
if(classTracker != null) {
|
||||
classTracker.add(array.getClass().getName());
|
||||
}//if//
|
||||
}//if//
|
||||
|
||||
return array;
|
||||
}//readArray()//
|
||||
/**
|
||||
* A recusive method which will iterate over each item in the array and output it to the stream.
|
||||
* The arrayType should be Stream.OBJECT or one of the primitives (ie Stream.INTEGER or Stream.BYTE..etc).
|
||||
* @param array The array housing the data to be read. This array is already correctly sized for the data.
|
||||
* @param typeNumber The array type indicating what type of data is being read.
|
||||
* @param dimension The current dimension being read.
|
||||
* @param dimensionCount The number of dimensions to be read.
|
||||
* @param dimensionSize The count of elements in the given array to be read.
|
||||
*/
|
||||
private void readArray(Object array, String typeName, int typeNumber, int dimension, int dimensionCount, int dimensionSize) throws IOException, ClassNotFoundException {
|
||||
if(dimension + 1 == dimensionCount) {
|
||||
switch(typeNumber) {
|
||||
case OBJECT: {
|
||||
for(int index = 0; index < dimensionSize; index++) {
|
||||
Object obj = readObject();
|
||||
|
||||
if(obj != null) { //Temp fix for gcj.//
|
||||
Array.set(array, index, obj);
|
||||
}//if//
|
||||
}//for//
|
||||
break;
|
||||
}//case//
|
||||
case INTEGER: {
|
||||
int[] typedArray = (int[]) array;
|
||||
|
||||
for(int index = 0; index < dimensionSize; index++) {
|
||||
typedArray[index] = readInt();
|
||||
}//for//
|
||||
break;
|
||||
}//case//
|
||||
case LONG: {
|
||||
long[] typedArray = (long[]) array;
|
||||
|
||||
for(int index = 0; index < dimensionSize; index++) {
|
||||
typedArray[index] = readLong();
|
||||
}//for//
|
||||
break;
|
||||
}//case//
|
||||
case SHORT: {
|
||||
short[] typedArray = (short[]) array;
|
||||
|
||||
for(int index = 0; index < dimensionSize; index++) {
|
||||
typedArray[index] = readShort();
|
||||
}//for//
|
||||
break;
|
||||
}//case//
|
||||
case BYTE: {
|
||||
byte[] typedArray = (byte[]) array;
|
||||
|
||||
read(typedArray);
|
||||
break;
|
||||
}//case//
|
||||
case CHARACTER: {
|
||||
char[] typedArray = (char[]) array;
|
||||
|
||||
for(int index = 0; index < dimensionSize; index++) {
|
||||
typedArray[index] = readChar();
|
||||
}//for//
|
||||
break;
|
||||
}//case//
|
||||
case BOOLEAN: {
|
||||
boolean[] typedArray = (boolean[]) array;
|
||||
|
||||
for(int index = 0; index < dimensionSize; index++) {
|
||||
typedArray[index] = readBoolean();
|
||||
}//for//
|
||||
break;
|
||||
}//case//
|
||||
case FLOAT: {
|
||||
float[] typedArray = (float[]) array;
|
||||
|
||||
for(int index = 0; index < dimensionSize; index++) {
|
||||
typedArray[index] = readFloat();
|
||||
}//for//
|
||||
break;
|
||||
}//case//
|
||||
case DOUBLE: {
|
||||
double[] typedArray = (double[]) array;
|
||||
|
||||
for(int index = 0; index < dimensionSize; index++) {
|
||||
typedArray[index] = readDouble();
|
||||
}//for//
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
throw new IOException("Invalid arrayType found.");
|
||||
}//default//
|
||||
}//switch//
|
||||
}//if//
|
||||
else {
|
||||
String nextTypeName;
|
||||
Class nextType;
|
||||
|
||||
if(dimension + 2 == dimensionCount) {
|
||||
if(typeNumber == OBJECT) {
|
||||
nextTypeName = typeName.substring(2, typeName.length() - 1);
|
||||
nextType = loadClass(nextTypeName);
|
||||
}//if//
|
||||
else {
|
||||
switch(typeNumber) {
|
||||
case BOOLEAN: {
|
||||
nextType = Boolean.TYPE;
|
||||
break;
|
||||
}//case//
|
||||
case BYTE: {
|
||||
nextType = Byte.TYPE;
|
||||
break;
|
||||
}//case//
|
||||
case SHORT: {
|
||||
nextType = Short.TYPE;
|
||||
break;
|
||||
}//case//
|
||||
case INTEGER: {
|
||||
nextType = Integer.TYPE;
|
||||
break;
|
||||
}//case//
|
||||
case FLOAT: {
|
||||
nextType = Float.TYPE;
|
||||
break;
|
||||
}//case//
|
||||
case LONG: {
|
||||
nextType = Long.TYPE;
|
||||
break;
|
||||
}//case//
|
||||
case DOUBLE: {
|
||||
nextType = Double.TYPE;
|
||||
break;
|
||||
}//case//
|
||||
case CHARACTER: {
|
||||
nextType = Character.TYPE;
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
Debug.log("Error: Unidentified primitive type.");
|
||||
nextType = null;
|
||||
break;
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
nextTypeName = nextType.getName();
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
nextTypeName = typeName.substring(1);
|
||||
nextType = loadClass(nextTypeName);
|
||||
}//else//
|
||||
|
||||
//Read the next dimension of the array.//
|
||||
for(int index = 0; index < dimensionSize; index++) {
|
||||
int nextDimensionSize = readInt();
|
||||
|
||||
//If the dimension is not null (as indicated by -1) then create it and read it.//
|
||||
if(nextDimensionSize != -1) {
|
||||
Object nextArray = Array.newInstance(nextType, nextDimensionSize);
|
||||
|
||||
Array.set(array, index, nextArray);
|
||||
readArray(nextArray, nextTypeName, typeNumber, dimension + 1, dimensionCount, nextDimensionSize);
|
||||
}//if//
|
||||
else {
|
||||
Array.set(array, index, null);
|
||||
}//else//
|
||||
}//for//
|
||||
}//else//
|
||||
}//readArray()//
|
||||
/**
|
||||
* Reads an object from the stream.
|
||||
* @return The object read from the stream.
|
||||
*/
|
||||
public Object readObject() throws ClassNotFoundException, IOException {
|
||||
return readObject(false);
|
||||
}//readObject()//
|
||||
/**
|
||||
* Reads an object from the stream.
|
||||
* @param loopDetect
|
||||
* @return The object read from the stream.
|
||||
*/
|
||||
protected Object readObject(boolean loopDetect) throws ClassNotFoundException, IOException {
|
||||
int objectType = readByte();
|
||||
Object result = null;
|
||||
boolean alreadyAddedToDeserializedValues = false; //Arrays and Object which may have internal recusive references must add to the list as soon as the object/array has been allocated.//
|
||||
|
||||
switch(objectType) {
|
||||
case ARRAY: {
|
||||
result = readArray();
|
||||
alreadyAddedToDeserializedValues = true;
|
||||
break;
|
||||
}//case//
|
||||
case NULL: {
|
||||
break;
|
||||
}//case//
|
||||
case RECURSIVE_OBJECT: {
|
||||
int number = readInt();
|
||||
|
||||
return deserializedValues.get(number);
|
||||
}//case//
|
||||
case CUSTOM_OBJECT: {
|
||||
if(loopDetect) {
|
||||
throw new IOException("Invalid stream detected due to unexpected looping.");
|
||||
}//if//
|
||||
|
||||
try {
|
||||
Class type;
|
||||
int deserializedValueIndex = deserializedValues.getSize();
|
||||
|
||||
//Add a place holder to the deserialized object list.//
|
||||
deserializedValues.add(null);
|
||||
type = (Class) readObject();
|
||||
|
||||
result = deserialize(type);
|
||||
deserializedValues.replace(deserializedValueIndex, result); //Replace the placeholder with the object.//
|
||||
alreadyAddedToDeserializedValues = true;
|
||||
}//try//
|
||||
catch(IOException e) {
|
||||
throw e;
|
||||
}//catch//
|
||||
catch(Throwable e) {
|
||||
Debug.log(e);
|
||||
throw new IOException("Stream corruption error or Stream setup error found while trying to read an Object.");
|
||||
}//catch//
|
||||
|
||||
break;
|
||||
}//case//
|
||||
case OBJECT: {
|
||||
if(loopDetect) {
|
||||
throw new IOException("Invalid stream detected due to unexpected looping.");
|
||||
}//if//
|
||||
|
||||
try {
|
||||
Class type;
|
||||
int deserializedValueIndex = deserializedValues.getSize();
|
||||
|
||||
//Add a place holder to the deserialized object list.//
|
||||
deserializedValues.add(null);
|
||||
type = (Class) readObject();
|
||||
|
||||
//Create a new instance using the default constructor.//
|
||||
try {
|
||||
result = type.newInstance();
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
//Ignore.//
|
||||
}//catch//
|
||||
|
||||
//Try to create a new instance using native code.//
|
||||
if(result == null) {
|
||||
try {
|
||||
result = allocateNewObject(type);
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
throw new IOException("Error allocating type: " + type.getName().toString() + " Cannot finish reading stream due to finding unknown object type: " + type.getName() + "\r\n\tCausing exception: " + e.toString());
|
||||
}//catch//
|
||||
}//if//
|
||||
|
||||
if(result != null) {
|
||||
deserializedValues.replace(deserializedValueIndex, result); //Replace the placeholder with the object.//
|
||||
alreadyAddedToDeserializedValues = true;
|
||||
result = deserialize(result);
|
||||
}//if//
|
||||
}//try//
|
||||
catch(IOException e) {
|
||||
throw e;
|
||||
}//catch//
|
||||
catch(Throwable e) {
|
||||
Debug.log(e);
|
||||
throw new IOException("Stream corruption error or Stream setup error found while trying to read an Object.");
|
||||
}//catch//
|
||||
|
||||
break;
|
||||
}//case//
|
||||
case BOOLEAN: {
|
||||
result = new Boolean(readBoolean());
|
||||
break;
|
||||
}//case//
|
||||
case BYTE: {
|
||||
result = new Byte(readByte());
|
||||
break;
|
||||
}//case//
|
||||
case CHARACTER: {
|
||||
result = new Character(readChar());
|
||||
break;
|
||||
}//case//
|
||||
case SHORT: {
|
||||
result = new Short(readShort());
|
||||
break;
|
||||
}//case//
|
||||
case INTEGER: {
|
||||
result = new Integer(readInt());
|
||||
break;
|
||||
}//case//
|
||||
case LONG: {
|
||||
result = new Long(readLong());
|
||||
break;
|
||||
}//case//
|
||||
case FLOAT: {
|
||||
result = new Float(readFloat());
|
||||
break;
|
||||
}//case//
|
||||
case DOUBLE: {
|
||||
result = new Double(readDouble());
|
||||
break;
|
||||
}//case//
|
||||
case STRING: {
|
||||
/*
|
||||
result = StringSupport.fromBytes(buffer, position, -1);
|
||||
pos += StringSupport.getStringLength((String) result) + 4;
|
||||
*/
|
||||
result = readUTF16();
|
||||
|
||||
break;
|
||||
}//case//
|
||||
case UTF8: {
|
||||
/*
|
||||
result = StringSupport.fromUtfBytes(buffer, position, -1);
|
||||
pos += StringSupport.getUtfStringLength((String) result) + 4;
|
||||
*/
|
||||
result = readUTF8();
|
||||
|
||||
break;
|
||||
}//case//
|
||||
case CLASS: {
|
||||
int deserializedValueIndex = deserializedValues.getSize();
|
||||
|
||||
//Add a place holder to the deserialized object list.//
|
||||
deserializedValues.add(null);
|
||||
//Read the type.//
|
||||
result = readType();
|
||||
//Replace the placeholder.//
|
||||
deserializedValues.replace(deserializedValueIndex, result);
|
||||
//Set the flag so we don't add the deserialized value twice.//
|
||||
alreadyAddedToDeserializedValues = true;
|
||||
|
||||
break;
|
||||
}//case//
|
||||
case SHARED_BOOLEAN: {
|
||||
result = (readBoolean() == true ? Boolean.TRUE : Boolean.FALSE);
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
if(isDecrypting()) {
|
||||
throw new IOSecurityException("Stream corruption detected. Most likely cause was a failure to properly decrypt the stream.");
|
||||
}//if//
|
||||
else {
|
||||
throw new IOException("Stream corruption detected. Unknown object type.");
|
||||
}//else//
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
if((result != null) && (!alreadyAddedToDeserializedValues)) {
|
||||
//Cache the return value in case the object is referenced again in this stream.//
|
||||
deserializedValues.add(result);
|
||||
}//if//
|
||||
|
||||
return result;
|
||||
}//readObject()//
|
||||
/**
|
||||
* Reads a string from the stream as an object. This is wholly different from using the readUTF() readUTF8() and readUTF16() methods.
|
||||
* @return The value read from the stream.
|
||||
*/
|
||||
public String readString() throws IOException {
|
||||
try {
|
||||
return (String) readObject(false);
|
||||
}//try//
|
||||
catch(ClassCastException e) {
|
||||
throw new IOException("Stream corruption: Unable to cast Object to String in readString().");
|
||||
}//catch//
|
||||
catch(ClassNotFoundException e) {
|
||||
throw new IOException("Stream corruption: Unable to find a class while reading a string: " + e.getMessage());
|
||||
}//catch//
|
||||
}//readString()//
|
||||
/**
|
||||
* Reads a class name or ID off of the stream.
|
||||
* If optimized class streaming is enabled on the remote process, then the classList will be used to cache the mapping of class objects to ID's.
|
||||
* @return The class object read from the stream.
|
||||
*/
|
||||
protected Class readType() throws IOException, ClassNotFoundException {
|
||||
Object object = readObject();
|
||||
Integer index = (Integer) readObject();
|
||||
Class result = null;
|
||||
|
||||
if(object != null) {
|
||||
try {
|
||||
if(object instanceof String) {
|
||||
result = loadClass((String) object);
|
||||
}//if//
|
||||
else {
|
||||
switch(((Byte) object).intValue()) {
|
||||
case BOOLEAN: {
|
||||
result = Boolean.TYPE;
|
||||
break;
|
||||
}//case//
|
||||
case BYTE: {
|
||||
result = Byte.TYPE;
|
||||
break;
|
||||
}//case//
|
||||
case SHORT: {
|
||||
result = Short.TYPE;
|
||||
break;
|
||||
}//case//
|
||||
case INTEGER: {
|
||||
result = Integer.TYPE;
|
||||
break;
|
||||
}//case//
|
||||
case FLOAT: {
|
||||
result = Float.TYPE;
|
||||
break;
|
||||
}//case//
|
||||
case LONG: {
|
||||
result = Long.TYPE;
|
||||
break;
|
||||
}//case//
|
||||
case DOUBLE: {
|
||||
result = Double.TYPE;
|
||||
break;
|
||||
}//case//
|
||||
case CHARACTER: {
|
||||
result = Character.TYPE;
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
Debug.log("Error: Unidentified primitive type.");
|
||||
break;
|
||||
}//default//
|
||||
}//switch//
|
||||
}//else//
|
||||
}//try//
|
||||
catch(ClassNotFoundException e) {
|
||||
if(streamManager != null) {
|
||||
result = streamManager.replaceType((String) object);
|
||||
|
||||
if(result == null) {
|
||||
throw e;
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
throw e;
|
||||
}//else//
|
||||
}//catch//
|
||||
|
||||
//Save the class reference if the index is non null.//
|
||||
if(index != null) {
|
||||
synchronized(classList) {
|
||||
//Only place the type in the classList when it will be the last item in the class list.//
|
||||
while(classList.getSize() != index.intValue()) {
|
||||
try {
|
||||
classList.wait();
|
||||
}//try//
|
||||
catch(InterruptedException e) {
|
||||
Thread.interrupted();
|
||||
}//catch//
|
||||
}//while//
|
||||
|
||||
classList.add(result);
|
||||
|
||||
classList.notifyAll();
|
||||
}//synchronized//
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
synchronized(classList) {
|
||||
if(classList.getSize() <= index.intValue()) {
|
||||
throw new IOException("Unable to find the class due to an invalid index being received.");
|
||||
}//if//
|
||||
|
||||
result = (Class) classList.get(index.intValue());
|
||||
}//synchronized//
|
||||
}//else//
|
||||
|
||||
return result;
|
||||
}//readType()//
|
||||
/**
|
||||
* Resets this stream so that it may be re-read.
|
||||
*/
|
||||
public void reset() throws java.io.IOException {
|
||||
if(deserializedValues != null) {
|
||||
deserializedValues.removeAll();
|
||||
}//if//
|
||||
}//reset()//
|
||||
}//AbstractObjectInputStream//
|
||||
697
Common/src/com/common/io/AbstractObjectOutputStream.java
Normal file
697
Common/src/com/common/io/AbstractObjectOutputStream.java
Normal file
@@ -0,0 +1,697 @@
|
||||
/*
|
||||
* Copyright (c) 2005,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Externalizable;
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
import com.common.orb.Orb;
|
||||
import com.common.util.*;
|
||||
import com.common.debug.*;
|
||||
import com.common.util.optimized.*;
|
||||
|
||||
/**
|
||||
* Defines a basic object output stream which can be subclassed as needed.
|
||||
*/
|
||||
public abstract class AbstractObjectOutputStream extends AbstractStandardOutputStream implements IObjectStream, java.io.ObjectOutput, IObjectOutputStream {
|
||||
/** The mapping class names to numbers allowing the stream to optimize the serialization of classes. The hash map keys should be compared using an identity comparator. This value may be <code>null</code> which will turn off optimized type streaming. */
|
||||
private IHashMap classMap;
|
||||
/** A collection of objects which have already been serialized, used to prevent recusive serialization. */
|
||||
private ObjectIntHashMap serializedObjectMap;
|
||||
/** The handler called when writing a class name to the stream. This allows the application to swap the name for another name. */
|
||||
private IClassReplacementHandler classReplacementHandler = null;
|
||||
/**
|
||||
* Adds a custom serialization handler to the mapping for use by the object input and output streams.
|
||||
* @param type The class the handler will be used to serialize and deserialize.
|
||||
* @param handler The handler used to serialize and deserialize instances of the given class.
|
||||
*/
|
||||
public static final void addCustomSerializationHandler(Class type, ISerializationHandler handler) {
|
||||
AbstractObjectInputStream.addCustomSerializationHandler(type, handler);
|
||||
}//addCustomSerializationHandler()//
|
||||
/**
|
||||
* AbstractObjectOutputStream constructor.
|
||||
* <p>WARNING: If a classMap is provided (optimized type streaming is used), then the user must be careful to reuse the same maps while streaming under the same context. In addition, the receiver of the stream must be careful to reuse thier maps so that the indexes match up properly.
|
||||
* <p></b>IMPORTANT: The supplied map MUST use an IDENTITY comparator <code>Comparator.getIdentityComparator()</code> for key comparison.</b>
|
||||
* @param classMap The mapping class names to numbers allowing the stream to optimize the serialization of classes. The hash map keys should be compared using an identity comparator. This value may be <code>null</code> which will turn off optimized type streaming.
|
||||
* @param classReplacementHandler The handler called when writing a class name to the stream. This allows the application to swap the name for another name.
|
||||
*/
|
||||
public AbstractObjectOutputStream(IHashMap classMap, IClassReplacementHandler classReplacementHandler) throws IOException {
|
||||
this(classMap, classReplacementHandler, null);
|
||||
}//AbstractObjectOutputStream()//
|
||||
/**
|
||||
* AbstractObjectOutputStream constructor.
|
||||
* <p>WARNING: If a classMap is provided (optimized type streaming is used), then the user must be careful to reuse the same maps while streaming under the same context. In addition, the receiver of the stream must be careful to reuse thier maps so that the indexes match up properly.
|
||||
* <p></b>IMPORTANT: The supplied map MUST use an IDENTITY comparator <code>Comparator.getIdentityComparator()</code> for key comparison.</b>
|
||||
* @param classMap The optional mapping class names to numbers allowing the stream to optimize the serialization of classes. The hash map keys should be compared using an identity comparator. This value may be <code>null</code> which will turn off optimized type streaming.
|
||||
* @param classReplacementHandler The optional handler called when writing a class name to the stream. This allows the application to swap the name for another name.
|
||||
* @param serializedObjectMap The optional map of indices by class name - used in conjunction with the classMap to serialize class names.
|
||||
*/
|
||||
protected AbstractObjectOutputStream(IHashMap classMap, IClassReplacementHandler classReplacementHandler, ObjectIntHashMap serializedObjectMap) throws IOException {
|
||||
super();
|
||||
this.classReplacementHandler = classReplacementHandler;
|
||||
//Save the class mapping for later use. This will be used to substitute class identifiers for class names in the stream.//
|
||||
this.classMap = classMap;
|
||||
//Setup the mapping of serialized objects so that recursion can be detected.//
|
||||
this.serializedObjectMap = serializedObjectMap != null ? serializedObjectMap : new ObjectIntHashMap(30, com.common.comparison.Comparator.getIdentityComparator());
|
||||
}//AbstractObjectOutputStream()//
|
||||
/**
|
||||
* AbstractObjectOutputStream constructor.
|
||||
* <p>WARNING: If a classMap is provided (optimized type streaming is used), then the user must be careful to reuse the same maps while streaming under the same context. In addition, the receiver of the stream must be careful to reuse thier maps so that the indexes match up properly.
|
||||
* <p></b>IMPORTANT: The supplied map MUST use an IDENTITY comparator <code>Comparator.getIdentityComparator()</code> for key comparison.</b>
|
||||
* @param classMap The mapping class names to numbers allowing the stream to optimize the serialization of classes. The hash map keys should be compared using an identity comparator. This value may be <code>null</code> which will turn off optimized type streaming.
|
||||
* @param classReplacementHandler The handler called when writing a class name to the stream. This allows the application to swap the name for another name.
|
||||
* @param defaultNumberStyle One of the STYLE_xx identifiers. This defaults to most significant byte first.
|
||||
*/
|
||||
public AbstractObjectOutputStream(IHashMap classMap, IClassReplacementHandler classReplacementHandler, int defaultNumberStyle) throws IOException {
|
||||
this(classMap, classReplacementHandler, null, defaultNumberStyle);
|
||||
}//AbstractObjectOutputStream()//
|
||||
/**
|
||||
* AbstractObjectOutputStream constructor.
|
||||
* <p>WARNING: If a classMap is provided (optimized type streaming is used), then the user must be careful to reuse the same maps while streaming under the same context. In addition, the receiver of the stream must be careful to reuse thier maps so that the indexes match up properly.
|
||||
* <p></b>IMPORTANT: The supplied map MUST use an IDENTITY comparator <code>Comparator.getIdentityComparator()</code> for key comparison.</b>
|
||||
* @param classMap The optional mapping class names to numbers allowing the stream to optimize the serialization of classes. The hash map keys should be compared using an identity comparator. This value may be <code>null</code> which will turn off optimized type streaming.
|
||||
* @param classReplacementHandler The optional handler called when writing a class name to the stream. This allows the application to swap the name for another name.
|
||||
* @param serializedObjectMap The optional map of indices by class name - used in conjunction with the classMap to serialize class names.
|
||||
* @param defaultNumberStyle One of the STYLE_xx identifiers. This defaults to most significant byte first.
|
||||
*/
|
||||
protected AbstractObjectOutputStream(IHashMap classMap, IClassReplacementHandler classReplacementHandler, ObjectIntHashMap serializedObjectMap, int defaultNumberStyle) throws IOException {
|
||||
super(defaultNumberStyle);
|
||||
this.classReplacementHandler = classReplacementHandler;
|
||||
//Save the class mapping for later use. This will be used to substitute class identifiers for class names in the stream.//
|
||||
this.classMap = classMap;
|
||||
//Setup the mapping of serialized objects so that recursion can be detected.//
|
||||
this.serializedObjectMap = serializedObjectMap != null ? serializedObjectMap : new ObjectIntHashMap(30, com.common.comparison.Comparator.getIdentityComparator());
|
||||
}//AbstractObjectOutputStream()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IObjectOutputStream#getSerializedObjectMap()
|
||||
*/
|
||||
public ObjectIntHashMap getSerializedObjectMap() {
|
||||
return serializedObjectMap;
|
||||
}//getSerializedObjectMap()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IObjectOutputStream#getClassMap()
|
||||
*/
|
||||
public IHashMap getClassMap() {
|
||||
return classMap;
|
||||
}//getClassMap()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IObjectOutputStream#getClassReplacementHandler()
|
||||
*/
|
||||
public IClassReplacementHandler getClassReplacementHandler() {
|
||||
return classReplacementHandler;
|
||||
}//getClassReplacementHandler()//
|
||||
/**
|
||||
* Closes this output stream and releases any system resources associated with this stream.
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
//Clear out the serialized object map to help GC.//
|
||||
if(serializedObjectMap != null) {
|
||||
serializedObjectMap.removeAll();
|
||||
}//if//
|
||||
}//close()//
|
||||
/**
|
||||
* Flushes any buffered bytes to their destination.
|
||||
*/
|
||||
public abstract void flush() throws IOException;
|
||||
/**
|
||||
* Resets the stream so it may be reused.
|
||||
* It is the caller's reponsibility to ensure that other chained streams are also reset.
|
||||
*/
|
||||
protected void internalReset() {
|
||||
if(serializedObjectMap != null) {
|
||||
serializedObjectMap.removeAll();
|
||||
}//if//
|
||||
}//internalReset()//
|
||||
/**
|
||||
* Serializes the given object to this stream.
|
||||
* <p>NOTE: The OBJECT identifier and the object's type have already been serialized to the stream.
|
||||
* @param object The object to serialize.
|
||||
*/
|
||||
protected void serializeObject(Object object) throws IOException {
|
||||
//Note: The proxy class can't implement IExternalizable, but the proxied class can. To avoid trying to make a remote call to the IExternalizable writeExternal method, we need to ensure this isn't a proxy.//
|
||||
if(object instanceof IExternalizable/* && !Orb.isProxy(object)*/) {
|
||||
//Use the serialize handler.//
|
||||
write(OBJECT);
|
||||
//Write the object's class.//
|
||||
writeObject(object.getClass());
|
||||
//Call object to write its' self out.//
|
||||
((IExternalizable) object).writeExternal(this);
|
||||
}//if//
|
||||
else if(object instanceof Externalizable) {
|
||||
//Use the serialize handler.//
|
||||
write(OBJECT);
|
||||
//Write the object's class.//
|
||||
writeObject(object.getClass());
|
||||
//Call object to write its' self out.//
|
||||
((Externalizable) object).writeExternal(this);
|
||||
}//else if//
|
||||
else {
|
||||
ISerializationHandler serializeHandler = (ISerializationHandler) ObjectStream.serializationHandlersMap.get(object.getClass());
|
||||
|
||||
//Use the serialize handler.//
|
||||
write(CUSTOM_OBJECT);
|
||||
//Write the object's class.//
|
||||
writeObject(object.getClass());
|
||||
|
||||
if(serializeHandler != null) {
|
||||
serializeHandler.serialize(object, this);
|
||||
}//if//
|
||||
else if(object instanceof Throwable) {
|
||||
//Allow exceptions to be serialized, although the exception stack and message data will not be serialized because it cannot be reassembled on the other side.//
|
||||
}//else if//
|
||||
else {
|
||||
throw new IOException(object.getClass().getName() + " does not support serialization.");
|
||||
}//else//
|
||||
}//else//
|
||||
}//serialize()//
|
||||
/**
|
||||
* Will recusively write out the contents of the array. Will also optimize for primitive types.
|
||||
* @param array The array to write to the stream.
|
||||
*/
|
||||
private void writeArray(Object array) throws IOException, ClassNotFoundException {
|
||||
String className = array.getClass().getName();
|
||||
int dimensionCount = 0;
|
||||
char arrayTypeCharacter;
|
||||
int typeNumber;
|
||||
//Class arrayClass = null;
|
||||
|
||||
//Count the number of array dimensions.//
|
||||
while(className.charAt(dimensionCount) == '[') {
|
||||
dimensionCount++;
|
||||
}//while//
|
||||
|
||||
//Identify the array type (Object, int, byte, float, etc...).//
|
||||
arrayTypeCharacter = className.charAt(dimensionCount);
|
||||
|
||||
switch(arrayTypeCharacter) {
|
||||
case 'L': {
|
||||
typeNumber = OBJECT;
|
||||
break;
|
||||
}//case//
|
||||
case 'B': {
|
||||
typeNumber = BYTE;
|
||||
break;
|
||||
}//case//
|
||||
case 'D': {
|
||||
typeNumber = DOUBLE;
|
||||
break;
|
||||
}//case//
|
||||
case 'F': {
|
||||
typeNumber = FLOAT;
|
||||
break;
|
||||
}//case//
|
||||
case 'I': {
|
||||
typeNumber = INTEGER;
|
||||
break;
|
||||
}//case//
|
||||
case 'J': {
|
||||
typeNumber = LONG;
|
||||
break;
|
||||
}//case//
|
||||
case 'S': {
|
||||
typeNumber = SHORT;
|
||||
break;
|
||||
}//case//
|
||||
case 'V': {
|
||||
typeNumber = BOOLEAN;
|
||||
break;
|
||||
}//case//
|
||||
case 'C': {
|
||||
typeNumber = CHARACTER;
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
Debug.log("Error: Unable to determine the array type.");
|
||||
typeNumber = OBJECT;
|
||||
break;
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
//Write the array header to the stream.//
|
||||
write(ARRAY);
|
||||
|
||||
if(dimensionCount == 1) {
|
||||
if(typeNumber == OBJECT) {
|
||||
writeBoolean(false);
|
||||
//Remove the preceeding '[L' and ending ';'.//
|
||||
writeString(className.substring(2, className.length() - 1));
|
||||
}//if//
|
||||
else {
|
||||
writeBoolean(true);
|
||||
writeByte(typeNumber);
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
writeBoolean(false);
|
||||
//Remove the preceeding '['.//
|
||||
writeString(className.substring(1));
|
||||
}//else//
|
||||
|
||||
writeByte((byte) typeNumber);
|
||||
writeInt(dimensionCount);
|
||||
writeArray(array, typeNumber, dimensionCount, 0);
|
||||
}//writeObject()//
|
||||
/**
|
||||
* A recusive method which will iterate over each item in the array and output it to the stream.
|
||||
* The arrayType should be Stream.OBJECT or one of the primitives (ie Stream.INTEGER or Stream.BYTE..etc).
|
||||
* <p>NOTE: The length of the dimensionSizeList may not be the same as the numberOfDimensions.
|
||||
* @param array The array to write to the stream.
|
||||
* @param arrayType The type of the array we are writing.
|
||||
* @param numberOfDimensions The number of dimensions for this array.
|
||||
* @param dimensionIndex The index of the dimension we are currently writing.
|
||||
* @param dimensionSizeList ?
|
||||
*/
|
||||
private void writeArray(Object array, int typeNumber, int dimensionCount, int dimensionIndex) throws IOException {
|
||||
int dimensionSize = array != null ? Array.getLength(array) : -1;
|
||||
|
||||
//Write the dimension size or -1 if the array is null.//
|
||||
writeInt(dimensionSize);
|
||||
|
||||
//If the array is not null then write it out.//
|
||||
if(array != null) {
|
||||
if(dimensionCount == dimensionIndex + 1) {
|
||||
switch(typeNumber) {
|
||||
case OBJECT: {
|
||||
Object[] objects = (Object[]) array;
|
||||
|
||||
for(int index = 0; index < dimensionSize; index++) {
|
||||
writeObject(objects[index]);
|
||||
}//for//
|
||||
break;
|
||||
}//case//
|
||||
case INTEGER: {
|
||||
int[] ints = (int[]) array;
|
||||
|
||||
for(int index = 0; index < dimensionSize; index++) {
|
||||
writeInt(ints[index]);
|
||||
}//for//
|
||||
break;
|
||||
}//case//
|
||||
case LONG: {
|
||||
long[] longs = (long[]) array;
|
||||
|
||||
for(int index = 0; index < dimensionSize; index++) {
|
||||
writeLong(longs[index]);
|
||||
}//for//
|
||||
break;
|
||||
}//case//
|
||||
case SHORT: {
|
||||
short[] shorts = (short[]) array;
|
||||
|
||||
for(int index = 0; index < dimensionSize; index++) {
|
||||
writeShort(shorts[index]);
|
||||
}//for//
|
||||
break;
|
||||
}//case//
|
||||
case BYTE: {
|
||||
write((byte[]) array);
|
||||
break;
|
||||
}//case//
|
||||
case CHARACTER: {
|
||||
char[] chars = (char[]) array;
|
||||
|
||||
for(int index = 0; index < dimensionSize; index++) {
|
||||
writeChar(chars[index]);
|
||||
}//for//
|
||||
break;
|
||||
}//case//
|
||||
case BOOLEAN: {
|
||||
boolean[] booleans = (boolean[]) array;
|
||||
|
||||
for(int index = 0; index < dimensionSize; index++) {
|
||||
writeBoolean(booleans[index]);
|
||||
}//for//
|
||||
break;
|
||||
}//case//
|
||||
case FLOAT: {
|
||||
float[] floats = (float[]) array;
|
||||
|
||||
for(int index = 0; index < dimensionSize; index++) {
|
||||
writeFloat(floats[index]);
|
||||
}//for//
|
||||
break;
|
||||
}//case//
|
||||
case DOUBLE: {
|
||||
double[] doubles = (double[]) array;
|
||||
|
||||
for(int index = 0; index < dimensionSize; index++) {
|
||||
writeDouble(doubles[index]);
|
||||
}//for//
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
throw new IOException("Invalid arrayType found while streaming the array.");
|
||||
}//default//
|
||||
}//switch//
|
||||
}//if//
|
||||
else {
|
||||
for(int index = 0; index < dimensionSize; index++) {
|
||||
writeArray(Array.get(array, index), typeNumber, dimensionCount, dimensionIndex + 1);
|
||||
}//for//
|
||||
}//else//
|
||||
}//if//
|
||||
}//writeArray()//
|
||||
/**
|
||||
* Writes a string in double byte format (two byte Unicode).
|
||||
* @param string The string to write.
|
||||
*/
|
||||
public void writeDoubleByte(String string) throws IOException {
|
||||
writeObject(string, STRING);
|
||||
}//writeDoubleByte()//
|
||||
/**
|
||||
* Writes a Boolean object to the stream.
|
||||
* @param object The boolean to write.
|
||||
*/
|
||||
public void writeObject(Boolean object) throws IOException {
|
||||
writeObject(object, (object == Boolean.TRUE || object == Boolean.FALSE) ? SHARED_BOOLEAN : BOOLEAN);
|
||||
}//writeObject()//
|
||||
/**
|
||||
* Writes a Byte object to the stream.
|
||||
* @param object The byte to write.
|
||||
*/
|
||||
public void writeObject(Byte object) throws IOException {
|
||||
writeObject(object, BYTE);
|
||||
}//writeObject()//
|
||||
/**
|
||||
* Writes a Character object to the stream.
|
||||
* @param object The character to write.
|
||||
*/
|
||||
public void writeObject(Character object) throws IOException {
|
||||
writeObject(object, CHARACTER);
|
||||
}//writeObject()//
|
||||
/**
|
||||
* Writes a Double object to the stream.
|
||||
* @param object The double to write.
|
||||
*/
|
||||
public void writeObject(Double object) throws IOException {
|
||||
writeObject(object, DOUBLE);
|
||||
}//writeObject()//
|
||||
/**
|
||||
* Writes a Float object to the stream.
|
||||
* @param object The float to write.
|
||||
*/
|
||||
public void writeObject(Float object) throws IOException {
|
||||
writeObject(object, FLOAT);
|
||||
}//writeObject()//
|
||||
/**
|
||||
* Writes an Integer object to the stream.
|
||||
* @param object The integer to write.
|
||||
*/
|
||||
public void writeObject(Integer object) throws IOException {
|
||||
writeObject(object, INTEGER);
|
||||
}//writeObject()//
|
||||
/**
|
||||
* Writes a Long object to the stream.
|
||||
* @param object The long to write.
|
||||
*/
|
||||
public void writeObject(Long object) throws IOException {
|
||||
writeObject(object, LONG);
|
||||
}//writeObject()//
|
||||
/**
|
||||
* Writes an object to the stream.
|
||||
* @param object The object to write to this stream.
|
||||
*/
|
||||
public void writeObject(Object object) throws IOException {
|
||||
writeObject(object, UNKNOWN_OBJECT);
|
||||
}//writeObject()//
|
||||
/**
|
||||
* TODO: Update this documentation!<p>
|
||||
* Writes any object to the stream. The object must either be one of the optimized types, or it must implement Externalizable, IExternalizable, or it must have registered special serialization handlers.
|
||||
* @param object The object to serialize to this stream.
|
||||
* @param objectType The type code for the object. This should be UNKNOWN_OBJECT if the type code is not yet known.
|
||||
*/
|
||||
protected void writeObject(Object object, byte objectType) throws IOException {
|
||||
try {
|
||||
int objectNumber;
|
||||
|
||||
if(object == null) {
|
||||
//Write the null value to the stream.//
|
||||
write(NULL);
|
||||
}//if//
|
||||
else if((objectNumber = serializedObjectMap.get(object)) != IObjectIntHashMap.NULL_VALUE) { //Check to see if this object has already been serialized.//
|
||||
//Place the object number on the stream because the object has already been streamed.//
|
||||
write(RECURSIVE_OBJECT);
|
||||
writeInt(objectNumber);
|
||||
}//if//
|
||||
else {
|
||||
//Add the object to the collection of already sent objects.//
|
||||
objectNumber = serializedObjectMap.getSize();
|
||||
serializedObjectMap.put(object, objectNumber);
|
||||
|
||||
//Serialize the object.//
|
||||
if(object instanceof Class) {
|
||||
writeByte(CLASS);
|
||||
writeType((Class) object);
|
||||
}//if//
|
||||
else if(object.getClass().isArray()) {
|
||||
writeArray(object);
|
||||
}//else if//
|
||||
else {
|
||||
//Setup the type identifier so that some optimizations can occur.//
|
||||
if(objectType == UNKNOWN_OBJECT) {
|
||||
if(object instanceof java.lang.Number) {
|
||||
if(object instanceof java.lang.Integer) {
|
||||
objectType = INTEGER;
|
||||
}//if//
|
||||
else if(object instanceof java.lang.Long) {
|
||||
objectType = LONG;
|
||||
}//else if//
|
||||
else if(object instanceof java.lang.Byte) {
|
||||
objectType = BYTE;
|
||||
}//else if//
|
||||
else if(object instanceof java.lang.Short) {
|
||||
objectType = SHORT;
|
||||
}//else if//
|
||||
else if(object instanceof java.lang.Float) {
|
||||
objectType = FLOAT;
|
||||
}//else if//
|
||||
else if(object instanceof java.lang.Double) {
|
||||
objectType = DOUBLE;
|
||||
}//else if//
|
||||
}//if//
|
||||
else if(object instanceof java.lang.Character) {
|
||||
objectType = CHARACTER;
|
||||
}//else if//
|
||||
else if(object instanceof java.lang.String) {
|
||||
objectType = UTF8;
|
||||
}//else if//
|
||||
else if(object instanceof java.lang.Boolean) {
|
||||
if(object == Boolean.TRUE || object == Boolean.FALSE) {
|
||||
objectType = SHARED_BOOLEAN;
|
||||
}//if//
|
||||
else {
|
||||
objectType = BOOLEAN;
|
||||
}//else//
|
||||
}//else if//
|
||||
}//if//
|
||||
|
||||
//Write the object using either the optimized code, or the standard object serialization code.//
|
||||
if(objectType != UNKNOWN_OBJECT) {
|
||||
//Write the type code.//
|
||||
write(objectType);
|
||||
|
||||
//Determine which optimized type it is.//
|
||||
switch(objectType) {
|
||||
case BOOLEAN: {
|
||||
writeBoolean(((Boolean) object).booleanValue());
|
||||
break;
|
||||
}//case//
|
||||
case BYTE: {
|
||||
writeByte(((Byte) object).byteValue());
|
||||
break;
|
||||
}//case//
|
||||
case CHARACTER: {
|
||||
writeChar(((Character) object).charValue());
|
||||
break;
|
||||
}//case//
|
||||
case SHORT: {
|
||||
writeShort(((Short) object).shortValue());
|
||||
break;
|
||||
}//case//
|
||||
case INTEGER: {
|
||||
writeInt(((Integer) object).intValue());
|
||||
break;
|
||||
}//case//
|
||||
case LONG: {
|
||||
writeLong(((Long) object).longValue());
|
||||
break;
|
||||
}//case//
|
||||
case FLOAT: {
|
||||
writeFloat(((Float) object).floatValue());
|
||||
break;
|
||||
}//case//
|
||||
case DOUBLE: {
|
||||
writeDouble(((Double) object).doubleValue());
|
||||
break;
|
||||
}//case//
|
||||
case STRING: {
|
||||
/*
|
||||
String str = ((String) outObject);
|
||||
int length = str.length();
|
||||
char[] chars = str.toCharArray();
|
||||
|
||||
writeInt(length);
|
||||
|
||||
for(int i = 0; i < length; i++) {
|
||||
write((int) chars[i]);
|
||||
}//for//
|
||||
*/
|
||||
/*
|
||||
writeInt(((String) outObject).length());
|
||||
StringSupport.writeString((String) outObject, this);
|
||||
*/
|
||||
/*
|
||||
int numBytes;
|
||||
|
||||
//Calculate the number of bytes the string will write out.//
|
||||
numBytes = StringSupport.getUnicode16Length((String) object) + 4;
|
||||
//Write the string bytes.//
|
||||
outputStream.ensureSpace(numBytes);
|
||||
StringSupport.toBytes((String) object, outputStream.getBuffer(), outputStream.index);
|
||||
outputStream.index += numBytes;
|
||||
*/
|
||||
writeUTF16((String) object);
|
||||
|
||||
break;
|
||||
}//case//
|
||||
case UTF8: {
|
||||
/*
|
||||
int numBytes;
|
||||
|
||||
//Calculate the number of bytes the string will write out.//
|
||||
numBytes = StringSupport.getUtf8Length((String) object) + 4;
|
||||
//Write the string bytes.//
|
||||
outputStream.ensureSpace(numBytes);
|
||||
StringSupport.toUtf8Bytes((String) object, outputStream.getBuffer(), outputStream.index);
|
||||
outputStream.index += numBytes;
|
||||
*/
|
||||
writeUTF8((String) object);
|
||||
|
||||
break;
|
||||
}//case//
|
||||
case SHARED_BOOLEAN: {
|
||||
writeBoolean(((Boolean) object).booleanValue());
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
throw new IOException("Unknown optimized type.");
|
||||
}//default//
|
||||
}//switch//
|
||||
}//if//
|
||||
else {
|
||||
//Write the object's attributes.//
|
||||
serializeObject(object);
|
||||
}//else//
|
||||
}//else//
|
||||
}//else//
|
||||
}//try//
|
||||
catch(IOException e) {
|
||||
throw e; //Rethrow//
|
||||
}//catch//
|
||||
catch(Throwable e) {
|
||||
Debug.log(e);
|
||||
throw new IOException("Caught a " + e.getClass().getName() + " exception while serializing an object of the class " + object.getClass());
|
||||
}//catch//
|
||||
}//writeObject()//
|
||||
/**
|
||||
* Writes a Short object to the stream.
|
||||
* @param object The short to write.
|
||||
*/
|
||||
public void writeObject(Short object) throws IOException {
|
||||
writeObject(object, SHORT);
|
||||
}//writeObject()//
|
||||
/**
|
||||
* Writes a String object to the stream.
|
||||
* @param object The string to write.
|
||||
*/
|
||||
public void writeObject(String object) throws IOException {
|
||||
writeObject(object, UTF8);
|
||||
}//writeObject()//
|
||||
/**
|
||||
* Writes a string using the default format (UTF8 or multi-byte Unicode).
|
||||
* @param string The string to stream.
|
||||
*/
|
||||
public void writeString(String string) throws IOException {
|
||||
writeObject(string, UTF8);
|
||||
}//writeString()//
|
||||
/**
|
||||
* Manages the type collections so that the stream may be optimized such that a class name only has to be written to the stream once.
|
||||
* @param type The class to write to the stream.
|
||||
*/
|
||||
protected void writeType(Class type) throws IOException {
|
||||
//Check to see if we are using optimized type streaming.//
|
||||
Object typeData = null;
|
||||
Integer typeNumber = null;
|
||||
|
||||
if((classMap != null) && (classMap.containsKey(type))) {
|
||||
typeNumber = (Integer) classMap.get(type);
|
||||
}//if//
|
||||
else {
|
||||
if(classMap != null) {
|
||||
//We can use the size of the class map as an index because values will never be removed from the map.//
|
||||
classMap.put(type, (typeNumber = new Integer(classMap.getSize())));
|
||||
}//if//
|
||||
|
||||
if(type.isPrimitive()) {
|
||||
String name = type.getName();
|
||||
|
||||
switch(Character.toLowerCase(name.charAt(0))) {
|
||||
case 'i': {
|
||||
typeData = new Byte(INTEGER);
|
||||
break;
|
||||
}//case//
|
||||
case 'b': {
|
||||
if(type.equals(Byte.TYPE)) {
|
||||
typeData = new Byte(BYTE);
|
||||
}//if//
|
||||
else {
|
||||
typeData = new Byte(BOOLEAN);
|
||||
}//else//
|
||||
break;
|
||||
}//case//
|
||||
case 's': {
|
||||
typeData = new Byte(SHORT);
|
||||
break;
|
||||
}//case//
|
||||
case 'l': {
|
||||
typeData = new Byte(LONG);
|
||||
break;
|
||||
}//case//
|
||||
case 'f': {
|
||||
typeData = new Byte(FLOAT);
|
||||
break;
|
||||
}//case//
|
||||
case 'd': {
|
||||
typeData = new Byte(DOUBLE);
|
||||
break;
|
||||
}//case//
|
||||
case 'c': {
|
||||
typeData = new Byte(CHARACTER);
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
Debug.log("Error: Unidentified primitive type name.");
|
||||
break;
|
||||
}//case//
|
||||
}//switch//
|
||||
}//if//
|
||||
else {
|
||||
//Write the type name this one time so that the remote process knows what the index will map to.//
|
||||
typeData = type.getName();
|
||||
|
||||
if(classReplacementHandler != null) {
|
||||
typeData = classReplacementHandler.getReplacementClassName((String) typeData);
|
||||
}//if//
|
||||
}//else//
|
||||
}//else//
|
||||
|
||||
writeObject(typeData);
|
||||
writeObject(typeNumber);
|
||||
}//writeType()//
|
||||
}//AbstractObjectOutputStream//
|
||||
314
Common/src/com/common/io/AbstractStandardInputStream.java
Normal file
314
Common/src/com/common/io/AbstractStandardInputStream.java
Normal file
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2008 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.EOFException;
|
||||
|
||||
/**
|
||||
* Provides basic functionality for a standard stream that can deserialize basic java data types.
|
||||
*/
|
||||
public abstract class AbstractStandardInputStream extends InputStream implements IStandardInputStream {
|
||||
public static final int STYLE_LSF = StreamSupport.NUMBER_LSF;
|
||||
public static final int STYLE_MSF = StreamSupport.NUMBER_MSF;
|
||||
public static final int STYLE_VLSF = StreamSupport.NUMBER_VLSF;
|
||||
public static final int STYLE_VMSF = StreamSupport.NUMBER_VMSF;
|
||||
public static final int STYLE_DEFAULT = STYLE_MSF;
|
||||
|
||||
protected static final String READ_EOF_MESSAGE = "There are not enough bytes in the stream to read the requested value.";
|
||||
private int defaultNumberStyle = STYLE_DEFAULT;
|
||||
/**
|
||||
* AbstractStandardInputStream constructor.
|
||||
*/
|
||||
protected AbstractStandardInputStream() {
|
||||
super();
|
||||
}//AbstractStandardInputStream()//
|
||||
/**
|
||||
* AbstractStandardInputStream constructor.
|
||||
* @param defaultNumberStyle One of the STYLE_xx identifiers. This defaults to most significant byte first.
|
||||
*/
|
||||
protected AbstractStandardInputStream(int defaultNumberStyle) {
|
||||
super();
|
||||
this.defaultNumberStyle = defaultNumberStyle;
|
||||
}//AbstractStandardInputStream()//
|
||||
/**
|
||||
* Gets the number style used by default when serializing numbers.
|
||||
* @return The number style identifier used by default.
|
||||
*/
|
||||
public int getDefaultNumberStyle() {
|
||||
return defaultNumberStyle;
|
||||
}//getDefaultNumberStyle()//
|
||||
/**
|
||||
* Gets the number of available bytes in this input stream.
|
||||
* @return The count of bytes that may be immediatly read from the stream.
|
||||
*/
|
||||
public abstract int available() throws IOException;
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IInputStream#canDecrypt()
|
||||
*/
|
||||
public boolean canDecrypt() {
|
||||
return false;
|
||||
}//canDecrypt()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.InputStream#close()
|
||||
*/
|
||||
public abstract void close() throws IOException;
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IInputStream#decrypt(boolean)
|
||||
*/
|
||||
public void decrypt(boolean decrypt) throws IOException {
|
||||
throw new IOException(ERROR_DECRYPTION_NOT_SUPPORTED);
|
||||
}//decrypt()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IInputStream#isDecrypting()
|
||||
*/
|
||||
public boolean isDecrypting() {
|
||||
return false;
|
||||
}//isDecrypting()//
|
||||
/**
|
||||
* Marks the stream so that the reader can reset to the current position.
|
||||
* @param readLimit The number of bytes that may be read before the mark becomes invalid.
|
||||
*/
|
||||
public abstract void mark(int readLimit);
|
||||
/**
|
||||
* Determines whether the stream supports using the mark method.
|
||||
* @return Whether the mark method is supported.
|
||||
*/
|
||||
public abstract boolean markSupported();
|
||||
/**
|
||||
* Reads an unsigned byte from the stream.
|
||||
* @return The unsigned byte read from the stream.
|
||||
*/
|
||||
public abstract int read() throws IOException;
|
||||
/**
|
||||
* Reads bytes from the stream until the buffer is full or there are no more bytes in the stream.
|
||||
* @param buffer The buffer where the read bytes will be placed.
|
||||
* @return The number of bytes read into the buffer.
|
||||
*/
|
||||
public abstract int read(byte[] buffer) throws IOException;
|
||||
/**
|
||||
* Reads bytes from the stream until the buffer is full or there are no more bytes in the stream.
|
||||
* @param buffer The buffer where the read bytes will be placed.
|
||||
* @param offset The offset where the first read byte should be placed in the buffer.
|
||||
* @param length The number of bytes that should be read into the buffer.
|
||||
* @return The number of bytes read into the buffer.
|
||||
*/
|
||||
public abstract int read(byte[] buffer, int offset, int length) throws IOException;
|
||||
/**
|
||||
* @see IInputStream.read(java.io.OutputStream, int)
|
||||
*/
|
||||
public abstract int read(java.io.OutputStream out, int length) throws IOException;
|
||||
/**
|
||||
* Reads a boolean from the stream.
|
||||
* @return The value read from the stream.
|
||||
*/
|
||||
public boolean readBoolean() throws IOException {
|
||||
int value = read();
|
||||
|
||||
if(value == -1) {
|
||||
throw new EOFException(READ_EOF_MESSAGE);
|
||||
}//if//
|
||||
|
||||
return value > 0;
|
||||
}//readBoolean()//
|
||||
/**
|
||||
* Reads a byte from the stream.
|
||||
* @return The value read from the stream.
|
||||
*/
|
||||
public byte readByte() throws IOException {
|
||||
return (byte) read();
|
||||
}//readByte()//
|
||||
/**
|
||||
* Reads a (2 byte) character from the stream.
|
||||
* @return The value read from the stream.
|
||||
*/
|
||||
public char readChar() throws IOException {
|
||||
return StreamSupport.readCharacter(this);
|
||||
}//readChar()//
|
||||
/**
|
||||
* Reads a (8 byte) double from the stream.
|
||||
* @return The value read from the stream.
|
||||
*/
|
||||
public double readDouble() throws IOException {
|
||||
return StreamSupport.readDouble(this);
|
||||
}//readDouble()//
|
||||
/**
|
||||
* Reads a fixed length string from file removes the unnecessary padding.
|
||||
* @param length The fixed number of bytes in the string.
|
||||
* @return The read string minus all space at the beginning or end of the string.
|
||||
* @exception IOException If an I/O error occurs. In particular, an <code>IOException</code> may be thrown if the input stream has been closed.
|
||||
*/
|
||||
public String readFixedLengthString(int length) throws java.io.IOException {
|
||||
byte[] bytes = new byte[length];
|
||||
|
||||
if(read(bytes) != length) {
|
||||
throw new IOException("Unable to finish reading the fixed length string.");
|
||||
}//if//
|
||||
|
||||
while((length > 0) && (bytes[length - 1] == 32)) {
|
||||
length--;
|
||||
}//while//
|
||||
|
||||
return new String(bytes, 0, length, STRING_FORMAT_UTF8);
|
||||
}//writeFixedLengthString()//
|
||||
/**
|
||||
* Reads a (4 byte) float from the stream.
|
||||
* @return The value read from the stream.
|
||||
*/
|
||||
public float readFloat() throws IOException {
|
||||
return StreamSupport.readFloat(this);
|
||||
}//readFloat()//
|
||||
/**
|
||||
* Don't know why this method exists?
|
||||
* @param bytes
|
||||
*/
|
||||
public void readFully(byte[] bytes) throws IOException {
|
||||
read(bytes);
|
||||
}//readFully()//
|
||||
/**
|
||||
* Don't know why this method exists?
|
||||
* @param bytes
|
||||
* @param offset
|
||||
* @param length
|
||||
*/
|
||||
public void readFully(byte[] bytes, int offset, int length) throws IOException {
|
||||
read(bytes, offset, length);
|
||||
}//readFully()//
|
||||
/**
|
||||
* Reads a (4 byte) int from the stream.
|
||||
* @return The value read from the stream.
|
||||
*/
|
||||
public int readInt() throws IOException {
|
||||
return StreamSupport.readInt(this, defaultNumberStyle);
|
||||
}//readInt()//
|
||||
/**
|
||||
* Reads a (4 byte) int from the stream.
|
||||
* @return The value read from the stream.
|
||||
*/
|
||||
public int readInt(int style) throws IOException {
|
||||
return StreamSupport.readInt(this, style);
|
||||
}//readInt()//
|
||||
/**
|
||||
* Reads a (8 byte) long from the stream.
|
||||
* @return The value read from the stream.
|
||||
*/
|
||||
public long readLong() throws IOException {
|
||||
return StreamSupport.readLong(this, defaultNumberStyle);
|
||||
}//readLong()//
|
||||
/**
|
||||
* Reads a (8 byte) long from the stream.
|
||||
* @return The value read from the stream.
|
||||
*/
|
||||
public long readLong(int style) throws IOException {
|
||||
return StreamSupport.readLong(this, style);
|
||||
}//readLong()//
|
||||
/**
|
||||
* Reads a string value from this stream.
|
||||
* <p>WARNING: This method is for backward compatibility only! It will not read a single line of a string, but will rather read the entire string prefixed by the string length.
|
||||
* @return The string value read.
|
||||
*/
|
||||
public String readLine() throws IOException {
|
||||
return readUTF();
|
||||
}//readLine()//
|
||||
/**
|
||||
* Reads a (2 byte) short from the stream.
|
||||
* @return The value read from the stream.
|
||||
*/
|
||||
public short readShort() throws IOException {
|
||||
return StreamSupport.readShort(this);
|
||||
}//readShort()//
|
||||
public int readUnsignedByte() throws IOException {
|
||||
int retVal = read();
|
||||
|
||||
return (int) (retVal < 0 ? retVal + 256 : retVal);
|
||||
}//readUnsignedByte()//
|
||||
public int readUnsignedShort() throws IOException {
|
||||
short retVal = readShort();
|
||||
|
||||
return (int) (retVal < 0 ? retVal + 65536 : retVal);
|
||||
}//readUnsignedShort()//
|
||||
/**
|
||||
* Reads a UTF8 string from the stream.
|
||||
* @see #readUTF8()
|
||||
* @return The string read from the stream.
|
||||
*/
|
||||
public String readUTF() throws IOException {
|
||||
return readUTF8();
|
||||
}//readUTF()//
|
||||
/**
|
||||
* Reads a UTF16 string from the stream.
|
||||
* A UTF16 string is a fixed character size string using 2 bytes for each character.
|
||||
* <p>WARNING: The user must call writeUTF16(String) in the output stream for this method to work properly. The user cannot mix and match string serialization methods.
|
||||
* @return The string read from the stream.
|
||||
*/
|
||||
public String readUTF16() throws IOException {
|
||||
int size = readInt();
|
||||
String result = null;
|
||||
|
||||
if(size != -1) {
|
||||
byte[] bytes = new byte[size];
|
||||
|
||||
read(bytes);
|
||||
result = new String(bytes, STRING_FORMAT_UNICODE);
|
||||
}//if//
|
||||
|
||||
return result;
|
||||
}//readUTF()//
|
||||
/**
|
||||
* Reads a UTF8 string from the stream.
|
||||
* A UTF8 string is a variable character size string using 1..N bytes for each character. All ASCII characters will use 1 byte, but most european characters will use 2 and some oriental characters will use 3 bytes.
|
||||
* <p>WARNING: The user must call writeUTF8(String) in the output stream for this method to work properly. The user cannot mix and match string serialization methods.
|
||||
* @return The string read from the stream.
|
||||
*/
|
||||
public String readUTF8() throws IOException {
|
||||
int size = readInt();
|
||||
String result = null;
|
||||
|
||||
if(size != -1) {
|
||||
byte[] bytes = null;
|
||||
|
||||
//TODO: Remove this - seems like old code - it flagged my big-data test that used a string with 100k characters in it.
|
||||
//if(size > 16767) {
|
||||
// throw new IOException("Corruption detected while reading a UTF8 string from a stream. Please check to make sure that you are reading in the same order you wrote to the stream.");
|
||||
//}//if//
|
||||
|
||||
bytes = new byte[size];
|
||||
read(bytes);
|
||||
result = new String(bytes, STRING_FORMAT_UTF8);
|
||||
}//if//
|
||||
|
||||
return result;
|
||||
}//readUTF8()//
|
||||
/**
|
||||
* Resets the stream by telling the encapsulated stream to reset.
|
||||
*/
|
||||
public abstract void reset() throws IOException;
|
||||
/**
|
||||
* Skips the next <code>count</code> bytes on the stream.
|
||||
* @param count The number of bytes to skip.
|
||||
* @return The number of bytes that were skipped.
|
||||
*/
|
||||
public abstract long skip(long count) throws IOException;
|
||||
/**
|
||||
* Skips the specified number of bytes so that they are never read.
|
||||
* @param byteCount The number of bytes to skip.
|
||||
* @return The number of bytes skipped.
|
||||
*/
|
||||
public int skipBytes(int byteCount) throws IOException {
|
||||
return (int) skip((long) byteCount);
|
||||
}//skipBytes()//
|
||||
/**
|
||||
* Skips the specified number of bytes so that they are never read.
|
||||
* @param byteCount The number of bytes to skip.
|
||||
* @return The number of bytes skipped.
|
||||
*/
|
||||
public long skipBytes(long byteCount) throws IOException {
|
||||
return skip(byteCount);
|
||||
}//skipBytes()//
|
||||
}//AbstractStandardInputStream//
|
||||
275
Common/src/com/common/io/AbstractStandardOutputStream.java
Normal file
275
Common/src/com/common/io/AbstractStandardOutputStream.java
Normal file
@@ -0,0 +1,275 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2007 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Provides basic functionality for a standard stream that can serialize basic java data types.
|
||||
*/
|
||||
public abstract class AbstractStandardOutputStream extends OutputStream implements IStandardOutputStream {
|
||||
public static final int STYLE_LSF = StreamSupport.NUMBER_LSF;
|
||||
public static final int STYLE_MSF = StreamSupport.NUMBER_MSF;
|
||||
public static final int STYLE_VLSF = StreamSupport.NUMBER_VLSF;
|
||||
public static final int STYLE_VMSF = StreamSupport.NUMBER_VMSF;
|
||||
public static final int STYLE_DEFAULT = STYLE_MSF;
|
||||
|
||||
private boolean containsEncryptedSegments = false;
|
||||
private int defaultNumberStyle = STYLE_DEFAULT;
|
||||
/**
|
||||
* AbstractStandardOutputStream constructor.
|
||||
*/
|
||||
protected AbstractStandardOutputStream() {
|
||||
super();
|
||||
}//AbstractStandardOutputStream()//
|
||||
/**
|
||||
* AbstractStandardOutputStream constructor.
|
||||
* @param defaultNumberStyle One of the STYLE_xx identifiers. This defaults to most significant byte first.
|
||||
*/
|
||||
protected AbstractStandardOutputStream(int defaultNumberStyle) {
|
||||
super();
|
||||
this.defaultNumberStyle = defaultNumberStyle;
|
||||
}//AbstractStandardOutputStream()//
|
||||
/**
|
||||
* Gets the number style used by default when serializing numbers.
|
||||
* @return The number style identifier used by default.
|
||||
*/
|
||||
public int getDefaultNumberStyle() {
|
||||
return defaultNumberStyle;
|
||||
}//getDefaultNumberStyle()//
|
||||
/**
|
||||
* @see IObjectOutputStream.canEncrypt()
|
||||
*/
|
||||
public boolean canEncrypt() {
|
||||
return false;
|
||||
}//canEncrypt()//
|
||||
/**
|
||||
* Closes this output stream and the encapsulated output stream.
|
||||
*/
|
||||
public abstract void close() throws IOException;
|
||||
/**
|
||||
* Determines whether encryption was used for some or all of the stream.
|
||||
* @return Whether the stream utilized encryption.
|
||||
*/
|
||||
public boolean containsEncryptedSegments() {
|
||||
return containsEncryptedSegments;
|
||||
}//containsEncryptedSegments()//
|
||||
/**
|
||||
* Determines whether encryption was used for some or all of the stream.
|
||||
* @param containsEncryptedSegments Whether the stream utilized encryption.
|
||||
*/
|
||||
protected void containsEncryptedSegments(boolean containsEncryptedSegments) {
|
||||
this.containsEncryptedSegments = containsEncryptedSegments;
|
||||
}//containsEncryptedSegments()//
|
||||
/**
|
||||
* @see IObjectOutputStream.encrypt(boolean)
|
||||
*/
|
||||
public void encrypt(boolean encrypt) throws IOException {
|
||||
throw new IOException(ERROR_ENCRYPTION_NOT_SUPPORTED);
|
||||
}//encrypt()//
|
||||
/**
|
||||
* Flushes this output stream and the encapsulated output stream.
|
||||
*/
|
||||
public abstract void flush() throws IOException;
|
||||
/**
|
||||
* @see IObjectOutputStream.isEncrypting()
|
||||
*/
|
||||
public boolean isEncrypting() {
|
||||
return false;
|
||||
}//isEncrypting()//
|
||||
/**
|
||||
* Writes the bytes to the stream.
|
||||
* @param bytes The bytes to write to the stream.
|
||||
*/
|
||||
public abstract void write(byte[] bytes) throws IOException;
|
||||
/**
|
||||
* Writes the bytes to the stream.
|
||||
* @param bytes The bytes to write to the stream.
|
||||
* @param offset The offset of the first byte to write.
|
||||
* @param length the number of bytes to write.
|
||||
*/
|
||||
public abstract void write(byte[] bytes, int offset, int length) throws IOException;
|
||||
/**
|
||||
* Writes the unsigned byte to the stream.
|
||||
* @param b The unsigned byte to write to the stream.
|
||||
*/
|
||||
public abstract void write(int b) throws IOException;
|
||||
/**
|
||||
* Writes a boolean to the stream.
|
||||
* @param value The value to write to the stream.
|
||||
*/
|
||||
public void writeBoolean(boolean value) throws IOException {
|
||||
write(value ? 1 : 0);
|
||||
}//writeBoolean()//
|
||||
/**
|
||||
* Writes a byte to the stream.
|
||||
* @param value The value to write to the stream.
|
||||
*/
|
||||
public void writeByte(byte value) throws IOException {
|
||||
write(value);
|
||||
}//writeByte()//
|
||||
/**
|
||||
* Writes an unsigned byte to the stream.
|
||||
* @param value The unsigned value to write to the stream.
|
||||
*/
|
||||
public void writeByte(int value) throws IOException {
|
||||
write(value);
|
||||
}//writeByte()//
|
||||
/**
|
||||
* Writes a string in the default UTF8 (multi-byte Unicode) format.
|
||||
* @param string The string to stream.
|
||||
* @deprecated Use writeUTF16(String).
|
||||
*/
|
||||
public void writeBytes(String string) throws IOException {
|
||||
writeUTF16(string);
|
||||
}//writeBytes()//
|
||||
/**
|
||||
* Writes a character to the stream.
|
||||
* @param value The value to write to the stream.
|
||||
*/
|
||||
public void writeChar(char value) throws IOException {
|
||||
StreamSupport.writeCharacter(value, this);
|
||||
}//writeChar()//
|
||||
/**
|
||||
* Writes a character to the stream.
|
||||
* @param value The value to write to the stream.
|
||||
*/
|
||||
public void writeChar(int value) throws IOException {
|
||||
StreamSupport.writeCharacter((char) value, this);
|
||||
}//writeChar()//
|
||||
/**
|
||||
* Writes a string in the default UTF8 (multi-byte Unicode) format.
|
||||
* @param string The string to stream.
|
||||
* @deprecated Use writeUTF8(String).
|
||||
*/
|
||||
public void writeChars(String string) throws IOException {
|
||||
writeUTF8(string);
|
||||
}//writeChars()//
|
||||
/**
|
||||
* Writes a double to the stream.
|
||||
* @param value The value to write to the stream.
|
||||
*/
|
||||
public void writeDouble(double value) throws IOException {
|
||||
StreamSupport.writeDouble(value, this);
|
||||
}//writeDouble()//
|
||||
/**
|
||||
* Writes a fixed length string to file and pads it with spaces where necessary.
|
||||
* @param string The string to write. This string must be under the byte size limit and an IOException will result from an improperly sized string.
|
||||
* @param length The fixed number of bytes in the string.
|
||||
* @exception IOException If an I/O error occurs. In particular, an <code>IOException</code> may be thrown if the output stream has been closed.
|
||||
*/
|
||||
public void writeFixedLengthString(String string, int length) throws java.io.IOException {
|
||||
byte[] bytes = string.getBytes(STRING_FORMAT_UTF8);
|
||||
int underflow;
|
||||
|
||||
if(bytes.length > length) {
|
||||
throw new IOException("Fixed string length exceeds expected length.");
|
||||
}//if//
|
||||
|
||||
write(bytes);
|
||||
underflow = length - bytes.length;
|
||||
|
||||
while(underflow-- > 0) {
|
||||
write(32);
|
||||
}//while//
|
||||
}//writeFixedLengthString()//
|
||||
/**
|
||||
* Writes a float to the stream.
|
||||
* @param value The value to write to the stream.
|
||||
*/
|
||||
public void writeFloat(float value) throws IOException {
|
||||
StreamSupport.writeFloat(value, this);
|
||||
}//writeFloat()//
|
||||
/**
|
||||
* Writes a int to the stream.
|
||||
* @param value The value to write to the stream.
|
||||
*/
|
||||
public void writeInt(int value) throws IOException {
|
||||
StreamSupport.writeInt(value, this, defaultNumberStyle);
|
||||
}//writeInt()//
|
||||
/**
|
||||
* Writes a int to the stream.
|
||||
* @param value The value to write to the stream.
|
||||
* @param style One of the style identifiers defined by this output stream.
|
||||
*/
|
||||
public void writeInt(int value, int style) throws IOException {
|
||||
StreamSupport.writeInt(value, this, style);
|
||||
}//writeInt()//
|
||||
/**
|
||||
* Writes a long to the stream.
|
||||
* @param value The value to write to the stream.
|
||||
*/
|
||||
public void writeLong(long value) throws IOException {
|
||||
StreamSupport.writeLong(value, this, defaultNumberStyle);
|
||||
}//writeLong()//
|
||||
/**
|
||||
* Writes a long to the stream.
|
||||
* @param value The value to write to the stream.
|
||||
* @param style One of the style identifiers defined by this output stream.
|
||||
*/
|
||||
public void writeLong(long value, int style) throws IOException {
|
||||
StreamSupport.writeLong(value, this, style);
|
||||
}//writeLong()//
|
||||
/**
|
||||
* Writes an unsigned short to the stream.
|
||||
* @param value The unsigned value to write to the stream.
|
||||
*/
|
||||
public void writeShort(int value) throws IOException {
|
||||
StreamSupport.writeShort((short) (value & 0xFFFF), this);
|
||||
}//writeShort()//
|
||||
/**
|
||||
* Writes a short to the stream.
|
||||
* @param value The value to write to the stream.
|
||||
*/
|
||||
public void writeShort(short value) throws IOException {
|
||||
StreamSupport.writeShort(value, this);
|
||||
}//writeShort()//
|
||||
/**
|
||||
* Writes a UTF8 string to the stream.
|
||||
* @see #writeUTF8()
|
||||
* @param string The string to write to the stream.
|
||||
*/
|
||||
public void writeUTF(String string) throws IOException {
|
||||
writeUTF8(string);
|
||||
}//writeUTF()//
|
||||
/**
|
||||
* Writes a UTF16 string to the stream.
|
||||
* A UTF16 string is a fixed character size string using 2 bytes for each character.
|
||||
* <p>WARNING: The user must call readUTF16(String) in the input stream for this method to work properly. The user cannot mix and match string serialization methods.
|
||||
* @param string The string to write to the stream.
|
||||
*/
|
||||
public void writeUTF16(String string) throws IOException {
|
||||
if(string != null) {
|
||||
byte[] bytes = string.getBytes(STRING_FORMAT_UNICODE);
|
||||
|
||||
writeInt(bytes.length);
|
||||
write(bytes);
|
||||
}//if//
|
||||
else {
|
||||
writeInt(-1);
|
||||
}//else//
|
||||
}//writeUTF16()//
|
||||
/**
|
||||
* Writes a UTF8 string to the stream.
|
||||
* A UTF8 string is a variable character size string using 1..N bytes for each character. All ASCII characters will use 1 byte, but most european characters will use 2 and some oriental characters will use 3 bytes.
|
||||
* <p>WARNING: The user must call readUTF8(String) in the input stream for this method to work properly. The user cannot mix and match string serialization methods.
|
||||
* @param string The string to write to the stream.
|
||||
*/
|
||||
public void writeUTF8(String string) throws IOException {
|
||||
if(string != null) {
|
||||
byte[] bytes = string.getBytes(STRING_FORMAT_UTF8);
|
||||
|
||||
writeInt(bytes.length);
|
||||
write(bytes);
|
||||
}//if//
|
||||
else {
|
||||
writeInt(-1);
|
||||
}//else//
|
||||
}//writeUTF8()//
|
||||
}//StandardOutputStream//
|
||||
34
Common/src/com/common/io/AsymmetricInputStream.java
Normal file
34
Common/src/com/common/io/AsymmetricInputStream.java
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.InputStream;
|
||||
import com.common.security.*;
|
||||
|
||||
/*
|
||||
* This class allows an asymmetricly encrypted stream to be plugged into an input stream so that read bytes are decrypted using the private key.
|
||||
*/
|
||||
public class AsymmetricInputStream extends CryptoInputStream implements IInputStream {
|
||||
private IAsymmetricAlgorithm algorithm = null;
|
||||
/**
|
||||
* AsymmetricInputStream constructor.
|
||||
*/
|
||||
public AsymmetricInputStream(InputStream stream, IAsymmetricAlgorithm algorithm) {
|
||||
super(stream, algorithm);
|
||||
|
||||
this.algorithm = algorithm;
|
||||
this.encryptedBuffer = new byte[algorithm.getOptimalDecryptionBlockSize()];
|
||||
this.decryptedBuffer = new byte[algorithm.getOptimalEncryptionBlockSize()];
|
||||
}//AsymmetricInputStream()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.CryptoOutputStream#decrypt(byte[], int, int, byte[], int)
|
||||
*/
|
||||
protected int decrypt(byte[] data, int dataOffset, int dataLength, byte[] output, int outputOffset) {
|
||||
return algorithm.decrypt(data, dataOffset, dataLength, output, outputOffset);
|
||||
}//decrypt()//
|
||||
}//AsymmetricInputStream//
|
||||
34
Common/src/com/common/io/AsymmetricOutputStream.java
Normal file
34
Common/src/com/common/io/AsymmetricOutputStream.java
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import com.common.security.*;
|
||||
|
||||
/*
|
||||
* This class allows an asymmetric stream to be plugged into an output stream so that written bytes are encrypted using the public key.
|
||||
*/
|
||||
public class AsymmetricOutputStream extends CryptoOutputStream implements IOutputStream {
|
||||
private IAsymmetricAlgorithm algorithm = null;
|
||||
/**
|
||||
* AsymmetricOutputStream constructor.
|
||||
*/
|
||||
public AsymmetricOutputStream(OutputStream stream, IAsymmetricAlgorithm algorithm) {
|
||||
super(stream, algorithm);
|
||||
|
||||
this.algorithm = algorithm;
|
||||
this.encryptedBuffer = new byte[algorithm.getOptimalDecryptionBlockSize()];
|
||||
this.decryptedBuffer = new byte[algorithm.getOptimalEncryptionBlockSize()];
|
||||
}//AsymmetricOutputStream()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.CryptoOutputStream#encrypt(byte[], int, int, byte[], int)
|
||||
*/
|
||||
protected int encrypt(byte[] data, int dataOffset, int dataLength, byte[] output, int outputOffset) {
|
||||
return algorithm.encrypt(data, dataOffset, dataLength, output, outputOffset);
|
||||
}//encrypt()//
|
||||
}//AsymmetricOutputStream//
|
||||
272
Common/src/com/common/io/BufferedInputStream.java
Normal file
272
Common/src/com/common/io/BufferedInputStream.java
Normal file
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* The buffered input stream is used for two reasons. The first reason is to allow the user to peek
|
||||
* at future values in the stream. The second reason is to all more efficient read operations when
|
||||
* dealing with streams where reading one byte at a time is inefficient.
|
||||
* <p>TODO: Should add a close method which will close the underlying stream.</p>
|
||||
*/
|
||||
public class BufferedInputStream extends InputStream {
|
||||
public static final int DEFAULT_BLOCK_BUFFER_SIZE = 10;
|
||||
|
||||
private InputStream inputStream = null; //The input stream that source will be read from.//
|
||||
private byte[] buffer = null; //The buffer that will hold unread values.//
|
||||
private int bufferedSize = 0; //The number of bytes currently in the buffer.//
|
||||
private int firstByteOffset = 0; //The offset of the first byte in the buffer. This is necessary because we are using a rotating scheme where the first byte in the buffer is not always at index zero and the last byte may be at a smaller index than the first byte.//
|
||||
/**
|
||||
* BufferedInputStream constructor.
|
||||
* @param inputStream The stream containing the source data.
|
||||
*/
|
||||
public BufferedInputStream(InputStream inputStream) {
|
||||
this(inputStream, DEFAULT_BLOCK_BUFFER_SIZE);
|
||||
}//BufferedInputStream()//
|
||||
/**
|
||||
* BufferedInputStream constructor.
|
||||
* @param inputStream The stream containing the source data.
|
||||
* @param bufferSize The number of bytes to buffer at one time. This value must be greater than zero and it will determine how far the user can peek in the stream.
|
||||
*/
|
||||
public BufferedInputStream(InputStream inputStream, int bufferSize) {
|
||||
super();
|
||||
|
||||
if(bufferSize < 1) {
|
||||
throw new RuntimeException("The BufferedInputStream requires a buffer size > 0.");
|
||||
}//if//
|
||||
|
||||
this.inputStream = inputStream;
|
||||
this.buffer = new byte[bufferSize];
|
||||
}//BufferedInputStream()//
|
||||
/**
|
||||
* Determines how many more bytes of source data are available to be read.
|
||||
* @return The number of source bytes that are readable.
|
||||
*/
|
||||
public int available() throws IOException {
|
||||
return inputStream.available();
|
||||
}//available()//
|
||||
/**
|
||||
* Fills the buffer with source bytes until either the buffer is full or there are no more source bytes.
|
||||
*/
|
||||
protected void fillBuffer() throws IOException {
|
||||
if(bufferedSize == 0) {
|
||||
firstByteOffset = 0;
|
||||
bufferedSize = inputStream.read(buffer);
|
||||
}//if//
|
||||
else {
|
||||
int offset = firstByteOffset + bufferedSize;
|
||||
int length;
|
||||
|
||||
if(offset < buffer.length) {
|
||||
bufferedSize += inputStream.read(buffer, offset, buffer.length - offset);
|
||||
}//if//
|
||||
|
||||
//Calculate the number of bytes remaining to be read (so that the buffer is full).//
|
||||
length = buffer.length - bufferedSize;
|
||||
|
||||
if(length > 0) {
|
||||
bufferedSize += inputStream.read(buffer, 0, length);
|
||||
}//if//
|
||||
}//else//
|
||||
}//fillBuffer()//
|
||||
/**
|
||||
* Gets the encapsulated input stream.
|
||||
* @return Gets the input stream that this object wrappers.
|
||||
*/
|
||||
public InputStream getInputStream() {
|
||||
return inputStream;
|
||||
}//getInputStream()//
|
||||
/**
|
||||
* Peeks at a single unsigned byte value in the stream of future values.
|
||||
* This method does NOT consume the value and the value will eventually be returned durring a read operation.
|
||||
* @param offset The offset in the stream for the byte that should be returned. A value of zero will return the byte that will next be returned by the read() operation. This value must be greater than or equal to zero and less than the buffer size used when creating this stream.
|
||||
* @return The byte at the given offset from the current position in the stream.
|
||||
*/
|
||||
public int peek(int offset) throws IOException {
|
||||
int retVal;
|
||||
|
||||
if((offset > buffer.length) || (offset < 0)) {
|
||||
throw new RuntimeException("Unable to peek at a byte that cannot be buffered. Please make sure you specify a large enough buffer size when constructing the BufferedInputStream object. You also may not peek at bytes already read from the stream.");
|
||||
}//if//
|
||||
else {
|
||||
int bufferOffset = offset + firstByteOffset;
|
||||
|
||||
if(bufferedSize < offset + 1) {
|
||||
fillBuffer();
|
||||
|
||||
if(bufferedSize < offset + 1) {
|
||||
throw new RuntimeException("Unable to peek at a byte that does not exist in the stream. Please make sure you verify there are enough bytes in the stream by calling inputStream.available().");
|
||||
}//if//
|
||||
}//if//
|
||||
|
||||
if(bufferOffset > buffer.length) {
|
||||
bufferOffset -= buffer.length;
|
||||
}//if//
|
||||
|
||||
retVal = buffer[bufferOffset];
|
||||
}//else//
|
||||
|
||||
return retVal;
|
||||
}//peek()//
|
||||
/**
|
||||
* Peeks at a group of bytes in the stream's future.
|
||||
* This method does NOT consume the values and the values will eventually be returned durring a read operation.
|
||||
* @param streamOffset The offset in the stream for the first byte that should be returned. A value of zero will return the byte that will next be returned by the read() operation. This value must be greater than or equal to zero and less than the buffer size (used when creating this stream) minus the requested length.
|
||||
* @param outputBuffer The buffer that should be filled with the output bytes.
|
||||
* @param offset The offset in the output buffer where the first output byte will be placed.
|
||||
* @param length The number of output bytes requested for this operation. All requested bytes will be supplied or an exception will be raised because the stream either does not have enough bytes to fulfill the request, or because the buffer being used is smaller than the length + stream offset.
|
||||
* @return The byte at the given offset from the current position in the stream.
|
||||
*/
|
||||
public void peek(int streamOffset, byte[] outputBuffer, int offset, int length) throws IOException {
|
||||
if((streamOffset + length > buffer.length) || (streamOffset < 0)) {
|
||||
throw new RuntimeException("Unable to peek at a byte that cannot be buffered. Please make sure you specify a large enough buffer size when constructing the BufferedInputStream object. You also may not peek at bytes already read from the stream.");
|
||||
}//if//
|
||||
else {
|
||||
int bufferOffset = streamOffset + firstByteOffset;
|
||||
|
||||
if(bufferedSize < streamOffset + length) {
|
||||
fillBuffer();
|
||||
|
||||
if(bufferedSize < offset + length) {
|
||||
throw new RuntimeException("Unable to peek at a byte that does not exist in the stream. Please make sure you verify there are enough bytes in the stream by calling inputStream.available().");
|
||||
}//if//
|
||||
}//if//
|
||||
|
||||
while(length < 0) {
|
||||
//Adjust the starting point within the buffer.//
|
||||
if(bufferOffset > buffer.length) {
|
||||
bufferOffset -= buffer.length;
|
||||
}//if//
|
||||
|
||||
outputBuffer[offset++] = buffer[bufferOffset++];
|
||||
}//while//
|
||||
}//else//
|
||||
}//peek()//
|
||||
/**
|
||||
* Reads a single unsigned byte value from the stream.
|
||||
* @return The next unsigned byte value in the stream.
|
||||
*/
|
||||
public int read() throws IOException {
|
||||
int retVal;
|
||||
|
||||
if(bufferedSize == 0) {
|
||||
fillBuffer();
|
||||
|
||||
if(bufferedSize > 0) {
|
||||
retVal = buffer[firstByteOffset++];
|
||||
bufferedSize--;
|
||||
|
||||
if(firstByteOffset == buffer.length) {
|
||||
firstByteOffset = 0;
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
throw new IOException("No more source data.");
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
retVal = buffer[firstByteOffset++];
|
||||
bufferedSize--;
|
||||
|
||||
if(firstByteOffset == buffer.length) {
|
||||
firstByteOffset = 0;
|
||||
}//if//
|
||||
}//else//
|
||||
|
||||
return retVal;
|
||||
}//read()//
|
||||
/**
|
||||
* Reads a bytes off the source stream and places them in the bytes buffer.
|
||||
* @param bytes The buffer that will contain the source bytes read from the stream.
|
||||
* @return The number of bytes read.
|
||||
*/
|
||||
public int read(byte[] bytes) throws IOException {
|
||||
return read(bytes, 0, bytes.length);
|
||||
}//read()//
|
||||
/**
|
||||
* Reads a bytes off the source stream and places them in the bytes buffer.
|
||||
* @param bytes The buffer that will contain the source bytes read from the stream.
|
||||
* @param offset The offset in the bytes buffer where the first source byte will be placed.
|
||||
* @param length The number of source bytes that will be placed in the bytes buffer. Note that <code>bytes.length - offset >= length</code> - this is not checked and non-compliance will result in a ArrayIndexOutOfBounds exception.
|
||||
* @return The number of bytes read.
|
||||
*/
|
||||
public int read(byte[] bytes, int offset, int length) throws IOException {
|
||||
int retVal = 0;
|
||||
|
||||
//If we have buffered bytes then first add them.//
|
||||
if(bufferedSize > 0) {
|
||||
int endLength = length > bufferedSize ? bufferedSize : length;
|
||||
int beginLength = 0;
|
||||
|
||||
//Save the number of bytes being copied.//
|
||||
retVal = endLength;
|
||||
|
||||
//Adjust the end length if it will over run the buffer size.//
|
||||
if(endLength + firstByteOffset > buffer.length) {
|
||||
beginLength = endLength - (buffer.length - firstByteOffset);
|
||||
endLength -= beginLength;
|
||||
}//if//
|
||||
|
||||
//Copy the bytes at the end of the buffer.//
|
||||
System.arraycopy(buffer, firstByteOffset, bytes, offset, endLength);
|
||||
|
||||
//Copy the bytes at the beginning of the buffer.//
|
||||
if(beginLength > 0) {
|
||||
System.arraycopy(buffer, 0, bytes, offset + endLength, beginLength);
|
||||
}//if//
|
||||
|
||||
//Adjust the buffer indexes.//
|
||||
bufferedSize = length > bufferedSize ? 0 : bufferedSize - length;
|
||||
firstByteOffset = bufferedSize == 0 ? 0 : firstByteOffset + length;
|
||||
|
||||
if(firstByteOffset >= buffer.length) {
|
||||
firstByteOffset = firstByteOffset - buffer.length;
|
||||
}//if//
|
||||
}//if//
|
||||
|
||||
//If we did not have enough buffered bytes to fill the array then we will need to send the array to the source stream.//
|
||||
if(retVal < length) {
|
||||
retVal += inputStream.read(bytes, offset + retVal, length - retVal);
|
||||
}//if//
|
||||
|
||||
return retVal;
|
||||
}//read()//
|
||||
/**
|
||||
* Skips <code>count</code> bytes in the stream.
|
||||
* @param count The number to skip.
|
||||
* @return The number of bytes skipped.
|
||||
*/
|
||||
public long skip(long count) throws IOException {
|
||||
int skipCount = 0;
|
||||
|
||||
//Skip the buffered values as necessary.//
|
||||
if(bufferedSize != 0) {
|
||||
//If the count is greater than the buffer size then clear the buffer, otherwise clear part of the buffer.//
|
||||
if(count > bufferedSize) {
|
||||
skipCount = bufferedSize;
|
||||
bufferedSize = 0;
|
||||
firstByteOffset = 0;
|
||||
}//if//
|
||||
else {
|
||||
skipCount = (int) count;
|
||||
bufferedSize -= count;
|
||||
firstByteOffset += count;
|
||||
|
||||
//Adjust the first byte offset so it is in the correct range.//
|
||||
if(firstByteOffset >= buffer.length) {
|
||||
firstByteOffset -= buffer.length;
|
||||
}//if//
|
||||
}//else//
|
||||
}//if//
|
||||
|
||||
//Skip any unbuffered values as necessary.//
|
||||
return skipCount < count ? inputStream.skip(count - skipCount) + skipCount : skipCount;
|
||||
}//skip()//
|
||||
}//BufferedInputStream//
|
||||
603
Common/src/com/common/io/BufferedOutputStream.java
Normal file
603
Common/src/com/common/io/BufferedOutputStream.java
Normal file
@@ -0,0 +1,603 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
import com.common.util.*;
|
||||
import com.common.debug.*;
|
||||
|
||||
/**
|
||||
* Implements a buffer around another output stream such that the user can insert values into the stream at a later time, and can track the byte location of a specific point in the stream so that it is updated when the stream is modified.
|
||||
* <p><b>WARNING: This class is not the least bit thread safe and is not designed to ever be thread safe.</b></p>
|
||||
* <p>TODO: It would be nice to be able to have a buffered output stream wrapper a byte array stream such that the buffered stream writes directly to the byte stream except when necessary (because of insert streams for example).</p>
|
||||
*/
|
||||
public class BufferedOutputStream extends OutputStream implements IOutputStreamLocation {
|
||||
public static final int DEFAULT_BUFFER_INCREMENT_SIZE = 1000;
|
||||
public static final int DEFAULT_INSERT_BUFFER_INCREMENT_SIZE = 100;
|
||||
public static final int DEFAULT_BUFFER_SIZE = 2000;
|
||||
public static final int DEFAULT_INSERT_BUFFER_SIZE = 200;
|
||||
|
||||
private int streamLocation = 0; //The location that the current stream is inserting into its parent output stream. If this stream is not inserting then it is the number of bytes already flushed to the encapuslated stream.//
|
||||
private boolean isFixedSize = false; //TODO: May determine by checking whether the buffer attribute is null.//
|
||||
private boolean isInsertStream = false; //Whether the stream is inserting into another buffer stream.//
|
||||
private int reservedByteCount = 0; //Only applies to fixed size insert streams. The number of bytes reserved in the encapsulated buffered output stream. This value goes down as bytes are written.//
|
||||
|
||||
private OutputStream outputStream = null; //The stream being buffered.//
|
||||
private int bufferIncrementSize = DEFAULT_BUFFER_INCREMENT_SIZE; //The number of bytes to increment the buffer by (when it is necessary).//
|
||||
private LiteList locations = new LiteList(10, 20); //The ordered collection of stream location objects.//
|
||||
private byte[] buffer = null; //The collection of bytes currently buffered.//
|
||||
private int bufferSize = 0; //The number of bytes currently buffered.// //TODO:Rename this to bufferIndex or bufferCount. BufferSize is very confusing.//
|
||||
/**
|
||||
* BufferedOutputStream constructor.
|
||||
* This constructor creates a simple location marker within a parent buffered output stream. The location will be updated as bytes are inserted earlier in the stream, and the updated location is accessable by the user.
|
||||
* @param streamLocation The location within the parent buffered output stream. This location will be updated by the parent stream as necessary.
|
||||
*/
|
||||
protected BufferedOutputStream(int streamLocation) {
|
||||
super();
|
||||
|
||||
this.streamLocation = streamLocation;
|
||||
this.isInsertStream = false;
|
||||
}//BufferedOutputStream()//
|
||||
/**
|
||||
* BufferedOutputStream constructor.
|
||||
* @param outputStream The destination for written data.
|
||||
* @param streamLocation The location of this output stream in the context of the parent buffered output stream. This location will be the index of the last reserved byte, or if there are no reserved bytes then it will be the location at which bytes will be inserted into the parent stream.
|
||||
* @param reservedByteCount The initial size of the buffer used for buffering the data when necessary, or if this is a fixed size stream then it will be the number of bytes reserved in the parent stream.
|
||||
*/
|
||||
protected BufferedOutputStream(BufferedOutputStream outputStream, int streamLocation, int reservedByteCount) {
|
||||
super();
|
||||
|
||||
this.outputStream = outputStream;
|
||||
this.streamLocation = streamLocation;
|
||||
this.buffer = null;
|
||||
this.reservedByteCount = reservedByteCount;
|
||||
this.isFixedSize = true;
|
||||
this.isInsertStream = true;
|
||||
}//BufferedOutputStream()//
|
||||
/**
|
||||
* BufferedOutputStream constructor.
|
||||
* @param outputStream The destination for written data.
|
||||
* @param streamLocation The location of this output stream in the context of the parent buffered output stream. This location will be the index of the last reserved byte, or if there are no reserved bytes then it will be the location at which bytes will be inserted into the parent stream.
|
||||
* @param byteCount The initial size of the buffer used for buffering the data when necessary, or if this is a fixed size stream then it will be the number of bytes reserved in the parent stream.
|
||||
* @param isFixedSize Whether the parent stream has reserved a fixed number of bytes allocated to this stream. If it is not fixed size then the user can write as many bytes as desired before closing the stream.
|
||||
*/
|
||||
protected BufferedOutputStream(BufferedOutputStream outputStream, int streamLocation, int bufferSize, int incrementSize) {
|
||||
super();
|
||||
|
||||
this.outputStream = outputStream;
|
||||
this.streamLocation = streamLocation;
|
||||
this.buffer = new byte[bufferSize <= 0 ? DEFAULT_BUFFER_SIZE : bufferSize];
|
||||
this.bufferIncrementSize = incrementSize <= 0 ? DEFAULT_BUFFER_INCREMENT_SIZE : incrementSize;
|
||||
this.isFixedSize = false;
|
||||
this.isInsertStream = true;
|
||||
}//BufferedOutputStream()//
|
||||
/**
|
||||
* BufferedOutputStream constructor.
|
||||
*/
|
||||
public BufferedOutputStream(OutputStream outputStream) {
|
||||
this(outputStream, DEFAULT_BUFFER_SIZE);
|
||||
}//BufferedOutputStream()//
|
||||
/**
|
||||
* BufferedOutputStream constructor.
|
||||
* @param outputStream The destination for written data.
|
||||
* @param bufferSize The initial size of the buffer used for buffering the data when necessary.
|
||||
*/
|
||||
public BufferedOutputStream(OutputStream outputStream, int bufferSize) {
|
||||
super();
|
||||
|
||||
this.outputStream = outputStream;
|
||||
this.buffer = new byte[bufferSize];
|
||||
this.streamLocation = 0;
|
||||
this.isFixedSize = false;
|
||||
this.isInsertStream = false;
|
||||
}//BufferedOutputStream()//
|
||||
/**
|
||||
* Closes the stream and flushes any remaining buffered data.
|
||||
* <p>If this stream is an insertion stream then it will not close the encapsulated (parent) stream because the close only means no more bytes will be inserted.
|
||||
* <p>If this stream is not an insertion stream then the encapsulated stream will be told to close. If for example, this is a buffered output stream encapsulating a FileOutputStream, then the file output stream will receive all buffered data, and then will be told to close.
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
flush();
|
||||
|
||||
if(bufferSize > 0) {
|
||||
throw new IOException("Unable to close the buffered output stream because there are open insertion buffer output streams in existance preventing the stream data from flushing to the encapsulated output stream. Please close all related insertion streams before closing this stream.");
|
||||
}//if//
|
||||
|
||||
if(isInsertStream) {
|
||||
if((isFixedSize) && (reservedByteCount != 0)) {
|
||||
throw new IOException("Unable to close the insertion stream because the reserved bytes have not all been filled. Either don't reserve bytes, or you must fill exactly that number of bytes.");
|
||||
}//if//
|
||||
|
||||
isInsertStream = false;
|
||||
}//if//
|
||||
else {
|
||||
//Close the encapsulated output stream.//
|
||||
//TODO: Modify to not set the isInsertStream = false when the stream can no longer insert. Then this can be turned back on.//
|
||||
//TODO: Why is this commented out? We need to notify the underlying stream that it should close.//
|
||||
// outputStream.close();
|
||||
}//else//
|
||||
}//close()//
|
||||
/**
|
||||
* Flushes all or some of the buffer to the stream.
|
||||
* <p>Note: The flush method may only flush bytes that occur earlier than the first insert stream's location because the insert opertion will add or modify bytes and those bytes must stay buffered to allow this.
|
||||
*/
|
||||
public void flush() throws IOException {
|
||||
if((!isFixedSize) && (buffer != null) && (bufferSize > 0)) {
|
||||
//Remove locations such that the first location in the collection is an insertable BufferedOutputStream object.//
|
||||
while((locations.getSize() > 0) && (!((BufferedOutputStream) locations.getFirst()).isInsertStream())) {
|
||||
locations.remove(0);
|
||||
}//while//
|
||||
|
||||
//Flush the buffer up to the first active BufferedOutputStream's location.//
|
||||
if(locations.getSize() == 0) {
|
||||
if(bufferSize > 0) {
|
||||
if(isInsertStream) {
|
||||
//Insert the bytes into the encapsulated buffered output stream.//
|
||||
((BufferedOutputStream) outputStream).insert(streamLocation, buffer, 0, bufferSize, false);
|
||||
}//if//
|
||||
else {
|
||||
//Append the bytes to the encapsulated output stream.//
|
||||
outputStream.write(buffer, 0, bufferSize);
|
||||
}//else//
|
||||
|
||||
//Update the overall stream location.//
|
||||
//streamLocation += bufferSize; //This is automatically done by the underlying buffered output stream.//
|
||||
//Update the buffer size.//
|
||||
bufferSize = 0;
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
BufferedOutputStream location = (BufferedOutputStream) locations.getFirst();
|
||||
int flushableByteCount = location.getByteIndex() - streamLocation;
|
||||
|
||||
//Adjust the number of flushable bytes if the first location has unused reserved bytes.//
|
||||
if(location.getReservedByteCount() > 0) {
|
||||
flushableByteCount -= location.getReservedByteCount();
|
||||
}//if//
|
||||
|
||||
//Flush those bytes that we can.//
|
||||
if(flushableByteCount > 0) {
|
||||
if(isInsertStream) {
|
||||
//Insert the bytes into the encapsulated buffered output stream.//
|
||||
((BufferedOutputStream) outputStream).insert(streamLocation, buffer, 0, flushableByteCount, false);
|
||||
}//if//
|
||||
else {
|
||||
//Append the bytes to the encapsulated output stream.//
|
||||
outputStream.write(buffer, 0, flushableByteCount);
|
||||
}//else//
|
||||
|
||||
//Update the overall stream location.//
|
||||
streamLocation += flushableByteCount;
|
||||
//Update the buffer size.//
|
||||
bufferSize -= flushableByteCount;
|
||||
//Shift remaining buffered bytes so that they begin at the first index in the buffer.//
|
||||
System.arraycopy(buffer, flushableByteCount, buffer, 0, bufferSize);
|
||||
}//if//
|
||||
}//else//
|
||||
}//if//
|
||||
}//flush()//
|
||||
/**
|
||||
* Gets the stream index of the location in the stream when this object was created.
|
||||
* This value will change if there is an update location object that the users writes data to (unless it has reserved space), or if this location is an update location and did not reserve space and writes data.
|
||||
* The location will be the last byte index in the set of values written to the stream, or the index of the stream at the time the location was created (updated if any new bytes were written to the stream at an earlier index).
|
||||
* @return The index within the stream of this location object (or the ending index if the location allows updating).
|
||||
*/
|
||||
public int getByteIndex() {
|
||||
return streamLocation + bufferSize;
|
||||
}//getByteIndex()//
|
||||
/**
|
||||
* Gets an output stream object that allows the user to write a fixed amount of data to the stream at some future time at the current location.
|
||||
* @param reservedByteCount The number of bytes to reserve in the stream. The user must write exactly this many bytes before the stream can be successfully flushed.
|
||||
* @return An IStreamUpdateLocation object that can provide the index within the stream and allows the user to write data to the stream at the current position at some future time.
|
||||
*/
|
||||
public BufferedOutputStream getInsertOutputStream(int reservedByteCount) throws IOException {
|
||||
BufferedOutputStream stream = null;
|
||||
|
||||
if(reservedByteCount > 0) {
|
||||
//Add the reserved bytes to the buffer.//
|
||||
if(bufferSize + reservedByteCount > buffer.length) {
|
||||
resizeBuffer(reservedByteCount);
|
||||
}//if//
|
||||
|
||||
bufferSize += reservedByteCount;
|
||||
}//if//
|
||||
|
||||
//Create an update location.//
|
||||
stream = new BufferedOutputStream(this, streamLocation + bufferSize, reservedByteCount);
|
||||
|
||||
locations.add(stream);
|
||||
|
||||
return stream;
|
||||
}//getInsertOutputStream()//
|
||||
/**
|
||||
* Gets an output stream object that allows the user to write data to the stream at some future time at the current location.
|
||||
* @param initialBufferSize The size of the initial buffer. This value should be large enough to provide efficient writes to the buffered stream, but small enough not to be wasteful.
|
||||
* @param incrementSize The number of bytes to increment the buffer by if it is necessary. The buffer will first try to flush to the buffered stream, and will only increase in size if necessary.
|
||||
* @return An IStreamUpdateLocation object that can provide the index within the stream and allows the user to write data to the stream at the current position at some future time.
|
||||
*/
|
||||
public BufferedOutputStream getInsertOutputStream(int initialBufferSize, int incrementSize) throws IOException {
|
||||
BufferedOutputStream stream = new BufferedOutputStream(this, streamLocation + bufferSize, initialBufferSize, incrementSize);
|
||||
|
||||
locations.add(stream);
|
||||
|
||||
return stream;
|
||||
}//getInsertOutputStream()//
|
||||
/**
|
||||
* Gets the encapsulated output stream.
|
||||
* @return Gets the output stream that this object wrappers.
|
||||
*/
|
||||
public OutputStream getOutputStream() {
|
||||
return outputStream;
|
||||
}//getOutputStream()//
|
||||
/**
|
||||
* Gets a location object associated with the current location in the stream.
|
||||
* This location object can be used to access the current stream position at the location.
|
||||
* This is useful for the user because the user could also get a dynamic update location which allows the stream to be dynamically modified at some future time.
|
||||
* A location after the dynamic update location would tell the user what the byte index is after the dynamic update location was completed (all bytes written).
|
||||
* @return An IStreamLocation object that can provide the index within the stream. It will be updated automatically if a dynamic update location is used to insert byte earlier in the stream.
|
||||
*/
|
||||
public IOutputStreamLocation getOutputStreamLocation() throws IOException {
|
||||
BufferedOutputStream location = new BufferedOutputStream(streamLocation + bufferSize);
|
||||
|
||||
if(locations.getSize() > 0) {
|
||||
locations.add(location);
|
||||
}//if//
|
||||
|
||||
return location;
|
||||
}//getOutputStreamLocation()//
|
||||
/**
|
||||
* Gets the number of bytes reserved in the encapsulated buffered output stream.
|
||||
* <p>Note: This value is only valid if this stream encapsulates a buffered output stream and is an insert buffer with a fixed number of insertable bytes.
|
||||
* <p>Note: If this value is non-zero then the parent stream may not flush bytes (beyond the reserved bytes in the stream) to its encapsulated output stream. Thus the user must use ALL reserved bytes, no more, no less.
|
||||
* @return The number of reserved bytes. This value goes down as bytes are written, until the value reaches zero. If this value is zero then no more bytes may be written.
|
||||
*/
|
||||
public int getReservedByteCount() {
|
||||
return reservedByteCount;
|
||||
}//getReservedByteCount()//
|
||||
/**
|
||||
* Inserts the specified byte values to the stream.
|
||||
* @param streamIndex The index of the first array byte within the stream (where index zero is the very first byte written to the stream).
|
||||
* @param bytes The array of values to write to the stream.
|
||||
* @param offset The offset of the first value to write to the stream.
|
||||
* @param length The number of values to write to the stream.
|
||||
* @param isReserved Whether the byte is being written to a reserved space. If this is true then an insert buffer will not be used because space in the buffer is already allocated.
|
||||
*/
|
||||
protected void insert(int streamIndex, byte[] bytes, int offset, int length, boolean isReserved) throws IOException {
|
||||
//If this value is going into a reserved space in the buffer then simply write to the buffer, otherwise we will add it to the insert buffer.//
|
||||
if(isReserved) {
|
||||
System.arraycopy(bytes, offset, buffer, streamIndex - streamLocation, length);
|
||||
}//if//
|
||||
else {
|
||||
int availableSpace = buffer.length - bufferSize;
|
||||
int remainingBytes = length;
|
||||
int bufferInsertLocation = streamIndex - streamLocation;
|
||||
|
||||
//Determine whether we can perform a simple write, or whether we need to perform a write & flush loop or resize the buffer.//
|
||||
if(availableSpace < remainingBytes) {
|
||||
//Keep writing and flushing as long as there is data and buffer space.//
|
||||
while((availableSpace > 0) && (remainingBytes > 0)) {
|
||||
int copyLength = availableSpace > remainingBytes ? remainingBytes : availableSpace;
|
||||
|
||||
//Shift the buffered bytes so that there is space for the inserted bytes.//
|
||||
if(bufferSize > bufferInsertLocation) {
|
||||
System.arraycopy(buffer, bufferInsertLocation, buffer, copyLength + bufferInsertLocation, bufferSize - bufferInsertLocation);
|
||||
}//if//
|
||||
|
||||
//Copy the data into the correct place in the buffer.//
|
||||
System.arraycopy(bytes, offset, buffer, bufferInsertLocation, copyLength);
|
||||
bufferSize += copyLength;
|
||||
remainingBytes -= copyLength;
|
||||
offset += copyLength;
|
||||
|
||||
if(remainingBytes > 0) {
|
||||
flush();
|
||||
//Recompute the location to insert the remaining bytes.//
|
||||
bufferInsertLocation = streamIndex - streamLocation + offset;
|
||||
//Recompute the amount of available space in the buffer.//
|
||||
availableSpace = buffer.length - bufferSize;
|
||||
|
||||
//Make sure we are not being grossly inefficient by ensuring that we at least flush some substantial number of bytes each round.//
|
||||
if(availableSpace < bufferIncrementSize) {
|
||||
resizeBuffer(bufferIncrementSize);
|
||||
availableSpace = buffer.length - bufferSize;
|
||||
}//if//
|
||||
}//if//
|
||||
}//while//
|
||||
|
||||
//If we must, then resize the buffer to accomidate the data.//
|
||||
if((availableSpace == 0) && (remainingBytes > 0)) {
|
||||
//Resize the buffer so it can contain the new data.//
|
||||
resizeBuffer(remainingBytes);
|
||||
|
||||
//Shift the buffered bytes so that there is space for the inserted bytes.//
|
||||
if(bufferSize > bufferInsertLocation) {
|
||||
System.arraycopy(buffer, bufferInsertLocation, buffer, remainingBytes + bufferInsertLocation, bufferSize - bufferInsertLocation);
|
||||
}//if//
|
||||
|
||||
//Copy the bytes into the buffer.//
|
||||
System.arraycopy(bytes, offset, buffer, bufferInsertLocation, remainingBytes);
|
||||
//Update the buffer size.//
|
||||
bufferSize += remainingBytes;
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
//Shift the buffered bytes so that there is space for the inserted bytes.//
|
||||
if(bufferSize > bufferInsertLocation) {
|
||||
System.arraycopy(buffer, bufferInsertLocation, buffer, bufferInsertLocation + length, bufferSize - bufferInsertLocation);
|
||||
}//if//
|
||||
|
||||
//Copy the bytes into the buffer.//
|
||||
System.arraycopy(bytes, offset, buffer, bufferInsertLocation, length);
|
||||
//Update the buffer size.//
|
||||
bufferSize += length;
|
||||
}//else//
|
||||
/* The code above replaces this code - it provides better buffer usage.
|
||||
int bufferInsertLocation = streamIndex - streamLocation;
|
||||
|
||||
//Resize the buffer if necessary.//
|
||||
if(length + bufferSize > buffer.length) {
|
||||
resizeBuffer(length);
|
||||
}//if//
|
||||
|
||||
//Shift the buffered bytes so that there is space for the inserted bytes.//
|
||||
if(bufferSize > bufferInsertLocation) {
|
||||
System.arraycopy(buffer, bufferInsertLocation, buffer, length + bufferInsertLocation, bufferSize - bufferInsertLocation);
|
||||
}//if//
|
||||
|
||||
//Copy the inserted bytes.//
|
||||
System.arraycopy(bytes, offset, buffer, bufferInsertLocation, length);
|
||||
*/
|
||||
|
||||
//Notify the location objects that their positions may have changed.//
|
||||
updateLocations(streamIndex, length);
|
||||
}//else//
|
||||
}//insert()//
|
||||
/**
|
||||
* Inserts the specified byte values to the stream.
|
||||
* @param streamIndex The index of the first array byte within the stream (where index zero is the very first byte written to the stream).
|
||||
* @param bytes The array of values to write to the stream.
|
||||
* @param isReserved Whether the byte is being written to a reserved space. If this is true then an insert buffer will not be used because space in the buffer is already allocated.
|
||||
*/
|
||||
protected void insert(int streamIndex, byte[] bytes, boolean isReserved) throws IOException {
|
||||
insert(streamIndex, bytes, 0, bytes.length, isReserved);
|
||||
}//insert()//
|
||||
/**
|
||||
* Inserts the specified unsigned byte value to the stream.
|
||||
* @param streamIndex The index of the byte within the stream (where index zero is the very first byte written to the stream).
|
||||
* @param b The unsigned byte value to write to the stream.
|
||||
* @param isReserved Whether the byte is being written to a reserved space. If this is true then an insert buffer will not be used because space in the buffer is already allocated.
|
||||
*/
|
||||
protected void insert(int streamIndex, int b, boolean isReserved) throws IOException {
|
||||
//If this value is going into a reserved space in the buffer then simply write to the buffer, otherwise we will add it to the insert buffer.//
|
||||
if(isReserved) {
|
||||
buffer[streamIndex - streamLocation] = (byte) b;
|
||||
}//if//
|
||||
else {
|
||||
Debug.halt(); //Should not occur.//
|
||||
}//else//
|
||||
}//insert()//
|
||||
/**
|
||||
* Determines whether this stream is performing an insert of bytes into another BufferedOutputStream object.
|
||||
* @return Whether this stream is inserting into another stream.
|
||||
*/
|
||||
protected boolean isInsertStream() {
|
||||
return isInsertStream;
|
||||
}//isInsertStream()//
|
||||
/**
|
||||
* Shifts the location of the buffered output stream.
|
||||
* <p>This will occur if this stream is either a simple marker, or an insertable stream into the encapsulated buffered output stream.
|
||||
* The encapsulated buffered output stream will call this method if another insertable stream inserts some data into the stream at an earlier stream location.
|
||||
* @param offset The number of bytes to move the location forward (higher or later in the stream).
|
||||
*/
|
||||
protected void moveLocation(int offset) {
|
||||
streamLocation += offset;
|
||||
}//moveLocation()//
|
||||
/**
|
||||
* Resizes the buffer so that it can contain <code>count</code> more bytes (at a minimum).
|
||||
* @param count The number of bytes the user expects to add immediatly.
|
||||
*/
|
||||
protected void resizeBuffer(int count) throws IOException {
|
||||
byte[] tempBuffer = new byte[buffer.length + (count > bufferIncrementSize ? count + bufferIncrementSize : bufferIncrementSize)];
|
||||
|
||||
System.arraycopy(buffer, 0, tempBuffer, 0, buffer.length);
|
||||
buffer = tempBuffer;
|
||||
}//resizeBuffer()//
|
||||
/**
|
||||
* Copies the contents of the stream's buffer into a new byte array.
|
||||
* @return A byte array containing all of the bytes written to this stream.
|
||||
*/
|
||||
public byte[] toByteArray() throws IOException {
|
||||
byte[] bytes = null;
|
||||
|
||||
flush();
|
||||
|
||||
if(outputStream instanceof java.io.ByteArrayOutputStream) {
|
||||
bytes = ((java.io.ByteArrayOutputStream) outputStream).toByteArray();
|
||||
}//if//
|
||||
else if(outputStream instanceof ByteArrayOutputStream) {
|
||||
bytes = ((ByteArrayOutputStream) outputStream).toByteArray();
|
||||
}//else if//
|
||||
else if(outputStream instanceof BufferedOutputStream) {
|
||||
bytes = ((BufferedOutputStream) outputStream).toByteArray();
|
||||
}//else if//
|
||||
else {
|
||||
throw new com.common.exception.MethodNotSupportedException("toByteArray() not supported except for java.io.ByteArrayOutputStream and com.common.io.ByteArrayOutputStream");
|
||||
}//else//
|
||||
|
||||
return bytes;
|
||||
}//toByteArray()//
|
||||
/**
|
||||
* Updates the location objects after bytes were inserted into the stream.
|
||||
* @param byteIndex The stream byte index that the bytes were inserted at.
|
||||
* @param insertedByteCount The number of bytes inserted.
|
||||
*/
|
||||
protected void updateLocations(int byteIndex, int insertedByteCount) {
|
||||
IIterator iterator = locations.iterator();
|
||||
|
||||
while(iterator.hasNext()) {
|
||||
BufferedOutputStream location = (BufferedOutputStream) iterator.next();
|
||||
|
||||
if(((location.isFixedSize) && ((location.getByteIndex() - location.reservedByteCount) >= byteIndex)) || ((!location.isFixedSize) && (location.getByteIndex() >= byteIndex))) {
|
||||
location.moveLocation(insertedByteCount);
|
||||
}//if//
|
||||
}//while//
|
||||
}//updateLocations()//
|
||||
/**
|
||||
* Writes the specified byte values to the stream.
|
||||
* @param bytes The array of values to write to the stream.
|
||||
*/
|
||||
public void write(byte[] bytes) throws IOException {
|
||||
if((isInsertStream) && (isFixedSize)) {
|
||||
if(bytes.length > reservedByteCount) {
|
||||
throw new IOException("Cannot write more bytes than were reserved when the insert output stream was created.");
|
||||
}//if//
|
||||
|
||||
//Send the data to the encapsulated stream at the location of the earliest unused reserved byte.//
|
||||
((BufferedOutputStream) outputStream).insert(streamLocation - reservedByteCount, bytes, isFixedSize);
|
||||
//Update the count of reserved bytes.//
|
||||
reservedByteCount -= bytes.length;
|
||||
|
||||
if(reservedByteCount == 0) {
|
||||
close();
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
int offset = 0;
|
||||
int availableSpace = buffer.length - bufferSize;
|
||||
int remainingBytes = bytes.length;
|
||||
|
||||
//Determine whether we can perform a simple write, or whether we need to perform a write & flush loop or resize the buffer.//
|
||||
if(availableSpace < remainingBytes) {
|
||||
//Keep writing and flushing as long as there is data and buffer space.//
|
||||
while((availableSpace > 0) && (remainingBytes > 0)) {
|
||||
int copyLength = availableSpace > remainingBytes ? remainingBytes : availableSpace;
|
||||
|
||||
System.arraycopy(bytes, offset, buffer, bufferSize, copyLength);
|
||||
bufferSize += copyLength;
|
||||
remainingBytes -= copyLength;
|
||||
offset += copyLength;
|
||||
|
||||
if(remainingBytes > 0) {
|
||||
flush();
|
||||
availableSpace = buffer.length - bufferSize;
|
||||
}//if//
|
||||
}//while//
|
||||
|
||||
//If we must, then resize the buffer to accomidate the data.//
|
||||
if((availableSpace == 0) && (remainingBytes > 0)) {
|
||||
//Resize the buffer so it can contain the new data.//
|
||||
resizeBuffer(remainingBytes);
|
||||
//Copy the bytes into the buffer.//
|
||||
System.arraycopy(bytes, offset, buffer, bufferSize, remainingBytes);
|
||||
//Update the buffer size.//
|
||||
bufferSize += remainingBytes;
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
//Copy the bytes into the buffer.//
|
||||
System.arraycopy(bytes, 0, buffer, bufferSize, bytes.length);
|
||||
//Update the buffer size.//
|
||||
bufferSize += bytes.length;
|
||||
}//else//
|
||||
}//else//
|
||||
}//write()//
|
||||
/**
|
||||
* Writes the specified byte values to the stream.
|
||||
* @param bytes The array of values to write to the stream.
|
||||
* @param offset The offset of the first value to write to the stream.
|
||||
* @param length The number of values to write to the stream.
|
||||
*/
|
||||
public void write(byte[] bytes, int offset, int length) throws IOException {
|
||||
if((isInsertStream) && (isFixedSize)) {
|
||||
if(length > reservedByteCount) {
|
||||
throw new IOException("Cannot write more bytes than were reserved when the insert output stream was created.");
|
||||
}//if//
|
||||
|
||||
//Send the data to the encapsulated stream at the location of the earliest unused reserved byte.//
|
||||
((BufferedOutputStream) outputStream).insert(streamLocation - reservedByteCount, bytes, offset, length, isFixedSize);
|
||||
//Update the count of reserved bytes.//
|
||||
reservedByteCount -= length;
|
||||
|
||||
if(reservedByteCount == 0) {
|
||||
close();
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
int availableSpace = buffer.length - bufferSize;
|
||||
int remainingBytes = length;
|
||||
|
||||
//Determine whether we can perform a simple write, or whether we need to perform a write & flush loop or resize the buffer.//
|
||||
if(availableSpace < remainingBytes) {
|
||||
//Keep writing and flushing as long as there is data and buffer space.//
|
||||
while((availableSpace > 0) && (remainingBytes > 0)) {
|
||||
int copyLength = availableSpace > remainingBytes ? remainingBytes : availableSpace;
|
||||
|
||||
System.arraycopy(bytes, offset, buffer, bufferSize, copyLength);
|
||||
bufferSize += copyLength;
|
||||
remainingBytes -= copyLength;
|
||||
offset += copyLength;
|
||||
|
||||
if(remainingBytes > 0) {
|
||||
flush();
|
||||
availableSpace = buffer.length - bufferSize;
|
||||
}//if//
|
||||
}//while//
|
||||
|
||||
//If we must, then resize the buffer to accomidate the data.//
|
||||
if((availableSpace == 0) && (remainingBytes > 0)) {
|
||||
//Resize the buffer so it can contain the new data.//
|
||||
resizeBuffer(remainingBytes);
|
||||
//Copy the bytes into the buffer.//
|
||||
System.arraycopy(bytes, offset, buffer, bufferSize, remainingBytes);
|
||||
//Update the buffer size.//
|
||||
bufferSize += remainingBytes;
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
//Copy the bytes into the buffer.//
|
||||
System.arraycopy(bytes, offset, buffer, bufferSize, length);
|
||||
//Update the buffer size.//
|
||||
bufferSize += length;
|
||||
}//else//
|
||||
}//else//
|
||||
}//write()//
|
||||
/**
|
||||
* Writes the specified unsigned byte value to the stream.
|
||||
* @param b The unsigned byte value to write to the stream.
|
||||
*/
|
||||
public void write(int b) throws IOException {
|
||||
if((isInsertStream) && (isFixedSize)) {
|
||||
if(reservedByteCount == 0) {
|
||||
throw new IOException("Cannot write more bytes than were reserved when the insert output stream was created.");
|
||||
}//if//
|
||||
|
||||
//Send the data to the encapsulated stream at the location of the earliest unused reserved byte.//
|
||||
((BufferedOutputStream) outputStream).insert(streamLocation - reservedByteCount, b, isFixedSize);
|
||||
//Update the count of reserved bytes.//
|
||||
reservedByteCount--;
|
||||
|
||||
if(reservedByteCount == 0) {
|
||||
close();
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
//If there is not enough room in the buffer then try to flush it, and if still no room then resize it.//
|
||||
if(bufferSize == buffer.length) {
|
||||
flush();
|
||||
|
||||
if(bufferSize == buffer.length) {
|
||||
resizeBuffer(1);
|
||||
}//if//
|
||||
}//if//
|
||||
|
||||
//Write the byte to the buffer.//
|
||||
buffer[bufferSize++] = (byte) b;
|
||||
}//else//
|
||||
}//write()//
|
||||
}//BufferedOutputStream//
|
||||
328
Common/src/com/common/io/ByteArrayInputStream.java
Normal file
328
Common/src/com/common/io/ByteArrayInputStream.java
Normal file
@@ -0,0 +1,328 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2008 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* A simple stream that reads bytes from a byte array.
|
||||
* This stream is capable of decrypting the bytes as they are read.
|
||||
*/
|
||||
public class ByteArrayInputStream extends java.io.InputStream implements IInputStream {
|
||||
/** The default initial size of the buffer. */
|
||||
private static final int DEFAULT_SIZE = 1001;
|
||||
|
||||
private byte[] buffer;
|
||||
private int position;
|
||||
private int count;
|
||||
private int expectedSize;
|
||||
//private boolean reuseBuffer;
|
||||
private int originalPosition = 0;
|
||||
private int originalCount = 0;
|
||||
/**
|
||||
* Creates the byte array input stream with a buffer containing source data.
|
||||
* @param buffer A buffer containing the source data for this stream.
|
||||
*/
|
||||
public ByteArrayInputStream(byte[] buffer) {
|
||||
this(buffer, 0, (buffer != null ? buffer.length : 0));
|
||||
}//ByteArrayInputStream()//
|
||||
/**
|
||||
* Creates the byte array input stream with a buffer containing source data.
|
||||
* @param buffer A buffer containing the source data for this stream.
|
||||
* @param offset The offset of the first byte of source data in the buffer.
|
||||
* @param length The number of bytes of source data in the buffer.
|
||||
*/
|
||||
public ByteArrayInputStream(byte[] buffer, int offset, int length) {
|
||||
//this.reuseBuffer = false;
|
||||
this.expectedSize = DEFAULT_SIZE;
|
||||
internalSetBuffer(buffer, offset, length);
|
||||
}//ByteArrayInputStream()//
|
||||
/**
|
||||
* Creates the byte array input stream with the estimated number of source bytes to be put in the stream.
|
||||
* @param expectedSize The number of bytes the user expects will be in this stream.
|
||||
*/
|
||||
public ByteArrayInputStream(int expectedSize) {
|
||||
//this.reuseBuffer = true;
|
||||
this.expectedSize = expectedSize;
|
||||
this.buffer = null;
|
||||
this.position = 0;
|
||||
this.count = 0;
|
||||
}//ByteArrayInputStream()//
|
||||
/**
|
||||
* Gets the current position in the stream.
|
||||
* @return The current position.
|
||||
*/
|
||||
public int getPosition() {
|
||||
return position;
|
||||
}//getPosition()//
|
||||
/**
|
||||
* Sets the current position in the stream.
|
||||
* @param position The current position.
|
||||
*/
|
||||
public void setPosition(int position) {
|
||||
this.position = position;
|
||||
}//setPosition()//
|
||||
/**
|
||||
* Gets the number of available bytes in the input stream.
|
||||
* @return The number of bytes that have not yet been read from the input stream.
|
||||
*/
|
||||
public int available() throws IOException {
|
||||
return count - position;
|
||||
}//available()//
|
||||
/**
|
||||
* @see IInputStream.canDecrypt()
|
||||
*/
|
||||
public boolean canDecrypt() {
|
||||
return false;
|
||||
}//canDecrypt()//
|
||||
/**
|
||||
* @see IInputStream.canReadFrom()
|
||||
*/
|
||||
public boolean canReadFrom() {
|
||||
return true;
|
||||
}//canReadFrom()//
|
||||
/**
|
||||
* Closes the stream and releases all held resources.
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
internalRelease();
|
||||
}//close()//
|
||||
/**
|
||||
* Switches decryption of the stream off and on.
|
||||
* Nothing will occur if no symmetric algorithm was provided to the stream.
|
||||
* The stream does maintain a decryption count which is incremented when decryption is turned on and only stops the decrypting when this count reaches zero.
|
||||
* Since data written to the ByteArrayOutputStream is never double encrypted, the data read will also not be double decrypted.
|
||||
* @param decrypt Whether to turn decryption on (<code>true</code>) or off (<code>false</code>).
|
||||
* @see IInputStream.decrypt(boolean)
|
||||
*/
|
||||
public void decrypt(boolean decrypt) throws java.io.IOException {
|
||||
|
||||
}//encrypt()//
|
||||
/**
|
||||
* Makes sure the buffer is large enough to hold <code>size</code> bytes in addition to any bytes already held.
|
||||
* @param size The number of new bytes the buffer must be able to hold.
|
||||
*/
|
||||
protected void ensureSpace(int size) {
|
||||
byte[] oldBuffer = buffer;
|
||||
|
||||
if(oldBuffer == null) {
|
||||
buffer = new byte[expectedSize < size ? size + 50 : expectedSize];
|
||||
}//if//
|
||||
else if(oldBuffer.length - count < size) {
|
||||
byte[] newBuffer = new byte[oldBuffer.length + size + 50];
|
||||
|
||||
System.arraycopy(oldBuffer, 0, newBuffer, 0, count);
|
||||
buffer = newBuffer;
|
||||
}//else if//
|
||||
}//ensureSpace()//
|
||||
/**
|
||||
* Will release any held resources.
|
||||
*/
|
||||
public void finalize() {
|
||||
//Release the stream resources.//
|
||||
internalRelease();
|
||||
}//finalize()//
|
||||
/**
|
||||
* Initializes the stream with the given source material.
|
||||
* @param buffer The new byte array buffer to use for source bytes.
|
||||
*/
|
||||
public void initialize(byte[] buffer) {
|
||||
if(buffer != null) {
|
||||
internalInitialize(buffer, 0, buffer.length);
|
||||
}//if//
|
||||
else {
|
||||
throw new com.common.exception.InvalidArgumentException("Must supply a valid buffer.");
|
||||
}//else//
|
||||
}//initialize()//
|
||||
/**
|
||||
* Initializes the stream with the given source material.
|
||||
* @param buffer The new byte array buffer to use for source bytes.
|
||||
* @param offset The offset in the buffer where the first source byte can be found.
|
||||
* @param length The number of source bytes available in the supplied buffer.
|
||||
*/
|
||||
public void initialize(byte[] buffer, int offset, int length) {
|
||||
internalInitialize(buffer, offset, length);
|
||||
}//initialize()//
|
||||
/**
|
||||
* Initializes the stream with the given source material.
|
||||
* @param buffer The new byte array buffer to use for source bytes.
|
||||
* @param offset The offset in the buffer where the first source byte can be found.
|
||||
* @param length The number of source bytes available in the supplied buffer.
|
||||
*/
|
||||
private void internalInitialize(byte[] buffer, int offset, int length) {
|
||||
//Cleanup in case this stream is being reused.//
|
||||
internalRelease();
|
||||
//The buffer is not reusable.//
|
||||
//reuseBuffer = false;
|
||||
//Initialize the stream with the new source material.//
|
||||
internalSetBuffer(buffer, offset, length);
|
||||
}//internalInitialize()//
|
||||
/**
|
||||
* Releases the held resources and resets the stream indexes.
|
||||
* This is useful if the stream will be reused, if the buffers are reuseable, or to assist GC.
|
||||
*/
|
||||
private void internalRelease() {
|
||||
//Clean the stream.//
|
||||
buffer = null;
|
||||
originalPosition = 0;
|
||||
originalCount = 0;
|
||||
position = 0;
|
||||
count = 0;
|
||||
}//internalRelease()//
|
||||
/**
|
||||
* Resets the stream so that it may be re-read.
|
||||
*/
|
||||
private void internalReset() {
|
||||
//Reset the position and count to the original values.//
|
||||
position = originalPosition;
|
||||
count = originalCount;
|
||||
}//internalReset()//
|
||||
/**
|
||||
* Sets the buffer to be used by this stream as a source of bytes.
|
||||
* @param buffer The new byte array buffer to use for source bytes.
|
||||
* @param offset The offset in the buffer where the first source byte can be found.
|
||||
* @param length The number of source bytes available in the supplied buffer.
|
||||
*/
|
||||
protected void internalSetBuffer(byte[] buffer, int offset, int length) {
|
||||
//Set the position variables.//
|
||||
this.originalPosition = offset;
|
||||
this.originalCount = length + offset;
|
||||
this.buffer = buffer;
|
||||
this.position = offset;
|
||||
this.count = length + offset;
|
||||
}//internalSetBuffer()//
|
||||
/**
|
||||
* Gets the underlying buffer used by the input stream.
|
||||
* @return The underlying buffer.
|
||||
*/
|
||||
public byte[] getBuffer() {
|
||||
return buffer;
|
||||
}//getBuffer()//
|
||||
/**
|
||||
* @see IInputStream.isDecrypting()
|
||||
*/
|
||||
public boolean isDecrypting() {
|
||||
return false;
|
||||
}//isDecrypting()//
|
||||
/**
|
||||
* Gets the next byte from the stream without actually incrementing the stream.
|
||||
* @return The next byte in the stream.
|
||||
*/
|
||||
public byte peek() throws IOException {
|
||||
return peek(1);
|
||||
}//peek()//
|
||||
/**
|
||||
* Gets the byte from the stream at the requested offset without actually incrementing the stream.
|
||||
* @param offset The offset from the current location in the stream. This value must be positive and should not exceed the number of bytes left in the stream.
|
||||
* @return The byte found at the specified offset.
|
||||
*/
|
||||
public byte peek(int offset) throws IOException {
|
||||
if((position + offset < count) && (position + offset >= 0)) {
|
||||
return buffer[position + offset];
|
||||
}//if//
|
||||
|
||||
throw new IOException("Invalid offset.");
|
||||
}//peek()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.InputStream#read()
|
||||
*/
|
||||
public int read() throws IOException {
|
||||
return position < count ? buffer[position++] & 0xFF : -1;
|
||||
}//read()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.InputStream#read(byte[], int, int)
|
||||
*/
|
||||
public int read(byte[] bytes, int offset, int length) throws IOException {
|
||||
int newPosition = position + length;
|
||||
|
||||
//Check to see if there are any bytes available.//
|
||||
if(position < count) {
|
||||
//Update the number of requested bytes if there are not enough available.//
|
||||
if(newPosition > count) {
|
||||
length = count - position;
|
||||
newPosition = position + length;
|
||||
}//if//
|
||||
|
||||
//Copy the bytes from this stream to the buffer.//
|
||||
System.arraycopy(buffer, position, bytes, offset, length);
|
||||
//Update the stream position.//
|
||||
position = newPosition;
|
||||
}//if//
|
||||
else {
|
||||
//Note: I changed this to -1 to comply with the java.io.InputStream#read(byte[], int, int) commenting. This may cause problems with existing code that uses this class.//
|
||||
length = -1;
|
||||
}//else//
|
||||
|
||||
//Return the number of bytes pulled off the stream.//
|
||||
return length;
|
||||
}//read()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IInputStream#read(java.io.OutputStream, int)
|
||||
*/
|
||||
public int read(java.io.OutputStream out, int length) throws IOException {
|
||||
int newPosition = position + length;
|
||||
|
||||
//Check to see if there are any bytes available.//
|
||||
if(position < count) {
|
||||
//Update the number of requested bytes if there are not enough available.//
|
||||
if(newPosition > count) {
|
||||
length = count - position;
|
||||
newPosition = position + length;
|
||||
}//if//
|
||||
|
||||
//Copy the bytes from this stream to the output stream.//
|
||||
out.write(buffer, position, length);
|
||||
//Update the stream position.//
|
||||
position = newPosition;
|
||||
}//if//
|
||||
else {
|
||||
length = 0;
|
||||
}//else//
|
||||
|
||||
//Return the number of bytes pulled off the stream.//
|
||||
return length;
|
||||
}//read()//
|
||||
/**
|
||||
* Replaces the buffered data in this input stream with the bytes from the given input stream.
|
||||
* @param in The input stream containing the data to be buffered by this input stream.
|
||||
* @param numberOfBytes The number of bytes to be read.
|
||||
* @throws IOException If there are not enough bytes on the given input stream.
|
||||
*/
|
||||
public void readFrom(InputStream in, int numberOfBytes) throws IOException {
|
||||
int totalNumberOfBytes = numberOfBytes + count;
|
||||
int bytesRead;
|
||||
|
||||
//Ensure the length of the buffer.//
|
||||
ensureSpace(numberOfBytes);
|
||||
|
||||
//Read the bytes off the stream.//
|
||||
while(count != totalNumberOfBytes) {
|
||||
bytesRead = in.read(buffer, count, totalNumberOfBytes - count);
|
||||
|
||||
if(bytesRead == -1) {
|
||||
throw new IOException();
|
||||
}//if//
|
||||
|
||||
count += bytesRead;
|
||||
originalCount += bytesRead;
|
||||
}//while//
|
||||
}//readFrom()//
|
||||
/**
|
||||
* Releases the stream resources and resets the stream so that the object may be GC'd or reused.
|
||||
* This stream will no longer be re-readable.
|
||||
*/
|
||||
public void release() {
|
||||
internalRelease();
|
||||
}//release()//
|
||||
/**
|
||||
* Resets the stream so that it may be re-read.
|
||||
*/
|
||||
public void reset() throws IOException {
|
||||
internalReset();
|
||||
}//reset()//
|
||||
}//ByteArrayInputStream//
|
||||
307
Common/src/com/common/io/ByteArrayOutputStream.java
Normal file
307
Common/src/com/common/io/ByteArrayOutputStream.java
Normal file
@@ -0,0 +1,307 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2008 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import com.common.security.*;
|
||||
|
||||
/**
|
||||
* A simple stream that writes bytes to a byte array.
|
||||
* This stream is capable of encrypting the bytes as they are written.
|
||||
*/
|
||||
public class ByteArrayOutputStream extends OutputStream implements IOutputStream {
|
||||
private byte[] buffer;
|
||||
protected int index;
|
||||
private int optimalSize = 0;
|
||||
//private boolean reuseBuffer;
|
||||
/**
|
||||
* ByteArrayOutputStream constructor.
|
||||
* @param optimalSize The estimated number of bytes that will be written to the stream.
|
||||
* @param reuseBuffer Whether the resources should be reused.
|
||||
*/
|
||||
public ByteArrayOutputStream(int optimalSize, boolean reuseBuffer) {
|
||||
//this.reuseBuffer = reuseBuffer;
|
||||
this.optimalSize = optimalSize;
|
||||
this.buffer = null;
|
||||
this.index = 0;
|
||||
}//ByteArrayOutputStream()//
|
||||
/**
|
||||
* @see IOutputStream.canEncrypt()
|
||||
*/
|
||||
public boolean canEncrypt() {
|
||||
return true;
|
||||
}//canEncrypt()//
|
||||
/**
|
||||
* @see IOutputStream.canEncrypt()
|
||||
*/
|
||||
public boolean canGetSize() {
|
||||
return true;
|
||||
}//canGetSize()//
|
||||
/**
|
||||
* @see IOutputStream.canReset()
|
||||
*/
|
||||
public boolean canReset() {
|
||||
return true;
|
||||
}//canReset()//
|
||||
/**
|
||||
* @see IOutputStream.canWriteTo()
|
||||
*/
|
||||
public boolean canWriteTo() {
|
||||
return true;
|
||||
}//canWriteTo()//
|
||||
/**
|
||||
* Closes the stream and releases all held resources.
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
internalRelease();
|
||||
}//close()//
|
||||
/**
|
||||
* Switches encryption of the stream off and on.
|
||||
* Nothing will occur if no symmetric algorithm was provided to the stream.
|
||||
* The stream does maintain an encryption count which is incremented when encryption is turned on and only stops the encrypting when this count reaches zero.
|
||||
* Since data written to the ByteArrayOutputStream is never double encrypted, the data read will also not be double decrypted.
|
||||
* @param encrypt Whether to turn encryption on (<code>true</code>) or off (<code>false</code>).
|
||||
*/
|
||||
public void encrypt(boolean encrypt) throws java.io.IOException {
|
||||
|
||||
}//encrypt()//
|
||||
/**
|
||||
* Makes sure there is enough space available to write <code>size</code> bytes to the stream.
|
||||
* @param size The number of bytes of space that should be available.
|
||||
*/
|
||||
protected void ensureSpace(int size) {
|
||||
byte[] oldBuffer = buffer;
|
||||
|
||||
if(oldBuffer == null) {
|
||||
buffer = new byte[optimalSize < size ? size + 100 : optimalSize];
|
||||
}//if//
|
||||
else if(oldBuffer.length - index < size) {
|
||||
byte[] newBuffer = new byte[oldBuffer.length + size + 100];
|
||||
|
||||
System.arraycopy(oldBuffer, 0, newBuffer, 0, index);
|
||||
buffer = newBuffer;
|
||||
}//else if//
|
||||
}//ensureSpace()//
|
||||
/**
|
||||
* Will release any held resources.
|
||||
*/
|
||||
public void finalize() throws Throwable {
|
||||
internalRelease();
|
||||
}//finalize()//
|
||||
/**
|
||||
* Gets the buffer used by this stream.
|
||||
* @return The buffer used by the stream for storing bytes written.
|
||||
*/
|
||||
public byte[] getBuffer() {
|
||||
return buffer;
|
||||
}//getBuffer()//
|
||||
/**
|
||||
* Sets the buffer used by this stream.
|
||||
* @param buffer The buffer used by the stream for storing bytes written.
|
||||
*/
|
||||
protected void setBuffer(byte[] buffer) {
|
||||
this.buffer = buffer;
|
||||
}//setBuffer()//
|
||||
/**
|
||||
* Gets the number of bytes in the stream (including reserved or inset bytes if there are any).
|
||||
* @return The number of bytes in the stream.
|
||||
*/
|
||||
public int getSize() {
|
||||
return index;
|
||||
}//getSize()//
|
||||
/**
|
||||
* Initializes the stream with a new buffer.
|
||||
*/
|
||||
public void initialize(int insetSize, ISymmetricAlgorithm symmetricAlgorithm) {
|
||||
internalInitialize(insetSize, symmetricAlgorithm);
|
||||
}//initialize()//
|
||||
/**
|
||||
* Initializes the stream with a new buffer.
|
||||
*/
|
||||
protected void internalInitialize(int insetSize, ISymmetricAlgorithm symmetricAlgorithm) {
|
||||
//Make sure we are clean.//
|
||||
internalRelease();
|
||||
//Get a new buffer.//
|
||||
internalSetBuffer(new byte[optimalSize]);
|
||||
//Set the current index.//
|
||||
this.index = insetSize;
|
||||
}//internalInitialize()//
|
||||
/**
|
||||
* Resets the stream and releases any held resources.
|
||||
*/
|
||||
private void internalRelease() {
|
||||
buffer = null;
|
||||
index = 0;
|
||||
}//internalRelease()//
|
||||
/**
|
||||
* Resets the stream so it may be reused.
|
||||
*/
|
||||
private void internalReset() {
|
||||
index = 0;
|
||||
}//internalReset()//
|
||||
/**
|
||||
* Sets the stream's buffer.
|
||||
* @param buffer The byte array buffer to be used by this stream.
|
||||
*/
|
||||
private void internalSetBuffer(byte[] buffer) {
|
||||
this.buffer = buffer;
|
||||
}//internalSetBuffer()//
|
||||
/**
|
||||
* @see IOutputStream.isEncrypting()
|
||||
*/
|
||||
public boolean isEncrypting() {
|
||||
return false;
|
||||
}//isEncrypting()//
|
||||
/**
|
||||
* Will add padding to the stream up to the given index within the stream.
|
||||
* <p>NOTE: The purpose of this method is to get around timing problems in win95/98 where streams of a size less than 255 bytes causes 150ms delays in reading from the stream.
|
||||
* @param index The index (position) within the stream to pad to.
|
||||
*/
|
||||
public void padTo(int index) throws IOException {
|
||||
int paddingSize = index - this.index;
|
||||
|
||||
//Write zeros to the stream for padding.//
|
||||
if(paddingSize > 0) {
|
||||
while(paddingSize != 0) {
|
||||
write(0);
|
||||
paddingSize--;
|
||||
}//while//
|
||||
}//if//
|
||||
}//padTo()//
|
||||
/**
|
||||
* Adds padding to the stream.
|
||||
* @param size The number of padding bytes to be written to the stream.
|
||||
*/
|
||||
public void pad(int size) throws IOException {
|
||||
//Write zeros to the stream for padding.//
|
||||
if(size > 0) {
|
||||
while(size != 0) {
|
||||
write(0);
|
||||
size--;
|
||||
}//while//
|
||||
}//if//
|
||||
}//pad()//
|
||||
/**
|
||||
* Resets the stream so that it may be reused.
|
||||
*/
|
||||
public void reset() throws IOException {
|
||||
internalReset();
|
||||
}//reset()//
|
||||
/**
|
||||
* Gets the current position in the output stream.
|
||||
* @return The current stream position. Same as calling getSize().
|
||||
*/
|
||||
public int getPosition() {
|
||||
return index;
|
||||
}//getPosition()//
|
||||
/**
|
||||
* Sets the stream position for writing.
|
||||
* @param position The position of the stream. This will change the size of the stream.
|
||||
*/
|
||||
public void setPosition(int position) {
|
||||
if(position > buffer.length) {
|
||||
ensureSpace(position - index);
|
||||
}//if//
|
||||
|
||||
index = position;
|
||||
}//setPosition()//
|
||||
/**
|
||||
* Copies the contents of the stream's buffer into a new byte array.
|
||||
* @return A byte array containing all of the bytes written to this stream.
|
||||
*/
|
||||
public byte[] toByteArray() {
|
||||
byte[] newbuffer = new byte[index];
|
||||
|
||||
if(buffer != null) {
|
||||
System.arraycopy(buffer, 0, newbuffer, 0, index);
|
||||
}//if//
|
||||
|
||||
return newbuffer;
|
||||
}//toByteArray()//
|
||||
/**
|
||||
* Writes the bytes to this stream.
|
||||
* @param bytes The data to be written to this stream.
|
||||
*/
|
||||
public void write(ByteBuffer bytes) throws java.io.IOException {
|
||||
int count = bytes.remaining();
|
||||
|
||||
//Make sure there is enough space.//
|
||||
ensureSpace(count);
|
||||
//Copy the bytes to the stream buffer.//
|
||||
bytes.get(buffer, index, count);
|
||||
//Update the index.//
|
||||
index += count;
|
||||
}//write()//
|
||||
/**
|
||||
* Writes the bytes to this stream.
|
||||
* @param bytes The data to be written to this stream.
|
||||
* @param length The number of bytes to write to this stream.
|
||||
*/
|
||||
public void write(ByteBuffer bytes, int count) throws java.io.IOException {
|
||||
//Make sure there is enough space.//
|
||||
ensureSpace(count);
|
||||
//Copy the bytes to the stream buffer.//
|
||||
bytes.get(buffer, index, count);
|
||||
//Update the index.//
|
||||
index += count;
|
||||
}//write()//
|
||||
/**
|
||||
* Writes the bytes to this stream.
|
||||
* @param bytes The data to be written to this stream.
|
||||
*/
|
||||
public void write(byte[] bytes) throws java.io.IOException {
|
||||
//Make sure there is enough space.//
|
||||
ensureSpace(bytes.length);
|
||||
//Copy the bytes to the stream buffer.//
|
||||
System.arraycopy(bytes, 0, buffer, index, bytes.length);
|
||||
//Update the index.//
|
||||
index += bytes.length;
|
||||
}//write()//
|
||||
/**
|
||||
* Writes the bytes to this stream.
|
||||
* @param bytes The data to be written to this stream.
|
||||
* @param offset The offset of the first byte to write.
|
||||
* @param length The number of bytes to write to this stream.
|
||||
*/
|
||||
public void write(byte[] bytes, int offset, int length) throws java.io.IOException {
|
||||
//Make sure there is enough space.//
|
||||
ensureSpace(length);
|
||||
//Copy the bytes to the stream buffer.//
|
||||
System.arraycopy(bytes, offset, buffer, index, length);
|
||||
//Update the index.//
|
||||
index += length;
|
||||
}//write()//
|
||||
/**
|
||||
* Writes the specified byte to this stream.
|
||||
* @param b The byte to append to this stream.
|
||||
*/
|
||||
public void write(int b) throws IOException {
|
||||
//Make sure there is enough space.//
|
||||
ensureSpace(1);
|
||||
//Append the new byte to the end of the buffer.//
|
||||
buffer[index] = (byte) b;
|
||||
//Adjust the count of bytes in the buffer.//
|
||||
index++;
|
||||
}//write()//
|
||||
/**
|
||||
* Writes the contents of the stream buffer to the given output stream.
|
||||
* @param out The output stream to write the data to.
|
||||
*/
|
||||
public void writeTo(OutputStream out) throws IOException {
|
||||
out.write(buffer, 0, index);
|
||||
}//writeTo()//
|
||||
/**
|
||||
* Writes the contents of the stream buffer to the given byte buffer.
|
||||
* @param out The output stream to write the data to.
|
||||
*/
|
||||
public void writeTo(ByteBuffer buffer) throws IOException {
|
||||
buffer.put(this.buffer, 0, index);
|
||||
}//writeTo()//
|
||||
}//ByteArrayOutputStream//
|
||||
204
Common/src/com/common/io/CompressionInputStream.java
Normal file
204
Common/src/com/common/io/CompressionInputStream.java
Normal file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.zip.*;
|
||||
import com.common.debug.*;
|
||||
|
||||
public class CompressionInputStream extends InputStream implements IInputStream {
|
||||
public static final int DEFAULT_BUFFER_SIZE = 301;
|
||||
|
||||
protected InputStream stream = null;
|
||||
protected Inflater inflater = null;
|
||||
protected byte[] internalBuffer = null;
|
||||
protected byte[] bufferOfOne = new byte[1];
|
||||
/**
|
||||
* CompressionInputStream constructor.
|
||||
* @param stream The stream that will provide input to this compression stream.
|
||||
*/
|
||||
public CompressionInputStream(InputStream stream) {
|
||||
this(stream, new Inflater(true), DEFAULT_BUFFER_SIZE);
|
||||
}//CompressionInputStream()//
|
||||
/**
|
||||
* CompressionInputStream constructor.
|
||||
* @param stream The stream that will provide input to this compression stream.
|
||||
* @param inflater The inflater to be used to inflate the input data.
|
||||
*/
|
||||
public CompressionInputStream(InputStream stream, Inflater inflater) {
|
||||
this(stream, inflater, DEFAULT_BUFFER_SIZE);
|
||||
}//CompressionInputStream()//
|
||||
/**
|
||||
* CompressionInputStream constructor.
|
||||
* @param stream The stream that will provide input to this compression stream.
|
||||
* @param inflater The inflater to be used to inflate the input data.
|
||||
* @param bufferSize The size of the internal buffer used to shuttle data from the underlying stream through the inflater.
|
||||
*/
|
||||
public CompressionInputStream(InputStream stream, Inflater inflater, int bufferSize) {
|
||||
//Validate the inputs.//
|
||||
if(bufferSize < 1) {
|
||||
throw new IllegalArgumentException("Buffer size must be greater than zero.");
|
||||
}//if//
|
||||
else if(stream == null) {
|
||||
throw new IllegalArgumentException("A non-null input stream must be provided.");
|
||||
}//else if//
|
||||
else if(inflater == null) {
|
||||
inflater = new Inflater(true);
|
||||
}//else if//
|
||||
|
||||
this.stream = stream;
|
||||
this.inflater = inflater;
|
||||
this.internalBuffer = new byte[bufferSize];
|
||||
}//CompressionInputStream()//
|
||||
/* (non-Javadoc)
|
||||
* @see IInputStream#canDecrypt()
|
||||
*/
|
||||
public boolean canDecrypt() {
|
||||
return (stream instanceof IInputStream) && (((IInputStream) stream).canDecrypt());
|
||||
}//canDecrypt()//
|
||||
/* (non-Javadoc)
|
||||
* @see IInputStream#decrypt(boolean)
|
||||
*/
|
||||
public void decrypt(boolean decrypt) throws IOException {
|
||||
if(stream instanceof IInputStream) {
|
||||
if(((IInputStream) stream).canDecrypt()) {
|
||||
((IInputStream) stream).decrypt(decrypt);
|
||||
}//if//
|
||||
else {
|
||||
throw new IOException(ERROR_DECRYPTION_NOT_SUPPORTED);
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
throw new IOException(ERROR_DECRYPTION_NOT_SUPPORTED);
|
||||
}//else//
|
||||
}//decrypt()//
|
||||
/**
|
||||
* Inflates the next section of compressed data.
|
||||
* @return Whether there was a next section to be decompressed.
|
||||
*/
|
||||
private boolean inflate() throws IOException {
|
||||
int readSize = (int) (StreamSupport.readShort(stream) & 0xFFFF);
|
||||
boolean result = false;
|
||||
|
||||
if((readSize = stream.read(internalBuffer, 0, readSize)) > 0) {
|
||||
inflater.setInput(internalBuffer, 0, readSize);
|
||||
result = true;
|
||||
}//if//
|
||||
|
||||
return result;
|
||||
}//inflate()//
|
||||
/* (non-Javadoc)
|
||||
* @see IInputStream#isDecrypting()
|
||||
*/
|
||||
public boolean isDecrypting() {
|
||||
return (stream instanceof IInputStream) && (((IInputStream) stream).isDecrypting());
|
||||
}//isDecrypting()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.InputStream#read()
|
||||
*/
|
||||
public int read() throws IOException {
|
||||
int result = -2;
|
||||
|
||||
try {
|
||||
while(result == -2) {
|
||||
if(inflater.inflate(bufferOfOne, 0, 1) == 0) {
|
||||
if(inflater.needsDictionary()) {
|
||||
//TODO: Do we need to do anything special if a dictionary is needed?
|
||||
Debug.log(new RuntimeException("Needs dictionary."));
|
||||
result = -1;
|
||||
}//if//
|
||||
else if(inflater.finished()) {
|
||||
result = -1;
|
||||
}//else if//
|
||||
else if(inflater.needsInput()) {
|
||||
//int readSize = length > internalBuffer.length ? internalBuffer.length : length;
|
||||
//int readSize = internalBuffer.length;
|
||||
if(!inflate()) {
|
||||
break;
|
||||
}//if//
|
||||
}//else if//
|
||||
}//if//
|
||||
else {
|
||||
result = bufferOfOne[0] & 0xFF;
|
||||
}//else//
|
||||
}//while//
|
||||
}//try//
|
||||
catch(DataFormatException e) {
|
||||
Debug.log(e);
|
||||
throw new IOException("Stream corruption error in decompressing.");
|
||||
}//catch//
|
||||
|
||||
return result;
|
||||
}//read()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.InputStream#read(byte[])
|
||||
*/
|
||||
public int read(byte[] buffer) throws IOException {
|
||||
return read(buffer, 0, buffer.length);
|
||||
}//read()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.InputStream#read(byte[], int, int)
|
||||
*/
|
||||
public int read(byte[] buffer, int offset, int length) throws IOException {
|
||||
int result = 0;
|
||||
|
||||
try {
|
||||
int count = 0;
|
||||
|
||||
while(count != -1 && length > 0) {
|
||||
if((count = inflater.inflate(buffer, offset, length)) == 0) {
|
||||
if(inflater.needsDictionary()) {
|
||||
//TODO: Do we need to do anything special if a dictionary is needed?
|
||||
Debug.log(new RuntimeException("Needs dictionary."));
|
||||
count = -1;
|
||||
}//if//
|
||||
else if(inflater.finished()) {
|
||||
count = -1;
|
||||
}//else if//
|
||||
else if(inflater.needsInput()) {
|
||||
//int readSize = length > internalBuffer.length ? internalBuffer.length : length;
|
||||
//int readSize = internalBuffer.length;
|
||||
if(!inflate()) {
|
||||
break;
|
||||
}//if//
|
||||
}//else if//
|
||||
}//if//
|
||||
else {
|
||||
offset += count;
|
||||
length -= count;
|
||||
result += count;
|
||||
}//else//
|
||||
}//while//
|
||||
}//try//
|
||||
catch(DataFormatException e) {
|
||||
Debug.log(e);
|
||||
throw new IOException("Stream corruption error in decompressing.");
|
||||
}//catch//
|
||||
|
||||
return result == 0 ? -1 : result;
|
||||
}//read()//
|
||||
/* (non-Javadoc)
|
||||
* @see IInputStream#read(java.io.OutputStream, int)
|
||||
*/
|
||||
public int read(java.io.OutputStream out, int length) throws IOException {
|
||||
int result;
|
||||
|
||||
if(stream instanceof IInputStream) {
|
||||
result = ((IInputStream) stream).read(out, length);
|
||||
}//if//
|
||||
else {
|
||||
byte[] bytes = new byte[length];
|
||||
|
||||
result = stream.read(bytes, 0, bytes.length);
|
||||
out.write(bytes, 0, result);
|
||||
}//else//
|
||||
|
||||
return result;
|
||||
}//read()//
|
||||
}//CompressionInputStream//
|
||||
152
Common/src/com/common/io/CompressionOutputStream.java
Normal file
152
Common/src/com/common/io/CompressionOutputStream.java
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 2003,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.zip.*;
|
||||
|
||||
public class CompressionOutputStream extends OutputStream implements IOutputStream {
|
||||
public static final int DEFAULT_BUFFER_SIZE = 301;
|
||||
public static final int MAX_BUFFER_SIZE = 65535;
|
||||
|
||||
protected OutputStream stream = null;
|
||||
protected Deflater deflater = null;
|
||||
protected byte[] outputBuffer = null;
|
||||
/**
|
||||
* CompressionOutputStream constructor.
|
||||
* @param stream The stream that will handle all output from this stream.
|
||||
*/
|
||||
public CompressionOutputStream(OutputStream stream) {
|
||||
this(stream, null, DEFAULT_BUFFER_SIZE);
|
||||
}//CompressionOutputStream()//
|
||||
/**
|
||||
* CompressionOutputStream constructor.
|
||||
* @param stream The stream that will handle all output from this stream.
|
||||
* @param deflater The deflater to be used.
|
||||
*/
|
||||
public CompressionOutputStream(OutputStream stream, Deflater deflater) {
|
||||
this(stream, deflater, DEFAULT_BUFFER_SIZE);
|
||||
}//CompressionOutputStream()//
|
||||
/**
|
||||
* CompressionOutputStream constructor.
|
||||
* @param stream The stream that will handle all output from this stream.
|
||||
* @param deflater The deflater to be used.
|
||||
* @param bufferSize The size of the buffer used to read from the deflater.
|
||||
*/
|
||||
public CompressionOutputStream(OutputStream stream, Deflater deflater, int bufferSize) {
|
||||
//Validate the inputs.//
|
||||
if(bufferSize < 1) {
|
||||
throw new IllegalArgumentException("Buffer size must be greater than zero.");
|
||||
}//if//
|
||||
else if(bufferSize > MAX_BUFFER_SIZE) {
|
||||
throw new IllegalArgumentException("Buffer size must be less than " + MAX_BUFFER_SIZE + ".");
|
||||
}//else if//
|
||||
else if(stream == null) {
|
||||
throw new IllegalArgumentException("A non-null output stream must be provided.");
|
||||
}//else if//
|
||||
else if(deflater == null) {
|
||||
deflater = new Deflater(Deflater.DEFAULT_COMPRESSION, true);
|
||||
}//else if//
|
||||
|
||||
this.stream = stream;
|
||||
this.deflater = deflater;
|
||||
this.outputBuffer = new byte[bufferSize];
|
||||
}//CompressionOutputStream()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.IOutputStream#canEncrypt()
|
||||
*/
|
||||
public boolean canEncrypt() {
|
||||
return (stream instanceof IOutputStream) && (((IOutputStream) stream).canEncrypt());
|
||||
}//canEncrypt()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.OutputStream#close()
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
deflater.finish();
|
||||
deflate();
|
||||
|
||||
super.close();
|
||||
}//close()//
|
||||
/**
|
||||
* Deflates the cached data.
|
||||
*/
|
||||
private void deflate() throws IOException {
|
||||
int count = 0;
|
||||
|
||||
while((count = deflater.deflate(outputBuffer, 2, outputBuffer.length - 2)) > 0) {
|
||||
StreamSupport.writeShort((short) count, outputBuffer, 0); //Note: count should never exceed the buffer length and thus should stay within two bytes in size.//
|
||||
stream.write(outputBuffer, 0, count + 2);
|
||||
}//while//
|
||||
|
||||
/* Another way of doing the same thing I think.
|
||||
while(!deflater.needsInput()) {
|
||||
int count = deflater.deflate(outputBuffer);
|
||||
|
||||
if(count > 0) {
|
||||
stream.write(outputBuffer, 0, count);
|
||||
}//if//
|
||||
}//while//
|
||||
*/
|
||||
}//deflate()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.IOutputStream#encrypt(boolean)
|
||||
*/
|
||||
public void encrypt(boolean encrypt) throws IOException {
|
||||
if(stream instanceof IOutputStream) {
|
||||
if(((IOutputStream) stream).canEncrypt()) {
|
||||
flush();
|
||||
((IOutputStream) stream).encrypt(encrypt);
|
||||
}//if//
|
||||
else {
|
||||
throw new IOException(ERROR_ENCRYPTION_NOT_SUPPORTED);
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
throw new IOException(ERROR_ENCRYPTION_NOT_SUPPORTED);
|
||||
}//else//
|
||||
}//encrypt()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.OutputStream#flush()
|
||||
*/
|
||||
public void flush() throws IOException {
|
||||
if(deflater.getTotalIn() > 0) {
|
||||
deflater.finish();
|
||||
deflate();
|
||||
deflater.reset();
|
||||
}//if//
|
||||
|
||||
stream.flush();
|
||||
}//flush()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.IOutputStream#isEncrypting()
|
||||
*/
|
||||
public boolean isEncrypting() {
|
||||
return (stream instanceof IOutputStream) && (((IOutputStream) stream).isEncrypting());
|
||||
}//isEncrypting()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.OutputStream#write(byte[])
|
||||
*/
|
||||
public void write(byte[] buffer) throws IOException {
|
||||
write(buffer, 0, buffer.length);
|
||||
}//write()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.OutputStream#write(byte[], int, int)
|
||||
*/
|
||||
public void write(byte[] buffer, int offset, int length) throws IOException {
|
||||
deflater.setInput(buffer, offset, length);
|
||||
deflate();
|
||||
}//write()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.OutputStream#write(int)
|
||||
*/
|
||||
public void write(int b) throws IOException {
|
||||
outputBuffer[0] = (byte) (b & 0xFF);
|
||||
write(outputBuffer, 0, 1);
|
||||
}//write()//
|
||||
}//CompressionOutputStream//
|
||||
209
Common/src/com/common/io/CryptoInputStream.java
Normal file
209
Common/src/com/common/io/CryptoInputStream.java
Normal file
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import com.common.security.*;
|
||||
|
||||
/*
|
||||
* This class allows an symmetricly encrypted stream to be plugged into an input stream so that read bytes are decrypted using the private key.
|
||||
*/
|
||||
public abstract class CryptoInputStream extends java.io.InputStream implements IInputStream {
|
||||
protected InputStream stream = null;
|
||||
protected int decryptionCount;
|
||||
protected byte[] encryptedBuffer = null;
|
||||
protected byte[] decryptedBuffer = null;
|
||||
protected int decryptedBufferOffset = 0;
|
||||
protected int decryptionLength = 0;
|
||||
protected boolean stopFlag = false; //Used to notify the read methods that the encrypted segments have ended and that wrappering streams attempting to buffer should be told there are no more bytes at this time.//
|
||||
/**
|
||||
* CryptoInputStream constructor.
|
||||
*/
|
||||
public CryptoInputStream(InputStream stream, IAlgorithm algorithm) {
|
||||
super();
|
||||
|
||||
if(stream == null) {
|
||||
throw new IllegalArgumentException("Must provide a valid output stream.");
|
||||
}//if//
|
||||
else if(algorithm == null) {
|
||||
throw new IllegalArgumentException("Must provide a valid algorithm.");
|
||||
}//if//
|
||||
|
||||
this.stream = stream;
|
||||
}//CryptoInputStream()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.InputStream#available()
|
||||
*/
|
||||
public int available() throws IOException {
|
||||
return stream.available();
|
||||
}//available()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IInputStream#canDecrypt()
|
||||
*/
|
||||
public boolean canDecrypt() {
|
||||
return true;
|
||||
}//canDecrypt()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.InputStream#close()
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
super.close();
|
||||
stream.close();
|
||||
}//close()//
|
||||
/**
|
||||
* Decrypts or verifies (unsigns) data and strips all padding.
|
||||
* @param data The buffer containing encrypted data.
|
||||
* @param dataOffset The index of the first encrypted byte.
|
||||
* @param dataLength The number of encrypted data bytes.
|
||||
* @param output A buffer to contain the decrypted data.
|
||||
* @param outputOffset The location of the first decrypted byte in the output buffer.
|
||||
* @return The number of bytes decrypted.
|
||||
*/
|
||||
protected abstract int decrypt(byte[] data, int dataOffset, int dataLength, byte[] output, int outputOffset);
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IInputStream#decrypt(boolean)
|
||||
*/
|
||||
public void decrypt(boolean decrypt) throws IOException {
|
||||
if(decrypt) {
|
||||
if(decryptionCount == 0) {
|
||||
refillBuffer();
|
||||
}//if//
|
||||
|
||||
decryptionCount++;
|
||||
}//if//
|
||||
else {
|
||||
decryptionCount--;
|
||||
|
||||
if(decryptionCount == 0) {
|
||||
if(stopFlag) {
|
||||
stopFlag = false;
|
||||
}//if//
|
||||
else if((stream.read() & 0xFF) != 0xF0) {
|
||||
throw new java.io.StreamCorruptedException("Error: Premature decryption completion.");
|
||||
}//else if//
|
||||
}//if//
|
||||
}//else//
|
||||
}//decrypt()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IInputStream#isDecrypting()
|
||||
*/
|
||||
public boolean isDecrypting() {
|
||||
return decryptionCount > 0;
|
||||
}//isDecrypting()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.InputStream#read()
|
||||
*/
|
||||
public int read() throws IOException {
|
||||
int result = -1;
|
||||
|
||||
if(!stopFlag) {
|
||||
if(decryptionCount > 0) {
|
||||
if(decryptedBufferOffset == decryptionLength) {
|
||||
refillBuffer();
|
||||
}//if//
|
||||
|
||||
//The stop flag may be set when we refilled the buffer.//
|
||||
if(!stopFlag) {
|
||||
result = decryptedBuffer[decryptedBufferOffset++];
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
result = stream.read();
|
||||
}//else//
|
||||
}//if//
|
||||
|
||||
return result;
|
||||
}//read()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.InputStream#read(byte[], int, int)
|
||||
*/
|
||||
public int read(byte[] buffer, int offset, int length) throws IOException {
|
||||
int result = -1;
|
||||
|
||||
if(!stopFlag) {
|
||||
if(decryptionCount > 0) {
|
||||
result = 0;
|
||||
|
||||
while((!stopFlag) && (result != length)) {
|
||||
int size = 0;
|
||||
|
||||
if(decryptedBufferOffset == decryptionLength) {
|
||||
refillBuffer();
|
||||
}//if//
|
||||
|
||||
//The stop flag may be set when we refilled the buffer.//
|
||||
if(!stopFlag) {
|
||||
size = decryptionLength - decryptedBufferOffset;
|
||||
|
||||
if(size > length - result) {
|
||||
size = length - result;
|
||||
}//if//
|
||||
|
||||
System.arraycopy(decryptedBuffer, decryptedBufferOffset, buffer, offset + result, size);
|
||||
result += size;
|
||||
decryptedBufferOffset += size;
|
||||
}//if//
|
||||
}//while//
|
||||
|
||||
if(result == 0) {
|
||||
result = -1;
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
result = stream.read(buffer, offset, length);
|
||||
}//else//
|
||||
}//if//
|
||||
|
||||
return result;
|
||||
}//read()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IInputStream#read(java.io.OutputStream, int)
|
||||
*/
|
||||
public int read(java.io.OutputStream out, int length) throws IOException {
|
||||
int result = 0;
|
||||
byte[] bytes = new byte[length];
|
||||
|
||||
result = stream.read(bytes, 0, bytes.length);
|
||||
out.write(bytes, 0, result);
|
||||
|
||||
return result;
|
||||
}//read()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.InputStream#read()
|
||||
*/
|
||||
private boolean refillBuffer() throws IOException {
|
||||
boolean result = !stopFlag;
|
||||
|
||||
if(!stopFlag) {
|
||||
int flag = (stream.read() & 0xFF);
|
||||
|
||||
if(flag == 0xF0) {
|
||||
//Sometimes a wrappering stream will try to buffer beyond the encrypted segment. In such cases we will stop reading until the decryption flag is turned off.//
|
||||
stopFlag = true;
|
||||
result = false;
|
||||
}//if//
|
||||
else if(flag == 0xFF) {
|
||||
int size = StreamSupport.readInt(stream);
|
||||
int count = stream.read(encryptedBuffer, 0, size);
|
||||
|
||||
if(count != size) {
|
||||
throw new IOException("Error: Invalid read length.");
|
||||
}//if//
|
||||
|
||||
decryptionLength = decrypt(encryptedBuffer, 0, count, decryptedBuffer, 0);
|
||||
decryptedBufferOffset = 0;
|
||||
}//else if//
|
||||
else {
|
||||
throw new IOException("Stream corruption found while decrypting.");
|
||||
}//else//
|
||||
}//if//
|
||||
|
||||
return result;
|
||||
}//refillBuffer()//
|
||||
}//CryptoInputStream//
|
||||
166
Common/src/com/common/io/CryptoOutputStream.java
Normal file
166
Common/src/com/common/io/CryptoOutputStream.java
Normal file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (c) 2003,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
import com.common.security.*;
|
||||
|
||||
/*
|
||||
* This class allows an asymmetric stream to be plugged into an output stream so that written bytes are encrypted using the public key.
|
||||
*/
|
||||
public abstract class CryptoOutputStream extends OutputStream implements IOutputStream {
|
||||
protected OutputStream stream = null;
|
||||
protected int encryptionCount;
|
||||
protected byte[] encryptedBuffer = null;
|
||||
protected byte[] decryptedBuffer = null;
|
||||
protected int decryptedBufferOffset = 0;
|
||||
/**
|
||||
* CryptoOutputStream constructor.
|
||||
*/
|
||||
public CryptoOutputStream(OutputStream stream, IAlgorithm algorithm) {
|
||||
super();
|
||||
|
||||
if(stream == null) {
|
||||
throw new IllegalArgumentException("Must provide a valid output stream.");
|
||||
}//if//
|
||||
else if(algorithm == null) {
|
||||
throw new IllegalArgumentException("Must provide a valid algorithm.");
|
||||
}//if//
|
||||
|
||||
this.stream = stream;
|
||||
}//CryptoOutputStream()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IOutputStream#canEncrypt()
|
||||
*/
|
||||
public boolean canEncrypt() {
|
||||
return true;
|
||||
}//canEncrypt()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.OutputStream#close()
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
while(isEncrypting()) {
|
||||
encrypt(false);
|
||||
}//while//
|
||||
|
||||
super.close();
|
||||
stream.close();
|
||||
}//close()//
|
||||
/**
|
||||
* Empties the buffer containing to-be encrypted data.
|
||||
*/
|
||||
protected void emptyBuffer() throws IOException {
|
||||
if(decryptedBufferOffset > 0) {
|
||||
int size = encrypt(decryptedBuffer, 0, decryptedBufferOffset, encryptedBuffer, 0);
|
||||
|
||||
//Write the block header.//
|
||||
stream.write(0xFF);
|
||||
//Write the encrypted size.//
|
||||
StreamSupport.writeInt(size, stream);
|
||||
//Write the block data.//
|
||||
stream.write(encryptedBuffer, 0, size);
|
||||
//Reset the block indexes.//
|
||||
decryptedBufferOffset = 0;
|
||||
}//if//
|
||||
}//emptyBuffer()//
|
||||
/**
|
||||
* Encrypts or signs the data.
|
||||
* @param data The buffer containing unencrypted data.
|
||||
* @param dataOffset The index of the first unencrypted byte.
|
||||
* @param dataLength The number of unencrypted data bytes.
|
||||
* @param output A buffer to contain the encrypted data.
|
||||
* @param outputOffset The location of the first encrypted byte in the output buffer.
|
||||
* @return The number of encrypted bytes (includes formatting and padding).
|
||||
*/
|
||||
protected abstract int encrypt(byte[] data, int dataOffset, int dataLength, byte[] output, int outputOffset);
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IOutputStream#encrypt(boolean)
|
||||
*/
|
||||
public void encrypt(boolean encrypt) throws IOException {
|
||||
if(encrypt) {
|
||||
//Flush any unencrypted data before beginning an encrypted segment.//
|
||||
if(encryptionCount == 0) {
|
||||
//TODO: Should flush data from all wrappering streams. This isn't possible with the current "pipe" design pattern for streams.//
|
||||
}//if//
|
||||
|
||||
encryptionCount++;
|
||||
}//if//
|
||||
else {
|
||||
encryptionCount--;
|
||||
|
||||
if(encryptionCount == 0) {
|
||||
//TODO: Should flush data from all wrappering streams. This isn't possible with the current "pipe" design pattern for streams.//
|
||||
//Empty the buffer and end the encrypted segment.//
|
||||
emptyBuffer();
|
||||
stream.write(0xF0);
|
||||
}//if//
|
||||
}//else//
|
||||
}//encrypt()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.OutputStream#flush()
|
||||
*/
|
||||
public void flush() throws IOException {
|
||||
/* This could cause a lot of unnecessary padding.
|
||||
if(encryptionCount > 0) {
|
||||
emptyBuffer();
|
||||
}//if//
|
||||
*/
|
||||
stream.flush();
|
||||
}//flush()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IOutputStream#isEncrypting()
|
||||
*/
|
||||
public boolean isEncrypting() {
|
||||
return encryptionCount > 0;
|
||||
}//isEncrypting()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.OutputStream#write(byte[], int, int)
|
||||
*/
|
||||
public void write(byte[] buffer, int offset, int length) throws IOException {
|
||||
if(encryptionCount > 0) {
|
||||
int count = 0;
|
||||
|
||||
while(count != length) {
|
||||
int size = 0;
|
||||
|
||||
if(decryptedBufferOffset == decryptedBuffer.length) {
|
||||
emptyBuffer();
|
||||
}//if//
|
||||
|
||||
size = decryptedBuffer.length - decryptedBufferOffset;
|
||||
|
||||
if(size > length - count) {
|
||||
size = length - count;
|
||||
}//if//
|
||||
|
||||
System.arraycopy(buffer, offset + count, decryptedBuffer, decryptedBufferOffset, size);
|
||||
count += size;
|
||||
decryptedBufferOffset += size;
|
||||
}//while//
|
||||
}//if//
|
||||
else {
|
||||
stream.write(buffer, offset, length);
|
||||
}//else//
|
||||
}//write()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.OutputStream#write(int)
|
||||
*/
|
||||
public void write(int b) throws IOException {
|
||||
if(encryptionCount > 0) {
|
||||
if(decryptedBufferOffset == decryptedBuffer.length) {
|
||||
emptyBuffer();
|
||||
}//if//
|
||||
|
||||
decryptedBuffer[decryptedBufferOffset++] = (byte) b;
|
||||
}//if//
|
||||
else {
|
||||
stream.write(b);
|
||||
}//else//
|
||||
}//write()//
|
||||
}//CryptoOutputStream//
|
||||
80
Common/src/com/common/io/FileSupport.java
Normal file
80
Common/src/com/common/io/FileSupport.java
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2006,2007 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
|
||||
import com.common.debug.Debug;
|
||||
import com.common.security.IHashAlgorithm;
|
||||
import com.common.util.StringSupport;
|
||||
|
||||
public class FileSupport {
|
||||
/**
|
||||
* FileSupport constructor.
|
||||
*/
|
||||
private FileSupport() {
|
||||
super();
|
||||
}//FileSupport()//
|
||||
/**
|
||||
* Gets the hash of the given file.
|
||||
* @param file The file whose contents will be hashed.
|
||||
* @param hashAlgorithm The hash algorithm to use.
|
||||
* @return The hash of the file.
|
||||
*/
|
||||
public static String getFileHash(File file, IHashAlgorithm hashAlgorithm) {
|
||||
try {
|
||||
FileInputStream fin = new FileInputStream(file);
|
||||
int available = fin.available();
|
||||
byte[] bytes = new byte[available > 100000 ? 100000 : available];
|
||||
int readCount = 0;
|
||||
|
||||
hashAlgorithm.reset();
|
||||
|
||||
while(readCount < available) {
|
||||
int read = fin.read(bytes, 0, available - readCount > bytes.length ? bytes.length : available - readCount);
|
||||
|
||||
readCount += read;
|
||||
hashAlgorithm.add(bytes, 0, read);
|
||||
}//while//
|
||||
|
||||
fin.close();
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
Debug.log(e);
|
||||
}//catch//
|
||||
|
||||
return StringSupport.toHexString(hashAlgorithm.hash());
|
||||
}//getFileHash()//
|
||||
/**
|
||||
* Gets the contents of the given file.
|
||||
* @param file The file whose contents will be retrieved.
|
||||
* @return The contents of the file or null if there was a problem.
|
||||
*/
|
||||
public static byte[] getFileContents(File file) {
|
||||
byte[] result = null;
|
||||
|
||||
try {
|
||||
FileInputStream fin = new FileInputStream(file);
|
||||
int readCount = 0;
|
||||
|
||||
result = new byte[fin.available()];
|
||||
|
||||
while(readCount < result.length) {
|
||||
readCount += fin.read(result, readCount, result.length - readCount);
|
||||
}//while//
|
||||
|
||||
fin.close();
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
Debug.log(e);
|
||||
}//catch//
|
||||
|
||||
return result;
|
||||
}//getFileHash()//
|
||||
}//FileSupport//
|
||||
188
Common/src/com/common/io/HashedInputStream.java
Normal file
188
Common/src/com/common/io/HashedInputStream.java
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import com.common.security.*;
|
||||
|
||||
/**
|
||||
* Maintains a hash of all streamed data and automates validating the hash with a hash embedded in the stream.
|
||||
*/
|
||||
public class HashedInputStream extends java.io.InputStream implements IInputStream {
|
||||
private InputStream stream = null;
|
||||
private IHashAlgorithm algorithm = null;
|
||||
private boolean isHashing = false;
|
||||
private byte[] oneByte = new byte[1];
|
||||
/**
|
||||
* HashedInputStream constructor.
|
||||
* <p>Note: The hashed input stream will default to hash all streamed data. Call hash(boolean) to turn hashing on and off.</p>
|
||||
* @param stream The input stream to retrieve data from.
|
||||
* @param algorithm The hashing algorithm to be used.
|
||||
*/
|
||||
public HashedInputStream(InputStream stream, IHashAlgorithm algorithm) {
|
||||
super();
|
||||
|
||||
this.stream = stream;
|
||||
this.algorithm = algorithm;
|
||||
this.isHashing = true;
|
||||
}//HashedInputStream()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IInputStream#canDecrypt()
|
||||
*/
|
||||
public boolean canDecrypt() {
|
||||
return (stream instanceof IInputStream) && (((IInputStream) stream).canDecrypt());
|
||||
}//canDecrypt()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.InputStream#close()
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
super.close();
|
||||
stream.close();
|
||||
}//close()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IInputStream#decrypt(boolean)
|
||||
*/
|
||||
public void decrypt(boolean decrypt) throws IOException {
|
||||
if(stream instanceof IInputStream) {
|
||||
if(((IInputStream) stream).canDecrypt()) {
|
||||
((IInputStream) stream).decrypt(decrypt);
|
||||
}//if//
|
||||
else {
|
||||
throw new IOException(ERROR_DECRYPTION_NOT_SUPPORTED);
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
throw new IOException(ERROR_DECRYPTION_NOT_SUPPORTED);
|
||||
}//else//
|
||||
}//decrypt()//
|
||||
/**
|
||||
* Gets the hash of all data streamed while we were hashing.
|
||||
* <p>Note: Calling this method will reset the hashing algorithm but will not turn hashing off.</p>
|
||||
* @return The hash or null if hashing is not on.
|
||||
*/
|
||||
public byte[] getHash() {
|
||||
byte[] retVal = null;
|
||||
|
||||
if(isHashing) {
|
||||
retVal = algorithm.hash();
|
||||
algorithm.reset();
|
||||
}//if//
|
||||
|
||||
return retVal;
|
||||
}//getHash()//
|
||||
/**
|
||||
* Begins or ends hashing streamed data. Ending hashing does not reset the hash and hashing can resume at a later time.
|
||||
* @param hash Whether to hash read data.
|
||||
* @throws IOException Thrown if the stream is told to hash or stop hashing twice in a row.
|
||||
*/
|
||||
public void hash(boolean hash) throws IOException {
|
||||
if(isHashing == hash) {
|
||||
throw new IOException("Cannot start or end hashing twice.");
|
||||
}//if//
|
||||
|
||||
isHashing = hash;
|
||||
}//getHash()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IInputStream#isDecrypting()
|
||||
*/
|
||||
public boolean isDecrypting() {
|
||||
return (stream instanceof IInputStream) && (((IInputStream) stream).isDecrypting());
|
||||
}//isDecrypting()//
|
||||
/**
|
||||
* Determines whether the data read from the stream is being hashed.
|
||||
* @return Whether the stream is currently being hashed.
|
||||
*/
|
||||
public boolean isHashing() {
|
||||
return isHashing;
|
||||
}//isHashing()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.InputStream#read()
|
||||
*/
|
||||
public int read() throws IOException {
|
||||
int retVal = stream.read();
|
||||
|
||||
if(isHashing) {
|
||||
oneByte[0] = (byte) retVal;
|
||||
algorithm.add(oneByte);
|
||||
}//if//
|
||||
|
||||
return retVal;
|
||||
}//read()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.InputStream#read(byte[], int, int)
|
||||
*/
|
||||
public int read(byte[] buffer, int offset, int length) throws IOException {
|
||||
int retVal = stream.read(buffer, offset, length);
|
||||
|
||||
if(isHashing) {
|
||||
algorithm.add(buffer, offset, length);
|
||||
}//if//
|
||||
|
||||
return retVal;
|
||||
}//read()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IInputStream#read(java.io.OutputStream, int)
|
||||
*/
|
||||
public int read(java.io.OutputStream out, int length) throws IOException {
|
||||
int retVal = 0;
|
||||
byte[] bytes = new byte[length];
|
||||
|
||||
retVal = stream.read(bytes, 0, bytes.length);
|
||||
out.write(bytes, 0, retVal);
|
||||
|
||||
return retVal;
|
||||
}//read()//
|
||||
/**
|
||||
* Reads a hash from the stream. This is useful if the application will manually check the hashes.
|
||||
* <p>In most cases the hash embedded in the stream will be signed or encrypted. If such is the case the application should enable decryption before calling this method.</p>
|
||||
* <p>Note: This does not reset the hash algorithm and does not automatically stop the stream hashing.</p>
|
||||
* @return The read hash value.
|
||||
* @see java.io.InputStream#read()
|
||||
*/
|
||||
public byte[] readHash() throws IOException {
|
||||
byte[] hash = null;
|
||||
|
||||
hash = new byte[(int) (StreamSupport.readShort(stream) & 0xFFFF)];
|
||||
read(hash, 0, hash.length);
|
||||
|
||||
return hash;
|
||||
}//read()//
|
||||
/**
|
||||
* Validates the stream by comparing the stream hash to the hash embedded in the stream.
|
||||
* <p>In most cases the hash embedded in the stream will be signed or encrypted. If such is the case the application should enable decryption before calling this method.</p>
|
||||
* <p>Note: This does reset the hash algorithm and will automatically pause all hashing to get a valid comparison.</p>
|
||||
* @return Whether a valid hash was read from the input stream.
|
||||
*/
|
||||
public boolean validateHash() throws IOException {
|
||||
boolean flag = isHashing;
|
||||
byte[] readHash = null;
|
||||
byte[] inputHash = getHash();
|
||||
boolean isValid = true;
|
||||
|
||||
algorithm.reset();
|
||||
isHashing = false;
|
||||
readHash = new byte[(int) (StreamSupport.readShort(stream) & 0xFFFF)];
|
||||
read(readHash, 0, readHash.length);
|
||||
isHashing = flag;
|
||||
|
||||
//Validate the hashes.//
|
||||
if(inputHash.length == readHash.length) {
|
||||
for(int index = 0; ((isValid) && (index < inputHash.length)); index++) {
|
||||
if(readHash[index] != inputHash[index]) {
|
||||
isValid = false;
|
||||
}//if//
|
||||
}//for//
|
||||
}//if//
|
||||
else {
|
||||
isValid = false;
|
||||
}//else//
|
||||
|
||||
return isValid;
|
||||
}//read()//
|
||||
}//HashedInputStream//
|
||||
147
Common/src/com/common/io/HashedOutputStream.java
Normal file
147
Common/src/com/common/io/HashedOutputStream.java
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
import com.common.security.*;
|
||||
|
||||
/**
|
||||
* Maintains a hash of all streamed data and automates the embedding of the hash in the stream.
|
||||
*/
|
||||
public class HashedOutputStream extends OutputStream implements IOutputStream {
|
||||
private OutputStream stream = null;
|
||||
private IHashAlgorithm algorithm = null;
|
||||
private boolean isHashing = false;
|
||||
private byte[] oneByte = new byte[1];
|
||||
/**
|
||||
* HashedOutputStream constructor.
|
||||
* <p>Note: The hashed output stream will default to hash all streamed data. Call hash(boolean) to turn hashing on and off.</p>
|
||||
* @param stream The output stream to send all streamed data to.
|
||||
* @param algorithm The hashing algorithm to be used.
|
||||
*/
|
||||
public HashedOutputStream(OutputStream stream, IHashAlgorithm algorithm) {
|
||||
super();
|
||||
|
||||
this.stream = stream;
|
||||
this.algorithm = algorithm;
|
||||
this.isHashing = true;
|
||||
}//HashedOutputStream()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IOutputStream#canEncrypt()
|
||||
*/
|
||||
public boolean canEncrypt() {
|
||||
return (stream instanceof IOutputStream) && (((IOutputStream) stream).canEncrypt());
|
||||
}//canEncrypt()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.OutputStream#close()
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
super.close();
|
||||
stream.close();
|
||||
}//close()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IOutputStream#encrypt(boolean)
|
||||
*/
|
||||
public void encrypt(boolean encrypt) throws IOException {
|
||||
if(stream instanceof IOutputStream) {
|
||||
if(((IOutputStream) stream).canEncrypt()) {
|
||||
flush();
|
||||
((IOutputStream) stream).encrypt(encrypt);
|
||||
}//if//
|
||||
else {
|
||||
throw new IOException(ERROR_ENCRYPTION_NOT_SUPPORTED);
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
throw new IOException(ERROR_ENCRYPTION_NOT_SUPPORTED);
|
||||
}//else//
|
||||
}//encrypt()//
|
||||
/**
|
||||
* Flushes this output stream and the encapsulated output stream.
|
||||
*/
|
||||
public void flush() throws IOException {
|
||||
stream.flush();
|
||||
}//flush()//
|
||||
/**
|
||||
* Gets the hash of all data streamed while we were hashing.
|
||||
* <p>Note: Calling this method will reset the hashing algorithm but will not turn hashing off.</p>
|
||||
* @return The hash or null if hashing is not on.
|
||||
*/
|
||||
public byte[] getHash() {
|
||||
byte[] retVal = null;
|
||||
|
||||
if(isHashing) {
|
||||
retVal = algorithm.hash();
|
||||
algorithm.reset();
|
||||
}//if//
|
||||
|
||||
return retVal;
|
||||
}//getHash()//
|
||||
/**
|
||||
* Begins or ends hashing streamed data. Ending hashing does not reset the hash and hashing can resume at a later time.
|
||||
* @param hash Whether to hash read data.
|
||||
* @throws IOException Thrown if the stream is told to hash or stop hashing twice in a row.
|
||||
*/
|
||||
public void hash(boolean hash) throws IOException {
|
||||
if(isHashing == hash) {
|
||||
throw new IOException("Cannot start or end hashing twice.");
|
||||
}//if//
|
||||
|
||||
isHashing = hash;
|
||||
}//getHash()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IOutputStream#isEncrypting()
|
||||
*/
|
||||
public boolean isEncrypting() {
|
||||
return (stream instanceof IOutputStream) && (((IOutputStream) stream).isEncrypting());
|
||||
}//isEncrypting()//
|
||||
/**
|
||||
* Determines whether the data read from the stream is being hashed.
|
||||
* @return Whether the stream is currently being hashed.
|
||||
*/
|
||||
public boolean isHashing() {
|
||||
return isHashing;
|
||||
}//isHashing()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.OutputStream#write(byte[], int, int)
|
||||
*/
|
||||
public void write(byte[] buffer, int offset, int length) throws IOException {
|
||||
stream.write(buffer, offset, length);
|
||||
|
||||
if(isHashing) {
|
||||
algorithm.add(buffer, offset, length);
|
||||
}//if//
|
||||
}//write()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.OutputStream#write(int)
|
||||
*/
|
||||
public void write(int b) throws IOException {
|
||||
stream.write(b);
|
||||
|
||||
if(isHashing) {
|
||||
oneByte[0] = (byte) b;
|
||||
algorithm.add(oneByte);
|
||||
}//if//
|
||||
}//write()//
|
||||
/**
|
||||
* Gets the hash of all data streamed while we were hashing.
|
||||
* <p>Note: Calling this method will reset the hashing algorithm but will not turn hashing off.</p>
|
||||
* @return The hash or null if hashing is not on.
|
||||
*/
|
||||
public void writeHash() throws IOException {
|
||||
byte[] hash = algorithm.hash();
|
||||
boolean flag = isHashing;
|
||||
|
||||
algorithm.reset();
|
||||
isHashing = false;
|
||||
StreamSupport.writeShort((short) hash.length, this);
|
||||
write(hash, 0, hash.length);
|
||||
isHashing = flag;
|
||||
}//getHash()//
|
||||
}//HashedOutputStream//
|
||||
69
Common/src/com/common/io/HexInputStream.java
Normal file
69
Common/src/com/common/io/HexInputStream.java
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2006,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class HexInputStream extends InputStream {
|
||||
/** The input stream to read hex codes from. */
|
||||
private InputStream in = null;
|
||||
/**
|
||||
* HexInputStream constructor.
|
||||
*/
|
||||
public HexInputStream(InputStream in) {
|
||||
super();
|
||||
}//HexInputStream()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.InputStream#read()
|
||||
*/
|
||||
public int read() throws IOException {
|
||||
return ((0x0F & in.read()) << 4) | (0x0F & in.read());
|
||||
}//read()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.InputStream#read(byte[], int, int)
|
||||
*/
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
int readCount = 0;
|
||||
|
||||
for(int index = off; index + off < len; index++) {
|
||||
int high = in.read();
|
||||
int low = in.read();
|
||||
|
||||
if(high != -1 && low != -1) {
|
||||
b[index] = (byte) (((0x0F & high) << 4) | (0x0F & low));
|
||||
readCount++;
|
||||
}//if//
|
||||
else {
|
||||
break;
|
||||
}//else//
|
||||
}//for//
|
||||
|
||||
return readCount;
|
||||
}//read()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.InputStream#read(byte[])
|
||||
*/
|
||||
public int read(byte[] b) throws IOException {
|
||||
int readCount = 0;
|
||||
|
||||
while(readCount < b.length) {
|
||||
int high = in.read();
|
||||
int low = in.read();
|
||||
|
||||
if(high != -1 && low != -1) {
|
||||
b[readCount++] = (byte) (((0x0F & high) << 4) | (0x0F & low));
|
||||
}//if//
|
||||
else {
|
||||
break;
|
||||
}//else//
|
||||
}//while//
|
||||
|
||||
return readCount;
|
||||
}//read()//
|
||||
}//HexInputStream//
|
||||
51
Common/src/com/common/io/HexOutputStream.java
Normal file
51
Common/src/com/common/io/HexOutputStream.java
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2006,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/*
|
||||
* Converts all bytes written to the stream into hexidecimal codes.
|
||||
*/
|
||||
public class HexOutputStream extends OutputStream {
|
||||
/** The output stream to send the hexidecimal values to. */
|
||||
private OutputStream out = null;
|
||||
/**
|
||||
* HexOutputStream constructor.
|
||||
*/
|
||||
public HexOutputStream(OutputStream out) {
|
||||
super();
|
||||
this.out = out;
|
||||
}//HexOutputStream()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.OutputStream#write(int)
|
||||
*/
|
||||
public void write(int b) throws IOException {
|
||||
out.write((b >> 4) & 0x0F);
|
||||
out.write(b & 0x0F);
|
||||
}//write()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.OutputStream#write(byte[], int, int)
|
||||
*/
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
for(int index = off; index + off < len; index++) {
|
||||
out.write((b[index] >> 4) & 0x0F);
|
||||
out.write(b[index] & 0x0F);
|
||||
}//for//
|
||||
}//write()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.OutputStream#write(byte[])
|
||||
*/
|
||||
public void write(byte[] b) throws IOException {
|
||||
for(int index = 0; index < b.length; index++) {
|
||||
out.write((b[index] >> 4) & 0x0F);
|
||||
out.write(b[index] & 0x0F);
|
||||
}//for//
|
||||
}//write()//
|
||||
}//HexOutputStream//
|
||||
17
Common/src/com/common/io/IClassReplacementHandler.java
Normal file
17
Common/src/com/common/io/IClassReplacementHandler.java
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (c) 2008,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
public interface IClassReplacementHandler {
|
||||
/**
|
||||
* Allows the caller to receive an alternate name for the given class name.
|
||||
* @param className The name of the class as read by the stream.
|
||||
* @return The replacement class name to be used by the stream.
|
||||
*/
|
||||
public String getReplacementClassName(String className);
|
||||
}//IClassReplacementHandler//
|
||||
16
Common/src/com/common/io/IClassTracker.java
Normal file
16
Common/src/com/common/io/IClassTracker.java
Normal file
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
public interface IClassTracker {
|
||||
/**
|
||||
* Adds the class name to the collection being tracked.
|
||||
* @param className The class name to be kept track of.
|
||||
*/
|
||||
public void add(String className);
|
||||
}//IClassTracker//
|
||||
23
Common/src/com/common/io/IExternalizable.java
Normal file
23
Common/src/com/common/io/IExternalizable.java
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
public interface IExternalizable {
|
||||
public static final Object NULL_VALUE = new Object();
|
||||
/**
|
||||
* Reads this object from the given stream.
|
||||
* @param in The input stream to read this object from.
|
||||
* @return The replacement object if applicable. Allows the read object to replace its self with an alternate. Useful if the object already exists as an identifier somewhere. If null then the stream will assume this instance is the result.
|
||||
*/
|
||||
public Object readExternal(IObjectInputStream in) throws java.io.IOException, ClassNotFoundException;
|
||||
/**
|
||||
* Writes this object to the given stream.
|
||||
* @param out The output stream to write this object to.
|
||||
*/
|
||||
public void writeExternal(IObjectOutputStream out) throws java.io.IOException;
|
||||
}//IExternalizable//
|
||||
42
Common/src/com/common/io/IInputStream.java
Normal file
42
Common/src/com/common/io/IInputStream.java
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Defines some common functionality associated with advanced streams.
|
||||
* Implementors can implement some or all of the functionality and users can determine whether an aggregate stream supports the functionality it requires.
|
||||
*/
|
||||
public interface IInputStream {
|
||||
public static final String ERROR_DECRYPTION_NOT_SUPPORTED = "Underlying stream does not provide decryption facilities. Please make sure that this (or the aggregate) stream supports decryption before calling this method.";
|
||||
/**
|
||||
* Determines whether the stream is capable of decrypting parts or all of the message.
|
||||
* @return Whether the data stream is capable of decryption.
|
||||
*/
|
||||
public boolean canDecrypt();
|
||||
/**
|
||||
* Starts or stops decrypting the message from the current index within the stream.
|
||||
* <p>Warning: The input stream does not have to support this functionality. A MethodNotSupportedException will be thrown if the functionality is not supported.
|
||||
* @param decrypt Whether to start or stop decrypting. This method call should occur at the same points in the stream as the calls were made in the output stream.
|
||||
* @see #canDecrypt()
|
||||
*/
|
||||
public void decrypt(boolean decrypt) throws IOException;
|
||||
/**
|
||||
* Determines whether the stream is currently decrypting the part or all of the message being read.
|
||||
* @return Whether the data stream is currently being decrypted.
|
||||
*/
|
||||
public boolean isDecrypting();
|
||||
/**
|
||||
* Reads bytes from this stream and places them into the supplied output stream.
|
||||
* @param out The output stream to write the read bytes to.
|
||||
* @param length The number of bytes to read from the stream.
|
||||
* @return The number of bytes read from the stream.
|
||||
*/
|
||||
public int read(java.io.OutputStream out, int length) throws IOException;
|
||||
}//IInputStream//
|
||||
21
Common/src/com/common/io/IInstanceFactory.java
Normal file
21
Common/src/com/common/io/IInstanceFactory.java
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) 2002,2008 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
/**
|
||||
* Provides for instance creation for streams requiring an instance of a class where the class is defined by the application.
|
||||
* <p>Most streams allow an instance factory to provide customized behavior when the default behavior is not acceptable.</p>
|
||||
*/
|
||||
public interface IInstanceFactory {
|
||||
/**
|
||||
* Creates an uninitialized instance of the given class. The method should only throw an InstantiationException if the caller does not want the user to locate the class via other means.
|
||||
* @param clazz The class to create an instance of.
|
||||
* @return The instance created, or null if an instance was not createable.
|
||||
*/
|
||||
public Object createInstance(Class clazz) throws InstantiationException;
|
||||
}//IInstanceFactory//
|
||||
50
Common/src/com/common/io/IObjectInputStream.java
Normal file
50
Common/src/com/common/io/IObjectInputStream.java
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import com.common.util.IList;
|
||||
|
||||
public interface IObjectInputStream extends IStandardInputStream, java.io.ObjectInput {
|
||||
/**
|
||||
* Gets the optional factory that generates class instances.
|
||||
* @return A factory that will produce an instance of the given class. If provided, this will be used instead of calling Class.newInstance().
|
||||
*/
|
||||
public IInstanceFactory getInstanceFactory();
|
||||
/**
|
||||
* Gets the optional class tracker which will be notified when a class is used.
|
||||
* @return The class tracker is notified every time a class is referenced by the stream. It allows the application to track what classes are utilized by the streams.
|
||||
*/
|
||||
public IClassTracker getClassTracker();
|
||||
/**
|
||||
* Gets the collection of Class instances ordered by the index the stream will reference them by furthor on in the stream.
|
||||
* <p>Warning: This is provided to allow sub-streams. Modifying this value out of context will cause stream corruption errors.</p>
|
||||
* @return The list of classes that were serialized indexed by the number the stream will use to reference them in the future.
|
||||
*/
|
||||
public IList getClassList();
|
||||
/**
|
||||
* Gets the optional class loader used to obtain a Class instance given a class name.
|
||||
* @return The optional class loader which is used if provided to lookup the class names.
|
||||
*/
|
||||
public ClassLoader getLoader();
|
||||
/**
|
||||
* Gets the collection of previously deserialized objects indexed by the number used in the stream to reference recursively.
|
||||
* <p>Warning: This is provided to allow sub-streams. Modifying this value out of context will cause stream corruption errors.</p>
|
||||
* @return The collection of objects deserialized in order of deserialization. Used to reference previously deserialized values by number in the stream to prevent recursive references from bloating the stream.
|
||||
*/
|
||||
public IList getDeserializedValues();
|
||||
/**
|
||||
* Gets the optional class replacement handler which if provided will always be called upon to alter the stream specified class name with another equivalent name prior to class lookup.
|
||||
* @return Called prior to looking up the deserialized class name - allows replacement of the class name.
|
||||
*/
|
||||
public IClassReplacementHandler getClassReplacementHandler();
|
||||
/**
|
||||
* Gets the optional stream manager which allows a class to be swapped for another at runtime if the original class cannot be identified.
|
||||
* @return Allows the input stream to replace one class with another <b>if the original class cannot be found</b>.
|
||||
*/
|
||||
public IStreamManager getStreamManager();
|
||||
}//IObjectInputStream//
|
||||
32
Common/src/com/common/io/IObjectOutputStream.java
Normal file
32
Common/src/com/common/io/IObjectOutputStream.java
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import com.common.util.IHashMap;
|
||||
import com.common.util.IList;
|
||||
import com.common.util.optimized.ObjectIntHashMap;
|
||||
|
||||
public interface IObjectOutputStream extends IStandardOutputStream, java.io.ObjectOutput {
|
||||
/**
|
||||
* Gets the mapping of serialized object's index number by the object that was serialized.
|
||||
* <p>Warning: This is provided to allow sub-streams. Modifying this value out of context will cause stream corruption errors.</p>
|
||||
* @return The mapping that allows a previously serialized object to be replaced by a number thus avoiding infinate loops and compressing the stream.
|
||||
*/
|
||||
public ObjectIntHashMap getSerializedObjectMap();
|
||||
/**
|
||||
* Gets the mapping of class names to index such that the index can be used in place of the class name in the stream.
|
||||
* <p>Warning: This is provided to allow sub-streams. Modifying this value out of context will cause stream corruption errors.</p>
|
||||
* @return The mapping that allows a previously serialized class name to be replaced by a number.
|
||||
*/
|
||||
public IHashMap getClassMap();
|
||||
/**
|
||||
* Gets the handler that will be called to swap one class with another.
|
||||
* @return The optional handler that performs class replacment.
|
||||
*/
|
||||
public IClassReplacementHandler getClassReplacementHandler();
|
||||
}//IObjectOutputStream//
|
||||
39
Common/src/com/common/io/IObjectStream.java
Normal file
39
Common/src/com/common/io/IObjectStream.java
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2006 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
/**
|
||||
* Defines some basic identifiers and values used by the object streams.
|
||||
*/
|
||||
public interface IObjectStream {
|
||||
//Stream identifiers.//
|
||||
public static final byte OBJECT = -1;
|
||||
public static final byte RECURSIVE_OBJECT = -2;
|
||||
public static final byte UNKNOWN_OBJECT = -3;
|
||||
public static final byte NULL = -4;
|
||||
public static final byte PRIMITIVE_ARRAY = -5;
|
||||
public static final byte ARRAY = -6;
|
||||
public static final byte CUSTOM_OBJECT = -7;
|
||||
//Optimized object types.//
|
||||
public static final byte BOOLEAN = 0;
|
||||
public static final byte BYTE = 1;
|
||||
public static final byte CHARACTER = 2;
|
||||
public static final byte SHORT = 3;
|
||||
public static final byte INTEGER = 4;
|
||||
public static final byte LONG = 5;
|
||||
public static final byte FLOAT = 6;
|
||||
public static final byte DOUBLE = 7;
|
||||
public static final byte STRING = 8;
|
||||
public static final byte CLASS = 9;
|
||||
public static final byte UTF8 = 10;
|
||||
public static final byte SHARED_BOOLEAN = 11;
|
||||
public static final byte LAST_OPTIMIZED_TYPE_NUMBER = 11;
|
||||
|
||||
public static final String STRING_FORMAT_UTF8 = StreamSupport.STRING_FORMAT_UTF8;
|
||||
public static final String STRING_FORMAT_UNICODE = StreamSupport.STRING_FORMAT_UNICODE;
|
||||
}//IObjectStream//
|
||||
34
Common/src/com/common/io/IOutputStream.java
Normal file
34
Common/src/com/common/io/IOutputStream.java
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2003,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Specifies methods provided by all output streams defined in this package.
|
||||
*/
|
||||
public interface IOutputStream {
|
||||
public static final String ERROR_ENCRYPTION_NOT_SUPPORTED = "Underlying stream does not provide encryption facilities. Please make sure that this (or the aggregate) stream supports encryption before calling this method.";
|
||||
/**
|
||||
* Determines whether the stream is capable of encrypting parts or all of the message.
|
||||
* @return Whether the data stream is capable of encryption.
|
||||
*/
|
||||
public boolean canEncrypt();
|
||||
/**
|
||||
* Starts or stops encrypting the message at the current index within the stream.
|
||||
* <p>Warning: The output stream does not have to support this functionality. A MethodNotSupportedException will be thrown if the functionality is not supported.
|
||||
* @param encrypt Whether to start or stop encrypting.
|
||||
* @see #canEncrypt()
|
||||
*/
|
||||
public void encrypt(boolean encrypt) throws IOException;
|
||||
/**
|
||||
* Determines whether the stream is currently encrypting the part or all of the message being written.
|
||||
* @return Whether the data stream is currently being encrypted.
|
||||
*/
|
||||
public boolean isEncrypting();
|
||||
}//IOutputStream//
|
||||
18
Common/src/com/common/io/IOutputStreamLocation.java
Normal file
18
Common/src/com/common/io/IOutputStreamLocation.java
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
public interface IOutputStreamLocation {
|
||||
/**
|
||||
* Gets the stream index of the location in the stream when this object was created.
|
||||
* This value will change if there is an update location object that the users writes data to (unless it has reserved space), or if this location is an update location and did not reserve space and writes data.
|
||||
* The location will be the last byte index in the set of values written to the stream, or the index of the stream at the time the location was created (updated if any new bytes were written to the stream at an earlier index).
|
||||
* @return The index within the stream of this location object (or the ending index if the location allows updating).
|
||||
*/
|
||||
public int getByteIndex();
|
||||
}//IOutputStreamLocation//
|
||||
29
Common/src/com/common/io/ISerializationHandler.java
Normal file
29
Common/src/com/common/io/ISerializationHandler.java
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Defines a serialization handler for a specific class of object. This handler will both serialize and deserialize instances of the class.
|
||||
*/
|
||||
public interface ISerializationHandler {
|
||||
/**
|
||||
* Handles the deserialization for the given type from the given stream.
|
||||
* @param object The object to deserialize.
|
||||
* @param in The input stream to deserialize from.
|
||||
* @return The deserialized object.
|
||||
*/
|
||||
public Object deserialize(IObjectInputStream in) throws IOException, ClassNotFoundException;
|
||||
/**
|
||||
* Handles the serialization for the given value to the given stream.
|
||||
* @param value The value to serialize.
|
||||
* @param out The output stream to serialize to.
|
||||
*/
|
||||
public void serialize(Object value, IObjectOutputStream out) throws IOException;
|
||||
}//ISerializationHandler//
|
||||
39
Common/src/com/common/io/IStandardInputStream.java
Normal file
39
Common/src/com/common/io/IStandardInputStream.java
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface IStandardInputStream extends IObjectStream, IInputStream, java.io.DataInput {
|
||||
/**
|
||||
* Gets the number style used by default when deserializing numbers.
|
||||
* @return The number style identifier used by default.
|
||||
*/
|
||||
public int getDefaultNumberStyle();
|
||||
/**
|
||||
* Reads a fixed length string from file removes the unnecessary padding.
|
||||
* @param length The fixed number of bytes in the string.
|
||||
* @return The read string minus all space at the beginning or end of the string.
|
||||
* @exception IOException If an I/O error occurs. In particular, an <code>IOException</code> may be thrown if the input stream has been closed.
|
||||
*/
|
||||
public String readFixedLengthString(int length) throws java.io.IOException;
|
||||
/**
|
||||
* Reads a UTF16 string from the stream.
|
||||
* A UTF16 string is a fixed character size string using 2 bytes for each character.
|
||||
* <p>WARNING: The user must call writeUTF16(String) in the output stream for this method to work properly. The user cannot mix and match string serialization methods.
|
||||
* @return The string read from the stream.
|
||||
*/
|
||||
public String readUTF16() throws IOException;
|
||||
/**
|
||||
* Reads a UTF8 string from the stream.
|
||||
* A UTF8 string is a variable character size string using 1..N bytes for each character. All ASCII characters will use 1 byte, but most european characters will use 2 and some oriental characters will use 3 bytes.
|
||||
* <p>WARNING: The user must call writeUTF8(String) in the output stream for this method to work properly. The user cannot mix and match string serialization methods.
|
||||
* @return The string read from the stream.
|
||||
*/
|
||||
public String readUTF8() throws IOException;
|
||||
}//IObjectInputStream//
|
||||
39
Common/src/com/common/io/IStandardOutputStream.java
Normal file
39
Common/src/com/common/io/IStandardOutputStream.java
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface IStandardOutputStream extends IObjectStream, IOutputStream, java.io.DataOutput {
|
||||
/**
|
||||
* Gets the number style used by default when serializing numbers.
|
||||
* @return The number style identifier used by default.
|
||||
*/
|
||||
public int getDefaultNumberStyle();
|
||||
/**
|
||||
* Writes a fixed length string to file and pads it with spaces where necessary.
|
||||
* @param string The string to write. This string must be under the byte size limit and an IOException will result from an improperly sized string.
|
||||
* @param length The fixed number of bytes in the string.
|
||||
* @exception IOException If an I/O error occurs. In particular, an <code>IOException</code> may be thrown if the output stream has been closed.
|
||||
*/
|
||||
public void writeFixedLengthString(String string, int length) throws java.io.IOException;
|
||||
/**
|
||||
* Writes a UTF16 string to the stream.
|
||||
* A UTF16 string is a fixed character size string using 2 bytes for each character.
|
||||
* <p>WARNING: The user must call readUTF16(String) in the input stream for this method to work properly. The user cannot mix and match string serialization methods.
|
||||
* @param string The string to write to the stream.
|
||||
*/
|
||||
public void writeUTF16(String string) throws IOException;
|
||||
/**
|
||||
* Writes a UTF8 string to the stream.
|
||||
* A UTF8 string is a variable character size string using 1..N bytes for each character. All ASCII characters will use 1 byte, but most european characters will use 2 and some oriental characters will use 3 bytes.
|
||||
* <p>WARNING: The user must call readUTF8(String) in the input stream for this method to work properly. The user cannot mix and match string serialization methods.
|
||||
* @param string The string to write to the stream.
|
||||
*/
|
||||
public void writeUTF8(String string) throws IOException;
|
||||
}//IObjectOutputStream//
|
||||
18
Common/src/com/common/io/IStreamManager.java
Normal file
18
Common/src/com/common/io/IStreamManager.java
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
public interface IStreamManager {
|
||||
/**
|
||||
* Allows the stream manager to replace one class with another while deserializing a stream.
|
||||
* <p>NOTE: This currently is only called if the stream cannot load the requested type.
|
||||
* @param typeName The name of the type to replace.
|
||||
* @return The replacement type (or same type if no replacement is required).
|
||||
*/
|
||||
public Class replaceType(String typeName);
|
||||
}//IStreamManager//
|
||||
31
Common/src/com/common/io/IWriter.java
Normal file
31
Common/src/com/common/io/IWriter.java
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
/**
|
||||
* Used by non-stream classes that want to allow writing via the stream support class.
|
||||
*/
|
||||
public interface IWriter {
|
||||
/**
|
||||
* Writes a single byte.
|
||||
* @param b The byte to write.
|
||||
*/
|
||||
public void write(byte b);
|
||||
/**
|
||||
* Writes a range of bytes.
|
||||
* @param bytes The bytes to write.
|
||||
*/
|
||||
public void write(byte[] bytes);
|
||||
/**
|
||||
* Writes a range of bytes.
|
||||
* @param bytes The bytes to write.
|
||||
* @param offset The offset in the bytes array of the first byte to write.
|
||||
* @param length The number of bytes from the bytes array to write.
|
||||
*/
|
||||
public void write(byte[] bytes, int offset, int length);
|
||||
}//IWriter//
|
||||
224
Common/src/com/common/io/IndexedObjectInputStream.java
Normal file
224
Common/src/com/common/io/IndexedObjectInputStream.java
Normal file
@@ -0,0 +1,224 @@
|
||||
package com.common.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import com.common.util.IList;
|
||||
|
||||
/**
|
||||
* Allows the caller to read the components of the stream they are interested in.
|
||||
* Requests to read missing components will not corrupt the stream.
|
||||
*/
|
||||
public class IndexedObjectInputStream extends AbstractObjectInputStream {
|
||||
/** The stream being wrapped. */
|
||||
private InputStream wrapped = null;
|
||||
/** The buffered content. */
|
||||
private byte[] buffer = null;
|
||||
/** The array of element indices. Each element is an index for an element supplied during serialization. */
|
||||
private int[] indices = null;
|
||||
/** The array of index element offsets within the buffer. The index of the size corresponds to the index in the indices array. */
|
||||
private int[] offsets = null;
|
||||
/** The last used index from the indices array. */
|
||||
private int lastIndicesIndex = 0;
|
||||
/** The index within the indicies array of the index we are about to read, or -1. */
|
||||
private int nextIndex = -1;
|
||||
/** The offset within the buffer of the next data byte to be read, associated with the indexed data element referenced by nextIndex. */
|
||||
private int nextOffset = -1;
|
||||
/** The count of remaining bytes (within the buffer) of the data associated with the indexed data element referenced by nextIndex. */
|
||||
private int nextRemainingSize = -1;
|
||||
/**
|
||||
* IndexedObjectInputStream constructor.
|
||||
* @param in
|
||||
* @throws IOException
|
||||
*/
|
||||
public IndexedObjectInputStream(ObjectInput in) throws IOException {
|
||||
super(in instanceof IObjectInputStream ? ((IObjectInputStream) in).getLoader() : null, in instanceof IObjectInputStream ? ((IObjectInputStream) in).getClassReplacementHandler() : null, in instanceof IObjectInputStream ? ((IObjectInputStream) in).getClassList() : null, in instanceof IObjectInputStream ? ((IObjectInputStream) in).getInstanceFactory() : null, in instanceof IObjectInputStream ? ((IObjectInputStream) in).getClassTracker() : null, in instanceof IObjectInputStream ? ((IObjectInputStream) in).getDeserializedValues() : null, in instanceof IObjectInputStream ? ((IObjectInputStream) in).getDefaultNumberStyle() : AbstractStandardInputStream.STYLE_DEFAULT);
|
||||
this.wrapped = (InputStream) in;
|
||||
initialize();
|
||||
}//IndexedObjectInputStream()//
|
||||
/**
|
||||
* IndexedObjectInputStream constructor.
|
||||
* @param in
|
||||
* @throws IOException
|
||||
*/
|
||||
public IndexedObjectInputStream(IObjectInputStream in) throws IOException {
|
||||
super(in.getLoader(), in.getClassReplacementHandler(), in.getClassList(), in.getInstanceFactory(), in.getClassTracker(), in.getDeserializedValues(), in.getDefaultNumberStyle());
|
||||
this.wrapped = (InputStream) in;
|
||||
initialize();
|
||||
}//IndexedObjectInputStream()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.AbstractStandardInputStream#skip(long)
|
||||
*/
|
||||
public long skip(long count) throws IOException {
|
||||
//Not supported.//
|
||||
return 0;
|
||||
}//skip()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.AbstractStandardInputStream#mark(int)
|
||||
*/
|
||||
public void mark(int readLimit) {
|
||||
//Not supported.//
|
||||
}//mark()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.AbstractStandardInputStream#markSupported()
|
||||
*/
|
||||
public boolean markSupported() {
|
||||
//Not supported.//
|
||||
return false;
|
||||
}//markSupported()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.AbstractStandardInputStream#available()
|
||||
*/
|
||||
public int available() throws IOException {
|
||||
return wrapped.available();
|
||||
}//available()//
|
||||
/**
|
||||
* Initializes the stream.
|
||||
* @throws IOException
|
||||
*/
|
||||
protected void initialize() throws IOException {
|
||||
int count = StreamSupport.readInt(wrapped, StreamSupport.NUMBER_VLSF);
|
||||
int lastSize = -1;
|
||||
int totalSize = 0;
|
||||
|
||||
indices = new int[count];
|
||||
offsets = new int[count];
|
||||
|
||||
for(int i = 0; i < count; i++) {
|
||||
//Set the offset within the buffer.//
|
||||
offsets[i] = lastSize != -1 ? lastSize + offsets[i - 1] : 0;
|
||||
//Read the identifier for the value.//
|
||||
indices[i] = StreamSupport.readInt(wrapped, StreamSupport.NUMBER_VLSF);
|
||||
//Read the offset of the start of the value.//
|
||||
lastSize = StreamSupport.readInt(wrapped, StreamSupport.NUMBER_VLSF);
|
||||
//Update the total size of the data byte array.//
|
||||
totalSize += lastSize;
|
||||
}//for//
|
||||
|
||||
//Setup the content buffer.//
|
||||
buffer = new byte[totalSize];
|
||||
|
||||
//Buffer the whole content.//
|
||||
if(StreamSupport.readBytes(wrapped, buffer) != buffer.length) {
|
||||
throw new IOException("Failed to read enough bytes.");
|
||||
}//if//
|
||||
|
||||
lastIndicesIndex = offsets.length - 1;
|
||||
}//initialize()//
|
||||
/**
|
||||
* Begins the deserialization of the value at the given index.
|
||||
* <p>This must be called prior to any other read operation, for every read operation performed.</p>
|
||||
* @param index The index of the value to be deserialized.
|
||||
* @return Whether the stream contains a value associated with the index.
|
||||
*/
|
||||
public boolean begin(int index) {
|
||||
int i = lastIndicesIndex;
|
||||
|
||||
nextIndex = -1;
|
||||
|
||||
//Use a rotating loop over the indices starting with the index of the last match plus one. Often things are read in the same order they were written so this is just more efficient.//
|
||||
do {
|
||||
i++;
|
||||
|
||||
if(i == indices.length) {
|
||||
i = 0;
|
||||
}//if//
|
||||
|
||||
if(indices[i] == index) {
|
||||
nextIndex = i;
|
||||
nextOffset = offsets[i];
|
||||
nextRemainingSize = offsets.length > i + 1 ? offsets[i + 1] - offsets[i] : buffer.length - offsets[i];
|
||||
}//if//
|
||||
} while(nextIndex == -1 && i != lastIndicesIndex);
|
||||
|
||||
lastIndicesIndex = i;
|
||||
|
||||
return nextIndex != -1;
|
||||
}//begin()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.AbstractStandardInputStream#read()
|
||||
*/
|
||||
public int read() throws IOException {
|
||||
if(nextIndex == -1) {
|
||||
throw new IOException("Must call begin(int) prior to reading data. Each piece of data must be indexed.");
|
||||
}//if//
|
||||
else if(nextRemainingSize <= 0) {
|
||||
throw new IOException("End of element stream reached.");
|
||||
}//else if//
|
||||
|
||||
return buffer[nextOffset++];
|
||||
}//read()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.AbstractStandardInputStream#read(byte[])
|
||||
*/
|
||||
public int read(byte[] buffer) throws IOException {
|
||||
int result = Math.min(buffer.length, nextRemainingSize);
|
||||
|
||||
if(nextIndex == -1) {
|
||||
throw new IOException("Must call begin(int) prior to reading data. Each piece of data must be indexed.");
|
||||
}//if//
|
||||
else if(nextRemainingSize <= 0) {
|
||||
throw new IOException("End of element stream reached.");
|
||||
}//else if//
|
||||
|
||||
System.arraycopy(this.buffer, nextOffset, buffer, 0, result);
|
||||
nextOffset += result;
|
||||
nextRemainingSize -= result;
|
||||
|
||||
return result;
|
||||
}//read()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.AbstractStandardInputStream#read(byte[], int, int)
|
||||
*/
|
||||
public int read(byte[] buffer, int offset, int length) throws IOException {
|
||||
int result = Math.min(length, nextRemainingSize);
|
||||
|
||||
if(nextIndex == -1) {
|
||||
throw new IOException("Must call begin(int) prior to reading data. Each piece of data must be indexed.");
|
||||
}//if//
|
||||
else if(nextRemainingSize <= 0) {
|
||||
throw new IOException("End of element stream reached.");
|
||||
}//else if//
|
||||
|
||||
System.arraycopy(this.buffer, nextOffset, buffer, offset, result);
|
||||
nextOffset += result;
|
||||
nextRemainingSize -= result;
|
||||
|
||||
return result;
|
||||
}//read()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.AbstractStandardInputStream#read(java.io.OutputStream, int)
|
||||
*/
|
||||
public int read(OutputStream out, int length) throws IOException {
|
||||
byte[] bytes = new byte[Math.min(length, nextRemainingSize)];
|
||||
|
||||
if(nextIndex == -1) {
|
||||
throw new IOException("Must call begin(int) prior to reading data. Each piece of data must be indexed.");
|
||||
}//if//
|
||||
else if(nextRemainingSize <= 0) {
|
||||
throw new IOException("End of element stream reached.");
|
||||
}//else if//
|
||||
|
||||
System.arraycopy(this.buffer, nextOffset, bytes, 0, bytes.length);
|
||||
nextOffset += bytes.length;
|
||||
nextRemainingSize -= bytes.length;
|
||||
out.write(bytes);
|
||||
|
||||
return bytes.length;
|
||||
}//read()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.AbstractObjectInputStream#peekByte(int)
|
||||
*/
|
||||
public byte peekByte(int offset) throws IOException {
|
||||
if(nextIndex == -1) {
|
||||
throw new IOException("Must call begin(int) prior to reading data. Each piece of data must be indexed.");
|
||||
}//if//
|
||||
else if(nextRemainingSize <= 0) {
|
||||
throw new IOException("End of element stream reached.");
|
||||
}//else if//
|
||||
|
||||
return buffer[nextOffset];
|
||||
}//peekByte()//
|
||||
}//IndexedObjectInputStream//
|
||||
162
Common/src/com/common/io/IndexedObjectOutputStream.java
Normal file
162
Common/src/com/common/io/IndexedObjectOutputStream.java
Normal file
@@ -0,0 +1,162 @@
|
||||
package com.common.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectOutput;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import com.common.util.LiteHashMap;
|
||||
|
||||
/**
|
||||
* The indexed streams are designed to wrapper another stream (usually with a serialization handler) to allow for more independance from the stream structure.
|
||||
* The idea is that by indexing the values serialized, the stream will become more flexible, allowing the reader to skip unexpected values, and recognize that expected values were not provided.
|
||||
*/
|
||||
public class IndexedObjectOutputStream extends AbstractObjectOutputStream {
|
||||
/** The stream being wrapped. */
|
||||
private OutputStream wrapped = null;
|
||||
/** The buffer containing the element data for each indexed element. */
|
||||
private byte[] buffer;
|
||||
/** The offset within the buffer where the next byte of data will be written. */
|
||||
private int bufferOffset = 0;
|
||||
/** The next index being written. The index identifies the element being written to the stream as it is being read by the input stream. */
|
||||
private int nextIndex = -1;
|
||||
/** The offset within the buffer of the start of the nextIndex element. */
|
||||
private int nextOffset = -1;
|
||||
/** The count of index elements written to the stream. */
|
||||
private int indexCount = 0;
|
||||
/** The serialized index metadata. Contains integer pairs for each indexed element written. */
|
||||
private byte[] indexData = new byte[100];
|
||||
/** The offset within the indexData where the next index data will be written. */
|
||||
private int indexDataOffset = 0;
|
||||
/**
|
||||
* IndexedObjectOutputStream constructor.
|
||||
* @param out
|
||||
* @throws IOException
|
||||
*/
|
||||
public IndexedObjectOutputStream(ObjectOutput out) throws IOException {
|
||||
super(out instanceof IObjectOutputStream ? ((IObjectOutputStream) out).getClassMap() : null, out instanceof IObjectOutputStream ? ((IObjectOutputStream) out).getClassReplacementHandler() : null, out instanceof IObjectOutputStream ? ((IObjectOutputStream) out).getSerializedObjectMap() : null, out instanceof IObjectOutputStream ? ((IObjectOutputStream) out).getDefaultNumberStyle() : AbstractStandardInputStream.STYLE_DEFAULT);
|
||||
wrapped = (OutputStream) out;
|
||||
buffer = new byte[1000];
|
||||
}//IndexedObjectOutputStream()//
|
||||
/**
|
||||
* IndexedObjectOutputStream constructor.
|
||||
* @param out
|
||||
* @throws IOException
|
||||
*/
|
||||
public IndexedObjectOutputStream(IObjectOutputStream out) throws IOException {
|
||||
super(out.getClassMap(), out.getClassReplacementHandler(), out.getSerializedObjectMap(), out.getDefaultNumberStyle());
|
||||
wrapped = (OutputStream) out;
|
||||
buffer = new byte[1000];
|
||||
}//IndexedObjectOutputStream()//
|
||||
/**
|
||||
* Starts the writing of a new indexed value to the stream.
|
||||
* @param index The index of the value. The deserialization must supply this index to retrieve the value.
|
||||
*/
|
||||
public void begin(int index) {
|
||||
if(nextIndex != -1) {
|
||||
//Write the index and size to the index data buffer.//
|
||||
writeIndex();
|
||||
}//if//
|
||||
|
||||
nextIndex = index;
|
||||
nextOffset = bufferOffset;
|
||||
indexCount++;
|
||||
}//begin()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.AbstractObjectOutputStream#flush()
|
||||
*/
|
||||
public void flush() throws IOException {
|
||||
//Does nothing - cannot flush since we are writing the index to the stream at the top.//
|
||||
}//flush()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.AbstractObjectOutputStream#close()
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
if(nextIndex != -1) {
|
||||
//Write the index and size to the index data buffer.//
|
||||
writeIndex();
|
||||
}//if//
|
||||
|
||||
StreamSupport.writeInt(indexCount, wrapped, StreamSupport.NUMBER_VLSF);
|
||||
wrapped.write(indexData, 0, indexDataOffset);
|
||||
wrapped.write(buffer, 0, bufferOffset);
|
||||
super.close();
|
||||
}//close()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.AbstractStandardOutputStream#write(byte[])
|
||||
*/
|
||||
public void write(byte[] bytes) throws IOException {
|
||||
ensureSpace(bytes.length);
|
||||
System.arraycopy(bytes, 0, buffer, bufferOffset, bytes.length);
|
||||
bufferOffset += bytes.length;
|
||||
}//write()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.AbstractStandardOutputStream#write(byte[], int, int)
|
||||
*/
|
||||
public void write(byte[] bytes, int offset, int length) throws IOException {
|
||||
ensureSpace(length);
|
||||
System.arraycopy(bytes, offset, buffer, bufferOffset, length);
|
||||
bufferOffset += length;
|
||||
}//write()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.AbstractStandardOutputStream#write(int)
|
||||
*/
|
||||
public void write(int b) throws IOException {
|
||||
ensureSpace(1);
|
||||
buffer[bufferOffset++] = (byte) b;
|
||||
}//write()//
|
||||
/**
|
||||
* Ensures the buffer is capable of adding the passed number of bytes.
|
||||
* @param availableSpace The space being requested.
|
||||
*/
|
||||
protected void ensureSpace(int availableSpace) {
|
||||
if(buffer.length - bufferOffset < availableSpace) {
|
||||
byte[] temp = new byte[bufferOffset + Math.max(availableSpace, 1000)];
|
||||
|
||||
System.arraycopy(buffer, 0, temp, 0, bufferOffset);
|
||||
buffer = temp;
|
||||
}//if//
|
||||
}//ensureSpace()//
|
||||
/**
|
||||
* Writes the next index (set by calling begin(int)) and the size of the data element.
|
||||
*/
|
||||
protected void writeIndex() {
|
||||
//Ensure that begin(int) was called prior to streaming the value.//
|
||||
if(nextIndex == -1) {
|
||||
throw new RuntimeException("Must call begin(int) prior to writing data. Each piece of data must be indexed.");
|
||||
}//if//
|
||||
|
||||
//Ensure we have enough space for two integers.//
|
||||
if(indexData.length - indexDataOffset < 8) {
|
||||
byte[] temp = new byte[indexData.length + 100];
|
||||
|
||||
System.arraycopy(indexData, 0, temp, 0, indexDataOffset);
|
||||
indexData = temp;
|
||||
}//if//
|
||||
|
||||
//Write the index number for the data element.//
|
||||
indexDataOffset += StreamSupport.writeInt(nextIndex, indexData, indexDataOffset, StreamSupport.NUMBER_VLSF);
|
||||
//Write the size of the data element.//
|
||||
indexDataOffset += StreamSupport.writeInt(bufferOffset - nextOffset, indexData, indexDataOffset, StreamSupport.NUMBER_VLSF);
|
||||
//Reset the next variables.//
|
||||
nextIndex = -1;
|
||||
nextOffset = -1;
|
||||
}//writeIndex()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.AbstractStandardOutputStream#canEncrypt()
|
||||
*/
|
||||
public boolean canEncrypt() {
|
||||
return false;
|
||||
}//canEncrypt()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.AbstractStandardOutputStream#encrypt(boolean)
|
||||
*/
|
||||
public void encrypt(boolean encrypt) throws IOException {
|
||||
throw new IOException("Encryption not supported at this level. The underlying stream can be encrypted if so desired.");
|
||||
}//encrypt()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.AbstractStandardOutputStream#isEncrypting()
|
||||
*/
|
||||
public boolean isEncrypting() {
|
||||
return false;
|
||||
}//isEncrypting()//
|
||||
}//IndexedObjectOutputStream//
|
||||
235
Common/src/com/common/io/ObjectInputStream.java
Normal file
235
Common/src/com/common/io/ObjectInputStream.java
Normal file
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import com.common.util.*;
|
||||
|
||||
public class ObjectInputStream extends AbstractObjectInputStream implements IObjectStream, java.io.ObjectInput, IObjectInputStream {
|
||||
private InputStream stream = null;
|
||||
/**
|
||||
* ObjectInputStream constructor.
|
||||
* @param stream The input stream that will be encapsulated. <b>Warning: If specialized functionality provided by the IOuputStream interface is required then the entire hierarchy of passed output streams *MUST* all implement this interface or it will not properly work.</b>
|
||||
* @param loader The class loader to use when it is necessary to load classes when creating objects read from the stream.
|
||||
* @param classList An optional list used to maintain the order classes were recognized by the stream. This allows class indexes to be streamed in place of the class name. This list is passed so that it may be reused if multiple streams from the same source are read.
|
||||
*/
|
||||
public ObjectInputStream(InputStream stream, ClassLoader loader, IList classList) throws IOException {
|
||||
super(loader, classList);
|
||||
|
||||
this.stream = stream;
|
||||
}//ObjectInputStream()//
|
||||
/**
|
||||
* ObjectInputStream constructor.
|
||||
* @param stream The input stream that will be encapsulated. <b>Warning: If specialized functionality provided by the IOuputStream interface is required then the entire hierarchy of passed output streams *MUST* all implement this interface or it will not properly work.</b>
|
||||
* @param loader The class loader to use when it is necessary to load classes when creating objects read from the stream.
|
||||
* @param classList An optional list used to maintain the order classes were recognized by the stream. This allows class indexes to be streamed in place of the class name. This list is passed so that it may be reused if multiple streams from the same source are read.
|
||||
* @param instanceFactory The instance factory to be used to generate instances of classes read from the stream.
|
||||
*/
|
||||
public ObjectInputStream(InputStream stream, ClassLoader loader, IList classList, IInstanceFactory instanceFactory) throws IOException {
|
||||
super(loader, classList, instanceFactory);
|
||||
|
||||
this.stream = stream;
|
||||
}//ObjectInputStream()//
|
||||
/**
|
||||
* ObjectInputStream constructor.
|
||||
* @param stream The input stream that will be encapsulated. <b>Warning: If specialized functionality provided by the IOuputStream interface is required then the entire hierarchy of passed output streams *MUST* all implement this interface or it will not properly work.</b>
|
||||
* @param loader The class loader to use when it is necessary to load classes when creating objects read from the stream.
|
||||
* @param classList An optional list used to maintain the order classes were recognized by the stream. This allows class indexes to be streamed in place of the class name. This list is passed so that it may be reused if multiple streams from the same source are read.
|
||||
* @param instanceFactory The instance factory to be used to generate instances of classes read from the stream.
|
||||
* @param classTracker This optional handler is notified if a class is instantiated, allowing applications to track which classes are being streamed and instantiated.
|
||||
*/
|
||||
public ObjectInputStream(InputStream stream, ClassLoader loader, IList classList, IInstanceFactory instanceFactory, IClassTracker classTracker) throws IOException {
|
||||
super(loader, null, classList, instanceFactory, classTracker);
|
||||
|
||||
this.stream = stream;
|
||||
}//ObjectInputStream()//
|
||||
/**
|
||||
* ObjectInputStream constructor.
|
||||
* @param stream The input stream that will be encapsulated. <b>Warning: If specialized functionality provided by the IOuputStream interface is required then the entire hierarchy of passed output streams *MUST* all implement this interface or it will not properly work.</b>
|
||||
* @param loader The class loader to use when it is necessary to load classes when creating objects read from the stream.
|
||||
* @param classReplacementHandler The optional handler called when the stream loads a class. Allows the stream to replace one class name with another.
|
||||
* @param classList An optional list used to maintain the order classes were recognized by the stream. This allows class indexes to be streamed in place of the class name. This list is passed so that it may be reused if multiple streams from the same source are read.
|
||||
* @param instanceFactory The instance factory to be used to generate instances of classes read from the stream.
|
||||
* @param classTracker This optional handler is notified if a class is instantiated, allowing applications to track which classes are being streamed and instantiated.
|
||||
*/
|
||||
public ObjectInputStream(InputStream stream, ClassLoader loader, IClassReplacementHandler classReplacementHandler, IList classList, IInstanceFactory instanceFactory, IClassTracker classTracker) throws IOException {
|
||||
super(loader, classReplacementHandler, classList, instanceFactory, classTracker);
|
||||
|
||||
this.stream = stream;
|
||||
}//ObjectInputStream()//
|
||||
/**
|
||||
* ObjectInputStream constructor.
|
||||
* @param stream The input stream that will be encapsulated. <b>Warning: If specialized functionality provided by the IOuputStream interface is required then the entire hierarchy of passed output streams *MUST* all implement this interface or it will not properly work.</b>
|
||||
* @param loader The class loader to use when it is necessary to load classes when creating objects read from the stream.
|
||||
* @param classList An optional list used to maintain the order classes were recognized by the stream. This allows class indexes to be streamed in place of the class name. This list is passed so that it may be reused if multiple streams from the same source are read.
|
||||
* @param defaultNumberStyle One of the STYLE_xx identifiers. This defaults to most significant byte first.
|
||||
*/
|
||||
public ObjectInputStream(InputStream stream, ClassLoader loader, IList classList, int defaultNumberStyle) throws IOException {
|
||||
this(stream, loader, null, classList, null, null, defaultNumberStyle);
|
||||
}//ObjectInputStream()//
|
||||
/**
|
||||
* ObjectInputStream constructor.
|
||||
* @param stream The input stream that will be encapsulated. <b>Warning: If specialized functionality provided by the IOuputStream interface is required then the entire hierarchy of passed output streams *MUST* all implement this interface or it will not properly work.</b>
|
||||
* @param loader The class loader to use when it is necessary to load classes when creating objects read from the stream.
|
||||
* @param classList An optional list used to maintain the order classes were recognized by the stream. This allows class indexes to be streamed in place of the class name. This list is passed so that it may be reused if multiple streams from the same source are read.
|
||||
* @param instanceFactory The instance factory to be used to generate instances of classes read from the stream.
|
||||
* @param defaultNumberStyle One of the STYLE_xx identifiers. This defaults to most significant byte first.
|
||||
*/
|
||||
public ObjectInputStream(InputStream stream, ClassLoader loader, IList classList, IInstanceFactory instanceFactory, int defaultNumberStyle) throws IOException {
|
||||
this(stream, loader, null, classList, instanceFactory, null, defaultNumberStyle);
|
||||
}//ObjectInputStream()//
|
||||
/**
|
||||
* ObjectInputStream constructor.
|
||||
* @param stream The input stream that will be encapsulated. <b>Warning: If specialized functionality provided by the IOuputStream interface is required then the entire hierarchy of passed output streams *MUST* all implement this interface or it will not properly work.</b>
|
||||
* @param loader The class loader to use when it is necessary to load classes when creating objects read from the stream.
|
||||
* @param classList An optional list used to maintain the order classes were recognized by the stream. This allows class indexes to be streamed in place of the class name. This list is passed so that it may be reused if multiple streams from the same source are read.
|
||||
* @param instanceFactory The instance factory to be used to generate instances of classes read from the stream.
|
||||
* @param classTracker This optional handler is notified if a class is instantiated, allowing applications to track which classes are being streamed and instantiated.
|
||||
* @param defaultNumberStyle One of the STYLE_xx identifiers. This defaults to most significant byte first.
|
||||
*/
|
||||
public ObjectInputStream(InputStream stream, ClassLoader loader, IList classList, IInstanceFactory instanceFactory, IClassTracker classTracker, int defaultNumberStyle) throws IOException {
|
||||
this(stream, loader, null, classList, instanceFactory, classTracker, defaultNumberStyle);
|
||||
}//ObjectInputStream()//
|
||||
/**
|
||||
* ObjectInputStream constructor.
|
||||
* @param stream The input stream that will be encapsulated. <b>Warning: If specialized functionality provided by the IOuputStream interface is required then the entire hierarchy of passed output streams *MUST* all implement this interface or it will not properly work.</b>
|
||||
* @param loader The class loader to use when it is necessary to load classes when creating objects read from the stream.
|
||||
* @param classReplacementHandler The optional handler called when the stream loads a class. Allows the stream to replace one class name with another.
|
||||
* @param classList An optional list used to maintain the order classes were recognized by the stream. This allows class indexes to be streamed in place of the class name. This list is passed so that it may be reused if multiple streams from the same source are read.
|
||||
* @param instanceFactory The instance factory to be used to generate instances of classes read from the stream.
|
||||
* @param classTracker This optional handler is notified if a class is instantiated, allowing applications to track which classes are being streamed and instantiated.
|
||||
* @param defaultNumberStyle One of the STYLE_xx identifiers. This defaults to most significant byte first.
|
||||
*/
|
||||
public ObjectInputStream(InputStream stream, ClassLoader loader, IClassReplacementHandler classReplacementHandler, IList classList, IInstanceFactory instanceFactory, IClassTracker classTracker, int defaultNumberStyle) throws IOException {
|
||||
super(loader, classReplacementHandler, classList, instanceFactory, classTracker, defaultNumberStyle);
|
||||
|
||||
this.stream = stream;
|
||||
}//ObjectInputStream()//
|
||||
/**
|
||||
* Gets the number of available bytes in the input stream.
|
||||
* @return The number of bytes that have not yet been read from the input stream.
|
||||
*/
|
||||
public int available() throws IOException {
|
||||
return stream.available();
|
||||
}//available()//
|
||||
/**
|
||||
* @see IInputStream.canDecrypt()
|
||||
*/
|
||||
public boolean canDecrypt() {
|
||||
return (stream instanceof IInputStream) && (((IInputStream) stream).canDecrypt());
|
||||
}//canDecrypt()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.InputStream#close()
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
super.close();
|
||||
stream.close();
|
||||
}//close()//
|
||||
/**
|
||||
* @see IInputStream.decrypt(boolean)
|
||||
*/
|
||||
public void decrypt(boolean decrypt) throws IOException {
|
||||
if(stream instanceof IInputStream) {
|
||||
if(((IInputStream) stream).canDecrypt()) {
|
||||
((IInputStream) stream).decrypt(decrypt);
|
||||
}//if//
|
||||
else {
|
||||
throw new IOException(ERROR_DECRYPTION_NOT_SUPPORTED);
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
throw new IOException(ERROR_DECRYPTION_NOT_SUPPORTED);
|
||||
}//else//
|
||||
}//decrypt()//
|
||||
/**
|
||||
* Gets the encapsulated input stream.
|
||||
* @return Gets the input stream that this object wrappers.
|
||||
*/
|
||||
public InputStream getInputStream() {
|
||||
return stream;
|
||||
}//getInputStream()//
|
||||
/**
|
||||
* @see IInputStream.isDecrypting()
|
||||
*/
|
||||
public boolean isDecrypting() {
|
||||
return (stream instanceof IInputStream) && (((IInputStream) stream).isDecrypting());
|
||||
}//isDecrypting()//
|
||||
/**
|
||||
* Marks the stream so that the reader can reset to the current position.
|
||||
* @param readLimit The number of bytes that may be read before the mark becomes invalid.
|
||||
*/
|
||||
public void mark(int readLimit) {
|
||||
stream.mark(readLimit);
|
||||
}//mark()//
|
||||
/**
|
||||
* Determines whether the stream supports using the mark method.
|
||||
* @return Whether the mark method is supported.
|
||||
*/
|
||||
public boolean markSupported() {
|
||||
return stream.markSupported();
|
||||
}//markSupported()//
|
||||
/**
|
||||
* Reads an unsigned byte from the stream.
|
||||
* @return The unsigned byte read from the stream.
|
||||
*/
|
||||
public int read() throws IOException {
|
||||
return stream.read();
|
||||
}//read()//
|
||||
/**
|
||||
* Reads bytes from the stream until the buffer is full or there are no more bytes in the stream.
|
||||
* @param buffer The buffer where the read bytes will be placed.
|
||||
* @return The number of bytes read into the buffer.
|
||||
*/
|
||||
public int read(byte[] buffer) throws IOException {
|
||||
return stream.read(buffer);
|
||||
}//read()//
|
||||
/**
|
||||
* Reads bytes from the stream until the buffer is full or there are no more bytes in the stream.
|
||||
* @param buffer The buffer where the read bytes will be placed.
|
||||
* @param offset The offset where the first read byte should be placed in the buffer.
|
||||
* @param length The number of bytes that should be read into the buffer.
|
||||
* @return The number of bytes read into the buffer.
|
||||
*/
|
||||
public int read(byte[] buffer, int offset, int length) throws IOException {
|
||||
return stream.read(buffer, offset, length);
|
||||
}//read()//
|
||||
/**
|
||||
* @see IInputStream.read(java.io.OutputStream, int)
|
||||
*/
|
||||
public int read(java.io.OutputStream out, int length) throws IOException {
|
||||
int retVal;
|
||||
|
||||
if(stream instanceof IInputStream) {
|
||||
retVal = ((IInputStream) stream).read(out,length);
|
||||
}//if//
|
||||
else {
|
||||
byte[] bytes = new byte[length];
|
||||
|
||||
retVal = stream.read(bytes, 0, bytes.length);
|
||||
out.write(bytes, 0, retVal);
|
||||
}//else//
|
||||
|
||||
return retVal;
|
||||
}//read()//
|
||||
/**
|
||||
* Resets this stream so that it may be re-read.
|
||||
*/
|
||||
public void reset() throws java.io.IOException {
|
||||
super.reset();
|
||||
stream.reset();
|
||||
}//reset()//
|
||||
/**
|
||||
* Skips the next <code>count</code> bytes on the stream.
|
||||
* @param count The number of bytes to skip.
|
||||
* @return The number of bytes that were skipped.
|
||||
*/
|
||||
public long skip(long count) throws IOException {
|
||||
return stream.skip(count);
|
||||
}//skip()//
|
||||
}//ObjectInputStream//
|
||||
131
Common/src/com/common/io/ObjectOutputStream.java
Normal file
131
Common/src/com/common/io/ObjectOutputStream.java
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
import com.common.util.*;
|
||||
|
||||
/**
|
||||
* This default implementation of an object output stream uses an encapsulated stream for performing the actual data output.
|
||||
* Users can create their own composite streams using this class, or when necessary can exend AbstractObjectOutputStream to create a customized stream.
|
||||
*/
|
||||
public class ObjectOutputStream extends AbstractObjectOutputStream {
|
||||
private OutputStream stream = null; //The underlying byte stream if buffering is used.//
|
||||
/**
|
||||
* QuickOutputStream constructor.
|
||||
* <p>WARNING: If a classMap is provided (optimized type streaming is used), then the user must be careful to reuse the same maps while streaming under the same context. In addition, the receiver of the stream must be careful to reuse thier maps so that the indexes match up properly.
|
||||
* <p></b>IMPORTANT: The supplied map MUST use an IDENTITY comparator <code>Comparator.getIdentityComparator()</code> for key comparison.</b>
|
||||
* @param stream The stream that the objects get written to. <b>Warning: If specialized functionality provided by the IOuputStream interface is required then the entire hierarchy of passed output streams *MUST* all implement this interface or it will not properly work.</b>
|
||||
* @param classMap The mapping class names to numbers allowing the stream to optimize the serialization of classes. The hash map keys should be compared using an identity comparator. This value may be <code>null</code> which will turn off optimized type streaming.
|
||||
*/
|
||||
public ObjectOutputStream(OutputStream stream, LiteHashMap classMap) throws IOException {
|
||||
this(stream, classMap, null);
|
||||
}//ObjectOutputStream()//
|
||||
/**
|
||||
* QuickOutputStream constructor.
|
||||
* <p>WARNING: If a classMap is provided (optimized type streaming is used), then the user must be careful to reuse the same maps while streaming under the same context. In addition, the receiver of the stream must be careful to reuse thier maps so that the indexes match up properly.
|
||||
* <p></b>IMPORTANT: The supplied map MUST use an IDENTITY comparator <code>Comparator.getIdentityComparator()</code> for key comparison.</b>
|
||||
* @param stream The stream that the objects get written to. <b>Warning: If specialized functionality provided by the IOuputStream interface is required then the entire hierarchy of passed output streams *MUST* all implement this interface or it will not properly work.</b>
|
||||
* @param classMap The mapping class names to numbers allowing the stream to optimize the serialization of classes. The hash map keys should be compared using an identity comparator. This value may be <code>null</code> which will turn off optimized type streaming.
|
||||
* @param classReplacementHandler The handler called when writing a class name to the stream. This allows the application to swap the name for another name.
|
||||
*/
|
||||
public ObjectOutputStream(OutputStream stream, LiteHashMap classMap, IClassReplacementHandler classReplacementHandler) throws IOException {
|
||||
super(classMap, classReplacementHandler);
|
||||
this.stream = stream;
|
||||
}//ObjectOutputStream()//
|
||||
/**
|
||||
* QuickOutputStream constructor.
|
||||
* <p>WARNING: If a classMap is provided (optimized type streaming is used), then the user must be careful to reuse the same maps while streaming under the same context. In addition, the receiver of the stream must be careful to reuse thier maps so that the indexes match up properly.
|
||||
* <p></b>IMPORTANT: The supplied map MUST use an IDENTITY comparator <code>Comparator.getIdentityComparator()</code> for key comparison.</b>
|
||||
* @param stream The stream that the objects get written to. <b>Warning: If specialized functionality provided by the IOuputStream interface is required then the entire hierarchy of passed output streams *MUST* all implement this interface or it will not properly work.</b>
|
||||
* @param classMap The mapping class names to numbers allowing the stream to optimize the serialization of classes. The hash map keys should be compared using an identity comparator. This value may be <code>null</code> which will turn off optimized type streaming.
|
||||
* @param defaultNumberStyle One of the STYLE_xx identifiers. This defaults to most significant byte first.
|
||||
*/
|
||||
public ObjectOutputStream(OutputStream stream, LiteHashMap classMap, int defaultNumberStyle) throws IOException {
|
||||
this(stream, classMap, null, defaultNumberStyle);
|
||||
}//ObjectOutputStream()//
|
||||
/**
|
||||
* QuickOutputStream constructor.
|
||||
* <p>WARNING: If a classMap is provided (optimized type streaming is used), then the user must be careful to reuse the same maps while streaming under the same context. In addition, the receiver of the stream must be careful to reuse thier maps so that the indexes match up properly.
|
||||
* <p></b>IMPORTANT: The supplied map MUST use an IDENTITY comparator <code>Comparator.getIdentityComparator()</code> for key comparison.</b>
|
||||
* @param stream The stream that the objects get written to. <b>Warning: If specialized functionality provided by the IOuputStream interface is required then the entire hierarchy of passed output streams *MUST* all implement this interface or it will not properly work.</b>
|
||||
* @param classMap The mapping class names to numbers allowing the stream to optimize the serialization of classes. The hash map keys should be compared using an identity comparator. This value may be <code>null</code> which will turn off optimized type streaming.
|
||||
* @param classReplacementHandler The handler called when writing a class name to the stream. This allows the application to swap the name for another name.
|
||||
* @param defaultNumberStyle One of the STYLE_xx identifiers. This defaults to most significant byte first.
|
||||
*/
|
||||
public ObjectOutputStream(OutputStream stream, LiteHashMap classMap, IClassReplacementHandler classReplacementHandler, int defaultNumberStyle) throws IOException {
|
||||
super(classMap, classReplacementHandler, defaultNumberStyle);
|
||||
this.stream = stream;
|
||||
}//ObjectOutputStream()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.AbstractStandardOutputStream#canEncrypt()
|
||||
*/
|
||||
public boolean canEncrypt() {
|
||||
return (stream instanceof IOutputStream) && (((IOutputStream) stream).canEncrypt());
|
||||
}//canEncrypt()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.OutputStream#close()
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
super.close();
|
||||
stream.close();
|
||||
}//close()//
|
||||
/**
|
||||
* @see IOutputStream.encrypt(boolean)
|
||||
*/
|
||||
public void encrypt(boolean encrypt) throws IOException {
|
||||
if(stream instanceof IOutputStream) {
|
||||
if(((IOutputStream) stream).canEncrypt()) {
|
||||
flush();
|
||||
((IOutputStream) stream).encrypt(encrypt);
|
||||
}//if//
|
||||
else {
|
||||
throw new IOException(ERROR_ENCRYPTION_NOT_SUPPORTED);
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
throw new IOException(ERROR_ENCRYPTION_NOT_SUPPORTED);
|
||||
}//else//
|
||||
}//encrypt()//
|
||||
/**
|
||||
* Flushes this output stream and the encapsulated output stream.
|
||||
*/
|
||||
public void flush() throws IOException {
|
||||
stream.flush();
|
||||
}//flush()//
|
||||
/**
|
||||
* @see IOutputStream.isEncrypting()
|
||||
*/
|
||||
public boolean isEncrypting() {
|
||||
return (stream instanceof IOutputStream) && (((IOutputStream) stream).isEncrypting());
|
||||
}//isEncrypting()//
|
||||
/**
|
||||
* Writes the bytes to the stream.
|
||||
* @param bytes The bytes to write to the stream.
|
||||
*/
|
||||
public void write(byte[] bytes) throws IOException {
|
||||
stream.write(bytes);
|
||||
}//write()//
|
||||
/**
|
||||
* Writes the bytes to the stream.
|
||||
* @param bytes The bytes to write to the stream.
|
||||
* @param offset The offset of the first byte to write.
|
||||
* @param length the number of bytes to write.
|
||||
*/
|
||||
public void write(byte[] bytes, int offset, int length) throws IOException {
|
||||
stream.write(bytes, offset, length);
|
||||
}//write()//
|
||||
/**
|
||||
* Writes the unsigned byte to the stream.
|
||||
* @param b The unsigned byte to write to the stream.
|
||||
*/
|
||||
public void write(int b) throws IOException {
|
||||
stream.write(b);
|
||||
}//write()//
|
||||
}//ObjectOutputStream//
|
||||
213
Common/src/com/common/io/ObjectStream.java
Normal file
213
Common/src/com/common/io/ObjectStream.java
Normal file
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.text.*;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import com.common.debug.Debug;
|
||||
import com.common.util.IHashMap;
|
||||
import com.common.util.LiteHashMap;
|
||||
|
||||
/**
|
||||
* A container for settings and methods relating to object streaming.
|
||||
*/
|
||||
public class ObjectStream {
|
||||
/**
|
||||
* A collection of handlers providing customized serialization handlers indexed by class name or the index of the class in the collection of class names.
|
||||
* @see com.common.io.AbstractObjectInputStream.setCustomSerializationHandler(Class, ISerializationHandler)
|
||||
* @see com.common.io.ISerializationHandler
|
||||
*/
|
||||
public static final IHashMap serializationHandlersMap = new LiteHashMap(20, new Object[][] {
|
||||
{BigDecimal.class, new ISerializationHandler() {
|
||||
public void serialize(Object value, IObjectOutputStream out) throws IOException {
|
||||
byte[] bytes = ((BigDecimal) value).unscaledValue().toByteArray();
|
||||
|
||||
out.writeInt(bytes.length);
|
||||
out.write(bytes);
|
||||
out.writeInt(((BigDecimal) value).scale());
|
||||
}//serialize()//
|
||||
public Object deserialize(IObjectInputStream in) throws IOException {
|
||||
byte[] bytes = new byte[in.readInt()];
|
||||
|
||||
in.read(bytes);
|
||||
|
||||
return new BigDecimal(new BigInteger(bytes), in.readInt());
|
||||
}//deserialize()//
|
||||
}},
|
||||
{BigInteger.class, new ISerializationHandler() {
|
||||
public void serialize(Object value, IObjectOutputStream out) throws IOException {
|
||||
byte[] bytes = ((BigInteger) value).toByteArray();
|
||||
|
||||
out.writeInt(bytes.length);
|
||||
out.write(bytes);
|
||||
}//serialize()//
|
||||
public Object deserialize(IObjectInputStream in) throws IOException {
|
||||
byte[] bytes = new byte[in.readInt()];
|
||||
|
||||
in.read(bytes);
|
||||
|
||||
return new BigInteger(bytes);
|
||||
}//deserialize()//
|
||||
}},
|
||||
{java.io.File.class, new ISerializationHandler() {
|
||||
public void serialize(Object value, IObjectOutputStream out) throws IOException {
|
||||
out.writeObject(((java.io.File) value).getPath());
|
||||
}//serialize()//
|
||||
public Object deserialize(IObjectInputStream in) throws IOException {
|
||||
Object result = null;
|
||||
|
||||
try {
|
||||
result = new java.io.File((String) in.readObject());
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
Debug.log(e);
|
||||
}//catch//
|
||||
|
||||
return result;
|
||||
}//deserialize()//
|
||||
}},
|
||||
{Locale.class, new ISerializationHandler() {
|
||||
public void serialize(Object value, IObjectOutputStream out) throws IOException {
|
||||
Locale locale = (Locale) value;
|
||||
|
||||
out.writeUTF8(locale.getLanguage());
|
||||
out.writeUTF8(locale.getCountry());
|
||||
out.writeUTF8(locale.getVariant());
|
||||
}//serialize()//
|
||||
public Object deserialize(IObjectInputStream in) throws IOException {
|
||||
String language = in.readUTF8();
|
||||
String country = in.readUTF8();
|
||||
String varient = in.readUTF8();
|
||||
|
||||
return new Locale(language, country, varient);
|
||||
}//deserialize()//
|
||||
}},
|
||||
{MessageFormat.class, new ISerializationHandler() {
|
||||
public void serialize(Object value, IObjectOutputStream out) throws IOException {
|
||||
MessageFormat format = (MessageFormat) value;
|
||||
Format[] formats = format.getFormats();
|
||||
|
||||
out.writeInt(formats == null ? 0 : formats.length);
|
||||
|
||||
for(int index = 0; index < formats.length; index++) {
|
||||
out.writeObject(formats[index]);
|
||||
}//for//
|
||||
|
||||
out.writeObject(format.getLocale());
|
||||
out.writeUTF8(format.toPattern());
|
||||
}//serialize()//
|
||||
public Object deserialize(IObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
MessageFormat format;
|
||||
int formatCount = in.readInt();
|
||||
Format[] formats = new Format[formatCount];
|
||||
Locale locale;
|
||||
|
||||
for(int index = 0; index < formats.length; index++) {
|
||||
formats[index] = (Format) in.readObject();
|
||||
}//for//
|
||||
|
||||
locale = (Locale) in.readObject();
|
||||
|
||||
if(locale == null) {
|
||||
format = new MessageFormat(in.readUTF8());
|
||||
}//if//
|
||||
else {
|
||||
format = new MessageFormat(in.readUTF8(), locale);
|
||||
}//else//
|
||||
|
||||
if(formats != null) {
|
||||
format.setFormats(formats);
|
||||
}//if//
|
||||
|
||||
return format;
|
||||
}//deserialize()//
|
||||
}},
|
||||
{DecimalFormat.class, new ISerializationHandler() {
|
||||
public void serialize(Object value, IObjectOutputStream out) throws IOException {
|
||||
DecimalFormat format = (DecimalFormat) value;
|
||||
|
||||
out.writeUTF8(format.toPattern());
|
||||
}//serialize()//
|
||||
public Object deserialize(IObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
return new DecimalFormat(in.readUTF8());
|
||||
}//deserialize()//
|
||||
}},
|
||||
{ChoiceFormat.class, new ISerializationHandler() {
|
||||
public void serialize(Object value, IObjectOutputStream out) throws IOException {
|
||||
ChoiceFormat format = (ChoiceFormat) value;
|
||||
|
||||
out.writeUTF8(format.toPattern());
|
||||
}//serialize()//
|
||||
public Object deserialize(IObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
return new ChoiceFormat(in.readUTF8());
|
||||
}//deserialize()//
|
||||
}},
|
||||
{SimpleDateFormat.class, new ISerializationHandler() {
|
||||
public void serialize(Object value, IObjectOutputStream out) throws IOException {
|
||||
SimpleDateFormat format = (SimpleDateFormat) value;
|
||||
|
||||
out.writeUTF8(format.toPattern());
|
||||
out.writeUTF8(format.getTimeZone().getID());
|
||||
}//serialize()//
|
||||
public Object deserialize(IObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
SimpleDateFormat result = new SimpleDateFormat(in.readUTF8());
|
||||
|
||||
result.setTimeZone(TimeZone.getTimeZone(in.readUTF8()));
|
||||
return result;
|
||||
}//deserialize()//
|
||||
}},
|
||||
{java.util.Date.class, new ISerializationHandler() {
|
||||
public void serialize(Object value, IObjectOutputStream out) throws IOException {
|
||||
out.writeLong(((java.util.Date) value).getTime());
|
||||
}//serialize()//
|
||||
public Object deserialize(IObjectInputStream in) throws IOException {
|
||||
return new java.util.Date(in.readLong());
|
||||
}//deserialize()//
|
||||
}},
|
||||
{java.sql.Date.class, new ISerializationHandler() {
|
||||
public void serialize(Object value, IObjectOutputStream out) throws IOException {
|
||||
out.writeLong(((java.sql.Date) value).getTime());
|
||||
}//serialize()//
|
||||
public Object deserialize(IObjectInputStream in) throws IOException {
|
||||
return new java.sql.Date(in.readLong());
|
||||
}//deserialize()//
|
||||
}},
|
||||
{java.sql.Time.class, new ISerializationHandler() {
|
||||
public void serialize(Object value, IObjectOutputStream out) throws IOException {
|
||||
out.writeLong(((java.sql.Time) value).getTime());
|
||||
}//serialize()//
|
||||
public Object deserialize(IObjectInputStream in) throws IOException {
|
||||
return new java.sql.Time(in.readLong());
|
||||
}//deserialize()//
|
||||
}},
|
||||
{java.sql.Timestamp.class, new ISerializationHandler() {
|
||||
public void serialize(Object value, IObjectOutputStream out) throws IOException {
|
||||
out.writeLong(((java.sql.Timestamp) value).getTime());
|
||||
out.writeInt(((java.sql.Timestamp) value).getNanos());
|
||||
}//serialize()//
|
||||
public Object deserialize(IObjectInputStream in) throws IOException {
|
||||
java.sql.Timestamp result = new java.sql.Timestamp(in.readLong());
|
||||
|
||||
result.setNanos(in.readInt());
|
||||
|
||||
return result;
|
||||
}//deserialize()//
|
||||
}}
|
||||
});
|
||||
/**
|
||||
* ObjectStream constructor.
|
||||
*/
|
||||
private ObjectStream() {
|
||||
super();
|
||||
}//ObjectStream()//
|
||||
}//ObjectStream//
|
||||
34
Common/src/com/common/io/SignatureInputStream.java
Normal file
34
Common/src/com/common/io/SignatureInputStream.java
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.InputStream;
|
||||
import com.common.security.*;
|
||||
|
||||
/*
|
||||
* This class allows a signature stream to be plugged into an input stream so that read bytes are decrypted using the public key (verified).
|
||||
*/
|
||||
public class SignatureInputStream extends CryptoInputStream implements IInputStream {
|
||||
private ISignatureAlgorithm algorithm = null;
|
||||
/**
|
||||
* SignatureInputStream constructor.
|
||||
*/
|
||||
public SignatureInputStream(InputStream stream, ISignatureAlgorithm algorithm) {
|
||||
super(stream, algorithm);
|
||||
|
||||
this.algorithm = algorithm;
|
||||
this.encryptedBuffer = new byte[algorithm.getOptimalVerificationBlockSize()];
|
||||
this.decryptedBuffer = new byte[algorithm.getOptimalSignatureBlockSize()];
|
||||
}//SignatureInputStream()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.CryptoOutputStream#decrypt(byte[], int, int, byte[], int)
|
||||
*/
|
||||
protected int decrypt(byte[] data, int dataOffset, int dataLength, byte[] output, int outputOffset) {
|
||||
return algorithm.verify(data, dataOffset, dataLength, output, outputOffset);
|
||||
}//decrypt()//
|
||||
}//SignatureInputStream//
|
||||
34
Common/src/com/common/io/SignatureOutputStream.java
Normal file
34
Common/src/com/common/io/SignatureOutputStream.java
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import com.common.security.*;
|
||||
|
||||
/*
|
||||
* This class allows a signature stream to be plugged into an output stream so that written bytes are encrypted using the private key (signed).
|
||||
*/
|
||||
public class SignatureOutputStream extends CryptoOutputStream implements IOutputStream {
|
||||
private ISignatureAlgorithm algorithm = null;
|
||||
/**
|
||||
* SignatureOutputStream constructor.
|
||||
*/
|
||||
public SignatureOutputStream(OutputStream stream, ISignatureAlgorithm algorithm) {
|
||||
super(stream, algorithm);
|
||||
|
||||
this.algorithm = algorithm;
|
||||
this.encryptedBuffer = new byte[algorithm.getOptimalVerificationBlockSize()];
|
||||
this.decryptedBuffer = new byte[algorithm.getOptimalSignatureBlockSize()]; //The smaller buffer.//
|
||||
}//SignatureOutputStream()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.CryptoOutputStream#encrypt(byte[], int, int, byte[], int)
|
||||
*/
|
||||
protected int encrypt(byte[] data, int dataOffset, int dataLength, byte[] output, int outputOffset) {
|
||||
return algorithm.sign(data, dataOffset, dataLength, output, outputOffset);
|
||||
}//encrypt()//
|
||||
}//SignatureOutputStream//
|
||||
146
Common/src/com/common/io/StandardInputStream.java
Normal file
146
Common/src/com/common/io/StandardInputStream.java
Normal file
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class StandardInputStream extends AbstractStandardInputStream {
|
||||
private InputStream inputStream = null;
|
||||
/**
|
||||
* StandardInputStream constructor.
|
||||
*/
|
||||
public StandardInputStream(InputStream inputStream) {
|
||||
super();
|
||||
|
||||
if(inputStream == null) {
|
||||
throw new NullPointerException("Must provide a non-null input stream when constructing a StandardInputStream instance.");
|
||||
}//if//
|
||||
|
||||
this.inputStream = inputStream;
|
||||
}//StandardInputStream()//
|
||||
/**
|
||||
* Gets the number of available bytes in this input stream.
|
||||
* @return The count of bytes that may be immediatly read from the stream.
|
||||
*/
|
||||
public int available() throws IOException {
|
||||
return inputStream.available();
|
||||
}//available()//
|
||||
/**
|
||||
* @see IObjectInputStream.canDecrypt()
|
||||
*/
|
||||
public boolean canDecrypt() {
|
||||
return (inputStream instanceof IInputStream) && (((IInputStream) inputStream).canDecrypt());
|
||||
}//canDecrypt()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.InputStream#close()
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
inputStream.close();
|
||||
}//close()//
|
||||
/**
|
||||
* @see IObjectInputStream.decrypt(boolean)
|
||||
*/
|
||||
public void decrypt(boolean decrypt) throws IOException {
|
||||
if(inputStream instanceof IInputStream) {
|
||||
if(((IInputStream) inputStream).canDecrypt()) {
|
||||
((IInputStream) inputStream).decrypt(decrypt);
|
||||
}//if//
|
||||
else {
|
||||
throw new IOException(ERROR_DECRYPTION_NOT_SUPPORTED);
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
throw new IOException(ERROR_DECRYPTION_NOT_SUPPORTED);
|
||||
}//else//
|
||||
}//decrypt()//
|
||||
/**
|
||||
* Gets the encapsulated input stream.
|
||||
* @return Gets the input stream that this object wrappers.
|
||||
*/
|
||||
public InputStream getInputStream() {
|
||||
return inputStream;
|
||||
}//getInputStream()//
|
||||
/**
|
||||
* @see IObjectInputStream.isDecrypting()
|
||||
*/
|
||||
public boolean isDecrypting() {
|
||||
return (inputStream instanceof IInputStream) && (((IInputStream) inputStream).isDecrypting());
|
||||
}//isDecrypting()//
|
||||
/**
|
||||
* Marks the stream so that the reader can reset to the current position.
|
||||
* @param readLimit The number of bytes that may be read before the mark becomes invalid.
|
||||
*/
|
||||
public void mark(int readLimit) {
|
||||
inputStream.mark(readLimit);
|
||||
}//mark()//
|
||||
/**
|
||||
* Determines whether the stream supports using the mark method.
|
||||
* @return Whether the mark method is supported.
|
||||
*/
|
||||
public boolean markSupported() {
|
||||
return inputStream.markSupported();
|
||||
}//markSupported()//
|
||||
/**
|
||||
* Reads an unsigned byte from the stream.
|
||||
* @return The unsigned byte read from the stream.
|
||||
*/
|
||||
public int read() throws IOException {
|
||||
return inputStream.read();
|
||||
}//read()//
|
||||
/**
|
||||
* Reads bytes from the stream until the buffer is full or there are no more bytes in the stream.
|
||||
* @param buffer The buffer where the read bytes will be placed.
|
||||
* @return The number of bytes read into the buffer.
|
||||
*/
|
||||
public int read(byte[] buffer) throws IOException {
|
||||
return inputStream.read(buffer);
|
||||
}//read()//
|
||||
/**
|
||||
* Reads bytes from the stream until the buffer is full or there are no more bytes in the stream.
|
||||
* @param buffer The buffer where the read bytes will be placed.
|
||||
* @param offset The offset where the first read byte should be placed in the buffer.
|
||||
* @param length The number of bytes that should be read into the buffer.
|
||||
* @return The number of bytes read into the buffer.
|
||||
*/
|
||||
public int read(byte[] buffer, int offset, int length) throws IOException {
|
||||
return inputStream.read(buffer, offset, length);
|
||||
}//read()//
|
||||
/**
|
||||
* @see IInputStream.read(java.io.OutputStream, int)
|
||||
*/
|
||||
public int read(java.io.OutputStream out, int length) throws IOException {
|
||||
int retVal;
|
||||
|
||||
if(inputStream instanceof IInputStream) {
|
||||
retVal = ((IInputStream) inputStream).read(out,length);
|
||||
}//if//
|
||||
else {
|
||||
byte[] bytes = new byte[length];
|
||||
|
||||
retVal = inputStream.read(bytes, 0, bytes.length);
|
||||
out.write(bytes, 0, retVal);
|
||||
}//else//
|
||||
|
||||
return retVal;
|
||||
}//read()//
|
||||
/**
|
||||
* Resets the stream by telling the encapsulated stream to reset.
|
||||
*/
|
||||
public void reset() throws IOException {
|
||||
inputStream.reset();
|
||||
}//reset()//
|
||||
/**
|
||||
* Skips the next <code>count</code> bytes on the stream.
|
||||
* @param count The number of bytes to skip.
|
||||
* @return The number of bytes that were skipped.
|
||||
*/
|
||||
public long skip(long count) throws IOException {
|
||||
return inputStream.skip(count);
|
||||
}//skip()//
|
||||
}//StandardInputStream//
|
||||
108
Common/src/com/common/io/StandardOutputStream.java
Normal file
108
Common/src/com/common/io/StandardOutputStream.java
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class StandardOutputStream extends AbstractStandardOutputStream {
|
||||
private OutputStream outputStream = null;
|
||||
/**
|
||||
* StandardOutputStream constructor.
|
||||
* @param outputStream The stream to encapsulate.
|
||||
*/
|
||||
public StandardOutputStream(OutputStream outputStream) {
|
||||
super();
|
||||
|
||||
if(outputStream == null) {
|
||||
throw new NullPointerException("Must provide a non-null output stream when constructing a StandardOutputStream instance.");
|
||||
}//if//
|
||||
|
||||
this.outputStream = outputStream;
|
||||
}//StandardOutputStream()//
|
||||
/**
|
||||
* StandardOutputStream constructor.
|
||||
* @param outputStream The stream to encapsulate.
|
||||
* @param defaultNumberStyle One of the STYLE_xx identifiers. This defaults to most significant byte first.
|
||||
*/
|
||||
public StandardOutputStream(OutputStream outputStream, int defaultNumberStyle) {
|
||||
super(defaultNumberStyle);
|
||||
|
||||
if(outputStream == null) {
|
||||
throw new NullPointerException("Must provide a non-null output stream when constructing a StandardOutputStream instance.");
|
||||
}//if//
|
||||
|
||||
this.outputStream = outputStream;
|
||||
}//StandardOutputStream()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.AbstractStandardOutputStream#canEncrypt()
|
||||
*/
|
||||
public boolean canEncrypt() {
|
||||
return (outputStream instanceof IOutputStream) && (((IOutputStream) outputStream).canEncrypt());
|
||||
}//canEncrypt()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.OutputStream#close()
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
outputStream.close();
|
||||
}//close()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.AbstractStandardOutputStream#encrypt(boolean)
|
||||
*/
|
||||
public void encrypt(boolean encrypt) throws IOException {
|
||||
if(outputStream instanceof IOutputStream) {
|
||||
if(((IOutputStream) outputStream).canEncrypt()) {
|
||||
flush();
|
||||
((IOutputStream) outputStream).encrypt(encrypt);
|
||||
}//if//
|
||||
else {
|
||||
throw new IOException(ERROR_ENCRYPTION_NOT_SUPPORTED);
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
throw new IOException(ERROR_ENCRYPTION_NOT_SUPPORTED);
|
||||
}//else//
|
||||
}//encrypt()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.AbstractStandardOutputStream#isEncrypting()
|
||||
*/
|
||||
public boolean isEncrypting() {
|
||||
return (outputStream instanceof IOutputStream) && (((IOutputStream) outputStream).isEncrypting());
|
||||
}//isEncrypting()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.AbstractStandardOutputStream#flush()
|
||||
*/
|
||||
public void flush() throws IOException {
|
||||
outputStream.flush();
|
||||
}//flush()//
|
||||
/**
|
||||
* Gets the encapsulated output stream.
|
||||
* @return Gets the output stream that this object wrappers.
|
||||
*/
|
||||
public OutputStream getOutputStream() {
|
||||
return outputStream;
|
||||
}//getOutputStream()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.AbstractStandardOutputStream#write(byte[])
|
||||
*/
|
||||
public void write(byte[] bytes) throws IOException {
|
||||
outputStream.write(bytes);
|
||||
}//write()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.AbstractStandardOutputStream#write(byte[], int, int)
|
||||
*/
|
||||
public void write(byte[] bytes, int offset, int length) throws IOException {
|
||||
outputStream.write(bytes, offset, length);
|
||||
}//write()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.AbstractStandardOutputStream#write(int)
|
||||
*/
|
||||
public void write(int b) throws IOException {
|
||||
outputStream.write(b);
|
||||
}//write()//
|
||||
}//StandardOutputStream//
|
||||
3191
Common/src/com/common/io/StreamSupport.java
Normal file
3191
Common/src/com/common/io/StreamSupport.java
Normal file
File diff suppressed because it is too large
Load Diff
37
Common/src/com/common/io/StringBufferPrintWriter.java
Normal file
37
Common/src/com/common/io/StringBufferPrintWriter.java
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2006 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/*
|
||||
* A print writer that simply wrappers a string buffer and whose string can be retreived by calling toString().
|
||||
* This is useful for retrieving a stack trace using <code>exception.printStackTrace(PrintWriter)</code>.
|
||||
*/
|
||||
public class StringBufferPrintWriter extends PrintWriter {
|
||||
/**
|
||||
* StringBufferPrintWriter constructor.
|
||||
* @param file
|
||||
* @throws FileNotFoundException
|
||||
*/
|
||||
public StringBufferPrintWriter(StringBuffer buffer) {
|
||||
super(new StringBufferWriter(buffer));
|
||||
}//StringBufferPrintWriter()//
|
||||
/**
|
||||
* StringBufferPrintWriter constructor.
|
||||
*/
|
||||
public StringBufferPrintWriter() {
|
||||
super(new StringBufferWriter(new StringBuffer(1000)));
|
||||
}//StringBufferPrintWriter()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
return ((StringBufferWriter) out).toString();
|
||||
}//toString()//
|
||||
}//StringBufferPrintWriter//
|
||||
63
Common/src/com/common/io/StringBufferWriter.java
Normal file
63
Common/src/com/common/io/StringBufferWriter.java
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2006 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
/*
|
||||
* A writer that simply wrappers a string buffer and whose string can be retreived by calling toString().
|
||||
*/
|
||||
public class StringBufferWriter extends Writer {
|
||||
private StringBuffer buffer = null;
|
||||
private boolean isClosed = false;
|
||||
/**
|
||||
* StringBufferWriter constructor.
|
||||
*/
|
||||
public StringBufferWriter() {
|
||||
super();
|
||||
this.buffer = new StringBuffer(1000);
|
||||
}//StringBufferWriter()//
|
||||
/**
|
||||
* StringBufferWriter constructor.
|
||||
* @param buffer The buffer to be appended to.
|
||||
*/
|
||||
public StringBufferWriter(StringBuffer buffer) {
|
||||
super();
|
||||
this.buffer = buffer;
|
||||
}//StringBufferWriter()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.Writer#write(char[], int, int)
|
||||
*/
|
||||
public void write(char[] cbuf, int off, int len) throws IOException {
|
||||
if(!isClosed) {
|
||||
buffer.append(cbuf, off, len);
|
||||
}//if//
|
||||
else {
|
||||
throw new IOException("Closed writer cannot be written to.");
|
||||
}//else//
|
||||
}//write()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.Writer#flush()
|
||||
*/
|
||||
public void flush() throws IOException {
|
||||
//Does nothing.//
|
||||
}//flush()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.Writer#close()
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
isClosed = true;
|
||||
}//close()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
return buffer.toString();
|
||||
}//toString()//
|
||||
}//StringBufferWriter//
|
||||
34
Common/src/com/common/io/SymmetricInputStream.java
Normal file
34
Common/src/com/common/io/SymmetricInputStream.java
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.InputStream;
|
||||
import com.common.security.*;
|
||||
|
||||
/*
|
||||
* This class allows an symmetricly encrypted stream to be plugged into an input stream so that read bytes are decrypted using the private key.
|
||||
*/
|
||||
public class SymmetricInputStream extends CryptoInputStream implements IInputStream {
|
||||
private ISymmetricAlgorithm algorithm = null;
|
||||
/**
|
||||
* SymmetricInputStream constructor.
|
||||
*/
|
||||
public SymmetricInputStream(InputStream stream, ISymmetricAlgorithm algorithm) {
|
||||
super(stream, algorithm);
|
||||
|
||||
this.algorithm = algorithm;
|
||||
this.encryptedBuffer = new byte[algorithm.getOptimalDecryptionBlockSize()];
|
||||
this.decryptedBuffer = new byte[algorithm.getOptimalEncryptionBlockSize()];
|
||||
}//SymmetricInputStream()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.CryptoOutputStream#decrypt(byte[], int, int, byte[], int)
|
||||
*/
|
||||
protected int decrypt(byte[] data, int dataOffset, int dataLength, byte[] output, int outputOffset) {
|
||||
return algorithm.decrypt(data, dataOffset, dataLength, output, outputOffset);
|
||||
}//decrypt()//
|
||||
}//SymmetricInputStream//
|
||||
34
Common/src/com/common/io/SymmetricOutputStream.java
Normal file
34
Common/src/com/common/io/SymmetricOutputStream.java
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.io;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import com.common.security.*;
|
||||
|
||||
/*
|
||||
* This class allows an asymmetric stream to be plugged into an output stream so that written bytes are encrypted using the public key.
|
||||
*/
|
||||
public class SymmetricOutputStream extends CryptoOutputStream implements IOutputStream {
|
||||
private ISymmetricAlgorithm algorithm = null;
|
||||
/**
|
||||
* AsymmetricOutputStream constructor.
|
||||
*/
|
||||
public SymmetricOutputStream(OutputStream stream, ISymmetricAlgorithm algorithm) {
|
||||
super(stream, algorithm);
|
||||
|
||||
this.algorithm = algorithm;
|
||||
this.encryptedBuffer = new byte[algorithm.getOptimalDecryptionBlockSize()];
|
||||
this.decryptedBuffer = new byte[algorithm.getOptimalEncryptionBlockSize()];
|
||||
}//AsymmetricOutputStream()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.CryptoOutputStream#encrypt(byte[], int, int, byte[], int)
|
||||
*/
|
||||
protected int encrypt(byte[] data, int dataOffset, int dataLength, byte[] output, int outputOffset) {
|
||||
return algorithm.encrypt(data, dataOffset, dataLength, output, outputOffset);
|
||||
}//encrypt()//
|
||||
}//SymmetricOutputStream//
|
||||
229
Common/src/com/common/orb/Address.java
Normal file
229
Common/src/com/common/orb/Address.java
Normal file
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.orb;
|
||||
|
||||
import com.common.comparison.Comparator;
|
||||
import com.common.debug.*;
|
||||
|
||||
public class Address implements IAddress {
|
||||
public static final int INVALID_PORT = -1;
|
||||
|
||||
private String name = null;
|
||||
private int port = INVALID_PORT;
|
||||
private String resource = null;
|
||||
/**
|
||||
* Address constructor.
|
||||
*/
|
||||
public Address() {
|
||||
this(null, -1, null);
|
||||
}//Address()//
|
||||
/**
|
||||
* Address constructor.
|
||||
* @param address The address in string form which follows the URL rules.
|
||||
*/
|
||||
public Address(String address) {
|
||||
super();
|
||||
|
||||
parseAddress(address);
|
||||
}//Address()//
|
||||
/**
|
||||
* Address constructor.
|
||||
* @param name The address URL or IP address.
|
||||
* @param port The address port number.
|
||||
*/
|
||||
public Address(String name, int port) {
|
||||
this(name, port, null);
|
||||
}//Address()//
|
||||
/**
|
||||
* Address constructor.
|
||||
* <p>Note: At least one of the parameters should normally be non-null. Some methods will require that multiple parameters be non-null.</p>
|
||||
* @param name The address URL or IP address.
|
||||
* @param port The address port number.
|
||||
* @param resource The referenced resource at the address.
|
||||
*/
|
||||
public Address(String name, int port, String resource) {
|
||||
super();
|
||||
|
||||
this.name = name;
|
||||
this.port = port;
|
||||
this.resource = resource;
|
||||
}//Address()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#clone()
|
||||
*/
|
||||
public Object clone() throws CloneNotSupportedException {
|
||||
return super.clone();
|
||||
}//clone()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return port ^ (name != null ? name.hashCode() : 0) ^ (resource != null ? resource.hashCode() : 0);
|
||||
}//hashCode()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object object) {
|
||||
return object instanceof Address && ((Address) object).port == port && Comparator.equals(((Address) object).name, name) && Comparator.equals(((Address) object).resource, resource);
|
||||
}//equals()//
|
||||
/**
|
||||
* Gets the ip address or machine name that identifies the first part of the address.
|
||||
* @return The IP or URL name of the computer being addressed.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}//getName()//
|
||||
/**
|
||||
* Gets the port number that identifies the second part of the address.
|
||||
* @return The addressed computer's port identifying the listener (server socket) being addressed.
|
||||
*/
|
||||
public int getPort() {
|
||||
return port;
|
||||
}//getPort()//
|
||||
/**
|
||||
* Gets the name of the resource that is being referenced at the address.
|
||||
* @return The addressed resource's name.
|
||||
*/
|
||||
public String getResource() {
|
||||
return resource;
|
||||
}//getResource()//
|
||||
/**
|
||||
* Parses the address from a string containing the name and port in the format (or variation of): [protocol]://[name]:[port]/[object].
|
||||
* @param address The address in string form.
|
||||
*/
|
||||
private void parseAddress(String address) {
|
||||
address = address.trim();
|
||||
|
||||
try {
|
||||
int lastIndex = 0;
|
||||
int index = address.indexOf("://", lastIndex);
|
||||
|
||||
//Try both slash directions.//
|
||||
if(index == -1) {
|
||||
index = address.indexOf(":\\\\", lastIndex);
|
||||
}//if//
|
||||
|
||||
//Ignore beginning protocol and slashes.//
|
||||
if(index != -1) {
|
||||
//TODO: Capture the protocol.//
|
||||
lastIndex = index + 3;
|
||||
}//if//
|
||||
|
||||
index = address.indexOf("//", lastIndex);
|
||||
|
||||
//Try both slash directions.//
|
||||
if(index == -1) {
|
||||
index = address.indexOf("\\\\", lastIndex);
|
||||
}//if//
|
||||
|
||||
//Ignore beginning slashes.//
|
||||
if(index != -1) {
|
||||
lastIndex = index + 2;
|
||||
}//if//
|
||||
|
||||
index = address.indexOf(':', lastIndex);
|
||||
|
||||
//Capture the name and or port.//
|
||||
if((index != -1) && (address.indexOf('/', lastIndex) != lastIndex) && (address.indexOf('\\', lastIndex) != lastIndex)) {
|
||||
int index2 = 0;
|
||||
|
||||
if(index != lastIndex) {
|
||||
name = address.substring(lastIndex, index);
|
||||
}//if//
|
||||
|
||||
lastIndex = index + 1;
|
||||
index = address.indexOf('/', lastIndex);
|
||||
index2 = address.indexOf("\\", lastIndex);
|
||||
index = (index2 != -1) && (index2 < index) ? index2 : index;
|
||||
|
||||
if(index == -1) {
|
||||
port = Integer.parseInt(address.substring(lastIndex));
|
||||
lastIndex = -1;
|
||||
}//if//
|
||||
else {
|
||||
port = Integer.parseInt(address.substring(lastIndex, index));
|
||||
lastIndex = index;
|
||||
}//else//
|
||||
}//if//
|
||||
|
||||
if((lastIndex != -1) && (name == null) && (address.indexOf('/', lastIndex) != lastIndex) && (address.indexOf('\\', lastIndex) != lastIndex)) {
|
||||
int index2 = address.indexOf("\\", lastIndex);
|
||||
|
||||
index = address.indexOf('/', lastIndex);
|
||||
index = (index2 != -1) && (index2 < index) ? index2 : index;
|
||||
|
||||
if(index == -1) {
|
||||
name = address.substring(lastIndex);
|
||||
lastIndex = -1;
|
||||
}//if//
|
||||
else {
|
||||
name = address.substring(lastIndex, index);
|
||||
lastIndex = index + 1;
|
||||
}//else//
|
||||
}//if//
|
||||
|
||||
//Read the resource name.//
|
||||
if(lastIndex != -1) {
|
||||
if(address.startsWith("\\", lastIndex) || address.startsWith("/", lastIndex)) {
|
||||
lastIndex++;
|
||||
}//if//
|
||||
|
||||
resource = address.substring(lastIndex);
|
||||
}//if//
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
Debug.log(e);
|
||||
Debug.halt();
|
||||
}//catch//
|
||||
}//parseAddress()//
|
||||
/**
|
||||
* Sets the ip address or machine name that identifies the first part of the address.
|
||||
* @param name The IP or URL name of the computer being addressed.
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}//setName()//
|
||||
/**
|
||||
* Sets the port number that identifies the second part of the address.
|
||||
* @param port The addressed computer's port identifying the listener (server socket) being addressed.
|
||||
*/
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}//setPort()//
|
||||
/**
|
||||
* Sets the name of the resource that is being referenced at the address.
|
||||
* @param resource The addressed resource's name.
|
||||
*/
|
||||
public void setResource(String resource) {
|
||||
this.resource = resource;
|
||||
}//setResource()//
|
||||
/**
|
||||
* Gets a string representation of the address.
|
||||
* @return A representation of the address in string form.
|
||||
*/
|
||||
public String toString() {
|
||||
String result = "";
|
||||
|
||||
if(name != null) {
|
||||
result += name;
|
||||
|
||||
if(port != INVALID_PORT) {
|
||||
result += ":" + port;
|
||||
}//if//
|
||||
}//if//
|
||||
else if(port != INVALID_PORT) {
|
||||
result += "<any>:" + port;
|
||||
}//else if//
|
||||
|
||||
if(resource != null) {
|
||||
result += '/' + resource;
|
||||
}//if//
|
||||
|
||||
return result;
|
||||
}//toString()//
|
||||
}//Address//
|
||||
45
Common/src/com/common/orb/IAddress.java
Normal file
45
Common/src/com/common/orb/IAddress.java
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2008 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.orb;
|
||||
|
||||
public interface IAddress {
|
||||
/**
|
||||
* Gets the ip address or machine name that identifies the first part of the address.
|
||||
* @return The IP or URL name of the computer being addressed.
|
||||
*/
|
||||
public String getName();
|
||||
/**
|
||||
* Gets the port number that identifies the second part of the address.
|
||||
* @return The addressed computer's port identifying the listener (server socket) being addressed.
|
||||
*/
|
||||
public int getPort();
|
||||
/**
|
||||
* Gets the name of the resource that is being referenced at the address.
|
||||
* @return The addressed resource's name.
|
||||
*/
|
||||
public String getResource();
|
||||
/**
|
||||
* Sets the ip address or machine name that identifies the first part of the address.
|
||||
* @param name The IP or URL name of the computer being addressed.
|
||||
*/
|
||||
public void setName(String name);
|
||||
/**
|
||||
* Sets the port number that identifies the second part of the address.
|
||||
* @param port The addressed computer's port identifying the listener (server socket) being addressed.
|
||||
*/
|
||||
public void setPort(int port);
|
||||
/**
|
||||
* Sets the name of the resource that is being referenced at the address.
|
||||
* @param resource The addressed resource's name.
|
||||
*/
|
||||
public void setResource(String resource);
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#clone()
|
||||
*/
|
||||
public Object clone() throws CloneNotSupportedException;
|
||||
}//IAddress//
|
||||
23
Common/src/com/common/orb/IInvalidProxyListener.java
Normal file
23
Common/src/com/common/orb/IInvalidProxyListener.java
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.orb;
|
||||
|
||||
/**
|
||||
* Allows the application to register to be notified when a proxy object is no longer valid and should no longer be used.
|
||||
* This handler will be called if the proxy's socket is closed, or if the proxy experiences an error it cannot recover from.
|
||||
* @see Orb.registerInvalidProxyListener(Object, IInvalidProxyListener)
|
||||
* @see Orb.unregisterInvalidProxyListener(Object, IInvalidProxyListener)
|
||||
*/
|
||||
public interface IInvalidProxyListener {
|
||||
/**
|
||||
* Handles the invalid proxy event. This could be caused by the proxy's socket closing, or due to an error that could not be recovered from.
|
||||
* <p>This handler should complete in a timely manner so that the proxy can notify other listeners.</p>
|
||||
* @param proxy The proxy that is no longer valid.
|
||||
*/
|
||||
public void evaluate(Object proxy);
|
||||
}//IInvalidProxyListener//
|
||||
134
Common/src/com/common/orb/IOrbWrapper.java
Normal file
134
Common/src/com/common/orb/IOrbWrapper.java
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.orb;
|
||||
|
||||
import com.common.event.ObjectHandler1;
|
||||
import com.common.util.*;
|
||||
|
||||
/**
|
||||
* The orb wrapper interface should be extended for the perticular orb you want the system to use.
|
||||
* <p>NOTE: All major pieces of functionality MUST be supported or some services may not work properly.</p>
|
||||
*/
|
||||
public interface IOrbWrapper {
|
||||
/**
|
||||
* @see com.common.orb.Orb.bind(Object, Object, LiteHashSet)
|
||||
*/
|
||||
public void bind(Object object, Object resource, LiteHashSet permissions);
|
||||
/**
|
||||
* @see com.common.orb.Orb.checkExactEquality(Object, Object)
|
||||
*/
|
||||
public boolean checkExactEquality(Object object1, Object object2);
|
||||
/**
|
||||
* @see com.common.orb.Orb.closeServerSocket(Object)
|
||||
*/
|
||||
public void closeServerSocket(Object serverSocketIdentifier) throws java.io.IOException;
|
||||
/**
|
||||
* @see com.common.orb.Orb.closeSocket(Object)
|
||||
*/
|
||||
public void closeSocket(Object socketIdentifier) throws java.io.IOException;
|
||||
/**
|
||||
* @see com.common.orb.Orb.closeSocket(Object, long)
|
||||
*/
|
||||
public void closeSocket(Object socketIdentifier, long delayTime) throws java.io.IOException;
|
||||
/**
|
||||
* @see com.common.orb.Orb.closeSocket(String)
|
||||
*/
|
||||
public void closeSocket(String socketName) throws java.io.IOException;
|
||||
/**
|
||||
* @see com.common.orb.Orb.closeSocket(String, long)
|
||||
*/
|
||||
public void closeSocket(String socketName, long delayTime) throws java.io.IOException;
|
||||
/**
|
||||
* @see com.common.orb.Orb.getConnectionIdentifier(Object)
|
||||
*/
|
||||
public Object getConnectionIdentifier(Object proxy) throws IllegalArgumentException;
|
||||
/**
|
||||
* @see com.common.orb.Orb.getLocal(Object)
|
||||
*/
|
||||
public Object getLocal(Object object);
|
||||
/**
|
||||
* @see com.common.orb.Orb.getNonProxyClass(Object)
|
||||
*/
|
||||
public Class getNonProxyClass(Object object) throws ClassNotFoundException;
|
||||
/**
|
||||
* @see com.common.orb.Orb.getNonProxyClassName(Object)
|
||||
*/
|
||||
public String getNonProxyClassName(Object object);
|
||||
/**
|
||||
* @see com.common.orb.Orb.getProxy(Object, Class)
|
||||
*/
|
||||
public Object getProxy(Object object, Class type) throws IllegalArgumentException;
|
||||
/**
|
||||
* @see com.common.orb.Orb.isInvalidProxyException(Throwable)
|
||||
*/
|
||||
public boolean isInvalidProxyException(Throwable exception);
|
||||
/**
|
||||
* @see com.common.orb.Orb.isLocal(Object)
|
||||
*/
|
||||
public boolean isLocal(Object object);
|
||||
/**
|
||||
* @see com.common.orb.Orb.isProxy(Object)
|
||||
*/
|
||||
public boolean isProxy(Object object);
|
||||
/**
|
||||
* @see com.common.orb.Orb.isProxyValid(Object)
|
||||
*/
|
||||
public boolean isProxyValid(Object object);
|
||||
/**
|
||||
* @see com.common.orb.Orb.isTimeoutException(Throwable)
|
||||
*/
|
||||
public boolean isTimeoutException(Throwable exception);
|
||||
/**
|
||||
* @see com.common.orb.Orb.lookup(Object, Object)
|
||||
*/
|
||||
public Object lookup(Object resource, Object socketId);
|
||||
/**
|
||||
* @see com.common.orb.Orb.openServerSocket(String, Object)
|
||||
*/
|
||||
public Object openServerSocket(String socketName, Object serverSocketOptions) throws java.io.IOException;
|
||||
/**
|
||||
* @see com.common.orb.Orb.openSocket(String, Object)
|
||||
*/
|
||||
public Object openSocket(String socketName, Object socketOptions) throws java.io.IOException;
|
||||
/**
|
||||
* @see com.common.orb.Orb.registerInvalidProxyListener(Object, IInvalidProxyListener)
|
||||
*/
|
||||
public void registerInvalidProxyListener(Object proxy, IInvalidProxyListener invalidProxyListener);
|
||||
/**
|
||||
* @see com.common.orb.Orb.sendAgent(Object, Object, boolean, long, IResultCallback)
|
||||
*/
|
||||
public Object sendAgent(Object agent, Object connection, boolean isOneWay, long timeout, IResultCallback callback);
|
||||
/**
|
||||
* @see com.common.orb.Orb.setAutoProxy(Object, Class)
|
||||
*/
|
||||
public void setAutoProxy(Object object, Class interfaceType);
|
||||
/**
|
||||
* @see com.common.orb.Orb.setAutoProxy(Object, Class, com.common.event.ObjectHandler1)
|
||||
*/
|
||||
public void setAutoMorph(Object object, Class interfaceType, ObjectHandler1 morphHandler);
|
||||
/**
|
||||
* @see com.common.orb.Orb.setCallTimeout(Object, long)
|
||||
*/
|
||||
public void setCallTimeout(Object object, long timeout);
|
||||
/**
|
||||
* @see com.common.orb.Orb.setOneWayCall(Object)
|
||||
*/
|
||||
public void setOneWayCall(Object object);
|
||||
/**
|
||||
* @see com.common.orb.Orb.setResultCallback(Object, IResultCallback)
|
||||
*/
|
||||
public void setResultCallback(Object object, IResultCallback callback);
|
||||
/**
|
||||
* @see com.common.orb.Orb.unregisterInvalidProxyListener(Object, IInvalidProxyListener)
|
||||
*/
|
||||
public void unregisterInvalidProxyListener(Object proxy, IInvalidProxyListener invalidProxyListener);
|
||||
/**
|
||||
* @see com.common.orb.Orb.shutdown()
|
||||
*/
|
||||
public void shutdown();
|
||||
}//IOrbWrapper//
|
||||
19
Common/src/com/common/orb/IResultCallback.java
Normal file
19
Common/src/com/common/orb/IResultCallback.java
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.orb;
|
||||
|
||||
/**
|
||||
* Defines the method the orb will call when a bi-directional remote call has returned a result.
|
||||
*/
|
||||
public interface IResultCallback {
|
||||
/**
|
||||
* Called by the Orb when the result of a remote call is received.
|
||||
* @param result The result of the remote call.
|
||||
*/
|
||||
public void run(Object result);
|
||||
}//IResultCallback//
|
||||
349
Common/src/com/common/orb/Orb.java
Normal file
349
Common/src/com/common/orb/Orb.java
Normal file
@@ -0,0 +1,349 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.orb;
|
||||
|
||||
import com.common.event.ObjectHandler1;
|
||||
import com.common.util.*;
|
||||
|
||||
/**
|
||||
* This orb class is a static interface to what ever orb is being used by the system.
|
||||
*/
|
||||
public class Orb {
|
||||
private static IOrbWrapper _orbWrapper = null;
|
||||
/**
|
||||
* Orb constructor.
|
||||
* <p>NOTE: An instance of this class should never be created.</p>
|
||||
*/
|
||||
protected Orb() {
|
||||
super();
|
||||
}//Orb//
|
||||
/**
|
||||
* Binds an object to a resource with specified permissions.
|
||||
* @param object The object to bind to the resource. If this is null then any previous binding for the resource will be removed.
|
||||
* @param resource The application defined non-null resource to bind the object to. This resource is how other processes can identify the bound object. The resource should be capable of logical comparison and serialization.
|
||||
* @param permissions The application defined permission set. If this value is null then all clients or peers will have permissions to the bound object.
|
||||
*/
|
||||
public static void bind(Object object, Object resource, LiteHashSet permissions) {
|
||||
IOrbWrapper wrapper = getOrbWrapper();
|
||||
|
||||
//TODO: Should probably throw an exception if the wrapper is null.//
|
||||
wrapper.bind(object, resource, permissions);
|
||||
}//bind()//
|
||||
/**
|
||||
* Checks two objects to see if they are exactly equal. Either, both, or neither object may be a proxy. If possible the IComparable interface will be utilized.
|
||||
* @param object1 The first object to compare.
|
||||
* @param object2 The second object that is compared.
|
||||
* @return Whether the two objects are exactly equal, if one object proxies another, or they both proxy the same object.
|
||||
*/
|
||||
public static boolean checkExactEquality(Object object1, Object object2) {
|
||||
IOrbWrapper wrapper = getOrbWrapper();
|
||||
|
||||
return wrapper != null ? getOrbWrapper().checkExactEquality(object1, object2) : object1 == object2;
|
||||
}//checkExactEquality()//
|
||||
/**
|
||||
* Closes the server socket immediatly (if the reference count reaches zero).
|
||||
* @param serverSocketIdentifier The identifier for the server socket to be closed.
|
||||
*/
|
||||
public static void closeServerSocket(Object serverSocketIdentifier) throws java.io.IOException {
|
||||
getOrbWrapper().closeServerSocket(serverSocketIdentifier);
|
||||
}//closeServerSocket()//
|
||||
/**
|
||||
* Closes the socket immediatly (if the reference count reaches zero).
|
||||
* @param socketIdentifier The identifier for the socket to be closed.
|
||||
*/
|
||||
public static void closeSocket(Object socketIdentifier) throws java.io.IOException {
|
||||
getOrbWrapper().closeSocket(socketIdentifier);
|
||||
}//closeSocket()//
|
||||
/**
|
||||
* Closes the socket (if the reference count reaches zero).
|
||||
* @param socketIdentifier The identifier for the socket to be closed.
|
||||
* @param delayTime The amount of time in milliseconds to wait before closing the socket. <b>Note: This method returns immediatly. The closing is scheduled and it will only be as accurate as the scheduler allows.</b>
|
||||
*/
|
||||
public static void closeSocket(Object socketIdentifier, long delayTime) throws java.io.IOException {
|
||||
getOrbWrapper().closeSocket(socketIdentifier, delayTime);
|
||||
}//closeSocket()//
|
||||
/**
|
||||
* Closes the socket immediatly (if the reference count reaches zero).
|
||||
* @param socketName The name of the socket to be closed.
|
||||
*/
|
||||
public static void closeSocket(String socketName) throws java.io.IOException {
|
||||
getOrbWrapper().closeSocket(socketName);
|
||||
}//closeSocket()//
|
||||
/**
|
||||
* Closes the socket (if the reference count reaches zero).
|
||||
* @param socketName The name of the socket to be closed.
|
||||
* @param delayTime The amount of time in milliseconds to wait before closing the socket. <b>Note: This method returns immediatly. The closing is scheduled and it will only be as accurate as the scheduler allows.</b>
|
||||
*/
|
||||
public static void closeSocket(String socketName, long delayTime) throws java.io.IOException {
|
||||
getOrbWrapper().closeSocket(socketName, delayTime);
|
||||
}//closeSocket()//
|
||||
/**
|
||||
* Gets the next network connection identifier for the given proxy.
|
||||
* @param proxy A remote proxy object.
|
||||
* @return The network connection identifier object for the first hop toward the proxied object, or null if the passed object is not a proxy.
|
||||
*/
|
||||
public static Object getConnectionIdentifier(Object proxy) throws IllegalArgumentException {
|
||||
return getOrbWrapper() == null ? null : getOrbWrapper().getConnectionIdentifier(proxy);
|
||||
}//getConnectionIdentifier()//
|
||||
/**
|
||||
* Gets the local object for a possible proxy object.
|
||||
* @param object Either a proxy that has a local reference to the proxied object, or a non-proxy object.
|
||||
* @return Will get the local object from the proxy, or will return the passed object if it is not a proxy.
|
||||
* @see #isLocal(Object)
|
||||
*/
|
||||
public static Object getLocal(Object object) {
|
||||
IOrbWrapper wrapper = getOrbWrapper();
|
||||
|
||||
return wrapper != null ? wrapper.getLocal(object) : object;
|
||||
}//getLocal()//
|
||||
/**
|
||||
* Gets the class for the passed object. If the passed object is a proxy then the proxied object's class will be returned.
|
||||
* @param object The object whose class is desired.
|
||||
* @return The object's class.
|
||||
*/
|
||||
public static Class getNonProxyClass(Object object) throws ClassNotFoundException {
|
||||
IOrbWrapper wrapper = getOrbWrapper();
|
||||
|
||||
return wrapper != null ? wrapper.getNonProxyClass(object) : object.getClass();
|
||||
}//getNonProxyClass()//
|
||||
/**
|
||||
* Gets the class name for the passed object. If the passed object is a proxy then the proxied object's class name will be returned.
|
||||
* <p>NOTE: This method should <b>NOT</b> load the proxied class!
|
||||
* @param object The object whose class name is desired.
|
||||
* @return The name of the class.
|
||||
*/
|
||||
public static String getNonProxyClassName(Object object) {
|
||||
IOrbWrapper wrapper = getOrbWrapper();
|
||||
|
||||
return wrapper != null ? wrapper.getNonProxyClassName(object) : object.getClass().getName();
|
||||
}//getNonProxyClassName()//
|
||||
/**
|
||||
* Gets the orb wrapper object that is being used by the system.
|
||||
* @return The orb wrapper that will interface the application to the desired orb.
|
||||
*/
|
||||
public static IOrbWrapper getOrbWrapper() {
|
||||
return _orbWrapper;
|
||||
}//getOrbWrapper()//
|
||||
/**
|
||||
* Creates a proxy to the passed object such that the proxy implements the provided interface.
|
||||
* @param object Creates a proxy for this object. If this object is already a proxy then it will just be returned. <b>Note: If this is already a proxy then no furthor action will be taken.</b>
|
||||
* @param type The class that the proxy will implement. <b>Note: This must be an interface that the object implements!</b>
|
||||
* @return The proxy object that wrappers the passed object.
|
||||
*/
|
||||
public static Object getProxy(Object object, Class type) throws IllegalArgumentException {
|
||||
Object result = null;
|
||||
|
||||
if(object != null && getOrbWrapper() != null) {
|
||||
result = getOrbWrapper().getProxy(object, type);
|
||||
}//if//
|
||||
else {
|
||||
//The orb has not been setup, and thus proxies cannot be created.//
|
||||
//This should not be an error because while proxies cannot be created, objects cannot also be remote.//
|
||||
result = object;
|
||||
}//else//
|
||||
|
||||
return result;
|
||||
}//getProxy()//
|
||||
/**
|
||||
* Determines whether the passed exception is an invalid proxy exception.
|
||||
* <p>This method allows an application to properly separate the Orb interface from the implementation. It should be called instead of directly catching the exception if the application wants to be able to swap one orb for another without code changes.</p>
|
||||
* @param exception The throwable exception that might be an invalid proxy exception thrown by the orb.
|
||||
* @return Whether the exception does indicate that a proxy is invalid.
|
||||
*/
|
||||
public static boolean isInvalidProxyException(Throwable exception) {
|
||||
IOrbWrapper wrapper = getOrbWrapper();
|
||||
|
||||
return wrapper != null ? wrapper.isInvalidProxyException(exception) : false;
|
||||
}//isInvalidProxyException()//
|
||||
/**
|
||||
* Checks an object to determine if it is a proxy.
|
||||
* @param object The object to be checked.
|
||||
* @return Will be <code>true</code> if the passed object is either not a proxy, or is a local proxy.
|
||||
*/
|
||||
public static boolean isLocal(Object object) {
|
||||
IOrbWrapper wrapper = getOrbWrapper();
|
||||
|
||||
return wrapper != null ? wrapper.isLocal(object) : true;
|
||||
}//isLocal()//
|
||||
/**
|
||||
* Checks an object to determine if it is a proxy.
|
||||
* @param object The object to be checked.
|
||||
* @return Will be true if the passed object is a proxy.
|
||||
*/
|
||||
public static boolean isProxy(Object object) {
|
||||
IOrbWrapper wrapper = getOrbWrapper();
|
||||
|
||||
return wrapper != null ? wrapper.isProxy(object) : false;
|
||||
}//isProxy()//
|
||||
/**
|
||||
* Checks an object to determine if it is a proxy.
|
||||
* @param object The object to be checked.
|
||||
* @return Will be true if the passed object is not a proxy or is a valid proxy and is not null.
|
||||
*/
|
||||
public static boolean isProxyValid(Object object) {
|
||||
IOrbWrapper wrapper = getOrbWrapper();
|
||||
|
||||
return (object != null) && (wrapper != null) ? wrapper.isProxyValid(object) : object != null;
|
||||
}//isProxyValid()//
|
||||
/**
|
||||
* Determines whether the passed exception is a timeout exception.
|
||||
* <p>This method allows an application to properly separate the Orb interface from the implementation. It should be called instead of directly catching the exception if the application wants to be able to swap one orb for another without code changes.</p>
|
||||
* @param exception The throwable exception that might be a timeout exception thrown by the orb.
|
||||
* @return Whether the exception does indicate that a timeout occured.
|
||||
*/
|
||||
public static boolean isTimeoutException(Throwable exception) {
|
||||
IOrbWrapper wrapper = getOrbWrapper();
|
||||
|
||||
return wrapper != null ? wrapper.isTimeoutException(exception) : false;
|
||||
}//isTimeoutException()//
|
||||
/**
|
||||
* Looks up an object previously bound to an application defined resource.
|
||||
* @param resource The application defined resource the requested object is bound to. This must be serializeable (or externalizable), and it is usually a string.
|
||||
* @param socketId The object that identifies the socket (returned when the socket was created), or the name of the socket.
|
||||
*/
|
||||
public static Object lookup(Object resource, Object socketId) {
|
||||
return getOrbWrapper().lookup(resource, socketId);
|
||||
}//lookup()//
|
||||
/**
|
||||
* Opens a server socket to a perticular location.
|
||||
* @param socketName The name of the socket. <b>If a socket with the same (locally equal) name is found then that socket will be returned (and the open count incremented).</b>
|
||||
* @param serverSocketOptions The options object specifies all of the options used to create the server socket, including the address that the socket will be listening on. The type of this value is ORB implementation specific.
|
||||
* @return The socket reference object which can be later used to identify the socket.
|
||||
*/
|
||||
public static Object openServerSocket(String socketName, Object serverSocketOptions) throws java.io.IOException {
|
||||
return getOrbWrapper().openServerSocket(socketName, serverSocketOptions);
|
||||
}//openServerSocket()//
|
||||
/**
|
||||
* Opens a socket to a perticular location.
|
||||
* @param socketName The name of the socket. <b>If a socket with the same (locally equal) name is found then that socket will be returned (and the open count incremented).</b>
|
||||
* @param socketOptions The options object specifies all of the options used to create the socket, including the address that the socket will be created to.
|
||||
* @return The socket reference object which can be later used to identify the socket.
|
||||
*/
|
||||
public static Object openSocket(String socketName, Object socketOptions) throws java.io.IOException {
|
||||
return getOrbWrapper().openSocket(socketName, socketOptions);
|
||||
}//openSocket()//
|
||||
/**
|
||||
* Registers an invalid proxy listener with a proxy to be notified if the proxy is or becomes invalid.
|
||||
* <p>This method will ignore any attempt to register a listener with a non-proxy and will not generate an error.</p>
|
||||
* @param proxy The proxy to register the listener with.
|
||||
* @param invalidProxyListener The listener that will be notified by the proxy when the proxy detects that it is not valid.
|
||||
*/
|
||||
public static void registerInvalidProxyListener(Object proxy, IInvalidProxyListener invalidProxyListener) {
|
||||
getOrbWrapper().registerInvalidProxyListener(proxy, invalidProxyListener);
|
||||
}//registerInvalidProxyListener()//
|
||||
/**
|
||||
* Sends an agent to be executed on a remote process.
|
||||
* @param agent The agent to be sent.
|
||||
* @param connection The network connection to send the agent to, or a proxy whose path will be used to send the agent.
|
||||
* @param isOneWay Whether a return value will be expected. If this is one way then this method will return null.
|
||||
* @param timeout The amount of time to stay blocked waiting for a response. If this time is exceeded then a timeout exception will be raised. A value of zero indicates no timeout.
|
||||
* @deprecated Use the method that takes a callback instead.
|
||||
*/
|
||||
public static Object sendAgent(Object agent, Object connection, boolean isOneWay, long timeout) {
|
||||
return getOrbWrapper().sendAgent(agent, connection, isOneWay, timeout, null);
|
||||
}//sendAgent()//
|
||||
/**
|
||||
* Sends an agent to be executed on a remote process.
|
||||
* @param agent The agent to be sent.
|
||||
* @param connection The network connection to send the agent to, or a proxy whose path will be used to send the agent.
|
||||
* @param isOneWay Whether a return value will be expected. If this is one way then this method will return null.
|
||||
* @param timeout The amount of time to stay blocked waiting for a response. If this time is exceeded then a timeout exception will be raised. A value of zero indicates no timeout.
|
||||
* @param callback The optional callback object that will receive the result of the execution. If this is non-null and the method call is one-way, we will simply ignore the callback.
|
||||
*/
|
||||
public static Object sendAgent(Object agent, Object connection, boolean isOneWay, long timeout, IResultCallback callback) {
|
||||
return getOrbWrapper().sendAgent(agent, connection, isOneWay, timeout, callback);
|
||||
}//sendAgent()//
|
||||
/**
|
||||
* Requests that the result of the next call to the specified object return a proxy of the resulting value.
|
||||
* <p>Warning: The provided class must be an interface, and it must be compatible with the method's return type. Failure to do so may cause unpredictable results or a ClassCastException.</p>
|
||||
* <p>Note: If the object is not a proxy, is local, the method is one-way, or the method's return value is null, then the method call will be ignored.</p>
|
||||
* @param object A proxy to a remote object. If this is <code>null</code>, a non-proxy object, or a local proxy, then this call will do nothing.
|
||||
* @param interfaceType The interface class that will be used to proxy the return value of the next method called on the object. If this is null or a non-interface class then the call will be ignored.
|
||||
*/
|
||||
public static void setAutoProxy(Object object, Class interfaceType) {
|
||||
if((object != null) && (interfaceType != null) && (interfaceType.isInterface())) {
|
||||
IOrbWrapper wrapper = getOrbWrapper();
|
||||
|
||||
if(wrapper != null) {
|
||||
wrapper.setAutoProxy(object, interfaceType);
|
||||
}//if//
|
||||
}//if//
|
||||
}//setAutoProxy()//
|
||||
/**
|
||||
* Automates the manipulation of both the result of the next call on the remote system before it is sent to this local system, and the value on this local system prior to being returned to the application as the result of the method call on the proxy.
|
||||
* @param object The proxy whose next method call (on this current thread only) will be affected.
|
||||
* @param interfaceType The optional interface to proxy the result on the remote system. This will have no effect if the proxy passed as the first parameter is local.
|
||||
* @param morphHandler The required handler which will be called locally passing the result just prior to being returned by the proxy via the method called by the application on the proxy. Allows the result value to be morphed into a proper result just prior to being returned.
|
||||
*/
|
||||
public static void setAutoMorph(Object object, Class interfaceType, ObjectHandler1 morphHandler) {
|
||||
if((object != null) && (interfaceType != null) && (interfaceType.isInterface())) {
|
||||
IOrbWrapper wrapper = getOrbWrapper();
|
||||
|
||||
if(wrapper != null) {
|
||||
wrapper.setAutoMorph(object, interfaceType, morphHandler);
|
||||
}//if//
|
||||
}//if//
|
||||
}//setAutoProxy()//
|
||||
/**
|
||||
* Sets the timout value for the next call to the specified object.
|
||||
* @param object This value should be a proxy to a remote object. If this is <code>null</code>, a non-proxy object, or a local proxy, then this call will do nothing.
|
||||
* @param timeout The number of milliseconds to wait for the return value before raising a timeout error. If this value is zero or less than zero then the call will never timeout.
|
||||
*/
|
||||
public static void setCallTimeout(Object object, long timeout) {
|
||||
IOrbWrapper wrapper = getOrbWrapper();
|
||||
|
||||
if(wrapper != null) {
|
||||
wrapper.setCallTimeout(object, timeout);
|
||||
}//if//
|
||||
}//setCallTimeout()//
|
||||
/**
|
||||
* Makes the next call to the specified object a one way call (meaning that the return value is ignored and the thread does not wait for any return value).
|
||||
* @param object This value should be a proxy to a remote object. If this is <code>null</code>, a non-proxy object, or a local proxy, then this call should do nothing.
|
||||
*/
|
||||
public static void setOneWayCall(Object object) {
|
||||
IOrbWrapper wrapper = getOrbWrapper();
|
||||
|
||||
if(wrapper != null) {
|
||||
wrapper.setOneWayCall(object);
|
||||
}//if//
|
||||
}//setOneWayCall()//
|
||||
/**
|
||||
* Makes the next call to the given object on this thread return immediatly and call the given result callback object when the result is received.
|
||||
* @param object This value should be a proxy to a remote object. If this is <code>null</code>, a non-proxy object, or a local proxy, then this call should do nothing.
|
||||
* @param callback The callback that will be invoked when the orb receives a result for the remote call. This must be non-null.
|
||||
*/
|
||||
public static void setResultCallback(Object object, IResultCallback callback) {
|
||||
IOrbWrapper wrapper = getOrbWrapper();
|
||||
|
||||
if(wrapper != null) {
|
||||
wrapper.setResultCallback(object, callback);
|
||||
}//if//
|
||||
}//setOneWayCall()//
|
||||
/**
|
||||
* Sets the orb wrapper object that is being used by the system.
|
||||
* @param orbWrapper The orb wrapper that will interface the application to the desired orb.
|
||||
*/
|
||||
public static void setOrbWrapper(IOrbWrapper orbWrapper) {
|
||||
_orbWrapper = orbWrapper;
|
||||
}//setOrbWrapper()//
|
||||
/**
|
||||
* Unregisters an invalid proxy listener with a proxy.
|
||||
* <p>This method will ignore any attempt to unregister a listener with a non-proxy and will not generate an error.</p>
|
||||
* @param proxy The proxy to unregister the listener from.
|
||||
* @param invalidProxyListener The listener that will be unregistered.
|
||||
*/
|
||||
public static void unregisterInvalidProxyListener(Object proxy, IInvalidProxyListener invalidProxyListener) {
|
||||
getOrbWrapper().unregisterInvalidProxyListener(proxy, invalidProxyListener);
|
||||
}//unregisterInvalidProxyListener()//
|
||||
/**
|
||||
* Shuts the orb down, closing all server sockets and sockets.
|
||||
*/
|
||||
public static void shutdown() {
|
||||
getOrbWrapper().shutdown();
|
||||
}//shutdown()//
|
||||
}//Orb//
|
||||
46
Common/src/com/common/orb/ResultCallback.java
Normal file
46
Common/src/com/common/orb/ResultCallback.java
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.orb;
|
||||
|
||||
/**
|
||||
* A simple implementation of result callback that allows polling for the result.
|
||||
* This implementation can be extended to provide notification as well as holding the result.
|
||||
*/
|
||||
public class ResultCallback implements IResultCallback {
|
||||
private Object value = null;
|
||||
private boolean hasValue = false;
|
||||
/**
|
||||
* ResultCallback constructor.
|
||||
*/
|
||||
public ResultCallback() {
|
||||
super();
|
||||
}//ResultCallback()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.orb.IResultCallback#run(java.lang.Object)
|
||||
*/
|
||||
public synchronized void run(Object value) {
|
||||
if(!hasValue) {
|
||||
hasValue = true;
|
||||
this.value = value;
|
||||
}//if//
|
||||
}//run()//
|
||||
/**
|
||||
* Gets the value returned by the ORB.
|
||||
* @return The value which was the result of the orb call.
|
||||
*/
|
||||
public synchronized Object getValue() {
|
||||
return value;
|
||||
}//getValue()//
|
||||
/**
|
||||
* Determines whether the orb has returned a value yet.
|
||||
* @return Whether a return value has been received from the orb.
|
||||
*/
|
||||
public synchronized boolean hasValue() {
|
||||
return hasValue;
|
||||
}//hasValue()//
|
||||
}//ResultCallback//
|
||||
16
Common/src/com/common/security/IAlgorithm.java
Normal file
16
Common/src/com/common/security/IAlgorithm.java
Normal file
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 2003,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.security;
|
||||
|
||||
public interface IAlgorithm {
|
||||
/**
|
||||
* Allows the algorithm an opportunity to cleanup any resources.
|
||||
* This method should always be called when the object will no longer be used.
|
||||
*/
|
||||
public void cleanup();
|
||||
}//IAlgorithm//
|
||||
101
Common/src/com/common/security/IAsymmetricAlgorithm.java
Normal file
101
Common/src/com/common/security/IAsymmetricAlgorithm.java
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2003,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.security;
|
||||
|
||||
public interface IAsymmetricAlgorithm extends IAlgorithm, java.io.Externalizable {
|
||||
/**
|
||||
* Decrypts data and strips all padding.
|
||||
* @param data The encrypted data.
|
||||
* @return The decrypted data.
|
||||
*/
|
||||
public byte[] decrypt(byte[] data);
|
||||
/**
|
||||
* Decrypts data and strips all padding.
|
||||
* @param data The buffer containing encrypted data.
|
||||
* @param dataOffset The index of the first encrypted byte.
|
||||
* @param dataLength The number of encrypted data bytes.
|
||||
* @return The decrypted data.
|
||||
*/
|
||||
public byte[] decrypt(byte[] data, int dataOffset, int dataLength);
|
||||
/**
|
||||
* Decrypts data and strips all padding.
|
||||
* @param data The buffer containing encrypted data.
|
||||
* @param dataOffset The index of the first encrypted byte.
|
||||
* @param dataLength The number of encrypted data bytes.
|
||||
* @param output A buffer to contain the decrypted data.
|
||||
* @param outputOffset The location of the first decrypted byte in the output buffer.
|
||||
* @return The number of bytes decrypted.
|
||||
*/
|
||||
public int decrypt(byte[] data, int dataOffset, int dataLength, byte[] output, int outputOffset);
|
||||
/**
|
||||
* Encrypts data.
|
||||
* @param data The unencrypted data.
|
||||
* @return The encrypted data.
|
||||
*/
|
||||
public byte[] encrypt(byte[] data);
|
||||
/**
|
||||
* Encrypts data.
|
||||
* @param data The buffer containing unencrypted data.
|
||||
* @param dataOffset The index of the first unencrypted byte.
|
||||
* @param dataLength The number of unencrypted data bytes.
|
||||
* @return The encrypted data.
|
||||
*/
|
||||
public byte[] encrypt(byte[] data, int dataOffset, int dataLength);
|
||||
/**
|
||||
* Encrypts data.
|
||||
* @param data The buffer containing unencrypted data.
|
||||
* @param dataOffset The index of the first unencrypted byte.
|
||||
* @param dataLength The number of unencrypted data bytes.
|
||||
* @param output A buffer to contain the encrypted data.
|
||||
* @param outputOffset The location of the first encrypted byte in the output buffer.
|
||||
* @return The number of encrypted bytes (includes formatting and padding).
|
||||
*/
|
||||
public int encrypt(byte[] data, int dataOffset, int dataLength, byte[] output, int outputOffset);
|
||||
/**
|
||||
* Gets the <strong>exact</strong> number of bytes of encrypted data for the given number of unencrypted bytes.
|
||||
* @param unencryptedSize The number of unencrypted bytes of data.
|
||||
* @return The encrypted size.
|
||||
*/
|
||||
public int getEncryptedSize(int unencryptedSize);
|
||||
/**
|
||||
* Gets the number of bytes in an optimal block of to-be-decrypted data. This allows for efficient streaming of data through the encryption algorithm.
|
||||
* @return The optimal size of data to be decrypted.
|
||||
*/
|
||||
public int getOptimalDecryptionBlockSize();
|
||||
/**
|
||||
* Gets the number of bytes in an optimal block of to-be-encrypted data. This allows for efficient streaming of data through the encryption algorithm.
|
||||
* @return The optimal size of data to be encrypted.
|
||||
*/
|
||||
public int getOptimalEncryptionBlockSize();
|
||||
/**
|
||||
* Gets the public algorithm used to encrypt data.
|
||||
* @return The public algorithm which can be used for encrypting.
|
||||
*/
|
||||
public IAsymmetricAlgorithm getPublicAsymmetricAlgorithm();
|
||||
/**
|
||||
* Gets the public key for this asymmetric algorithm.
|
||||
* @return The public key which can be used for encrypting.
|
||||
*/
|
||||
public Object getPublicKey();
|
||||
/**
|
||||
* Gets the public key as a stream of bytes for this asymmetric algorithm.
|
||||
* @return The public key bytes which can be converted and used for encrypting.
|
||||
*/
|
||||
public byte[] getPublicKeyBytes();
|
||||
/**
|
||||
* Gets the private key as a stream of bytes for this asymmetric algorithm.
|
||||
* @return The private key bytes which can be converted and used for encrypting, or null if the algorithm doesn't have a private key.
|
||||
*/
|
||||
public byte[] getPrivateKeyBytes();
|
||||
/**
|
||||
* Gets the maximum number of bytes of unencrypted data for the given number of encrypted bytes.
|
||||
* @param unencryptedSize The number of encrypted bytes of data.
|
||||
* @return The maximum unencrypted size.
|
||||
*/
|
||||
public int getUnencryptedSize(int encryptedSize);
|
||||
}//IAsymmetricAlgorithm//
|
||||
131
Common/src/com/common/security/IHashAlgorithm.java
Normal file
131
Common/src/com/common/security/IHashAlgorithm.java
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (c) 2003,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.security;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.common.io.IWriter;
|
||||
|
||||
/**
|
||||
* Defines a general hashing algorithm. Derived algorithms are not intended to be thread safe.
|
||||
*/
|
||||
public interface IHashAlgorithm extends IAlgorithm, java.io.Externalizable, IWriter {
|
||||
/**
|
||||
* Adds the source to the hash.
|
||||
* @param b The byte to add.
|
||||
*/
|
||||
public void add(byte b);
|
||||
/**
|
||||
* Adds the source to the hash.
|
||||
* @param buffer The buffer to pull source from.
|
||||
*/
|
||||
public void add(byte[] buffer);
|
||||
/**
|
||||
* Adds the source to the hash.
|
||||
* @param buffer The buffer to pull source from.
|
||||
* @param bufferOffset The index of the first source byte.
|
||||
* @param bufferLength The number of source bytes.
|
||||
*/
|
||||
public void add(byte[] buffer, int bufferOffset, int bufferLength);
|
||||
/**
|
||||
* Adds the source to the hash.
|
||||
* @param in The input stream containing the source.
|
||||
*/
|
||||
public void add(java.io.InputStream in) throws IOException;
|
||||
/**
|
||||
* Adds the source to the hash.
|
||||
* @param source The string to be added to the hash.
|
||||
*/
|
||||
public void add(String source);
|
||||
/**
|
||||
* Adds the source to the hash.
|
||||
* @param source The string to be added to the hash.
|
||||
*/
|
||||
public void add(char[] source);
|
||||
/**
|
||||
* Gets the size of the generated hash.
|
||||
* @return The number of bytes in every hash.
|
||||
*/
|
||||
public int getHashSize();
|
||||
/**
|
||||
* Generates a digest for previously provided source.
|
||||
* @return The digest bytes.
|
||||
* @see includeSource(byte[])
|
||||
* @see includeSource(byte[], int, int)
|
||||
* @see includeSource(java.io.InputStream)
|
||||
* @see includeSource(String)
|
||||
*/
|
||||
public byte[] hash();
|
||||
/**
|
||||
* Creates a hash value given some source.
|
||||
* @param source The last source to add before hashing.
|
||||
* @param sourceOffset The index of the first source byte.
|
||||
* @param sourceLength The number of source bytes.
|
||||
* @param hashBuffer The buffer that the hash will be placed in.
|
||||
* @param hashBufferOffset The index of the first byte of the hash in the buffer.
|
||||
*/
|
||||
public void hash(byte[] source, int sourceOffset, int sourceLength, byte[] hashBuffer, int hashBufferOffset);
|
||||
/**
|
||||
* Creates a hash value given some source.
|
||||
* @param source The last source to add before hashing.
|
||||
* @return The hash bytes.
|
||||
*/
|
||||
public byte[] hash(String source);
|
||||
/**
|
||||
* Creates a hash value given some source.
|
||||
* @param source The last source to add before hashing.
|
||||
* @param hashBuffer The buffer that the hash will be placed in.
|
||||
* @param hashBufferOffset The index of the first byte of the hash in the buffer.
|
||||
*/
|
||||
public void hash(String source, byte[] hashBuffer, int hashBufferOffset);
|
||||
/**
|
||||
* Creates a hash value given some source.
|
||||
* @param source The last source to add before hashing.
|
||||
* @return The hash bytes.
|
||||
*/
|
||||
public byte[] hash(char[] source);
|
||||
/**
|
||||
* Creates a hash value given some source.
|
||||
* @param source The last source to add before hashing.
|
||||
* @param hashBuffer The buffer that the hash will be placed in.
|
||||
* @param hashBufferOffset The index of the first byte of the hash in the buffer.
|
||||
*/
|
||||
public void hash(char[] source, byte[] hashBuffer, int hashBufferOffset);
|
||||
/**
|
||||
* Creates a hash string using UTF16 encoding given some source.
|
||||
* @return The hash bytes in the form of a string (UTF16 encoding).
|
||||
*/
|
||||
public String hashToString();
|
||||
/**
|
||||
* Creates a hash string using UTF16 encoding given some source.
|
||||
* @param source The last source to add before hashing.
|
||||
* @return The hash bytes in the form of a string (UTF16 encoding).
|
||||
*/
|
||||
public String hashToString(String source);
|
||||
/**
|
||||
* Creates a hash string using UTF16 encoding given some source.
|
||||
* @param source The last source to add before hashing.
|
||||
* @return The hash bytes in the form of a string (UTF16 encoding).
|
||||
*/
|
||||
public String hashToString(char[] source);
|
||||
/**
|
||||
* Creates a hash value given some source.
|
||||
* @return The hash bytes in the form of a string.
|
||||
*/
|
||||
public String hashToHex();
|
||||
/**
|
||||
* Creates a hash value given some source.
|
||||
* @param source The last source to add before hashing.
|
||||
* @return The hash bytes in the form of a string.
|
||||
*/
|
||||
public String hashToHex(String source);
|
||||
/**
|
||||
* Resets the algorithm so that it may be used again.
|
||||
*/
|
||||
public void reset();
|
||||
}//IHashAlgorithm//
|
||||
109
Common/src/com/common/security/ISignatureAlgorithm.java
Normal file
109
Common/src/com/common/security/ISignatureAlgorithm.java
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 2003,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.security;
|
||||
|
||||
public interface ISignatureAlgorithm extends IAlgorithm, java.io.Externalizable {
|
||||
/**
|
||||
* Gets the number of bytes in an optimal block of to-be-signed data. This allows for efficient streaming of data through the signature algorithm.
|
||||
* @return The optimal size of data to be signed.
|
||||
*/
|
||||
public int getOptimalSignatureBlockSize();
|
||||
/**
|
||||
* Gets the number of bytes in an optimal block of to-be-verified data. This allows for efficient streaming of data through the signature algorithm.
|
||||
* @return The optimal size of data to be verified.
|
||||
*/
|
||||
public int getOptimalVerificationBlockSize();
|
||||
/**
|
||||
* Gets the public algorithm used to verify data.
|
||||
* @return The public algorithm which can be used for verification.
|
||||
*/
|
||||
public ISignatureAlgorithm getPublicSignatureAlgorithm();
|
||||
/**
|
||||
* Gets the <strong>exact</strong> number of signed bytes for the given unsigned message size.
|
||||
* @param unsignedSize The number of unsigned bytes.
|
||||
* @return The number of signed bytes.
|
||||
*/
|
||||
public int getSignedSize(int unsignedSize);
|
||||
/**
|
||||
* Gets the maximum number of unsigned bytes for the given signed message size.
|
||||
* @param unsignedSize The number of signed bytes.
|
||||
* @return The maximum number of unsigned bytes.
|
||||
*/
|
||||
public int getUnsignedSize(int signedSize);
|
||||
/**
|
||||
* Gets the public algorithm used for signature verification.
|
||||
* @return The algorithm used to verify the signatures. This is a publicly accessable algorithm.
|
||||
*/
|
||||
public ISignatureAlgorithm getVerifyAlgorithm();
|
||||
/**
|
||||
* Gets the public key used for signature verification.
|
||||
* @return The key used to verify the signatures. This is a publicly accessable key.
|
||||
*/
|
||||
public Object getVerifyKey();
|
||||
/**
|
||||
* Signs an array of bytes by encrypting them with the private key.
|
||||
* @param data The input bytes.
|
||||
* @return The signed (encrypted) data.
|
||||
* @see #getBlockSize()
|
||||
*/
|
||||
public byte[] sign(byte[] data);
|
||||
/**
|
||||
* Signs an array of bytes by encrypting them with the private key.
|
||||
* @param data The input bytes.
|
||||
* @param dataOffset The offset in the data array to begin encrypting bytes.
|
||||
* @param dataLength The number of bytes in the data array to encrypt.
|
||||
* @return The signed (encrypted) data.
|
||||
* @see #getBlockSize()
|
||||
*/
|
||||
public byte[] sign(byte[] data, int dataOffset, int dataLength);
|
||||
/**
|
||||
* Signs an array of bytes by encrypting them with the private key and placing them in the supplied buffer.
|
||||
* <p>Warning: The encrypted byte length will most likely be larger than the unencrypted size.</p>
|
||||
* @param data The input bytes.
|
||||
* @param dataOffset The offset in the data array to begin encrypting bytes.
|
||||
* @param dataLength The number of bytes in the data array to encrypt.
|
||||
* @param buffer The output bytes.
|
||||
* @param bufferOffset The offset in the buffer array where the output bytes will begin.
|
||||
* @return The number of encrypted (signed) bytes placed in the output buffer (includes formatting and padding).
|
||||
* @see #getBlockSize()
|
||||
*/
|
||||
public int sign(byte[] data, int dataOffset, int dataLength, byte[] buffer, int bufferOffset);
|
||||
/**
|
||||
* Decrypts an array of bytes using the public key and stores the decrypted bytes in the buffer.
|
||||
* The output will not include any padding used during encryption.
|
||||
* <p>NOTE: The number of encrypted data bytes supplied MUST be a multiple of the Block Size (as outputed by the sign method).</p>
|
||||
* @param data The signed input (encrypted) bytes.
|
||||
* @return The verify (unencrypted) bytes.
|
||||
* @see #getBlockSize()
|
||||
*/
|
||||
public byte[] verify(byte[] data);
|
||||
/**
|
||||
* Decrypts an array of bytes using the public key and stores the decrypted bytes in the buffer.
|
||||
* The output will not include any padding used during encryption.
|
||||
* <p>NOTE: The number of encrypted data bytes supplied MUST be a multiple of the Block Size (as outputed by the sign method).</p>
|
||||
* @param data The signed input (encrypted) bytes.
|
||||
* @param dataOffset The offset in the data array to begin decrypting bytes.
|
||||
* @param dataLength The number of bytes in the data array to decrypt.
|
||||
* @return The verify (unencrypted) bytes.
|
||||
* @see #getBlockSize()
|
||||
*/
|
||||
public byte[] verify(byte[] data, int dataOffset, int dataLength);
|
||||
/**
|
||||
* Decrypts an array of bytes using the public key and stores the decrypted bytes in the buffer.
|
||||
* The output will not include any padding used during encryption.
|
||||
* <p>NOTE: The number of encrypted data bytes supplied MUST be a multiple of the Block Size (as outputed by the sign method).</p>
|
||||
* @param data The signed input (encrypted) bytes.
|
||||
* @param dataOffset The offset in the data array to begin decrypting bytes.
|
||||
* @param dataLength The number of bytes in the data array to decrypt.
|
||||
* @param buffer The decrypted output bytes. (This will be filled.)
|
||||
* @param bufferOffset The offset in the buffer array where the output bytes will begin.
|
||||
* @return The number of bytes placed in the output buffer.
|
||||
* @see #getBlockSize()
|
||||
*/
|
||||
public int verify(byte[] data, int dataOffset, int dataLength, byte[] buffer, int bufferOffset);
|
||||
}//ISignatureAlgorithm//
|
||||
61
Common/src/com/common/security/ISymmetricAlgorithm.java
Normal file
61
Common/src/com/common/security/ISymmetricAlgorithm.java
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2003,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.security;
|
||||
|
||||
public interface ISymmetricAlgorithm extends IAlgorithm, java.io.Externalizable {
|
||||
/**
|
||||
* Decrypts the data.
|
||||
* @param data The input (encrypted) bytes.
|
||||
* @param dataOffset The offset in the data array to begin decrypting bytes.
|
||||
* @param dataLength The number of bytes in the data array to decrypt.
|
||||
* @param output The decrypted output bytes. (This will be filled.)
|
||||
* @param outputOffset The offset in the buffer array where the output bytes will begin.
|
||||
* @return The number of bytes written to the output array.
|
||||
* @see #getBlockSize()
|
||||
*/
|
||||
public int decrypt(byte[] data, int dataOffset, int dataLength, byte[] output, int outputOffset);
|
||||
/**
|
||||
* Encrypts an array of bytes into the supplied buffer.
|
||||
* <p>NOTE: The number of data bytes supplied MUST be a multiple of the Block Size. Use random padding to achieve this.
|
||||
* @param data The input bytes.
|
||||
* @param dataOffset The offset in the data array to begin encrypting bytes.
|
||||
* @param dataLength The number of bytes in the data array to encrypt.
|
||||
* @param output The output bytes.
|
||||
* @param outputOffset The offset in the buffer array where the output bytes will begin.
|
||||
* @return The number of bytes written to the output array.
|
||||
* @see #getBlockSize()
|
||||
*/
|
||||
public int encrypt(byte[] data, int dataOffset, int dataLength, byte[] output, int outputOffset);
|
||||
/**
|
||||
* Gets the <strong>exact</strong> number of bytes of encrypted data for the given number of unencrypted bytes.
|
||||
* @param unencryptedSize The number of unencrypted bytes of data.
|
||||
* @return The encrypted size.
|
||||
*/
|
||||
public int getEncryptedSize(int unencryptedSize);
|
||||
/**
|
||||
* Gets the size of the symmetric key (in bytes).
|
||||
* @return The number of bytes in the algorithm's symmetric key.
|
||||
*/
|
||||
public int getKeySize();
|
||||
/**
|
||||
* Gets the smallest optimal block size for decrypted data.
|
||||
* @return The maximum size of a single block of decrypted data.
|
||||
*/
|
||||
public int getOptimalDecryptionBlockSize();
|
||||
/**
|
||||
* Gets the smallest optimal block size for encrypted data.
|
||||
* @return The maximum size of a single block of encrypted data.
|
||||
*/
|
||||
public int getOptimalEncryptionBlockSize();
|
||||
/**
|
||||
* Gets the maximum number of bytes of unencrypted data for the given number of encrypted bytes.
|
||||
* @param unencryptedSize The number of encrypted bytes of data.
|
||||
* @return The maximum unencrypted size.
|
||||
*/
|
||||
public int getUnencryptedSize(int encryptedSize);
|
||||
}//ISymmetricAlgorithm//
|
||||
93
Common/src/com/common/security/Random.java
Normal file
93
Common/src/com/common/security/Random.java
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2002,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.security;
|
||||
|
||||
/**
|
||||
* Encapsulates the generation of simple random numbers.
|
||||
*/
|
||||
public class Random extends java.security.SecureRandom {
|
||||
/**
|
||||
* Random constructor.
|
||||
*/
|
||||
public Random() {
|
||||
super();
|
||||
}//Random()//
|
||||
/**
|
||||
* Random constructor.
|
||||
* @param seed The seed for the generator.
|
||||
*/
|
||||
public Random(byte[] seed) {
|
||||
super(seed);
|
||||
}//Random()//
|
||||
/**
|
||||
* Random constructor.
|
||||
* @param seed The seed for the generator.
|
||||
*/
|
||||
public Random(long seed) {
|
||||
super();
|
||||
setSeed(seed);
|
||||
}//Random()//
|
||||
/**
|
||||
* Generates the next random byte.
|
||||
* @return The next byte in the random sequence.
|
||||
*/
|
||||
public byte nextByte() {
|
||||
return (byte) next(8);
|
||||
}//nextByte()//
|
||||
/**
|
||||
* Generates random bytes and places them in a buffer.
|
||||
* @param buffer The buffer that will contain the random bytes.
|
||||
* @param offset The offset in the buffer where the random bytes will begin.
|
||||
* @param length The number of random bytes placed in the buffer.
|
||||
*/
|
||||
public synchronized void nextBytes(byte[] buffer, int offset, int length) {
|
||||
int end = length + offset - 1;
|
||||
|
||||
for(int index = offset; index <= end; index++) {
|
||||
buffer[index] = nextByte();
|
||||
}//for//
|
||||
}//nextBytes()//
|
||||
/**
|
||||
* Gets the next random digit between 0 & 9.
|
||||
* @return The next random digit in the sequence.
|
||||
*/
|
||||
synchronized public char nextDigit() {
|
||||
int b;
|
||||
|
||||
do {
|
||||
b = next(4);
|
||||
} while(b > 9);
|
||||
|
||||
return (char) (b + '0');
|
||||
}//nextDigit()//
|
||||
/**
|
||||
* Creates a number along a given interval.
|
||||
* @param low The lowest allowed value.
|
||||
* @param high The highest allowed value.
|
||||
* @return The number on the given interval.
|
||||
*/
|
||||
public int nextInt(int low, int high) {
|
||||
int interval = high - low;
|
||||
int retVal = 0;
|
||||
|
||||
if(interval > 0) {
|
||||
long random = nextLong();
|
||||
|
||||
retVal = (int) Math.abs(random % interval);
|
||||
retVal += low;
|
||||
}//if//
|
||||
else if(interval == 0) {
|
||||
retVal = low;
|
||||
}//else if//
|
||||
else {
|
||||
throw new RuntimeException("Invalid interval: [" + high + "," + low + "]");
|
||||
}//else//
|
||||
|
||||
return retVal;
|
||||
}//nextInt()//
|
||||
}//Random//
|
||||
202
Common/src/com/common/security/Random2.java
Normal file
202
Common/src/com/common/security/Random2.java
Normal file
@@ -0,0 +1,202 @@
|
||||
package com.common.security;
|
||||
|
||||
import com.common.exception.MethodNotSupportedException;
|
||||
|
||||
/**
|
||||
* This is a Digesting Random Number Generator.
|
||||
* The original code comes from the BouncyCastle's DigestRandomGenerator, and was modified to use the Sha512 digest only.
|
||||
* The intent is to use this for generating a random sequence off of a password where the sequence is always the same for the same input.
|
||||
* The built in SecureRandom class in the JDK is broken on the Mac since it ignores any seed input and won't generate the same sequence for the same seed input.
|
||||
*/
|
||||
public class Random2 extends Random {
|
||||
private static long CYCLE_COUNT = 10;
|
||||
private long stateCounter;
|
||||
private long seedCounter;
|
||||
private Sha512 digest;
|
||||
private byte[] state;
|
||||
private byte[] seed;
|
||||
boolean isInitialized = false;
|
||||
public Random2() {
|
||||
this.digest = new Sha512();
|
||||
|
||||
this.seed = new byte[digest.getHashSize()];
|
||||
this.seedCounter = 1;
|
||||
|
||||
this.state = new byte[digest.getHashSize()];
|
||||
this.stateCounter = 1;
|
||||
}//Random2()//
|
||||
public void addSeedMaterial(byte[] inSeed) {
|
||||
synchronized(this) {
|
||||
if(isInitialized) {
|
||||
digestUpdate(inSeed);
|
||||
digestUpdate(seed);
|
||||
digestDoFinal(seed);
|
||||
}//if//
|
||||
}//synchronized//
|
||||
}//addSeedMaterial()//
|
||||
public void addSeedMaterial(long rSeed) {
|
||||
synchronized(this) {
|
||||
if(isInitialized) {
|
||||
digestAddCounter(rSeed);
|
||||
digestUpdate(seed);
|
||||
digestDoFinal(seed);
|
||||
}//if//
|
||||
}//synchronized//
|
||||
}//addSeedMaterial()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.security.SecureRandom#nextBytes(byte[])
|
||||
*/
|
||||
public void nextBytes(byte[] bytes) {
|
||||
nextBytes(bytes, 0, bytes.length);
|
||||
}//nextBytes()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.Random#nextBytes(byte[], int, int)
|
||||
*/
|
||||
public void nextBytes(byte[] bytes, int start, int len) {
|
||||
synchronized(this) {
|
||||
int stateOff = 0;
|
||||
int end;
|
||||
|
||||
generateState();
|
||||
end = start + len;
|
||||
|
||||
for(int i = start; i != end; i++) {
|
||||
if(stateOff == state.length) {
|
||||
generateState();
|
||||
stateOff = 0;
|
||||
}//if//
|
||||
|
||||
bytes[i] = state[stateOff++];
|
||||
}//for//
|
||||
}//synchronized//
|
||||
}//nextBytes()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.Random#nextByte()
|
||||
*/
|
||||
public byte nextByte() {
|
||||
synchronized(this) {
|
||||
generateState();
|
||||
|
||||
return state[0];
|
||||
}//synchronized//
|
||||
}//nextByte()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.security.SecureRandom#generateSeed(int)
|
||||
*/
|
||||
public byte[] generateSeed(int numBytes) {
|
||||
byte[] result = new byte[numBytes];
|
||||
|
||||
nextBytes(result, 0, result.length);
|
||||
|
||||
return result;
|
||||
}//generateSeed()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.security.SecureRandom#getAlgorithm()
|
||||
*/
|
||||
public String getAlgorithm() {
|
||||
return "DigestRandom/SHA512";
|
||||
}//getAlgorithm()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.security.SecureRandom#setSeed(byte[])
|
||||
*/
|
||||
public void setSeed(byte[] seed) {
|
||||
addSeedMaterial(seed);
|
||||
}//setSeed()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.security.SecureRandom#setSeed(long)
|
||||
*/
|
||||
public void setSeed(long seed) {
|
||||
addSeedMaterial(seed);
|
||||
}//setSeed()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.util.Random#nextBoolean()
|
||||
*/
|
||||
public boolean nextBoolean() {
|
||||
synchronized(this) {
|
||||
generateState();
|
||||
|
||||
return (state[0] & 0x1) > 0;
|
||||
}//synchronized//
|
||||
}//nextBoolean()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.util.Random#nextDouble()
|
||||
*/
|
||||
public double nextDouble() {
|
||||
throw new MethodNotSupportedException();
|
||||
}//nextDouble()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.util.Random#nextFloat()
|
||||
*/
|
||||
public float nextFloat() {
|
||||
throw new MethodNotSupportedException();
|
||||
}//nextFloat()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.util.Random#nextGaussian()
|
||||
*/
|
||||
public synchronized double nextGaussian() {
|
||||
throw new MethodNotSupportedException();
|
||||
}//nextGaussian()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.util.Random#nextInt()
|
||||
*/
|
||||
public int nextInt() {
|
||||
int result;
|
||||
|
||||
synchronized(this) {
|
||||
generateState();
|
||||
|
||||
result = (((int) state[0]) << 24) | (((int) state[0]) << 16) | (((int) state[0]) << 8) | ((int) state[0]);
|
||||
}//synchronized//
|
||||
|
||||
return result;
|
||||
}//nextInt()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.util.Random#nextInt(int)
|
||||
*/
|
||||
public int nextInt(int n) {
|
||||
throw new MethodNotSupportedException();
|
||||
}//nextInt()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.util.Random#nextLong()
|
||||
*/
|
||||
public long nextLong() {
|
||||
long result;
|
||||
|
||||
synchronized(this) {
|
||||
generateState();
|
||||
|
||||
result = (((long) state[0]) << 56) | (((long) state[0]) << 56) | (((long) state[0]) << 48) | (((long) state[0]) << 40) | (((long) state[0]) << 32) | (((long) state[0]) << 24) | (((long) state[0]) << 16) | (((long) state[0]) << 8) | ((long) state[0]);
|
||||
}//synchronized//
|
||||
|
||||
return result;
|
||||
}//nextLong()//
|
||||
private void cycleSeed() {
|
||||
digestUpdate(seed);
|
||||
digestAddCounter(seedCounter++);
|
||||
|
||||
digestDoFinal(seed);
|
||||
}//cycleSeed()//
|
||||
private void generateState() {
|
||||
digestAddCounter(stateCounter++);
|
||||
digestUpdate(state);
|
||||
digestUpdate(seed);
|
||||
|
||||
digestDoFinal(state);
|
||||
|
||||
if((stateCounter % CYCLE_COUNT) == 0) {
|
||||
cycleSeed();
|
||||
}
|
||||
}//generateState()//
|
||||
private void digestAddCounter(long seed) {
|
||||
for(int i = 0; i != 8; i++) {
|
||||
digest.add((byte) seed);
|
||||
seed >>>= 8;
|
||||
}
|
||||
}//digestAddCounter()//
|
||||
private void digestUpdate(byte[] inSeed) {
|
||||
digest.add(inSeed, 0, inSeed.length);
|
||||
}//digestUpdate()//
|
||||
private void digestDoFinal(byte[] result) {
|
||||
digest.finish(result, 0);
|
||||
}//digestDoFinal()//
|
||||
}//Random2//
|
||||
862
Common/src/com/common/security/Rijndael.java
Normal file
862
Common/src/com/common/security/Rijndael.java
Normal file
@@ -0,0 +1,862 @@
|
||||
/*
|
||||
* Copyright (c) 2003,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
/*
|
||||
* TODO: Determine original source.
|
||||
*/
|
||||
package com.common.security;
|
||||
|
||||
import com.common.debug.*;
|
||||
import com.common.util.StringSupport;
|
||||
|
||||
/*
|
||||
* An implementation of the Rijndael algorithm for symmetric block encryption.
|
||||
*/
|
||||
public class Rijndael implements ISymmetricAlgorithm {
|
||||
public static final int DEFAULT_KEY_SIZE = 32;
|
||||
public static final int DEFAULT_BLOCK_SIZE = 16;
|
||||
private static final int DEFAULT_VIRTUAL_BLOCK_SIZE = 128;
|
||||
private static final int MINIMUM_PADDING = DEFAULT_VIRTUAL_BLOCK_SIZE / DEFAULT_BLOCK_SIZE + 2; //Includes data size.//
|
||||
|
||||
//Static variables to assist in the de/encryption.//
|
||||
//private static final int[][][] shifts = new int[][][] {{{0, 0}, {1, 3}, {2, 2}, {3, 1}}, {{0, 0}, {1, 5}, {2, 4}, {3, 3}}, {{0, 0}, {1, 7}, {3, 5}, {4, 4}}};
|
||||
private static final int[] T1 = new int[256];
|
||||
private static final int[] T2 = new int[256];
|
||||
private static final int[] T3 = new int[256];
|
||||
private static final int[] T4 = new int[256];
|
||||
private static final int[] T5 = new int[256];
|
||||
private static final int[] T6 = new int[256];
|
||||
private static final int[] T7 = new int[256];
|
||||
private static final int[] T8 = new int[256];
|
||||
private static final int[] U1 = new int[256];
|
||||
private static final int[] U2 = new int[256];
|
||||
private static final int[] U3 = new int[256];
|
||||
private static final int[] U4 = new int[256];
|
||||
private static final int[] alog = new int[256];
|
||||
private static final int[] log = new int[256];
|
||||
private static final byte[] S = new byte[256];
|
||||
private static final byte[] Si = new byte[256];
|
||||
private static final byte[] rcon = new byte[30];
|
||||
|
||||
private Object[] key = null;
|
||||
private Random random = null;
|
||||
private byte[] tempBuffer = null;
|
||||
private int keySize = DEFAULT_KEY_SIZE; //The size (in bits) of the key.//
|
||||
private int blockSize = DEFAULT_BLOCK_SIZE; //The size (in bytes) of a block of de/encrypted data. This currently cannot be changed.//
|
||||
//private int virtualBlockSize = DEFAULT_VIRTUAL_BLOCK_SIZE; //The size (in bytes) of a virtual block of data. This is the externally visible block size (minus required padding).//
|
||||
private int randomByteCounter = 0;
|
||||
|
||||
/**
|
||||
* Setup the static variables.
|
||||
*/
|
||||
static {
|
||||
staticInitialize();
|
||||
}//static//
|
||||
/**
|
||||
* Rijndael constructor.
|
||||
* The caller must setup a key before using this algorithm.
|
||||
*/
|
||||
public Rijndael() {
|
||||
super();
|
||||
initialize();
|
||||
}//Rijndael()//
|
||||
/**
|
||||
* Rijndael constructor.
|
||||
* @param keySize One of the available key sizes.
|
||||
* @param random The random number generator for the key input. <b>Warning: The mac random number generator (SecureRandom - maybe also Random) does not properly accept the seed value as of jdk 1.6.</b>
|
||||
*/
|
||||
public Rijndael(java.util.Random random) {
|
||||
super();
|
||||
setupKey(DEFAULT_KEY_SIZE, random);
|
||||
initialize();
|
||||
}//Rijndael()//
|
||||
/**
|
||||
* Rijndael constructor.
|
||||
* @param keySize One of the available key sizes.
|
||||
* @param random The random number generator for the key input. <b>Warning: The mac random number generator (SecureRandom - maybe also Random) does not properly accept the seed value as of jdk 1.6.</b>
|
||||
*/
|
||||
public Rijndael(int keySize, java.util.Random random) {
|
||||
super();
|
||||
setupKey(keySize, random);
|
||||
initialize();
|
||||
}//Rijndael()//
|
||||
/**
|
||||
* Rijndael constructor.
|
||||
* @param keyData The key data used to setup the key. This must be exactly sized to the key size (length == keySize). The only valid lengths are: 16, 24, or 32.
|
||||
*/
|
||||
public Rijndael(byte[] keyData) {
|
||||
super();
|
||||
|
||||
setupKey(keyData, 0, keyData.length);
|
||||
initialize();
|
||||
}//Rijndael()//
|
||||
/**
|
||||
* Rijndael constructor.
|
||||
* @param keyData The key data used to setup the key.
|
||||
* @param offset The offset of the first byte of data in the keyData array.
|
||||
* @param length The number of key data bytes that should be used. This must be exactly sized to the key size (length == keySize). The only valid lengths are: 16, 24, or 32.
|
||||
*/
|
||||
public Rijndael(byte[] keyData, int offset, int length) {
|
||||
super();
|
||||
|
||||
setupKey(keyData, offset, length);
|
||||
initialize();
|
||||
}//Rijndael()//
|
||||
/**
|
||||
* Rijndael constructor.
|
||||
* <p>Warning: This code fails on the mac - the seed is not properly set on a mac as of Java 1.6.</p>
|
||||
* @param keyData The key data used to setup the key.
|
||||
*/
|
||||
public Rijndael(String keyData) {
|
||||
super();
|
||||
|
||||
setupKey(keyData);
|
||||
initialize();
|
||||
}//Rijndael()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IAlgorithm#cleanup()
|
||||
*/
|
||||
public void cleanup() {
|
||||
}//cleanup()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.ISymmetricAlgorithm#decrypt(byte[], int, int, byte[], int)
|
||||
*/
|
||||
public int decrypt(byte[] data, int dataOffset, int dataLength, byte[] buffer, int bufferOffset) {
|
||||
byte[] b = tempBuffer;
|
||||
int contentSize;
|
||||
int size;
|
||||
int bytesWritten = 0;
|
||||
|
||||
while(dataLength > 0) {
|
||||
//Copy the first block of encrypted content.//
|
||||
System.arraycopy(data, dataOffset, b, 0, b.length);
|
||||
//Decrypt the first block.//
|
||||
internalDecrypt(b, b, 0);
|
||||
//Read the size of the virtual block of content.//
|
||||
contentSize = (int) (com.common.io.StreamSupport.readShort(b, 0) & 0xFFFF);
|
||||
//Calculate the size of the block's content.//
|
||||
size = Math.min(contentSize, b.length - 3);
|
||||
//Copy the plaintext content to the output buffer.//
|
||||
System.arraycopy(b, 3, buffer, bufferOffset, size);
|
||||
bytesWritten += size;
|
||||
bufferOffset += size;
|
||||
contentSize -= size;
|
||||
dataOffset += b.length;
|
||||
dataLength -= b.length;
|
||||
|
||||
//Run through the decryption rounds until all the data has been accounted for.//
|
||||
while(contentSize > 0) {
|
||||
//Copy the next block of encrypted content.//
|
||||
System.arraycopy(data, dataOffset, b, 0, b.length);
|
||||
//Decrypt the next block.//
|
||||
internalDecrypt(b, b, 0);
|
||||
//Calculate the size of the block's content.//
|
||||
size = Math.min(contentSize, b.length - 1);
|
||||
//Copy the plaintext content to the output buffer.//
|
||||
System.arraycopy(b, 1, buffer, bufferOffset, size);
|
||||
bytesWritten += size;
|
||||
bufferOffset += size;
|
||||
contentSize -= size;
|
||||
dataOffset += b.length;
|
||||
dataLength -= b.length;
|
||||
}//while//
|
||||
}//while//
|
||||
|
||||
return bytesWritten;
|
||||
}//decrypt()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.ISymmetricAlgorithm#encrypt(byte[], int, int, byte[], int)
|
||||
*/
|
||||
public int encrypt(byte[] inputBuffer, int inputBufferOffset, int inputBufferLength, byte[] outputBuffer, int outputBufferOffset) {
|
||||
int bytesWritten = 0;
|
||||
|
||||
while(inputBufferLength > 0) {
|
||||
byte[] b = tempBuffer;
|
||||
int size = Math.min(b.length - 3, inputBufferLength);
|
||||
short contentSize = (short) Math.min(inputBufferLength, DEFAULT_VIRTUAL_BLOCK_SIZE - MINIMUM_PADDING);
|
||||
|
||||
//Perform the first encryption round.//
|
||||
//Transfer the plain text content to the block buffer.//
|
||||
System.arraycopy(inputBuffer, inputBufferOffset, b, 3, size);
|
||||
//Write the size of the content (up to the virutal block size).//
|
||||
com.common.io.StreamSupport.writeShort(contentSize, b, 0);
|
||||
//Add a random byte.//
|
||||
b[2] = getRandomByte();
|
||||
|
||||
//Pad the buffer with random data.//
|
||||
for(int i = size + 3; i < b.length; i++) {
|
||||
b[i] = getRandomByte();
|
||||
}//for//
|
||||
|
||||
//Encrypt the block.//
|
||||
internalEncrypt(b, outputBuffer, outputBufferOffset);
|
||||
//Update the indicies.//
|
||||
outputBufferOffset += b.length;
|
||||
inputBufferOffset += size;
|
||||
inputBufferLength -= size;
|
||||
contentSize -= size;
|
||||
bytesWritten += b.length;
|
||||
|
||||
//Perform following rounds.//
|
||||
while(contentSize > 0) {
|
||||
size = Math.min(inputBufferLength, b.length - 1);
|
||||
|
||||
//Transfer the plain text content to the block buffer.//
|
||||
System.arraycopy(inputBuffer, inputBufferOffset, b, 1, size);
|
||||
//Pad the first byte with random data.//
|
||||
b[0] = getRandomByte();
|
||||
|
||||
//Pad the buffer with random data.//
|
||||
for(int i = size + 1; i < b.length; i++) {
|
||||
b[i] = getRandomByte();
|
||||
}//for//
|
||||
|
||||
//Encrypt the block.//
|
||||
internalEncrypt(b, outputBuffer, outputBufferOffset);
|
||||
//Update the indicies.//
|
||||
outputBufferOffset += b.length;
|
||||
inputBufferOffset += size;
|
||||
inputBufferLength -= size;
|
||||
contentSize -= size;
|
||||
bytesWritten += b.length;
|
||||
}//while//
|
||||
}//for//
|
||||
|
||||
return bytesWritten;
|
||||
}//encrypt()//
|
||||
/**
|
||||
* Expand a user-supplied key material into a session key.
|
||||
* <p>WARNING: The keyData length must be 16, 24, or 32 bytes long!
|
||||
* @param keyData The 128/192/256-bit user-key to use.
|
||||
*/
|
||||
private void generateKey(byte[] keyData, int offset, int length) {
|
||||
int keySize = length;
|
||||
int ROUNDS = getRounds(keySize, blockSize);
|
||||
int BC = blockSize / 4;
|
||||
int[][] Ke = new int[ROUNDS + 1][BC]; //Encryption round keys.//
|
||||
int[][] Kd = new int[ROUNDS + 1][BC]; //Decryption round keys.//
|
||||
int ROUND_KEY_COUNT = (ROUNDS + 1) * BC;
|
||||
int KC = length / 4;
|
||||
int[] tk = new int[KC];
|
||||
int i, j;
|
||||
|
||||
//Copy user material bytes into temporary ints.//
|
||||
for(i = 0, j = offset; i < KC;) {
|
||||
tk[i++] = (keyData[j++] & 0xFF) << 24 | (keyData[j++] & 0xFF) << 16 | (keyData[j++] & 0xFF) << 8 | (keyData[j++] & 0xFF);
|
||||
}//for//
|
||||
|
||||
//Copy values into round key arrays.//
|
||||
int t = 0;
|
||||
|
||||
for(j = 0;(j < KC) && (t < ROUND_KEY_COUNT); j++, t++) {
|
||||
Ke[t / BC][t % BC] = tk[j];
|
||||
Kd[ROUNDS - (t / BC)][t % BC] = tk[j];
|
||||
}//for//
|
||||
|
||||
int tt;
|
||||
int rconpointer = 0;
|
||||
|
||||
while(t < ROUND_KEY_COUNT) {
|
||||
//Extrapolate using phi (the round key evolution function).//
|
||||
tt = tk[KC - 1];
|
||||
tk[0] ^= (S[ (tt >>> 16) & 0xFF] & 0xFF) << 24 ^ (S[ (tt >>> 8) & 0xFF] & 0xFF) << 16 ^ (S[tt & 0xFF] & 0xFF) << 8 ^ (S[ (tt >>> 24) & 0xFF] & 0xFF) ^ (rcon[rconpointer++] & 0xFF) << 24;
|
||||
|
||||
if(KC != 8) {
|
||||
for(i = 1, j = 0; i < KC;) {
|
||||
tk[i++] ^= tk[j++];
|
||||
}//for//
|
||||
}//if//
|
||||
else {
|
||||
for(i = 1, j = 0; i < KC / 2;) {
|
||||
tk[i++] ^= tk[j++];
|
||||
}//for//
|
||||
|
||||
tt = tk[KC / 2 - 1];
|
||||
tk[KC / 2] ^= (S[tt & 0xFF] & 0xFF) ^ (S[ (tt >>> 8) & 0xFF] & 0xFF) << 8 ^ (S[ (tt >>> 16) & 0xFF] & 0xFF) << 16 ^ (S[ (tt >>> 24) & 0xFF] & 0xFF) << 24;
|
||||
|
||||
for(j = KC / 2, i = j + 1; i < KC;) {
|
||||
tk[i++] ^= tk[j++];
|
||||
}//for//
|
||||
}//else//
|
||||
|
||||
//Copy values into round key arrays.//
|
||||
for(j = 0;(j < KC) && (t < ROUND_KEY_COUNT); j++, t++) {
|
||||
Ke[t / BC][t % BC] = tk[j];
|
||||
Kd[ROUNDS - (t / BC)][t % BC] = tk[j];
|
||||
}//for//
|
||||
}//while//
|
||||
|
||||
for(int r = 1; r < ROUNDS; r++) {
|
||||
//Inverse MixColumn where needed.//
|
||||
for(j = 0; j < BC; j++) {
|
||||
tt = Kd[r][j];
|
||||
Kd[r][j] = U1[(tt >>> 24) & 0xFF] ^ U2[(tt >>> 16) & 0xFF] ^ U3[(tt >>> 8) & 0xFF] ^ U4[tt & 0xFF];
|
||||
}//for//
|
||||
}//for//
|
||||
|
||||
//Assemble the encryption (Ke) and decryption (Kd) round keys into one sessionKey object.//
|
||||
key = new Object[] {Ke, Kd};
|
||||
}//generateKey()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.ISymmetricAlgorithm#getEncryptedSize(int)
|
||||
*/
|
||||
public int getEncryptedSize(int unencryptedSize) {
|
||||
int virtualBlockCount = ((int) Math.ceil(unencryptedSize / ((float) (DEFAULT_VIRTUAL_BLOCK_SIZE - MINIMUM_PADDING))));
|
||||
int remainingPlainText = unencryptedSize - ((DEFAULT_VIRTUAL_BLOCK_SIZE - MINIMUM_PADDING) * (virtualBlockCount - 1));
|
||||
int blockCount = ((virtualBlockCount - 1) * (DEFAULT_VIRTUAL_BLOCK_SIZE / blockSize)) + ((int) Math.ceil((remainingPlainText + 2) / ((double) (blockSize - 1))));
|
||||
|
||||
return blockCount * blockSize;
|
||||
//return ((int) Math.ceil(unencryptedSize / ((float) (DEFAULT_VIRTUAL_BLOCK_SIZE - MINIMUM_PADDING)))) * (DEFAULT_VIRTUAL_BLOCK_SIZE);
|
||||
}//getEncryptedSize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.ISymmetricAlgorithm#getKeySize()
|
||||
*/
|
||||
public int getKeySize() {
|
||||
return keySize;
|
||||
}//getKeySize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.ISymmetricAlgorithm#getOptimalDecryptionBlockSize()
|
||||
*/
|
||||
public int getOptimalDecryptionBlockSize() {
|
||||
return DEFAULT_VIRTUAL_BLOCK_SIZE;
|
||||
}//getOptimalDecryptionBlockSize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.ISymmetricAlgorithm#getOptimalEncryptionBlockSize()
|
||||
*/
|
||||
public int getOptimalEncryptionBlockSize() {
|
||||
return DEFAULT_VIRTUAL_BLOCK_SIZE - MINIMUM_PADDING;
|
||||
}//getOptimalEncryptionBlockSize()//
|
||||
/**
|
||||
* Gets the number of rounds for a key and block size combination.
|
||||
* <p>Wynne::This will be 10, 12, or 14 if the blockSize is 16. The user could also have 24 or 32 byte blocks which would increase the rounds by 2 or 4, not to exceed 14 though. I don't know exactly which combinations are allowed, but I assume they are all allowed.
|
||||
* @param keySize The size of the user key material in bytes.
|
||||
* @param blockSize The desired block size in bytes.
|
||||
* @return The number of rounds that must be performed.
|
||||
*/
|
||||
private int getRounds(int keySize, int blockSize) {
|
||||
switch(keySize) {
|
||||
case 16 :
|
||||
return blockSize == 16 ? 10 : (blockSize == 24 ? 12 : 14);
|
||||
case 24 :
|
||||
return blockSize != 32 ? 12 : 14;
|
||||
default : //32 bytes = 256 bits.//
|
||||
return 14;
|
||||
}//switch//
|
||||
}//getRounds()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.ISymmetricAlgorithm#getUnencryptedSize(int)
|
||||
*/
|
||||
public int getUnencryptedSize(int encryptedSize) {
|
||||
return (int) Math.ceil(((encryptedSize / (double) DEFAULT_VIRTUAL_BLOCK_SIZE) * (DEFAULT_VIRTUAL_BLOCK_SIZE - MINIMUM_PADDING)) - .5d);
|
||||
}//getUnencryptedSize()//
|
||||
/**
|
||||
* Initializes the Rijndael static variables.
|
||||
* These variables support the encrypting & decrypting algorithums.
|
||||
*/
|
||||
protected void initialize() {
|
||||
if(tempBuffer == null) {
|
||||
tempBuffer = new byte[blockSize];
|
||||
}//if//
|
||||
|
||||
if(random == null) {
|
||||
random = createRandom();
|
||||
}//if//
|
||||
}//initialize()//
|
||||
/**
|
||||
* Creates a new random number generator.
|
||||
* @return The random number generator.
|
||||
*/
|
||||
protected Random createRandom() {
|
||||
return new Random();
|
||||
}//createRandom()//
|
||||
/**
|
||||
* Gets a single random byte.
|
||||
* @return The random byte.
|
||||
*/
|
||||
protected byte getRandomByte() {
|
||||
//Regenerate the random sequence every thousand bytes.//
|
||||
if(random == null || randomByteCounter++ > 1000) {
|
||||
random = createRandom();
|
||||
}//if//
|
||||
|
||||
return random.nextByte();
|
||||
}//getRandomByte()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.ISymmetricAlgorithm#decrypt(byte[], int, int, byte[], int)
|
||||
*/
|
||||
private void internalDecrypt(byte[] inputBuffer, byte[] outputBuffer, int outputBufferOffset) {
|
||||
int[][] kd = (int[][]) key[1]; //Extract decryption round keys.//
|
||||
int rounds = kd.length - 1;
|
||||
int[] kdr;
|
||||
int t0;
|
||||
int t1;
|
||||
int t2;
|
||||
int t3;
|
||||
int a0;
|
||||
int a1;
|
||||
int a2;
|
||||
int a3;
|
||||
int tt;
|
||||
byte[] b = inputBuffer;
|
||||
byte[] o = outputBuffer;
|
||||
int s = outputBufferOffset;
|
||||
|
||||
kdr = kd[0];
|
||||
//Combine key data with input data.//
|
||||
t0 = ((b[0] & 0xFF) << 24 | (b[1] & 0xFF) << 16 | (b[2] & 0xFF) << 8 | (b[3] & 0xFF)) ^ kdr[0];
|
||||
t1 = ((b[4] & 0xFF) << 24 | (b[5] & 0xFF) << 16 | (b[6] & 0xFF) << 8 | (b[7] & 0xFF)) ^ kdr[1];
|
||||
t2 = ((b[8] & 0xFF) << 24 | (b[9] & 0xFF) << 16 | (b[10] & 0xFF) << 8 | (b[11] & 0xFF)) ^ kdr[2];
|
||||
t3 = ((b[12] & 0xFF) << 24 | (b[13] & 0xFF) << 16 | (b[14] & 0xFF) << 8 | (b[15] & 0xFF)) ^ kdr[3];
|
||||
|
||||
//Round transforms.//
|
||||
for(int round = 1; round < rounds; round++) {
|
||||
kdr = kd[round];
|
||||
|
||||
a0 = (T5[(t0 >>> 24) & 0xFF] ^ T6[(t3 >>> 16) & 0xFF] ^ T7[(t2 >>> 8) & 0xFF] ^ T8[t1 & 0xFF]) ^ kdr[0];
|
||||
a1 = (T5[(t1 >>> 24) & 0xFF] ^ T6[(t0 >>> 16) & 0xFF] ^ T7[(t3 >>> 8) & 0xFF] ^ T8[t2 & 0xFF]) ^ kdr[1];
|
||||
a2 = (T5[(t2 >>> 24) & 0xFF] ^ T6[(t1 >>> 16) & 0xFF] ^ T7[(t0 >>> 8) & 0xFF] ^ T8[t3 & 0xFF]) ^ kdr[2];
|
||||
a3 = (T5[(t3 >>> 24) & 0xFF] ^ T6[(t2 >>> 16) & 0xFF] ^ T7[(t1 >>> 8) & 0xFF] ^ T8[t0 & 0xFF]) ^ kdr[3];
|
||||
t0 = a0;
|
||||
t1 = a1;
|
||||
t2 = a2;
|
||||
t3 = a3;
|
||||
}//for//
|
||||
|
||||
//Apply the last round.//
|
||||
kdr = kd[rounds];
|
||||
tt = kdr[0];
|
||||
|
||||
o[s++] = (byte) (Si[(t0 >>> 24) & 0xFF] ^ (tt >>> 24));
|
||||
o[s++] = (byte) (Si[(t3 >>> 16) & 0xFF] ^ (tt >>> 16));
|
||||
o[s++] = (byte) (Si[(t2 >>> 8) & 0xFF] ^ (tt >>> 8));
|
||||
o[s++] = (byte) (Si[t1 & 0xFF] ^ tt);
|
||||
tt = kdr[1];
|
||||
o[s++] = (byte) (Si[(t1 >>> 24) & 0xFF] ^ (tt >>> 24));
|
||||
o[s++] = (byte) (Si[(t0 >>> 16) & 0xFF] ^ (tt >>> 16));
|
||||
o[s++] = (byte) (Si[(t3 >>> 8) & 0xFF] ^ (tt >>> 8));
|
||||
o[s++] = (byte) (Si[t2 & 0xFF] ^ tt);
|
||||
tt = kdr[2];
|
||||
o[s++] = (byte) (Si[(t2 >>> 24) & 0xFF] ^ (tt >>> 24));
|
||||
o[s++] = (byte) (Si[(t1 >>> 16) & 0xFF] ^ (tt >>> 16));
|
||||
o[s++] = (byte) (Si[(t0 >>> 8) & 0xFF] ^ (tt >>> 8));
|
||||
o[s++] = (byte) (Si[t3 & 0xFF] ^ tt);
|
||||
tt = kdr[3];
|
||||
o[s++] = (byte) (Si[(t3 >>> 24) & 0xFF] ^ (tt >>> 24));
|
||||
o[s++] = (byte) (Si[(t2 >>> 16) & 0xFF] ^ (tt >>> 16));
|
||||
o[s++] = (byte) (Si[(t1 >>> 8) & 0xFF] ^ (tt >>> 8));
|
||||
o[s++] = (byte) (Si[t0 & 0xFF] ^ tt);
|
||||
}//internalDecrypt()//
|
||||
/**
|
||||
* Encrypts one block of data and places it in the supplied output buffer.
|
||||
* This method currently only accepts a single 16 byte block of input data.
|
||||
*/
|
||||
private void internalEncrypt(byte[] inputBuffer, byte[] outputBuffer, int outputBufferOffset) {
|
||||
int[][] ke = (int[][]) key[0]; //Extract encryption round keys.//
|
||||
int rounds = ke.length - 1;
|
||||
int[] ker;
|
||||
int t0;
|
||||
int t1;
|
||||
int t2;
|
||||
int t3;
|
||||
int a0;
|
||||
int a1;
|
||||
int a2;
|
||||
int a3;
|
||||
byte[] b = inputBuffer;
|
||||
byte[] o = outputBuffer;
|
||||
int s = outputBufferOffset;
|
||||
|
||||
//Initialize the variables.//
|
||||
ker = ke[0];
|
||||
//Plaintext to ints + key.//
|
||||
t0 = ((b[0] & 0xFF) << 24 | (b[1] & 0xFF) << 16 | (b[2] & 0xFF) << 8 | (b[3] & 0xFF)) ^ ker[0];
|
||||
t1 = ((b[4] & 0xFF) << 24 | (b[5] & 0xFF) << 16 | (b[6] & 0xFF) << 8 | (b[7] & 0xFF)) ^ ker[1];
|
||||
t2 = ((b[8] & 0xFF) << 24 | (b[9] & 0xFF) << 16 | (b[10] & 0xFF) << 8 | (b[11] & 0xFF)) ^ ker[2];
|
||||
t3 = ((b[12] & 0xFF) << 24 | (b[13] & 0xFF) << 16 | (b[14] & 0xFF) << 8 | (b[15] & 0xFF)) ^ ker[3];
|
||||
|
||||
//Apply round transforms.//
|
||||
for(int round = 1; round < rounds; round++) {
|
||||
ker = ke[round];
|
||||
|
||||
a0 = (T1[(t0 >>> 24) & 0xFF] ^ T2[(t1 >>> 16) & 0xFF] ^ T3[(t2 >>> 8) & 0xFF] ^ T4[t3 & 0xFF]) ^ ker[0];
|
||||
a1 = (T1[(t1 >>> 24) & 0xFF] ^ T2[(t2 >>> 16) & 0xFF] ^ T3[(t3 >>> 8) & 0xFF] ^ T4[t0 & 0xFF]) ^ ker[1];
|
||||
a2 = (T1[(t2 >>> 24) & 0xFF] ^ T2[(t3 >>> 16) & 0xFF] ^ T3[(t0 >>> 8) & 0xFF] ^ T4[t1 & 0xFF]) ^ ker[2];
|
||||
a3 = (T1[(t3 >>> 24) & 0xFF] ^ T2[(t0 >>> 16) & 0xFF] ^ T3[(t1 >>> 8) & 0xFF] ^ T4[t2 & 0xFF]) ^ ker[3];
|
||||
t0 = a0;
|
||||
t1 = a1;
|
||||
t2 = a2;
|
||||
t3 = a3;
|
||||
}//for//
|
||||
|
||||
//Last round is special.//
|
||||
ker = ke[rounds];
|
||||
int tt = ker[0];
|
||||
|
||||
o[s++] = (byte) (S[(t0 >>> 24) & 0xFF] ^ (tt >>> 24));
|
||||
o[s++] = (byte) (S[(t1 >>> 16) & 0xFF] ^ (tt >>> 16));
|
||||
o[s++] = (byte) (S[(t2 >>> 8) & 0xFF] ^ (tt >>> 8));
|
||||
o[s++] = (byte) (S[t3 & 0xFF] ^ tt);
|
||||
tt = ker[1];
|
||||
o[s++] = (byte) (S[(t1 >>> 24) & 0xFF] ^ (tt >>> 24));
|
||||
o[s++] = (byte) (S[(t2 >>> 16) & 0xFF] ^ (tt >>> 16));
|
||||
o[s++] = (byte) (S[(t3 >>> 8) & 0xFF] ^ (tt >>> 8));
|
||||
o[s++] = (byte) (S[t0 & 0xFF] ^ tt);
|
||||
tt = ker[2];
|
||||
o[s++] = (byte) (S[(t2 >>> 24) & 0xFF] ^ (tt >>> 24));
|
||||
o[s++] = (byte) (S[(t3 >>> 16) & 0xFF] ^ (tt >>> 16));
|
||||
o[s++] = (byte) (S[(t0 >>> 8) & 0xFF] ^ (tt >>> 8));
|
||||
o[s++] = (byte) (S[t1 & 0xFF] ^ tt);
|
||||
tt = ker[3];
|
||||
o[s++] = (byte) (S[(t3 >>> 24) & 0xFF] ^ (tt >>> 24));
|
||||
o[s++] = (byte) (S[(t0 >>> 16) & 0xFF] ^ (tt >>> 16));
|
||||
o[s++] = (byte) (S[(t1 >>> 8) & 0xFF] ^ (tt >>> 8));
|
||||
o[s++] = (byte) (S[t2 & 0xFF] ^ tt);
|
||||
}//internalEncrypt()//
|
||||
/**
|
||||
* A simple test main.
|
||||
* <p>TODO: Move this into a test suite.</p>
|
||||
* @param args None required.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
Rijndael algorithm = new Rijndael("test");
|
||||
|
||||
try {
|
||||
String text = "The quick brown fox jumped over the moon. The quick brown fox jumped over the moon. The quick brown fox jumped over the moon. The quick brown fox jumped over the moon. The quick brown fox jumped over the moon. The quick brown fox jumped over the moon. The quick brown fox jumped over the moon. The quick brown fox jumped over the moon. The quick brown fox jumped over the moon. The quick brown fox jumped over the moon. The quick brown fox jumped over the moon. The quick brown fox jumped over the moon. The quick brown fox jumped over the moon. The quick brown fox jumped over the moon. The quick brown fox jumped over the moon. The quick brown fox jumped over the moon. The quick brown fox jumped over the moon. The quick brown fox jumped over the moon. The quick brown fox jumped over the moon. The quick brown fox jumped over the moon. The quick brown fox jumped over the moon. The quick brown fox jumped over the moon.";
|
||||
byte[] source = text.getBytes("utf8");
|
||||
//byte[] source = new byte[20];
|
||||
byte[] encrypted = new byte[algorithm.getEncryptedSize(source.length)];
|
||||
byte[] decrypted = new byte[source.length];
|
||||
//Random random = createRandom();
|
||||
int encryptedSize = 0;
|
||||
|
||||
//random.nextBytes(source);
|
||||
encryptedSize = algorithm.encrypt(source, 0, source.length, encrypted, 0);
|
||||
algorithm.decrypt(encrypted, 0, encryptedSize, decrypted, 0);
|
||||
Debug.log("Input: " + text);
|
||||
Debug.log("Output: " + new String(decrypted, "utf8"));
|
||||
//Debug.log("1");
|
||||
}
|
||||
catch(Throwable e) {
|
||||
Debug.log(e);
|
||||
}
|
||||
|
||||
{
|
||||
byte[] source = new byte[] {0, 118, -65, -1, 10, 0, 0, 0, 32, 99, 111, 109, 46, 99, 111, 109};
|
||||
byte[] encrypted = new byte[source.length];
|
||||
byte[] decrypted = new byte[source.length];
|
||||
|
||||
algorithm.internalEncrypt(source, encrypted, 0);
|
||||
algorithm.internalDecrypt(encrypted, decrypted, 0);
|
||||
Debug.log("2");
|
||||
}
|
||||
|
||||
{
|
||||
byte[] encrypted = new byte[] {16, -82, 10, 87, 6, -112, 46, -64, -39, -72, -23, 114, -12, 31, -49, 106};
|
||||
byte[] decrypted = new byte[encrypted.length];
|
||||
algorithm.internalDecrypt(encrypted, decrypted, 0);
|
||||
Debug.log("3");
|
||||
}
|
||||
|
||||
System.exit(0);
|
||||
}//main()//
|
||||
//A really simple main for basic testing.
|
||||
//public static void main(String[] args) {
|
||||
// Rijndael alg = new Rijndael(new byte[] {1, 2, 3, 4});
|
||||
// byte[] b = new byte[16];
|
||||
// byte[] out = new byte[128];
|
||||
//
|
||||
// b[0] = 0;
|
||||
// b[1] = 118;
|
||||
// b[2] = 2;
|
||||
// b[3] = 0;
|
||||
// b[4] = 0;
|
||||
// b[5] = 0;
|
||||
// b[6] = 1;
|
||||
// b[7] = 0;
|
||||
// b[8] = 0;
|
||||
// b[9] = 0;
|
||||
// b[10] = 45;
|
||||
// b[11] = 80;
|
||||
// b[12] = 97;
|
||||
// b[13] = 114;
|
||||
// b[14] = 107;
|
||||
// b[15] = 105;
|
||||
//
|
||||
// byte[] orig = new byte[16];
|
||||
// System.arraycopy(b, 0, orig, 0, 16);
|
||||
//
|
||||
// alg.internalEncrypt(b, b, 0);
|
||||
// alg.internalDecrypt(b, b, 0);
|
||||
//
|
||||
// for(int index = 0; index < orig.length; index++) {
|
||||
// if(b[index] != orig[index]) {
|
||||
// Debug.log("Error in stream.");
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
/**
|
||||
* Multiply two elements of GF(2^m).
|
||||
* @param a
|
||||
* @param b
|
||||
* @return
|
||||
*/
|
||||
private static final int mul(int a, int b) {
|
||||
return (a != 0 && b != 0) ? alog[(log[a & 0xFF] + log[b & 0xFF]) % 255] : 0;
|
||||
}//mul()//
|
||||
/**
|
||||
* Convenience method used in generating Transposition boxes.
|
||||
* @param a
|
||||
* @param b
|
||||
* @return
|
||||
*/
|
||||
private static final int mul4(int a, byte[] b) {
|
||||
if(a == 0) {
|
||||
return 0;
|
||||
}//if//
|
||||
|
||||
a = log[a & 0xFF];
|
||||
int a0 = (b[0] != 0) ? alog[(a + log[b[0] & 0xFF]) % 255] & 0xFF : 0;
|
||||
int a1 = (b[1] != 0) ? alog[(a + log[b[1] & 0xFF]) % 255] & 0xFF : 0;
|
||||
int a2 = (b[2] != 0) ? alog[(a + log[b[2] & 0xFF]) % 255] & 0xFF : 0;
|
||||
int a3 = (b[3] != 0) ? alog[(a + log[b[3] & 0xFF]) % 255] & 0xFF : 0;
|
||||
|
||||
return a0 << 24 | a1 << 16 | a2 << 8 | a3;
|
||||
}//mul4()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.Externalizable#readExternal(java.io.ObjectInput)
|
||||
*/
|
||||
public void readExternal(java.io.ObjectInput in) throws java.io.IOException, ClassNotFoundException {
|
||||
key = (Object[]) in.readObject();
|
||||
blockSize = in.readInt();
|
||||
keySize = in.readInt();
|
||||
initialize();
|
||||
}//readExternal()//
|
||||
/**
|
||||
* Sets up the algorithm's key using the supplied data and key size.
|
||||
* @param buffer The data used to generate a key, or if it is the correct length it will be used as the key.
|
||||
* @param offset The offset of the first data byte in the buffer.
|
||||
* @param length The number of data bytes in the buffer. This must be exactly sized to the key size (length == keySize). The only valid lengths are: 16, 24, or 32.
|
||||
*/
|
||||
public void setupKey(byte[] buffer, int offset, int length) {
|
||||
switch(length) {
|
||||
case 16:
|
||||
case 24:
|
||||
case 32:
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Incorrect key length in Rijndael.setupKey(byte[])");
|
||||
}//switch//
|
||||
|
||||
generateKey(buffer, offset, length);
|
||||
}//setupKey()//
|
||||
/**
|
||||
* Creates a session key using the supplied key data.
|
||||
* @param buffer The data used as the key. This must be exactly sized to the key size (length == keySize). The only valid lengths are: 16, 24, or 32.
|
||||
*/
|
||||
public void setupKey(byte[] buffer) {
|
||||
setupKey(buffer, 0, buffer.length);
|
||||
}//setupKey()//
|
||||
/**
|
||||
* Creates a session key using the supplied key size.
|
||||
* @param keySize The size of the Rijndael key. The only valid values are: 16, 24, or 32.
|
||||
* @param random An optional random number generator that will be used by the algorithm.
|
||||
*/
|
||||
public void setupKey(int keySize, java.util.Random random) {
|
||||
byte[] keyData = null;
|
||||
|
||||
if(random == null) {
|
||||
random = createRandom();
|
||||
}//if//
|
||||
|
||||
switch(keySize) {
|
||||
case 16:
|
||||
case 24:
|
||||
case 32:
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Rijndael: Invalid key size.");
|
||||
}//switch//
|
||||
|
||||
keyData = new byte[keySize];
|
||||
random.nextBytes(keyData);
|
||||
generateKey(keyData, 0, keyData.length);
|
||||
}//setupKey()//
|
||||
/**
|
||||
* Creates a session key using the supplied key data and key size.
|
||||
* <p>Warning: This code fails on the mac - the seed is not properly set on a mac as of Java 1.6.</p>
|
||||
* @param data The data used to generate a key.
|
||||
* @param keySize The size of the Rijndael key. The only valid values are: 16, 24, or 32.
|
||||
*/
|
||||
public void setupKey(String data, int keySize) {
|
||||
byte[] buffer = new byte[keySize];
|
||||
Random r = new Random(data.getBytes()); //Note: This doesn't work on the mac. The mac fails to use the input to set the seed.
|
||||
|
||||
r.nextBytes(buffer);
|
||||
setupKey(buffer, 0, buffer.length);
|
||||
}//setupKey()//
|
||||
/**
|
||||
* Creates a session key using the supplied key data and the default key size.
|
||||
* <p>Warning: This code fails on the mac - the seed is not properly set on a mac as of Java 1.6.</p>
|
||||
* @param data The data used to generate a key.
|
||||
*/
|
||||
public void setupKey(String keyData) {
|
||||
setupKey(keyData, DEFAULT_KEY_SIZE);
|
||||
}//setupKey()//
|
||||
/**
|
||||
* Initializes the Rijndael static variables.
|
||||
* These variables support the encrypting & decrypting algorithums.
|
||||
*/
|
||||
protected static void staticInitialize() {
|
||||
int ROOT = 0x11B;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int r = 1;
|
||||
byte[][] A = new byte[][] {{1, 1, 1, 1, 1, 0, 0, 0}, {0, 1, 1, 1, 1, 1, 0, 0}, {0, 0, 1, 1, 1, 1, 1, 0}, {0, 0, 0, 1, 1, 1, 1, 1}, {1, 0, 0, 0, 1, 1, 1, 1}, {1, 1, 0, 0, 0, 1, 1, 1}, {1, 1, 1, 0, 0, 0, 1, 1}, {1, 1, 1, 1, 0, 0, 0, 1}};
|
||||
byte[] B = new byte[] {0, 1, 1, 0, 0, 0, 1, 1};
|
||||
int t;
|
||||
byte[][] box = new byte[256][8]; //Substitution Box (based on F^{-1}(x))//
|
||||
byte[][] cox = new byte[256][8]; //Affine Transform (box[i] <- B + A*box[i])//
|
||||
byte[][] G = new byte[][] {{2, 1, 1, 3}, {3, 2, 1, 1}, {1, 3, 2, 1}, {1, 1, 3, 2}}; //T-boxes.//
|
||||
byte[][] AA = new byte[4][8]; //T-boxes.//
|
||||
byte pivot;
|
||||
byte tmp;
|
||||
byte[][] iG = new byte[4][4];
|
||||
|
||||
alog[0] = 1;
|
||||
|
||||
for(i = 1; i < 256; i++) {
|
||||
j = (alog[i - 1] << 1) ^ alog[i - 1];
|
||||
|
||||
if((j & 0x100) != 0) {
|
||||
j ^= ROOT;
|
||||
}//if//
|
||||
|
||||
alog[i] = j;
|
||||
}//for//
|
||||
|
||||
for(i = 1; i < 255; i++) {
|
||||
log[alog[i]] = i;
|
||||
}//for//
|
||||
|
||||
box[1][7] = 1;
|
||||
|
||||
for(i = 2; i < 256; i++) {
|
||||
j = alog[255 - log[i]];
|
||||
|
||||
for(t = 0; t < 8; t++) {
|
||||
box[i][t] = (byte) ((j >>> (7 - t)) & 0x01);
|
||||
}//for//
|
||||
}//for//
|
||||
|
||||
for(i = 0; i < 256; i++) {
|
||||
for(t = 0; t < 8; t++) {
|
||||
cox[i][t] = B[t];
|
||||
|
||||
for(j = 0; j < 8; j++) {
|
||||
cox[i][t] ^= A[t][j] * box[i][j];
|
||||
}//for//
|
||||
}//for//
|
||||
}//for//
|
||||
|
||||
for(i = 0; i < 256; i++) {
|
||||
S[i] = (byte) (cox[i][0] << 7); //S-boxes.//
|
||||
|
||||
for (t = 1; t < 8; t++) {
|
||||
S[i] ^= cox[i][t] << (7 - t); //S-boxes.//
|
||||
}//for//
|
||||
|
||||
Si[S[i] & 0xFF] = (byte) i; //Inverse S-boxes.//
|
||||
}//for//
|
||||
|
||||
for(i = 0; i < 4; i++) {
|
||||
for(j = 0; j < 4; j++) {
|
||||
AA[i][j] = G[i][j];
|
||||
}//for//
|
||||
|
||||
AA[i][i + 4] = 1;
|
||||
}//for//
|
||||
|
||||
for(i = 0; i < 4; i++) {
|
||||
pivot = AA[i][i];
|
||||
|
||||
if(pivot == 0) {
|
||||
t = i + 1;
|
||||
|
||||
while((AA[t][i] == 0) && (t < 4)) {
|
||||
t++;
|
||||
}//while//
|
||||
|
||||
if(t == 4) {
|
||||
throw new RuntimeException("G matrix is not invertible");
|
||||
}//if//
|
||||
else {
|
||||
for(j = 0; j < 8; j++) {
|
||||
tmp = AA[i][j];
|
||||
AA[i][j] = AA[t][j];
|
||||
AA[t][j] = (byte) tmp;
|
||||
}//for//
|
||||
|
||||
pivot = AA[i][i];
|
||||
}//else//
|
||||
}//if//
|
||||
|
||||
for(j = 0; j < 8; j++) {
|
||||
if(AA[i][j] != 0) {
|
||||
AA[i][j] = (byte) alog[ (255 + log[AA[i][j] & 0xFF] - log[pivot & 0xFF]) % 255];
|
||||
}//if//
|
||||
}//for//
|
||||
|
||||
for(t = 0; t < 4; t++) {
|
||||
if(i != t) {
|
||||
for(j = i + 1; j < 8; j++) {
|
||||
AA[t][j] ^= mul(AA[i][j], AA[t][i]);
|
||||
}//for//
|
||||
|
||||
AA[t][i] = 0;
|
||||
}//if//
|
||||
}//for//
|
||||
}//for//
|
||||
|
||||
for(i = 0; i < 4; i++) {
|
||||
for(j = 0; j < 4; j++) {
|
||||
iG[i][j] = AA[i][j + 4];
|
||||
}//for//
|
||||
}//for//
|
||||
|
||||
for(t = 0; t < 256; t++) {
|
||||
int s = S[t];
|
||||
|
||||
T1[t] = mul4(s, G[0]);
|
||||
T2[t] = mul4(s, G[1]);
|
||||
T3[t] = mul4(s, G[2]);
|
||||
T4[t] = mul4(s, G[3]);
|
||||
s = Si[t];
|
||||
T5[t] = mul4(s, iG[0]);
|
||||
T6[t] = mul4(s, iG[1]);
|
||||
T7[t] = mul4(s, iG[2]);
|
||||
T8[t] = mul4(s, iG[3]);
|
||||
U1[t] = mul4(t, iG[0]);
|
||||
U2[t] = mul4(t, iG[1]);
|
||||
U3[t] = mul4(t, iG[2]);
|
||||
U4[t] = mul4(t, iG[3]);
|
||||
}//for//
|
||||
|
||||
rcon[0] = 1;
|
||||
|
||||
for(t = 1; t < 30;) {
|
||||
rcon[t++] = (byte) (r = mul(2, r)); //Round constants.//
|
||||
}//for//
|
||||
}//staticInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
|
||||
*/
|
||||
public void writeExternal(java.io.ObjectOutput out) throws java.io.IOException {
|
||||
out.writeObject(key);
|
||||
out.writeInt(blockSize);
|
||||
out.writeInt(keySize);
|
||||
}//writeExternal()//
|
||||
}//Rijndael//
|
||||
1093
Common/src/com/common/security/RsaAlgorithm.java
Normal file
1093
Common/src/com/common/security/RsaAlgorithm.java
Normal file
File diff suppressed because it is too large
Load Diff
587
Common/src/com/common/security/Sha1.java
Normal file
587
Common/src/com/common/security/Sha1.java
Normal file
@@ -0,0 +1,587 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.security;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import com.common.util.StringSupport;
|
||||
|
||||
/**
|
||||
* TODO: Determine original source.
|
||||
*/
|
||||
public class Sha1 implements IHashAlgorithm {
|
||||
/** The size of a hash in bytes. */
|
||||
private static final int HASH_SIZE = 20;
|
||||
/** The size of a hash in ints. */
|
||||
private static final int INT_HASH_SIZE = HASH_SIZE >> 2;
|
||||
/** The size of a block of source to be hashed (in bytes). */
|
||||
private static final int BLOCK_SIZE = 64;
|
||||
/** The size of a block of source to be hashed (in ints). */
|
||||
private static final int INT_BLOCK_SIZE = BLOCK_SIZE >> 2;
|
||||
/** The total source size. */
|
||||
private long sourceSize;
|
||||
/**
|
||||
* A buffer containing the bytes yet to be added to the digest.
|
||||
* This buffer will always be DATA_LENGTH in size and the digest will be updated when it is filled (so that this buffer can be emptied and reused).
|
||||
*/
|
||||
private byte[] sourceBuffer;
|
||||
private int sourceBufferLength;
|
||||
/**
|
||||
* The digest integers as an array.
|
||||
* This is where the digest actually gets stored until the hash has completely finished and the digest bytes are given to the user.
|
||||
*/
|
||||
private int[] hashBuffer;
|
||||
private int[] internalHashBuffer;
|
||||
private int[] internalBuffer;
|
||||
/**
|
||||
* Constructs SHA-1 algorithm used to generate digests from source data.
|
||||
*/
|
||||
public Sha1() {
|
||||
initialize();
|
||||
}//Sha1)//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IWriter#write(byte)
|
||||
*/
|
||||
public void write(byte b) {
|
||||
add(b);
|
||||
}//write()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IWriter#write(byte[], int, int)
|
||||
*/
|
||||
public void write(byte[] bytes, int offset, int length) {
|
||||
add(bytes, offset, length);
|
||||
}//write()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IWriter#write(byte[])
|
||||
*/
|
||||
public void write(byte[] bytes) {
|
||||
add(bytes);
|
||||
}//write()//
|
||||
/**
|
||||
* Sha1 copy constructor.
|
||||
* @param algorithm The algorithm to be copied.
|
||||
*/
|
||||
private Sha1(Sha1 algorithm) {
|
||||
sourceSize = algorithm.sourceSize;
|
||||
sourceBufferLength = algorithm.sourceBufferLength;
|
||||
sourceBuffer = (byte[]) algorithm.sourceBuffer.clone();
|
||||
internalHashBuffer = (int[]) algorithm.internalHashBuffer.clone();
|
||||
hashBuffer = (int[]) algorithm.hashBuffer.clone();
|
||||
internalBuffer = (int[]) algorithm.internalBuffer.clone();
|
||||
}//Sha1()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#add(byte)
|
||||
*/
|
||||
public void add(byte b) {
|
||||
sourceSize++;
|
||||
sourceBuffer[sourceBufferLength++] = b;
|
||||
|
||||
if(sourceBufferLength == BLOCK_SIZE) {
|
||||
//Transform the bytes into integers.//
|
||||
convert(sourceBuffer, 0, internalHashBuffer, 0, INT_BLOCK_SIZE);
|
||||
//Update the hash.//
|
||||
transform(internalHashBuffer);
|
||||
sourceBufferLength = 0;
|
||||
}//if//
|
||||
}//add()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#add(byte[])
|
||||
*/
|
||||
public void add(byte[] buffer) {
|
||||
if(buffer != null && buffer.length > 0) {
|
||||
add(buffer, 0, buffer.length);
|
||||
}//if//
|
||||
}//add()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#add(byte[], int, int)
|
||||
*/
|
||||
public void add(byte[] buffer, int bufferOffset, int bufferLength) {
|
||||
if(bufferLength > 0) {
|
||||
int size = 0;
|
||||
|
||||
sourceSize += bufferLength;
|
||||
|
||||
//Hash the source in blocks.//
|
||||
while((size = BLOCK_SIZE - sourceBufferLength) <= bufferLength) {
|
||||
//Fill the source buffer.//
|
||||
System.arraycopy(buffer, bufferOffset, sourceBuffer, sourceBufferLength, size);
|
||||
//Transform the bytes into integers.//
|
||||
convert(sourceBuffer, 0, internalHashBuffer, 0, INT_BLOCK_SIZE);
|
||||
//Update the hash.//
|
||||
transform(internalHashBuffer);
|
||||
bufferLength -= size;
|
||||
bufferOffset += size;
|
||||
sourceBufferLength = 0;
|
||||
}//while//
|
||||
|
||||
if(bufferLength > 0) {
|
||||
//Save partial source in the source buffer.//
|
||||
System.arraycopy(buffer, bufferOffset, sourceBuffer, sourceBufferLength, bufferLength);
|
||||
sourceBufferLength += bufferLength;
|
||||
}//if//
|
||||
}//if//
|
||||
}//add()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#add(java.io.InputStream)
|
||||
*/
|
||||
public void add(InputStream in) throws IOException {
|
||||
byte[] buffer = new byte[10000];
|
||||
int readCount = 0;
|
||||
|
||||
while(readCount >= 0) {
|
||||
readCount = in.read(buffer);
|
||||
|
||||
if(readCount > 0) {
|
||||
add(buffer, 0, readCount);
|
||||
}//if//
|
||||
}//while//
|
||||
}//add()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#add(String)
|
||||
*/
|
||||
public void add(String source) {
|
||||
if(source != null && source.length() > 0) {
|
||||
add(StringSupport.toUtf8Bytes(source));
|
||||
}//if//
|
||||
}//add()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#add(char[])
|
||||
*/
|
||||
public void add(char[] source) {
|
||||
if(source != null && source.length > 0) {
|
||||
add(StringSupport.toUtf8Bytes(source));
|
||||
}//if//
|
||||
}//add()//
|
||||
/**
|
||||
* Adds the last of the source to the hash. At the very least this adds the source size to the hash.
|
||||
*/
|
||||
private void addFinal() {
|
||||
int position = sourceBufferLength;
|
||||
long bitCount;
|
||||
|
||||
sourceBuffer[position++] = (byte) 0x80;
|
||||
|
||||
//Add remaining source to the hash.//
|
||||
if(position > BLOCK_SIZE - 8) {
|
||||
//Add trailing zeros.//
|
||||
while(position < BLOCK_SIZE) {
|
||||
sourceBuffer[position++] = 0;
|
||||
}//while//
|
||||
|
||||
convert(sourceBuffer, 0, internalHashBuffer, 0, INT_BLOCK_SIZE);
|
||||
transform(internalHashBuffer);
|
||||
position = 0;
|
||||
}//if//
|
||||
|
||||
//Clear the end of the source buffer.//
|
||||
for(int i = position; i < BLOCK_SIZE - 8; i ++) {
|
||||
sourceBuffer[i] = 0;
|
||||
}//for//
|
||||
|
||||
convert(sourceBuffer, 0, internalHashBuffer, 0, INT_BLOCK_SIZE);
|
||||
|
||||
//Add the message size to the hash.//
|
||||
bitCount = sourceSize << 3;
|
||||
internalHashBuffer[INT_BLOCK_SIZE - 2] = (int) (bitCount >>> 32);
|
||||
internalHashBuffer[INT_BLOCK_SIZE - 1] = (int) bitCount;
|
||||
transform(internalHashBuffer);
|
||||
}//addFinal()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#cleanup()
|
||||
*/
|
||||
public void cleanup() {
|
||||
}//cleanup()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#clone()
|
||||
*/
|
||||
public Object clone() {
|
||||
return new Sha1(this);
|
||||
}//clone()//
|
||||
/**
|
||||
* Converts bytes into integers.
|
||||
*/
|
||||
private void convert(byte[] source, int sourceOffset, int[] destination, int destinationOffset, int destinationLength) {
|
||||
while(destinationLength-- > 0) {
|
||||
//Big Endian//
|
||||
destination[destinationOffset++] = (source[sourceOffset++] << 24) | ((source[sourceOffset++] & 0xFF) << 16) | ((source[sourceOffset++] & 0xFF) << 8) | (source[sourceOffset++] & 0xFF);
|
||||
}//while//
|
||||
}//convert()//
|
||||
/**
|
||||
* Transform 1.
|
||||
*/
|
||||
private int f1(int a, int b, int c) {
|
||||
return (c ^ (a & (b ^ c))) + 0x5A827999;
|
||||
}//f1()//
|
||||
/**
|
||||
* Transform 2.
|
||||
*/
|
||||
private int f2(int a, int b, int c) {
|
||||
return (a ^ b ^ c) + 0x6ED9EBA1;
|
||||
}//f2()//
|
||||
/**
|
||||
* Transform 3.
|
||||
*/
|
||||
private int f3(int a, int b, int c) {
|
||||
return ((a & b) | (c & (a | b))) + 0x8F1BBCDC;
|
||||
}//f3()//
|
||||
/**
|
||||
* Transform 4.
|
||||
*/
|
||||
private int f4(int a, int b, int c) {
|
||||
return (a ^ b ^ c) + 0xCA62C1D6;
|
||||
}//f4()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#getHashSize()
|
||||
*/
|
||||
public int getHashSize() {
|
||||
return HASH_SIZE;
|
||||
}//getHashSize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#hash()
|
||||
*/
|
||||
public byte[] hash() {
|
||||
return internalHash();
|
||||
}//hash()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#hash(byte[], int, int)
|
||||
*/
|
||||
public byte[] hash(byte[] source, int sourceOffset, int sourceLength) {
|
||||
add(source, sourceOffset, sourceLength);
|
||||
|
||||
return internalHash();
|
||||
}//hash()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#hash(byte[], int, int, byte[], int)
|
||||
*/
|
||||
public void hash(byte[] source, int sourceOffset, int sourceLength, byte[] hashBuffer, int hashBufferOffset) {
|
||||
add(source, sourceOffset, sourceLength);
|
||||
internalHash(hashBuffer, hashBufferOffset);
|
||||
}//hash()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#hash(String)
|
||||
*/
|
||||
public byte[] hash(String source) {
|
||||
add(source);
|
||||
|
||||
return internalHash();
|
||||
}//hash()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#hash(String, byte[], int)
|
||||
*/
|
||||
public void hash(String source, byte[] hashBuffer, int hashBufferOffset) {
|
||||
add(source);
|
||||
internalHash(hashBuffer, hashBufferOffset);
|
||||
}//hash()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#hash(char[])
|
||||
*/
|
||||
public byte[] hash(char[] source) {
|
||||
add(source);
|
||||
|
||||
return internalHash();
|
||||
}//hash()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#hash(char[], byte[], int)
|
||||
*/
|
||||
public void hash(char[] source, byte[] hashBuffer, int hashBufferOffset) {
|
||||
add(source);
|
||||
internalHash(hashBuffer, hashBufferOffset);
|
||||
}//hash()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#hashToString()
|
||||
*/
|
||||
public String hashToString() {
|
||||
return hashToString((String) null);
|
||||
}//hashToString()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#hashToString(String)
|
||||
*/
|
||||
public String hashToString(String source) {
|
||||
byte[] hashBuffer = source != null ? hash(source) : hash();
|
||||
|
||||
return StringSupport.fromUnicode16Bytes(hashBuffer, 0, hashBuffer.length);
|
||||
}//hashToString()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#hashToString(char[])
|
||||
*/
|
||||
public String hashToString(char[] source) {
|
||||
byte[] hashBuffer = source != null ? hash(source) : hash();
|
||||
|
||||
return StringSupport.fromUnicode16Bytes(hashBuffer, 0, hashBuffer.length);
|
||||
}//hashToString()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#hashToHex()
|
||||
*/
|
||||
public String hashToHex() {
|
||||
return hashToHex(null);
|
||||
}//hashToHex()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#hashToHex(String)
|
||||
*/
|
||||
public String hashToHex(String source) {
|
||||
byte[] hashBuffer = source != null ? hash(source) : hash();
|
||||
|
||||
return StringSupport.toHexString(hashBuffer, 0, hashBuffer.length);
|
||||
}//hashToHex()//
|
||||
/**
|
||||
* Initializes the hash algorithm.
|
||||
*/
|
||||
private void initialize() {
|
||||
//Initialize the buffers.//
|
||||
sourceBuffer = new byte[BLOCK_SIZE];
|
||||
hashBuffer = new int[INT_HASH_SIZE];
|
||||
internalHashBuffer = new int[INT_BLOCK_SIZE];
|
||||
internalBuffer = new int[80];
|
||||
reset(); //Prepare the algorithm for its first hash.//
|
||||
}//initialize()//
|
||||
/**
|
||||
* Creates a hash of the previously supplied source.
|
||||
* @return The hash bytes.
|
||||
*/
|
||||
protected byte[] internalHash() {
|
||||
byte[] buffer = new byte[HASH_SIZE];
|
||||
|
||||
internalHash(buffer, 0);
|
||||
|
||||
return buffer;
|
||||
}//internalHash()//
|
||||
/**
|
||||
* Creates a hash of the previously supplied source.
|
||||
* @param hashBuffer The buffer to place the hash in.
|
||||
* @param hashBufferOffset The index of the first hash byte.
|
||||
*/
|
||||
protected void internalHash(byte[] hashBuffer, int hashBufferOffset) {
|
||||
//Add any final source into the mix.//
|
||||
addFinal();
|
||||
|
||||
//Copy the hash into the result buffer in Big Endian format.//
|
||||
for(int i = 0; i < INT_HASH_SIZE; ++i) {
|
||||
int value = this.hashBuffer[i];
|
||||
|
||||
hashBuffer[hashBufferOffset++] = (byte) (value >>> 24);
|
||||
hashBuffer[hashBufferOffset++] = (byte) (value >>> 16);
|
||||
hashBuffer[hashBufferOffset++] = (byte) (value >>> 8);
|
||||
hashBuffer[hashBufferOffset++] = (byte) value;
|
||||
}//for//
|
||||
|
||||
//Reset the algorithm.//
|
||||
reset();
|
||||
}//internalHash()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.Externalizable#readExternal(java.io.ObjectInput)
|
||||
*/
|
||||
public void readExternal(java.io.ObjectInput in) throws java.io.IOException, ClassNotFoundException {
|
||||
}//readExternal()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#reset()
|
||||
*/
|
||||
public void reset() {
|
||||
sourceBufferLength = 0;
|
||||
sourceSize = 0;
|
||||
hashBuffer[0] = 0x67452301;
|
||||
hashBuffer[1] = 0xEFCDAB89;
|
||||
hashBuffer[2] = 0x98BADCFE;
|
||||
hashBuffer[3] = 0x10325476;
|
||||
hashBuffer[4] = 0xC3D2E1F0;
|
||||
}//reset()//
|
||||
/**
|
||||
* The SHA-1 transform method which maintains the current hashBuffer by adding/transforming blocks of source data.
|
||||
* @param data The integers containing the source data to be added to the current hashBuffer.
|
||||
*/
|
||||
private void transform(int[] data) {
|
||||
int a = hashBuffer[0];
|
||||
int b = hashBuffer[1];
|
||||
int c = hashBuffer[2];
|
||||
int d = hashBuffer[3];
|
||||
int e = hashBuffer[4];
|
||||
int[] w = internalBuffer;
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
w[i] = data[i];
|
||||
}//for//
|
||||
|
||||
for(int i = 16; i < 80; i++) {
|
||||
int j = w[i - 16] ^ w[i - 14] ^ w[i - 8] ^ w[i - 3];
|
||||
|
||||
w[i] = j;
|
||||
w[i] = (j << 1) | (j >>> -1);
|
||||
}//for//
|
||||
|
||||
e += ((a << 5) | (a >>> -5)) + f1(b, c, d) + w[0];
|
||||
b = ((b << 30) | (b >>> -30));
|
||||
d += ((e << 5) | (e >>> -5)) + f1(a, b, c) + w[1];
|
||||
a = ((a << 30) | (a >>> -30));
|
||||
c += ((d << 5) | (d >>> -5)) + f1(e, a, b) + w[2];
|
||||
e = ((e << 30) | (e >>> -30));
|
||||
b += ((c << 5) | (c >>> -5)) + f1(d, e, a) + w[3];
|
||||
d = ((d << 30) | (d >>> -30));
|
||||
a += ((b << 5) | (b >>> -5)) + f1(c, d, e) + w[4];
|
||||
c = ((c << 30) | (c >>> -30));
|
||||
e += ((a << 5) | (a >>> -5)) + f1(b, c, d) + w[5];
|
||||
b = ((b << 30) | (b >>> -30));
|
||||
d += ((e << 5) | (e >>> -5)) + f1(a, b, c) + w[6];
|
||||
a = ((a << 30) | (a >>> -30));
|
||||
c += ((d << 5) | (d >>> -5)) + f1(e, a, b) + w[7];
|
||||
e = ((e << 30) | (e >>> -30));
|
||||
b += ((c << 5) | (c >>> -5)) + f1(d, e, a) + w[8];
|
||||
d = ((d << 30) | (d >>> -30));
|
||||
a += ((b << 5) | (b >>> -5)) + f1(c, d, e) + w[9];
|
||||
c = ((c << 30) | (c >>> -30));
|
||||
e += ((a << 5) | (a >>> -5)) + f1(b, c, d) + w[10];
|
||||
b = ((b << 30) | (b >>> -30));
|
||||
d += ((e << 5) | (e >>> -5)) + f1(a, b, c) + w[11];
|
||||
a = ((a << 30) | (a >>> -30));
|
||||
c += ((d << 5) | (d >>> -5)) + f1(e, a, b) + w[12];
|
||||
e = ((e << 30) | (e >>> -30));
|
||||
b += ((c << 5) | (c >>> -5)) + f1(d, e, a) + w[13];
|
||||
d = ((d << 30) | (d >>> -30));
|
||||
a += ((b << 5) | (b >>> -5)) + f1(c, d, e) + w[14];
|
||||
c = ((c << 30) | (c >>> -30));
|
||||
e += ((a << 5) | (a >>> -5)) + f1(b, c, d) + w[15];
|
||||
b = ((b << 30) | (b >>> -30));
|
||||
d += ((e << 5) | (e >>> -5)) + f1(a, b, c) + w[16];
|
||||
a = ((a << 30) | (a >>> -30));
|
||||
c += ((d << 5) | (d >>> -5)) + f1(e, a, b) + w[17];
|
||||
e = ((e << 30) | (e >>> -30));
|
||||
b += ((c << 5) | (c >>> -5)) + f1(d, e, a) + w[18];
|
||||
d = ((d << 30) | (d >>> -30));
|
||||
a += ((b << 5) | (b >>> -5)) + f1(c, d, e) + w[19];
|
||||
c = ((c << 30) | (c >>> -30));
|
||||
e += ((a << 5) | (a >>> -5)) + f2(b, c, d) + w[20];
|
||||
b = ((b << 30) | (b >>> -30));
|
||||
d += ((e << 5) | (e >>> -5)) + f2(a, b, c) + w[21];
|
||||
a = ((a << 30) | (a >>> -30));
|
||||
c += ((d << 5) | (d >>> -5)) + f2(e, a, b) + w[22];
|
||||
e = ((e << 30) | (e >>> -30));
|
||||
b += ((c << 5) | (c >>> -5)) + f2(d, e, a) + w[23];
|
||||
d = ((d << 30) | (d >>> -30));
|
||||
a += ((b << 5) | (b >>> -5)) + f2(c, d, e) + w[24];
|
||||
c = ((c << 30) | (c >>> -30));
|
||||
e += ((a << 5) | (a >>> -5)) + f2(b, c, d) + w[25];
|
||||
b = ((b << 30) | (b >>> -30));
|
||||
d += ((e << 5) | (e >>> -5)) + f2(a, b, c) + w[26];
|
||||
a = ((a << 30) | (a >>> -30));
|
||||
c += ((d << 5) | (d >>> -5)) + f2(e, a, b) + w[27];
|
||||
e = ((e << 30) | (e >>> -30));
|
||||
b += ((c << 5) | (c >>> -5)) + f2(d, e, a) + w[28];
|
||||
d = ((d << 30) | (d >>> -30));
|
||||
a += ((b << 5) | (b >>> -5)) + f2(c, d, e) + w[29];
|
||||
c = ((c << 30) | (c >>> -30));
|
||||
e += ((a << 5) | (a >>> -5)) + f2(b, c, d) + w[30];
|
||||
b = ((b << 30) | (b >>> -30));
|
||||
d += ((e << 5) | (e >>> -5)) + f2(a, b, c) + w[31];
|
||||
a = ((a << 30) | (a >>> -30));
|
||||
c += ((d << 5) | (d >>> -5)) + f2(e, a, b) + w[32];
|
||||
e = ((e << 30) | (e >>> -30));
|
||||
b += ((c << 5) | (c >>> -5)) + f2(d, e, a) + w[33];
|
||||
d = ((d << 30) | (d >>> -30));
|
||||
a += ((b << 5) | (b >>> -5)) + f2(c, d, e) + w[34];
|
||||
c = ((c << 30) | (c >>> -30));
|
||||
e += ((a << 5) | (a >>> -5)) + f2(b, c, d) + w[35];
|
||||
b = ((b << 30) | (b >>> -30));
|
||||
d += ((e << 5) | (e >>> -5)) + f2(a, b, c) + w[36];
|
||||
a = ((a << 30) | (a >>> -30));
|
||||
c += ((d << 5) | (d >>> -5)) + f2(e, a, b) + w[37];
|
||||
e = ((e << 30) | (e >>> -30));
|
||||
b += ((c << 5) | (c >>> -5)) + f2(d, e, a) + w[38];
|
||||
d = ((d << 30) | (d >>> -30));
|
||||
a += ((b << 5) | (b >>> -5)) + f2(c, d, e) + w[39];
|
||||
c = ((c << 30) | (c >>> -30));
|
||||
e += ((a << 5) | (a >>> -5)) + f3(b, c, d) + w[40];
|
||||
b = ((b << 30) | (b >>> -30));
|
||||
d += ((e << 5) | (e >>> -5)) + f3(a, b, c) + w[41];
|
||||
a = ((a << 30) | (a >>> -30));
|
||||
c += ((d << 5) | (d >>> -5)) + f3(e, a, b) + w[42];
|
||||
e = ((e << 30) | (e >>> -30));
|
||||
b += ((c << 5) | (c >>> -5)) + f3(d, e, a) + w[43];
|
||||
d = ((d << 30) | (d >>> -30));
|
||||
a += ((b << 5) | (b >>> -5)) + f3(c, d, e) + w[44];
|
||||
c = ((c << 30) | (c >>> -30));
|
||||
e += ((a << 5) | (a >>> -5)) + f3(b, c, d) + w[45];
|
||||
b = ((b << 30) | (b >>> -30));
|
||||
d += ((e << 5) | (e >>> -5)) + f3(a, b, c) + w[46];
|
||||
a = ((a << 30) | (a >>> -30));
|
||||
c += ((d << 5) | (d >>> -5)) + f3(e, a, b) + w[47];
|
||||
e = ((e << 30) | (e >>> -30));
|
||||
b += ((c << 5) | (c >>> -5)) + f3(d, e, a) + w[48];
|
||||
d = ((d << 30) | (d >>> -30));
|
||||
a += ((b << 5) | (b >>> -5)) + f3(c, d, e) + w[49];
|
||||
c = ((c << 30) | (c >>> -30));
|
||||
e += ((a << 5) | (a >>> -5)) + f3(b, c, d) + w[50];
|
||||
b = ((b << 30) | (b >>> -30));
|
||||
d += ((e << 5) | (e >>> -5)) + f3(a, b, c) + w[51];
|
||||
a = ((a << 30) | (a >>> -30));
|
||||
c += ((d << 5) | (d >>> -5)) + f3(e, a, b) + w[52];
|
||||
e = ((e << 30) | (e >>> -30));
|
||||
b += ((c << 5) | (c >>> -5)) + f3(d, e, a) + w[53];
|
||||
d = ((d << 30) | (d >>> -30));
|
||||
a += ((b << 5) | (b >>> -5)) + f3(c, d, e) + w[54];
|
||||
c = ((c << 30) | (c >>> -30));
|
||||
e += ((a << 5) | (a >>> -5)) + f3(b, c, d) + w[55];
|
||||
b = ((b << 30) | (b >>> -30));
|
||||
d += ((e << 5) | (e >>> -5)) + f3(a, b, c) + w[56];
|
||||
a = ((a << 30) | (a >>> -30));
|
||||
c += ((d << 5) | (d >>> -5)) + f3(e, a, b) + w[57];
|
||||
e = ((e << 30) | (e >>> -30));
|
||||
b += ((c << 5) | (c >>> -5)) + f3(d, e, a) + w[58];
|
||||
d = ((d << 30) | (d >>> -30));
|
||||
a += ((b << 5) | (b >>> -5)) + f3(c, d, e) + w[59];
|
||||
c = ((c << 30) | (c >>> -30));
|
||||
e += ((a << 5) | (a >>> -5)) + f4(b, c, d) + w[60];
|
||||
b = ((b << 30) | (b >>> -30));
|
||||
d += ((e << 5) | (e >>> -5)) + f4(a, b, c) + w[61];
|
||||
a = ((a << 30) | (a >>> -30));
|
||||
c += ((d << 5) | (d >>> -5)) + f4(e, a, b) + w[62];
|
||||
e = ((e << 30) | (e >>> -30));
|
||||
b += ((c << 5) | (c >>> -5)) + f4(d, e, a) + w[63];
|
||||
d = ((d << 30) | (d >>> -30));
|
||||
a += ((b << 5) | (b >>> -5)) + f4(c, d, e) + w[64];
|
||||
c = ((c << 30) | (c >>> -30));
|
||||
e += ((a << 5) | (a >>> -5)) + f4(b, c, d) + w[65];
|
||||
b = ((b << 30) | (b >>> -30));
|
||||
d += ((e << 5) | (e >>> -5)) + f4(a, b, c) + w[66];
|
||||
a = ((a << 30) | (a >>> -30));
|
||||
c += ((d << 5) | (d >>> -5)) + f4(e, a, b) + w[67];
|
||||
e = ((e << 30) | (e >>> -30));
|
||||
b += ((c << 5) | (c >>> -5)) + f4(d, e, a) + w[68];
|
||||
d = ((d << 30) | (d >>> -30));
|
||||
a += ((b << 5) | (b >>> -5)) + f4(c, d, e) + w[69];
|
||||
c = ((c << 30) | (c >>> -30));
|
||||
e += ((a << 5) | (a >>> -5)) + f4(b, c, d) + w[70];
|
||||
b = ((b << 30) | (b >>> -30));
|
||||
d += ((e << 5) | (e >>> -5)) + f4(a, b, c) + w[71];
|
||||
a = ((a << 30) | (a >>> -30));
|
||||
c += ((d << 5) | (d >>> -5)) + f4(e, a, b) + w[72];
|
||||
e = ((e << 30) | (e >>> -30));
|
||||
b += ((c << 5) | (c >>> -5)) + f4(d, e, a) + w[73];
|
||||
d = ((d << 30) | (d >>> -30));
|
||||
a += ((b << 5) | (b >>> -5)) + f4(c, d, e) + w[74];
|
||||
c = ((c << 30) | (c >>> -30));
|
||||
e += ((a << 5) | (a >>> -5)) + f4(b, c, d) + w[75];
|
||||
b = ((b << 30) | (b >>> -30));
|
||||
d += ((e << 5) | (e >>> -5)) + f4(a, b, c) + w[76];
|
||||
a = ((a << 30) | (a >>> -30));
|
||||
c += ((d << 5) | (d >>> -5)) + f4(e, a, b) + w[77];
|
||||
e = ((e << 30) | (e >>> -30));
|
||||
b += ((c << 5) | (c >>> -5)) + f4(d, e, a) + w[78];
|
||||
d = ((d << 30) | (d >>> -30));
|
||||
a += ((b << 5) | (b >>> -5)) + f4(c, d, e) + w[79];
|
||||
c = ((c << 30) | (c >>> -30));
|
||||
|
||||
hashBuffer[0] += a;
|
||||
hashBuffer[1] += b;
|
||||
hashBuffer[2] += c;
|
||||
hashBuffer[3] += d;
|
||||
hashBuffer[4] += e;
|
||||
}//transform()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
|
||||
*/
|
||||
public void writeExternal(java.io.ObjectOutput out) throws java.io.IOException {
|
||||
}//writeExternal()//
|
||||
}//Sha1//
|
||||
530
Common/src/com/common/security/Sha512.java
Normal file
530
Common/src/com/common/security/Sha512.java
Normal file
@@ -0,0 +1,530 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.security;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import com.common.util.StringSupport;
|
||||
|
||||
/*
|
||||
* Used the SHA512 specs and the Bouncy Castle LongDigest implementation as guides.
|
||||
* <p>The point of having this in the framework isn't to be different, but rather to cut out all the dependancies and make the hash super easy to be used in application code without extra lines in the classpath or consideration to licensing.</p>
|
||||
*/
|
||||
public class Sha512 implements IHashAlgorithm {
|
||||
/** Constants */
|
||||
private static final long K[] = {
|
||||
0x428A2F98D728AE22L, 0x7137449123EF65CDL, 0xB5C0FBCFEC4D3B2FL, 0xE9B5DBA58189DBBCL,
|
||||
0x3956C25BF348B538L, 0x59F111F1B605D019L, 0x923F82A4AF194F9BL, 0xAB1C5ED5DA6D8118L,
|
||||
0xD807AA98A3030242L, 0x12835B0145706FBEL, 0x243185BE4EE4B28CL, 0x550C7DC3D5FFB4E2L,
|
||||
0x72BE5D74F27B896FL, 0x80DEB1FE3B1696B1L, 0x9BDC06A725C71235L, 0xC19BF174CF692694L,
|
||||
0xE49B69C19EF14AD2L, 0xEFBE4786384F25E3L, 0x0FC19DC68B8CD5B5L, 0x240CA1CC77AC9C65L,
|
||||
0x2DE92C6F592B0275L, 0x4A7484AA6EA6E483L, 0x5CB0A9DCBD41FBD4L, 0x76F988DA831153B5L,
|
||||
0x983E5152EE66DFABL, 0xA831C66D2DB43210L, 0xB00327C898FB213FL, 0xBF597FC7BEEF0EE4L,
|
||||
0xC6E00BF33DA88FC2L, 0xD5A79147930AA725L, 0x06CA6351E003826FL, 0x142929670A0E6E70L,
|
||||
0x27B70A8546D22FFCL, 0x2E1B21385C26C926L, 0x4D2C6DFC5AC42AEDL, 0x53380D139D95B3DFL,
|
||||
0x650A73548BAF63DEL, 0x766A0ABB3C77B2A8L, 0x81C2C92E47EDAEE6L, 0x92722C851482353BL,
|
||||
0xA2BFE8A14CF10364L, 0xA81A664BBC423001L, 0xC24B8B70D0F89791L, 0xC76C51A30654BE30L,
|
||||
0xD192E819D6EF5218L, 0xD69906245565A910L, 0xF40E35855771202AL, 0x106AA07032BBD1B8L,
|
||||
0x19A4C116B8D2D0C8L, 0x1E376C085141AB53L, 0x2748774CDF8EEB99L, 0x34B0BCB5E19B48A8L,
|
||||
0x391C0CB3C5C95A63L, 0x4ED8AA4AE3418ACBL, 0x5B9CCA4F7763E373L, 0x682E6FF3D6B2B8A3L,
|
||||
0x748F82EE5DEFB2FCL, 0x78A5636F43172F60L, 0x84C87814A1F0AB72L, 0x8CC702081A6439ECL,
|
||||
0x90BEFFFA23631E28L, 0xA4506CEBDE82BDE9L, 0xBEF9A3F7B2C67915L, 0xC67178F2E372532BL,
|
||||
0xCA273ECEEA26619CL, 0xD186B8C721C0C207L, 0xEADA7DD6CDE0EB1EL, 0xF57D4F7FEE6ED178L,
|
||||
0x06F067AA72176FBAL, 0x0A637DC5A2C898A6L, 0x113F9804BEF90DAEL, 0x1B710B35131C471BL,
|
||||
0x28DB77F523047D84L, 0x32CAAB7B40C72493L, 0x3C9EBE0A15C9BEBCL, 0x431D67C49C100D4CL,
|
||||
0x4CC5D4BECB3E42B6L, 0x597F299CFC657E2AL, 0x5FCB6FAB3AD6FAECL, 0x6C44198C4A475817L
|
||||
};
|
||||
/** The size of a resulting hash in bytes (8 longs used to store the hash * 8 bytes per long). */
|
||||
private static final int HASH_SIZE = 64;
|
||||
/** The size of a block of source to be hashed (in bytes). (16 longs store a block of unhashed data, 8 bytes per long.) */
|
||||
private static final int BLOCK_SIZE = 128;
|
||||
/** The source size. */
|
||||
private long sourceSize;
|
||||
/** The overflow source size. */
|
||||
private long sourceSize2;
|
||||
/**
|
||||
* A buffer containing the bytes yet to be added to the digest.
|
||||
* This buffer will always be DATA_LENGTH in size and the digest will be updated when it is filled (so that this buffer can be emptied and reused).
|
||||
*/
|
||||
private byte[] sourceBuffer;
|
||||
private int sourceBufferLength;
|
||||
/**
|
||||
* The digest integers as an array.
|
||||
* This is where the digest actually gets stored until the hash has completely finished and the digest bytes are given to the user.
|
||||
*/
|
||||
private long[] hashBuffer;
|
||||
private long[] internalHashBuffer;
|
||||
private long[] internalBuffer;
|
||||
/**
|
||||
* Constructs SHA-512 algorithm used to generate digests from source data.
|
||||
*/
|
||||
public Sha512() {
|
||||
initialize();
|
||||
}//Sha512()//
|
||||
/**
|
||||
* Sha512 copy constructor.
|
||||
* @param algorithm The algorithm to be copied.
|
||||
*/
|
||||
private Sha512(Sha512 algorithm) {
|
||||
sourceSize = algorithm.sourceSize;
|
||||
sourceSize2 = algorithm.sourceSize2;
|
||||
sourceBufferLength = algorithm.sourceBufferLength;
|
||||
sourceBuffer = (byte[]) algorithm.sourceBuffer.clone();
|
||||
internalHashBuffer = (long[]) algorithm.internalHashBuffer.clone();
|
||||
hashBuffer = (long[]) algorithm.hashBuffer.clone();
|
||||
internalBuffer = (long[]) algorithm.internalBuffer.clone();
|
||||
}//Sha512()//
|
||||
/**
|
||||
* Initializes the hash algorithm.
|
||||
*/
|
||||
private void initialize() {
|
||||
//Initialize the buffers.//
|
||||
sourceBuffer = new byte[BLOCK_SIZE];
|
||||
hashBuffer = new long[8];
|
||||
internalHashBuffer = new long[BLOCK_SIZE/8];
|
||||
internalBuffer = new long[80];
|
||||
reset(); //Prepare the algorithm for its first hash.//
|
||||
}//initialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#reset()
|
||||
*/
|
||||
public void reset() {
|
||||
sourceBufferLength = 0;
|
||||
sourceSize = 0;
|
||||
sourceSize2 = 0;
|
||||
hashBuffer[0] = 0x6A09E667F3BCC908L;
|
||||
hashBuffer[1] = 0xBB67AE8584CAA73BL;
|
||||
hashBuffer[2] = 0x3C6EF372FE94F82BL;
|
||||
hashBuffer[3] = 0xA54FF53A5F1D36F1L;
|
||||
hashBuffer[4] = 0x510E527FADE682D1L;
|
||||
hashBuffer[5] = 0x9B05688C2B3E6C1FL;
|
||||
hashBuffer[6] = 0x1F83D9ABFB41BD6BL;
|
||||
hashBuffer[7] = 0x5BE0CD19137E2179L;
|
||||
}//reset()//
|
||||
/**
|
||||
* Manages overflowing the source size into a second long value.
|
||||
*/
|
||||
private void updateSourceSize() {
|
||||
//Check if we have to use the overflow source size.//
|
||||
//Note: We always clear the last 3 bits because we will multiply the source size by 8 to get a bit count when finishing the hash.//
|
||||
if(sourceSize > 0x1FFFFFFFFFFFFFFFL) {
|
||||
//Add the top 3 bits to the overflow source size.//
|
||||
sourceSize2 += (sourceSize >>> 61);
|
||||
//Clear the top 3 bits of the source size.//
|
||||
sourceSize &= 0x1FFFFFFFFFFFFFFFL;
|
||||
}//if//
|
||||
}//updateSourceSize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IWriter#write(byte)
|
||||
*/
|
||||
public void write(byte b) {
|
||||
add(b);
|
||||
}//write()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IWriter#write(byte[], int, int)
|
||||
*/
|
||||
public void write(byte[] bytes, int offset, int length) {
|
||||
add(bytes, offset, length);
|
||||
}//write()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IWriter#write(byte[])
|
||||
*/
|
||||
public void write(byte[] bytes) {
|
||||
add(bytes);
|
||||
}//write()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#add(byte)
|
||||
*/
|
||||
public void add(byte b) {
|
||||
sourceSize++;
|
||||
sourceBuffer[sourceBufferLength++] = b;
|
||||
|
||||
if(sourceBufferLength == BLOCK_SIZE) {
|
||||
//Transform the bytes into longs.//
|
||||
convert(sourceBuffer, 0, internalHashBuffer);
|
||||
//Update the hash.//
|
||||
transform(internalHashBuffer);
|
||||
sourceBufferLength = 0;
|
||||
}//if//
|
||||
}//add()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#add(byte[])
|
||||
*/
|
||||
public void add(byte[] buffer) {
|
||||
if(buffer != null && buffer.length > 0) {
|
||||
add(buffer, 0, buffer.length);
|
||||
}//if//
|
||||
}//add()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#add(byte[], int, int)
|
||||
*/
|
||||
public void add(byte[] buffer, int bufferOffset, int bufferLength) {
|
||||
if(bufferLength > 0) {
|
||||
int size = 0;
|
||||
|
||||
sourceSize += bufferLength;
|
||||
|
||||
//Hash the source in blocks.//
|
||||
while((size = BLOCK_SIZE - sourceBufferLength) <= bufferLength) {
|
||||
//Fill the source buffer.//
|
||||
System.arraycopy(buffer, bufferOffset, sourceBuffer, sourceBufferLength, size);
|
||||
//Transform the bytes into longs.//
|
||||
convert(sourceBuffer, 0, internalHashBuffer);
|
||||
//Update the hash.//
|
||||
transform(internalHashBuffer);
|
||||
bufferLength -= size;
|
||||
bufferOffset += size;
|
||||
sourceBufferLength = 0;
|
||||
}//while//
|
||||
|
||||
if(bufferLength > 0) {
|
||||
//Save partial source in the source buffer.//
|
||||
System.arraycopy(buffer, bufferOffset, sourceBuffer, sourceBufferLength, bufferLength);
|
||||
sourceBufferLength += bufferLength;
|
||||
}//if//
|
||||
}//if//
|
||||
}//add()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#add(java.io.InputStream)
|
||||
*/
|
||||
public void add(InputStream in) throws IOException {
|
||||
byte[] buffer = new byte[10000];
|
||||
int readCount = 0;
|
||||
|
||||
while(readCount >= 0) {
|
||||
readCount = in.read(buffer);
|
||||
|
||||
if(readCount > 0) {
|
||||
add(buffer, 0, readCount);
|
||||
}//if//
|
||||
}//while//
|
||||
}//add()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#add(String)
|
||||
*/
|
||||
public void add(String source) {
|
||||
if(source != null && source.length() > 0) {
|
||||
add(StringSupport.toUtf8Bytes(source));
|
||||
}//if//
|
||||
}//add()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#add(char[])
|
||||
*/
|
||||
public void add(char[] source) {
|
||||
if(source != null && source.length > 0) {
|
||||
add(StringSupport.toUtf8Bytes(source));
|
||||
}//if//
|
||||
}//add()//
|
||||
/**
|
||||
* Adds the last of the source to the hash. At the very least this adds the source size to the hash.
|
||||
*/
|
||||
private void addFinal() {
|
||||
int position = sourceBufferLength;
|
||||
|
||||
sourceBuffer[position++] = (byte) 0x80;
|
||||
|
||||
//If there isn't room for two more longs (the message size in # of bits), then process the source block with zero's padding the end.//
|
||||
if(position > BLOCK_SIZE - 16) {
|
||||
//Add trailing zeros.//
|
||||
while(position < BLOCK_SIZE) {
|
||||
sourceBuffer[position++] = 0;
|
||||
}//while//
|
||||
|
||||
convert(sourceBuffer, 0, internalHashBuffer);
|
||||
transform(internalHashBuffer);
|
||||
position = 0;
|
||||
}//if//
|
||||
|
||||
//Pad all but the last 2 long values of the buffers.//
|
||||
for(int i = position; i < BLOCK_SIZE - 16; i ++) {
|
||||
sourceBuffer[i] = 0;
|
||||
}//for//
|
||||
|
||||
//Convert the source bytes to longs.//
|
||||
convert(sourceBuffer, 0, internalHashBuffer);
|
||||
updateSourceSize();
|
||||
//Add the message size to the longs.//
|
||||
internalHashBuffer[internalHashBuffer.length - 2] = sourceSize2;
|
||||
internalHashBuffer[internalHashBuffer.length - 1] = sourceSize << 3;
|
||||
//Run the final transform.//
|
||||
transform(internalHashBuffer);
|
||||
}//addFinal()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#cleanup()
|
||||
*/
|
||||
public void cleanup() {
|
||||
}//cleanup()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#clone()
|
||||
*/
|
||||
public Object clone() {
|
||||
return new Sha512(this);
|
||||
}//clone()//
|
||||
/**
|
||||
* Convers bytes into longs.
|
||||
*/
|
||||
private void convert(byte[] source, int sourceOffset, long[] destination) {
|
||||
int destinationOffset = 0;
|
||||
int destinationLength = destination.length;
|
||||
|
||||
while(destinationLength-- > 0) {
|
||||
//Big Endian//
|
||||
destination[destinationOffset++] = ((long) (source[sourceOffset++] & 0xFF) << 56) | ((long) (source[sourceOffset++] & 0xFF) << 48) | ((long) (source[sourceOffset++] & 0xFF) << 40) | ((long) (source[sourceOffset++] & 0xFF) << 32) | ((long) (source[sourceOffset++] & 0xFF) << 24) | ((long) (source[sourceOffset++] & 0xFF) << 16) | ((long) (source[sourceOffset++] & 0xFF) << 8) | (source[sourceOffset++] & 0xFF);
|
||||
}//while//
|
||||
}//convert()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#getHashSize()
|
||||
*/
|
||||
public int getHashSize() {
|
||||
return HASH_SIZE;
|
||||
}//getHashSize()//
|
||||
/**
|
||||
* Performs the final hash using a custom buffer. This is the same as the hash() methods, but allows reuse of the buffer.
|
||||
* @param hash The buffer to place the hash in. Must have space for the hash size.
|
||||
* @param offset The offset in the hash array where the first hash byte will be placed.
|
||||
*/
|
||||
public void finish(byte[] hash, int offset) {
|
||||
if(hash.length - offset < HASH_SIZE) {
|
||||
throw new IllegalArgumentException();
|
||||
}//if//
|
||||
|
||||
internalHash(hash, 0);
|
||||
}//finish()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#hash()
|
||||
*/
|
||||
public byte[] hash() {
|
||||
return internalHash();
|
||||
}//hash()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#hash(byte[], int, int)
|
||||
*/
|
||||
public byte[] hash(byte[] source, int sourceOffset, int sourceLength) {
|
||||
add(source, sourceOffset, sourceLength);
|
||||
|
||||
return internalHash();
|
||||
}//hash()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#hash(byte[], int, int, byte[], int)
|
||||
*/
|
||||
public void hash(byte[] source, int sourceOffset, int sourceLength, byte[] hashBuffer, int hashBufferOffset) {
|
||||
add(source, sourceOffset, sourceLength);
|
||||
internalHash(hashBuffer, hashBufferOffset);
|
||||
}//hash()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#hash(String)
|
||||
*/
|
||||
public byte[] hash(String source) {
|
||||
add(source);
|
||||
|
||||
return internalHash();
|
||||
}//hash()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#hash(String, byte[], int)
|
||||
*/
|
||||
public void hash(String source, byte[] hashBuffer, int hashBufferOffset) {
|
||||
add(source);
|
||||
internalHash(hashBuffer, hashBufferOffset);
|
||||
}//hash()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#hash(char[])
|
||||
*/
|
||||
public byte[] hash(char[] source) {
|
||||
add(source);
|
||||
|
||||
return internalHash();
|
||||
}//hash()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#hash(char[], byte[], int)
|
||||
*/
|
||||
public void hash(char[] source, byte[] hashBuffer, int hashBufferOffset) {
|
||||
add(source);
|
||||
internalHash(hashBuffer, hashBufferOffset);
|
||||
}//hash()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#hashToString()
|
||||
*/
|
||||
public String hashToString() {
|
||||
return hashToString((String) null);
|
||||
}//hashToString()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#hashToString(String)
|
||||
*/
|
||||
public String hashToString(String source) {
|
||||
byte[] hashBuffer = source != null ? hash(source) : hash();
|
||||
|
||||
return StringSupport.fromUnicode16Bytes(hashBuffer, 0, hashBuffer.length);
|
||||
}//hashToString()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#hashToString(char[])
|
||||
*/
|
||||
public String hashToString(char[] source) {
|
||||
byte[] hashBuffer = source != null ? hash(source) : hash();
|
||||
|
||||
return StringSupport.fromUnicode16Bytes(hashBuffer, 0, hashBuffer.length);
|
||||
}//hashToString()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#hashToHex()
|
||||
*/
|
||||
public String hashToHex() {
|
||||
return hashToHex(null);
|
||||
}//hashToHex()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.security.IHashAlgorithm#hashToHex(String)
|
||||
*/
|
||||
public String hashToHex(String source) {
|
||||
byte[] hashBuffer = source != null ? hash(source) : hash();
|
||||
|
||||
return StringSupport.toHexString(hashBuffer, 0, hashBuffer.length);
|
||||
}//hashToHex()//
|
||||
/**
|
||||
* Creates a hash of the previously supplied source.
|
||||
* @return The hash bytes.
|
||||
*/
|
||||
protected byte[] internalHash() {
|
||||
byte[] buffer = new byte[HASH_SIZE];
|
||||
|
||||
internalHash(buffer, 0);
|
||||
|
||||
return buffer;
|
||||
}//internalHash()//
|
||||
/**
|
||||
* Creates a hash of the previously supplied source.
|
||||
* @param hashBuffer The buffer to place the hash in.
|
||||
* @param hashBufferOffset The index of the first hash byte.
|
||||
*/
|
||||
protected void internalHash(byte[] hashBuffer, int hashBufferOffset) {
|
||||
//Add any final source into the mix.//
|
||||
addFinal();
|
||||
|
||||
//Copy the hash into the result buffer in Big Endian format.//
|
||||
for(int i = 0; i < this.hashBuffer.length; ++i) {
|
||||
long value = this.hashBuffer[i];
|
||||
|
||||
hashBuffer[hashBufferOffset++] = (byte) (value >>> 56);
|
||||
hashBuffer[hashBufferOffset++] = (byte) (value >>> 48);
|
||||
hashBuffer[hashBufferOffset++] = (byte) (value >>> 40);
|
||||
hashBuffer[hashBufferOffset++] = (byte) (value >>> 32);
|
||||
hashBuffer[hashBufferOffset++] = (byte) (value >>> 24);
|
||||
hashBuffer[hashBufferOffset++] = (byte) (value >>> 16);
|
||||
hashBuffer[hashBufferOffset++] = (byte) (value >>> 8);
|
||||
hashBuffer[hashBufferOffset++] = (byte) value;
|
||||
}//for//
|
||||
|
||||
//Reset the algorithm.//
|
||||
reset();
|
||||
}//internalHash()//
|
||||
/**
|
||||
* The SHA-512 transform method which maintains the current hashBuffer by adding/transforming blocks of source data.
|
||||
* @param data The 8 longs containing the source data to be added to the current hashBuffer.
|
||||
*/
|
||||
private void transform(long[] data) {
|
||||
long a = hashBuffer[0];
|
||||
long b = hashBuffer[1];
|
||||
long c = hashBuffer[2];
|
||||
long d = hashBuffer[3];
|
||||
long e = hashBuffer[4];
|
||||
long f = hashBuffer[5];
|
||||
long g = hashBuffer[6];
|
||||
long h = hashBuffer[7];
|
||||
long[] w = internalBuffer;
|
||||
|
||||
updateSourceSize();
|
||||
|
||||
//Copy the data buffer into the first 16 positions in the working buffer.//
|
||||
for(int i = 0; i < 16; i++) {
|
||||
w[i] = data[i];
|
||||
}//for//
|
||||
|
||||
//Expand the data into the remaining working longs.//
|
||||
for(int i = 16; i < 80; i++) {
|
||||
long v1 = (w[i - 2] << 45 | w[i - 2] >>> 19) ^ (w[i - 2] << 3 | w[i - 2] >>> 61) ^ (w[i - 2] >>> 6);
|
||||
long v2 = (w[i - 15] << 63 | w[i - 15] >>> 1) ^ (w[i - 15] << 56 | w[i - 15] >>> 8) ^ (w[i - 15] >>> 7);
|
||||
|
||||
w[i] = v1 + w[i - 7] + v2 + w[i - 16];
|
||||
}//for//
|
||||
|
||||
//Mix it all up.//
|
||||
for(int i = 0, t = 0; i < 10; i++) {
|
||||
h += f4(e) + f1(e, f, g) + K[t] + w[t++];
|
||||
d += h;
|
||||
h += f3(a) + f2(a, b, c);
|
||||
|
||||
g += f4(d) + f1(d, e, f) + K[t] + w[t++];
|
||||
c += g;
|
||||
g += f3(h) + f2(h, a, b);
|
||||
|
||||
f += f4(c) + f1(c, d, e) + K[t] + w[t++];
|
||||
b += f;
|
||||
f += f3(g) + f2(g, h, a);
|
||||
|
||||
e += f4(b) + f1(b, c, d) + K[t] + w[t++];
|
||||
a += e;
|
||||
e += f3(f) + f2(f, g, h);
|
||||
|
||||
d += f4(a) + f1(a, b, c) + K[t] + w[t++];
|
||||
h += d;
|
||||
d += f3(e) + f2(e, f, g);
|
||||
|
||||
c += f4(h) + f1(h, a, b) + K[t] + w[t++];
|
||||
g += c;
|
||||
c += f3(d) + f2(d, e, f);
|
||||
|
||||
b += f4(g) + f1(g, h, a) + K[t] + w[t++];
|
||||
f += b;
|
||||
b += f3(c) + f2(c, d, e);
|
||||
|
||||
a += f4(f) + f1(f, g, h) + K[t] + w[t++];
|
||||
e += a;
|
||||
a += f3(b) + f2(b, c, d);
|
||||
}//for//
|
||||
|
||||
hashBuffer[0] += a;
|
||||
hashBuffer[1] += b;
|
||||
hashBuffer[2] += c;
|
||||
hashBuffer[3] += d;
|
||||
hashBuffer[4] += e;
|
||||
hashBuffer[5] += f;
|
||||
hashBuffer[6] += g;
|
||||
hashBuffer[7] += h;
|
||||
}//transform()//
|
||||
/**
|
||||
* Transform 1.
|
||||
*/
|
||||
private long f1(long x, long y, long z) {
|
||||
return ((x & y) ^ ((~x) & z));
|
||||
}//f1()//
|
||||
/**
|
||||
* Transform 2.
|
||||
*/
|
||||
private long f2(long x, long y, long z) {
|
||||
return ((x & y) ^ (x & z) ^ (y & z));
|
||||
}//f2()//
|
||||
/**
|
||||
* Transform 3.
|
||||
*/
|
||||
private long f3(long x) {
|
||||
return ((x << 36)|(x >>> 28)) ^ ((x << 30)|(x >>> 34)) ^ ((x << 25)|(x >>> 39));
|
||||
}//f3()//
|
||||
/**
|
||||
* Transform 4.
|
||||
*/
|
||||
private long f4(long x) {
|
||||
return ((x << 50)|(x >>> 14)) ^ ((x << 46)|(x >>> 18)) ^ ((x << 23)|(x >>> 41));
|
||||
}//f4()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.Externalizable#readExternal(java.io.ObjectInput)
|
||||
*/
|
||||
public void readExternal(java.io.ObjectInput in) throws java.io.IOException, ClassNotFoundException {
|
||||
}//readExternal()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
|
||||
*/
|
||||
public void writeExternal(java.io.ObjectOutput out) throws java.io.IOException {
|
||||
}//writeExternal()//
|
||||
}//Sha1//
|
||||
73
Common/src/com/common/system/ISystem.java
Normal file
73
Common/src/com/common/system/ISystem.java
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 1999,2005 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.system;
|
||||
|
||||
public interface ISystem {
|
||||
/**
|
||||
* Creates a string by reading the character bytes from a byte array beginning at a given offset.
|
||||
* @param bytes The byte array containing the character data.
|
||||
* @param offset The offset in the array where the character data begins.
|
||||
* @param length The number of bytes of character data to read.
|
||||
* @return The string represented by the character data in the byte array.
|
||||
*/
|
||||
public String convertUnicode16StringFromBytes(byte[] bytes, int offset, int length);
|
||||
/**
|
||||
* Writes the character bytes to the byte array starting at the offset.
|
||||
* @param string The string to write to the byte array.
|
||||
* @param bytes The byte array that should contain the string bytes.
|
||||
* @param offset The offset in the array where the character bytes should begin.
|
||||
* @return Will be the number of bytes written.
|
||||
*/
|
||||
public int convertUnicode16StringToBytes(String string, byte[] bytes, int offset);
|
||||
/**
|
||||
* Creates a string by reading the character bytes from a byte array beginning at a given offset.
|
||||
* @param bytes The byte array containing the character data.
|
||||
* @param offset The offset in the array where the character data begins.
|
||||
* @param length The number of bytes of character data to read.
|
||||
* @return The string represented by the character data in the byte array.
|
||||
*/
|
||||
public String convertUtf8StringFromBytes(byte[] bytes, int offset, int length);
|
||||
/**
|
||||
* Writes the character bytes to the byte array starting at the offset.
|
||||
* @param string The string to write to the byte array.
|
||||
* @param bytes The byte array that should contain the string bytes.
|
||||
* @param offset The offset in the array where the character bytes should begin.
|
||||
* @return Will be the number of bytes written.
|
||||
*/
|
||||
public int convertUtf8StringToBytes(String string, byte[] bytes, int offset);
|
||||
/**
|
||||
* Retrieves the system id for this process.
|
||||
* <p>NOTE: This will only be called once per logical process, and the value will be cached and reused.
|
||||
* @return The system process id.
|
||||
*/
|
||||
public int getProcessId();
|
||||
/**
|
||||
* Gets the number of bytes in the UTF8 string.
|
||||
* @param string The string to get the length of.
|
||||
* @return Will be the number of UTF8 bytes in the string.
|
||||
*/
|
||||
public int getUtf8StringLength(String string);
|
||||
/**
|
||||
* Creates a new instance of the given type.
|
||||
* <p><b>NOTE: This will NOT call any of the constructors.</b>
|
||||
* @param type The class object for the type to be instantiated.
|
||||
* @return The new uninitialized object.
|
||||
*/
|
||||
public Object instantiateObject(Class type);
|
||||
/**
|
||||
* Loads the system library using the default library name and a custom path.
|
||||
* @see SystemManager.setupSystem(ISystem, String, String)
|
||||
*/
|
||||
public void loadLibrary();
|
||||
/**
|
||||
* Loads the system library using the default library name and a custom path.
|
||||
* @param path The path where the library can be found.
|
||||
* @see SystemManager.setupSystem(ISystem, String, String)
|
||||
*/
|
||||
public void loadLibrary(String path);
|
||||
}//ISystem//
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user