Decoder.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /*
  2. * Copyright (c) 2014 by Farsight Security, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package framestream
  17. import (
  18. "io"
  19. "time"
  20. )
  21. // DecoderOptions specifies configuration for a framestream Decoder.
  22. type DecoderOptions struct {
  23. // MaxPayloadSize is the largest frame size accepted by the Decoder.
  24. //
  25. // If the Frame Streams Writer sends a frame in excess of this size,
  26. // Decode() will return the error ErrDataFrameTooLarge. The Decoder
  27. // attempts to recover from this error, so calls to Decode() after
  28. // receiving this error may succeed.
  29. MaxPayloadSize uint32
  30. // The ContentType expected by the Decoder. May be left unset for no
  31. // content negotiation. If the Writer requests a different content type,
  32. // NewDecoder() will return ErrContentTypeMismatch.
  33. ContentType []byte
  34. // If Bidirectional is true, the underlying io.Reader must be an
  35. // io.ReadWriter, and the Decoder will engage in a bidirectional
  36. // handshake with its peer to establish content type and communicate
  37. // shutdown.
  38. Bidirectional bool
  39. // Timeout gives the timeout for reading the initial handshake messages
  40. // from the peer and writing response messages if Bidirectional. It is
  41. // only effective for underlying Readers satisfying net.Conn.
  42. Timeout time.Duration
  43. }
  44. // A Decoder decodes Frame Streams frames read from an underlying io.Reader.
  45. //
  46. // It is provided for compatibility. Use Reader instead.
  47. type Decoder struct {
  48. buf []byte
  49. r *Reader
  50. }
  51. // NewDecoder returns a Decoder using the given io.Reader and options.
  52. func NewDecoder(r io.Reader, opt *DecoderOptions) (*Decoder, error) {
  53. if opt == nil {
  54. opt = &DecoderOptions{}
  55. }
  56. if opt.MaxPayloadSize == 0 {
  57. opt.MaxPayloadSize = DEFAULT_MAX_PAYLOAD_SIZE
  58. }
  59. ropt := &ReaderOptions{
  60. Bidirectional: opt.Bidirectional,
  61. Timeout: opt.Timeout,
  62. }
  63. if opt.ContentType != nil {
  64. ropt.ContentTypes = append(ropt.ContentTypes, opt.ContentType)
  65. }
  66. dr, err := NewReader(r, ropt)
  67. if err != nil {
  68. return nil, err
  69. }
  70. dec := &Decoder{
  71. buf: make([]byte, opt.MaxPayloadSize),
  72. r: dr,
  73. }
  74. return dec, nil
  75. }
  76. // Decode returns the data from a Frame Streams data frame. The slice returned
  77. // is valid until the next call to Decode.
  78. func (dec *Decoder) Decode() (frameData []byte, err error) {
  79. n, err := dec.r.ReadFrame(dec.buf)
  80. if err != nil {
  81. return nil, err
  82. }
  83. return dec.buf[:n], nil
  84. }