func DecodeLiteral(buf *swrap.SWrap) (value string) { // 最初のバイトを取り出す first := (*buf)[0] // 最初の 1bit をみて huffman かどうか取得 huffmanEncoded := (first&0x80 == 0x80) Trace("huffman = %t", huffmanEncoded) if huffmanEncoded { // 最初のバイトから 1 bit 目を消す (*buf)[0] = first & 127 // ここで prefixed Integer 7 で読む。 b := DecodePrefixedInteger(buf, 7) Trace("Literal Length = %v, buf size=%v", b, buf.Len()) // その長さの分だけバイト値を取り出す code := make([]byte, 0) for ; b > 0; b-- { code = append(code, buf.Shift()) } // ハフマンデコード value = string(huffman.Decode(code)) Trace("decoded = %v", value) } else { valueLength := DecodePrefixedInteger(buf, 7) value = DecodeString(buf, valueLength) } return value }
// read n byte from buffer as string func DecodeString(buf *swrap.SWrap, n uint32) string { valueBytes := make([]byte, 0, n) for i := n; i > 0; i-- { valueBytes = append(valueBytes, buf.Shift()) } return string(valueBytes) }
func (c *Context) Encode(headerList HeaderList) []byte { var buf swrap.SWrap // 全て StringLiteral(Indexing = false) でエンコード for _, h := range headerList { sl := NewStringLiteral(WITHOUT, h.Name, h.Value) buf.Merge(*sl.EncodeHuffman()) } return buf.Bytes() }
// Decode N bit prefixed Representation // to Integer // // Read N bit from first 1 byte as I // If I < 2^N-1 // decode I // Else // i = 0 // read next 1 byte as b // While b > 128 // I += (b - 128) * 128^(i-1) // i++ func Decode(buf swrap.SWrap, N uint8) uint32 { boundary := uint32(1<<N - 1) // 2^N-1 I := uint32(buf.Shift()) // Read N bit from first 1 byte as I if I < boundary { // less than 2^N-1 return I // as is } for i := 0; ; i++ { // continue while follow bites are bigger than 128 b := buf.Shift() shift := uint8(7 * i) if b >= 128 { // if first bit is 1 // to 0 at first bit (- 128) and shift 7*i bit // and add I += uint32(b-128) << shift } else { // if first bit is 0 // shit 7*i shift // and add I += uint32(b) << shift break } } return I }
// read prefixed N bytes from buffer // if N bit of first byte is 2^N-1 (ex 1111 in N=4) // read follow byte until it's smaller than 128 func ReadPrefixedInteger(buf *swrap.SWrap, N uint8) swrap.SWrap { boundary := byte(1<<N - 1) // 2^N-1 first := buf.Shift() first = first & boundary // mask N bit prefix := swrap.New([]byte{first}) // if first byte is smaller than boundary // it's end of the prefixed bytes if first < boundary { return prefix } // read bytes while bytes smaller than 128 for { tmp := buf.Shift() prefix.Add(tmp) if tmp < 128 { break } } return prefix }
// Decode single Frame from buffer and return it func DecodeHeader(buf *swrap.SWrap) Frame { // check first byte types := (*buf)[0] Trace("types = %v", types) if types >= 0x80 { // 1xxx xxxx Debug("Indexed Header Representation") index := DecodePrefixedInteger(buf, 7) Trace("Indexed = %v", index) frame := NewIndexedHeader(index) if index == 0 { // TODO: Decoding Error // log.Fatal("Decoding Error: The index value of 0 is not used.") } return frame } if types == 0 { // 0000 0000 Debug("StringLiteral (indexing = WITHOUT)") // remove first byte defines type buf.Shift() indexing := WITHOUT name := DecodeLiteral(buf) Trace("StringLiteral name = %v", name) value := DecodeLiteral(buf) Trace("StringLiteral value = %v", value) frame := NewStringLiteral(indexing, name, value) return frame } if types == 0x10 { // 0001 0000 Debug("StringLiteral (indexing = NEVER)") // remove first byte defines type buf.Shift() indexing := NEVER name := DecodeLiteral(buf) Trace("StringLiteral name = %v", name) value := DecodeLiteral(buf) Trace("StringLiteral value = %v", value) frame := NewStringLiteral(indexing, name, value) return frame } if types == 0x40 { // 0100 0000 Debug("StringLiteral (indexing = WITH)") // remove first byte defines type buf.Shift() indexing := WITH name := DecodeLiteral(buf) Trace("StringLiteral name = %v", name) value := DecodeLiteral(buf) Trace("StringLiteral value = %v", value) frame := NewStringLiteral(indexing, name, value) return frame } if types&0xc0 == 0x40 { // 01xx xxxx & 1100 0000 == 0100 0000 Debug("IndexedLiteral (indexing = WITH)") indexing := WITH index := DecodePrefixedInteger(buf, 6) Trace("IndexedLiteral index = %v", index) value := DecodeLiteral(buf) Trace("IndexedLiteral value = %v", value) frame := NewIndexedLiteral(indexing, index, value) return frame } if types&0xf0 == 0 { // 0000 xxxx & 1111 0000 == 0000 0000 Debug("IndexedLiteral (indexing = WITHOUT)") indexing := WITHOUT index := DecodePrefixedInteger(buf, 4) Trace("IndexedLiteral index = %v", index) value := DecodeLiteral(buf) Trace("IndexedLiteral value = %v", value) frame := NewIndexedLiteral(indexing, index, value) return frame } if types&0xf0 == 0x10 { // 0000 xxxx & 1111 0000 == 0001 0000 Debug("IndexedLiteral (indexing = NEVER)") indexing := NEVER index := DecodePrefixedInteger(buf, 4) Trace("IndexedLiteral index = %v", index) value := DecodeLiteral(buf) Trace("IndexedLiteral value = %v", value) frame := NewIndexedLiteral(indexing, index, value) return frame } if types&0xe0 == 0x20 { // 001x xxxx & 1110 0000 == 0010 0000 Debug("Header Table Size Update") maxSize := DecodePrefixedInteger(buf, 5) frame := NewDynamicTableSizeUpdate(maxSize) return frame } return nil }