mirror of
https://codeberg.org/scip/tablizer.git
synced 2025-12-18 13:01:11 +01:00
added
This commit is contained in:
128
vendor/github.com/glycerine/zygomys/zygo/bsave.go
generated
vendored
Normal file
128
vendor/github.com/glycerine/zygomys/zygo/bsave.go
generated
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
package zygo
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/glycerine/greenpack/msgp"
|
||||
)
|
||||
|
||||
// (bsave value path) writes value as greenpack to file.
|
||||
//
|
||||
// (greenpack value) writes value as greenpack to SexpRaw in memory.
|
||||
//
|
||||
// bsave converts to binary with (togo) then saves the binary to file.
|
||||
func WriteShadowGreenpackToFileFunction(env *Zlisp, name string, args []Sexp) (Sexp, error) {
|
||||
narg := len(args)
|
||||
if narg < 1 || narg > 2 {
|
||||
return SexpNull, WrongNargs
|
||||
}
|
||||
// check arg[0]
|
||||
var asHash *SexpHash
|
||||
switch x := args[0].(type) {
|
||||
default:
|
||||
return SexpNull, fmt.Errorf("%s error: top value must be a hash or defmap; we see '%T'", name, args[0])
|
||||
case *SexpHash:
|
||||
// okay, good
|
||||
asHash = x
|
||||
}
|
||||
|
||||
switch name {
|
||||
case "bsave":
|
||||
if narg != 2 {
|
||||
return SexpNull, WrongNargs
|
||||
}
|
||||
|
||||
case "greenpack":
|
||||
if narg != 1 {
|
||||
return SexpNull, WrongNargs
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
_, err := toGreenpackHelper(env, asHash, &buf, "memory")
|
||||
if err != nil {
|
||||
return SexpNull, err
|
||||
}
|
||||
return &SexpRaw{Val: buf.Bytes()}, nil
|
||||
}
|
||||
|
||||
// check arg[1]
|
||||
var fn string
|
||||
switch fna := args[1].(type) {
|
||||
case *SexpStr:
|
||||
fn = fna.S
|
||||
default:
|
||||
return SexpNull, fmt.Errorf("error: %s requires a string (SexpStr) path to write to as the second argument. we got type %T / value = %v", name, args[1], args[1])
|
||||
}
|
||||
|
||||
// don't overwrite existing file
|
||||
if FileExists(fn) {
|
||||
return SexpNull, fmt.Errorf("error: %s refusing to write to existing file '%s'",
|
||||
name, fn)
|
||||
}
|
||||
|
||||
f, err := os.Create(fn)
|
||||
if err != nil {
|
||||
return SexpNull, fmt.Errorf("error: %s sees error trying to create file '%s': '%v'", name, fn, err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
_, err = toGreenpackHelper(env, asHash, f, fn)
|
||||
return SexpNull, err
|
||||
}
|
||||
|
||||
func toGreenpackHelper(env *Zlisp, asHash *SexpHash, f io.Writer, fn string) (Sexp, error) {
|
||||
|
||||
// create shadow structs
|
||||
_, err := ToGoFunction(env, "togo", []Sexp{asHash})
|
||||
if err != nil {
|
||||
return SexpNull, fmt.Errorf("ToGo call sees error: '%v'", err)
|
||||
}
|
||||
|
||||
if asHash.GoShadowStruct == nil {
|
||||
return SexpNull, fmt.Errorf("GoShadowStruct was nil, on attempt to write to '%s'", fn)
|
||||
}
|
||||
|
||||
enc, ok := interface{}(asHash.GoShadowStruct).(msgp.Encodable)
|
||||
if !ok {
|
||||
return SexpNull, fmt.Errorf("error: GoShadowStruct was not greenpack Encodable -- run `go generate` or add greenpack to the source file for type '%T'. on attempt to save to '%s'", asHash.GoShadowStruct, fn)
|
||||
}
|
||||
w := msgp.NewWriter(f)
|
||||
err = msgp.Encode(w, enc)
|
||||
if err != nil {
|
||||
return SexpNull, fmt.Errorf("error: greenpack encoding to file '%s' of type '%T' sees error '%v'", fn, asHash.GoShadowStruct, err)
|
||||
}
|
||||
err = w.Flush()
|
||||
return SexpNull, err
|
||||
}
|
||||
|
||||
func ReadGreenpackFromFileFunction(env *Zlisp, name string, args []Sexp) (Sexp, error) {
|
||||
narg := len(args)
|
||||
|
||||
if narg != 1 {
|
||||
return SexpNull, WrongNargs
|
||||
}
|
||||
var fn string
|
||||
switch fna := args[0].(type) {
|
||||
case *SexpStr:
|
||||
fn = fna.S
|
||||
default:
|
||||
return SexpNull, fmt.Errorf("%s requires a string path to read. we got type %T / value = %v", name, args[0], args[0])
|
||||
}
|
||||
|
||||
if !FileExists(string(fn)) {
|
||||
return SexpNull, fmt.Errorf("file '%s' does not exist", fn)
|
||||
}
|
||||
f, err := os.Open(fn)
|
||||
if err != nil {
|
||||
return SexpNull, err
|
||||
}
|
||||
defer f.Close()
|
||||
by, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
return SexpNull, err
|
||||
}
|
||||
return MsgpackToSexp(by, env)
|
||||
}
|
||||
Reference in New Issue
Block a user