1 // Copyright 2015 Google Inc. All rights reserved 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package kati 16 17 import ( 18 "io" 19 "sync" 20 ) 21 22 var ( 23 ebufFree = sync.Pool{ 24 New: func() interface{} { return new(evalBuffer) }, 25 } 26 wbufFree = sync.Pool{ 27 New: func() interface{} { return new(wordBuffer) }, 28 } 29 ) 30 31 func writeByte(w io.Writer, b byte) error { 32 if bw, ok := w.(io.ByteWriter); ok { 33 return bw.WriteByte(b) 34 } 35 _, err := w.Write([]byte{b}) 36 return err 37 } 38 39 // use io.WriteString to stringWrite. 40 41 type ssvWriter struct { 42 io.Writer 43 sep bool 44 } 45 46 func (w *ssvWriter) writeWord(word []byte) { 47 if w.sep { 48 writeByte(w.Writer, ' ') 49 } 50 w.sep = true 51 w.Writer.Write(word) 52 } 53 54 func (w *ssvWriter) writeWordString(word string) { 55 if w.sep { 56 writeByte(w.Writer, ' ') 57 } 58 w.sep = true 59 io.WriteString(w.Writer, word) 60 } 61 62 func (w *ssvWriter) resetSep() { 63 w.sep = false 64 } 65 66 type buffer struct { 67 buf []byte 68 bootstrap [64]byte // memory to hold first slice 69 } 70 71 func (b *buffer) Write(data []byte) (int, error) { 72 b.buf = append(b.buf, data...) 73 return len(data), nil 74 } 75 76 func (b *buffer) WriteByte(c byte) error { 77 b.buf = append(b.buf, c) 78 return nil 79 } 80 81 func (b *buffer) WriteString(s string) (int, error) { 82 b.buf = append(b.buf, []byte(s)...) 83 return len(s), nil 84 } 85 86 func (b *buffer) Bytes() []byte { return b.buf } 87 func (b *buffer) Len() int { return len(b.buf) } 88 func (b *buffer) String() string { return string(b.buf) } 89 90 func (b *buffer) Reset() { 91 if b.buf == nil { 92 b.buf = b.bootstrap[:0] 93 } 94 b.buf = b.buf[:0] 95 } 96 97 type evalBuffer struct { 98 buffer 99 ssvWriter 100 args [][]byte 101 } 102 103 func newEbuf() *evalBuffer { 104 buf := ebufFree.Get().(*evalBuffer) 105 buf.Reset() 106 return buf 107 } 108 109 func (buf *evalBuffer) release() { 110 if cap(buf.Bytes()) > 1024 { 111 return 112 } 113 buf.Reset() 114 buf.args = buf.args[:0] 115 ebufFree.Put(buf) 116 } 117 118 func (b *evalBuffer) Reset() { 119 b.buffer.Reset() 120 b.resetSep() 121 } 122 123 func (b *evalBuffer) resetSep() { 124 if b.ssvWriter.Writer == nil { 125 b.ssvWriter.Writer = &b.buffer 126 } 127 b.ssvWriter.resetSep() 128 } 129 130 type wordBuffer struct { 131 buf buffer 132 words [][]byte 133 } 134 135 func newWbuf() *wordBuffer { 136 buf := wbufFree.Get().(*wordBuffer) 137 buf.Reset() 138 return buf 139 } 140 141 func (buf *wordBuffer) release() { 142 if cap(buf.Bytes()) > 1024 { 143 return 144 } 145 buf.Reset() 146 wbufFree.Put(buf) 147 } 148 149 func (wb *wordBuffer) Write(data []byte) (int, error) { 150 if len(data) == 0 { 151 return 0, nil 152 } 153 off := len(wb.buf.buf) 154 var cont bool 155 if !isWhitespace(rune(data[0])) && len(wb.buf.buf) > 0 { 156 cont = !isWhitespace(rune(wb.buf.buf[off-1])) 157 } 158 ws := newWordScanner(data) 159 for ws.Scan() { 160 if cont { 161 word := wb.words[len(wb.words)-1] 162 wb.words = wb.words[:len(wb.words)-1] 163 wb.buf.buf = wb.buf.buf[:len(wb.buf.buf)-len(word)] 164 var w []byte 165 w = append(w, word...) 166 w = append(w, ws.Bytes()...) 167 wb.writeWord(w) 168 cont = false 169 continue 170 } 171 wb.writeWord(ws.Bytes()) 172 } 173 if isWhitespace(rune(data[len(data)-1])) { 174 wb.buf.buf = append(wb.buf.buf, ' ') 175 } 176 return len(data), nil 177 } 178 179 func (wb *wordBuffer) WriteByte(c byte) error { 180 _, err := wb.Write([]byte{c}) 181 return err 182 } 183 184 func (wb *wordBuffer) WriteString(s string) (int, error) { 185 return wb.Write([]byte(s)) 186 } 187 188 func (wb *wordBuffer) writeWord(word []byte) { 189 if len(wb.buf.buf) > 0 { 190 wb.buf.buf = append(wb.buf.buf, ' ') 191 } 192 off := len(wb.buf.buf) 193 wb.buf.buf = append(wb.buf.buf, word...) 194 wb.words = append(wb.words, wb.buf.buf[off:off+len(word)]) 195 } 196 197 func (wb *wordBuffer) writeWordString(word string) { 198 wb.writeWord([]byte(word)) 199 } 200 201 func (wb *wordBuffer) Reset() { 202 wb.buf.Reset() 203 wb.words = nil 204 } 205 206 func (wb *wordBuffer) resetSep() {} 207 208 func (wb *wordBuffer) Bytes() []byte { 209 return wb.buf.Bytes() 210 } 211