expr/func-os.go

215 lines
4.9 KiB
Go
Raw Normal View History

// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
// All rights reserved.
// func-os.go
package expr
import (
"bufio"
"fmt"
"io"
"os"
)
type osHandle interface {
getFile() *os.File
}
type osWriter struct {
fh *os.File
writer *bufio.Writer
}
func (h *osWriter) TypeName() string {
return "osWriter"
}
func (h *osWriter) String() string {
return "writer"
}
func (h *osWriter) getFile() *os.File {
return h.fh
}
type osReader struct {
fh *os.File
reader *bufio.Reader
}
func (h *osReader) TypeName() string {
return "osReader"
}
func (h *osReader) String() string {
return "reader"
}
func (h *osReader) getFile() *os.File {
return h.fh
}
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 createFileFunc(ctx ExprContext, name string, args []any) (result any, err error) {
if filePath, ok := args[0].(string); ok && len(filePath) > 0 {
var fh *os.File
if fh, err = os.Create(filePath); err == nil {
result = &osWriter{fh: fh, writer: bufio.NewWriter(fh)}
}
} else {
err = errMissingFilePath("createFile")
}
return
}
func openFileFunc(ctx ExprContext, name string, args []any) (result any, err error) {
if filePath, ok := args[0].(string); ok && len(filePath) > 0 {
var fh *os.File
if fh, err = os.Open(filePath); err == nil {
result = &osReader{fh: fh, reader: bufio.NewReader(fh)}
}
} else {
err = errMissingFilePath("openFile")
}
return
}
func appendFileFunc(ctx ExprContext, name string, args []any) (result any, err error) {
if filePath, ok := args[0].(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 = &osWriter{fh: fh, writer: bufio.NewWriter(fh)}
}
} else {
err = errMissingFilePath("openFile")
}
return
}
func closeFileFunc(ctx ExprContext, name string, args []any) (result any, err error) {
var handle osHandle
var invalidFileHandle any
var ok bool
if handle, ok = args[0].(osHandle); !ok {
invalidFileHandle = args[0]
}
if handle != nil {
if fh := handle.getFile(); fh != nil {
if w, ok := handle.(*osWriter); ok {
err = w.writer.Flush()
}
if err == nil {
err = fh.Close()
}
}
}
if err == nil && (handle == nil || invalidFileHandle != nil) {
err = errInvalidFileHandle("closeFileFunc", handle)
}
result = err == nil
return
}
func writeFileFunc(ctx ExprContext, name string, args []any) (result any, err error) {
var handle osHandle
var invalidFileHandle any
var ok bool
if handle, ok = args[0].(osHandle); !ok {
invalidFileHandle = args[0]
}
if handle != nil {
if w, ok := handle.(*osWriter); ok {
result, err = fmt.Fprint(w.writer, args[1:]...)
} else {
invalidFileHandle = handle
}
}
if err == nil && (handle == nil || invalidFileHandle != nil) {
err = errInvalidFileHandle("writeFileFunc", invalidFileHandle)
}
return
}
func readFileFunc(ctx ExprContext, name string, args []any) (result any, err error) {
var handle osHandle
var invalidFileHandle any
var ok bool
result = nil
if handle, ok = args[0].(osHandle); !ok || args[0] == nil {
invalidFileHandle = args[0]
}
if handle != nil {
if r, ok := handle.(*osReader); ok {
var limit byte = '\n'
var v string
if s, ok := args[1].(string); ok && len(s) > 0 {
limit = s[0]
}
if v, err = r.reader.ReadString(limit); err == nil {
if len(v) > 0 && v[len(v)-1] == limit {
result = v[0 : len(v)-1]
} else {
result = v
}
}
if err == io.EOF {
err = nil
}
} else {
invalidFileHandle = handle
}
}
if err == nil && (handle == nil || invalidFileHandle != nil) {
err = errInvalidFileHandle("readFileFunc", invalidFileHandle)
}
return
}
func ImportOsFuncs(ctx ExprContext) {
ctx.RegisterFunc("openFile", newGolangFunctor(openFileFunc), typeHandle, []ExprFuncParam{
newFuncParam(typeFilepath),
})
ctx.RegisterFunc("appendFile", newGolangFunctor(appendFileFunc), typeHandle, []ExprFuncParam{
newFuncParam(typeFilepath),
})
ctx.RegisterFunc("createFile", newGolangFunctor(createFileFunc), typeHandle, []ExprFuncParam{
newFuncParam(typeFilepath),
})
ctx.RegisterFunc("writeFile", newGolangFunctor(writeFileFunc), typeInt, []ExprFuncParam{
newFuncParam(typeHandle),
newFuncParamFlagDef(typeItem, pfOptional|pfRepeat, ""),
})
ctx.RegisterFunc("readFile", newGolangFunctor(readFileFunc), typeString, []ExprFuncParam{
newFuncParam(typeHandle),
newFuncParamFlagDef("limitCh", pfOptional, "\n"),
})
ctx.RegisterFunc("closeFile", newGolangFunctor(closeFileFunc), typeBoolean, []ExprFuncParam{
newFuncParam(typeHandle),
})
}
2024-04-21 14:24:56 +02:00
func init() {
registerImport("os.file", ImportOsFuncs, "Operating system file functions")
2024-04-21 14:24:56 +02:00
}