package com.firefly.codec.http2.hpack; import java.nio.ByteBuffer; public class NBitInteger { public static int octectsNeeded(int n, int i) { if (n == 8) { int nbits = 0xFF; i = i - nbits; if (i < 0) return 1; if (i == 0) return 2; int lz = Integer.numberOfLeadingZeros(i); int log = 32 - lz; return 1 + (log + 6) / 7; } int nbits = 0xFF >>> (8 - n); i = i - nbits; if (i < 0) return 0; if (i == 0) return 1; int lz = Integer.numberOfLeadingZeros(i); int log = 32 - lz; return (log + 6) / 7; } public static void encode(ByteBuffer buf, int n, int i) { if (n == 8) { if (i < 0xFF) { buf.put((byte) i); } else { buf.put((byte) 0xFF); int length = i - 0xFF; while (true) { if ((length & ~0x7F) == 0) { buf.put((byte) length); return; } else { buf.put((byte) ((length & 0x7F) | 0x80)); length >>>= 7; } } } } else { int p = buf.position() - 1; int bits = 0xFF >>> (8 - n); if (i < bits) { buf.put(p, (byte) ((buf.get(p) & ~bits) | i)); } else { buf.put(p, (byte) (buf.get(p) | bits)); int length = i - bits; while (true) { if ((length & ~0x7F) == 0) { buf.put((byte) length); return; } else { buf.put((byte) ((length & 0x7F) | 0x80)); length >>>= 7; } } } } } public static int decode(ByteBuffer buffer, int n) { if (n == 8) { int nbits = 0xFF; int i = buffer.get() & 0xff; if (i == nbits) { int m = 1; int b; do { b = 0xff & buffer.get(); i = i + (b & 127) * m; m = m * 128; } while ((b & 128) == 128); } return i; } int nbits = 0xFF >>> (8 - n); int i = buffer.get(buffer.position() - 1) & nbits; if (i == nbits) { int m = 1; int b; do { b = 0xff & buffer.get(); i = i + (b & 127) * m; m = m * 128; } while ((b & 128) == 128); } return i; } }