// 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) } func init() { registerImport("os", ImportOsFuncs) }