165 lines
3.5 KiB
Go
165 lines
3.5 KiB
Go
|
// 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) getFile() *os.File {
|
||
|
return h.fh
|
||
|
}
|
||
|
|
||
|
type osReader struct {
|
||
|
fh *os.File
|
||
|
reader *bufio.Reader
|
||
|
}
|
||
|
|
||
|
func (h *osReader) getFile() *os.File {
|
||
|
return h.fh
|
||
|
}
|
||
|
|
||
|
func createFileFunc(ctx ExprContext, name string, args []any) (result any, err error) {
|
||
|
var filePath string
|
||
|
if len(args) > 0 {
|
||
|
filePath, _ = args[0].(string)
|
||
|
}
|
||
|
|
||
|
if 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 = fmt.Errorf("%s(): missing the file path", name)
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func openFileFunc(ctx ExprContext, name string, args []any) (result any, err error) {
|
||
|
var filePath string
|
||
|
if len(args) > 0 {
|
||
|
filePath, _ = args[0].(string)
|
||
|
}
|
||
|
|
||
|
if 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 = fmt.Errorf("%s(): missing the file path", name)
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func appendFileFunc(ctx ExprContext, name string, args []any) (result any, err error) {
|
||
|
var filePath string
|
||
|
if len(args) > 0 {
|
||
|
filePath, _ = args[0].(string)
|
||
|
}
|
||
|
|
||
|
if 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 = fmt.Errorf("%s(): missing the file path", name)
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func closeFileFunc(ctx ExprContext, name string, args []any) (result any, err error) {
|
||
|
var handle osHandle
|
||
|
|
||
|
if len(args) > 0 {
|
||
|
handle, _ = args[0].(osHandle)
|
||
|
}
|
||
|
|
||
|
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()
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
err = fmt.Errorf("%s(): invalid file handle", name)
|
||
|
}
|
||
|
result = err == nil
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func writeFileFunc(ctx ExprContext, name string, args []any) (result any, err error) {
|
||
|
var handle osHandle
|
||
|
|
||
|
if len(args) > 0 {
|
||
|
handle, _ = args[0].(osHandle)
|
||
|
}
|
||
|
|
||
|
if handle != nil {
|
||
|
if fh := handle.getFile(); fh != nil {
|
||
|
if w, ok := handle.(*osWriter); ok {
|
||
|
result, err = fmt.Fprint(w.writer, args[1:]...)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func readFileFunc(ctx ExprContext, name string, args []any) (result any, err error) {
|
||
|
var handle osHandle
|
||
|
|
||
|
if len(args) > 0 {
|
||
|
handle, _ = args[0].(osHandle)
|
||
|
}
|
||
|
|
||
|
if handle != nil {
|
||
|
if fh := handle.getFile(); fh != nil {
|
||
|
if r, ok := handle.(*osReader); ok {
|
||
|
var limit byte = '\n'
|
||
|
var v string
|
||
|
if len(args) > 1 {
|
||
|
if s, ok := args[1].(string); ok && len(s) > 0 {
|
||
|
limit = s[0]
|
||
|
}
|
||
|
}
|
||
|
if v, err = r.reader.ReadString(limit); err == nil || err == io.EOF {
|
||
|
if len(v) > 0 && v[len(v)-1] == limit {
|
||
|
result = v[0 : len(v)-1]
|
||
|
} else {
|
||
|
result = v
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func ImportOsFuncs(ctx ExprContext) {
|
||
|
ctx.RegisterFunc("openFile", &simpleFunctor{f: openFileFunc}, 1, 1)
|
||
|
ctx.RegisterFunc("appendFile", &simpleFunctor{f: appendFileFunc}, 1, 1)
|
||
|
ctx.RegisterFunc("createFile", &simpleFunctor{f: createFileFunc}, 1, 1)
|
||
|
ctx.RegisterFunc("writeFile", &simpleFunctor{f: writeFileFunc}, 1, -1)
|
||
|
ctx.RegisterFunc("readFile", &simpleFunctor{f: readFileFunc}, 1, 2)
|
||
|
ctx.RegisterFunc("closeFile", &simpleFunctor{f: closeFileFunc}, 1, 1)
|
||
|
}
|