variable byte code

Javaで実装。単なる関数なのであまりJavaっぽくないけど。都合でバイト列は引数渡し。

public class VariableByteCoder {
    
    public static void encode(int n, byte[] target, int offset) {
        int t = n;
        int i = 0;
        
        // 7ビットごとに分割
        for (; t > 0x7f; t >>>= 7) {
            target[offset + i++] = (byte)(t & 0x7f);
        }
        target[offset + i] = (byte)t;
        
        // 高位のビットを先頭に持ってくる
        int k = (i + 1) >> 1;
        for (int j=0; j<k; j++) {
            byte b = target[offset + j];
            target[offset + j] = target[offset + i - j];
            target[offset + i - j] = b;
        }
        
        // 最後にマーカー
        target[offset + i] |= 0x80;
    }
    
    public static int decode(byte[] target, int offset) {
        int n = 0;
        int p = offset;
        // 終わりが見えるまで取り出す
        for (; (target[p] & 0x80) == 0; p++) {
            n = (n << 7) | target[p];
        }
        
        // 終わりはマーカーをはずす。
        return (n << 7) | (target[p] & 0x7f);
        
    }
}


テスト。

public class VariableByteCoderTest {

    @Test
    public void test() {
        byte[] buffer = new byte[4];
        VariableByteCoder.encode(12345, buffer, 2);
        int n = VariableByteCoder.decode(buffer, 2);
        assertThat(n, is(12345));
        
        VariableByteCoder.encode(234567, buffer, 1);
        int m = VariableByteCoder.decode(buffer, 1);
        assertThat(m, is(234567));
        
        VariableByteCoder.encode(12, buffer, 3);
        int p = VariableByteCoder.decode(buffer, 3);
        assertThat(p, is(12));
    }
}