234 lines
6.2 KiB
Go
234 lines
6.2 KiB
Go
// Copyright (c) 2024-2026 Celestino Amoroso (celestino.amoroso@gmail.com).
|
|
// All rights reserved.
|
|
|
|
// builtin-os-file.go
|
|
package expr
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
|
|
"git.portale-stac.it/go-pkg/expr/file"
|
|
"git.portale-stac.it/go-pkg/expr/kern"
|
|
)
|
|
|
|
const (
|
|
osLimitCh = "limitCh"
|
|
)
|
|
|
|
func errMissingFilePath(funcName string) error {
|
|
return fmt.Errorf("%s(): missing or invalid file path", funcName)
|
|
}
|
|
|
|
func errInvalidFileHandle(funcName string, v any) error {
|
|
if v != nil {
|
|
return fmt.Errorf("%s(): invalid file handle %v [%T]", funcName, v, v)
|
|
} else {
|
|
return fmt.Errorf("%s(): invalid file handle", funcName)
|
|
}
|
|
}
|
|
|
|
func openFileFunc(ctx kern.ExprContext, name string, args map[string]any) (result any, err error) {
|
|
if filePath, ok := args[kern.ParamFilepath].(string); ok && len(filePath) > 0 {
|
|
// var fh *os.File
|
|
// if fh, err = os.Open(filePath); err == nil {
|
|
// result = file.NewReader(fh)
|
|
// }
|
|
result, err = file.OpenReader(filePath)
|
|
} else {
|
|
err = errMissingFilePath(name)
|
|
}
|
|
return
|
|
}
|
|
|
|
func createFileFunc(ctx kern.ExprContext, name string, args map[string]any) (result any, err error) {
|
|
if filePath, ok := args[kern.ParamFilepath].(string); ok && len(filePath) > 0 {
|
|
// var fh *os.File
|
|
// if fh, err = os.Create(filePath); err == nil {
|
|
// result = file.NewWriter(fh)
|
|
// }
|
|
result, err = file.CreateWriter(filePath)
|
|
} else {
|
|
err = errMissingFilePath(name)
|
|
}
|
|
return
|
|
}
|
|
|
|
func appendFileFunc(ctx kern.ExprContext, name string, args map[string]any) (result any, err error) {
|
|
if filePath, ok := args[kern.ParamFilepath].(string); ok && len(filePath) > 0 {
|
|
// var fh *os.File
|
|
// if fh, err = os.OpenFile(filePath, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0660); err == nil {
|
|
// result = file.NewWriter(fh)
|
|
// }
|
|
result, err = file.AppendWriter(filePath)
|
|
} else {
|
|
err = errMissingFilePath(name)
|
|
}
|
|
return
|
|
}
|
|
|
|
func closeFileFunc(ctx kern.ExprContext, name string, args map[string]any) (result any, err error) {
|
|
var handle file.Handle
|
|
var invalidFileHandle any
|
|
var ok bool
|
|
|
|
if handle, ok = args[kern.ParamHandle].(file.Handle); !ok {
|
|
invalidFileHandle = args[kern.ParamHandle]
|
|
}
|
|
|
|
if handle != nil {
|
|
if fh := handle.GetFile(); fh != nil {
|
|
if w, ok := handle.(*file.Writer); ok {
|
|
err = w.Flush()
|
|
}
|
|
|
|
if err == nil {
|
|
err = fh.Close()
|
|
}
|
|
}
|
|
}
|
|
if err == nil && (handle == nil || invalidFileHandle != nil) {
|
|
err = errInvalidFileHandle(name, handle)
|
|
}
|
|
result = err == nil
|
|
return
|
|
}
|
|
|
|
func fileWriteTextFunc(ctx kern.ExprContext, name string, args map[string]any) (result any, err error) {
|
|
var handle file.Handle
|
|
var invalidFileHandle any
|
|
var ok bool
|
|
|
|
if handle, ok = args[kern.ParamHandle].(file.Handle); !ok {
|
|
invalidFileHandle = args[kern.ParamHandle]
|
|
}
|
|
|
|
if handle != nil {
|
|
if w, ok := handle.(*file.Writer); ok {
|
|
if v, exists := args[kern.ParamItem]; exists {
|
|
argv := v.([]any)
|
|
// result, err = fmt.Fprint(w.writer, argv...)
|
|
result, err = w.Write(argv...)
|
|
}
|
|
} else {
|
|
invalidFileHandle = handle
|
|
}
|
|
}
|
|
|
|
if err == nil && (handle == nil || invalidFileHandle != nil) {
|
|
err = errInvalidFileHandle(name, invalidFileHandle)
|
|
}
|
|
return
|
|
}
|
|
|
|
func fileReadTextFunc(ctx kern.ExprContext, name string, args map[string]any) (result any, err error) {
|
|
var handle file.Handle
|
|
var invalidFileHandle any
|
|
var ok bool
|
|
|
|
result = nil
|
|
if handle, ok = args[kern.ParamHandle].(file.Handle); !ok || args[kern.ParamHandle] == nil {
|
|
invalidFileHandle = args[kern.ParamHandle]
|
|
}
|
|
|
|
if handle != nil {
|
|
if r, ok := handle.(*file.Reader); ok {
|
|
var limit byte = '\n'
|
|
var v string
|
|
if s, ok := args[osLimitCh].(string); ok && len(s) > 0 {
|
|
limit = s[0]
|
|
}
|
|
|
|
v, err = r.ReadString(limit)
|
|
if err == io.EOF {
|
|
err = nil
|
|
}
|
|
if len(v) > 0 {
|
|
if v[len(v)-1] == limit {
|
|
result = v[0 : len(v)-1]
|
|
} else {
|
|
result = v
|
|
}
|
|
}
|
|
} else {
|
|
invalidFileHandle = handle
|
|
}
|
|
}
|
|
|
|
if err == nil && (handle == nil || invalidFileHandle != nil) {
|
|
err = errInvalidFileHandle(name, invalidFileHandle)
|
|
}
|
|
return
|
|
}
|
|
|
|
func fileReadTextAllFunc(ctx kern.ExprContext, name string, args map[string]any) (result any, err error) {
|
|
var handle file.Handle
|
|
var invalidFileHandle any
|
|
var ok bool
|
|
|
|
result = nil
|
|
if handle, ok = args[kern.ParamHandle].(file.Handle); !ok || args[kern.ParamHandle] == nil {
|
|
invalidFileHandle = args[kern.ParamHandle]
|
|
}
|
|
|
|
if handle != nil {
|
|
if r, ok := handle.(*file.Reader); ok {
|
|
var b []byte
|
|
b, err = r.ReadAll()
|
|
result = string(b)
|
|
} else {
|
|
invalidFileHandle = handle
|
|
}
|
|
}
|
|
|
|
if err == nil && (handle == nil || invalidFileHandle != nil) {
|
|
err = errInvalidFileHandle(name, invalidFileHandle)
|
|
}
|
|
return
|
|
}
|
|
|
|
func ImportOsFuncs(ctx kern.ExprContext) {
|
|
ctx.RegisterFunc("fileOpen", kern.NewGolangFunctor(openFileFunc), kern.TypeFileHandle, []kern.ExprFuncParam{
|
|
kern.NewFuncParam(kern.ParamFilepath),
|
|
})
|
|
|
|
ctx.RegisterFunc("fileAppend", kern.NewGolangFunctor(appendFileFunc), kern.TypeFileHandle, []kern.ExprFuncParam{
|
|
kern.NewFuncParam(kern.ParamFilepath),
|
|
})
|
|
|
|
ctx.RegisterFunc("fileCreate", kern.NewGolangFunctor(createFileFunc), kern.TypeFileHandle, []kern.ExprFuncParam{
|
|
kern.NewFuncParam(kern.ParamFilepath),
|
|
})
|
|
|
|
ctx.RegisterFunc("fileClose", kern.NewGolangFunctor(closeFileFunc), kern.TypeBoolean, []kern.ExprFuncParam{
|
|
kern.NewFuncParam(kern.ParamHandle),
|
|
})
|
|
|
|
ctx.RegisterFunc("fileWriteText", kern.NewGolangFunctor(fileWriteTextFunc), kern.TypeInt, []kern.ExprFuncParam{
|
|
kern.NewFuncParam(kern.ParamHandle),
|
|
kern.NewFuncParamFlagDef(kern.ParamItem, kern.PfDefault|kern.PfRepeat, ""),
|
|
})
|
|
|
|
ctx.RegisterFunc("fileReadText", kern.NewGolangFunctor(fileReadTextFunc), kern.TypeString, []kern.ExprFuncParam{
|
|
kern.NewFuncParam(kern.ParamHandle),
|
|
kern.NewFuncParamFlagDef(osLimitCh, kern.PfDefault, "\n"),
|
|
})
|
|
|
|
ctx.RegisterFunc("fileReadTextAll", kern.NewGolangFunctor(fileReadTextAllFunc), kern.TypeString, []kern.ExprFuncParam{
|
|
kern.NewFuncParam(kern.ParamHandle),
|
|
})
|
|
|
|
ctx.RegisterFunc("fileLineIterator", kern.NewGolangFunctor(fileLineIteratorFunc), kern.TypeIterator, []kern.ExprFuncParam{
|
|
kern.NewFuncParam(paramHandleOrPath),
|
|
})
|
|
|
|
ctx.RegisterFunc("fileByteIterator", kern.NewGolangFunctor(fileByteIteratorFunc), kern.TypeIterator, []kern.ExprFuncParam{
|
|
kern.NewFuncParam(paramHandleOrPath),
|
|
})
|
|
|
|
}
|
|
|
|
func init() {
|
|
RegisterBuiltinModule("os.file", ImportOsFuncs, "Operating system file functions")
|
|
}
|