106 lines
2.3 KiB
Go
106 lines
2.3 KiB
Go
// Copyright (c) 2024-2026 Celestino Amoroso (celestino.amoroso@gmail.com).
|
|
// All rights reserved.
|
|
|
|
// builtin-os-file.go
|
|
package expr
|
|
|
|
import (
|
|
"git.portale-stac.it/go-pkg/expr/file"
|
|
"git.portale-stac.it/go-pkg/expr/kern"
|
|
)
|
|
|
|
const fileLineIteratorType = "fileLineIterator"
|
|
|
|
type fileFileLineIterator struct {
|
|
fileIterBase
|
|
line string
|
|
}
|
|
|
|
func newFileLineIterator(r *file.Reader, autoClose bool) *fileFileLineIterator {
|
|
return &fileFileLineIterator{
|
|
fileIterBase: fileIterBase{reader: r, index: -1, count: 0, autoClose: autoClose},
|
|
line: "",
|
|
}
|
|
}
|
|
|
|
func (it *fileFileLineIterator) TypeName() string {
|
|
return fileLineIteratorType
|
|
}
|
|
|
|
func (it *fileFileLineIterator) String() string {
|
|
return it.repr(fileLineIteratorType)
|
|
}
|
|
|
|
func (it *fileFileLineIterator) Next() (item any, err error) { // must return io.EOF after the last item
|
|
if it.line, err = it.reader.ReadString('\n'); err == nil {
|
|
it.increment()
|
|
item = it.line[0 : len(it.line)-1]
|
|
} else if it.autoClose {
|
|
it.Clean()
|
|
}
|
|
return
|
|
}
|
|
|
|
func (it *fileFileLineIterator) Current() (item any, err error) {
|
|
if len(it.line) > 0 {
|
|
item = it.line[0 : len(it.line)-1]
|
|
}
|
|
return
|
|
}
|
|
|
|
func (it *fileFileLineIterator) Reset() (err error) {
|
|
if err = it.reader.Reset(); err == nil {
|
|
it.reset()
|
|
it.line = ""
|
|
}
|
|
return
|
|
}
|
|
|
|
func (it *fileFileLineIterator) Clean() (err error) {
|
|
if it.reader != nil {
|
|
if err = it.reader.Close(); err == nil {
|
|
it.reader = nil
|
|
}
|
|
}
|
|
it.reset()
|
|
it.line = ""
|
|
return
|
|
}
|
|
|
|
func (it *fileFileLineIterator) CallOperation(name string, args map[string]any) (v any, err error) {
|
|
switch name {
|
|
case kern.NextName:
|
|
v, err = it.Next()
|
|
case kern.ResetName:
|
|
err = it.Reset()
|
|
case kern.CleanName:
|
|
err = it.Clean()
|
|
case kern.IndexName:
|
|
v = int64(it.Index())
|
|
case kern.CurrentName:
|
|
v, err = it.Current()
|
|
case kern.CountName:
|
|
v = it.count
|
|
default:
|
|
err = kern.ErrNoOperation(name)
|
|
}
|
|
return
|
|
}
|
|
|
|
func fileLineIteratorFunc(ctx kern.ExprContext, name string, args map[string]any) (result any, err error) {
|
|
var handle *file.Reader
|
|
var invalidFileHandle any
|
|
var autoClose bool
|
|
|
|
if handle, invalidFileHandle, autoClose, err = initFileHandle(ctx, name, args); err == nil {
|
|
if handle != nil {
|
|
result = newFileLineIterator(handle, autoClose)
|
|
}
|
|
}
|
|
|
|
if err == nil && (handle == nil || invalidFileHandle != nil) {
|
|
err = errInvalidFileHandle(name, invalidFileHandle)
|
|
}
|
|
return
|
|
}
|