# $SnapHashLicense:
#
# SnapLogic - Open source data services
#
# Copyright (C) 2008, SnapLogic, Inc. All rights reserved.
#
# See http://www.snaplogic.org for more information about
# the SnapLogic project.
#
# This program is free software, distributed under the terms of
# the GNU General Public License Version 2. See the LEGAL file
# at the top of the source tree.
#
# "SnapLogic" is a trademark of SnapLogic, Inc.
#
#
# $
# $Id: selectable_binary_pipe.py 4402 2008-09-22 17:04:01Z kurt $
"""
Contains the SelectableBinaryPipe object.
Provides support for a SelectablePipe that handles binary data.
"""
from snaplogic.common.snapstream.selectable_pipe import *
from snaplogic.common.snapstream.string_buffer import StringBuffer
from snaplogic.common.snapstream import memory
class SelectableBinaryPipe(SelectablePipe):
"""
A SelectablePipe for binary streams.
A binary stream of data is buffered as a string. This string is then made available via the SelectablePipe
interface. To provide flexibility for working efficiently with binary pipes, SelectablePipe operations
utilize a block size to determine availability. The block size defines the minimum amount of data that
must be buffered to consider the pipe available for a read. The block size is determined by the block_size
attribute on objects of this class. The default value is L{DEFAULT_BLOCK_SIZE}.
In addition to the block-level functionality, the buffer property provides read access to the internal buffer
of data. Also, the read() method allows data of arbitrary sizes to be read from the beginning of the buffer.
"""
def __init__(self):
super(SelectableBinaryPipe, self).__init__()
self._buffer = StringBuffer()
self.block_size = memory.DEFAULT_BLOCK_SIZE
def _available_write(self):
return self._buffer.length() < max(memory.MAX_BUFFER_SIZE, self.block_size)
def _available_read(self):
if self._buffer.length() < self.block_size:
# If the stream is still open, more datga may come later and we should not become available
# yet.
return not self._open and (self._buffer.length() > 0)
else:
return True
def _put(self, data):
self._buffer.write(data)
def _get(self):
return self._buffer.read(self.block_size)
def read(self, size):
"""
Blocking read of arbitrary sized blocks of data.
Reads a data block of up to size bytes out of the pipe. If not enough data is available, the call
will block until enough data is available. If EOF occurs before enough data is available, it will
result in a short read of the remaining bytes. Futher attempts to read will follow the same semantics
as get().
This call is equivalent to changing the block_size to size and issuing a blocking get. The call is provided
for the convenience of RP.
@param size: Number of bytes to read.
@type size: int
@return: A buffer of bytes read. If EOF, None is returned.
@rtype: string
"""
self.block_size = size
return self.get()
|