From efc7a5ebc9e10983571c080017100a8b39eee1d0 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Wed, 15 Nov 2017 21:39:40 -0500 Subject: more --- parse_catblob.go | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 parse_catblob.go (limited to 'parse_catblob.go') 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 \\n: %q", line) + } + if line[40] != '\n' { + return "", fmt.Errorf("get-mark: malformed \\n: %q", line) + } + for _, b := range line[:40] { + if !(('0' <= b && b <= '9') || ('a' <= b && b <= 'f')) { + return "", fmt.Errorf("get-mark: malformed : %q", line[:40]) + } + } + return line[:40], nil +} + +func cbpCatBlob(full string) (sha1 string, data string, err error) { + // The format is: + // + // SP 'blob' SP LF + // 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 : %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) { + // SP ('blob' | 'tree' | 'commit') SP HT LF + // or + // 'missing' SP 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 + } +} -- cgit v1.2.3