home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CDPD Public Domain Collection for CDTV 3
/
CDPDIII.bin
/
pd
/
programming
/
gnusmalltalk
/
positionablestream.st
< prev
next >
Wrap
Text File
|
1992-02-15
|
5KB
|
204 lines
"======================================================================
|
| PositionableStream Method Definitions
|
======================================================================"
"======================================================================
|
| Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
| Written by Steve Byrne.
|
| This file is part of GNU Smalltalk.
|
| GNU Smalltalk is free software; you can redistribute it and/or modify it
| under the terms of the GNU General Public License as published by the Free
| Software Foundation; either version 1, or (at your option) any later version.
|
| GNU Smalltalk 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 General Public License for more
| details.
|
| You should have received a copy of the GNU General Public License along with
| GNU Smalltalk; see the file COPYING. If not, write to the Free Software
| Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
======================================================================"
"
| Change Log
| ============================================================================
| Author Date Change
| sbb 16 Mar 91 Class creation now separate statement.
|
| sbyrne 19 Sep 89 Converted to use real method categories
|
| sbyrne 25 Apr 89 created.
|
"
Stream subclass: #PositionableStream
instanceVariableNames: 'collection ptr endPtr access'
classVariableNames: ''
poolDictionaries: ''
category: nil
!
PositionableStream comment:
'My instances represent streams where explicit positioning is permitted.
Thus, my streams act in a manner to normal disk files: you can read
or write sequentially, but also position the file to a particular place
whenever you choose. Generally, you''ll want to use ReadStream, WriteStream
or ReadWriteStream instead of me to create and use streams.' !
!PositionableStream class methodsFor: 'instance creation'!
on: aCollection
self subclassResponsiblity
!
on: aCollection from: firstIndex to: lastIndex
^self on: (aCollection copyFrom: firstIndex to: lastIndex)
!!
!PositionableStream methodsFor: 'accessing-reading'!
next
| element |
(access bitAnd: 1) = 0
ifTrue: [ ^self shouldNotImplement ].
self atEnd ifTrue: [ ^self error: 'end of stream reached' ].
element _ collection at: ptr.
ptr _ ptr + 1.
^element
!
next: anInteger
"Returns a collection of the same type that the stream accesses, that has
the next anInteger elements from the stream."
| newStream |
newStream _ WriteStream on: (collection species new: 0).
anInteger timesRepeat: [ newStream nextPut: (self next) ].
^newStream contents
!
peek
"Returns the next element of the stream without moving the pointer.
Returns nil when at end of stream."
| peekValue |
self atEnd ifTrue: [ ^nil ].
peekValue _ self next.
self skip: -1.
^peekValue
!
peekFor: anObject
"Returns true and gobbles the next element from the stream of it is
equal to anObject, returns false and doesn't gobble the next element
if the next element is not equal to anObject."
(self peek) = anObject
ifTrue: [ self next.
^true ]
ifFalse: [ ^false ]
!
upTo: anObject
"Returns a collection of the same type that the stream accesses, up to
but not including the object anObject. Returns the entire rest of the
stream's contents if anObject is not present. ### Should this use = or
==."
| newStream |
newStream _ WriteStream on: (collection species new: 0).
[ self atEnd or: [ self peek ~= anObject ] ] whileFalse:
[ newStream nextPut: (self next) ].
^newStream contents
!
contents
"Returns a collection of the same type that the stream accesses, up to
and including the final element."
^collection copyFrom: 1 to: endPtr
!
reverseContents
"Returns a collection of the same type that the stream accesses, up to
and including the final element, but in reverse order."
| newCollection |
newCollection _ collection species new: endPtr.
1 to: endPtr do:
[ :i | newCollection at: i put: (collection at: endPtr - i + 1) ].
^newCollection
!!
!PositionableStream methodsFor: 'testing'!
atEnd
^ptr > endPtr
!
isEmpty
^endPtr = 0
!!
!PositionableStream methodsFor: 'enumerating'!
!
!PositionableStream methodsFor: 'positioning'!
position
^ptr
!
position: anInteger
(anInteger between: 1 and: endPtr)
ifTrue: [ ptr _ anInteger ]
ifFalse: [ ^self error: 'position out of range' ]
!
reset
ptr _ 1
!
setToEnd
ptr _ endPtr + 1
!
skip: anInteger
ptr _ (ptr + anInteger max: 1) min: endPtr
!
skipTo: anObject
"Moves the current position to after the next occurrence of anObject
and returns true if anObject was found. If anObject doesn't exist, the
position is unchanged, and false is returned."
| curPos |
curPos _ self position.
[ self atEnd ] whileFalse:
[ (self nextMatchFor: anObject)
ifTrue: [ ^true ] ].
self position: curPos.
^false
!!
!PositionableStream methodsFor: 'private'!
access: anInteger
access _ anInteger
!!