(w io.Writer)
| 136 | } |
| 137 | |
| 138 | func (c *Conn) ReadPacketTo(w io.Writer) error { |
| 139 | if _, err := io.ReadFull(c.reader, c.header[:4]); err != nil { |
| 140 | // return errors.Wrapf(ErrBadConn, "io.ReadFull(header) failed. err %v", err) |
| 141 | return ErrBadConn |
| 142 | } |
| 143 | |
| 144 | length := int(uint32(c.header[0]) | uint32(c.header[1])<<8 | uint32(c.header[2])<<16) |
| 145 | sequence := c.header[3] |
| 146 | |
| 147 | if sequence != c.Sequence { |
| 148 | return errors.Errorf("invalid sequence %d != %d", sequence, c.Sequence) |
| 149 | } |
| 150 | |
| 151 | c.Sequence++ |
| 152 | |
| 153 | if buf, ok := w.(*bytes.Buffer); ok { |
| 154 | // Allocate the buffer with expected length directly instead of call `grow` and migrate data many times. |
| 155 | buf.Grow(length) |
| 156 | } |
| 157 | |
| 158 | if n, err := c.copyN(w, c.reader, int64(length)); err != nil { |
| 159 | // return errors.Wrapf(ErrBadConn, "io.CopyN failed. err %v, copied %v, expected %v", err, n, length) |
| 160 | return ErrBadConn |
| 161 | } else if n != int64(length) { |
| 162 | // return errors.Wrapf(ErrBadConn, "io.CopyN failed(n != int64(length)). %v bytes copied, while %v expected", n, length) |
| 163 | return ErrBadConn |
| 164 | } else { |
| 165 | if length < MaxPayloadLen { |
| 166 | return nil |
| 167 | } |
| 168 | |
| 169 | if err := c.ReadPacketTo(w); err != nil { |
| 170 | return ErrBadConn |
| 171 | } |
| 172 | } |
| 173 | |
| 174 | return nil |
| 175 | } |
| 176 | |
| 177 | // WritePacket: data already has 4 bytes header |
| 178 | // will modify data inplace |
no test coverage detected