implement huffman encoding
This commit is contained in:
parent
76724d8dfd
commit
48f1668b28
|
@ -344,6 +344,8 @@ public class Huffman
|
||||||
|
|
||||||
static public String decode(ByteBuffer buf) throws IOException
|
static public String decode(ByteBuffer buf) throws IOException
|
||||||
{
|
{
|
||||||
|
// TODO offer a version that does a direct lookup of compressed strings to known values
|
||||||
|
|
||||||
StringBuilder out = new StringBuilder(buf.remaining()*2);
|
StringBuilder out = new StringBuilder(buf.remaining()*2);
|
||||||
int node = 0;
|
int node = 0;
|
||||||
int current = 0;
|
int current = 0;
|
||||||
|
@ -391,4 +393,38 @@ public class Huffman
|
||||||
|
|
||||||
return out.toString();
|
return out.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static public void encode(ByteBuffer buf,String s) throws IOException
|
||||||
|
{
|
||||||
|
long current = 0;
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
int len = s.length();
|
||||||
|
for (int i=0;i<len;i++)
|
||||||
|
{
|
||||||
|
char c=s.charAt(i);
|
||||||
|
if (c>=128)
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
int code = CODES[c][0];
|
||||||
|
int bits = CODES[c][1];
|
||||||
|
|
||||||
|
current <<= bits;
|
||||||
|
current |= code;
|
||||||
|
n += bits;
|
||||||
|
|
||||||
|
while (n >= 8)
|
||||||
|
{
|
||||||
|
n -= 8;
|
||||||
|
buf.put((byte)(current >> n));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n > 0)
|
||||||
|
{
|
||||||
|
current <<= (8 - n);
|
||||||
|
current |= (0xFF >>> n);
|
||||||
|
buf.put((byte)current);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,7 +114,7 @@ public class NBitInteger
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int dencode5(ByteBuffer buf)
|
public static int decode5(ByteBuffer buf)
|
||||||
{
|
{
|
||||||
int nbits = 0xFF >>> (8 - 5);
|
int nbits = 0xFF >>> (8 - 5);
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ public class NBitInteger
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int dencode8(ByteBuffer buf)
|
public static int decode8(ByteBuffer buf)
|
||||||
{
|
{
|
||||||
int nbits = 0xFF >>> (8 - 8);
|
int nbits = 0xFF >>> (8 - 8);
|
||||||
|
|
||||||
|
|
|
@ -21,12 +21,12 @@ package org.eclipse.jetty.hpack;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.eclipse.jetty.util.TypeUtil;
|
import org.eclipse.jetty.util.TypeUtil;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class HuffmanTest
|
public class HuffmanTest
|
||||||
{
|
{
|
||||||
|
|
||||||
String[][] tests =
|
String[][] tests =
|
||||||
{
|
{
|
||||||
{"D.4.1","e7cf9bebe89b6fb16fa9b6ff","www.example.com"},
|
{"D.4.1","e7cf9bebe89b6fb16fa9b6ff","www.example.com"},
|
||||||
|
@ -49,6 +49,21 @@ public class HuffmanTest
|
||||||
String decoded=Huffman.decode(ByteBuffer.wrap(encoded));
|
String decoded=Huffman.decode(ByteBuffer.wrap(encoded));
|
||||||
Assert.assertEquals(test[0],test[2],decoded);
|
Assert.assertEquals(test[0],test[2],decoded);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEncode() throws Exception
|
||||||
|
{
|
||||||
|
for (String[] test:tests)
|
||||||
|
{
|
||||||
|
ByteBuffer buf = BufferUtil.allocate(1024);
|
||||||
|
int pos=BufferUtil.flipToFill(buf);
|
||||||
|
Huffman.encode(buf,test[2]);
|
||||||
|
BufferUtil.flipToFlush(buf,pos);
|
||||||
|
String encoded=TypeUtil.toHexString(BufferUtil.toArray(buf)).toLowerCase();
|
||||||
|
Assert.assertEquals(test[0],test[1],encoded);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ public class NBitIntegerTest
|
||||||
ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString("77EaFF"));
|
ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString("77EaFF"));
|
||||||
buf.position(2);
|
buf.position(2);
|
||||||
|
|
||||||
Assert.assertEquals(10,NBitInteger.dencode5(buf));
|
Assert.assertEquals(10,NBitInteger.decode5(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ public class NBitIntegerTest
|
||||||
ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString("881f9a0aff"));
|
ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString("881f9a0aff"));
|
||||||
buf.position(2);
|
buf.position(2);
|
||||||
|
|
||||||
Assert.assertEquals(1337,NBitInteger.dencode5(buf));
|
Assert.assertEquals(1337,NBitInteger.decode5(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ public class NBitIntegerTest
|
||||||
ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString("882aFf"));
|
ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString("882aFf"));
|
||||||
buf.position(1);
|
buf.position(1);
|
||||||
|
|
||||||
Assert.assertEquals(42,NBitInteger.dencode8(buf));
|
Assert.assertEquals(42,NBitInteger.decode8(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue