152 lines
3.6 KiB
Go
152 lines
3.6 KiB
Go
// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
|
|
// All rights reserved.
|
|
|
|
// builtin-os-file.go
|
|
package expr
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"slices"
|
|
|
|
"git.portale-stac.it/go-pkg/expr/kern"
|
|
)
|
|
|
|
const paramHandleOrPath = "handle-or-path"
|
|
const fileReadTextIteratorType = "fileReadTextIterator"
|
|
|
|
type fileReadTextIterator struct {
|
|
osReader *osReader
|
|
index int64
|
|
count int64
|
|
line string
|
|
autoClose bool
|
|
}
|
|
|
|
func newReadTextIterator(r *osReader, autoClose bool) *fileReadTextIterator {
|
|
return &fileReadTextIterator{osReader: r, index: -1, autoClose: autoClose}
|
|
}
|
|
|
|
func (it *fileReadTextIterator) TypeName() string {
|
|
return fileReadTextIteratorType
|
|
}
|
|
|
|
func (it *fileReadTextIterator) String() string {
|
|
if it.osReader != nil && it.osReader.fh != nil {
|
|
return fmt.Sprintf("$(%s@%q)", fileReadTextIteratorType, it.osReader.fh.Name())
|
|
}
|
|
return fmt.Sprintf("$(%s@<nil>)", fileReadTextIteratorType)
|
|
}
|
|
|
|
func (it *fileReadTextIterator) Count() int64 {
|
|
return it.count
|
|
}
|
|
|
|
func (it *fileReadTextIterator) Next() (item any, err error) { // must return io.EOF after the last item
|
|
if it.osReader.fh != nil {
|
|
if it.line, err = it.osReader.reader.ReadString('\n'); err == nil {
|
|
it.index++
|
|
it.count++
|
|
item = it.line[0 : len(it.line)-1]
|
|
} else if it.autoClose {
|
|
it.Clean()
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (it *fileReadTextIterator) Current() (item any, err error) {
|
|
if len(it.line) > 0 {
|
|
item = it.line[0 : len(it.line)-1]
|
|
}
|
|
return
|
|
}
|
|
|
|
func (it *fileReadTextIterator) Index() int64 {
|
|
return it.index
|
|
}
|
|
|
|
func (it *fileReadTextIterator) Reset() (err error) {
|
|
if _, err = it.osReader.fh.Seek(0, io.SeekStart); err == nil {
|
|
it.index = -1
|
|
it.count = 0
|
|
it.line = ""
|
|
}
|
|
return
|
|
}
|
|
|
|
func (it *fileReadTextIterator) HasOperation(name string) bool {
|
|
return slices.Contains([]string{kern.NextName, kern.ResetName, kern.IndexName, kern.CountName, kern.CurrentName, kern.CleanName}, name)
|
|
}
|
|
|
|
func (it *fileReadTextIterator) Clean() (err error) {
|
|
if it.osReader.fh != nil {
|
|
if err = it.osReader.fh.Close(); err == nil {
|
|
it.osReader = nil
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (it *fileReadTextIterator) 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 fileReadIteratorFunc(ctx kern.ExprContext, name string, args map[string]any) (result any, err error) {
|
|
var handle *osReader
|
|
var invalidFileHandle any
|
|
var ok, autoClose bool
|
|
|
|
result = nil
|
|
if handle, ok = args[paramHandleOrPath].(*osReader); !ok {
|
|
if fileName, ok := args[paramHandleOrPath].(string); ok && len(fileName) > 0 {
|
|
var handleAny any
|
|
if handleAny, err = openFileFunc(ctx, name, map[string]any{kern.ParamFilepath: fileName}); err != nil {
|
|
return
|
|
}
|
|
if handleAny != nil {
|
|
handle = handleAny.(*osReader)
|
|
autoClose = true
|
|
}
|
|
} else {
|
|
invalidFileHandle = args[paramHandleOrPath]
|
|
}
|
|
}
|
|
|
|
if handle != nil {
|
|
result = newReadTextIterator(handle, autoClose)
|
|
|
|
}
|
|
|
|
if err == nil && (handle == nil || invalidFileHandle != nil) {
|
|
err = errInvalidFileHandle(name, invalidFileHandle)
|
|
}
|
|
return
|
|
}
|
|
|
|
// func ImportOsIterFuncs(ctx ExprContext) {
|
|
// ctx.RegisterFunc("fileReadIterator", NewGolangFunctor(fileReadIteratorFunc), TypeIterator, []ExprFuncParam{
|
|
// NewFuncParam(paramHandleOrPath),
|
|
// })
|
|
// }
|
|
|
|
// func init() {
|
|
// RegisterBuiltinModule("os.file", ImportOsIterFuncs, "Operating system file iterator functions")
|
|
// }
|