/
encoder.go
120 lines (101 loc) · 2.71 KB
/
encoder.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package hpack
import (
"github.com/Jxck/hpack/huffman"
integer "github.com/Jxck/hpack/integer_representation"
. "github.com/Jxck/logger"
"github.com/Jxck/swrap"
)
func (frame *IndexedHeader) Encode() (buf *swrap.SWrap) {
buf = swrap.Make(integer.Encode(frame.Index, 7))
(*buf)[0] += 0x80
if frame.Index == 0 {
// TODO: Encoding Error
}
return buf
}
func (frame *IndexedLiteral) Encode() (buf *swrap.SWrap) {
switch frame.Indexing {
case WITH:
buf = swrap.Make(integer.Encode(frame.Index, 6))
(*buf)[0] += 0x20
case WITHOUT:
buf = swrap.Make(integer.Encode(frame.Index, 4))
case NEVER:
buf = swrap.Make(integer.Encode(frame.Index, 4))
(*buf)[0] += 0x8
}
// No Huffman
buf.Merge(integer.Encode(frame.ValueLength, 7))
buf.Merge([]byte(frame.ValueString))
return buf
}
func (frame *IndexedLiteral) EncodeHuffman() (buf *swrap.SWrap) {
switch frame.Indexing {
case WITH:
buf = swrap.Make(integer.Encode(frame.Index, 6))
(*buf)[0] += 0x20
case WITHOUT:
buf = swrap.Make(integer.Encode(frame.Index, 4))
case NEVER:
buf = swrap.Make(integer.Encode(frame.Index, 4))
(*buf)[0] += 0x8
}
var encoded, length []byte
// Value With Huffman
encoded = huffman.Encode([]byte(frame.ValueString))
length = integer.Encode(uint32(len(encoded)), 7)
length[0] += 0x80 // 1000 0000 (huffman flag)
buf.Merge(length)
buf.Merge(encoded)
return buf
}
func (frame *StringLiteral) Encode() (buf *swrap.SWrap) {
buf = new(swrap.SWrap)
switch frame.Indexing {
case WITH:
buf.Add(0x40) // 0100 0000
case WITHOUT:
buf.Add(0) // 0000 0000
case NEVER:
buf.Add(0x10) // 0001 0000
}
// No Huffman
buf.Merge(integer.Encode(frame.NameLength, 7))
buf.Merge([]byte(frame.NameString))
// No Huffman
buf.Merge(integer.Encode(frame.ValueLength, 7))
buf.Merge([]byte(frame.ValueString))
return buf
}
func (frame *StringLiteral) EncodeHuffman() (buf *swrap.SWrap) {
buf = new(swrap.SWrap)
switch frame.Indexing {
case WITH:
buf.Add(0x40) // 0100 0000
case WITHOUT:
buf.Add(0) // 0000 0000
case NEVER:
buf.Add(0x10) // 0001 0000
}
var encoded, length []byte
// Name With Huffman
encoded = huffman.Encode([]byte(frame.NameString))
length = integer.Encode(uint32(len(encoded)), 7)
length[0] += 0x80 // 1000 0000 (huffman flag)
buf.Merge(length)
buf.Merge(encoded)
// Value With Huffman
encoded = huffman.Encode([]byte(frame.ValueString))
length = integer.Encode(uint32(len(encoded)), 7)
length[0] += 0x80 // 1000 0000 (huffman flag)
buf.Merge(length)
buf.Merge(encoded)
Trace("huffman encoded %s %v", frame, *buf)
return buf
}
func (frame *DynamicTableSizeUpdate) Encode() (buf *swrap.SWrap) {
buf = new(swrap.SWrap)
buf.Add(0x20) // 0010 0000
buf.Merge(integer.Encode(frame.MaxSize, 4))
return buf
}