/**
* Copyright 2014 Ricardo Padilha
*
* 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 net.dsys.snio.impl.codec;
import java.util.zip.Adler32;
import java.util.zip.CRC32;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import net.dsys.commons.api.lang.Factory;
import net.dsys.snio.api.codec.MessageCodec;
/**
* @author Ricardo Padilha
*/
public final class Codecs {
private Codecs() {
// no instantiation allowed
return;
}
/**
* Frame encoding with a simple two-byte length header. Messages cannot be
* longer than 65525 bytes to make sure that they will fit in an UDP
* datagram. This codec is thread-safe.
*
* @return a codec configured for its maximum supported body length
*/
@Nonnull
public static MessageCodec getShort() {
return new ShortHeaderCodec();
}
@Nonnull
public static Factory<MessageCodec> getShortFactory() {
return new Factory<MessageCodec>() {
@Override
public MessageCodec newInstance() {
return getShort();
}
};
}
/**
* Frame encoding with a simple two-byte length header. Messages cannot be
* longer than 65525 bytes to make sure that they will fit in an UDP
* datagram. This codec is thread-safe.
*
* @param bodyLength
* maximum length of messages
* @return a codec configured for the given body length
* @throws IllegalArgumentException
* if the body length is too small or too large
*/
@Nonnull
public static MessageCodec getShort(@Nonnegative final int bodyLength) {
return new ShortHeaderCodec(bodyLength);
}
@Nonnull
public static Factory<MessageCodec> getShortFactory(@Nonnegative final int bodyLength) {
return new Factory<MessageCodec>() {
@Override
public MessageCodec newInstance() {
return getShort(bodyLength);
}
};
}
/**
* Frame encoding with a simple int length header. Messages cannot be longer
* than 2^31-5 bytes. This codec is thread-safe. Messages cannot be longer
* than 65531 bytes if they need to fit in an UDP datagram.
*
* @param bodyLength
* maximum length of messages
* @return a codec configured for the given body length
* @throws IllegalArgumentException
* if the body length is too small or too large
*/
@Nonnull
public static MessageCodec getDefault(@Nonnegative final int bodyLength) {
return new IntHeaderCodec(bodyLength);
}
@Nonnull
public static Factory<MessageCodec> getDefaultFactory(@Nonnegative final int bodyLength) {
return new Factory<MessageCodec>() {
@Override
public MessageCodec newInstance() {
return getDefault(bodyLength);
}
};
}
/**
* Frame encoding with a CRC32 checksum at the end. Messages cannot be
* longer than 65521 bytes if they need to fit in an UDP datagram.
* Thread-safety is guaranteed only between encoding and decoding, i.e., two
* different threads can encode and decode at the same time, but two threads
* cannot encode at the same time.
*
* @param bodyLength
* maximum length of messages
* @return a codec configured for the given body length
* @throws IllegalArgumentException
* if the body length is too small or too large
*/
@Nonnull
public static MessageCodec getCRC32Checksum(@Nonnegative final int bodyLength) {
return new ChecksumCodec(getDefault(bodyLength), new CRC32(), new CRC32());
}
@Nonnull
public static Factory<MessageCodec> getCRC32Factory(@Nonnegative final int bodyLength) {
return new Factory<MessageCodec>() {
@Override
public MessageCodec newInstance() {
return getCRC32Checksum(bodyLength);
}
};
}
/**
* Frame encoding with an Adler32 checksum at the end. Messages cannot be
* longer than 65521 bytes if they need to fit in an UDP datagram.
* Thread-safety is guaranteed only between encoding and decoding, i.e., two
* different threads can encode and decode at the same time, but two threads
* cannot encode at the same time.
*
* @param bodyLength
* maximum length of messages
* @return a codec configured for the given body length
* @throws IllegalArgumentException
* if the body length is too small or too large
*/
@Nonnull
public static MessageCodec getAdler32Checksum(@Nonnegative final int bodyLength) {
return new ChecksumCodec(getDefault(bodyLength), new Adler32(), new Adler32());
}
@Nonnull
public static Factory<MessageCodec> getAdler32Factory(@Nonnegative final int bodyLength) {
return new Factory<MessageCodec>() {
@Override
public MessageCodec newInstance() {
return getAdler32Checksum(bodyLength);
}
};
}
/**
* Frame encoding with an xxHash checksum at the end. Messages cannot be
* longer than 65521 bytes if they need to fit in an UDP datagram.
* Thread-safety is guaranteed only between encoding and decoding, i.e., two
* different threads can encode and decode at the same time, but two threads
* cannot encode at the same time.
*
* @param bodyLength
* maximum length of messages
* @return a codec configured for the given body length
* @throws IllegalArgumentException
* if the body length is too small or too large
*/
@Nonnull
public static MessageCodec getXXHashChecksum(@Nonnegative final int bodyLength) {
return new ChecksumCodec(getDefault(bodyLength), new XXHashChecksum(), new XXHashChecksum());
}
@Nonnull
public static Factory<MessageCodec> getXXHashFactory(@Nonnegative final int bodyLength) {
return new Factory<MessageCodec>() {
@Override
public MessageCodec newInstance() {
return getXXHashChecksum(bodyLength);
}
};
}
/**
* Frame encoding that compresses messages using deflate. Messages cannot be
* longer than 65499 bytes if they need to fit in an UDP datagram.
* Thread-safety is guaranteed only between encoding and decoding, i.e., two
* different threads can encode and decode at the same time, but two threads
* cannot encode at the same time.
*
* @param bodyLength
* maximum length of messages
* @return a codec configured for the given body length
* @throws IllegalArgumentException
* if the body length is too small or too large
*/
@Nonnull
public static MessageCodec getDeflateCompression(@Nonnegative final int bodyLength) {
return new DeflateCodec(bodyLength);
}
@Nonnull
public static Factory<MessageCodec> getDeflateFactory(@Nonnegative final int bodyLength) {
return new Factory<MessageCodec>() {
@Override
public MessageCodec newInstance() {
return getDeflateCompression(bodyLength);
}
};
}
/**
* Frame encoding that compresses messages using LZ4. Messages cannot be
* longer than 65252 bytes to make sure that they will fit in an UDP
* datagram. Thread-safety is guaranteed only between encoding and decoding,
* i.e., two different threads can encode and decode at the same time, but
* two threads cannot encode at the same time.
*
* @param bodyLength
* maximum length of messages
* @return a codec configured for the given body length
* @throws IllegalArgumentException
* if the body length is too small or too large
*/
@Nonnull
public static MessageCodec getLZ4Compression(@Nonnegative final int bodyLength) {
return new LZ4CompressionCodec(bodyLength);
}
@Nonnull
public static Factory<MessageCodec> getLZ4Factory(@Nonnegative final int bodyLength) {
return new Factory<MessageCodec>() {
@Override
public MessageCodec newInstance() {
return getLZ4Compression(bodyLength);
}
};
}
}