utils.go (2599B)
1 package tplc 2 3 import ( 4 "fmt" 5 "path" 6 "path/filepath" 7 "unicode/utf8" 8 9 "github.com/pkg/errors" 10 11 "go.lair.cx/go-core/net/htmlx" 12 ) 13 14 func getPackageName(dirName string) (string, error) { 15 absPath, err := filepath.Abs(dirName) 16 if err != nil { 17 return "", err 18 } 19 20 if absPath == "/" { 21 return "", errors.New("root directory is not allowed") 22 } 23 24 _, pkg := path.Split(absPath) 25 return pkg, nil 26 } 27 28 func getAttrs(t *htmlx.Tokenizer) map[string]string { 29 out := make(map[string]string) 30 31 for { 32 key, val, hasMore := t.TagAttr() 33 if key == nil { 34 break 35 } 36 37 out[string(key)] = string(val) 38 39 if !hasMore { 40 break 41 } 42 } 43 44 return out 45 } 46 47 func getByteAttrs(t *htmlx.Tokenizer) map[string][]byte { 48 out := make(map[string][]byte) 49 50 for { 51 key, val, hasMore := t.TagAttr() 52 if key == nil { 53 break 54 } 55 56 out[string(key)] = val 57 58 if !hasMore { 59 break 60 } 61 } 62 63 return out 64 } 65 66 func appendBacktickString(buf []byte, s string) ([]byte, error) { 67 if cap(buf)-len(buf) < len(s)+2 { 68 nbuf := make([]byte, len(buf), len(buf)+len(s)+2) 69 copy(nbuf, buf) 70 buf = nbuf 71 } 72 buf = append(buf, '`') 73 for width := 0; len(s) > 0; s = s[width:] { 74 var r rune 75 r, width = utf8.DecodeRuneInString(s) 76 if r == '\ufeff' { 77 return nil, errors.New("UTF-8 with BOM can not be encoded") 78 } else if r == utf8.RuneError { 79 return nil, errors.New("invalid utf-8 string") 80 } else if r < ' ' && r != '\t' || r == '\u007F' { 81 return nil, errors.New("control character can not be encoded") 82 } else if r == '`' { 83 buf = append(buf, "`+\"`\"+`"...) 84 } else { 85 buf = append(buf, s[:width]...) 86 } 87 } 88 buf = append(buf, '`') 89 return buf, nil 90 } 91 92 func appendBacktickByteString(buf []byte, s []byte) ([]byte, error) { 93 if cap(buf)-len(buf) < len(s)+2 { 94 nbuf := make([]byte, len(buf), len(buf)+len(s)+2) 95 copy(nbuf, buf) 96 buf = nbuf 97 } 98 buf = append(buf, '`') 99 for width := 0; len(s) > 0; s = s[width:] { 100 var r rune 101 r, width = utf8.DecodeRune(s) 102 if r == '\ufeff' { 103 return nil, errors.New("UTF-8 with BOM can not be encoded") 104 } else if r == utf8.RuneError { 105 return nil, errors.New("invalid utf-8 string") 106 } else if (r < ' ' && r != '\t' && r != '\r' && r != '\n') || r == '\u007F' { 107 return nil, errors.New("control character can not be encoded") 108 } else if r == '`' { 109 buf = append(buf, "`+\"`\"+`"...) 110 } else { 111 buf = append(buf, s[:width]...) 112 } 113 } 114 buf = append(buf, '`') 115 return buf, nil 116 } 117 118 func checkTagName(t *htmlx.Tokenizer, name string) error { 119 tagName, _ := t.TagName() 120 if string(tagName) != name { 121 return fmt.Errorf("unexpected closing tag: %s", tagName) 122 } 123 return nil 124 }