ReadResponse reads from the port until it sees a "\r\n" terminator or a read error. Returns the response without the terminator. A read that returns (0, nil) is treated as a timeout and surfaces as an error so callers don't quietly accept truncated responses.
()
| 139 | // returns (0, nil) is treated as a timeout and surfaces as an error so |
| 140 | // callers don't quietly accept truncated responses. |
| 141 | func (m *Mac) ReadResponse() (string, error) { |
| 142 | buf := make([]byte, 0, 256) |
| 143 | tmp := make([]byte, 64) |
| 144 | for { |
| 145 | n, err := m.port.Read(tmp) |
| 146 | if err != nil { |
| 147 | return "", fmt.Errorf("read: %w", err) |
| 148 | } |
| 149 | if n == 0 { |
| 150 | return "", fmt.Errorf("read timeout, partial response: %q", string(buf)) |
| 151 | } |
| 152 | buf = append(buf, tmp[:n]...) |
| 153 | if before, _, ok := bytes.Cut(buf, []byte("\r\n")); ok { |
| 154 | return string(before), nil |
| 155 | } |
| 156 | if len(buf) > maxResponseBytes { |
| 157 | return "", fmt.Errorf("response exceeded %d bytes without terminator: %q", maxResponseBytes, string(buf)) |
| 158 | } |
| 159 | } |
| 160 | } |
| 161 | |
| 162 | // Cmd drains pending bytes, writes raw to the port, and returns the |
| 163 | // response. Use for arbitrary protocol commands like "\{swrev?}" sent from |