1 module hunt.http.codec.http.hpack.NBitInteger; 2 3 import hunt.io.ByteBuffer; 4 import hunt.util.TypeUtils; 5 6 class NBitInteger { 7 static int octectsNeeded(int n, int i) { 8 if (n == 8) { 9 int nbits = 0xFF; 10 i = i - nbits; 11 if (i < 0) 12 return 1; 13 if (i == 0) 14 return 2; 15 int lz = TypeUtils.numberOfLeadingZeros(i); 16 int log = 32 - lz; 17 return 1 + (log + 6) / 7; 18 } 19 20 int nbits = 0xFF >>> (8 - n); 21 i = i - nbits; 22 if (i < 0) 23 return 0; 24 if (i == 0) 25 return 1; 26 int lz = TypeUtils.numberOfLeadingZeros(i); 27 int log = 32 - lz; 28 return (log + 6) / 7; 29 } 30 31 static void encode(ByteBuffer buf, int n, int i) { 32 if (n == 8) { 33 if (i < 0xFF) { 34 buf.put(cast(byte) i); 35 } else { 36 buf.put(cast(byte) 0xFF); 37 38 int length = i - 0xFF; 39 while (true) { 40 if ((length & ~0x7F) == 0) { 41 buf.put(cast(byte) length); 42 return; 43 } else { 44 buf.put(cast(byte) ((length & 0x7F) | 0x80)); 45 length >>>= 7; 46 } 47 } 48 } 49 } else { 50 int p = buf.position() - 1; 51 int bits = 0xFF >>> (8 - n); 52 53 if (i < bits) { 54 buf.put(p, cast(byte) ((buf.get(p) & ~bits) | i)); 55 } else { 56 buf.put(p, cast(byte) (buf.get(p) | bits)); 57 58 int length = i - bits; 59 while (true) { 60 if ((length & ~0x7F) == 0) { 61 buf.put(cast(byte) length); 62 return; 63 } else { 64 buf.put(cast(byte) ((length & 0x7F) | 0x80)); 65 length >>>= 7; 66 } 67 } 68 } 69 } 70 } 71 72 static int decode(ByteBuffer buffer, int n) { 73 if (n == 8) { 74 int nbits = 0xFF; 75 76 int i = buffer.get() & 0xff; 77 78 if (i == nbits) { 79 int m = 1; 80 int b; 81 do { 82 b = 0xff & buffer.get(); 83 i = i + (b & 127) * m; 84 m = m * 128; 85 } while ((b & 128) == 128); 86 } 87 return i; 88 } 89 90 int nbits = 0xFF >>> (8 - n); 91 92 int i = buffer.get(buffer.position() - 1) & nbits; 93 94 if (i == nbits) { 95 int m = 1; 96 int b; 97 do { 98 b = 0xff & buffer.get(); 99 i = i + (b & 127) * m; 100 m = m * 128; 101 } while ((b & 128) == 128); 102 } 103 return i; 104 } 105 }