github.com/aykevl/tinygo@v0.5.0/src/machine/buffer.go (about) 1 package machine 2 3 const bufferSize = 128 4 5 //go:volatile 6 type volatileByte byte 7 8 // RingBuffer is ring buffer implementation inspired by post at 9 // https://www.embeddedrelated.com/showthread/comp.arch.embedded/77084-1.php 10 // 11 // It has some limitations currently due to how "volatile" variables that are 12 // members of a struct are not compiled correctly by TinyGo. 13 // See https://github.com/tinygo-org/tinygo/issues/151 for details. 14 type RingBuffer struct { 15 rxbuffer [bufferSize]volatileByte 16 head volatileByte 17 tail volatileByte 18 } 19 20 // NewRingBuffer returns a new ring buffer. 21 func NewRingBuffer() *RingBuffer { 22 return &RingBuffer{} 23 } 24 25 // Used returns how many bytes in buffer have been used. 26 func (rb *RingBuffer) Used() uint8 { 27 return uint8(rb.head - rb.tail) 28 } 29 30 // Put stores a byte in the buffer. If the buffer is already 31 // full, the method will return false. 32 func (rb *RingBuffer) Put(val byte) bool { 33 if rb.Used() != bufferSize { 34 rb.head++ 35 rb.rxbuffer[rb.head%bufferSize] = volatileByte(val) 36 return true 37 } 38 return false 39 } 40 41 // Get returns a byte from the buffer. If the buffer is empty, 42 // the method will return a false as the second value. 43 func (rb *RingBuffer) Get() (byte, bool) { 44 if rb.Used() != 0 { 45 rb.tail++ 46 return byte(rb.rxbuffer[rb.tail%bufferSize]), true 47 } 48 return 0, false 49 }