summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2017-11-15 21:39:40 -0500
committerLuke Shumaker <lukeshu@lukeshu.com>2017-11-15 21:39:40 -0500
commitefc7a5ebc9e10983571c080017100a8b39eee1d0 (patch)
treeb11aea0aaefb6c16521b2433338ebe7d0440de14
parent7675ebe9567bd7cae4306f484e3677bf88ba8b55 (diff)
more
-rw-r--r--commands.go38
-rw-r--r--ezfiw.go4
-rw-r--r--fileactions.go40
-rw-r--r--frontend.go68
-rw-r--r--parse_catblob.go97
-rw-r--r--read_catblob.go69
-rw-r--r--read_fastimport.go28
-rw-r--r--textproto/io.go (renamed from io.go)52
-rw-r--r--textproto/types.go (renamed from types.go)18
9 files changed, 258 insertions, 156 deletions
diff --git a/commands.go b/commands.go
index a1f7f51..d017f7f 100644
--- a/commands.go
+++ b/commands.go
@@ -2,23 +2,25 @@ package libfastimport
import (
"strconv"
+
+ "git.lukeshu.com/go/libfastimport/textproto"
)
type Cmd interface {
- fiWriteCmd(*FIWriter) error
+ fiWriteCmd(*textproto.FIWriter) error
}
type CmdCommit struct {
Ref string
Mark int // optional; < 1 for non-use
- Author *UserTime
- Committer UserTime
+ Author *textproto.UserTime
+ Committer textproto.UserTime
Msg []byte
Parents []string
Tree []FileAction
}
-func (c *CmdCommit) fiWriteCmd(fiw *FIWriter) error {
+func (c CmdCommit) fiWriteCmd(fiw *textproto.FIWriter) error {
ez := &ezfiw{fiw: fiw}
ez.WriteLine("commit", c.Ref)
@@ -56,11 +58,11 @@ func (c *CmdCommit) fiWriteCmd(fiw *FIWriter) error {
type CmdTag struct {
RefName string
CommitIsh string
- Tagger UserTime
+ Tagger textproto.UserTime
Data []byte
}
-func (c *CmdTag) fiWriteCmd(fiw *FIWriter) error {
+func (c CmdTag) fiWriteCmd(fiw *textproto.FIWriter) error {
ez := &ezfiw{fiw: fiw}
ez.WriteLine("tag", c.RefName)
@@ -76,7 +78,7 @@ type CmdReset struct {
CommitIsh string // optional
}
-func (c *CmdReset) fiWriteCmd(fiw *FIWriter) error {
+func (c CmdReset) fiWriteCmd(fiw *textproto.FIWriter) error {
ez := &ezfiw{fiw: fiw}
ez.WriteLine("reset", c.RefName)
@@ -92,7 +94,7 @@ type CmdBlob struct {
Data []byte
}
-func (c *CmdBlob) fiWriteCmd(fiw *FIWriter) error {
+func (c CmdBlob) fiWriteCmd(fiw *textproto.FIWriter) error {
ez := &ezfiw{fiw: fiw}
ez.WriteLine("blob")
@@ -106,7 +108,7 @@ func (c *CmdBlob) fiWriteCmd(fiw *FIWriter) error {
type CmdCheckpoint struct{}
-func (c *CmdCheckpoint) fiWriteCmd(fiw *FIWriter) error {
+func (c CmdCheckpoint) fiWriteCmd(fiw *textproto.FIWriter) error {
return fiw.WriteLine("checkpoint")
}
@@ -114,7 +116,7 @@ type CmdProgress struct {
Str string
}
-func (c *CmdProgress) fiWriteCmd(fiw *FIWriter) error {
+func (c CmdProgress) fiWriteCmd(fiw *textproto.FIWriter) error {
return fiw.WriteLine("progress", c.Str)
}
@@ -122,7 +124,7 @@ type CmdGetMark struct {
Mark int
}
-func (c *CmdGetMark) fiWriteCmd(fiw *FIWriter) error {
+func (c CmdGetMark) fiWriteCmd(fiw *textproto.FIWriter) error {
return fiw.WriteLine("get-mark", ":"+strconv.Itoa(c.Mark))
}
@@ -130,17 +132,17 @@ type CmdCatBlob struct {
DataRef string
}
-func (c *CmdCatBlob) fiWriteCmd(fiw *FIWriter) error {
+func (c CmdCatBlob) fiWriteCmd(fiw *textproto.FIWriter) error {
return fiw.WriteLine("cat-blob", c.DataRef)
}
// See FileLs for using ls inside of a commit
type CmdLs struct {
DataRef string
- Path Path
+ Path textproto.Path
}
-func (c *CmdLs) fiWriteCmd(fiw *FIWriter) error {
+func (c CmdLs) fiWriteCmd(fiw *textproto.FIWriter) error {
return fiw.WriteLine("ls", c.DataRef, c.Path)
}
@@ -149,7 +151,7 @@ type CmdFeature struct {
Argument string
}
-func (c *CmdFeature) fiWriteCmd(fiw *FIWriter) error {
+func (c CmdFeature) fiWriteCmd(fiw *textproto.FIWriter) error {
if c.Argument != "" {
return fiw.WriteLine("feature", c.Feature+"="+c.Argument)
} else {
@@ -161,13 +163,13 @@ type CmdOption struct {
Option string
}
-func (c *CmdOption) fiWriteCmd(fiw *FIWriter) error {
+func (c CmdOption) fiWriteCmd(fiw *textproto.FIWriter) error {
return fiw.WriteLine("option", c.Option)
}
type CmdDone struct{}
-func (c *CmdDone) fiWriteCmd(fiw *FIWriter) error {
+func (c CmdDone) fiWriteCmd(fiw *textproto.FIWriter) error {
return fiw.WriteLine("done")
}
@@ -175,6 +177,6 @@ type CmdComment struct {
Comment string
}
-func (c *CmdComment) fiWriteCmd(fiw *FIWriter) error {
+func (c CmdComment) fiWriteCmd(fiw *textproto.FIWriter) error {
return fiw.WriteLine("#" + c.Comment)
}
diff --git a/ezfiw.go b/ezfiw.go
index 0143f48..03b4622 100644
--- a/ezfiw.go
+++ b/ezfiw.go
@@ -2,10 +2,12 @@ package libfastimport
import (
"strconv"
+
+ "git.lukeshu.com/go/libfastimport/textproto"
)
type ezfiw struct {
- fiw *FIWriter
+ fiw *textproto.FIWriter
err error
}
diff --git a/fileactions.go b/fileactions.go
index 2d81177..d45b982 100644
--- a/fileactions.go
+++ b/fileactions.go
@@ -1,26 +1,30 @@
package libfastimport
+import (
+ "git.lukeshu.com/go/libfastimport/textproto"
+)
+
type FileAction interface {
- fiWriteFA(*FIWriter) error
+ fiWriteFA(*textproto.FIWriter) error
}
type FileModify struct {
- Mode Mode
- Path Path
+ Mode textproto.Mode
+ Path textproto.Path
DataRef string
}
-func (o FileModify) fiWriteFA(fiw *FIWriter) error {
+func (o FileModify) fiWriteFA(fiw *textproto.FIWriter) error {
return fiw.WriteLine("M", o.Mode, o.DataRef, o.Path)
}
type FileModifyInline struct {
- Mode Mode
- Path Path
+ Mode textproto.Mode
+ Path textproto.Path
Data []byte
}
-func (o FileModifyInline) fiWriteFA(fiw *FIWriter) error {
+func (o FileModifyInline) fiWriteFA(fiw *textproto.FIWriter) error {
ez := &ezfiw{fiw: fiw}
ez.WriteLine("M", o.Mode, "inline", o.Path)
ez.WriteData(o.Data)
@@ -28,19 +32,19 @@ func (o FileModifyInline) fiWriteFA(fiw *FIWriter) error {
}
type FileDelete struct {
- Path Path
+ Path textproto.Path
}
-func (o FileDelete) fiWriteFA(fiw *FIWriter) error {
+func (o FileDelete) fiWriteFA(fiw *textproto.FIWriter) error {
return fiw.WriteLine("D", o.Path)
}
type FileCopy struct {
- Src Path
- Dst Path
+ Src textproto.Path
+ Dst textproto.Path
}
-func (o FileCopy) fiWriteFA(fiw *FIWriter) error {
+func (o FileCopy) fiWriteFA(fiw *textproto.FIWriter) error {
return fiw.WriteLine("C", o.Src, o.Dst)
}
@@ -49,13 +53,13 @@ type FileRename struct {
Dst string
}
-func (o FileRename) fiWriteFA(fiw *FIWriter) error {
+func (o FileRename) fiWriteFA(fiw *textproto.FIWriter) error {
return fiw.WriteLine("R", o.Src, o.Dst)
}
type FileDeleteAll struct{}
-func (o FileDeleteAll) fiWriteFA(fiw *FIWriter) error {
+func (o FileDeleteAll) fiWriteFA(fiw *textproto.FIWriter) error {
return fiw.WriteLine("deleteall")
}
@@ -64,7 +68,7 @@ type NoteModify struct {
DataRef string
}
-func (o NoteModify) fiWriteFA(fiw *FIWriter) error {
+func (o NoteModify) fiWriteFA(fiw *textproto.FIWriter) error {
return fiw.WriteLine("N", o.DataRef, o.CommitIsh)
}
@@ -73,7 +77,7 @@ type NoteModifyInline struct {
Data []byte
}
-func (o NoteModifyInline) fiWriteFA(fiw *FIWriter) error {
+func (o NoteModifyInline) fiWriteFA(fiw *textproto.FIWriter) error {
ez := &ezfiw{fiw: fiw}
ez.WriteLine("N", "inline", o.CommitIsh)
ez.WriteData(o.Data)
@@ -82,9 +86,9 @@ func (o NoteModifyInline) fiWriteFA(fiw *FIWriter) error {
// See CmdLs for using ls outside of a commit
type FileLs struct {
- Path Path
+ Path textproto.Path
}
-func (o FileLs) fiWriteFA(fiw *FIWriter) error {
+func (o FileLs) fiWriteFA(fiw *textproto.FIWriter) error {
return fiw.WriteLine("ls", o.Path)
}
diff --git a/frontend.go b/frontend.go
new file mode 100644
index 0000000..73f6d73
--- /dev/null
+++ b/frontend.go
@@ -0,0 +1,68 @@
+package libfastimport
+
+import (
+ "io"
+ "bufio"
+
+ "git.lukeshu.com/go/libfastimport/textproto"
+)
+
+type Frontend struct {
+ w *bufio.Writer
+ fiw *textproto.FIWriter
+ cbr *textproto.CatBlobReader
+}
+
+func NewFrontend(w io.Writer, r io.Reader) *Frontend {
+ ret := Frontend{}
+ ret.w = bufio.NewWriter(w)
+ ret.fiw = textproto.NewFIWriter(ret.w)
+ if r != nil {
+ ret.cbr = textproto.NewCatBlobReader(r)
+ }
+ return &ret
+}
+
+func (f *Frontend) Do(cmd Cmd) error {
+ err := cmd.fiWriteCmd(f.fiw)
+ if err != nil {
+ return err
+ }
+ return f.w.Flush()
+}
+
+func (f *Frontend) GetMark(cmd CmdGetMark) (string, error) {
+ err := f.Do(cmd)
+ if err != nil {
+ return "", err
+ }
+ line, err := f.cbr.ReadLine()
+ if err != nil {
+ return "", err
+ }
+ return cbpGetMark(line)
+}
+
+func (f *Frontend) CatBlob(cmd CmdCatBlob) (sha1 string, data string, err error) {
+ err = f.Do(cmd)
+ if err != nil {
+ return "", "", err
+ }
+ line, err := f.cbr.ReadLine()
+ if err != nil {
+ return "", "", err
+ }
+ return cbpCatBlob(line)
+}
+
+func (f *Frontend) Ls(cmd CmdLs) (mode textproto.Mode, dataref string, path textproto.Path, err error) {
+ err = f.Do(cmd)
+ if err != nil {
+ return 0, "", "", err
+ }
+ line, err := f.cbr.ReadLine()
+ if err != nil {
+ return 0, "", "", err
+ }
+ return cbpLs(line)
+}
diff --git a/parse_catblob.go b/parse_catblob.go
new file mode 100644
index 0000000..53f7d52
--- /dev/null
+++ b/parse_catblob.go
@@ -0,0 +1,97 @@
+package libfastimport
+
+import (
+ "fmt"
+ "strings"
+ "strconv"
+
+ "git.lukeshu.com/go/libfastimport/textproto"
+)
+
+func cbpGetMark(line string) (string, error) {
+ if len(line) != 41 {
+ return "", fmt.Errorf("get-mark: short <sha1>\\n: %q", line)
+ }
+ if line[40] != '\n' {
+ return "", fmt.Errorf("get-mark: malformed <sha1>\\n: %q", line)
+ }
+ for _, b := range line[:40] {
+ if !(('0' <= b && b <= '9') || ('a' <= b && b <= 'f')) {
+ return "", fmt.Errorf("get-mark: malformed <sha1>: %q", line[:40])
+ }
+ }
+ return line[:40], nil
+}
+
+func cbpCatBlob(full string) (sha1 string, data string, err error) {
+ // The format is:
+ //
+ // <sha1> SP 'blob' SP <size> LF
+ // <data> LF
+
+ if full[len(full)-1] != '\n' {
+ return "", "", fmt.Errorf("cat-blob: missing trailing newline")
+ }
+
+ lf := strings.IndexByte(full, '\n')
+ if lf < 0 || lf == len(full)-1 {
+ return "", "", fmt.Errorf("cat-blob: malformed header: %q", full)
+ }
+ head := full[:lf]
+ data = full[lf+1:len(full)-1]
+
+ if len(head) < 40+6+1 {
+ return "", "", fmt.Errorf("cat-blob: malformed header: %q", head)
+ }
+
+ sha1 = head[:40]
+ for _, b := range sha1 {
+ if !(('0' <= b && b <= '9') || ('a' <= b && b <= 'f')) {
+ return "", "", fmt.Errorf("cat-blob: malformed <sha1>: %q", sha1)
+ }
+ }
+
+ if string(head[40:46]) != " blob " {
+ return "", "", fmt.Errorf("cat-blob: malformed header: %q", head)
+ }
+
+ size, err := strconv.Atoi(head[46:])
+ if err != nil {
+ return "", "", fmt.Errorf("cat-blob: malformed blob size: %v", err)
+ }
+
+ if size != len(data) {
+ return "", "", fmt.Errorf("cat-blob: size header (%d) didn't match delivered size (%d)", size, len(data))
+ }
+
+ return sha1, data, err
+}
+
+func cbpLs(line string) (mode textproto.Mode, dataref string, path textproto.Path, err error) {
+ // <mode> SP ('blob' | 'tree' | 'commit') SP <dataref> HT <path> LF
+ // or
+ // 'missing' SP <path> LF
+ if line[len(line)-1] != '\n' {
+ return 0, "", "", fmt.Errorf("ls: missing trailing newline")
+ }
+ if strings.HasPrefix(line, "missing ") {
+ strPath := line[8:len(line)-1]
+ return 0, "", textproto.PathUnescape(strPath), nil
+ } else {
+ sp1 := strings.IndexByte(line, ' ')
+ sp2 := strings.IndexByte(line[sp1+1:], ' ')
+ ht := strings.IndexByte(line[sp2+1:], '\t')
+ if sp1 < 0 || sp2 < 0 || ht < 0 {
+ return 0, "", "", fmt.Errorf("ls: malformed line: %q", line)
+ }
+ strMode := line[:sp1]
+ strRef := line[sp2+1:ht]
+ strPath := line[ht+1:len(line)-1]
+
+ nMode, err := strconv.ParseUint(strMode, 8, 18)
+ if err != nil {
+ return 0, "", "", err
+ }
+ return textproto.Mode(nMode), strRef, textproto.PathUnescape(strPath), nil
+ }
+}
diff --git a/read_catblob.go b/read_catblob.go
deleted file mode 100644
index ed5cb14..0000000
--- a/read_catblob.go
+++ /dev/null
@@ -1,69 +0,0 @@
-package libfastimport
-
-import (
- "fmt"
- "bytes"
- "strconv"
-)
-
-func CatBlobParseGetMark(dat []byte) (string, error) {
- if len(dat) != 41 {
- return "", fmt.Errorf("get-mark: short <sha1>\\n: %q", string(dat))
- }
- if dat[40] != '\n' {
- return "", fmt.Errorf("get-mark: malformed <sha1>\\n: %q", string(dat))
- }
- for _, b := range dat[:40] {
- if !(('0' <= b && b <= '9') || ('a' <= b && b <= 'f')) {
- return "", fmt.Errorf("get-mark: malformed <sha1>: %q", string(dat[:40]))
- }
- }
- return string(dat[:40]), nil
-}
-
-func CatBlobParseCatBlob(full []byte) (sha1 string, data []byte, err error) {
- // The format is:
- //
- // <sha1> SP 'blob' SP <size> LF
- // <data> LF
-
- lf := bytes.IndexByte(full, '\n')
- if lf < 0 || lf == len(full)-1 {
- return "", nil, fmt.Errorf("cat-blob: malformed header: %q", string(full))
- }
- head := full[:lf]
- data = full[lf+1:len(full)-1]
-
- if len(head) < 40+6+1 {
- return "", nil, fmt.Errorf("cat-blob: malformed header: %q", string(head))
- }
-
- sha1 = string(head[:40])
- for _, b := range sha1 {
- if !(('0' <= b && b <= '9') || ('a' <= b && b <= 'f')) {
- return "", nil, fmt.Errorf("cat-blob: malformed <sha1>: %q", sha1)
- }
- }
-
- if string(head[40:46]) != " blob " {
- return "", nil, fmt.Errorf("cat-blob: malformed header: %q", head)
- }
-
- size, err := strconv.Atoi(string(head[46:]))
- if err != nil {
- return "", nil, fmt.Errorf("cat-blob: malformed blob size: %v", err)
- }
-
- if size != len(data) {
- return "", nil, fmt.Errorf("cat-blob: size header (%d) didn't match delivered size (%d)", size, len(data))
- }
-
- return sha1, data, err
-}
-
-func CatBlobParseLs(dataref string, path string) error {
- // <mode> SP ('blob' | 'tree' | 'commit') SP <dataref> HT <path> LF
- // or
- // 'missing' SP <path> LF
- return nil // TODO
-}
diff --git a/read_fastimport.go b/read_fastimport.go
index ea10885..abafa4b 100644
--- a/read_fastimport.go
+++ b/read_fastimport.go
@@ -1,5 +1,9 @@
package libfastimport
+import (
+ "git.lukeshu.com/go/libfastimport/textproto"
+)
+
type UnsupportedCommand string
func (e UnsupportedCommand) Error() string {
@@ -7,18 +11,18 @@ func (e UnsupportedCommand) Error() string {
}
type Parser struct {
- fir *FIReader
+ fir *textproto.FIReader
cmd chan Cmd
}
func (p *Parser) GetCmd() (Cmd, error) {
for p.cmd == nil {
- slice, err := p.fir.ReadSlice()
+ line, err := p.fir.ReadLine()
if err != nil {
return nil, err
}
- err = p.putSlice(slice)
+ err = p.putLine(line)
if err != nil {
return nil, err
}
@@ -26,23 +30,23 @@ func (p *Parser) GetCmd() (Cmd, error) {
return <-p.cmd, nil
}
-func (p *Parser) putSlice(slice []byte) error {
- if len(slice) < 1 {
- return UnsupportedCommand(slice)
+func (p *Parser) putLine(line string) error {
+ if len(line) < 1 {
+ return UnsupportedCommand(line)
}
- switch slice[0] {
+ switch line[0] {
case '#': // comment
case 'b': // blob
case 'c':
- if len(slice) < 2 {
- return UnsupportedCommand(slice)
+ if len(line) < 2 {
+ return UnsupportedCommand(line)
}
- switch slice[1] {
+ switch line[1] {
case 'o': // commit
case 'h': // checkpoint
case 'a': // cat-blob
default:
- return UnsupportedCommand(slice)
+ return UnsupportedCommand(line)
}
case 'd': // done
case 'f': // feature
@@ -53,7 +57,7 @@ func (p *Parser) putSlice(slice []byte) error {
case 'r': // reset
case 't': // tag
default:
- return UnsupportedCommand(slice)
+ return UnsupportedCommand(line)
}
return nil // TODO
}
diff --git a/io.go b/textproto/io.go
index d8a68bb..af2cb19 100644
--- a/io.go
+++ b/textproto/io.go
@@ -1,11 +1,11 @@
-package libfastimport
+package textproto
import (
- "fmt"
"bufio"
- "bytes"
+ "fmt"
"io"
"strconv"
+ "strings"
)
type FIReader struct {
@@ -18,9 +18,9 @@ func NewFIReader(r io.Reader) *FIReader {
}
}
-func (fir *FIReader) ReadSlice() (line []byte, err error) {
+func (fir *FIReader) ReadLine() (line string, err error) {
retry:
- line, err = fir.r.ReadSlice('\n')
+ line, err = fir.r.ReadString('\n')
if err != nil {
return
}
@@ -28,19 +28,16 @@ retry:
goto retry
}
- if bytes.HasPrefix(line, []byte("data ")) {
- if string(line[5:7]) == "<<" {
+ if strings.HasPrefix(line, "data ") {
+ if line[5:7] == "<<" {
// Delimited format
delim := line[7 : len(line)-1]
- suffix := []byte("\n" + string(delim) + "\n")
-
- _line := make([]byte, len(line))
- copy(_line, line)
- line = _line
+ suffix := "\n" + delim + "\n"
- for !bytes.HasSuffix(line, suffix) {
- _line, err = fir.r.ReadSlice('\n')
- line = append(line, _line...)
+ for !strings.HasSuffix(line, suffix) {
+ var _line string
+ _line, err = fir.r.ReadString('\n')
+ line += _line
if err != nil {
return
}
@@ -48,15 +45,13 @@ retry:
} else {
// Exact byte count format
var size int
- size, err = strconv.Atoi(string(line[5 : len(line)-1]))
+ size, err = strconv.Atoi(line[5 : len(line)-1])
if err != nil {
return
}
- _line := make([]byte, size+len(line))
- copy(_line, line)
- var n int
- n, err = io.ReadFull(fir.r, _line[len(line):])
- line = _line[:n+len(line)]
+ data := make([]byte, size)
+ _, err = io.ReadFull(fir.r, data)
+ line += string(data)
}
}
return
@@ -96,9 +91,9 @@ func NewCatBlobReader(r io.Reader) *CatBlobReader {
}
}
-func (cbr *CatBlobReader) ReadSlice() (line []byte, err error) {
+func (cbr *CatBlobReader) ReadLine() (line string, err error) {
retry:
- line, err = cbr.r.ReadSlice('\n')
+ line, err = cbr.r.ReadString('\n')
if err != nil {
return
}
@@ -112,7 +107,7 @@ retry:
// ls : 'missing' SP <path> LF
// decide if we have a cat-blob result
- if len(line) <= 46 || string(line[40:46]) != " blob " {
+ if len(line) <= 46 || line[40:46] != " blob " {
return
}
for _, b := range line[:40] {
@@ -122,14 +117,13 @@ retry:
}
// we have a cat-blob result
var size int
- size, err = strconv.Atoi(string(line[46 : len(line)-1]))
+ size, err = strconv.Atoi(line[46 : len(line)-1])
if err != nil {
return
}
- _line := make([]byte, len(line)+size+1)
- copy(_line, line)
- n, err := io.ReadFull(cbr.r, _line[len(line):])
- line = _line[:n+len(line)]
+ data := make([]byte, size+1)
+ _, err = io.ReadFull(cbr.r, data)
+ line += string(data[:size])
return
}
diff --git a/types.go b/textproto/types.go
index 1ce0741..2109517 100644
--- a/types.go
+++ b/textproto/types.go
@@ -1,4 +1,4 @@
-package libfastimport
+package textproto
import (
"fmt"
@@ -42,24 +42,24 @@ func (m Mode) String() string {
return fmt.Sprintf("%06o", m)
}
-func PathEscape(path string) string {
- if strings.HasPrefix(path, "\"") || strings.ContainsRune(path, '\n') {
- return "\"" + strings.Replace(strings.Replace(strings.Replace(path, "\\", "\\\\", -1), "\"", "\\\"", -1), "\n", "\\n", -1) + "\""
+func PathEscape(path Path) string {
+ if strings.HasPrefix(string(path), "\"") || strings.ContainsRune(string(path), '\n') {
+ return "\"" + strings.Replace(strings.Replace(strings.Replace(string(path), "\\", "\\\\", -1), "\"", "\\\"", -1), "\n", "\\n", -1) + "\""
} else {
- return path
+ return string(path)
}
}
-func PathUnescape(epath string) string {
+func PathUnescape(epath string) Path {
if strings.HasPrefix(epath, "\"") {
- return strings.Replace(strings.Replace(strings.Replace(epath[1:len(epath)-1], "\\n", "\n", -1), "\\\"", "\"", -1), "\\\\", "\\", -1)
+ return Path(strings.Replace(strings.Replace(strings.Replace(epath[1:len(epath)-1], "\\n", "\n", -1), "\\\"", "\"", -1), "\\\\", "\\", -1))
} else {
- return epath
+ return Path(epath)
}
}
type Path string
func (p Path) String() string {
- return PathEscape(string(p))
+ return PathEscape(p)
}