Ejemplo n.º 1
0
// 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
}
Ejemplo n.º 2
0
// 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)
}