2024-05-30 00:06:06 +07:00
|
|
|
package utils
|
2023-07-21 14:03:19 +02:00
|
|
|
|
2024-03-20 22:14:02 +01:00
|
|
|
import (
|
2024-04-05 22:31:33 +02:00
|
|
|
"fmt"
|
2024-03-20 22:14:02 +01:00
|
|
|
"io"
|
2024-04-05 22:31:33 +02:00
|
|
|
"os"
|
2025-01-30 14:20:17 +03:00
|
|
|
"strings"
|
|
|
|
|
"unicode"
|
2024-03-20 22:14:02 +01:00
|
|
|
)
|
2023-07-21 14:03:19 +02:00
|
|
|
|
2024-04-05 22:31:33 +02:00
|
|
|
func ReadFileTail(filePath string, maxLen int) (data []byte, err error) {
|
|
|
|
|
f, err := os.Open(filePath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("failed to open file: %w", err)
|
|
|
|
|
}
|
|
|
|
|
defer func() {
|
|
|
|
|
err = f.Close()
|
|
|
|
|
if err != nil {
|
|
|
|
|
err = fmt.Errorf("failed to close file: %w", err)
|
|
|
|
|
data = nil
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
var dataReader io.Reader = f
|
|
|
|
|
|
|
|
|
|
if maxLen > 0 {
|
|
|
|
|
stat, err := f.Stat()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("failed to stat file: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if stat.Size() > int64(maxLen) {
|
|
|
|
|
_, err = f.Seek(-int64(maxLen), io.SeekEnd)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("failed to seek file: %w", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dataReader = io.LimitReader(f, int64(maxLen))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
data, err = io.ReadAll(dataReader)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("failed to read file: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return data, nil
|
|
|
|
|
}
|
2024-06-28 21:21:08 +07:00
|
|
|
|
|
|
|
|
// filters values from a slice
|
|
|
|
|
func Filter[T any](s []T, f func(T) bool) []T {
|
|
|
|
|
var r []T
|
|
|
|
|
for _, v := range s {
|
|
|
|
|
if f(v) {
|
|
|
|
|
r = append(r, v)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return r
|
|
|
|
|
}
|
2025-01-30 14:20:17 +03:00
|
|
|
|
|
|
|
|
func ParseCommandLine(s string) ([]string, error) {
|
|
|
|
|
args := make([]string, 0)
|
|
|
|
|
var currentArg strings.Builder
|
|
|
|
|
inQuotes := false
|
|
|
|
|
escaped := false
|
|
|
|
|
|
|
|
|
|
for _, r := range s {
|
|
|
|
|
switch {
|
|
|
|
|
case escaped:
|
|
|
|
|
currentArg.WriteRune(r)
|
|
|
|
|
escaped = false
|
|
|
|
|
case r == '\\':
|
|
|
|
|
escaped = true
|
|
|
|
|
case r == '"':
|
|
|
|
|
inQuotes = !inQuotes
|
|
|
|
|
case unicode.IsSpace(r) && !inQuotes:
|
|
|
|
|
if currentArg.Len() > 0 {
|
|
|
|
|
args = append(args, currentArg.String())
|
|
|
|
|
currentArg.Reset()
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
currentArg.WriteRune(r)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if escaped || inQuotes {
|
|
|
|
|
return nil, fmt.Errorf("unexpected end of string")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if currentArg.Len() > 0 {
|
|
|
|
|
args = append(args, currentArg.String())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return args, nil
|
|
|
|
|
}
|