Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(267)

Side by Side Diff: common/logdog/frame/writer.go

Issue 1253353008: logdog: Add frame read/write library. (Closed) Base URL: https://github.com/luci/luci-go@logdog-review-output
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698