github.com/artyom/thrift@v0.0.0-20130902103359-388840a05deb/iostream_transport.go (about) 1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20 package thrift 21 22 import ( 23 "bufio" 24 "io" 25 ) 26 27 // StreamTransport is a Transport made of an io.Reader and/or an io.Writer 28 type StreamTransport struct { 29 Reader io.Reader 30 Writer io.Writer 31 isReadWriter bool 32 } 33 34 type StreamTransportFactory struct { 35 Reader io.Reader 36 Writer io.Writer 37 isReadWriter bool 38 } 39 40 func (p *StreamTransportFactory) GetTransport(trans TTransport) TTransport { 41 if trans != nil { 42 t, ok := trans.(*StreamTransport) 43 if ok { 44 if t.isReadWriter { 45 return NewStreamTransportRW(t.Reader.(io.ReadWriter)) 46 } 47 if t.Reader != nil && t.Writer != nil { 48 return NewStreamTransport(t.Reader, t.Writer) 49 } 50 if t.Reader != nil && t.Writer == nil { 51 return NewStreamTransportR(t.Reader) 52 } 53 if t.Reader == nil && t.Writer != nil { 54 return NewStreamTransportW(t.Writer) 55 } 56 return &StreamTransport{} 57 } 58 } 59 if p.isReadWriter { 60 return NewStreamTransportRW(p.Reader.(io.ReadWriter)) 61 } 62 if p.Reader != nil && p.Writer != nil { 63 return NewStreamTransport(p.Reader, p.Writer) 64 } 65 if p.Reader != nil && p.Writer == nil { 66 return NewStreamTransportR(p.Reader) 67 } 68 if p.Reader == nil && p.Writer != nil { 69 return NewStreamTransportW(p.Writer) 70 } 71 return &StreamTransport{} 72 } 73 74 func NewStreamTransportFactory(reader io.Reader, writer io.Writer, isReadWriter bool) *StreamTransportFactory { 75 return &StreamTransportFactory{Reader: reader, Writer: writer, isReadWriter: isReadWriter} 76 } 77 78 func NewStreamTransport(r io.Reader, w io.Writer) *StreamTransport { 79 return &StreamTransport{Reader: bufio.NewReader(r), Writer: bufio.NewWriter(w)} 80 } 81 82 func NewStreamTransportR(r io.Reader) *StreamTransport { 83 return &StreamTransport{Reader: bufio.NewReader(r)} 84 } 85 86 func NewStreamTransportW(w io.Writer) *StreamTransport { 87 return &StreamTransport{Writer: bufio.NewWriter(w)} 88 } 89 90 func NewStreamTransportRW(rw io.ReadWriter) *StreamTransport { 91 bufrw := bufio.NewReadWriter(bufio.NewReader(rw), bufio.NewWriter(rw)) 92 return &StreamTransport{Reader: bufrw, Writer: bufrw, isReadWriter: true} 93 } 94 95 // (The streams must already be open at construction time, so this should 96 // always return true.) 97 func (p *StreamTransport) IsOpen() bool { 98 return true 99 } 100 101 // (The streams must already be open. This method does nothing.) 102 func (p *StreamTransport) Open() error { 103 return nil 104 } 105 106 func (p *StreamTransport) Peek() bool { 107 return p.IsOpen() 108 } 109 110 // Closes both the input and output streams. 111 func (p *StreamTransport) Close() error { 112 closedReader := false 113 if p.Reader != nil { 114 c, ok := p.Reader.(io.Closer) 115 if ok { 116 e := c.Close() 117 closedReader = true 118 if e != nil { 119 return e 120 } 121 } 122 p.Reader = nil 123 } 124 if p.Writer != nil && (!closedReader || !p.isReadWriter) { 125 c, ok := p.Writer.(io.Closer) 126 if ok { 127 e := c.Close() 128 if e != nil { 129 return e 130 } 131 } 132 p.Writer = nil 133 } 134 return nil 135 } 136 137 // Reads from the underlying input stream if not null. 138 func (p *StreamTransport) Read(buf []byte) (int, error) { 139 if p.Reader == nil { 140 return 0, NewTTransportException(NOT_OPEN, "Cannot read from null inputStream") 141 } 142 n, err := p.Reader.Read(buf) 143 return n, NewTTransportExceptionFromError(err) 144 } 145 146 // Writes to the underlying output stream if not null. 147 func (p *StreamTransport) Write(buf []byte) (int, error) { 148 if p.Writer == nil { 149 return 0, NewTTransportException(NOT_OPEN, "Cannot write to null outputStream") 150 } 151 n, err := p.Writer.Write(buf) 152 return n, NewTTransportExceptionFromError(err) 153 } 154 155 // Flushes the underlying output stream if not null. 156 func (p *StreamTransport) Flush() error { 157 if p.Writer == nil { 158 return NewTTransportException(NOT_OPEN, "Cannot flush null outputStream") 159 } 160 f, ok := p.Writer.(Flusher) 161 if ok { 162 err := f.Flush() 163 if err != nil { 164 return NewTTransportExceptionFromError(err) 165 } 166 } 167 return nil 168 }