MCPcopy Index your code
hub / github.com/coder/coder / ReadFrame

Function ReadFrame

agent/boundarylogproxy/codec/codec.go:96–133  ·  view source on GitHub ↗

ReadFrame reads a framed message, returning the decoded tag and data. If the message size exceeds MaxMessageSizeV1, ErrMessageTooLarge is returned. The provided buf is used if it has sufficient capacity; otherwise a new buffer is allocated. To reuse the buffer across calls, pass in the returned data

(r io.Reader, buf []byte)

Source from the content-addressed store, hash-verified

94// _, buf, _ = ReadFrame(r, buf)
95// }
96func ReadFrame(r io.Reader, buf []byte) (Tag, []byte, error) {
97 var header uint32
98 if err := binary.Read(r, binary.BigEndian, &header); err != nil {
99 return 0, nil, xerrors.Errorf("read header error: %w", err)
100 }
101
102 const lengthMask = (1 << DataLength) - 1
103 length := header & lengthMask
104 const tagMask = (1 << tagLength) - 1 // 0xFF
105 shifted := (header >> DataLength) & tagMask
106 if shifted > tagMask {
107 // This is really only here to satisfy the gosec linter. We know from above that
108 // shifted <= tagMask.
109 return 0, nil, xerrors.Errorf("invalid tag: %d", shifted)
110 }
111 tag := Tag(shifted)
112
113 maxSize, err := maxSizeForTag(tag)
114 if err != nil {
115 return 0, nil, err
116 }
117
118 if length > maxSize {
119 return 0, nil, ErrMessageTooLarge
120 }
121
122 if cap(buf) < int(length) {
123 buf = make([]byte, length)
124 } else {
125 buf = buf[:length:cap(buf)]
126 }
127
128 if _, err := io.ReadFull(r, buf[:length]); err != nil {
129 return 0, nil, xerrors.Errorf("read full error: %w", err)
130 }
131
132 return tag, buf[:length], nil
133}
134
135// maxSizeForTag returns the maximum payload size for the given tag.
136func maxSizeForTag(tag Tag) (uint32, error) {

Callers 6

TestRoundTripFunction · 0.92
TestReadFrameTooLargeFunction · 0.92
TestReadFrameEmptyReaderFunction · 0.92
TestReadFrameInvalidTagFunction · 0.92
ReadMessageFunction · 0.85

Calls 4

TagTypeAlias · 0.85
maxSizeForTagFunction · 0.85
ReadMethod · 0.65
ErrorfMethod · 0.45

Tested by 5

TestRoundTripFunction · 0.74
TestReadFrameTooLargeFunction · 0.74
TestReadFrameEmptyReaderFunction · 0.74
TestReadFrameInvalidTagFunction · 0.74