Github user dcelasun commented on a diff in the pull request: https://github.com/apache/thrift/pull/1440#discussion_r175252307 --- Diff: lib/go/thrift/fast_buffer.go --- @@ -0,0 +1,257 @@ +package thrift + +import ( + "fmt" + "unsafe" +) + +type FastFrameBuffer struct { + w *TFramedTransport // + b []byte + wIdx int // write-offset, reset when Flush + frameSize int + rIdx int // read-offset, reset when read-new-frame + buf [4]byte // only for write&read data-len +} + +func NewFastBuffer(w *TFramedTransport, size int) *FastFrameBuffer { + return &FastFrameBuffer{ + w: w, + b: make([]byte, size), + rIdx: 0, + wIdx: 0, + } +} + +func (p *FastFrameBuffer) WritByte(b int8) { + if p.wIdx+1 > p.Cap() { + p.grow(2*p.Cap() + 1) + } + p.b[p.wIdx] = byte(b) + p.wIdx += 1 +} + +func (p *FastFrameBuffer) WriteBytes(b []byte) { + if p.wIdx+len(b) > p.Cap() { + p.grow(2*p.Cap() + len(b)) + } + copy(p.b[p.wIdx:], b) + p.wIdx += len(b) +} + +func (p *FastFrameBuffer) WriteI16(i uint16) { + if p.wIdx+2 > p.Cap() { + p.grow(2*p.Cap() + 2) + } + copy(p.b[p.wIdx:], []byte{byte(i >> 8), byte(i)}) + p.wIdx += 2 +} + +func (p *FastFrameBuffer) WriteI32(i uint32) { + if p.wIdx+4 > p.Cap() { + p.grow(2*p.Cap() + 4) + } + copy(p.b[p.wIdx:], []byte{byte(i >> 24), byte(i >> 16), byte(i >> 8), byte(i)}) + p.wIdx += 4 +} + +func (p *FastFrameBuffer) WriteI64(i uint64) { + if p.wIdx+8 > p.Cap() { + p.grow(2*p.Cap() + 8) + } + copy(p.b[p.wIdx:], []byte{byte(i >> 56), byte(i >> 48), byte(i >> 40), byte(i >> 32), byte(i >> 24), byte(i >> 16), byte(i >> 8), byte(i)}) + p.wIdx += 8 +} + +func (p *FastFrameBuffer) WriteString(s string) { + if p.wIdx+len(s) > p.Cap() { + p.grow(2*p.Cap() + len(s)) + } + copy(p.b[p.wIdx:], str2bytes(s)) + p.wIdx += len(s) +} + +func (p *FastFrameBuffer) Len() int { + return len(p.b) +} + +func (p *FastFrameBuffer) Cap() int { + return cap(p.b) +} + +func (p *FastFrameBuffer) Flush() error { + p.buf[0] = byte(p.wIdx >> 24) + p.buf[1] = byte(p.wIdx >> 16) + p.buf[2] = byte(p.wIdx >> 8) + p.buf[3] = byte(p.wIdx) + _, err := p.w.transport.Write(p.buf[:4]) + + if err != nil { + return fmt.Errorf("Flush Write-Len failed, err: %v\n", err) + } + _, err = p.w.transport.Write(p.b[:p.wIdx]) + if err != nil { + return fmt.Errorf("Flush Write-Dat failed, err: %v\n", err) + } + p.ResetWriter() + p.w.transport.Flush() + return nil +} + +func (p *FastFrameBuffer) ResetWriter() { + p.wIdx = 0 +} + +func (p *FastFrameBuffer) ResetReader() { + p.rIdx = 0 +} + +func (p *FastFrameBuffer) grow(n int) { + b := make([]byte, n) + copy(b, p.b[0:]) + p.b = b +} + +func (p *FastFrameBuffer) ReadByte() (c byte, err error) { + if p.frameSize == 0 { + p.frameSize, err = p.readFrameHeader() + if err != nil { + return + } + _, err = p.readAll(p.frameSize) + if err != nil { + return + } + } + if p.frameSize < 1 { + return 0, fmt.Errorf("Not enought frame size %d to read %d bytes", p.frameSize, 1) --- End diff -- s/enought/enough everywhere in the file.
---