Updated storage info. Updated netty, passes all unit tests

This commit is contained in:
nathan 2015-07-20 14:18:51 +02:00
parent ee6c01e371
commit 7665e116ed
18 changed files with 888 additions and 523 deletions

View File

@ -6,7 +6,6 @@
<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-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/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"/>
@ -23,9 +22,10 @@
<attribute name="javadoc_location" value="jar:platform:/resource/Dependencies/netty/netty-all-4.1.0-javadoc.zip!/"/>
</attributes>
</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/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/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"/>
</classpath>

View 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);
}

View File

@ -25,7 +25,8 @@ import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Sys {
public
class Sys {
public static final int javaVersion = getJavaVersion();
public static final boolean isAndroid = getIsAndroid();
@ -34,9 +35,10 @@ public class Sys {
public static final int GIGABYTE = 1024 * MEGABYTE;
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();
eraseString(string);
@ -44,7 +46,8 @@ public class Sys {
return charArray;
}
private static boolean getIsAndroid() {
private static
boolean getIsAndroid() {
try {
Class.forName("android.os.Process");
return true;
@ -53,31 +56,41 @@ public class Sys {
}
}
private static int getJavaVersion() {
private static
int getJavaVersion() {
String fullJavaVersion = System.getProperty("java.version");
// Converts a java version string, such as "1.7u45", and converts it into 7
char versionChar;
if (fullJavaVersion.startsWith("1.")) {
versionChar = fullJavaVersion.charAt(2);
} else {
}
else {
versionChar = fullJavaVersion.charAt(0);
}
switch (versionChar) {
case '4': return 4;
case '5': return 5;
case '6': return 6;
case '7': return 7;
case '8': return 8;
case '9': return 9;
default: return -1;
case '4':
return 4;
case '5':
return 5;
case '6':
return 6;
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 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/
*
* <p/>
* Replaces all occurrences of keys of the given map in the given string
* with the associated value in that map.
*
* <p/>
* This method is semantically the same as calling
* {@link String#replace(CharSequence, CharSequence)} for each of the
* 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
* expressions internally and results in many String object allocations when
* applied iteratively.
*
* <p/>
* The order in which replacements are applied depends on the order of the
* 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);
for (Entry<String, String> entry : replacements.entrySet()) {
String key = entry.getKey();
@ -158,9 +172,10 @@ public class Sys {
*
* @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();
for (int i=0;i<length;i++) {
for (int i = 0; i < length; i++) {
if (string.charAt(i) == c) {
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) {
return String.format("%2.2fTB", (float) size / TERABYTE);
}
@ -190,7 +206,8 @@ public class Sys {
/**
* Convenient close for a stream.
*/
public static void close(InputStream inputStream) {
public static
void close(InputStream inputStream) {
if (inputStream != null) {
try {
inputStream.close();
@ -204,7 +221,8 @@ public class Sys {
/**
* Convenient close for a stream.
*/
public static void close(OutputStream outputStream) {
public static
void close(OutputStream outputStream) {
if (outputStream != null) {
try {
outputStream.close();
@ -218,7 +236,8 @@ public class Sys {
/**
* Convenient close for a Reader.
*/
public static void close(Reader inputReader) {
public static
void close(Reader inputReader) {
if (inputReader != null) {
try {
inputReader.close();
@ -232,7 +251,8 @@ public class Sys {
/**
* Convenient close for a Writer.
*/
public static void close(Writer outputWriter) {
public static
void close(Writer outputWriter) {
if (outputWriter != null) {
try {
outputWriter.close();
@ -245,10 +265,11 @@ public class Sys {
/**
* Copy the contents of the input stream to the output stream.
* <p>
* <p/>
* 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];
int read = 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.
*/
public static byte[] getBytesFromStream(InputStream inputStream) throws IOException {
public static
byte[] getBytesFromStream(InputStream inputStream) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream(8192);
byte[] buffer = new byte[4096];
@ -275,11 +297,13 @@ public class Sys {
return baos.toByteArray();
}
public static final byte[] copyBytes(byte[] src) {
public static final
byte[] copyBytes(byte[] src) {
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;
byte[] b = new byte[length];
@ -287,7 +311,8 @@ public class Sys {
return b;
}
public static final byte[] concatBytes(byte[]... arrayBytes) {
public static final
byte[] concatBytes(byte[]... arrayBytes) {
int length = 0;
for (byte[] bytes : arrayBytes) {
length += bytes.length;
@ -304,8 +329,11 @@ public class Sys {
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) {
return null;
}
@ -322,8 +350,11 @@ public class Sys {
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());
SHA256Digest sha256 = new SHA256Digest();
@ -334,8 +365,11 @@ public class Sys {
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();
byte[] hashBytes = new byte[sha256.getDigestSize()];
@ -345,20 +379,24 @@ public class Sys {
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.
byte[] bytes = new byte[text.length*2];
for(int i=0; i<text.length; i++) {
bytes[2*i] = (byte) (text[i] >> 8);
bytes[2*i+1] = (byte) text[i];
byte[] bytes = new byte[text.length * 2];
for (int i = 0; i < text.length; i++) {
bytes[2 * i] = (byte) (text[i] >> 8);
bytes[2 * i + 1] = (byte) text[i];
}
return bytes;
}
public static final byte[] intsToBytes(int[] ints) {
public static final
byte[] intsToBytes(int[] ints) {
int length = ints.length;
byte[] bytes = new byte[length];
@ -369,13 +407,14 @@ public class Sys {
return new byte[length];
}
bytes[i] = (byte)intValue;
bytes[i] = (byte) intValue;
}
return bytes;
}
public static final int[] bytesToInts(byte[] bytes) {
public static final
int[] bytesToInts(byte[] bytes) {
int length = bytes.length;
int[] ints = new int[length];
@ -386,11 +425,13 @@ public class Sys {
return ints;
}
public static final String bytesToHex(byte[] bytes) {
public static final
String bytesToHex(byte[] bytes) {
return bytesToHex(bytes, false);
}
public static final String bytesToHex(byte[] bytes, boolean padding) {
public static final
String bytesToHex(byte[] bytes, boolean padding) {
if (padding) {
char[] hexString = new char[3 * bytes.length];
int j = 0;
@ -402,7 +443,8 @@ public class Sys {
}
return new String(hexString);
} else {
}
else {
char[] hexString = new char[2 * bytes.length];
int j = 0;
@ -419,47 +461,48 @@ public class Sys {
* Converts an ASCII character representing a hexadecimal
* value into its integer equivalent.
*/
public static final int hexByteToInt(byte b) {
public static final
int hexByteToInt(byte b) {
switch (b) {
case '0' :
case '0':
return 0;
case '1' :
case '1':
return 1;
case '2' :
case '2':
return 2;
case '3' :
case '3':
return 3;
case '4' :
case '4':
return 4;
case '5' :
case '5':
return 5;
case '6' :
case '6':
return 6;
case '7' :
case '7':
return 7;
case '8' :
case '8':
return 8;
case '9' :
case '9':
return 9;
case 'A' :
case 'a' :
case 'A':
case 'a':
return 10;
case 'B' :
case 'b' :
case 'B':
case 'b':
return 11;
case 'C' :
case 'c' :
case 'C':
case 'c':
return 12;
case 'D' :
case 'd' :
case 'D':
case 'd':
return 13;
case 'E' :
case 'e' :
case 'E':
case 'e':
return 14;
case 'F' :
case 'f' :
case 'F':
case 'f':
return 15;
default :
default:
throw new IllegalArgumentException("Error decoding byte");
}
}
@ -467,7 +510,8 @@ public class Sys {
/**
* 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 & 0x0F00) >> 8]);
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
* hexadecimal characters.
*
* @param bytes
* byte array to convert
* @param bytes byte array to convert
* @return a string representation of the byte array as a series of
* hexadecimal characters
*/
public static final String toHexString(byte[] bytes) {
public static final
String toHexString(byte[] bytes) {
char[] hexString = new char[2 * bytes.length];
int j = 0;
@ -501,11 +545,12 @@ public class Sys {
* @param originalArray this is the base of the XOR operation.
* @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 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
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;
for (String s : array) {
byte[] bytes = s.getBytes();
@ -526,7 +572,7 @@ public class Sys {
return new byte[0];
}
byte[] bytes = new byte[length+array.size()];
byte[] bytes = new byte[length + array.size()];
length = 0;
for (String s : array) {
@ -539,18 +585,19 @@ public class Sys {
return bytes;
}
public static final ArrayList<String> decodeStringArray(byte[] bytes) {
public static final
ArrayList<String> decodeStringArray(byte[] bytes) {
int length = bytes.length;
int position = 0;
byte token = (byte) 0x01;
ArrayList<String> list = new ArrayList<String>(0);
int last = 0;
while (last+position < length) {
byte b = bytes[last+position++];
if (b == token ) {
byte[] xx = new byte[position-1];
System.arraycopy(bytes, last, xx, 0, position-1);
while (last + position < length) {
byte b = bytes[last + position++];
if (b == token) {
byte[] xx = new byte[position - 1];
System.arraycopy(bytes, last, xx, 0, position - 1);
list.add(new String(xx));
last += position;
position = 0;
@ -561,32 +608,35 @@ public class Sys {
return list;
}
public static String printArrayRaw(byte[] bytes) {
public static
String printArrayRaw(byte[] bytes) {
return printArrayRaw(bytes, 0);
}
public static String printArrayRaw(byte[] bytes, int lineLength) {
public static
String printArrayRaw(byte[] bytes, int lineLength) {
if (lineLength > 0) {
int mod = lineLength;
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++) {
builder.append(bytes[i]);
if (i < comma) {
builder.append(",");
}
if (i > 0 && i%mod == 0) {
if (i > 0 && i % mod == 0) {
builder.append(OS.LINE_SEPARATOR);
}
}
return builder.toString();
} else {
}
else {
int length = bytes.length;
int comma = length-1;
int comma = length - 1;
StringBuilder builder = new StringBuilder(length + length);
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);
}
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);
}
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) {
System.err.println("Bytes: " + length);
}
int comma = length-1;
int comma = length - 1;
StringBuilder builder;
if (lineLength > 0) {
builder = new StringBuilder(length + comma + length/lineLength + 2);
} else {
builder = new StringBuilder(length + comma + length / lineLength + 2);
}
else {
builder = new StringBuilder(length + comma + 2);
}
builder.append("{");
@ -628,7 +682,7 @@ public class Sys {
if (i < comma) {
builder.append(",");
}
if (i > 0 && lineLength > 0 && i%lineLength == 0) {
if (i > 0 && lineLength > 0 && i % lineLength == 0) {
builder.append(OS.LINE_SEPARATOR);
}
}
@ -658,17 +712,18 @@ public class Sys {
* <p/>
*
* @throws UnknownHostException If the LAN address of the machine cannot be found.
*
* <p/>
* From: https://issues.apache.org/jira/browse/JCS-40
*/
public static InetAddress getLocalHostLanAddress() throws UnknownHostException {
public static
InetAddress getLocalHostLanAddress() throws UnknownHostException {
try {
InetAddress candidateAddress = null;
// 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();
// 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();
if (!inetAddr.isLoopbackAddress()) {
@ -700,8 +755,7 @@ public class Sys {
throw new UnknownHostException("The JDK InetAddress.getLocalHost() method unexpectedly returned null.");
}
return jdkSuppliedAddress;
}
catch (Exception e) {
} catch (Exception e) {
UnknownHostException unknownHostException = new UnknownHostException("Failed to determine LAN address: " + e);
unknownHostException.initCause(e);
throw unknownHostException;
@ -711,44 +765,39 @@ public class Sys {
/**
* 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>
*
* @return the public IP address if found, or null if it didn't find it
*/
@Deprecated
public static String getPublicIpViaHttp() {
public static
String getPublicIpViaHttp() {
// method 1: use DNS servers
// dig +short myip.opendns.com @resolver1.opendns.com
// method 2: use public http servers
final String websites[] = {
"http://ip.dorkbox.com/",
"http://ip.javalauncher.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/",
};
final String websites[] = {"http://ip.dorkbox.com/", "http://ip.javalauncher.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.
for (int i=0;i<websites.length;i++) {
for (int i = 0; i < websites.length; i++) {
try {
URL autoIP = new URL(websites[i]);
BufferedReader in = new BufferedReader(new InputStreamReader(autoIP.openStream()));
String response = in.readLine().trim();
String response = in.readLine()
.trim();
in.close();
Pattern pattern = Pattern.compile("\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b");
Matcher matcher = pattern.matcher(response);
if (matcher.find()) {
String IP = matcher.group().trim();
String IP = matcher.group()
.trim();
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
*
* @return null if not found
*/
public static InetAddress getIpAddressesFromNic() {
public static
InetAddress getIpAddressesFromNic() {
try {
Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
while (nets.hasMoreElements()) {

View File

@ -15,38 +15,34 @@
*/
package dorkbox.util.bytes;
import org.bouncycastle.crypto.digests.SHA256Digest;
import java.nio.charset.Charset;
import java.util.Arrays;
/**
* Necessary to provide equals and hashcode methods on a byte arrays, if they are to be used as keys in a map/set/etc
*/
public final class ByteArrayWrapper {
private final byte[] data;
public final
class ByteArrayWrapper {
public static final Charset UTF_8 = Charset.forName("UTF-8");
private byte[] data;
private Integer hashCode;
/**
* 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) {
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);
private
ByteArrayWrapper() {
// this is necessary for kryo
}
/**
* 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.
* 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) {
throw new NullPointerException();
}
@ -56,27 +52,61 @@ public final class ByteArrayWrapper {
this.data = new byte[length];
// copy so it's immutable as a key.
System.arraycopy(data, 0, this.data, 0, length);
} else {
}
else {
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;
}
@Override
public boolean equals(Object other) {
if (!(other instanceof ByteArrayWrapper)) {
return false;
}
// CANNOT be null, so we don't have to null check!
return Arrays.equals(this.data, ((ByteArrayWrapper) other).data);
}
@Override
public int hashCode() {
public
int hashCode() {
// might be null for a thread because it's stale. who cares, get the value again
Integer hashCode = this.hashCode;
if (hashCode == null) {
@ -87,7 +117,19 @@ public final class ByteArrayWrapper {
}
@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);
}
}

View File

@ -1,29 +1,31 @@
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.Serializer;
import com.esotericsoftware.kryo.io.Input;
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.
*/
public class EccPublicKeySerializer extends Serializer<ECPublicKeyParameters> {
public
class EccPublicKeySerializer extends Serializer<ECPublicKeyParameters> {
@Override
public void write(Kryo kryo, Output output, ECPublicKeyParameters key) {
public
void write(Kryo kryo, Output output, ECPublicKeyParameters key) {
write(output, key);
}
public static void write(Output output, ECPublicKeyParameters key) {
public static
void write(Output output, ECPublicKeyParameters key) {
byte[] bytes;
int length;
@ -50,12 +52,13 @@ public class EccPublicKeySerializer extends Serializer<ECPublicKeyParameters> {
@SuppressWarnings("rawtypes")
@Override
public ECPublicKeyParameters read(Kryo kryo, Input input, Class type) {
ECPublicKeyParameters ecPublicKeyParameters = read(input);
return ecPublicKeyParameters;
public
ECPublicKeyParameters read(Kryo kryo, Input input, Class type) {
return read(input);
}
public static ECPublicKeyParameters read(Input input) {
public static
ECPublicKeyParameters read(Input input) {
byte[] bytes;
int length;
@ -88,7 +91,6 @@ public class EccPublicKeySerializer extends Serializer<ECPublicKeyParameters> {
input.readBytes(bytes, 0, length);
ECPoint Q = curve.decodePoint(bytes);
ECPublicKeyParameters ecPublicKeyParameters = new ECPublicKeyParameters(Q, ecDomainParameters);
return ecPublicKeyParameters;
return new ECPublicKeyParameters(Q, ecDomainParameters);
}
}

View 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]";
}
}

View 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");
}

View File

@ -25,17 +25,21 @@ import java.util.Properties;
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 final Properties properties = new SortedProperties();
private final File propertiesFile;
public PropertiesProvider(String propertiesFile) {
public
PropertiesProvider(String propertiesFile) {
this(new File(propertiesFile));
}
public PropertiesProvider(File propertiesFile) {
public
PropertiesProvider(File propertiesFile) {
if (propertiesFile == null) {
throw new NullPointerException("propertiesFile");
}
@ -43,8 +47,10 @@ public class PropertiesProvider {
propertiesFile = FileUtil.normalize(propertiesFile);
// make sure the parent dir exists...
File parentFile = propertiesFile.getParentFile();
if (parentFile != null) {
parentFile.mkdirs();
if (parentFile != null && !parentFile.exists()) {
if (!parentFile.mkdirs()) {
throw new RuntimeException("Unable to create directories for: " + propertiesFile);
}
}
this.propertiesFile = propertiesFile;
@ -52,11 +58,13 @@ public class PropertiesProvider {
_load();
}
public void setComments(String comments) {
public
void setComments(String comments) {
this.comments = comments;
}
private final void _load() {
private
void _load() {
if (!this.propertiesFile.canRead() || !this.propertiesFile.exists()) {
// in this case, our properties file doesn't exist yet... create one!
_save();
@ -77,7 +85,8 @@ public class PropertiesProvider {
}
private final void _save() {
private
void _save() {
try {
FileOutputStream fos = new FileOutputStream(this.propertiesFile);
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);
_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) {
return;
}
if (value instanceof Color) {
value = ((Color)value).getRGB();
value = ((Color) value).getRGB();
}
this.properties.setProperty(key, value.toString());
@ -114,8 +126,9 @@ public class PropertiesProvider {
_save();
}
@SuppressWarnings("unchecked")
public synchronized <T> T get(String key, Class<T> clazz) {
@SuppressWarnings({"unchecked", "AutoUnboxing"})
public synchronized
<T> T get(String key, Class<T> clazz) {
if (key == null || clazz == null) {
return null;
}
@ -146,7 +159,8 @@ public class PropertiesProvider {
}
@Override
public String toString() {
public
String toString() {
return "PropertiesProvider [" + this.propertiesFile + "]";
}
}

View File

@ -35,7 +35,7 @@ import java.util.concurrent.locks.ReentrantLock;
*/
@SuppressWarnings("unused")
public
class DiskStorage implements DiskStorageIfface {
class DiskStorage implements Storage {
private final DelayTimer timer;
private final ByteArrayWrapper defaultKey;
private final StorageBase storage;
@ -51,10 +51,14 @@ class DiskStorage implements DiskStorageIfface {
* Creates or opens a new database file.
*/
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.defaultKey = ByteArrayWrapper.wrap("");
if (readOnly) {
this.timer = null;
}
else {
this.timer = new DelayTimer("Storage Writer", false, new DelayTimer.Callback() {
@Override
public
@ -75,6 +79,7 @@ class DiskStorage implements DiskStorageIfface {
DiskStorage.this.storage.doActionThings(actions);
}
});
}
this.isOpen.set(true);
}
@ -95,7 +100,9 @@ class DiskStorage implements DiskStorageIfface {
// flush actions
// timer action runs on THIS thread, not timer thread
if (timer != null) {
this.timer.delay(0L);
}
return this.storage.size();
}
@ -281,11 +288,13 @@ class DiskStorage implements DiskStorageIfface {
throw new RuntimeException("Unable to act on closed storage");
}
if (timer != null) {
action(key, object);
// timer action runs on TIMER thread, not this thread
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
@ -300,11 +309,13 @@ class DiskStorage implements DiskStorageIfface {
throw new RuntimeException("Unable to act on closed storage");
}
if (timer != null) {
action(this.defaultKey, object);
// timer action runs on TIMER thread, not this thread
this.timer.delay(this.milliSeconds);
}
}
/**
* 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);
// timer action runs on THIS thread, not timer thread
if (timer != null) {
this.timer.delay(0L);
return this.storage.delete(wrap);
}
else {
return false;
}
}
/**
* Closes the database and file.
*/
void close() {
// timer action runs on THIS thread, not timer thread
if (timer != null) {
this.timer.delay(0L);
}
// have to "close" it after we run the timer!
this.isOpen.set(false);
if (timer != null) {
this.storage.close();
}
}
/**
* @return the file that backs this storage
@ -357,7 +376,9 @@ class DiskStorage implements DiskStorageIfface {
public final
long getFileSize() {
// timer action runs on THIS thread, not timer thread
if (timer != null) {
this.timer.delay(0L);
}
return this.storage.getFileSize();
}
@ -372,8 +393,13 @@ class DiskStorage implements DiskStorageIfface {
throw new RuntimeException("Unable to act on closed storage");
}
if (timer != null) {
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
@ -457,8 +483,10 @@ class DiskStorage implements DiskStorageIfface {
}
// timer action runs on THIS thread, not timer thread
if (timer != null) {
this.timer.delay(0L);
}
}
/**
* Save the storage to disk, immediately.
@ -472,11 +500,12 @@ class DiskStorage implements DiskStorageIfface {
throw new RuntimeException("Unable to act on closed storage");
}
action(ByteArrayWrapper.wrap(key), object);
// timer action runs on THIS thread, not timer thread
if (timer != null) {
action(ByteArrayWrapper.wrap(key), object);
this.timer.delay(0L);
}
}
/**
* Save the storage to disk, immediately.
@ -490,12 +519,15 @@ class DiskStorage implements DiskStorageIfface {
throw new RuntimeException("Unable to act on closed storage");
}
if (timer != null) {
action(ByteArrayWrapper.wrap(key), object);
// timer action runs on THIS thread, not timer thread
this.timer.delay(0L);
}
}
/**
* Save the storage to disk, immediately.
* <p/>
@ -508,9 +540,11 @@ class DiskStorage implements DiskStorageIfface {
throw new RuntimeException("Unable to act on closed storage");
}
if (timer != null) {
action(key, object);
// timer action runs on THIS thread, not timer thread
this.timer.delay(0L);
}
}
}

View File

@ -10,13 +10,14 @@ import java.util.concurrent.ConcurrentHashMap;
*
*/
public
class MemoryStorage implements DiskStorageIfface {
class MemoryStorage implements Storage {
private final ConcurrentHashMap<ByteArrayWrapper, Object> storage;
private final ByteArrayWrapper defaultKey;
private int version;
private
MemoryStorage() throws IOException {
public
MemoryStorage() {
this.storage = new ConcurrentHashMap<ByteArrayWrapper, Object>();
this.defaultKey = ByteArrayWrapper.wrap("");
}
@ -122,6 +123,7 @@ class MemoryStorage implements DiskStorageIfface {
final Object o = storage.get(key);
if (o == null) {
storage.put(key, data);
return data;
}
return (T) o;
}

View File

@ -263,7 +263,7 @@ class Metadata {
<T> T readData(SerializationManager serializationManager, InflaterInputStream inputStream) {
Input input = new Input(inputStream, 1024); // read 1024 at a time
@SuppressWarnings("unchecked")
T readObject = (T) serializationManager.readClassAndObject(input);
T readObject = (T) serializationManager.readFullClassAndObject(input);
return readObject;
}
@ -277,7 +277,7 @@ class Metadata {
final DeflaterOutputStream outputStream) throws IOException {
// HAVE TO LOCK BEFORE THIS IS CALLED! (AND FREE AFTERWARDS!)
Output output = new Output(outputStream, 1024); // write 1024 at a time
serializationManager.writeClassAndObject(output, data);
serializationManager.writeFullClassAndObject(output, data);
output.flush();
outputStream.flush(); // sync-flush is enabled, so the output stream will finish compressing data.

View File

@ -9,7 +9,7 @@ import java.io.IOException;
*
*/
public
interface DiskStorageIfface {
interface Storage {
/**
* Returns the number of objects in the database.
*/

View File

@ -449,7 +449,7 @@ class StorageBase {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
OutputStream outputStream = new DeflaterOutputStream(byteArrayOutputStream, deflater);
Output output = new Output(outputStream, 1024); // write 1024 at a time
kryo.writeClassAndObject(output, data);
kryo.writeFullClassAndObject(output, data);
output.flush();
outputStream.flush();

View File

@ -1,20 +1,22 @@
package dorkbox.util.storage;
import dorkbox.util.SerializationManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import dorkbox.util.SerializationManager;
public
class MakeStorage {
class Store {
private static final Logger logger = LoggerFactory.getLogger(DiskStorage.class);
@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
DiskMaker Disk() {
@ -32,7 +34,7 @@ class MakeStorage {
public static
void close(File file) {
synchronized (storages) {
DiskStorageIfface storage = storages.get(file);
Storage storage = storages.get(file);
if (storage != null) {
if (storage instanceof DiskStorage) {
final DiskStorage diskStorage = (DiskStorage) storage;
@ -50,11 +52,10 @@ class MakeStorage {
* Closes the storage.
*/
public static
void close(DiskStorageIfface _storage) {
void close(Storage _storage) {
synchronized (storages) {
File file = _storage.getFile();
DiskStorageIfface storage = storages.get(file);
if (storage != null) {
Storage storage = storages.get(file);
if (storage instanceof DiskStorage) {
final DiskStorage diskStorage = (DiskStorage) storage;
boolean isLastOne = diskStorage.decrementReference();
@ -65,13 +66,12 @@ class MakeStorage {
}
}
}
}
public static
void shutdown() {
synchronized (storages) {
Collection<DiskStorageIfface> values = storages.values();
for (DiskStorageIfface storage : values) {
Collection<Storage> values = storages.values();
for (Storage storage : values) {
if (storage instanceof DiskStorage) {
//noinspection StatementWithEmptyBody
final DiskStorage diskStorage = (DiskStorage) storage;
@ -87,7 +87,7 @@ class MakeStorage {
public static
void delete(File file) {
synchronized (storages) {
DiskStorageIfface remove = storages.remove(file);
Storage remove = storages.remove(file);
if (remove != null && remove instanceof DiskStorage) {
((DiskStorage) remove).close();
}
@ -97,7 +97,7 @@ class MakeStorage {
}
public static
void delete(DiskStorageIfface storage) {
void delete(Storage storage) {
File file = storage.getFile();
delete(file);
}
@ -107,6 +107,7 @@ class MakeStorage {
class DiskMaker {
private File file;
private SerializationManager serializationManager;
private boolean readOnly;
public
DiskMaker file(File file) {
@ -121,15 +122,15 @@ class MakeStorage {
}
public
DiskStorageIfface make() {
if (file == null) {
Storage make() {
if (this.file == null) {
throw new IllegalArgumentException("file cannot be null!");
}
// if we load from a NEW storage at the same location as an ALREADY EXISTING storage,
// without saving the existing storage first --- whoops!
synchronized (storages) {
DiskStorageIfface storage = storages.get(file);
Storage storage = storages.get(this.file);
if (storage != null) {
if (storage instanceof DiskStorage) {
@ -141,13 +142,13 @@ class MakeStorage {
((DiskStorage) storage).increaseReference();
}
else {
throw new RuntimeException("Unable to change storage types for: " + file);
throw new RuntimeException("Unable to change storage types for: " + this.file);
}
}
else {
try {
storage = new DiskStorage(file, serializationManager);
storages.put(file, storage);
storage = new DiskStorage(this.file, this.serializationManager, this.readOnly);
storages.put(this.file, storage);
} catch (IOException e) {
logger.error("Unable to open storage", e);
}
@ -156,21 +157,20 @@ class MakeStorage {
return storage;
}
}
public
DiskMaker readOnly() {
this.readOnly = true;
return this;
}
}
public static
class MemoryMaker {
private SerializationManager serializationManager;
public
MemoryMaker serializer(SerializationManager serializationManager) {
this.serializationManager = serializationManager;
return this;
}
MemoryStorage make() {
return null;
MemoryStorage make() throws IOException {
return new MemoryStorage();
}
}
}

View File

@ -1,12 +1,11 @@
package dorkbox.util;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.Registration;
import com.esotericsoftware.kryo.Serializer;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import dorkbox.util.storage.DiskStorageIfface;
import dorkbox.util.storage.MakeStorage;
import dorkbox.util.storage.Storage;
import dorkbox.util.storage.Store;
import io.netty.buffer.ByteBuf;
import org.junit.*;
import org.junit.runners.MethodSorters;
@ -23,19 +22,6 @@ class StorageTest {
private static final SerializationManager manager = new SerializationManager() {
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
public
void register(final Class<?> clazz) {
@ -50,16 +36,15 @@ class StorageTest {
@Override
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);
return null;
}
@Override
public
void write(final ByteBuf buffer, final Object message) {
final Output output = new Output();
writeClassAndObject(output, message);
writeFullClassAndObject(output, message);
buffer.writeBytes(output.getBuffer());
}
@ -69,7 +54,7 @@ class StorageTest {
final Input input = new Input();
buffer.readBytes(input.getBuffer());
final Object o = readClassAndObject(input);
final Object o = readFullClassAndObject(input);
buffer.skipBytes(input.position());
return o;
@ -77,15 +62,26 @@ class StorageTest {
@Override
public
void writeClassAndObject(final Output output, final Object value) {
void writeFullClassAndObject(final Output output, final Object value) {
kryo.writeClassAndObject(output, value);
}
@Override
public
Object readClassAndObject(final Input input) {
Object readFullClassAndObject(final Input input) {
return kryo.readClassAndObject(input);
}
@Override
public
Kryo take() throws InterruptedException {
return kryo;
}
@Override
public
void release(final Kryo kryo) {
}
};
static
@ -96,20 +92,20 @@ class StorageTest {
@Before
public
void deleteDB() {
MakeStorage.delete(TEST_DB);
Store.delete(TEST_DB);
}
@After
public
void delete2DB() {
MakeStorage.delete(TEST_DB);
Store.delete(TEST_DB);
}
@Test
public
void testCreateDB() throws IOException {
DiskStorageIfface storage = MakeStorage.Disk()
Storage storage = Store.Disk()
.file(TEST_DB)
.serializer(manager)
.make();
@ -120,9 +116,9 @@ class StorageTest {
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!
MakeStorage.close(storage);
Store.close(storage);
storage = MakeStorage.Disk()
storage = Store.Disk()
.file(TEST_DB)
.serializer(manager)
.make();
@ -132,7 +128,7 @@ class StorageTest {
Assert.assertEquals("Record count is not the same", numberOfRecords1, numberOfRecords2);
Assert.assertEquals("size is not the same", size1, size2);
MakeStorage.close(storage);
Store.close(storage);
}
@ -142,7 +138,7 @@ class StorageTest {
int total = 100;
try {
DiskStorageIfface storage = MakeStorage.Disk()
Storage storage = Store.Disk()
.file(TEST_DB)
.serializer(manager)
.make();
@ -150,8 +146,8 @@ class StorageTest {
add(storage, i);
}
MakeStorage.close(storage);
storage = MakeStorage.Disk()
Store.close(storage);
storage = Store.Disk()
.file(TEST_DB)
.serializer(manager)
.make();
@ -162,7 +158,7 @@ class StorageTest {
Assert.assertEquals("Object is not the same", record1Data, readRecord);
}
MakeStorage.close(storage);
Store.close(storage);
} catch (Exception e) {
e.printStackTrace();
Assert.fail("Error!");
@ -175,7 +171,7 @@ class StorageTest {
int total = 100;
try {
DiskStorageIfface storage = MakeStorage.Disk()
Storage storage = Store.Disk()
.file(TEST_DB)
.serializer(manager)
.make();
@ -189,9 +185,9 @@ class StorageTest {
Assert.assertEquals("Object is not the same", addRecord, readData);
}
MakeStorage.close(storage);
Store.close(storage);
storage = MakeStorage.Disk()
storage = Store.Disk()
.file(TEST_DB)
.serializer(manager)
.make();
@ -208,7 +204,7 @@ class StorageTest {
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!
MakeStorage.close(storage);
Store.close(storage);
} catch (Exception e) {
e.printStackTrace();
Assert.fail("Error!");
@ -221,7 +217,7 @@ class StorageTest {
int total = 100;
try {
DiskStorageIfface storage = MakeStorage.Disk()
Storage storage = Store.Disk()
.file(TEST_DB)
.serializer(manager)
.make();
@ -241,9 +237,9 @@ class StorageTest {
Assert.assertEquals("Object is not the same", record1Data, readRecord);
}
MakeStorage.close(storage);
Store.close(storage);
storage = MakeStorage.Disk()
storage = Store.Disk()
.file(TEST_DB)
.serializer(manager)
.make();
@ -254,7 +250,7 @@ class StorageTest {
Assert.assertEquals("Object is not the same", dataCheck, readRecord);
}
MakeStorage.close(storage);
Store.close(storage);
} catch (Exception e) {
e.printStackTrace();
Assert.fail("Error!");
@ -267,7 +263,7 @@ class StorageTest {
int total = 100;
try {
DiskStorageIfface storage = MakeStorage.Disk()
Storage storage = Store.Disk()
.file(TEST_DB)
.serializer(manager)
.make();
@ -282,9 +278,9 @@ class StorageTest {
Assert.assertEquals("Object is not the same", record1Data, readRecord);
}
MakeStorage.close(storage);
Store.close(storage);
storage = MakeStorage.Disk()
storage = Store.Disk()
.file(TEST_DB)
.serializer(manager)
.make();
@ -295,7 +291,7 @@ class StorageTest {
Assert.assertEquals("Object is not the same", dataCheck, readRecord);
}
MakeStorage.close(storage);
Store.close(storage);
} catch (Exception e) {
e.printStackTrace();
Assert.fail("Error!");
@ -308,7 +304,7 @@ class StorageTest {
int total = 100;
try {
DiskStorageIfface storage = MakeStorage.Disk()
Storage storage = Store.Disk()
.file(TEST_DB)
.serializer(manager)
.make();
@ -318,9 +314,9 @@ class StorageTest {
Assert.assertEquals("Object is not the same", addRecord, readRecord);
}
MakeStorage.close(storage);
Store.close(storage);
storage = MakeStorage.Disk()
storage = Store.Disk()
.file(TEST_DB)
.serializer(manager)
.make();
@ -342,8 +338,8 @@ class StorageTest {
storage.load(createKey, data2);
Assert.assertEquals("Object is not the same", data, data2);
MakeStorage.close(storage);
storage = MakeStorage.Disk()
Store.close(storage);
storage = Store.Disk()
.file(TEST_DB)
.serializer(manager)
.make();
@ -352,7 +348,7 @@ class StorageTest {
storage.load(createKey, data2);
Assert.assertEquals("Object is not the same", data, data2);
MakeStorage.close(storage);
Store.close(storage);
} catch (Exception e) {
e.printStackTrace();
Assert.fail("Error!");
@ -366,7 +362,7 @@ class StorageTest {
int total = 100;
try {
DiskStorageIfface storage = MakeStorage.Disk()
Storage storage = Store.Disk()
.file(TEST_DB)
.serializer(manager)
.make();
@ -376,9 +372,9 @@ class StorageTest {
Assert.assertEquals("Object is not the same", addRecord, readRecord);
}
MakeStorage.close(storage);
Store.close(storage);
storage = MakeStorage.Disk()
storage = Store.Disk()
.file(TEST_DB)
.serializer(manager)
.make();
@ -408,9 +404,9 @@ class StorageTest {
Assert.assertEquals("Object is not the same", dataCheck, addRecord);
MakeStorage.close(storage);
Store.close(storage);
storage = MakeStorage.Disk()
storage = Store.Disk()
.file(TEST_DB)
.serializer(manager)
.make();
@ -437,7 +433,7 @@ class StorageTest {
int total = 100;
try {
DiskStorageIfface storage = MakeStorage.Disk()
Storage storage = Store.Disk()
.file(TEST_DB)
.serializer(manager)
.make();
@ -447,9 +443,9 @@ class StorageTest {
Assert.assertEquals("Object is not the same", addRecord, readRecord);
}
MakeStorage.close(storage);
Store.close(storage);
storage = MakeStorage.Disk()
storage = Store.Disk()
.file(TEST_DB)
.serializer(manager)
.make();
@ -458,8 +454,8 @@ class StorageTest {
String readRecord = readRecord(storage, 3);
Assert.assertEquals("Object is not the same", updateRecord, readRecord);
MakeStorage.close(storage);
storage = MakeStorage.Disk()
Store.close(storage);
storage = Store.Disk()
.file(TEST_DB)
.serializer(manager)
.make();
@ -469,8 +465,8 @@ class StorageTest {
updateRecord = updateRecord(storage, 3, createData(3));
MakeStorage.close(storage);
storage = MakeStorage.Disk()
Store.close(storage);
storage = Store.Disk()
.file(TEST_DB)
.serializer(manager)
.make();
@ -478,8 +474,8 @@ class StorageTest {
readRecord = readRecord(storage, 3);
Assert.assertEquals("Object is not the same", updateRecord, readRecord);
MakeStorage.close(storage);
storage = MakeStorage.Disk()
Store.close(storage);
storage = Store.Disk()
.file(TEST_DB)
.serializer(manager)
.make();
@ -488,7 +484,7 @@ class StorageTest {
readRecord = readRecord(storage, 0);
Assert.assertEquals("Object is not the same", updateRecord, readRecord);
MakeStorage.close(storage);
Store.close(storage);
} catch (Exception e) {
e.printStackTrace();
Assert.fail("Error!");
@ -502,7 +498,7 @@ class StorageTest {
int total = 100;
try {
DiskStorageIfface storage = MakeStorage.Disk()
Storage storage = Store.Disk()
.file(TEST_DB)
.serializer(manager)
.make();
@ -513,12 +509,12 @@ class StorageTest {
storage.put(createKey, data);
}
MakeStorage.close(storage);
Store.close(storage);
Data data = new Data();
makeData(data);
storage = MakeStorage.Disk()
storage = Store.Disk()
.file(TEST_DB)
.serializer(manager)
.make();
@ -529,7 +525,7 @@ class StorageTest {
storage.load(createKey, data2);
Assert.assertEquals("Object is not the same", data, data2);
}
MakeStorage.close(storage);
Store.close(storage);
} catch (Exception e) {
e.printStackTrace();
Assert.fail("Error!");
@ -544,7 +540,7 @@ class StorageTest {
}
public static
String add(DiskStorageIfface storage, int number) throws IOException {
String add(Storage storage, int number) throws IOException {
String record1Data = createData(number);
String record1Key = createKey(number);
@ -554,7 +550,7 @@ class StorageTest {
}
public static
String readRecord(DiskStorageIfface storage, int number) throws ClassNotFoundException, IOException {
String readRecord(Storage storage, int number) throws ClassNotFoundException, IOException {
String record1Key = createKey(number);
log("reading record " + number + "...");
@ -565,7 +561,7 @@ class StorageTest {
}
public static
void deleteRecord(DiskStorageIfface storage, int nNumber) throws ClassNotFoundException, IOException {
void deleteRecord(Storage storage, int nNumber) throws ClassNotFoundException, IOException {
String record1Key = createKey(nNumber);
log("deleting record " + nNumber + "...");
@ -573,7 +569,7 @@ class StorageTest {
}
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);
log("updating record " + number + "...");

View File

@ -35,20 +35,13 @@
*/
package dorkbox.util;
import static dorkbox.util.bytes.Unsigned.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 dorkbox.util.bytes.UByte;
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 {

View File

@ -1,26 +1,26 @@
/**
* Copyright (c) 2011-2013, Lukas Eder, lukas.eder@gmail.com
* All rights reserved.
*
* <p/>
* This software is licensed to you under the Apache License, Version 2.0
* (the "License"); You may obtain a copy of the License at
*
* <p/>
* http://www.apache.org/licenses/LICENSE-2.0
*
* <p/>
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* <p/>
* . Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* <p/>
* . Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* <p/>
* . Neither the name "jOOU" nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* <p/>
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@ -35,39 +35,33 @@
*/
package dorkbox.util;
import static dorkbox.util.bytes.Unsigned.uint;
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 dorkbox.util.bytes.UInteger;
import org.junit.Test;
import dorkbox.util.bytes.UInteger;
import java.io.*;
public class UIntegerTest {
private static final int CACHE_SIZE=256;
private static final int NEAR_MISS_OFFSET=4;
import static dorkbox.util.bytes.Unsigned.uint;
import static org.junit.Assert.*;
public
class UIntegerTest {
private static final int CACHE_SIZE = 256;
private static final int NEAR_MISS_OFFSET = 4;
@SuppressWarnings("deprecation")
@Test
public void testValueOfLong() {
for(long l=01; l<=UInteger.MAX_VALUE; l<<=1) {
assertEquals(l , uint(l).longValue());
public
void testValueOfLong() {
for (long l = 01; l <= UInteger.MAX_VALUE; l <<= 1) {
assertEquals(l, uint(l).longValue());
}
}
@SuppressWarnings("deprecation")
@Test
public void testValueOfLongCachingShift() {
for(long l=01; l<CACHE_SIZE; l<<=1)
{
public
void testValueOfLongCachingShift() {
for (long l = 01; l < CACHE_SIZE; l <<= 1) {
UInteger a = uint(l);
UInteger b = uint(l);
assertTrue(a == b);
@ -76,9 +70,9 @@ public class UIntegerTest {
@SuppressWarnings("deprecation")
@Test
public void testValueOfLongCachingNear() {
for(long l=CACHE_SIZE-NEAR_MISS_OFFSET; l<CACHE_SIZE; l++)
{
public
void testValueOfLongCachingNear() {
for (long l = CACHE_SIZE - NEAR_MISS_OFFSET; l < CACHE_SIZE; l++) {
UInteger a = uint(l);
UInteger b = uint(l);
assertTrue(a == b);
@ -87,9 +81,9 @@ public class UIntegerTest {
@SuppressWarnings("deprecation")
@Test
public void testValueOfLongNoCachingShift() {
for(long l=CACHE_SIZE; l<=CACHE_SIZE; l<<=1)
{
public
void testValueOfLongNoCachingShift() {
for (long l = CACHE_SIZE; l <= CACHE_SIZE; l <<= 1) {
UInteger a = uint(l);
UInteger b = uint(l);
assertFalse(a == b);
@ -98,9 +92,9 @@ public class UIntegerTest {
@SuppressWarnings("deprecation")
@Test
public void testValueOfLongNoCachingNear() {
for(long l=CACHE_SIZE; l<=CACHE_SIZE+NEAR_MISS_OFFSET; l++)
{
public
void testValueOfLongNoCachingNear() {
for (long l = CACHE_SIZE; l <= CACHE_SIZE + NEAR_MISS_OFFSET; l++) {
UInteger a = uint(l);
UInteger b = uint(l);
assertFalse(a == b);
@ -109,22 +103,24 @@ public class UIntegerTest {
@SuppressWarnings("deprecation")
@Test
public void testValueOfLongInvalid() {
public
void testValueOfLongInvalid() {
try {
uint(UInteger.MIN_VALUE - 1);
fail();
} catch (NumberFormatException e) {
}
catch (NumberFormatException e) {}
try {
uint(UInteger.MAX_VALUE + 1);
fail();
} catch (NumberFormatException e) {
}
catch (NumberFormatException e) {}
}
@SuppressWarnings("deprecation")
@Test
public void testSerializeDeserialize() throws ClassNotFoundException, IOException {
public
void testSerializeDeserialize() throws ClassNotFoundException, IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
ByteArrayInputStream bais;

View File

@ -35,28 +35,20 @@
*/
package dorkbox.util;
import static dorkbox.util.bytes.ULong.MAX_VALUE_LONG;
import static dorkbox.util.bytes.Unsigned.ubyte;
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 dorkbox.util.bytes.*;
import org.junit.Test;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.junit.Test;
import dorkbox.util.bytes.UByte;
import dorkbox.util.bytes.UInteger;
import dorkbox.util.bytes.ULong;
import dorkbox.util.bytes.UNumber;
import dorkbox.util.bytes.UShort;
import static dorkbox.util.bytes.ULong.MAX_VALUE_LONG;
import static dorkbox.util.bytes.Unsigned.*;
import static java.math.BigInteger.ONE;
import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
/**
* @author Lukas Eder