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  }