| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package recordio | 5 package recordio |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "bytes" |
| 8 "encoding/binary" | 9 "encoding/binary" |
| 9 "fmt" | 10 "fmt" |
| 10 "io" | 11 "io" |
| 11 ) | 12 ) |
| 12 | 13 |
| 13 // ErrFrameTooLarge is an error that is returned if a frame that is larger than | 14 // 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 // the maximum allowed size (not including the frame header) is read. |
| 15 var ErrFrameTooLarge = fmt.Errorf("frame: frame size exceeds maximum") | 16 var ErrFrameTooLarge = fmt.Errorf("frame: frame size exceeds maximum") |
| 16 | 17 |
| 17 // Reader reads individual frames from a frame-formatted input Reader. | 18 // Reader reads individual frames from a frame-formatted input Reader. |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 type simpleByteReader struct { | 96 type simpleByteReader struct { |
| 96 io.Reader | 97 io.Reader |
| 97 | 98 |
| 98 buf [1]byte | 99 buf [1]byte |
| 99 } | 100 } |
| 100 | 101 |
| 101 func (r *simpleByteReader) ReadByte() (byte, error) { | 102 func (r *simpleByteReader) ReadByte() (byte, error) { |
| 102 _, err := r.Read(r.buf[:]) | 103 _, err := r.Read(r.buf[:]) |
| 103 return r.buf[0], err | 104 return r.buf[0], err |
| 104 } | 105 } |
| 106 |
| 107 // Split splits the supplied buffer into its component records. |
| 108 // |
| 109 // This method implements zero-copy segmentation, so the individual records are |
| 110 // slices of the original data set. |
| 111 func Split(data []byte) (records [][]byte, err error) { |
| 112 br := bytes.NewReader(data) |
| 113 |
| 114 for br.Len() > 0 { |
| 115 var size uint64 |
| 116 size, err = binary.ReadUvarint(br) |
| 117 if err != nil { |
| 118 return |
| 119 } |
| 120 if size > uint64(br.Len()) { |
| 121 err = ErrFrameTooLarge |
| 122 return |
| 123 } |
| 124 |
| 125 // Pull out the record from the original byte stream without cop
ying. |
| 126 // Casting size to an integer is safe at this point, since we ha
ve asserted |
| 127 // that it is less than the remaining length in the buffer, whic
h is an int. |
| 128 offset := len(data) - br.Len() |
| 129 records = append(records, data[offset:offset+int(size)]) |
| 130 |
| 131 if _, err := br.Seek(int64(size), 1); err != nil { |
| 132 // Our measurements should protect us from this being an
invalid seek. |
| 133 panic(err) |
| 134 } |
| 135 } |
| 136 return records, nil |
| 137 } |
| OLD | NEW |