Home | History | Annotate | Download | only in kati
      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