Updated storage info. Updated netty, passes all unit tests
This commit is contained in:
parent
ee6c01e371
commit
7665e116ed
@ -6,7 +6,6 @@
|
|||||||
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
|
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
|
||||||
<classpathentry kind="lib" path="/Dependencies/logging/logback-classic-1.0.13.jar" sourcepath="/Dependencies/logging/logback-classic-1.0.13-sources.zip"/>
|
<classpathentry kind="lib" path="/Dependencies/logging/logback-classic-1.0.13.jar" sourcepath="/Dependencies/logging/logback-classic-1.0.13-sources.zip"/>
|
||||||
<classpathentry kind="lib" path="/Dependencies/logging/logback-core-1.0.13.jar" sourcepath="/Dependencies/logging/logback-core-1.0.13-sources.zip"/>
|
<classpathentry kind="lib" path="/Dependencies/logging/logback-core-1.0.13.jar" sourcepath="/Dependencies/logging/logback-core-1.0.13-sources.zip"/>
|
||||||
<classpathentry kind="lib" path="/Dependencies/kryo/reflectasm.jar"/>
|
|
||||||
<classpathentry kind="lib" path="/Dependencies/javassist/javassist.jar"/>
|
<classpathentry kind="lib" path="/Dependencies/javassist/javassist.jar"/>
|
||||||
<classpathentry kind="lib" path="/Dependencies/BouncyCastleCrypto/bcpkix-jdk15on-151.jar" sourcepath="/Dependencies/BouncyCastleCrypto/bcpkix-jdk15on-151-src.zip"/>
|
<classpathentry kind="lib" path="/Dependencies/BouncyCastleCrypto/bcpkix-jdk15on-151.jar" sourcepath="/Dependencies/BouncyCastleCrypto/bcpkix-jdk15on-151-src.zip"/>
|
||||||
<classpathentry kind="lib" path="/Dependencies/BouncyCastleCrypto/bcprov-debug-jdk15on-151.jar" sourcepath="/Dependencies/BouncyCastleCrypto/bcprov-jdk15on-151-src.zip"/>
|
<classpathentry kind="lib" path="/Dependencies/BouncyCastleCrypto/bcprov-debug-jdk15on-151.jar" sourcepath="/Dependencies/BouncyCastleCrypto/bcprov-jdk15on-151-src.zip"/>
|
||||||
@ -23,9 +22,10 @@
|
|||||||
<attribute name="javadoc_location" value="jar:platform:/resource/Dependencies/netty/netty-all-4.1.0-javadoc.zip!/"/>
|
<attribute name="javadoc_location" value="jar:platform:/resource/Dependencies/netty/netty-all-4.1.0-javadoc.zip!/"/>
|
||||||
</attributes>
|
</attributes>
|
||||||
</classpathentry>
|
</classpathentry>
|
||||||
<classpathentry kind="lib" path="/Dependencies/dorkbox/object_pool/ObjectPool_v1.1.jar" sourcepath="/Dependencies/dorkbox/object_pool/ObjectPool_v1.1_src.zip"/>
|
|
||||||
<classpathentry kind="lib" path="/Dependencies/asm/asm-5.0.4.jar"/>
|
<classpathentry kind="lib" path="/Dependencies/asm/asm-5.0.4.jar"/>
|
||||||
<classpathentry kind="lib" path="/Dependencies/dorkbox/message_bus/MessageBus_v1.0.jar" sourcepath="/Dependencies/dorkbox/message_bus/MessageBus_v1.0_src.zip"/>
|
<classpathentry kind="lib" path="/Dependencies/dorkbox/message_bus/MessageBus_v1.0.jar" sourcepath="/Dependencies/dorkbox/message_bus/MessageBus_v1.0_src.zip"/>
|
||||||
<classpathentry kind="lib" path="/Dependencies/JCTools/JCTools-v1.1-alpha-MTAQ.jar" sourcepath="/Dependencies/JCTools/JCTools-1.1-alpha-MTAQ-src.zip"/>
|
<classpathentry kind="lib" path="/Dependencies/JCTools/JCTools-v1.1-alpha-MTAQ.jar" sourcepath="/Dependencies/JCTools/JCTools-1.1-alpha-MTAQ-src.zip"/>
|
||||||
|
<classpathentry kind="lib" path="/Dependencies/kryo/reflectasm-1.11.0.jar" sourcepath="/Dependencies/kryo/reflectasm-1.11.0-sources.zip"/>
|
||||||
|
<classpathentry kind="lib" path="/Dependencies/dorkbox/object_pool/ObjectPool_v1.2.jar" sourcepath="/Dependencies/dorkbox/object_pool/ObjectPool_v1.2_src.zip"/>
|
||||||
<classpathentry kind="output" path="classes"/>
|
<classpathentry kind="output" path="classes"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
94
Dorkbox-Util/src/dorkbox/util/SerializationManager.java
Normal file
94
Dorkbox-Util/src/dorkbox/util/SerializationManager.java
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
package dorkbox.util;
|
||||||
|
|
||||||
|
import com.esotericsoftware.kryo.Kryo;
|
||||||
|
import com.esotericsoftware.kryo.KryoException;
|
||||||
|
import com.esotericsoftware.kryo.Serializer;
|
||||||
|
import com.esotericsoftware.kryo.io.Input;
|
||||||
|
import com.esotericsoftware.kryo.io.Output;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public
|
||||||
|
interface SerializationManager {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the class using the lowest, next available integer ID and the
|
||||||
|
* {@link Kryo#getDefaultSerializer(Class) default serializer}. If the class
|
||||||
|
* is already registered, the existing entry is updated with the new
|
||||||
|
* serializer. Registering a primitive also affects the corresponding
|
||||||
|
* primitive wrapper.
|
||||||
|
* <p/>
|
||||||
|
* Because the ID assigned is affected by the IDs registered before it, the
|
||||||
|
* order classes are registered is important when using this method. The
|
||||||
|
* order must be the same at deserialization as it was for serialization.
|
||||||
|
*/
|
||||||
|
void register(Class<?> clazz);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the class using the lowest, next available integer ID and the
|
||||||
|
* specified serializer. If the class is already registered, the existing
|
||||||
|
* entry is updated with the new serializer. Registering a primitive also
|
||||||
|
* affects the corresponding primitive wrapper.
|
||||||
|
* <p/>
|
||||||
|
* Because the ID assigned is affected by the IDs registered before it, the
|
||||||
|
* order classes are registered is important when using this method. The
|
||||||
|
* order must be the same at deserialization as it was for serialization.
|
||||||
|
*/
|
||||||
|
void register(Class<?> clazz, Serializer<?> serializer);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the class using the specified ID and serializer. If the ID is
|
||||||
|
* already in use by the same type, the old entry is overwritten. If the ID
|
||||||
|
* is already in use by a different type, a {@link KryoException} is thrown.
|
||||||
|
* Registering a primitive also affects the corresponding primitive wrapper.
|
||||||
|
* <p/>
|
||||||
|
* IDs must be the same at deserialization as they were for serialization.
|
||||||
|
*
|
||||||
|
* @param id Must be >= 0. Smaller IDs are serialized more efficiently. IDs
|
||||||
|
* 0-8 are used by default for primitive types and String, but
|
||||||
|
* these IDs can be repurposed.
|
||||||
|
*/
|
||||||
|
void register(Class<?> clazz, Serializer<?> serializer, int id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Waits until a kryo is available to write, using CAS operations to prevent having to synchronize.
|
||||||
|
* <p/>
|
||||||
|
* No crypto and no sequence number
|
||||||
|
* <p/>
|
||||||
|
* There is a small speed penalty if there were no kryo's available to use.
|
||||||
|
*/
|
||||||
|
void write(ByteBuf buffer, Object message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads an object from the buffer.
|
||||||
|
* <p/>
|
||||||
|
* No crypto and no sequence number
|
||||||
|
*
|
||||||
|
* @param length should ALWAYS be the length of the expected object!
|
||||||
|
*/
|
||||||
|
Object read(ByteBuf buffer, int length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the class and object using an available kryo instance
|
||||||
|
*/
|
||||||
|
void writeFullClassAndObject(Output output, Object value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a class read from the input
|
||||||
|
*/
|
||||||
|
Object readFullClassAndObject(Input input);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Borrows a kryo from the threadsafe pool. You must release it back to the pool when done.
|
||||||
|
*/
|
||||||
|
Kryo take() throws InterruptedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Releases the kryo back to the threadsafe pool
|
||||||
|
*/
|
||||||
|
void release(Kryo kryo);
|
||||||
|
}
|
@ -25,7 +25,8 @@ import java.util.Map.Entry;
|
|||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class Sys {
|
public
|
||||||
|
class Sys {
|
||||||
public static final int javaVersion = getJavaVersion();
|
public static final int javaVersion = getJavaVersion();
|
||||||
public static final boolean isAndroid = getIsAndroid();
|
public static final boolean isAndroid = getIsAndroid();
|
||||||
|
|
||||||
@ -34,9 +35,10 @@ public class Sys {
|
|||||||
public static final int GIGABYTE = 1024 * MEGABYTE;
|
public static final int GIGABYTE = 1024 * MEGABYTE;
|
||||||
public static final long TERABYTE = 1024L * GIGABYTE;
|
public static final long TERABYTE = 1024L * GIGABYTE;
|
||||||
|
|
||||||
public static char[] HEX_CHARS = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
public static char[] HEX_CHARS = new char[] {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||||
|
|
||||||
public static final char[] convertStringToChars(String string) {
|
public static final
|
||||||
|
char[] convertStringToChars(String string) {
|
||||||
char[] charArray = string.toCharArray();
|
char[] charArray = string.toCharArray();
|
||||||
|
|
||||||
eraseString(string);
|
eraseString(string);
|
||||||
@ -44,7 +46,8 @@ public class Sys {
|
|||||||
return charArray;
|
return charArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean getIsAndroid() {
|
private static
|
||||||
|
boolean getIsAndroid() {
|
||||||
try {
|
try {
|
||||||
Class.forName("android.os.Process");
|
Class.forName("android.os.Process");
|
||||||
return true;
|
return true;
|
||||||
@ -53,31 +56,41 @@ public class Sys {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getJavaVersion() {
|
private static
|
||||||
|
int getJavaVersion() {
|
||||||
String fullJavaVersion = System.getProperty("java.version");
|
String fullJavaVersion = System.getProperty("java.version");
|
||||||
|
|
||||||
// Converts a java version string, such as "1.7u45", and converts it into 7
|
// Converts a java version string, such as "1.7u45", and converts it into 7
|
||||||
char versionChar;
|
char versionChar;
|
||||||
if (fullJavaVersion.startsWith("1.")) {
|
if (fullJavaVersion.startsWith("1.")) {
|
||||||
versionChar = fullJavaVersion.charAt(2);
|
versionChar = fullJavaVersion.charAt(2);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
versionChar = fullJavaVersion.charAt(0);
|
versionChar = fullJavaVersion.charAt(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (versionChar) {
|
switch (versionChar) {
|
||||||
case '4': return 4;
|
case '4':
|
||||||
case '5': return 5;
|
return 4;
|
||||||
case '6': return 6;
|
case '5':
|
||||||
case '7': return 7;
|
return 5;
|
||||||
case '8': return 8;
|
case '6':
|
||||||
case '9': return 9;
|
return 6;
|
||||||
default: return -1;
|
case '7':
|
||||||
|
return 7;
|
||||||
|
case '8':
|
||||||
|
return 8;
|
||||||
|
case '9':
|
||||||
|
return 9;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static final void eraseString(String string) {
|
public static final
|
||||||
|
void eraseString(String string) {
|
||||||
// You can change the value of the inner char[] using reflection.
|
// You can change the value of the inner char[] using reflection.
|
||||||
//
|
//
|
||||||
// You must be careful to either change it with an array of the same length,
|
// You must be careful to either change it with an array of the same length,
|
||||||
@ -120,10 +133,10 @@ public class Sys {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* FROM: https://www.cqse.eu/en/blog/string-replace-performance/
|
* FROM: https://www.cqse.eu/en/blog/string-replace-performance/
|
||||||
*
|
* <p/>
|
||||||
* Replaces all occurrences of keys of the given map in the given string
|
* Replaces all occurrences of keys of the given map in the given string
|
||||||
* with the associated value in that map.
|
* with the associated value in that map.
|
||||||
*
|
* <p/>
|
||||||
* This method is semantically the same as calling
|
* This method is semantically the same as calling
|
||||||
* {@link String#replace(CharSequence, CharSequence)} for each of the
|
* {@link String#replace(CharSequence, CharSequence)} for each of the
|
||||||
* entries in the map, but may be significantly faster for many replacements
|
* entries in the map, but may be significantly faster for many replacements
|
||||||
@ -131,11 +144,12 @@ public class Sys {
|
|||||||
* {@link String#replace(CharSequence, CharSequence)} uses regular
|
* {@link String#replace(CharSequence, CharSequence)} uses regular
|
||||||
* expressions internally and results in many String object allocations when
|
* expressions internally and results in many String object allocations when
|
||||||
* applied iteratively.
|
* applied iteratively.
|
||||||
*
|
* <p/>
|
||||||
* The order in which replacements are applied depends on the order of the
|
* The order in which replacements are applied depends on the order of the
|
||||||
* map's entry set.
|
* map's entry set.
|
||||||
*/
|
*/
|
||||||
public static String replaceStringFast(String string, Map<String, String> replacements) {
|
public static
|
||||||
|
String replaceStringFast(String string, Map<String, String> replacements) {
|
||||||
StringBuilder sb = new StringBuilder(string);
|
StringBuilder sb = new StringBuilder(string);
|
||||||
for (Entry<String, String> entry : replacements.entrySet()) {
|
for (Entry<String, String> entry : replacements.entrySet()) {
|
||||||
String key = entry.getKey();
|
String key = entry.getKey();
|
||||||
@ -158,9 +172,10 @@ public class Sys {
|
|||||||
*
|
*
|
||||||
* @return index if it's there, -1 if not there
|
* @return index if it's there, -1 if not there
|
||||||
*/
|
*/
|
||||||
public static int searchStringFast(String string, char c) {
|
public static
|
||||||
|
int searchStringFast(String string, char c) {
|
||||||
int length = string.length();
|
int length = string.length();
|
||||||
for (int i=0;i<length;i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
if (string.charAt(i) == c) {
|
if (string.charAt(i) == c) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@ -170,7 +185,8 @@ public class Sys {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static String getSizePretty(final long size) {
|
public static
|
||||||
|
String getSizePretty(final long size) {
|
||||||
if (size > TERABYTE) {
|
if (size > TERABYTE) {
|
||||||
return String.format("%2.2fTB", (float) size / TERABYTE);
|
return String.format("%2.2fTB", (float) size / TERABYTE);
|
||||||
}
|
}
|
||||||
@ -190,7 +206,8 @@ public class Sys {
|
|||||||
/**
|
/**
|
||||||
* Convenient close for a stream.
|
* Convenient close for a stream.
|
||||||
*/
|
*/
|
||||||
public static void close(InputStream inputStream) {
|
public static
|
||||||
|
void close(InputStream inputStream) {
|
||||||
if (inputStream != null) {
|
if (inputStream != null) {
|
||||||
try {
|
try {
|
||||||
inputStream.close();
|
inputStream.close();
|
||||||
@ -204,7 +221,8 @@ public class Sys {
|
|||||||
/**
|
/**
|
||||||
* Convenient close for a stream.
|
* Convenient close for a stream.
|
||||||
*/
|
*/
|
||||||
public static void close(OutputStream outputStream) {
|
public static
|
||||||
|
void close(OutputStream outputStream) {
|
||||||
if (outputStream != null) {
|
if (outputStream != null) {
|
||||||
try {
|
try {
|
||||||
outputStream.close();
|
outputStream.close();
|
||||||
@ -218,7 +236,8 @@ public class Sys {
|
|||||||
/**
|
/**
|
||||||
* Convenient close for a Reader.
|
* Convenient close for a Reader.
|
||||||
*/
|
*/
|
||||||
public static void close(Reader inputReader) {
|
public static
|
||||||
|
void close(Reader inputReader) {
|
||||||
if (inputReader != null) {
|
if (inputReader != null) {
|
||||||
try {
|
try {
|
||||||
inputReader.close();
|
inputReader.close();
|
||||||
@ -232,7 +251,8 @@ public class Sys {
|
|||||||
/**
|
/**
|
||||||
* Convenient close for a Writer.
|
* Convenient close for a Writer.
|
||||||
*/
|
*/
|
||||||
public static void close(Writer outputWriter) {
|
public static
|
||||||
|
void close(Writer outputWriter) {
|
||||||
if (outputWriter != null) {
|
if (outputWriter != null) {
|
||||||
try {
|
try {
|
||||||
outputWriter.close();
|
outputWriter.close();
|
||||||
@ -245,10 +265,11 @@ public class Sys {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy the contents of the input stream to the output stream.
|
* Copy the contents of the input stream to the output stream.
|
||||||
* <p>
|
* <p/>
|
||||||
* DOES NOT CLOSE THE STEAMS!
|
* DOES NOT CLOSE THE STEAMS!
|
||||||
*/
|
*/
|
||||||
public static <T extends OutputStream> T copyStream(InputStream inputStream, T outputStream) throws IOException {
|
public static
|
||||||
|
<T extends OutputStream> T copyStream(InputStream inputStream, T outputStream) throws IOException {
|
||||||
byte[] buffer = new byte[4096];
|
byte[] buffer = new byte[4096];
|
||||||
int read = 0;
|
int read = 0;
|
||||||
while ((read = inputStream.read(buffer)) > 0) {
|
while ((read = inputStream.read(buffer)) > 0) {
|
||||||
@ -261,7 +282,8 @@ public class Sys {
|
|||||||
/**
|
/**
|
||||||
* Convert the contents of the input stream to a byte array.
|
* Convert the contents of the input stream to a byte array.
|
||||||
*/
|
*/
|
||||||
public static byte[] getBytesFromStream(InputStream inputStream) throws IOException {
|
public static
|
||||||
|
byte[] getBytesFromStream(InputStream inputStream) throws IOException {
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(8192);
|
ByteArrayOutputStream baos = new ByteArrayOutputStream(8192);
|
||||||
|
|
||||||
byte[] buffer = new byte[4096];
|
byte[] buffer = new byte[4096];
|
||||||
@ -275,11 +297,13 @@ public class Sys {
|
|||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final byte[] copyBytes(byte[] src) {
|
public static final
|
||||||
|
byte[] copyBytes(byte[] src) {
|
||||||
return copyBytes(src, 0);
|
return copyBytes(src, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final byte[] copyBytes(byte[] src, int position) {
|
public static final
|
||||||
|
byte[] copyBytes(byte[] src, int position) {
|
||||||
int length = src.length - position;
|
int length = src.length - position;
|
||||||
|
|
||||||
byte[] b = new byte[length];
|
byte[] b = new byte[length];
|
||||||
@ -287,7 +311,8 @@ public class Sys {
|
|||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final byte[] concatBytes(byte[]... arrayBytes) {
|
public static final
|
||||||
|
byte[] concatBytes(byte[]... arrayBytes) {
|
||||||
int length = 0;
|
int length = 0;
|
||||||
for (byte[] bytes : arrayBytes) {
|
for (byte[] bytes : arrayBytes) {
|
||||||
length += bytes.length;
|
length += bytes.length;
|
||||||
@ -304,8 +329,11 @@ public class Sys {
|
|||||||
return concatBytes;
|
return concatBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** gets the SHA256 hash + SALT of the specified username, as UTF-16 */
|
/**
|
||||||
public static final byte[] getSha256WithSalt(String username, byte[] saltBytes) {
|
* gets the SHA256 hash + SALT of the specified username, as UTF-16
|
||||||
|
*/
|
||||||
|
public static final
|
||||||
|
byte[] getSha256WithSalt(String username, byte[] saltBytes) {
|
||||||
if (username == null) {
|
if (username == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -322,8 +350,11 @@ public class Sys {
|
|||||||
return usernameHashBytes;
|
return usernameHashBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** gets the SHA256 hash of the specified string, as UTF-16 */
|
/**
|
||||||
public static final byte[] getSha256(String string) {
|
* gets the SHA256 hash of the specified string, as UTF-16
|
||||||
|
*/
|
||||||
|
public static final
|
||||||
|
byte[] getSha256(String string) {
|
||||||
byte[] charToBytes = Sys.charToBytes(string.toCharArray());
|
byte[] charToBytes = Sys.charToBytes(string.toCharArray());
|
||||||
|
|
||||||
SHA256Digest sha256 = new SHA256Digest();
|
SHA256Digest sha256 = new SHA256Digest();
|
||||||
@ -334,8 +365,11 @@ public class Sys {
|
|||||||
return usernameHashBytes;
|
return usernameHashBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** gets the SHA256 hash of the specified byte array */
|
/**
|
||||||
public static final byte[] getSha256(byte[] bytes) {
|
* gets the SHA256 hash of the specified byte array
|
||||||
|
*/
|
||||||
|
public static final
|
||||||
|
byte[] getSha256(byte[] bytes) {
|
||||||
|
|
||||||
SHA256Digest sha256 = new SHA256Digest();
|
SHA256Digest sha256 = new SHA256Digest();
|
||||||
byte[] hashBytes = new byte[sha256.getDigestSize()];
|
byte[] hashBytes = new byte[sha256.getDigestSize()];
|
||||||
@ -345,20 +379,24 @@ public class Sys {
|
|||||||
return hashBytes;
|
return hashBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** this saves the char array in UTF-16 format of bytes */
|
/**
|
||||||
public static final byte[] charToBytes(char[] text) {
|
* this saves the char array in UTF-16 format of bytes
|
||||||
|
*/
|
||||||
|
public static final
|
||||||
|
byte[] charToBytes(char[] text) {
|
||||||
// NOTE: this saves the char array in UTF-16 format of bytes.
|
// NOTE: this saves the char array in UTF-16 format of bytes.
|
||||||
byte[] bytes = new byte[text.length*2];
|
byte[] bytes = new byte[text.length * 2];
|
||||||
for(int i=0; i<text.length; i++) {
|
for (int i = 0; i < text.length; i++) {
|
||||||
bytes[2*i] = (byte) (text[i] >> 8);
|
bytes[2 * i] = (byte) (text[i] >> 8);
|
||||||
bytes[2*i+1] = (byte) text[i];
|
bytes[2 * i + 1] = (byte) text[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static final byte[] intsToBytes(int[] ints) {
|
public static final
|
||||||
|
byte[] intsToBytes(int[] ints) {
|
||||||
int length = ints.length;
|
int length = ints.length;
|
||||||
byte[] bytes = new byte[length];
|
byte[] bytes = new byte[length];
|
||||||
|
|
||||||
@ -369,13 +407,14 @@ public class Sys {
|
|||||||
return new byte[length];
|
return new byte[length];
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes[i] = (byte)intValue;
|
bytes[i] = (byte) intValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final int[] bytesToInts(byte[] bytes) {
|
public static final
|
||||||
|
int[] bytesToInts(byte[] bytes) {
|
||||||
int length = bytes.length;
|
int length = bytes.length;
|
||||||
int[] ints = new int[length];
|
int[] ints = new int[length];
|
||||||
|
|
||||||
@ -386,11 +425,13 @@ public class Sys {
|
|||||||
return ints;
|
return ints;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String bytesToHex(byte[] bytes) {
|
public static final
|
||||||
|
String bytesToHex(byte[] bytes) {
|
||||||
return bytesToHex(bytes, false);
|
return bytesToHex(bytes, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String bytesToHex(byte[] bytes, boolean padding) {
|
public static final
|
||||||
|
String bytesToHex(byte[] bytes, boolean padding) {
|
||||||
if (padding) {
|
if (padding) {
|
||||||
char[] hexString = new char[3 * bytes.length];
|
char[] hexString = new char[3 * bytes.length];
|
||||||
int j = 0;
|
int j = 0;
|
||||||
@ -402,7 +443,8 @@ public class Sys {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return new String(hexString);
|
return new String(hexString);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
char[] hexString = new char[2 * bytes.length];
|
char[] hexString = new char[2 * bytes.length];
|
||||||
int j = 0;
|
int j = 0;
|
||||||
|
|
||||||
@ -419,47 +461,48 @@ public class Sys {
|
|||||||
* Converts an ASCII character representing a hexadecimal
|
* Converts an ASCII character representing a hexadecimal
|
||||||
* value into its integer equivalent.
|
* value into its integer equivalent.
|
||||||
*/
|
*/
|
||||||
public static final int hexByteToInt(byte b) {
|
public static final
|
||||||
|
int hexByteToInt(byte b) {
|
||||||
switch (b) {
|
switch (b) {
|
||||||
case '0' :
|
case '0':
|
||||||
return 0;
|
return 0;
|
||||||
case '1' :
|
case '1':
|
||||||
return 1;
|
return 1;
|
||||||
case '2' :
|
case '2':
|
||||||
return 2;
|
return 2;
|
||||||
case '3' :
|
case '3':
|
||||||
return 3;
|
return 3;
|
||||||
case '4' :
|
case '4':
|
||||||
return 4;
|
return 4;
|
||||||
case '5' :
|
case '5':
|
||||||
return 5;
|
return 5;
|
||||||
case '6' :
|
case '6':
|
||||||
return 6;
|
return 6;
|
||||||
case '7' :
|
case '7':
|
||||||
return 7;
|
return 7;
|
||||||
case '8' :
|
case '8':
|
||||||
return 8;
|
return 8;
|
||||||
case '9' :
|
case '9':
|
||||||
return 9;
|
return 9;
|
||||||
case 'A' :
|
case 'A':
|
||||||
case 'a' :
|
case 'a':
|
||||||
return 10;
|
return 10;
|
||||||
case 'B' :
|
case 'B':
|
||||||
case 'b' :
|
case 'b':
|
||||||
return 11;
|
return 11;
|
||||||
case 'C' :
|
case 'C':
|
||||||
case 'c' :
|
case 'c':
|
||||||
return 12;
|
return 12;
|
||||||
case 'D' :
|
case 'D':
|
||||||
case 'd' :
|
case 'd':
|
||||||
return 13;
|
return 13;
|
||||||
case 'E' :
|
case 'E':
|
||||||
case 'e' :
|
case 'e':
|
||||||
return 14;
|
return 14;
|
||||||
case 'F' :
|
case 'F':
|
||||||
case 'f' :
|
case 'f':
|
||||||
return 15;
|
return 15;
|
||||||
default :
|
default:
|
||||||
throw new IllegalArgumentException("Error decoding byte");
|
throw new IllegalArgumentException("Error decoding byte");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -467,7 +510,8 @@ public class Sys {
|
|||||||
/**
|
/**
|
||||||
* A 4-digit hex result.
|
* A 4-digit hex result.
|
||||||
*/
|
*/
|
||||||
public static final void hex4(char c, StringBuilder sb) {
|
public static final
|
||||||
|
void hex4(char c, StringBuilder sb) {
|
||||||
sb.append(HEX_CHARS[(c & 0xF000) >> 12]);
|
sb.append(HEX_CHARS[(c & 0xF000) >> 12]);
|
||||||
sb.append(HEX_CHARS[(c & 0x0F00) >> 8]);
|
sb.append(HEX_CHARS[(c & 0x0F00) >> 8]);
|
||||||
sb.append(HEX_CHARS[(c & 0x00F0) >> 4]);
|
sb.append(HEX_CHARS[(c & 0x00F0) >> 4]);
|
||||||
@ -478,12 +522,12 @@ public class Sys {
|
|||||||
* Returns a string representation of the byte array as a series of
|
* Returns a string representation of the byte array as a series of
|
||||||
* hexadecimal characters.
|
* hexadecimal characters.
|
||||||
*
|
*
|
||||||
* @param bytes
|
* @param bytes byte array to convert
|
||||||
* byte array to convert
|
|
||||||
* @return a string representation of the byte array as a series of
|
* @return a string representation of the byte array as a series of
|
||||||
* hexadecimal characters
|
* hexadecimal characters
|
||||||
*/
|
*/
|
||||||
public static final String toHexString(byte[] bytes) {
|
public static final
|
||||||
|
String toHexString(byte[] bytes) {
|
||||||
char[] hexString = new char[2 * bytes.length];
|
char[] hexString = new char[2 * bytes.length];
|
||||||
int j = 0;
|
int j = 0;
|
||||||
|
|
||||||
@ -501,11 +545,12 @@ public class Sys {
|
|||||||
* @param originalArray this is the base of the XOR operation.
|
* @param originalArray this is the base of the XOR operation.
|
||||||
* @param keyArray this is XOR'd into the original array, repeats if necessary.
|
* @param keyArray this is XOR'd into the original array, repeats if necessary.
|
||||||
*/
|
*/
|
||||||
public static void xorArrays(byte[] originalArray, byte[] keyArray) {
|
public static
|
||||||
|
void xorArrays(byte[] originalArray, byte[] keyArray) {
|
||||||
int keyIndex = 0;
|
int keyIndex = 0;
|
||||||
int keyLength = keyArray.length;
|
int keyLength = keyArray.length;
|
||||||
|
|
||||||
for (int i=0;i<originalArray.length;i++) {
|
for (int i = 0; i < originalArray.length; i++) {
|
||||||
//XOR the data and start over if necessary
|
//XOR the data and start over if necessary
|
||||||
originalArray[i] = (byte) (originalArray[i] ^ keyArray[keyIndex++ % keyLength]);
|
originalArray[i] = (byte) (originalArray[i] ^ keyArray[keyIndex++ % keyLength]);
|
||||||
}
|
}
|
||||||
@ -513,7 +558,8 @@ public class Sys {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static final byte[] encodeStringArray(List<String> array) {
|
public static final
|
||||||
|
byte[] encodeStringArray(List<String> array) {
|
||||||
int length = 0;
|
int length = 0;
|
||||||
for (String s : array) {
|
for (String s : array) {
|
||||||
byte[] bytes = s.getBytes();
|
byte[] bytes = s.getBytes();
|
||||||
@ -526,7 +572,7 @@ public class Sys {
|
|||||||
return new byte[0];
|
return new byte[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] bytes = new byte[length+array.size()];
|
byte[] bytes = new byte[length + array.size()];
|
||||||
|
|
||||||
length = 0;
|
length = 0;
|
||||||
for (String s : array) {
|
for (String s : array) {
|
||||||
@ -539,18 +585,19 @@ public class Sys {
|
|||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final ArrayList<String> decodeStringArray(byte[] bytes) {
|
public static final
|
||||||
|
ArrayList<String> decodeStringArray(byte[] bytes) {
|
||||||
int length = bytes.length;
|
int length = bytes.length;
|
||||||
int position = 0;
|
int position = 0;
|
||||||
byte token = (byte) 0x01;
|
byte token = (byte) 0x01;
|
||||||
ArrayList<String> list = new ArrayList<String>(0);
|
ArrayList<String> list = new ArrayList<String>(0);
|
||||||
|
|
||||||
int last = 0;
|
int last = 0;
|
||||||
while (last+position < length) {
|
while (last + position < length) {
|
||||||
byte b = bytes[last+position++];
|
byte b = bytes[last + position++];
|
||||||
if (b == token ) {
|
if (b == token) {
|
||||||
byte[] xx = new byte[position-1];
|
byte[] xx = new byte[position - 1];
|
||||||
System.arraycopy(bytes, last, xx, 0, position-1);
|
System.arraycopy(bytes, last, xx, 0, position - 1);
|
||||||
list.add(new String(xx));
|
list.add(new String(xx));
|
||||||
last += position;
|
last += position;
|
||||||
position = 0;
|
position = 0;
|
||||||
@ -561,32 +608,35 @@ public class Sys {
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String printArrayRaw(byte[] bytes) {
|
public static
|
||||||
|
String printArrayRaw(byte[] bytes) {
|
||||||
return printArrayRaw(bytes, 0);
|
return printArrayRaw(bytes, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String printArrayRaw(byte[] bytes, int lineLength) {
|
public static
|
||||||
|
String printArrayRaw(byte[] bytes, int lineLength) {
|
||||||
if (lineLength > 0) {
|
if (lineLength > 0) {
|
||||||
int mod = lineLength;
|
int mod = lineLength;
|
||||||
int length = bytes.length;
|
int length = bytes.length;
|
||||||
int comma = length-1;
|
int comma = length - 1;
|
||||||
|
|
||||||
StringBuilder builder = new StringBuilder(length + length/mod);
|
StringBuilder builder = new StringBuilder(length + length / mod);
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
builder.append(bytes[i]);
|
builder.append(bytes[i]);
|
||||||
if (i < comma) {
|
if (i < comma) {
|
||||||
builder.append(",");
|
builder.append(",");
|
||||||
}
|
}
|
||||||
if (i > 0 && i%mod == 0) {
|
if (i > 0 && i % mod == 0) {
|
||||||
builder.append(OS.LINE_SEPARATOR);
|
builder.append(OS.LINE_SEPARATOR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
|
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
int length = bytes.length;
|
int length = bytes.length;
|
||||||
int comma = length-1;
|
int comma = length - 1;
|
||||||
|
|
||||||
StringBuilder builder = new StringBuilder(length + length);
|
StringBuilder builder = new StringBuilder(length + length);
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
@ -600,25 +650,29 @@ public class Sys {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void printArray(byte[] bytes) {
|
public static
|
||||||
|
void printArray(byte[] bytes) {
|
||||||
printArray(bytes, bytes.length, true);
|
printArray(bytes, bytes.length, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void printArray(byte[] bytes, int length, boolean includeByteCount) {
|
public static
|
||||||
|
void printArray(byte[] bytes, int length, boolean includeByteCount) {
|
||||||
printArray(bytes, length, includeByteCount, 40);
|
printArray(bytes, length, includeByteCount, 40);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void printArray(byte[] bytes, int length, boolean includeByteCount, int lineLength) {
|
public static
|
||||||
|
void printArray(byte[] bytes, int length, boolean includeByteCount, int lineLength) {
|
||||||
if (includeByteCount) {
|
if (includeByteCount) {
|
||||||
System.err.println("Bytes: " + length);
|
System.err.println("Bytes: " + length);
|
||||||
}
|
}
|
||||||
|
|
||||||
int comma = length-1;
|
int comma = length - 1;
|
||||||
|
|
||||||
StringBuilder builder;
|
StringBuilder builder;
|
||||||
if (lineLength > 0) {
|
if (lineLength > 0) {
|
||||||
builder = new StringBuilder(length + comma + length/lineLength + 2);
|
builder = new StringBuilder(length + comma + length / lineLength + 2);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
builder = new StringBuilder(length + comma + 2);
|
builder = new StringBuilder(length + comma + 2);
|
||||||
}
|
}
|
||||||
builder.append("{");
|
builder.append("{");
|
||||||
@ -628,7 +682,7 @@ public class Sys {
|
|||||||
if (i < comma) {
|
if (i < comma) {
|
||||||
builder.append(",");
|
builder.append(",");
|
||||||
}
|
}
|
||||||
if (i > 0 && lineLength > 0 && i%lineLength == 0) {
|
if (i > 0 && lineLength > 0 && i % lineLength == 0) {
|
||||||
builder.append(OS.LINE_SEPARATOR);
|
builder.append(OS.LINE_SEPARATOR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -658,17 +712,18 @@ public class Sys {
|
|||||||
* <p/>
|
* <p/>
|
||||||
*
|
*
|
||||||
* @throws UnknownHostException If the LAN address of the machine cannot be found.
|
* @throws UnknownHostException If the LAN address of the machine cannot be found.
|
||||||
*
|
* <p/>
|
||||||
* From: https://issues.apache.org/jira/browse/JCS-40
|
* From: https://issues.apache.org/jira/browse/JCS-40
|
||||||
*/
|
*/
|
||||||
public static InetAddress getLocalHostLanAddress() throws UnknownHostException {
|
public static
|
||||||
|
InetAddress getLocalHostLanAddress() throws UnknownHostException {
|
||||||
try {
|
try {
|
||||||
InetAddress candidateAddress = null;
|
InetAddress candidateAddress = null;
|
||||||
// Iterate all NICs (network interface cards)...
|
// Iterate all NICs (network interface cards)...
|
||||||
for (Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements();) {
|
for (Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements(); ) {
|
||||||
NetworkInterface iface = ifaces.nextElement();
|
NetworkInterface iface = ifaces.nextElement();
|
||||||
// Iterate all IP addresses assigned to each card...
|
// Iterate all IP addresses assigned to each card...
|
||||||
for (Enumeration<InetAddress> inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();) {
|
for (Enumeration<InetAddress> inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements(); ) {
|
||||||
InetAddress inetAddr = inetAddrs.nextElement();
|
InetAddress inetAddr = inetAddrs.nextElement();
|
||||||
if (!inetAddr.isLoopbackAddress()) {
|
if (!inetAddr.isLoopbackAddress()) {
|
||||||
|
|
||||||
@ -700,8 +755,7 @@ public class Sys {
|
|||||||
throw new UnknownHostException("The JDK InetAddress.getLocalHost() method unexpectedly returned null.");
|
throw new UnknownHostException("The JDK InetAddress.getLocalHost() method unexpectedly returned null.");
|
||||||
}
|
}
|
||||||
return jdkSuppliedAddress;
|
return jdkSuppliedAddress;
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
UnknownHostException unknownHostException = new UnknownHostException("Failed to determine LAN address: " + e);
|
UnknownHostException unknownHostException = new UnknownHostException("Failed to determine LAN address: " + e);
|
||||||
unknownHostException.initCause(e);
|
unknownHostException.initCause(e);
|
||||||
throw unknownHostException;
|
throw unknownHostException;
|
||||||
@ -711,44 +765,39 @@ public class Sys {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This will retrieve your IP address via an HTTP server.
|
* This will retrieve your IP address via an HTTP server.
|
||||||
* <p>
|
* <p/>
|
||||||
* <b>NOTE: Use DnsClient.getPublicIp() instead. It's much faster and more reliable as it uses DNS.</b>
|
* <b>NOTE: Use DnsClient.getPublicIp() instead. It's much faster and more reliable as it uses DNS.</b>
|
||||||
*
|
*
|
||||||
* @return the public IP address if found, or null if it didn't find it
|
* @return the public IP address if found, or null if it didn't find it
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static String getPublicIpViaHttp() {
|
public static
|
||||||
|
String getPublicIpViaHttp() {
|
||||||
// method 1: use DNS servers
|
// method 1: use DNS servers
|
||||||
// dig +short myip.opendns.com @resolver1.opendns.com
|
// dig +short myip.opendns.com @resolver1.opendns.com
|
||||||
|
|
||||||
// method 2: use public http servers
|
// method 2: use public http servers
|
||||||
final String websites[] = {
|
final String websites[] = {"http://ip.dorkbox.com/", "http://ip.javalauncher.com/", "http://checkip.dyndns.com/",
|
||||||
"http://ip.dorkbox.com/",
|
"http://checkip.dyn.com/", "http://curlmyip.com/", "http://tnx.nl/ip", "http://ipecho.net/plain",
|
||||||
"http://ip.javalauncher.com/",
|
"http://icanhazip.com/", "http://ip.appspot.com/",};
|
||||||
"http://checkip.dyndns.com/",
|
|
||||||
"http://checkip.dyn.com/",
|
|
||||||
"http://curlmyip.com/",
|
|
||||||
"http://tnx.nl/ip",
|
|
||||||
"http://ipecho.net/plain",
|
|
||||||
"http://icanhazip.com/",
|
|
||||||
"http://ip.appspot.com/",
|
|
||||||
};
|
|
||||||
|
|
||||||
// loop, since they won't always work.
|
// loop, since they won't always work.
|
||||||
for (int i=0;i<websites.length;i++) {
|
for (int i = 0; i < websites.length; i++) {
|
||||||
try {
|
try {
|
||||||
URL autoIP = new URL(websites[i]);
|
URL autoIP = new URL(websites[i]);
|
||||||
BufferedReader in = new BufferedReader(new InputStreamReader(autoIP.openStream()));
|
BufferedReader in = new BufferedReader(new InputStreamReader(autoIP.openStream()));
|
||||||
String response = in.readLine().trim();
|
String response = in.readLine()
|
||||||
|
.trim();
|
||||||
in.close();
|
in.close();
|
||||||
|
|
||||||
Pattern pattern = Pattern.compile("\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b");
|
Pattern pattern = Pattern.compile("\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b");
|
||||||
Matcher matcher = pattern.matcher(response);
|
Matcher matcher = pattern.matcher(response);
|
||||||
if (matcher.find()) {
|
if (matcher.find()) {
|
||||||
String IP = matcher.group().trim();
|
String IP = matcher.group()
|
||||||
|
.trim();
|
||||||
return IP;
|
return IP;
|
||||||
}
|
}
|
||||||
} catch (Exception e){
|
} catch (Exception e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -757,9 +806,11 @@ public class Sys {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to retrieve the IP address from the NIC. Order is ETHx -> EMx -> WLANx
|
* Tries to retrieve the IP address from the NIC. Order is ETHx -> EMx -> WLANx
|
||||||
|
*
|
||||||
* @return null if not found
|
* @return null if not found
|
||||||
*/
|
*/
|
||||||
public static InetAddress getIpAddressesFromNic() {
|
public static
|
||||||
|
InetAddress getIpAddressesFromNic() {
|
||||||
try {
|
try {
|
||||||
Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
|
Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
|
||||||
while (nets.hasMoreElements()) {
|
while (nets.hasMoreElements()) {
|
||||||
|
@ -15,38 +15,34 @@
|
|||||||
*/
|
*/
|
||||||
package dorkbox.util.bytes;
|
package dorkbox.util.bytes;
|
||||||
|
|
||||||
|
import org.bouncycastle.crypto.digests.SHA256Digest;
|
||||||
|
|
||||||
|
import java.nio.charset.Charset;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Necessary to provide equals and hashcode methods on a byte arrays, if they are to be used as keys in a map/set/etc
|
* Necessary to provide equals and hashcode methods on a byte arrays, if they are to be used as keys in a map/set/etc
|
||||||
*/
|
*/
|
||||||
public final class ByteArrayWrapper {
|
public final
|
||||||
private final byte[] data;
|
class ByteArrayWrapper {
|
||||||
|
public static final Charset UTF_8 = Charset.forName("UTF-8");
|
||||||
|
|
||||||
|
private byte[] data;
|
||||||
private Integer hashCode;
|
private Integer hashCode;
|
||||||
|
|
||||||
/**
|
private
|
||||||
* Makes a safe copy of the byte array, so that changes to the original do not affect the wrapper.
|
ByteArrayWrapper() {
|
||||||
* Side affect is additional memory is used.
|
// this is necessary for kryo
|
||||||
*/
|
|
||||||
public static ByteArrayWrapper copy(byte[] data) {
|
|
||||||
return new ByteArrayWrapper(data, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Does not make a copy of the data, so changes to the original will also affect the wrapper.
|
|
||||||
* Side affect is no extra memory is needed.
|
|
||||||
*/
|
|
||||||
public static ByteArrayWrapper wrap(byte[] data) {
|
|
||||||
return new ByteArrayWrapper(data, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Permits the re-use of a byte array.
|
* Permits the re-use of a byte array.
|
||||||
|
*
|
||||||
* @param copyBytes if TRUE, then the byteArray is copies. if FALSE, the byte array is uses as-is.
|
* @param copyBytes if TRUE, then the byteArray is copies. if FALSE, the byte array is uses as-is.
|
||||||
* Using FALSE IS DANGEROUS!!!! If the underlying byte array is modified, this changes as well.
|
* Using FALSE IS DANGEROUS!!!! If the underlying byte array is modified, this changes as well.
|
||||||
*/
|
*/
|
||||||
private ByteArrayWrapper(byte[] data, boolean copyBytes) {
|
private
|
||||||
|
ByteArrayWrapper(byte[] data, boolean copyBytes) {
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
}
|
}
|
||||||
@ -56,27 +52,61 @@ public final class ByteArrayWrapper {
|
|||||||
this.data = new byte[length];
|
this.data = new byte[length];
|
||||||
// copy so it's immutable as a key.
|
// copy so it's immutable as a key.
|
||||||
System.arraycopy(data, 0, this.data, 0, length);
|
System.arraycopy(data, 0, this.data, 0, length);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getBytes() {
|
/**
|
||||||
|
* Makes a safe copy of the byte array, so that changes to the original do not affect the wrapper.
|
||||||
|
* Side affect is additional memory is used.
|
||||||
|
*/
|
||||||
|
public static
|
||||||
|
ByteArrayWrapper copy(byte[] data) {
|
||||||
|
if (data == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ByteArrayWrapper(data, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does not make a copy of the data, so changes to the original will also affect the wrapper.
|
||||||
|
* Side affect is no extra memory is needed.
|
||||||
|
*/
|
||||||
|
public static
|
||||||
|
ByteArrayWrapper wrap(byte[] data) {
|
||||||
|
if (data == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new ByteArrayWrapper(data, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static
|
||||||
|
ByteArrayWrapper wrap(String data) {
|
||||||
|
if (data == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] bytes = data.getBytes(UTF_8);
|
||||||
|
|
||||||
|
SHA256Digest digest = new SHA256Digest();
|
||||||
|
digest.update(bytes, 0, bytes.length);
|
||||||
|
byte[] hashBytes = new byte[digest.getDigestSize()];
|
||||||
|
digest.doFinal(hashBytes, 0);
|
||||||
|
|
||||||
|
return ByteArrayWrapper.wrap(hashBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public
|
||||||
|
byte[] getBytes() {
|
||||||
return this.data;
|
return this.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object other) {
|
public
|
||||||
if (!(other instanceof ByteArrayWrapper)) {
|
int hashCode() {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// CANNOT be null, so we don't have to null check!
|
|
||||||
return Arrays.equals(this.data, ((ByteArrayWrapper) other).data);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
// might be null for a thread because it's stale. who cares, get the value again
|
// might be null for a thread because it's stale. who cares, get the value again
|
||||||
Integer hashCode = this.hashCode;
|
Integer hashCode = this.hashCode;
|
||||||
if (hashCode == null) {
|
if (hashCode == null) {
|
||||||
@ -87,7 +117,19 @@ public final class ByteArrayWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public
|
||||||
|
boolean equals(Object other) {
|
||||||
|
if (!(other instanceof ByteArrayWrapper)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CANNOT be null, so we don't have to null check!
|
||||||
|
return Arrays.equals(this.data, ((ByteArrayWrapper) other).data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public
|
||||||
|
String toString() {
|
||||||
return "ByteArrayWrapper " + java.util.Arrays.toString(this.data);
|
return "ByteArrayWrapper " + java.util.Arrays.toString(this.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,29 +1,31 @@
|
|||||||
package dorkbox.util.crypto.serialization;
|
package dorkbox.util.crypto.serialization;
|
||||||
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
import org.bouncycastle.crypto.params.ECDomainParameters;
|
|
||||||
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
|
||||||
import org.bouncycastle.math.ec.ECCurve;
|
|
||||||
import org.bouncycastle.math.ec.ECPoint;
|
|
||||||
|
|
||||||
import com.esotericsoftware.kryo.Kryo;
|
import com.esotericsoftware.kryo.Kryo;
|
||||||
import com.esotericsoftware.kryo.Serializer;
|
import com.esotericsoftware.kryo.Serializer;
|
||||||
import com.esotericsoftware.kryo.io.Input;
|
import com.esotericsoftware.kryo.io.Input;
|
||||||
import com.esotericsoftware.kryo.io.Output;
|
import com.esotericsoftware.kryo.io.Output;
|
||||||
|
import org.bouncycastle.crypto.params.ECDomainParameters;
|
||||||
|
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
||||||
|
import org.bouncycastle.math.ec.ECCurve;
|
||||||
|
import org.bouncycastle.math.ec.ECPoint;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Only public keys are ever sent across the wire.
|
* Only public keys are ever sent across the wire.
|
||||||
*/
|
*/
|
||||||
public class EccPublicKeySerializer extends Serializer<ECPublicKeyParameters> {
|
public
|
||||||
|
class EccPublicKeySerializer extends Serializer<ECPublicKeyParameters> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(Kryo kryo, Output output, ECPublicKeyParameters key) {
|
public
|
||||||
|
void write(Kryo kryo, Output output, ECPublicKeyParameters key) {
|
||||||
write(output, key);
|
write(output, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void write(Output output, ECPublicKeyParameters key) {
|
public static
|
||||||
|
void write(Output output, ECPublicKeyParameters key) {
|
||||||
byte[] bytes;
|
byte[] bytes;
|
||||||
int length;
|
int length;
|
||||||
|
|
||||||
@ -50,12 +52,13 @@ public class EccPublicKeySerializer extends Serializer<ECPublicKeyParameters> {
|
|||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
@Override
|
@Override
|
||||||
public ECPublicKeyParameters read(Kryo kryo, Input input, Class type) {
|
public
|
||||||
ECPublicKeyParameters ecPublicKeyParameters = read(input);
|
ECPublicKeyParameters read(Kryo kryo, Input input, Class type) {
|
||||||
return ecPublicKeyParameters;
|
return read(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ECPublicKeyParameters read(Input input) {
|
public static
|
||||||
|
ECPublicKeyParameters read(Input input) {
|
||||||
byte[] bytes;
|
byte[] bytes;
|
||||||
int length;
|
int length;
|
||||||
|
|
||||||
@ -88,7 +91,6 @@ public class EccPublicKeySerializer extends Serializer<ECPublicKeyParameters> {
|
|||||||
input.readBytes(bytes, 0, length);
|
input.readBytes(bytes, 0, length);
|
||||||
ECPoint Q = curve.decodePoint(bytes);
|
ECPoint Q = curve.decodePoint(bytes);
|
||||||
|
|
||||||
ECPublicKeyParameters ecPublicKeyParameters = new ECPublicKeyParameters(Q, ecDomainParameters);
|
return new ECPublicKeyParameters(Q, ecDomainParameters);
|
||||||
return ecPublicKeyParameters;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
116
Dorkbox-Util/src/dorkbox/util/database/DB_Server.java
Normal file
116
Dorkbox-Util/src/dorkbox/util/database/DB_Server.java
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
package dorkbox.util.database;
|
||||||
|
|
||||||
|
import dorkbox.util.bytes.ByteArrayWrapper;
|
||||||
|
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
|
||||||
|
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public
|
||||||
|
class DB_Server {
|
||||||
|
/**
|
||||||
|
* Address 0.0.0.0/32 may be used as a source address for this host on this network.
|
||||||
|
*/
|
||||||
|
public static final ByteArrayWrapper IP_0_0_0_0 = ByteArrayWrapper.wrap(new byte[] {0, 0, 0, 0});
|
||||||
|
|
||||||
|
// salt + IP address is used for equals!
|
||||||
|
private byte[] ipAddress;
|
||||||
|
private byte[] salt;
|
||||||
|
|
||||||
|
private ECPrivateKeyParameters privateKey;
|
||||||
|
private ECPublicKeyParameters publicKey;
|
||||||
|
|
||||||
|
// must have empty constructor
|
||||||
|
public
|
||||||
|
DB_Server() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public
|
||||||
|
byte[] getAddress() {
|
||||||
|
if (this.ipAddress == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return this.ipAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public
|
||||||
|
void setAddress(byte[] ipAddress) {
|
||||||
|
this.ipAddress = ipAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public
|
||||||
|
byte[] getSalt() {
|
||||||
|
return this.salt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public
|
||||||
|
void setSalt(byte[] salt) {
|
||||||
|
this.salt = salt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public
|
||||||
|
ECPrivateKeyParameters getPrivateKey() {
|
||||||
|
return this.privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public
|
||||||
|
void setPrivateKey(ECPrivateKeyParameters privateKey) {
|
||||||
|
this.privateKey = privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public
|
||||||
|
ECPublicKeyParameters getPublicKey() {
|
||||||
|
return this.publicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public
|
||||||
|
void setPublicKey(ECPublicKeyParameters publicKey) {
|
||||||
|
this.publicKey = publicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public
|
||||||
|
int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + (this.ipAddress == null ? 0 : Arrays.hashCode(this.ipAddress));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public
|
||||||
|
boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
DB_Server other = (DB_Server) obj;
|
||||||
|
if (this.ipAddress == null) {
|
||||||
|
if (other.ipAddress != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!Arrays.equals(this.ipAddress, other.ipAddress)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Arrays.equals(this.salt, other.salt);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public
|
||||||
|
String toString() {
|
||||||
|
byte[] bytes = this.ipAddress;
|
||||||
|
if (bytes != null) {
|
||||||
|
return "DB_Server " + Arrays.toString(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return "DB_Server [no-ip-set]";
|
||||||
|
}
|
||||||
|
}
|
33
Dorkbox-Util/src/dorkbox/util/database/DatabaseStorage.java
Normal file
33
Dorkbox-Util/src/dorkbox/util/database/DatabaseStorage.java
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 dorkbox, llc
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package dorkbox.util.database;
|
||||||
|
|
||||||
|
import dorkbox.util.bytes.ByteArrayWrapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of all of the keys used by the storage database
|
||||||
|
*/
|
||||||
|
public
|
||||||
|
class DatabaseStorage {
|
||||||
|
public static final ByteArrayWrapper SERVERS = ByteArrayWrapper.wrap("servers");
|
||||||
|
public static final ByteArrayWrapper ROOT = ByteArrayWrapper.wrap("root");
|
||||||
|
public static final ByteArrayWrapper USERS = ByteArrayWrapper.wrap("users");
|
||||||
|
public static final ByteArrayWrapper ADMIN_HASH = ByteArrayWrapper.wrap("adminHash");
|
||||||
|
public static final ByteArrayWrapper FILES = ByteArrayWrapper.wrap("files");
|
||||||
|
public static final ByteArrayWrapper GENERIC = ByteArrayWrapper.wrap("generic");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -25,17 +25,21 @@ import java.util.Properties;
|
|||||||
|
|
||||||
import dorkbox.util.FileUtil;
|
import dorkbox.util.FileUtil;
|
||||||
|
|
||||||
public class PropertiesProvider {
|
@SuppressWarnings("unused")
|
||||||
|
public
|
||||||
|
class PropertiesProvider {
|
||||||
|
|
||||||
private String comments = "Settings and configuration file. Strings must be escape formatted!";
|
private String comments = "Settings and configuration file. Strings must be escape formatted!";
|
||||||
private final Properties properties = new SortedProperties();
|
private final Properties properties = new SortedProperties();
|
||||||
private final File propertiesFile;
|
private final File propertiesFile;
|
||||||
|
|
||||||
public PropertiesProvider(String propertiesFile) {
|
public
|
||||||
|
PropertiesProvider(String propertiesFile) {
|
||||||
this(new File(propertiesFile));
|
this(new File(propertiesFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
public PropertiesProvider(File propertiesFile) {
|
public
|
||||||
|
PropertiesProvider(File propertiesFile) {
|
||||||
if (propertiesFile == null) {
|
if (propertiesFile == null) {
|
||||||
throw new NullPointerException("propertiesFile");
|
throw new NullPointerException("propertiesFile");
|
||||||
}
|
}
|
||||||
@ -43,8 +47,10 @@ public class PropertiesProvider {
|
|||||||
propertiesFile = FileUtil.normalize(propertiesFile);
|
propertiesFile = FileUtil.normalize(propertiesFile);
|
||||||
// make sure the parent dir exists...
|
// make sure the parent dir exists...
|
||||||
File parentFile = propertiesFile.getParentFile();
|
File parentFile = propertiesFile.getParentFile();
|
||||||
if (parentFile != null) {
|
if (parentFile != null && !parentFile.exists()) {
|
||||||
parentFile.mkdirs();
|
if (!parentFile.mkdirs()) {
|
||||||
|
throw new RuntimeException("Unable to create directories for: " + propertiesFile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.propertiesFile = propertiesFile;
|
this.propertiesFile = propertiesFile;
|
||||||
@ -52,11 +58,13 @@ public class PropertiesProvider {
|
|||||||
_load();
|
_load();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setComments(String comments) {
|
public
|
||||||
|
void setComments(String comments) {
|
||||||
this.comments = comments;
|
this.comments = comments;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final void _load() {
|
private
|
||||||
|
void _load() {
|
||||||
if (!this.propertiesFile.canRead() || !this.propertiesFile.exists()) {
|
if (!this.propertiesFile.canRead() || !this.propertiesFile.exists()) {
|
||||||
// in this case, our properties file doesn't exist yet... create one!
|
// in this case, our properties file doesn't exist yet... create one!
|
||||||
_save();
|
_save();
|
||||||
@ -77,7 +85,8 @@ public class PropertiesProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private final void _save() {
|
private
|
||||||
|
void _save() {
|
||||||
try {
|
try {
|
||||||
FileOutputStream fos = new FileOutputStream(this.propertiesFile);
|
FileOutputStream fos = new FileOutputStream(this.propertiesFile);
|
||||||
this.properties.store(fos, this.comments);
|
this.properties.store(fos, this.comments);
|
||||||
@ -95,18 +104,21 @@ public class PropertiesProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public synchronized final void remove(final String key) {
|
public final synchronized
|
||||||
|
void remove(final String key) {
|
||||||
this.properties.remove(key);
|
this.properties.remove(key);
|
||||||
_save();
|
_save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized final void save(final String key, Object value) {
|
@SuppressWarnings("AutoBoxing")
|
||||||
|
public final synchronized
|
||||||
|
void save(final String key, Object value) {
|
||||||
if (key == null || value == null) {
|
if (key == null || value == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value instanceof Color) {
|
if (value instanceof Color) {
|
||||||
value = ((Color)value).getRGB();
|
value = ((Color) value).getRGB();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.properties.setProperty(key, value.toString());
|
this.properties.setProperty(key, value.toString());
|
||||||
@ -114,8 +126,9 @@ public class PropertiesProvider {
|
|||||||
_save();
|
_save();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings({"unchecked", "AutoUnboxing"})
|
||||||
public synchronized <T> T get(String key, Class<T> clazz) {
|
public synchronized
|
||||||
|
<T> T get(String key, Class<T> clazz) {
|
||||||
if (key == null || clazz == null) {
|
if (key == null || clazz == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -146,7 +159,8 @@ public class PropertiesProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public
|
||||||
|
String toString() {
|
||||||
return "PropertiesProvider [" + this.propertiesFile + "]";
|
return "PropertiesProvider [" + this.propertiesFile + "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ import java.util.concurrent.locks.ReentrantLock;
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public
|
public
|
||||||
class DiskStorage implements DiskStorageIfface {
|
class DiskStorage implements Storage {
|
||||||
private final DelayTimer timer;
|
private final DelayTimer timer;
|
||||||
private final ByteArrayWrapper defaultKey;
|
private final ByteArrayWrapper defaultKey;
|
||||||
private final StorageBase storage;
|
private final StorageBase storage;
|
||||||
@ -51,10 +51,14 @@ class DiskStorage implements DiskStorageIfface {
|
|||||||
* Creates or opens a new database file.
|
* Creates or opens a new database file.
|
||||||
*/
|
*/
|
||||||
protected
|
protected
|
||||||
DiskStorage(File storageFile, SerializationManager serializationManager) throws IOException {
|
DiskStorage(File storageFile, SerializationManager serializationManager, final boolean readOnly) throws IOException {
|
||||||
this.storage = new StorageBase(storageFile, serializationManager);
|
this.storage = new StorageBase(storageFile, serializationManager);
|
||||||
this.defaultKey = ByteArrayWrapper.wrap("");
|
this.defaultKey = ByteArrayWrapper.wrap("");
|
||||||
|
|
||||||
|
if (readOnly) {
|
||||||
|
this.timer = null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
this.timer = new DelayTimer("Storage Writer", false, new DelayTimer.Callback() {
|
this.timer = new DelayTimer("Storage Writer", false, new DelayTimer.Callback() {
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
@ -75,6 +79,7 @@ class DiskStorage implements DiskStorageIfface {
|
|||||||
DiskStorage.this.storage.doActionThings(actions);
|
DiskStorage.this.storage.doActionThings(actions);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this.isOpen.set(true);
|
this.isOpen.set(true);
|
||||||
}
|
}
|
||||||
@ -95,7 +100,9 @@ class DiskStorage implements DiskStorageIfface {
|
|||||||
|
|
||||||
// flush actions
|
// flush actions
|
||||||
// timer action runs on THIS thread, not timer thread
|
// timer action runs on THIS thread, not timer thread
|
||||||
|
if (timer != null) {
|
||||||
this.timer.delay(0L);
|
this.timer.delay(0L);
|
||||||
|
}
|
||||||
|
|
||||||
return this.storage.size();
|
return this.storage.size();
|
||||||
}
|
}
|
||||||
@ -281,11 +288,13 @@ class DiskStorage implements DiskStorageIfface {
|
|||||||
throw new RuntimeException("Unable to act on closed storage");
|
throw new RuntimeException("Unable to act on closed storage");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (timer != null) {
|
||||||
action(key, object);
|
action(key, object);
|
||||||
|
|
||||||
// timer action runs on TIMER thread, not this thread
|
// timer action runs on TIMER thread, not this thread
|
||||||
this.timer.delay(this.milliSeconds);
|
this.timer.delay(this.milliSeconds);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the given object to the storage using a default (blank) key, OR -- if it has been registered, using it's registered key
|
* Adds the given object to the storage using a default (blank) key, OR -- if it has been registered, using it's registered key
|
||||||
@ -300,11 +309,13 @@ class DiskStorage implements DiskStorageIfface {
|
|||||||
throw new RuntimeException("Unable to act on closed storage");
|
throw new RuntimeException("Unable to act on closed storage");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (timer != null) {
|
||||||
action(this.defaultKey, object);
|
action(this.defaultKey, object);
|
||||||
|
|
||||||
// timer action runs on TIMER thread, not this thread
|
// timer action runs on TIMER thread, not this thread
|
||||||
this.timer.delay(this.milliSeconds);
|
this.timer.delay(this.milliSeconds);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes an object from storage. To ALSO remove from the cache, use unRegister(key)
|
* Deletes an object from storage. To ALSO remove from the cache, use unRegister(key)
|
||||||
@ -321,23 +332,31 @@ class DiskStorage implements DiskStorageIfface {
|
|||||||
ByteArrayWrapper wrap = ByteArrayWrapper.wrap(key);
|
ByteArrayWrapper wrap = ByteArrayWrapper.wrap(key);
|
||||||
|
|
||||||
// timer action runs on THIS thread, not timer thread
|
// timer action runs on THIS thread, not timer thread
|
||||||
|
if (timer != null) {
|
||||||
this.timer.delay(0L);
|
this.timer.delay(0L);
|
||||||
|
|
||||||
return this.storage.delete(wrap);
|
return this.storage.delete(wrap);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes the database and file.
|
* Closes the database and file.
|
||||||
*/
|
*/
|
||||||
void close() {
|
void close() {
|
||||||
// timer action runs on THIS thread, not timer thread
|
// timer action runs on THIS thread, not timer thread
|
||||||
|
if (timer != null) {
|
||||||
this.timer.delay(0L);
|
this.timer.delay(0L);
|
||||||
|
}
|
||||||
|
|
||||||
// have to "close" it after we run the timer!
|
// have to "close" it after we run the timer!
|
||||||
this.isOpen.set(false);
|
this.isOpen.set(false);
|
||||||
|
|
||||||
|
if (timer != null) {
|
||||||
this.storage.close();
|
this.storage.close();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the file that backs this storage
|
* @return the file that backs this storage
|
||||||
@ -357,7 +376,9 @@ class DiskStorage implements DiskStorageIfface {
|
|||||||
public final
|
public final
|
||||||
long getFileSize() {
|
long getFileSize() {
|
||||||
// timer action runs on THIS thread, not timer thread
|
// timer action runs on THIS thread, not timer thread
|
||||||
|
if (timer != null) {
|
||||||
this.timer.delay(0L);
|
this.timer.delay(0L);
|
||||||
|
}
|
||||||
|
|
||||||
return this.storage.getFileSize();
|
return this.storage.getFileSize();
|
||||||
}
|
}
|
||||||
@ -372,8 +393,13 @@ class DiskStorage implements DiskStorageIfface {
|
|||||||
throw new RuntimeException("Unable to act on closed storage");
|
throw new RuntimeException("Unable to act on closed storage");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (timer != null) {
|
||||||
return this.timer.isWaiting();
|
return this.timer.isWaiting();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the delay in milliseconds this will wait after the last action to flush the data to the disk
|
* @return the delay in milliseconds this will wait after the last action to flush the data to the disk
|
||||||
@ -457,8 +483,10 @@ class DiskStorage implements DiskStorageIfface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// timer action runs on THIS thread, not timer thread
|
// timer action runs on THIS thread, not timer thread
|
||||||
|
if (timer != null) {
|
||||||
this.timer.delay(0L);
|
this.timer.delay(0L);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the storage to disk, immediately.
|
* Save the storage to disk, immediately.
|
||||||
@ -472,11 +500,12 @@ class DiskStorage implements DiskStorageIfface {
|
|||||||
throw new RuntimeException("Unable to act on closed storage");
|
throw new RuntimeException("Unable to act on closed storage");
|
||||||
}
|
}
|
||||||
|
|
||||||
action(ByteArrayWrapper.wrap(key), object);
|
|
||||||
|
|
||||||
// timer action runs on THIS thread, not timer thread
|
// timer action runs on THIS thread, not timer thread
|
||||||
|
if (timer != null) {
|
||||||
|
action(ByteArrayWrapper.wrap(key), object);
|
||||||
this.timer.delay(0L);
|
this.timer.delay(0L);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the storage to disk, immediately.
|
* Save the storage to disk, immediately.
|
||||||
@ -490,12 +519,15 @@ class DiskStorage implements DiskStorageIfface {
|
|||||||
throw new RuntimeException("Unable to act on closed storage");
|
throw new RuntimeException("Unable to act on closed storage");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (timer != null) {
|
||||||
action(ByteArrayWrapper.wrap(key), object);
|
action(ByteArrayWrapper.wrap(key), object);
|
||||||
|
|
||||||
// timer action runs on THIS thread, not timer thread
|
// timer action runs on THIS thread, not timer thread
|
||||||
this.timer.delay(0L);
|
this.timer.delay(0L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the storage to disk, immediately.
|
* Save the storage to disk, immediately.
|
||||||
* <p/>
|
* <p/>
|
||||||
@ -508,9 +540,11 @@ class DiskStorage implements DiskStorageIfface {
|
|||||||
throw new RuntimeException("Unable to act on closed storage");
|
throw new RuntimeException("Unable to act on closed storage");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (timer != null) {
|
||||||
action(key, object);
|
action(key, object);
|
||||||
|
|
||||||
// timer action runs on THIS thread, not timer thread
|
// timer action runs on THIS thread, not timer thread
|
||||||
this.timer.delay(0L);
|
this.timer.delay(0L);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,13 +10,14 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
class MemoryStorage implements DiskStorageIfface {
|
class MemoryStorage implements Storage {
|
||||||
private final ConcurrentHashMap<ByteArrayWrapper, Object> storage;
|
private final ConcurrentHashMap<ByteArrayWrapper, Object> storage;
|
||||||
private final ByteArrayWrapper defaultKey;
|
private final ByteArrayWrapper defaultKey;
|
||||||
private int version;
|
private int version;
|
||||||
|
|
||||||
private
|
|
||||||
MemoryStorage() throws IOException {
|
public
|
||||||
|
MemoryStorage() {
|
||||||
this.storage = new ConcurrentHashMap<ByteArrayWrapper, Object>();
|
this.storage = new ConcurrentHashMap<ByteArrayWrapper, Object>();
|
||||||
this.defaultKey = ByteArrayWrapper.wrap("");
|
this.defaultKey = ByteArrayWrapper.wrap("");
|
||||||
}
|
}
|
||||||
@ -122,6 +123,7 @@ class MemoryStorage implements DiskStorageIfface {
|
|||||||
final Object o = storage.get(key);
|
final Object o = storage.get(key);
|
||||||
if (o == null) {
|
if (o == null) {
|
||||||
storage.put(key, data);
|
storage.put(key, data);
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
return (T) o;
|
return (T) o;
|
||||||
}
|
}
|
||||||
|
@ -263,7 +263,7 @@ class Metadata {
|
|||||||
<T> T readData(SerializationManager serializationManager, InflaterInputStream inputStream) {
|
<T> T readData(SerializationManager serializationManager, InflaterInputStream inputStream) {
|
||||||
Input input = new Input(inputStream, 1024); // read 1024 at a time
|
Input input = new Input(inputStream, 1024); // read 1024 at a time
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
T readObject = (T) serializationManager.readClassAndObject(input);
|
T readObject = (T) serializationManager.readFullClassAndObject(input);
|
||||||
return readObject;
|
return readObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,7 +277,7 @@ class Metadata {
|
|||||||
final DeflaterOutputStream outputStream) throws IOException {
|
final DeflaterOutputStream outputStream) throws IOException {
|
||||||
// HAVE TO LOCK BEFORE THIS IS CALLED! (AND FREE AFTERWARDS!)
|
// HAVE TO LOCK BEFORE THIS IS CALLED! (AND FREE AFTERWARDS!)
|
||||||
Output output = new Output(outputStream, 1024); // write 1024 at a time
|
Output output = new Output(outputStream, 1024); // write 1024 at a time
|
||||||
serializationManager.writeClassAndObject(output, data);
|
serializationManager.writeFullClassAndObject(output, data);
|
||||||
output.flush();
|
output.flush();
|
||||||
|
|
||||||
outputStream.flush(); // sync-flush is enabled, so the output stream will finish compressing data.
|
outputStream.flush(); // sync-flush is enabled, so the output stream will finish compressing data.
|
||||||
|
@ -9,7 +9,7 @@ import java.io.IOException;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
interface DiskStorageIfface {
|
interface Storage {
|
||||||
/**
|
/**
|
||||||
* Returns the number of objects in the database.
|
* Returns the number of objects in the database.
|
||||||
*/
|
*/
|
@ -449,7 +449,7 @@ class StorageBase {
|
|||||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||||
OutputStream outputStream = new DeflaterOutputStream(byteArrayOutputStream, deflater);
|
OutputStream outputStream = new DeflaterOutputStream(byteArrayOutputStream, deflater);
|
||||||
Output output = new Output(outputStream, 1024); // write 1024 at a time
|
Output output = new Output(outputStream, 1024); // write 1024 at a time
|
||||||
kryo.writeClassAndObject(output, data);
|
kryo.writeFullClassAndObject(output, data);
|
||||||
output.flush();
|
output.flush();
|
||||||
|
|
||||||
outputStream.flush();
|
outputStream.flush();
|
||||||
|
@ -1,20 +1,22 @@
|
|||||||
package dorkbox.util.storage;
|
package dorkbox.util.storage;
|
||||||
|
|
||||||
import dorkbox.util.SerializationManager;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import dorkbox.util.SerializationManager;
|
||||||
|
|
||||||
public
|
public
|
||||||
class MakeStorage {
|
class Store {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(DiskStorage.class);
|
private static final Logger logger = LoggerFactory.getLogger(DiskStorage.class);
|
||||||
|
|
||||||
@SuppressWarnings("SpellCheckingInspection")
|
@SuppressWarnings("SpellCheckingInspection")
|
||||||
private static final Map<File, DiskStorageIfface> storages = new HashMap<File, DiskStorageIfface>(1);
|
private static final Map<File, Storage> storages = new HashMap<File, Storage>(1);
|
||||||
|
|
||||||
public static
|
public static
|
||||||
DiskMaker Disk() {
|
DiskMaker Disk() {
|
||||||
@ -32,7 +34,7 @@ class MakeStorage {
|
|||||||
public static
|
public static
|
||||||
void close(File file) {
|
void close(File file) {
|
||||||
synchronized (storages) {
|
synchronized (storages) {
|
||||||
DiskStorageIfface storage = storages.get(file);
|
Storage storage = storages.get(file);
|
||||||
if (storage != null) {
|
if (storage != null) {
|
||||||
if (storage instanceof DiskStorage) {
|
if (storage instanceof DiskStorage) {
|
||||||
final DiskStorage diskStorage = (DiskStorage) storage;
|
final DiskStorage diskStorage = (DiskStorage) storage;
|
||||||
@ -50,11 +52,10 @@ class MakeStorage {
|
|||||||
* Closes the storage.
|
* Closes the storage.
|
||||||
*/
|
*/
|
||||||
public static
|
public static
|
||||||
void close(DiskStorageIfface _storage) {
|
void close(Storage _storage) {
|
||||||
synchronized (storages) {
|
synchronized (storages) {
|
||||||
File file = _storage.getFile();
|
File file = _storage.getFile();
|
||||||
DiskStorageIfface storage = storages.get(file);
|
Storage storage = storages.get(file);
|
||||||
if (storage != null) {
|
|
||||||
if (storage instanceof DiskStorage) {
|
if (storage instanceof DiskStorage) {
|
||||||
final DiskStorage diskStorage = (DiskStorage) storage;
|
final DiskStorage diskStorage = (DiskStorage) storage;
|
||||||
boolean isLastOne = diskStorage.decrementReference();
|
boolean isLastOne = diskStorage.decrementReference();
|
||||||
@ -65,13 +66,12 @@ class MakeStorage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public static
|
public static
|
||||||
void shutdown() {
|
void shutdown() {
|
||||||
synchronized (storages) {
|
synchronized (storages) {
|
||||||
Collection<DiskStorageIfface> values = storages.values();
|
Collection<Storage> values = storages.values();
|
||||||
for (DiskStorageIfface storage : values) {
|
for (Storage storage : values) {
|
||||||
if (storage instanceof DiskStorage) {
|
if (storage instanceof DiskStorage) {
|
||||||
//noinspection StatementWithEmptyBody
|
//noinspection StatementWithEmptyBody
|
||||||
final DiskStorage diskStorage = (DiskStorage) storage;
|
final DiskStorage diskStorage = (DiskStorage) storage;
|
||||||
@ -87,7 +87,7 @@ class MakeStorage {
|
|||||||
public static
|
public static
|
||||||
void delete(File file) {
|
void delete(File file) {
|
||||||
synchronized (storages) {
|
synchronized (storages) {
|
||||||
DiskStorageIfface remove = storages.remove(file);
|
Storage remove = storages.remove(file);
|
||||||
if (remove != null && remove instanceof DiskStorage) {
|
if (remove != null && remove instanceof DiskStorage) {
|
||||||
((DiskStorage) remove).close();
|
((DiskStorage) remove).close();
|
||||||
}
|
}
|
||||||
@ -97,7 +97,7 @@ class MakeStorage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static
|
public static
|
||||||
void delete(DiskStorageIfface storage) {
|
void delete(Storage storage) {
|
||||||
File file = storage.getFile();
|
File file = storage.getFile();
|
||||||
delete(file);
|
delete(file);
|
||||||
}
|
}
|
||||||
@ -107,6 +107,7 @@ class MakeStorage {
|
|||||||
class DiskMaker {
|
class DiskMaker {
|
||||||
private File file;
|
private File file;
|
||||||
private SerializationManager serializationManager;
|
private SerializationManager serializationManager;
|
||||||
|
private boolean readOnly;
|
||||||
|
|
||||||
public
|
public
|
||||||
DiskMaker file(File file) {
|
DiskMaker file(File file) {
|
||||||
@ -121,15 +122,15 @@ class MakeStorage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public
|
public
|
||||||
DiskStorageIfface make() {
|
Storage make() {
|
||||||
if (file == null) {
|
if (this.file == null) {
|
||||||
throw new IllegalArgumentException("file cannot be null!");
|
throw new IllegalArgumentException("file cannot be null!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we load from a NEW storage at the same location as an ALREADY EXISTING storage,
|
// if we load from a NEW storage at the same location as an ALREADY EXISTING storage,
|
||||||
// without saving the existing storage first --- whoops!
|
// without saving the existing storage first --- whoops!
|
||||||
synchronized (storages) {
|
synchronized (storages) {
|
||||||
DiskStorageIfface storage = storages.get(file);
|
Storage storage = storages.get(this.file);
|
||||||
|
|
||||||
if (storage != null) {
|
if (storage != null) {
|
||||||
if (storage instanceof DiskStorage) {
|
if (storage instanceof DiskStorage) {
|
||||||
@ -141,13 +142,13 @@ class MakeStorage {
|
|||||||
((DiskStorage) storage).increaseReference();
|
((DiskStorage) storage).increaseReference();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new RuntimeException("Unable to change storage types for: " + file);
|
throw new RuntimeException("Unable to change storage types for: " + this.file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
try {
|
try {
|
||||||
storage = new DiskStorage(file, serializationManager);
|
storage = new DiskStorage(this.file, this.serializationManager, this.readOnly);
|
||||||
storages.put(file, storage);
|
storages.put(this.file, storage);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.error("Unable to open storage", e);
|
logger.error("Unable to open storage", e);
|
||||||
}
|
}
|
||||||
@ -156,21 +157,20 @@ class MakeStorage {
|
|||||||
return storage;
|
return storage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public
|
||||||
|
DiskMaker readOnly() {
|
||||||
|
this.readOnly = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static
|
public static
|
||||||
class MemoryMaker {
|
class MemoryMaker {
|
||||||
private SerializationManager serializationManager;
|
|
||||||
|
|
||||||
public
|
public
|
||||||
MemoryMaker serializer(SerializationManager serializationManager) {
|
MemoryStorage make() throws IOException {
|
||||||
this.serializationManager = serializationManager;
|
return new MemoryStorage();
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
MemoryStorage make() {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,12 +1,11 @@
|
|||||||
package dorkbox.util;
|
package dorkbox.util;
|
||||||
|
|
||||||
import com.esotericsoftware.kryo.Kryo;
|
import com.esotericsoftware.kryo.Kryo;
|
||||||
import com.esotericsoftware.kryo.Registration;
|
|
||||||
import com.esotericsoftware.kryo.Serializer;
|
import com.esotericsoftware.kryo.Serializer;
|
||||||
import com.esotericsoftware.kryo.io.Input;
|
import com.esotericsoftware.kryo.io.Input;
|
||||||
import com.esotericsoftware.kryo.io.Output;
|
import com.esotericsoftware.kryo.io.Output;
|
||||||
import dorkbox.util.storage.DiskStorageIfface;
|
import dorkbox.util.storage.Storage;
|
||||||
import dorkbox.util.storage.MakeStorage;
|
import dorkbox.util.storage.Store;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
import org.junit.runners.MethodSorters;
|
import org.junit.runners.MethodSorters;
|
||||||
@ -23,19 +22,6 @@ class StorageTest {
|
|||||||
private static final SerializationManager manager = new SerializationManager() {
|
private static final SerializationManager manager = new SerializationManager() {
|
||||||
Kryo kryo = new Kryo();
|
Kryo kryo = new Kryo();
|
||||||
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
boolean setReferences(final boolean references) {
|
|
||||||
kryo.setReferences(references);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
void setRegistrationRequired(final boolean registrationRequired) {
|
|
||||||
kryo.setRegistrationRequired(registrationRequired);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void register(final Class<?> clazz) {
|
void register(final Class<?> clazz) {
|
||||||
@ -50,16 +36,15 @@ class StorageTest {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
Registration register(final Class<?> type, final Serializer<?> serializer, final int id) {
|
void register(final Class<?> type, final Serializer<?> serializer, final int id) {
|
||||||
kryo.register(type, serializer, id);
|
kryo.register(type, serializer, id);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void write(final ByteBuf buffer, final Object message) {
|
void write(final ByteBuf buffer, final Object message) {
|
||||||
final Output output = new Output();
|
final Output output = new Output();
|
||||||
writeClassAndObject(output, message);
|
writeFullClassAndObject(output, message);
|
||||||
buffer.writeBytes(output.getBuffer());
|
buffer.writeBytes(output.getBuffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +54,7 @@ class StorageTest {
|
|||||||
final Input input = new Input();
|
final Input input = new Input();
|
||||||
buffer.readBytes(input.getBuffer());
|
buffer.readBytes(input.getBuffer());
|
||||||
|
|
||||||
final Object o = readClassAndObject(input);
|
final Object o = readFullClassAndObject(input);
|
||||||
buffer.skipBytes(input.position());
|
buffer.skipBytes(input.position());
|
||||||
|
|
||||||
return o;
|
return o;
|
||||||
@ -77,15 +62,26 @@ class StorageTest {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void writeClassAndObject(final Output output, final Object value) {
|
void writeFullClassAndObject(final Output output, final Object value) {
|
||||||
kryo.writeClassAndObject(output, value);
|
kryo.writeClassAndObject(output, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
Object readClassAndObject(final Input input) {
|
Object readFullClassAndObject(final Input input) {
|
||||||
return kryo.readClassAndObject(input);
|
return kryo.readClassAndObject(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public
|
||||||
|
Kryo take() throws InterruptedException {
|
||||||
|
return kryo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public
|
||||||
|
void release(final Kryo kryo) {
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static
|
static
|
||||||
@ -96,20 +92,20 @@ class StorageTest {
|
|||||||
@Before
|
@Before
|
||||||
public
|
public
|
||||||
void deleteDB() {
|
void deleteDB() {
|
||||||
MakeStorage.delete(TEST_DB);
|
Store.delete(TEST_DB);
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public
|
public
|
||||||
void delete2DB() {
|
void delete2DB() {
|
||||||
MakeStorage.delete(TEST_DB);
|
Store.delete(TEST_DB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public
|
public
|
||||||
void testCreateDB() throws IOException {
|
void testCreateDB() throws IOException {
|
||||||
DiskStorageIfface storage = MakeStorage.Disk()
|
Storage storage = Store.Disk()
|
||||||
.file(TEST_DB)
|
.file(TEST_DB)
|
||||||
.serializer(manager)
|
.serializer(manager)
|
||||||
.make();
|
.make();
|
||||||
@ -120,9 +116,9 @@ class StorageTest {
|
|||||||
Assert.assertEquals("count is not correct", numberOfRecords1, 0);
|
Assert.assertEquals("count is not correct", numberOfRecords1, 0);
|
||||||
Assert.assertEquals("size is not correct", size1, 208L); // NOTE this will change based on the data size added!
|
Assert.assertEquals("size is not correct", size1, 208L); // NOTE this will change based on the data size added!
|
||||||
|
|
||||||
MakeStorage.close(storage);
|
Store.close(storage);
|
||||||
|
|
||||||
storage = MakeStorage.Disk()
|
storage = Store.Disk()
|
||||||
.file(TEST_DB)
|
.file(TEST_DB)
|
||||||
.serializer(manager)
|
.serializer(manager)
|
||||||
.make();
|
.make();
|
||||||
@ -132,7 +128,7 @@ class StorageTest {
|
|||||||
Assert.assertEquals("Record count is not the same", numberOfRecords1, numberOfRecords2);
|
Assert.assertEquals("Record count is not the same", numberOfRecords1, numberOfRecords2);
|
||||||
Assert.assertEquals("size is not the same", size1, size2);
|
Assert.assertEquals("size is not the same", size1, size2);
|
||||||
|
|
||||||
MakeStorage.close(storage);
|
Store.close(storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -142,7 +138,7 @@ class StorageTest {
|
|||||||
int total = 100;
|
int total = 100;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DiskStorageIfface storage = MakeStorage.Disk()
|
Storage storage = Store.Disk()
|
||||||
.file(TEST_DB)
|
.file(TEST_DB)
|
||||||
.serializer(manager)
|
.serializer(manager)
|
||||||
.make();
|
.make();
|
||||||
@ -150,8 +146,8 @@ class StorageTest {
|
|||||||
add(storage, i);
|
add(storage, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
MakeStorage.close(storage);
|
Store.close(storage);
|
||||||
storage = MakeStorage.Disk()
|
storage = Store.Disk()
|
||||||
.file(TEST_DB)
|
.file(TEST_DB)
|
||||||
.serializer(manager)
|
.serializer(manager)
|
||||||
.make();
|
.make();
|
||||||
@ -162,7 +158,7 @@ class StorageTest {
|
|||||||
Assert.assertEquals("Object is not the same", record1Data, readRecord);
|
Assert.assertEquals("Object is not the same", record1Data, readRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
MakeStorage.close(storage);
|
Store.close(storage);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Assert.fail("Error!");
|
Assert.fail("Error!");
|
||||||
@ -175,7 +171,7 @@ class StorageTest {
|
|||||||
int total = 100;
|
int total = 100;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DiskStorageIfface storage = MakeStorage.Disk()
|
Storage storage = Store.Disk()
|
||||||
.file(TEST_DB)
|
.file(TEST_DB)
|
||||||
.serializer(manager)
|
.serializer(manager)
|
||||||
.make();
|
.make();
|
||||||
@ -189,9 +185,9 @@ class StorageTest {
|
|||||||
|
|
||||||
Assert.assertEquals("Object is not the same", addRecord, readData);
|
Assert.assertEquals("Object is not the same", addRecord, readData);
|
||||||
}
|
}
|
||||||
MakeStorage.close(storage);
|
Store.close(storage);
|
||||||
|
|
||||||
storage = MakeStorage.Disk()
|
storage = Store.Disk()
|
||||||
.file(TEST_DB)
|
.file(TEST_DB)
|
||||||
.serializer(manager)
|
.serializer(manager)
|
||||||
.make();
|
.make();
|
||||||
@ -208,7 +204,7 @@ class StorageTest {
|
|||||||
Assert.assertEquals("count is not correct", numberOfRecords1, 1);
|
Assert.assertEquals("count is not correct", numberOfRecords1, 1);
|
||||||
Assert.assertEquals("size is not correct", size1, 235L); // NOTE this will change based on the data size added!
|
Assert.assertEquals("size is not correct", size1, 235L); // NOTE this will change based on the data size added!
|
||||||
|
|
||||||
MakeStorage.close(storage);
|
Store.close(storage);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Assert.fail("Error!");
|
Assert.fail("Error!");
|
||||||
@ -221,7 +217,7 @@ class StorageTest {
|
|||||||
int total = 100;
|
int total = 100;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DiskStorageIfface storage = MakeStorage.Disk()
|
Storage storage = Store.Disk()
|
||||||
.file(TEST_DB)
|
.file(TEST_DB)
|
||||||
.serializer(manager)
|
.serializer(manager)
|
||||||
.make();
|
.make();
|
||||||
@ -241,9 +237,9 @@ class StorageTest {
|
|||||||
Assert.assertEquals("Object is not the same", record1Data, readRecord);
|
Assert.assertEquals("Object is not the same", record1Data, readRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
MakeStorage.close(storage);
|
Store.close(storage);
|
||||||
|
|
||||||
storage = MakeStorage.Disk()
|
storage = Store.Disk()
|
||||||
.file(TEST_DB)
|
.file(TEST_DB)
|
||||||
.serializer(manager)
|
.serializer(manager)
|
||||||
.make();
|
.make();
|
||||||
@ -254,7 +250,7 @@ class StorageTest {
|
|||||||
Assert.assertEquals("Object is not the same", dataCheck, readRecord);
|
Assert.assertEquals("Object is not the same", dataCheck, readRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
MakeStorage.close(storage);
|
Store.close(storage);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Assert.fail("Error!");
|
Assert.fail("Error!");
|
||||||
@ -267,7 +263,7 @@ class StorageTest {
|
|||||||
int total = 100;
|
int total = 100;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DiskStorageIfface storage = MakeStorage.Disk()
|
Storage storage = Store.Disk()
|
||||||
.file(TEST_DB)
|
.file(TEST_DB)
|
||||||
.serializer(manager)
|
.serializer(manager)
|
||||||
.make();
|
.make();
|
||||||
@ -282,9 +278,9 @@ class StorageTest {
|
|||||||
Assert.assertEquals("Object is not the same", record1Data, readRecord);
|
Assert.assertEquals("Object is not the same", record1Data, readRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
MakeStorage.close(storage);
|
Store.close(storage);
|
||||||
|
|
||||||
storage = MakeStorage.Disk()
|
storage = Store.Disk()
|
||||||
.file(TEST_DB)
|
.file(TEST_DB)
|
||||||
.serializer(manager)
|
.serializer(manager)
|
||||||
.make();
|
.make();
|
||||||
@ -295,7 +291,7 @@ class StorageTest {
|
|||||||
Assert.assertEquals("Object is not the same", dataCheck, readRecord);
|
Assert.assertEquals("Object is not the same", dataCheck, readRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
MakeStorage.close(storage);
|
Store.close(storage);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Assert.fail("Error!");
|
Assert.fail("Error!");
|
||||||
@ -308,7 +304,7 @@ class StorageTest {
|
|||||||
int total = 100;
|
int total = 100;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DiskStorageIfface storage = MakeStorage.Disk()
|
Storage storage = Store.Disk()
|
||||||
.file(TEST_DB)
|
.file(TEST_DB)
|
||||||
.serializer(manager)
|
.serializer(manager)
|
||||||
.make();
|
.make();
|
||||||
@ -318,9 +314,9 @@ class StorageTest {
|
|||||||
|
|
||||||
Assert.assertEquals("Object is not the same", addRecord, readRecord);
|
Assert.assertEquals("Object is not the same", addRecord, readRecord);
|
||||||
}
|
}
|
||||||
MakeStorage.close(storage);
|
Store.close(storage);
|
||||||
|
|
||||||
storage = MakeStorage.Disk()
|
storage = Store.Disk()
|
||||||
.file(TEST_DB)
|
.file(TEST_DB)
|
||||||
.serializer(manager)
|
.serializer(manager)
|
||||||
.make();
|
.make();
|
||||||
@ -342,8 +338,8 @@ class StorageTest {
|
|||||||
storage.load(createKey, data2);
|
storage.load(createKey, data2);
|
||||||
Assert.assertEquals("Object is not the same", data, data2);
|
Assert.assertEquals("Object is not the same", data, data2);
|
||||||
|
|
||||||
MakeStorage.close(storage);
|
Store.close(storage);
|
||||||
storage = MakeStorage.Disk()
|
storage = Store.Disk()
|
||||||
.file(TEST_DB)
|
.file(TEST_DB)
|
||||||
.serializer(manager)
|
.serializer(manager)
|
||||||
.make();
|
.make();
|
||||||
@ -352,7 +348,7 @@ class StorageTest {
|
|||||||
storage.load(createKey, data2);
|
storage.load(createKey, data2);
|
||||||
Assert.assertEquals("Object is not the same", data, data2);
|
Assert.assertEquals("Object is not the same", data, data2);
|
||||||
|
|
||||||
MakeStorage.close(storage);
|
Store.close(storage);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Assert.fail("Error!");
|
Assert.fail("Error!");
|
||||||
@ -366,7 +362,7 @@ class StorageTest {
|
|||||||
int total = 100;
|
int total = 100;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DiskStorageIfface storage = MakeStorage.Disk()
|
Storage storage = Store.Disk()
|
||||||
.file(TEST_DB)
|
.file(TEST_DB)
|
||||||
.serializer(manager)
|
.serializer(manager)
|
||||||
.make();
|
.make();
|
||||||
@ -376,9 +372,9 @@ class StorageTest {
|
|||||||
|
|
||||||
Assert.assertEquals("Object is not the same", addRecord, readRecord);
|
Assert.assertEquals("Object is not the same", addRecord, readRecord);
|
||||||
}
|
}
|
||||||
MakeStorage.close(storage);
|
Store.close(storage);
|
||||||
|
|
||||||
storage = MakeStorage.Disk()
|
storage = Store.Disk()
|
||||||
.file(TEST_DB)
|
.file(TEST_DB)
|
||||||
.serializer(manager)
|
.serializer(manager)
|
||||||
.make();
|
.make();
|
||||||
@ -408,9 +404,9 @@ class StorageTest {
|
|||||||
|
|
||||||
Assert.assertEquals("Object is not the same", dataCheck, addRecord);
|
Assert.assertEquals("Object is not the same", dataCheck, addRecord);
|
||||||
|
|
||||||
MakeStorage.close(storage);
|
Store.close(storage);
|
||||||
|
|
||||||
storage = MakeStorage.Disk()
|
storage = Store.Disk()
|
||||||
.file(TEST_DB)
|
.file(TEST_DB)
|
||||||
.serializer(manager)
|
.serializer(manager)
|
||||||
.make();
|
.make();
|
||||||
@ -437,7 +433,7 @@ class StorageTest {
|
|||||||
int total = 100;
|
int total = 100;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DiskStorageIfface storage = MakeStorage.Disk()
|
Storage storage = Store.Disk()
|
||||||
.file(TEST_DB)
|
.file(TEST_DB)
|
||||||
.serializer(manager)
|
.serializer(manager)
|
||||||
.make();
|
.make();
|
||||||
@ -447,9 +443,9 @@ class StorageTest {
|
|||||||
|
|
||||||
Assert.assertEquals("Object is not the same", addRecord, readRecord);
|
Assert.assertEquals("Object is not the same", addRecord, readRecord);
|
||||||
}
|
}
|
||||||
MakeStorage.close(storage);
|
Store.close(storage);
|
||||||
|
|
||||||
storage = MakeStorage.Disk()
|
storage = Store.Disk()
|
||||||
.file(TEST_DB)
|
.file(TEST_DB)
|
||||||
.serializer(manager)
|
.serializer(manager)
|
||||||
.make();
|
.make();
|
||||||
@ -458,8 +454,8 @@ class StorageTest {
|
|||||||
String readRecord = readRecord(storage, 3);
|
String readRecord = readRecord(storage, 3);
|
||||||
Assert.assertEquals("Object is not the same", updateRecord, readRecord);
|
Assert.assertEquals("Object is not the same", updateRecord, readRecord);
|
||||||
|
|
||||||
MakeStorage.close(storage);
|
Store.close(storage);
|
||||||
storage = MakeStorage.Disk()
|
storage = Store.Disk()
|
||||||
.file(TEST_DB)
|
.file(TEST_DB)
|
||||||
.serializer(manager)
|
.serializer(manager)
|
||||||
.make();
|
.make();
|
||||||
@ -469,8 +465,8 @@ class StorageTest {
|
|||||||
|
|
||||||
updateRecord = updateRecord(storage, 3, createData(3));
|
updateRecord = updateRecord(storage, 3, createData(3));
|
||||||
|
|
||||||
MakeStorage.close(storage);
|
Store.close(storage);
|
||||||
storage = MakeStorage.Disk()
|
storage = Store.Disk()
|
||||||
.file(TEST_DB)
|
.file(TEST_DB)
|
||||||
.serializer(manager)
|
.serializer(manager)
|
||||||
.make();
|
.make();
|
||||||
@ -478,8 +474,8 @@ class StorageTest {
|
|||||||
readRecord = readRecord(storage, 3);
|
readRecord = readRecord(storage, 3);
|
||||||
Assert.assertEquals("Object is not the same", updateRecord, readRecord);
|
Assert.assertEquals("Object is not the same", updateRecord, readRecord);
|
||||||
|
|
||||||
MakeStorage.close(storage);
|
Store.close(storage);
|
||||||
storage = MakeStorage.Disk()
|
storage = Store.Disk()
|
||||||
.file(TEST_DB)
|
.file(TEST_DB)
|
||||||
.serializer(manager)
|
.serializer(manager)
|
||||||
.make();
|
.make();
|
||||||
@ -488,7 +484,7 @@ class StorageTest {
|
|||||||
readRecord = readRecord(storage, 0);
|
readRecord = readRecord(storage, 0);
|
||||||
Assert.assertEquals("Object is not the same", updateRecord, readRecord);
|
Assert.assertEquals("Object is not the same", updateRecord, readRecord);
|
||||||
|
|
||||||
MakeStorage.close(storage);
|
Store.close(storage);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Assert.fail("Error!");
|
Assert.fail("Error!");
|
||||||
@ -502,7 +498,7 @@ class StorageTest {
|
|||||||
int total = 100;
|
int total = 100;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DiskStorageIfface storage = MakeStorage.Disk()
|
Storage storage = Store.Disk()
|
||||||
.file(TEST_DB)
|
.file(TEST_DB)
|
||||||
.serializer(manager)
|
.serializer(manager)
|
||||||
.make();
|
.make();
|
||||||
@ -513,12 +509,12 @@ class StorageTest {
|
|||||||
|
|
||||||
storage.put(createKey, data);
|
storage.put(createKey, data);
|
||||||
}
|
}
|
||||||
MakeStorage.close(storage);
|
Store.close(storage);
|
||||||
|
|
||||||
Data data = new Data();
|
Data data = new Data();
|
||||||
makeData(data);
|
makeData(data);
|
||||||
|
|
||||||
storage = MakeStorage.Disk()
|
storage = Store.Disk()
|
||||||
.file(TEST_DB)
|
.file(TEST_DB)
|
||||||
.serializer(manager)
|
.serializer(manager)
|
||||||
.make();
|
.make();
|
||||||
@ -529,7 +525,7 @@ class StorageTest {
|
|||||||
storage.load(createKey, data2);
|
storage.load(createKey, data2);
|
||||||
Assert.assertEquals("Object is not the same", data, data2);
|
Assert.assertEquals("Object is not the same", data, data2);
|
||||||
}
|
}
|
||||||
MakeStorage.close(storage);
|
Store.close(storage);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Assert.fail("Error!");
|
Assert.fail("Error!");
|
||||||
@ -544,7 +540,7 @@ class StorageTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static
|
public static
|
||||||
String add(DiskStorageIfface storage, int number) throws IOException {
|
String add(Storage storage, int number) throws IOException {
|
||||||
String record1Data = createData(number);
|
String record1Data = createData(number);
|
||||||
String record1Key = createKey(number);
|
String record1Key = createKey(number);
|
||||||
|
|
||||||
@ -554,7 +550,7 @@ class StorageTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static
|
public static
|
||||||
String readRecord(DiskStorageIfface storage, int number) throws ClassNotFoundException, IOException {
|
String readRecord(Storage storage, int number) throws ClassNotFoundException, IOException {
|
||||||
String record1Key = createKey(number);
|
String record1Key = createKey(number);
|
||||||
|
|
||||||
log("reading record " + number + "...");
|
log("reading record " + number + "...");
|
||||||
@ -565,7 +561,7 @@ class StorageTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static
|
public static
|
||||||
void deleteRecord(DiskStorageIfface storage, int nNumber) throws ClassNotFoundException, IOException {
|
void deleteRecord(Storage storage, int nNumber) throws ClassNotFoundException, IOException {
|
||||||
String record1Key = createKey(nNumber);
|
String record1Key = createKey(nNumber);
|
||||||
|
|
||||||
log("deleting record " + nNumber + "...");
|
log("deleting record " + nNumber + "...");
|
||||||
@ -573,7 +569,7 @@ class StorageTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static
|
private static
|
||||||
String updateRecord(DiskStorageIfface storage, int number, String newData) throws IOException {
|
String updateRecord(Storage storage, int number, String newData) throws IOException {
|
||||||
String record1Key = createKey(number);
|
String record1Key = createKey(number);
|
||||||
|
|
||||||
log("updating record " + number + "...");
|
log("updating record " + number + "...");
|
||||||
|
@ -35,20 +35,13 @@
|
|||||||
*/
|
*/
|
||||||
package dorkbox.util;
|
package dorkbox.util;
|
||||||
|
|
||||||
import static dorkbox.util.bytes.Unsigned.ubyte;
|
import dorkbox.util.bytes.UByte;
|
||||||
import static junit.framework.Assert.assertEquals;
|
|
||||||
import static junit.framework.Assert.assertTrue;
|
|
||||||
import static junit.framework.Assert.fail;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.ObjectInputStream;
|
|
||||||
import java.io.ObjectOutputStream;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import dorkbox.util.bytes.UByte;
|
import java.io.*;
|
||||||
|
|
||||||
|
import static dorkbox.util.bytes.Unsigned.ubyte;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
public class UByteTest {
|
public class UByteTest {
|
||||||
|
|
||||||
|
@ -1,26 +1,26 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2011-2013, Lukas Eder, lukas.eder@gmail.com
|
* Copyright (c) 2011-2013, Lukas Eder, lukas.eder@gmail.com
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
* <p/>
|
||||||
* This software is licensed to you under the Apache License, Version 2.0
|
* This software is licensed to you under the Apache License, Version 2.0
|
||||||
* (the "License"); You may obtain a copy of the License at
|
* (the "License"); You may obtain a copy of the License at
|
||||||
*
|
* <p/>
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
* <p/>
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
*
|
* <p/>
|
||||||
* . Redistributions of source code must retain the above copyright notice, this
|
* . Redistributions of source code must retain the above copyright notice, this
|
||||||
* list of conditions and the following disclaimer.
|
* list of conditions and the following disclaimer.
|
||||||
*
|
* <p/>
|
||||||
* . Redistributions in binary form must reproduce the above copyright notice,
|
* . Redistributions in binary form must reproduce the above copyright notice,
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
* and/or other materials provided with the distribution.
|
* and/or other materials provided with the distribution.
|
||||||
*
|
* <p/>
|
||||||
* . Neither the name "jOOU" nor the names of its contributors may be
|
* . Neither the name "jOOU" nor the names of its contributors may be
|
||||||
* used to endorse or promote products derived from this software without
|
* used to endorse or promote products derived from this software without
|
||||||
* specific prior written permission.
|
* specific prior written permission.
|
||||||
*
|
* <p/>
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
@ -35,39 +35,33 @@
|
|||||||
*/
|
*/
|
||||||
package dorkbox.util;
|
package dorkbox.util;
|
||||||
|
|
||||||
import static dorkbox.util.bytes.Unsigned.uint;
|
import dorkbox.util.bytes.UInteger;
|
||||||
import static junit.framework.Assert.assertEquals;
|
|
||||||
import static junit.framework.Assert.assertFalse;
|
|
||||||
import static junit.framework.Assert.assertTrue;
|
|
||||||
import static junit.framework.Assert.fail;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.ObjectInputStream;
|
|
||||||
import java.io.ObjectOutputStream;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import dorkbox.util.bytes.UInteger;
|
import java.io.*;
|
||||||
|
|
||||||
public class UIntegerTest {
|
import static dorkbox.util.bytes.Unsigned.uint;
|
||||||
private static final int CACHE_SIZE=256;
|
import static org.junit.Assert.*;
|
||||||
private static final int NEAR_MISS_OFFSET=4;
|
|
||||||
|
public
|
||||||
|
class UIntegerTest {
|
||||||
|
private static final int CACHE_SIZE = 256;
|
||||||
|
private static final int NEAR_MISS_OFFSET = 4;
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
@Test
|
@Test
|
||||||
public void testValueOfLong() {
|
public
|
||||||
for(long l=01; l<=UInteger.MAX_VALUE; l<<=1) {
|
void testValueOfLong() {
|
||||||
assertEquals(l , uint(l).longValue());
|
for (long l = 01; l <= UInteger.MAX_VALUE; l <<= 1) {
|
||||||
|
assertEquals(l, uint(l).longValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
@Test
|
@Test
|
||||||
public void testValueOfLongCachingShift() {
|
public
|
||||||
for(long l=01; l<CACHE_SIZE; l<<=1)
|
void testValueOfLongCachingShift() {
|
||||||
{
|
for (long l = 01; l < CACHE_SIZE; l <<= 1) {
|
||||||
UInteger a = uint(l);
|
UInteger a = uint(l);
|
||||||
UInteger b = uint(l);
|
UInteger b = uint(l);
|
||||||
assertTrue(a == b);
|
assertTrue(a == b);
|
||||||
@ -76,9 +70,9 @@ public class UIntegerTest {
|
|||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
@Test
|
@Test
|
||||||
public void testValueOfLongCachingNear() {
|
public
|
||||||
for(long l=CACHE_SIZE-NEAR_MISS_OFFSET; l<CACHE_SIZE; l++)
|
void testValueOfLongCachingNear() {
|
||||||
{
|
for (long l = CACHE_SIZE - NEAR_MISS_OFFSET; l < CACHE_SIZE; l++) {
|
||||||
UInteger a = uint(l);
|
UInteger a = uint(l);
|
||||||
UInteger b = uint(l);
|
UInteger b = uint(l);
|
||||||
assertTrue(a == b);
|
assertTrue(a == b);
|
||||||
@ -87,9 +81,9 @@ public class UIntegerTest {
|
|||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
@Test
|
@Test
|
||||||
public void testValueOfLongNoCachingShift() {
|
public
|
||||||
for(long l=CACHE_SIZE; l<=CACHE_SIZE; l<<=1)
|
void testValueOfLongNoCachingShift() {
|
||||||
{
|
for (long l = CACHE_SIZE; l <= CACHE_SIZE; l <<= 1) {
|
||||||
UInteger a = uint(l);
|
UInteger a = uint(l);
|
||||||
UInteger b = uint(l);
|
UInteger b = uint(l);
|
||||||
assertFalse(a == b);
|
assertFalse(a == b);
|
||||||
@ -98,9 +92,9 @@ public class UIntegerTest {
|
|||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
@Test
|
@Test
|
||||||
public void testValueOfLongNoCachingNear() {
|
public
|
||||||
for(long l=CACHE_SIZE; l<=CACHE_SIZE+NEAR_MISS_OFFSET; l++)
|
void testValueOfLongNoCachingNear() {
|
||||||
{
|
for (long l = CACHE_SIZE; l <= CACHE_SIZE + NEAR_MISS_OFFSET; l++) {
|
||||||
UInteger a = uint(l);
|
UInteger a = uint(l);
|
||||||
UInteger b = uint(l);
|
UInteger b = uint(l);
|
||||||
assertFalse(a == b);
|
assertFalse(a == b);
|
||||||
@ -109,22 +103,24 @@ public class UIntegerTest {
|
|||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
@Test
|
@Test
|
||||||
public void testValueOfLongInvalid() {
|
public
|
||||||
|
void testValueOfLongInvalid() {
|
||||||
try {
|
try {
|
||||||
uint(UInteger.MIN_VALUE - 1);
|
uint(UInteger.MIN_VALUE - 1);
|
||||||
fail();
|
fail();
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
}
|
}
|
||||||
catch (NumberFormatException e) {}
|
|
||||||
try {
|
try {
|
||||||
uint(UInteger.MAX_VALUE + 1);
|
uint(UInteger.MAX_VALUE + 1);
|
||||||
fail();
|
fail();
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
}
|
}
|
||||||
catch (NumberFormatException e) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
@Test
|
@Test
|
||||||
public void testSerializeDeserialize() throws ClassNotFoundException, IOException {
|
public
|
||||||
|
void testSerializeDeserialize() throws ClassNotFoundException, IOException {
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||||
ByteArrayInputStream bais;
|
ByteArrayInputStream bais;
|
||||||
|
@ -35,28 +35,20 @@
|
|||||||
*/
|
*/
|
||||||
package dorkbox.util;
|
package dorkbox.util;
|
||||||
|
|
||||||
import static dorkbox.util.bytes.ULong.MAX_VALUE_LONG;
|
import dorkbox.util.bytes.*;
|
||||||
import static dorkbox.util.bytes.Unsigned.ubyte;
|
import org.junit.Test;
|
||||||
import static dorkbox.util.bytes.Unsigned.uint;
|
|
||||||
import static dorkbox.util.bytes.Unsigned.ulong;
|
|
||||||
import static dorkbox.util.bytes.Unsigned.ushort;
|
|
||||||
import static java.math.BigInteger.ONE;
|
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
import static junit.framework.Assert.assertEquals;
|
|
||||||
import static junit.framework.Assert.assertFalse;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.junit.Test;
|
import static dorkbox.util.bytes.ULong.MAX_VALUE_LONG;
|
||||||
|
import static dorkbox.util.bytes.Unsigned.*;
|
||||||
import dorkbox.util.bytes.UByte;
|
import static java.math.BigInteger.ONE;
|
||||||
import dorkbox.util.bytes.UInteger;
|
import static java.util.Arrays.asList;
|
||||||
import dorkbox.util.bytes.ULong;
|
import static org.junit.Assert.assertEquals;
|
||||||
import dorkbox.util.bytes.UNumber;
|
import static org.junit.Assert.assertFalse;
|
||||||
import dorkbox.util.bytes.UShort;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Lukas Eder
|
* @author Lukas Eder
|
||||||
|
Loading…
Reference in New Issue
Block a user