encoder.go 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. package qpack
  2. import (
  3. "io"
  4. )
  5. // An Encoder performs QPACK encoding.
  6. type Encoder struct {
  7. wrotePrefix bool
  8. w io.Writer
  9. buf []byte
  10. }
  11. // NewEncoder returns a new Encoder which performs QPACK encoding. An
  12. // encoded data is written to w.
  13. func NewEncoder(w io.Writer) *Encoder {
  14. return &Encoder{w: w}
  15. }
  16. // WriteField encodes f into a single Write to e's underlying Writer.
  17. // This function may also produce bytes for the Header Block Prefix
  18. // if necessary. If produced, it is done before encoding f.
  19. func (e *Encoder) WriteField(f HeaderField) error {
  20. // write the Header Block Prefix
  21. if !e.wrotePrefix {
  22. e.buf = appendVarInt(e.buf, 8, 0)
  23. e.buf = appendVarInt(e.buf, 7, 0)
  24. e.wrotePrefix = true
  25. }
  26. e.writeLiteralFieldWithoutNameReference(f)
  27. e.w.Write(e.buf)
  28. e.buf = e.buf[:0]
  29. return nil
  30. }
  31. // Close declares that the encoding is complete and resets the Encoder
  32. // to be reused again for a new header block.
  33. func (e *Encoder) Close() error {
  34. e.wrotePrefix = false
  35. return nil
  36. }
  37. func (e *Encoder) writeLiteralFieldWithoutNameReference(f HeaderField) {
  38. offset := len(e.buf)
  39. e.buf = appendVarInt(e.buf, 3, uint64(len(f.Name)))
  40. e.buf[offset] ^= 0x20
  41. e.buf = append(e.buf, []byte(f.Name)...)
  42. e.buf = appendVarInt(e.buf, 7, uint64(len(f.Value)))
  43. e.buf = append(e.buf, []byte(f.Value)...)
  44. }