/*
* Copyright 2010 NCHOVY
*
* 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 org.krakenapps.codec;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import static org.junit.Assert.*;
public class EncodingRuleTest {
@Test
public void encodeDecodePrimitiveList() {
int[] i = new int[] { 1, 2, 3 };
long[] l = new long[] { 1, 2, 3 };
short[] s = new short[] { 1, 2, 3 };
double[] d = new double[] { 1.11, 2.22, 3.33 };
float[] f = new float[] { 1.1f, 2.2f, 3.3f };
boolean[] b = new boolean[] { true, false, true };
byte[] by = new byte[] { 1, 2, 3 };
// int array
ByteBuffer bb = ByteBuffer.allocate(EncodingRule.lengthOf(i));
EncodingRule.encode(bb, i);
bb.flip();
Object[] o = (Object[]) EncodingRule.decode(bb);
for (int index = 0; index < o.length; index++)
assertEquals(i[index], o[index]);
// long array
bb = ByteBuffer.allocate(EncodingRule.lengthOf(l));
EncodingRule.encode(bb, l);
bb.flip();
o = (Object[]) EncodingRule.decode(bb);
for (int index = 0; index < o.length; index++)
assertEquals(l[index], o[index]);
// short array
bb = ByteBuffer.allocate(EncodingRule.lengthOf(s));
EncodingRule.encode(bb, s);
bb.flip();
o = (Object[]) EncodingRule.decode(bb);
for (int index = 0; index < o.length; index++)
assertEquals(s[index], o[index]);
// double array
bb = ByteBuffer.allocate(EncodingRule.lengthOf(d));
EncodingRule.encode(bb, d);
bb.flip();
o = (Object[]) EncodingRule.decode(bb);
for (int index = 0; index < o.length; index++)
assertEquals(d[index], o[index]);
// float array
bb = ByteBuffer.allocate(EncodingRule.lengthOf(f));
EncodingRule.encode(bb, f);
bb.flip();
o = (Object[]) EncodingRule.decode(bb);
for (int index = 0; index < o.length; index++)
assertEquals(f[index], o[index]);
// boolean array
bb = ByteBuffer.allocate(EncodingRule.lengthOf(b));
EncodingRule.encode(bb, b);
bb.flip();
o = (Object[]) EncodingRule.decode(bb);
for (int index = 0; index < o.length; index++)
assertEquals(b[index], o[index]);
// byte array
bb = ByteBuffer.allocate(EncodingRule.lengthOf(by));
EncodingRule.encode(bb, by);
bb.flip();
byte[] barr = (byte[]) EncodingRule.decode(bb);
for (int index = 0; index < o.length; index++)
assertEquals(by[index], barr[index]);
}
@Test(expected = UnsupportedTypeException.class)
public void lengthOfCharArrayTest() {
char[] c = new char[] { 'a', 'b', 'c' };
ByteBuffer.allocate(EncodingRule.lengthOf(c));
}
@Test(expected = UnsupportedTypeException.class)
public void encodeCharArrayTest() {
char[] c = new char[] { 'a', 'b', 'c' };
ByteBuffer bb = ByteBuffer.allocate(10);
EncodingRule.encode(bb, c);
}
@Test
public void encodeDecodeList() {
List<String> i = new ArrayList<String>();
i.add("a");
i.add("b");
i.add("c");
ByteBuffer bb = ByteBuffer.allocate(EncodingRule.lengthOf(i));
EncodingRule.encode(bb, i);
bb.flip();
Object[] o = (Object[]) EncodingRule.decode(bb);
assertEquals("a", o[0]);
assertEquals("b", o[1]);
assertEquals("c", o[2]);
Object[] l = new Object[] { "String Test", (long) -14231231, (int) -200, (short) -10 };
bb = ByteBuffer.allocate(EncodingRule.lengthOf(l));
EncodingRule.encode(bb, l);
assertEquals(bb.position(), EncodingRule.lengthOf(l));
bb.flip();
Object[] decodedL = (Object[]) EncodingRule.decode(bb);
assertEquals("String Test", decodedL[0]);
assertEquals((long) -14231231, decodedL[1]);
assertEquals((int) -200, decodedL[2]);
assertEquals((short) -10, decodedL[3]);
}
@Test
public void decodeNumber() {
ByteBuffer bb = ByteBuffer.allocate(100);
// no high bit case
bb.put((byte) EncodingRule.INT32_TYPE);
bb.put((byte) 0x7f);
bb.flip();
assertEquals(0x7f, EncodingRule.decodePlainInt(bb));
// 2 byte length case
// 30000 (10) = 1110101 00110000 (2)
// (1)0000001 (1)1101010 (0)0110000
bb.clear();
bb.put((byte) EncodingRule.INT16_TYPE);
bb.put((byte) 0x81);
bb.put((byte) 0xEA);
bb.put((byte) 0x30);
bb.flip();
assertEquals((short) 30000, EncodingRule.decodePlainShort(bb));
// same, but dummy byte trailing test
bb.clear();
bb.put((byte) EncodingRule.INT32_TYPE);
bb.put((byte) 0x81);
bb.put((byte) 0xEA);
bb.put((byte) 0x30);
bb.put((byte) 0x30); // will not be read (cause of non higher bit)
bb.flip();
assertEquals(30000, EncodingRule.decodePlainInt(bb));
}
@Test
public void encodeNumber() {
ByteBuffer bb = ByteBuffer.allocate(100);
// 1 byte boundary test
EncodingRule.encode(bb, 0x3F);
bb.flip();
assertEquals(2, bb.remaining());
assertEquals(0x3f, EncodingRule.decode(bb));
bb.clear();
EncodingRule.encode(bb, 0x3F + 1);
bb.flip();
assertEquals(3, bb.remaining());
assertEquals(0x3f + 1, EncodingRule.decode(bb));
// 2 byte boundary test
bb.clear();
EncodingRule.encode(bb, 0x1FFF);
bb.flip();
assertEquals(3, bb.remaining());
assertEquals(0x1FFF, EncodingRule.decode(bb));
bb.clear();
EncodingRule.encode(bb, 0x1FFF + 1);
bb.flip();
assertEquals(4, bb.remaining());
assertEquals(0x1FFF + 1, EncodingRule.decode(bb));
// negative number test
bb.clear();
EncodingRule.encode(bb, -10);
bb.flip();
assertEquals(2, bb.remaining());
assertEquals(-10, EncodingRule.decode(bb));
}
@Test
public void encodeDecodeZigzagNumber() {
ByteBuffer bb = ByteBuffer.allocate(100);
bb.clear();
EncodingRule.encode(bb, (int) 0);
bb.flip();
bb.get();
assertEquals(0, EncodingRule.decodeRawNumber(bb));
bb.clear();
EncodingRule.encode(bb, (int) -1);
bb.flip();
bb.get();
assertEquals(1, EncodingRule.decodeRawNumber(bb));
bb.clear();
EncodingRule.encode(bb, (int) 1);
bb.flip();
bb.get();
assertEquals(2, EncodingRule.decodeRawNumber(bb));
bb.clear();
EncodingRule.encode(bb, (int) -2);
bb.flip();
bb.get();
assertEquals(3, EncodingRule.decodeRawNumber(bb));
bb.clear();
EncodingRule.encode(bb, Integer.MAX_VALUE);
bb.flip();
bb.get();
assertEquals(0xFFFFFFFFL - 1, EncodingRule.decodeRawNumber(bb));
bb.clear();
EncodingRule.encode(bb, (int) Integer.MIN_VALUE);
bb.flip();
bb.get();
assertEquals(0xFFFFFFFFL, EncodingRule.decodeRawNumber(bb));
}
@Test
public void encodeDecodeNumberBoundary() {
ByteBuffer bb = ByteBuffer.allocate(100);
bb.clear();
EncodingRule.encode(bb, Short.MAX_VALUE);
bb.flip();
assertEquals(Short.MAX_VALUE, EncodingRule.decode(bb));
bb.clear();
EncodingRule.encode(bb, Integer.MAX_VALUE);
bb.flip();
assertEquals(Integer.MAX_VALUE, EncodingRule.decode(bb));
bb.clear();
EncodingRule.encode(bb, Long.MAX_VALUE);
bb.flip();
assertEquals(Long.MAX_VALUE, EncodingRule.decode(bb));
bb.clear();
EncodingRule.encode(bb, Short.MIN_VALUE);
bb.flip();
assertEquals(Short.MIN_VALUE, EncodingRule.decode(bb));
bb.clear();
EncodingRule.encode(bb, Integer.MIN_VALUE);
bb.flip();
assertEquals(Integer.MIN_VALUE, EncodingRule.decode(bb));
bb.clear();
EncodingRule.encode(bb, Long.MIN_VALUE);
bb.flip();
assertEquals(Long.MIN_VALUE, EncodingRule.decode(bb));
}
@Test
public void encodeDecodeNumber() {
ByteBuffer bb = ByteBuffer.allocate(100);
EncodingRule.encode(bb, 0x0);
bb.flip();
assertEquals(2, bb.remaining());
assertEquals(0x0, EncodingRule.decode(bb));
bb.clear();
EncodingRule.encode(bb, 0x2121212121212121L);
bb.flip();
assertEquals(10, bb.remaining());
assertEquals(0x2121212121212121L, EncodingRule.decode(bb));
bb.clear();
EncodingRule.encode(bb, -0x2121212121212121L);
bb.flip();
assertEquals(10, bb.remaining());
assertEquals(-0x2121212121212121L, EncodingRule.decode(bb));
bb.clear();
EncodingRule.encode(bb, -0x21212);
bb.flip();
assertEquals(4, bb.remaining());
assertEquals(-0x21212, EncodingRule.decode(bb));
bb.clear();
EncodingRule.encode(bb, (short) -0x212);
bb.flip();
assertEquals(3, bb.remaining());
assertEquals((short) -0x212, EncodingRule.decode(bb));
}
@Test
public void encodeDecodeString() {
// ordinary string test
ByteBuffer bb = ByteBuffer.allocate(100);
EncodingRule.encodeString(bb, "xeraph");
bb.flip();
assertEquals("xeraph", EncodingRule.decodeString(bb));
// empty string test
bb.clear();
EncodingRule.encode(bb, "");
bb.flip();
assertEquals("", EncodingRule.decodeString(bb));
}
@Test
public void encodeDecodeBoolean() {
ByteBuffer bb = ByteBuffer.allocate(2);
bb.clear();
EncodingRule.encodeBoolean(bb, true);
bb.flip();
assertEquals(true, EncodingRule.decode(bb));
}
@Test
public void encodeDecodeStringInt() {
// trailing other data
ByteBuffer bb = ByteBuffer.allocate(100);
bb.clear();
EncodingRule.encodeString(bb, "xeraph");
EncodingRule.encodeInt(bb, 100);
bb.flip();
assertEquals("xeraph", EncodingRule.decodeString(bb));
assertEquals(100, EncodingRule.decodeInt(bb));
}
@Test
public void encodeDecodeArray() {
ByteBuffer bb = ByteBuffer.allocate(1024);
Object[] array = new Object[] { 1234, "xeraph" };
EncodingRule.encodeArray(bb, array);
bb.flip();
Object[] decodedArray = (Object[]) EncodingRule.decode(bb);
assertEquals(2, decodedArray.length);
assertEquals(1234, decodedArray[0]);
assertEquals("xeraph", decodedArray[1]);
}
@Test
public void encodeDecodeIp() throws UnknownHostException {
// case ip4
Inet4Address ip4 = (Inet4Address) Inet4Address.getByAddress(new byte[] { 10, 0, 0, 1 });
ByteBuffer bb = ByteBuffer.allocate(128);
EncodingRule.encodeIp4(bb, ip4);
bb.flip();
assertEquals(ip4, EncodingRule.decodeIp4(bb));
// case ip6
bb.clear();
Inet6Address ip6 = (Inet6Address) Inet6Address.getByAddress(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16 });
EncodingRule.encodeIp6(bb, ip6);
bb.flip();
assertEquals(ip6, EncodingRule.decodeIp6(bb));
}
@Test
public void encodeDecodeMapIp() throws UnknownHostException {
Map<String, Object> m = new HashMap<String, Object>();
InetAddress local = Inet4Address.getByAddress(new byte[] { 127, 0, 0, 1 });
m.put("ip", local);
int length = EncodingRule.lengthOf(m);
ByteBuffer bb = ByteBuffer.allocate(length);
EncodingRule.encode(bb, m);
bb.flip();
Map<String, Object> dm = EncodingRule.decodeMap(bb);
assertEquals(local, dm.get("ip"));
}
@Test
public void encodeDecodeMap() throws UnknownHostException {
Calendar cal = Calendar.getInstance();
cal.set(2009, 1, 21, 0, 0, 0);
cal.set(Calendar.MILLISECOND, 0);
Date since = cal.getTime();
Map<String, Object> m = new HashMap<String, Object>();
m.put("name", "nchovy");
m.put("since", since);
m.put("employee", 8);
m.put("capital", 30000000);
m.put("servers", new Object[] { "soul", "navi" });
m.put("null", null);
int length = EncodingRule.lengthOf(m);
ByteBuffer bb = ByteBuffer.allocate(length);
EncodingRule.encode(bb, m);
bb.flip();
Map<String, Object> dm = EncodingRule.decodeMap(bb);
assertEquals(6, m.size());
assertEquals("nchovy", dm.get("name"));
assertEquals(since, dm.get("since"));
assertEquals(8, dm.get("employee"));
assertEquals(30000000, dm.get("capital"));
assertNull(dm.get("null"));
Object[] decodedServers = (Object[]) dm.get("servers");
assertEquals(2, decodedServers.length);
assertEquals("soul", decodedServers[0]);
assertEquals("navi", decodedServers[1]);
}
@Test
public void encodeDecodeBlob() {
byte[] blob = new byte[] { 0x42, (byte) 0xDE, (byte) 0xAD, (byte) 0xBE, (byte) 0xEF };
ByteBuffer bb = ByteBuffer.allocate(100);
EncodingRule.encode(bb, blob);
bb.flip();
byte[] decodedBlob = EncodingRule.decodeBlob(bb);
assertEquals(blob.length, decodedBlob.length);
for (int i = 0; i < blob.length; i++) {
assertEquals(blob[i], decodedBlob[i]);
}
}
@Test
public void lengthTest() {
ByteBuffer bb = ByteBuffer.allocate(100);
bb.mark();
// int
int intSamples[] = { 1, 10, 200, 2000, 1000000, -1, -2000 };
for (int value : intSamples) {
EncodingRule.encodeInt(bb, value);
assertEquals(EncodingRule.lengthOfInt(value), bb.position());
bb.reset();
}
// null
EncodingRule.encodeNull(bb);
assertEquals(EncodingRule.lengthOfNull(), bb.position());
bb.reset();
// short
short shortSamples[] = { 1, 10, 200, 2000, -1, -2000 };
for (short value : shortSamples) {
EncodingRule.encodeShort(bb, value);
assertEquals(EncodingRule.lengthOfShort(value), bb.position());
bb.reset();
}
// string
String stringSamples[] = { "sample", "chia", "pixar up", "asdfjkl;awefjkl;",
"This method transfers the bytes remaining in the given source" };
for (String value : stringSamples) {
EncodingRule.encodeString(bb, value);
assertEquals(EncodingRule.lengthOfString(value), bb.position());
bb.reset();
}
// date
Date dateSample = new Date();
EncodingRule.encodeDate(bb, dateSample);
assertEquals(EncodingRule.lengthOfDate(), bb.position());
bb.reset();
// address
Inet4Address in4 = null;
try {
in4 = (Inet4Address) InetAddress.getLocalHost();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
EncodingRule.encodeIp4(bb, in4);
assertEquals(EncodingRule.lengthOfIp4(in4), bb.position());
bb.reset();
// map
Map<String, Object> mapSample = new HashMap<String, Object>();
mapSample.put("address", in4);
mapSample.put("blabla", "aerosmith");
mapSample.put("date", new Date());
EncodingRule.encodeMap(bb, mapSample);
assertEquals(EncodingRule.lengthOfMap(mapSample), bb.position());
bb.reset();
// array
Object[] arraySample = { "24", new Date(), in4, "bla" };
EncodingRule.encodeArray(bb, arraySample);
assertEquals(EncodingRule.lengthOfArray(arraySample), bb.position());
bb.reset();
// blob
byte[] blobSample = { 1, 100, 110, -110, -5 };
EncodingRule.encodeBlob(bb, blobSample);
assertEquals(EncodingRule.lengthOfBlob(blobSample), bb.position());
bb.reset();
}
}