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

Side by Side Diff: common/logdog/frame/reader.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 "encoding/binary"
9 "fmt"
10 "io"
11 )
12
13 // ErrFrameTooLarge is an error that is returned if a frame that is larger than
14 // the maximum allowed size (not including the frame header) is read.
15 var ErrFrameTooLarge = fmt.Errorf("frame: frame size exceeds maximum")
16
17 // Reader reads individual frames from a frame-formatted input Reader.
18 type Reader interface {
19 // ReadFrame returns the contents of the next frame. If there are no mor e
20 // frames available, Next will return io.EOF.
21 ReadFrame() ([]byte, error)
22 }
23
24 // reader is an implementation of a Reader that uses an underlying
25 // io.Reader and io.ByteReader to read frames.
26 //
27 // The io.Reader and io.ByteReader must read from the same source.
28 type reader struct {
29 io.Reader
30 io.ByteReader
31
32 maxSize int
33 }
iannucci 2015/08/03 22:21:24 interface assertion?
dnj 2015/08/03 22:42:58 Going with vadimsh@ style: since NewReader returns
34
35 // NewReader creates a new Reader which reads frame data from the
36 // supplied Reader instance.
37 //
38 // If the Reader instance is also an io.ByteReader, its ReadByte method will
39 // be used directly.
40 func NewReader(r io.Reader, maxSize int) Reader {
41 br, ok := r.(io.ByteReader)
42 if !ok {
43 br = &simpleByteReader{Reader: r}
iannucci 2015/08/03 22:21:24 not sure if this is needed? why not just have this
dnj 2015/08/03 22:42:58 It puts the burden on the caller to implement Byte
44 }
45 return &reader{
46 Reader: r,
47 ByteReader: br,
48 maxSize: maxSize,
49 }
50 }
51
52 func (r *reader) ReadFrame() ([]byte, error) {
53 // Read the frame size.
54 count, err := binary.ReadUvarint(r)
55 if err != nil {
56 return nil, err
57 }
58
59 if count > uint64(r.maxSize) {
60 return nil, ErrFrameTooLarge
61 }
62
63 data := make([]byte, int(count))
64 if _, err := r.Read(data); err != nil {
65 return nil, err
66 }
67 return data, nil
68 }
69
70 // simpleByteReader implements the io.ByteReader interface for an io.Reader.
71 type simpleByteReader struct {
72 io.Reader
73
74 buf [1]byte
iannucci 2015/08/03 22:21:24 not threadsafe? why have it in the struct at all?
dnj 2015/08/03 22:42:58 No, struct is not threadsafe :) Most readers aren'
iannucci 2015/08/04 17:13:50 Right, but you have to slice it every time, which
75 }
76
77 func (r *simpleByteReader) ReadByte() (byte, error) {
78 _, err := r.Read(r.buf[:])
79 return r.buf[0], err
80 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698