"======================================================================
|
|   ReadBuffer and WriteBuffer classes
|
|   $Revision: 1.7.5$
|   $Date: 2000/05/28 16:56:52$
|   $Author: pb$
|
 ======================================================================"


"======================================================================
|
| Copyright 1988-92, 1994-95, 1999, 2000 Free Software Foundation, Inc.
| Written by Paolo Bonzini.
|
| This file is part of the GNU Smalltalk class library.
|
| The GNU Smalltalk class library is free software; you can redistribute it
| and/or modify it under the terms of the GNU Lesser General Public License
| as published by the Free Software Foundation; either version 2.1, or (at
| your option) any later version.
| 
| The GNU Smalltalk class library is distributed in the hope that it will be
| useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
| General Public License for more details.
| 
| You should have received a copy of the GNU Lesser General Public License
| along with the GNU Smalltalk class library; see the file COPYING.LESSER.
| If not, write to the Free Software Foundation, 59 Temple Place - Suite
| 330, Boston, MA 02111-1307, USA.  
|
 ======================================================================"


WriteStream subclass: #WriteBuffer
	   instanceVariableNames: 'flushBlock'
	   classVariableNames: ''
	   poolDictionaries: ''
	   category: 'Examples-Useful tools'
!

WriteBuffer comment: '
I''m a WriteStream that, instead of growing the collection,
evaluates an user defined block and starts over with the same
collection.'!

!WriteBuffer methodsFor: 'buffer handling'!

flush
    flushBlock notNil ifTrue: [
	flushBlock value: collection value: ptr - 1.
    ].
    ptr := 1.
!

flushBlock: block
    flushBlock := block
! !

!WriteBuffer methodsFor: 'private'!

growCollection
    self flush
! !

ReadStream subclass: #ReadBuffer
	   instanceVariableNames: 'fillBlock'
	   classVariableNames: ''
	   poolDictionaries: ''
	   category: 'Examples-Useful tools'
!

ReadBuffer comment: '
I''m a ReadStream that, when the end of the stream is reached,
evaluates an user defined block to try to get some more data.'!

!ReadBuffer class methodsFor: 'instance creation'!

on: aCollection
    ^(super on: aCollection)
	setToEnd;		"Force a buffer load soon"
	yourself
! !

!ReadBuffer methodsFor: 'buffer handling'!

atEnd
    self basicAtEnd ifFalse: [ ^false ].
    fillBlock isNil ifTrue: [ ^true ].

    ptr := 1.
    endPtr := fillBlock value: collection value: collection size.
    ^self basicAtEnd
!

bufferContents
  | contents |
  self basicAtEnd ifTrue: [ ^self species new: 0 ].
  contents := self copyFrom: ptr to: endPtr.
  endPtr := ptr - 1. "Empty the buffer"
  ^contents
!

fill
    ^self atEnd
!

fillBlock: block
    "Set the block that fills the buffer. It receives a collection
    and the number of bytes to fill in it, and must return the number
    of bytes actually read"
    fillBlock := block
!

isEmpty
    "Answer whether the next input operation will force a buffer fill"
    ^self basicAtEnd
!

isFull
    ^self notEmpty and: [ self position = 1 ]
!

notEmpty
    "Answer whether the next input operation will force a buffer fill"
    ^self basicAtEnd not
! !
