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 }