master
兔子 3 years ago
commit 195b967331

@ -0,0 +1,128 @@
package stario
import (
"errors"
"fmt"
"io"
"sync"
"time"
)
type StarBuffer struct {
io.Reader
io.Writer
io.Closer
datas []byte
pStart int
pEnd int
cap int
isClose bool
isEnd bool
rmu sync.Mutex
wmu sync.Mutex
}
func NewStarBuffer(cap int) *StarBuffer {
rtnBuffer := new(StarBuffer)
rtnBuffer.cap = cap
rtnBuffer.datas = make([]byte, cap)
return rtnBuffer
}
func (star *StarBuffer) Free() int {
return star.cap - star.Len()
}
func (star *StarBuffer) Cap() int {
return star.cap
}
func (star *StarBuffer) Len() int {
length := star.pEnd - star.pStart
if length < 0 {
return star.cap + length - 1
}
return length
}
func (star *StarBuffer) getByte() (byte, error) {
if star.isClose || (star.isEnd && star.Len() == 0) {
return 0, io.EOF
}
if star.Len() == 0 {
return 0, errors.New("no byte available now")
}
data := star.datas[star.pStart]
star.pStart++
if star.pStart == star.cap {
star.pStart = 0
}
return data, nil
}
func (star *StarBuffer) putByte(data byte) error {
if star.isClose || star.isEnd {
return io.EOF
}
kariEnd := star.pEnd + 1
if kariEnd == star.cap {
kariEnd = 0
}
if kariEnd == star.pStart {
for {
time.Sleep(time.Microsecond)
if kariEnd != star.pStart {
break
}
}
}
star.datas[star.pEnd] = data
star.pEnd = kariEnd
return nil
}
func (star *StarBuffer) Close() error {
star.isClose = true
return nil
}
func (star *StarBuffer) Read(buf []byte) (int, error) {
if star.isClose {
return 0, io.EOF
}
if buf == nil {
return 0, errors.New("buffer is nil")
}
star.rmu.Lock()
defer star.rmu.Unlock()
var sum int = 0
for i := 0; i < len(buf); i++ {
data, err := star.getByte()
if err != nil {
if err == io.EOF {
return sum, err
}
return sum, nil
}
buf[i] = data
sum++
}
return sum, nil
}
func (star *StarBuffer) Write(bts []byte) (int, error) {
if bts == nil || star.isClose {
star.isEnd = true
return 0, io.EOF
}
star.wmu.Lock()
defer star.wmu.Unlock()
var sum = 0
for i := 0; i < len(bts); i++ {
err := star.putByte(bts[i])
if err != nil {
fmt.Println("Write bts err:", err)
return sum, err
}
sum++
}
return sum, nil
}

151
io.go

@ -0,0 +1,151 @@
package stario
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
type InputMsg struct {
msg string
err error
}
func MessageBox(hint string, defaultVal string) InputMsg {
if hint != "" {
fmt.Print(hint)
}
inputReader := bufio.NewReader(os.Stdin)
str, err := inputReader.ReadString('\n')
if err != nil {
return InputMsg{"", err}
}
return InputMsg{strings.TrimSpace(str), nil}
}
func (im InputMsg) String() (string, error) {
if im.err != nil {
return "", im.err
}
return im.msg, nil
}
func (im InputMsg) MustString() string {
res, _ := im.String()
return res
}
func (im InputMsg) Int() (int, error) {
if im.err != nil {
return 0, im.err
}
return strconv.Atoi(im.msg)
}
func (im InputMsg) MustInt() int {
res, _ := im.Int()
return res
}
func (im InputMsg) Int64() (int64, error) {
if im.err != nil {
return 0, im.err
}
return strconv.ParseInt(im.msg, 10, 64)
}
func (im InputMsg) MustInt64() int64 {
res, _ := im.Int64()
return res
}
func (im InputMsg) Uint64() (uint64, error) {
if im.err != nil {
return 0, im.err
}
return strconv.ParseUint(im.msg, 10, 64)
}
func (im InputMsg) MustUint64() uint64 {
res, _ := im.Uint64()
return res
}
func (im InputMsg) Bool() (bool, error) {
if im.err != nil {
return false, im.err
}
return strconv.ParseBool(im.msg)
}
func (im InputMsg) MustBool() bool {
res, _ := im.Bool()
return res
}
func (im InputMsg) Float64() (float64, error) {
if im.err != nil {
return 0, im.err
}
return strconv.ParseFloat(im.msg, 64)
}
func (im InputMsg) MustFloat64() float64 {
res, _ := im.Float64()
return res
}
func (im InputMsg) Float32() (float32, error) {
if im.err != nil {
return 0, im.err
}
res, err := strconv.ParseFloat(im.msg, 32)
return float32(res), err
}
func (im InputMsg) MustFloat32() float32 {
res, _ := im.Float32()
return res
}
func YesNo(hint string, defaults bool) bool {
res := strings.ToUpper(MessageBox(hint, "").MustString())
if res == "" {
return defaults
}
res = res[0:1]
if res == "Y" {
return true
} else if res == "N" {
return false
} else {
return defaults
}
}
func StopUntil(hint string, trigger string) error {
pressLen := len(trigger)
if trigger == "" {
pressLen = 1
} else {
pressLen = len(trigger)
}
ioBuf := make([]byte, pressLen)
for {
if hint != "" {
fmt.Print(hint)
}
inputReader := bufio.NewReader(os.Stdin)
_, err := inputReader.Read(ioBuf)
if err != nil {
return err
}
if string(ioBuf) == trigger || trigger == "" {
break
}
fmt.Print("\n")
}
return nil
}
Loading…
Cancel
Save