// Implementation of io.Reader interface. func (p *Port) Read(b []byte) (int, error) { var c int32 var start time.Time if Debug { start = time.Now() } buf, size := unsafe.Pointer(&b[0]), C.size_t(len(b)) if p.readDeadline.IsZero() { // no deadline c = C.sp_blocking_read(p.p, buf, size, 0) } else if millis := deadline2millis(p.readDeadline); millis <= 0 { // call nonblocking read c = C.sp_nonblocking_read(p.p, buf, size) } else { // call blocking read c = C.sp_blocking_read(p.p, buf, size, C.uint(millis)) } if Debug { log.Printf("read time: %d ns", time.Since(start).Nanoseconds()) } n := int(c) // check for error if n < 0 { return 0, errmsg(c) } else if n != len(b) { return n, ErrTimeout } // update slice length reflect.ValueOf(&b).Elem().SetLen(int(c)) return n, nil }
// BlockingRead attempts to read the lesser of the number of bytes waiting or the // capacity of the rx buffer, blocks while reading, timeout is the number of mS // to wait or set 0 to wait indefinitely. // rxBuf size should not exceed the capacity of int32 func BlockingRead(port Port, rxBuf []byte, timeout uint) (int32, error) { var result int32 = SP_OK waiting, err := Waiting(port) if err == nil { // Passing to C so don't exceed the buffer length length := minInt32(waiting, int32(len(rxBuf))) if waiting > 0 { result = C.sp_blocking_read(port, (unsafe.Pointer(&rxBuf[0])), C.size_t(length), C.uint(timeout)) } return result, checkResult(result) } return waiting, checkResult(waiting) }