61 lines
1.8 KiB
Go
61 lines
1.8 KiB
Go
// internal/adapter/reader.go
|
|
package adapter
|
|
|
|
import (
|
|
"bufio"
|
|
"context"
|
|
"io"
|
|
"log"
|
|
"os"
|
|
)
|
|
|
|
// StdinReader читает бинарные данные из stdin и пишет в буфер
|
|
type StdinReader struct {
|
|
updates chan byte // канал для real-time уведомлений (0 = без уведомлений)
|
|
}
|
|
|
|
// NewStdinReader создает читалку stdin
|
|
func NewStdinReader(updates chan byte) *StdinReader {
|
|
return &StdinReader{
|
|
updates: updates,
|
|
}
|
|
}
|
|
|
|
// Start начинает чтение stdin в отдельной горутине
|
|
func (r *StdinReader) Start(ctx context.Context, buf *RingBuffer) error {
|
|
reader := bufio.NewReader(os.Stdin)
|
|
|
|
go func() {
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
log.Println("StdinReader: остановлен")
|
|
return
|
|
default:
|
|
b, err := reader.ReadByte()
|
|
if err != nil {
|
|
if err == io.EOF {
|
|
log.Println("StdinReader: stdin закрыт (EOF)")
|
|
return
|
|
}
|
|
// Другие ошибки игнорируем, продолжаем читать
|
|
continue
|
|
}
|
|
|
|
buf.Write(b)
|
|
|
|
// Неблокирующая отправка в канал уведомлений
|
|
if r.updates != nil {
|
|
select {
|
|
case r.updates <- b:
|
|
default:
|
|
// Канал заполнен, пропускаем уведомление
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}()
|
|
|
|
return nil
|
|
}
|