diff options
author | Alberto Cortés <alcortesm@gmail.com> | 2016-10-26 17:56:26 +0200 |
---|---|---|
committer | Máximo Cuadros <mcuadros@gmail.com> | 2016-10-26 15:56:26 +0000 |
commit | 73fa9ef25a8af9c8337a4cf34a67cfe208f1a7c5 (patch) | |
tree | 66886d9b47e373b748c1bceafe1885e6f47868dd /formats/packp/pktline | |
parent | f3ab3a6c73015b5ae9b2a4756dc646e1211cedb9 (diff) | |
download | go-git-73fa9ef25a8af9c8337a4cf34a67cfe208f1a7c5.tar.gz |
Use advrefs in gituploadpackinfo (#92)
* add advrefs encoder and parser
* modify advrefs encoder to resemble json encoder
* turn advrefs parser into a decoder
* clean code
* improve documentation
* improve documentation
* clean code
* upgrade to new pktline.Add and add Flush const to easy integration
* gometalinter
* Use packp/advrefs for GitUploadPackInfo parsing
- GitUploadPackInfo now uses packp/advrefs instead of parsing the
message by itself.
- Capabilities has been moved from clients/common to packp to avoid a
circular import.
- Cleaning of advrefs_test code.
- Add support for prefix encoding and decoding in advrefs.
* clean advrefs test code
* clean advrefs test code
* clean advrefs test code
* gometalinter
* add pktline encoder
* change pktline.EncodeFlush to pktline.Flush
* make scanner tests use the encoder instead of Pktlines
* check errors on flush and clean constants
* ubstitute the PktLines type with a pktline.Encoder
* use pktline.Encoder in all go-git
* add example of pktline.Encodef()
* add package overview
* documentation
* support symbolic links other than HEAD
* simplify decoding of shallows
* packp: fix mcuadros comments
- all abbreviates removed (by visual inspection, some may remain)
- all empty maps are initialized using make
- simplify readRef with a switch
- make decodeShallow malformed error more verbose
- add pktline.Encoder.encodeLine
- remove infamous panic in checkPayloadLength by refactoring out
the whole function
Diffstat (limited to 'formats/packp/pktline')
-rw-r--r-- | formats/packp/pktline/encoder.go | 123 | ||||
-rw-r--r-- | formats/packp/pktline/encoder_test.go | 249 | ||||
-rw-r--r-- | formats/packp/pktline/pktlines.go | 140 | ||||
-rw-r--r-- | formats/packp/pktline/pktlines_test.go | 231 | ||||
-rw-r--r-- | formats/packp/pktline/scanner_test.go | 46 |
5 files changed, 402 insertions, 387 deletions
diff --git a/formats/packp/pktline/encoder.go b/formats/packp/pktline/encoder.go new file mode 100644 index 0000000..0a88a9b --- /dev/null +++ b/formats/packp/pktline/encoder.go @@ -0,0 +1,123 @@ +// Package pktline implements reading payloads form pkt-lines and encoding pkt-lines from payloads. +package pktline + +import ( + "bytes" + "errors" + "fmt" + "io" +) + +// An Encoder writes pkt-lines to an output stream. +type Encoder struct { + w io.Writer +} + +const ( + // MaxPayloadSize is the maximum payload size of a pkt-line in bytes. + MaxPayloadSize = 65516 +) + +var ( + // FlushPkt are the contents of a flush-pkt pkt-line. + FlushPkt = []byte{'0', '0', '0', '0'} + // Flush is the payload to use with the Encode method to encode a flush-pkt. + Flush = []byte{} + // FlushString is the payload to use with the EncodeString method to encode a flush-pkt. + FlushString = "" + // ErrPayloadTooLong is returned by the Encode methods when any of the + // provided payloads is bigger than MaxPayloadSize. + ErrPayloadTooLong = errors.New("payload is too long") +) + +// NewEncoder returns a new encoder that writes to w. +func NewEncoder(w io.Writer) *Encoder { + return &Encoder{ + w: w, + } +} + +// Flush encodes a flush-pkt to the output stream. +func (e *Encoder) Flush() error { + _, err := e.w.Write(FlushPkt) + return err +} + +// Encode encodes a pkt-line with the payload specified and write it to +// the output stream. If several payloads are specified, each of them +// will get streamed in their own pkt-lines. +func (e *Encoder) Encode(payloads ...[]byte) error { + for _, p := range payloads { + if err := e.encodeLine(p); err != nil { + return err + } + } + + return nil +} + +func (e *Encoder) encodeLine(p []byte) error { + if len(p) > MaxPayloadSize { + return ErrPayloadTooLong + } + + if bytes.Equal(p, Flush) { + if err := e.Flush(); err != nil { + return err + } + return nil + } + + n := len(p) + 4 + if _, err := e.w.Write(asciiHex16(n)); err != nil { + return err + } + if _, err := e.w.Write(p); err != nil { + return err + } + + return nil +} + +// Returns the hexadecimal ascii representation of the 16 less +// significant bits of n. The length of the returned slice will always +// be 4. Example: if n is 1234 (0x4d2), the return value will be +// []byte{'0', '4', 'd', '2'}. +func asciiHex16(n int) []byte { + var ret [4]byte + ret[0] = byteToASCIIHex(byte(n & 0xf000 >> 12)) + ret[1] = byteToASCIIHex(byte(n & 0x0f00 >> 8)) + ret[2] = byteToASCIIHex(byte(n & 0x00f0 >> 4)) + ret[3] = byteToASCIIHex(byte(n & 0x000f)) + + return ret[:] +} + +// turns a byte into its hexadecimal ascii representation. Example: +// from 11 (0xb) to 'b'. +func byteToASCIIHex(n byte) byte { + if n < 10 { + return '0' + n + } + + return 'a' - 10 + n +} + +// EncodeString works similarly as Encode but payloads are specified as strings. +func (e *Encoder) EncodeString(payloads ...string) error { + for _, p := range payloads { + if err := e.Encode([]byte(p)); err != nil { + return err + } + } + + return nil +} + +// Encodef encodes a single pkt-line with the payload formatted as +// the format specifier and the rest of the arguments suggest. +func (e *Encoder) Encodef(format string, a ...interface{}) error { + return e.EncodeString( + fmt.Sprintf(format, a...), + ) +} diff --git a/formats/packp/pktline/encoder_test.go b/formats/packp/pktline/encoder_test.go new file mode 100644 index 0000000..5990ea5 --- /dev/null +++ b/formats/packp/pktline/encoder_test.go @@ -0,0 +1,249 @@ +package pktline_test + +import ( + "bytes" + "os" + "strings" + "testing" + + "gopkg.in/src-d/go-git.v4/formats/packp/pktline" + + . "gopkg.in/check.v1" +) + +func Test(t *testing.T) { TestingT(t) } + +type SuiteEncoder struct{} + +var _ = Suite(&SuiteEncoder{}) + +func (s *SuiteEncoder) TestFlush(c *C) { + var buf bytes.Buffer + e := pktline.NewEncoder(&buf) + + err := e.Flush() + c.Assert(err, IsNil) + + obtained := buf.Bytes() + c.Assert(obtained, DeepEquals, pktline.FlushPkt) +} + +func (s *SuiteEncoder) TestEncode(c *C) { + for i, test := range [...]struct { + input [][]byte + expected []byte + }{ + { + input: [][]byte{ + []byte("hello\n"), + }, + expected: []byte("000ahello\n"), + }, { + input: [][]byte{ + []byte("hello\n"), + pktline.Flush, + }, + expected: []byte("000ahello\n0000"), + }, { + input: [][]byte{ + []byte("hello\n"), + []byte("world!\n"), + []byte("foo"), + }, + expected: []byte("000ahello\n000bworld!\n0007foo"), + }, { + input: [][]byte{ + []byte("hello\n"), + pktline.Flush, + []byte("world!\n"), + []byte("foo"), + pktline.Flush, + }, + expected: []byte("000ahello\n0000000bworld!\n0007foo0000"), + }, { + input: [][]byte{ + []byte(strings.Repeat("a", pktline.MaxPayloadSize)), + }, + expected: []byte( + "fff0" + strings.Repeat("a", pktline.MaxPayloadSize)), + }, { + input: [][]byte{ + []byte(strings.Repeat("a", pktline.MaxPayloadSize)), + []byte(strings.Repeat("b", pktline.MaxPayloadSize)), + }, + expected: []byte( + "fff0" + strings.Repeat("a", pktline.MaxPayloadSize) + + "fff0" + strings.Repeat("b", pktline.MaxPayloadSize)), + }, + } { + comment := Commentf("input %d = %v\n", i, test.input) + + var buf bytes.Buffer + e := pktline.NewEncoder(&buf) + + err := e.Encode(test.input...) + c.Assert(err, IsNil, comment) + + c.Assert(buf.Bytes(), DeepEquals, test.expected, comment) + } +} + +func (s *SuiteEncoder) TestEncodeErrPayloadTooLong(c *C) { + for i, input := range [...][][]byte{ + [][]byte{ + []byte(strings.Repeat("a", pktline.MaxPayloadSize+1)), + }, + [][]byte{ + []byte("hello world!"), + []byte(strings.Repeat("a", pktline.MaxPayloadSize+1)), + }, + [][]byte{ + []byte("hello world!"), + []byte(strings.Repeat("a", pktline.MaxPayloadSize+1)), + []byte("foo"), + }, + } { + comment := Commentf("input %d = %v\n", i, input) + + var buf bytes.Buffer + e := pktline.NewEncoder(&buf) + + err := e.Encode(input...) + c.Assert(err, Equals, pktline.ErrPayloadTooLong, comment) + } +} + +func (s *SuiteEncoder) TestEncodeStrings(c *C) { + for i, test := range [...]struct { + input []string + expected []byte + }{ + { + input: []string{ + "hello\n", + }, + expected: []byte("000ahello\n"), + }, { + input: []string{ + "hello\n", + pktline.FlushString, + }, + expected: []byte("000ahello\n0000"), + }, { + input: []string{ + "hello\n", + "world!\n", + "foo", + }, + expected: []byte("000ahello\n000bworld!\n0007foo"), + }, { + input: []string{ + "hello\n", + pktline.FlushString, + "world!\n", + "foo", + pktline.FlushString, + }, + expected: []byte("000ahello\n0000000bworld!\n0007foo0000"), + }, { + input: []string{ + strings.Repeat("a", pktline.MaxPayloadSize), + }, + expected: []byte( + "fff0" + strings.Repeat("a", pktline.MaxPayloadSize)), + }, { + input: []string{ + strings.Repeat("a", pktline.MaxPayloadSize), + strings.Repeat("b", pktline.MaxPayloadSize), + }, + expected: []byte( + "fff0" + strings.Repeat("a", pktline.MaxPayloadSize) + + "fff0" + strings.Repeat("b", pktline.MaxPayloadSize)), + }, + } { + comment := Commentf("input %d = %v\n", i, test.input) + + var buf bytes.Buffer + e := pktline.NewEncoder(&buf) + + err := e.EncodeString(test.input...) + c.Assert(err, IsNil, comment) + c.Assert(buf.Bytes(), DeepEquals, test.expected, comment) + } +} + +func (s *SuiteEncoder) TestEncodeStringErrPayloadTooLong(c *C) { + for i, input := range [...][]string{ + []string{ + strings.Repeat("a", pktline.MaxPayloadSize+1), + }, + []string{ + "hello world!", + strings.Repeat("a", pktline.MaxPayloadSize+1), + }, + []string{ + "hello world!", + strings.Repeat("a", pktline.MaxPayloadSize+1), + "foo", + }, + } { + comment := Commentf("input %d = %v\n", i, input) + + var buf bytes.Buffer + e := pktline.NewEncoder(&buf) + + err := e.EncodeString(input...) + c.Assert(err, Equals, pktline.ErrPayloadTooLong, comment) + } +} + +func (s *SuiteEncoder) TestEncodef(c *C) { + format := " %s %d\n" + str := "foo" + d := 42 + + var buf bytes.Buffer + e := pktline.NewEncoder(&buf) + + err := e.Encodef(format, str, d) + c.Assert(err, IsNil) + + expected := []byte("000c foo 42\n") + c.Assert(buf.Bytes(), DeepEquals, expected) +} + +func ExampleEncoder() { + // Create an encoder that writes pktlines to stdout. + e := pktline.NewEncoder(os.Stdout) + + // Encode some data as a new pkt-line. + _ = e.Encode([]byte("data\n")) // error checks removed for brevity + + // Encode a flush-pkt. + _ = e.Flush() + + // Encode a couple of byte slices and a flush in one go. Each of + // them will end up as payloads of their own pktlines. + _ = e.Encode( + []byte("hello\n"), + []byte("world!\n"), + pktline.Flush, + ) + + // You can also encode strings: + _ = e.EncodeString( + "foo\n", + "bar\n", + pktline.FlushString, + ) + + // You can also format and encode a payload: + _ = e.Encodef(" %s %d\n", "foo", 42) + // Output: + // 0009data + // 0000000ahello + // 000bworld! + // 00000008foo + // 0008bar + // 0000000c foo 42 +} diff --git a/formats/packp/pktline/pktlines.go b/formats/packp/pktline/pktlines.go deleted file mode 100644 index c19aa2e..0000000 --- a/formats/packp/pktline/pktlines.go +++ /dev/null @@ -1,140 +0,0 @@ -// Package pktline implements reading payloads form pkt-lines and creating pkt-lines from payloads. -package pktline - -import ( - "bytes" - "errors" - "io" - "strings" -) - -const ( - // MaxPayloadSize is the maximum payload size of a pkt-line in bytes. - MaxPayloadSize = 65516 -) - -var ( - flush = []byte{'0', '0', '0', '0'} -) - -// PktLines values represent a succession of pkt-lines. Values from -// this type are not zero-value safe, use the New function instead. -type PktLines struct { - r io.Reader -} - -var ( - // ErrPayloadTooLong is returned by the Add methods when any of the - // provided payloads is bigger than MaxPayloadSize. - ErrPayloadTooLong = errors.New("payload is too long") - // ErrEmptyPayload is returned by the Add methods when an empty - // payload is provided. - ErrEmptyPayload = errors.New("cannot add empty payloads") -) - -// New returns an empty PktLines (with no payloads) ready to be used. -func New() *PktLines { - return &PktLines{ - r: bytes.NewReader(nil), - } -} - -// AddFlush adds a flush-pkt to p. -func (p *PktLines) AddFlush() { - p.r = io.MultiReader(p.r, bytes.NewReader(flush)) -} - -// Add adds the slices in pp as the payloads of a -// corresponding number of pktlines. -func (p *PktLines) Add(pp ...[]byte) error { - tmp := []io.Reader{p.r} - for _, p := range pp { - if err := add(&tmp, p); err != nil { - return err - } - } - p.r = io.MultiReader(tmp...) - - return nil -} - -func add(dst *[]io.Reader, e []byte) error { - if err := checkPayloadLength(len(e)); err != nil { - return err - } - - n := len(e) + 4 - *dst = append(*dst, bytes.NewReader(asciiHex16(n))) - *dst = append(*dst, bytes.NewReader(e)) - - return nil -} - -func checkPayloadLength(n int) error { - switch { - case n < 0: - panic("unexpected negative payload length") - case n == 0: - return ErrEmptyPayload - case n > MaxPayloadSize: - return ErrPayloadTooLong - default: - return nil - } -} - -// Returns the hexadecimal ascii representation of the 16 less -// significant bits of n. The length of the returned slice will always -// be 4. Example: if n is 1234 (0x4d2), the return value will be -// []byte{'0', '4', 'd', '2'}. -func asciiHex16(n int) []byte { - var ret [4]byte - ret[0] = byteToASCIIHex(byte(n & 0xf000 >> 12)) - ret[1] = byteToASCIIHex(byte(n & 0x0f00 >> 8)) - ret[2] = byteToASCIIHex(byte(n & 0x00f0 >> 4)) - ret[3] = byteToASCIIHex(byte(n & 0x000f)) - - return ret[:] -} - -// turns a byte into its hexadecimal ascii representation. Example: -// from 11 (0xb) to 'b'. -func byteToASCIIHex(n byte) byte { - if n < 10 { - return '0' + n - } - - return 'a' - 10 + n -} - -// AddString adds the strings in pp as payloads of a -// corresponding number of pktlines. -func (p *PktLines) AddString(pp ...string) error { - tmp := []io.Reader{p.r} - for _, p := range pp { - if err := addString(&tmp, p); err != nil { - return err - } - } - - p.r = io.MultiReader(tmp...) - - return nil -} - -func addString(dst *[]io.Reader, s string) error { - if err := checkPayloadLength(len(s)); err != nil { - return err - } - - n := len(s) + 4 - *dst = append(*dst, bytes.NewReader(asciiHex16(n))) - *dst = append(*dst, strings.NewReader(s)) - - return nil -} - -// Read reads the pktlines for the payloads added so far. -func (p *PktLines) Read(b []byte) (n int, err error) { - return p.r.Read(b) -} diff --git a/formats/packp/pktline/pktlines_test.go b/formats/packp/pktline/pktlines_test.go deleted file mode 100644 index e0ba16b..0000000 --- a/formats/packp/pktline/pktlines_test.go +++ /dev/null @@ -1,231 +0,0 @@ -package pktline_test - -import ( - "io" - "io/ioutil" - "os" - "strings" - "testing" - - "gopkg.in/src-d/go-git.v4/formats/packp/pktline" - - . "gopkg.in/check.v1" -) - -func Test(t *testing.T) { TestingT(t) } - -type SuitePktLine struct { -} - -var _ = Suite(&SuitePktLine{}) - -func (s *SuitePktLine) TestNewIsEmpty(c *C) { - p := pktline.New() - - b, err := ioutil.ReadAll(p) - c.Assert(err, IsNil) - c.Assert(b, DeepEquals, []byte{}) -} - -func (s *SuitePktLine) TestAddFlush(c *C) { - p := pktline.New() - p.AddFlush() - - b, err := ioutil.ReadAll(p) - c.Assert(err, IsNil) - c.Assert(string(b), DeepEquals, "0000") -} - -func (s *SuitePktLine) TestAdd(c *C) { - for i, test := range [...]struct { - input [][]byte - expected []byte - }{ - { - input: [][]byte{ - []byte("hello\n"), - }, - expected: []byte("000ahello\n"), - }, { - input: [][]byte{ - []byte("hello\n"), - []byte("world!\n"), - []byte("foo"), - }, - expected: []byte("000ahello\n000bworld!\n0007foo"), - }, { - input: [][]byte{ - []byte(strings.Repeat("a", pktline.MaxPayloadSize)), - }, - expected: []byte( - "fff0" + strings.Repeat("a", pktline.MaxPayloadSize)), - }, { - input: [][]byte{ - []byte(strings.Repeat("a", pktline.MaxPayloadSize)), - []byte(strings.Repeat("b", pktline.MaxPayloadSize)), - }, - expected: []byte( - "fff0" + strings.Repeat("a", pktline.MaxPayloadSize) + - "fff0" + strings.Repeat("b", pktline.MaxPayloadSize)), - }, - } { - p := pktline.New() - err := p.Add(test.input...) - c.Assert(err, IsNil, Commentf("input %d = %v", i, test.input)) - - obtained, err := ioutil.ReadAll(p) - c.Assert(err, IsNil, Commentf("input %d = %v", i, test.input)) - - c.Assert(obtained, DeepEquals, test.expected, - Commentf("input %d = %v", i, test.input)) - } -} - -func (s *SuitePktLine) TestAddErrEmptyPayload(c *C) { - for _, input := range [...][][]byte{ - [][]byte{ - []byte{}, - }, - [][]byte{ - []byte(nil), - }, - [][]byte{ - []byte("hello world!"), - []byte{}, - }, - [][]byte{ - []byte{}, - []byte("hello world!"), - }, - } { - p := pktline.New() - err := p.Add(input...) - c.Assert(err, Equals, pktline.ErrEmptyPayload) - } -} - -func (s *SuitePktLine) TestAddErrPayloadTooLong(c *C) { - for _, input := range [...][][]byte{ - [][]byte{ - []byte(strings.Repeat("a", pktline.MaxPayloadSize+1)), - }, - [][]byte{ - []byte("hello world!"), - []byte(strings.Repeat("a", pktline.MaxPayloadSize+1)), - }, - [][]byte{ - []byte("hello world!"), - []byte(strings.Repeat("a", pktline.MaxPayloadSize+1)), - []byte("foo"), - }, - } { - p := pktline.New() - err := p.Add(input...) - c.Assert(err, Equals, pktline.ErrPayloadTooLong, - Commentf("%v\n", input)) - } -} - -func (s *SuitePktLine) TestAddString(c *C) { - for i, test := range [...]struct { - input []string - expected []byte - }{ - { - input: []string{ - "hello\n", - }, - expected: []byte("000ahello\n"), - }, { - input: []string{ - "hello\n", - "world!\n", - "foo", - }, - expected: []byte("000ahello\n000bworld!\n0007foo"), - }, { - input: []string{ - strings.Repeat("a", pktline.MaxPayloadSize), - }, - expected: []byte( - "fff0" + strings.Repeat("a", pktline.MaxPayloadSize)), - }, { - input: []string{ - strings.Repeat("a", pktline.MaxPayloadSize), - strings.Repeat("b", pktline.MaxPayloadSize), - }, - expected: []byte( - "fff0" + strings.Repeat("a", pktline.MaxPayloadSize) + - "fff0" + strings.Repeat("b", pktline.MaxPayloadSize)), - }, - } { - p := pktline.New() - err := p.AddString(test.input...) - c.Assert(err, IsNil, Commentf("input %d = %v", i, test.input)) - - obtained, err := ioutil.ReadAll(p) - c.Assert(err, IsNil, Commentf("input %d = %v", i, test.input)) - - c.Assert(obtained, DeepEquals, test.expected, - Commentf("input %d = %v", i, test.input)) - } -} - -func (s *SuitePktLine) TestAddStringErrEmptyPayload(c *C) { - for _, input := range [...][]string{ - []string{""}, - []string{"hello world!", ""}, - []string{"", "hello world!"}, - } { - p := pktline.New() - err := p.AddString(input...) - c.Assert(err, Equals, pktline.ErrEmptyPayload) - } -} - -func (s *SuitePktLine) TestAddStringErrPayloadTooLong(c *C) { - for _, input := range [...][]string{ - []string{ - strings.Repeat("a", pktline.MaxPayloadSize+1), - }, - []string{ - "hello world!", - strings.Repeat("a", pktline.MaxPayloadSize+1), - }, - []string{ - "hello world!", - strings.Repeat("a", pktline.MaxPayloadSize+1), - "foo", - }, - } { - p := pktline.New() - err := p.AddString(input...) - c.Assert(err, Equals, pktline.ErrPayloadTooLong, - Commentf("%v\n", input)) - } -} - -func ExamplePktLines() { - // Create an empty collection of pktlines. - p := pktline.New() - - // Add two strings as payloads ("foo\n" and "bar\n"), they will - // end up as two consecutive pktlines. - p.AddString("foo\n", "bar\n") // error checks removed for brevity - - // You can also add byte slices as payloads... - p.Add([]byte("hello\n"), []byte("world!\n")) - - // Add a flush-pkt. - p.AddFlush() - - // PktLines are Readers, so you can directly read the full sequence. - io.Copy(os.Stdout, p) - - // Output: - // 0008foo - // 0008bar - // 000ahello - // 000bworld! - // 0000 -} diff --git a/formats/packp/pktline/scanner_test.go b/formats/packp/pktline/scanner_test.go index de0f8df..b5a3c7d 100644 --- a/formats/packp/pktline/scanner_test.go +++ b/formats/packp/pktline/scanner_test.go @@ -1,6 +1,7 @@ package pktline_test import ( + "bytes" "fmt" "io" "strings" @@ -41,11 +42,14 @@ func (s *SuiteScanner) TestEmptyReader(c *C) { } func (s *SuiteScanner) TestFlush(c *C) { - p := pktline.New() - p.AddFlush() - sc := pktline.NewScanner(p) + var buf bytes.Buffer + e := pktline.NewEncoder(&buf) + err := e.Flush() + c.Assert(err, IsNil) + sc := pktline.NewScanner(&buf) c.Assert(sc.Scan(), Equals, true) + payload := sc.Bytes() c.Assert(len(payload), Equals, 0) } @@ -70,14 +74,16 @@ func (s *SuiteScanner) TestScanAndPayload(c *C) { strings.Repeat("a", pktline.MaxPayloadSize), strings.Repeat("a", pktline.MaxPayloadSize-1) + "\n", } { - p := pktline.New() - err := p.AddString(test) + var buf bytes.Buffer + e := pktline.NewEncoder(&buf) + err := e.EncodeString(test) c.Assert(err, IsNil, Commentf("input len=%x, contents=%.10q\n", len(test), test)) - sc := pktline.NewScanner(p) + sc := pktline.NewScanner(&buf) c.Assert(sc.Scan(), Equals, true, Commentf("test = %.20q...", test)) + obtained := sc.Bytes() c.Assert(obtained, DeepEquals, []byte(test), Commentf("in = %.20q out = %.20q", test, string(obtained))) @@ -107,16 +113,19 @@ func (s *SuiteScanner) TestSkip(c *C) { expected: []byte("third"), }, } { - p := pktline.New() - err := p.AddString(test.input...) + var buf bytes.Buffer + e := pktline.NewEncoder(&buf) + err := e.EncodeString(test.input...) c.Assert(err, IsNil) - sc := pktline.NewScanner(p) + + sc := pktline.NewScanner(&buf) for i := 0; i < test.n; i++ { c.Assert(sc.Scan(), Equals, true, Commentf("scan error = %s", sc.Err())) } c.Assert(sc.Scan(), Equals, true, Commentf("scan error = %s", sc.Err())) + obtained := sc.Bytes() c.Assert(obtained, DeepEquals, test.expected, Commentf("\nin = %.20q\nout = %.20q\nexp = %.20q", @@ -125,10 +134,12 @@ func (s *SuiteScanner) TestSkip(c *C) { } func (s *SuiteScanner) TestEOF(c *C) { - p := pktline.New() - err := p.AddString("first", "second") + var buf bytes.Buffer + e := pktline.NewEncoder(&buf) + err := e.EncodeString("first", "second") c.Assert(err, IsNil) - sc := pktline.NewScanner(p) + + sc := pktline.NewScanner(&buf) for sc.Scan() { } c.Assert(sc.Err(), IsNil) @@ -164,19 +175,22 @@ func (s *SuiteScanner) TestReadSomeSections(c *C) { // 0000 // and so on func sectionsExample(c *C, nSections, nLines int) io.Reader { - p := pktline.New() + var buf bytes.Buffer + e := pktline.NewEncoder(&buf) + for section := 0; section < nSections; section++ { ss := []string{} for line := 0; line < nLines; line++ { line := fmt.Sprintf(" %d.%d\n", section, line) ss = append(ss, line) } - err := p.AddString(ss...) + err := e.EncodeString(ss...) + c.Assert(err, IsNil) + err = e.Flush() c.Assert(err, IsNil) - p.AddFlush() } - return p + return &buf } func ExampleScanner() { |