Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 package frame | |
| 6 | |
| 7 import ( | |
| 8 "bytes" | |
| 9 "encoding/binary" | |
| 10 "io" | |
| 11 ) | |
| 12 | |
| 13 type frameWriter interface { | |
| 14 io.WriteCloser | |
| 15 | |
| 16 // Flush creates a new frame for the buffered written data. | |
| 17 Flush() error | |
| 18 } | |
|
iannucci
2015/08/03 22:21:24
interface assertion
dnj
2015/08/03 22:42:58
(see above, NewWriter).
| |
| 19 | |
| 20 // WriteFrame writes a single frame to an io.Writer. | |
| 21 func WriteFrame(w io.Writer, frame []byte) (int, error) { | |
| 22 var sizeBuf [binary.MaxVarintLen64]byte | |
|
iannucci
2015/08/03 22:21:24
why not just `make([]byte, binary.MaxVarintLen64)`
dnj
2015/08/03 22:42:58
I _think_ because this is a stack allocation, and
iannucci
2015/08/04 17:13:50
No it's not... the compiler analyzes all pointers
dnj
2015/08/04 17:51:41
Oh, interesting. I didn't know that. This suggests
| |
| 23 sizeBytes := binary.PutUvarint(sizeBuf[:], uint64(len(frame))) | |
| 24 | |
| 25 count, err := w.Write(sizeBuf[:sizeBytes]) | |
| 26 if err != nil { | |
| 27 return count, err | |
| 28 } | |
| 29 | |
| 30 amount, err := w.Write(frame) | |
| 31 count += amount | |
| 32 if err != nil { | |
| 33 return count, err | |
| 34 } | |
| 35 | |
| 36 return count, nil | |
| 37 } | |
| 38 | |
| 39 // Writer implements the io.Writer interface. Data written to the Writer is | |
| 40 // translated into a series of frames. Each frame is spearated by a call to | |
| 41 // Flush. | |
| 42 // | |
| 43 // Frame boundaries are created by calling Flush or Close. Close does not close | |
| 44 // the wrapped Writer. | |
| 45 // | |
| 46 // Flush will always write a frame, even if the frame's data size is zero. | |
| 47 // Close, on the other hand, will only write a frame if at least one Write | |
| 48 // (even for zero bytes) has been called for that frame. | |
|
iannucci
2015/08/03 22:21:24
I don't think this is true anymore? Looks like thi
dnj
2015/08/03 22:42:58
Oh sorry, updated.
| |
| 49 // | |
| 50 // Data written over consecutive Write calls belongs to the same frame. It is | |
| 51 // buffered until a frame boundary is created. | |
| 52 type Writer interface { | |
| 53 io.Writer | |
| 54 | |
| 55 // Flush writes the buffered frame | |
| 56 Flush() error | |
| 57 } | |
| 58 | |
| 59 // writer implements the Writer interface by wrapping an io.Writer. | |
| 60 type writer struct { | |
| 61 inner io.Writer | |
| 62 buf bytes.Buffer | |
| 63 } | |
| 64 | |
| 65 // NewWriter creates a new Writer instance that data as frames to an underlying | |
| 66 // io.Writer. | |
| 67 func NewWriter(w io.Writer) Writer { | |
| 68 return &writer{ | |
| 69 inner: w, | |
| 70 } | |
| 71 } | |
| 72 | |
| 73 func (w *writer) Write(data []byte) (int, error) { | |
| 74 return w.buf.Write(data) | |
| 75 } | |
| 76 | |
| 77 func (w *writer) Flush() error { | |
| 78 _, err := WriteFrame(w.inner, w.buf.Bytes()) | |
| 79 if err != nil { | |
| 80 return err | |
| 81 } | |
| 82 | |
| 83 w.buf.Reset() | |
| 84 return nil | |
| 85 } | |
| OLD | NEW |