github.com/go-graphite/carbonapi@v0.17.0/expr/types/extract.go (about) 1 package types 2 3 import ( 4 "strings" 5 "unicode/utf8" 6 ) 7 8 var allowedCharactersInMetricName = map[byte]struct{}{ 9 '=': struct{}{}, 10 '@': struct{}{}, 11 } 12 13 func byteAllowedInName(b byte) bool { 14 _, ok := allowedCharactersInMetricName[b] 15 return ok 16 } 17 18 // ExtractNameLoc extracts name start:end location out of function list with . Only for use in MetrciData name parse, it's has more allowed chard in names, like = 19 func ExtractNameLoc(s string) (int, int) { 20 // search for a metric name in 's' 21 // metric name is defined to be a Series of name characters terminated by a ',' or ')' 22 23 var w, i, start, braces int 24 var c rune 25 FOR: 26 for i, c = range s { 27 w = i 28 switch c { 29 case '{': 30 braces++ 31 case '}': 32 if braces == 0 { 33 break FOR 34 } 35 braces-- 36 case ',': 37 if braces == 0 { 38 break FOR 39 } 40 case '(': 41 if i >= 11 { 42 n := i - 11 43 if s[n:i] == "seriesByTag" { 44 end := strings.IndexRune(s[n:], ')') 45 if end == -1 { 46 return n, len(s) // broken end of args, can't exist in correctly parsed functions 47 } else { 48 return n, n + end + 1 49 } 50 } 51 } 52 start = i + 1 53 case ')': 54 break FOR 55 } 56 w += utf8.RuneLen(c) 57 } 58 59 return start, w 60 } 61 62 // ExtractName extracts name out of function list. Only for use in MetrciData name parse, it's has more allowed chard in names, like = 63 func ExtractName(s string) string { 64 start, end := ExtractNameLoc(s) 65 return s[start:end] 66 } 67 68 // ExtractNameTag extracts name tag out of function list with . Only for use in MetrciData name parse, it's has more allowed chard in names, like = 69 func ExtractNameTag(s string) string { 70 // search for a metric name in 's' 71 // metric name is defined to be a Series of name characters terminated by a ',' or ')' 72 73 var w, i, start, braces int 74 var c rune 75 FOR: 76 for i, c = range s { 77 w = i 78 switch c { 79 case '{': 80 braces++ 81 case '}': 82 if braces == 0 { 83 break FOR 84 } 85 braces-- 86 case ',': 87 if braces == 0 { 88 break FOR 89 } 90 case '(': 91 if i >= 11 { 92 n := i - 11 93 if s[n:i] == "seriesByTag" { 94 end := strings.IndexRune(s[n:], ')') 95 if end == -1 { 96 return s[n:len(s)] // broken end of args, can't exist in correctly parsed functions 97 } else { 98 return s[n : n+end+1] 99 } 100 } 101 } 102 start = i + 1 103 case ')', ';': 104 break FOR 105 } 106 w += utf8.RuneLen(c) 107 } 108 109 return s[start:w] 110 }