1package protocol 2 3import ( 4 "fmt" 5 "time" 6) 7 8// Write writes out data to a line protocol encoder. Note: it does no sorting. It assumes you have done your own sorting for tagValues 9func (e *Encoder) Write(name []byte, ts time.Time, tagKeys, tagVals, fieldKeys [][]byte, fieldVals []interface{}) (int, error) { 10 e.header = e.header[:0] 11 if len(name) == 0 || name[len(name)-1] == byte('\\') { 12 return 0, ErrInvalidName 13 } 14 nameEscapeBytes(&e.header, name) 15 for i := range tagKeys { 16 // Some keys and values are not encodeable as line protocol, such as 17 // those with a trailing '\' or empty strings. 18 if len(tagKeys[i]) == 0 || len(tagVals[i]) == 0 || tagKeys[i][len(tagKeys[i])-1] == byte('\\') { 19 if e.failOnFieldError { 20 return 0, fmt.Errorf("invalid field: key \"%s\", val \"%s\"", tagKeys[i], tagVals[i]) 21 } 22 continue 23 } 24 e.header = append(e.header, byte(',')) 25 escapeBytes(&e.header, tagKeys[i]) 26 e.header = append(e.header, byte('=')) 27 escapeBytes(&e.header, tagVals[i]) 28 } 29 e.header = append(e.header, byte(' ')) 30 e.buildFooter(ts) 31 32 i := 0 33 totalWritten := 0 34 pairsLen := 0 35 firstField := true 36 for i := range fieldKeys { 37 e.pair = e.pair[:0] 38 key := fieldKeys[i] 39 if len(key) == 0 || key[len(key)-1] == byte('\\') { 40 if e.failOnFieldError { 41 return 0, &FieldError{"invalid field key"} 42 } 43 continue 44 } 45 escapeBytes(&e.pair, key) 46 // Some keys are not encodeable as line protocol, such as those with a 47 // trailing '\' or empty strings. 48 e.pair = append(e.pair, byte('=')) 49 err := e.buildFieldVal(fieldVals[i]) 50 if err != nil { 51 if e.failOnFieldError { 52 return 0, err 53 } 54 continue 55 } 56 57 bytesNeeded := len(e.header) + pairsLen + len(e.pair) + len(e.footer) 58 59 // Additional length needed for field separator `,` 60 if !firstField { 61 bytesNeeded++ 62 } 63 64 if e.maxLineBytes > 0 && bytesNeeded > e.maxLineBytes { 65 // Need at least one field per line 66 if firstField { 67 return 0, ErrNeedMoreSpace 68 } 69 70 i, err = e.w.Write(e.footer) 71 if err != nil { 72 return 0, err 73 } 74 totalWritten += i 75 76 bytesNeeded = len(e.header) + len(e.pair) + len(e.footer) 77 78 if e.maxLineBytes > 0 && bytesNeeded > e.maxLineBytes { 79 return 0, ErrNeedMoreSpace 80 } 81 82 i, err = e.w.Write(e.header) 83 if err != nil { 84 return 0, err 85 } 86 totalWritten += i 87 88 i, err = e.w.Write(e.pair) 89 if err != nil { 90 return 0, err 91 } 92 totalWritten += i 93 94 pairsLen += len(e.pair) 95 firstField = false 96 continue 97 } 98 99 if firstField { 100 i, err = e.w.Write(e.header) 101 if err != nil { 102 return 0, err 103 } 104 totalWritten += i 105 106 } else { 107 i, err = e.w.Write(comma) 108 if err != nil { 109 return 0, err 110 } 111 totalWritten += i 112 113 } 114 115 e.w.Write(e.pair) 116 117 pairsLen += len(e.pair) 118 firstField = false 119 } 120 121 if firstField { 122 return 0, ErrNoFields 123 } 124 i, err := e.w.Write(e.footer) 125 if err != nil { 126 return 0, err 127 } 128 totalWritten += i 129 return totalWritten, nil 130} 131