core/Xtreams__PositionWriteStream.st
author mkobetic
Tue, 31 Jan 2012 03:47:19 +0000
changeset 90 59f68d289949
parent 74 752e2d88fe73
child 94 7e6a328c5f8b
permissions -rw-r--r--
(none)

"{ Package: 'stx:goodies/xtreams/core' }"

"{ NameSpace: Xtreams }"

WriteStream subclass:#PositionWriteStream
	instanceVariableNames:'buffer'
	classVariableNames:''
	poolDictionaries:'XtreamsPool'
	category:'Xtreams-Core'
!

PositionWriteStream comment:'Wraps a non-positionable stream and provides positioning capability by buffering written elements. Buffering strategy can be configured via different Buffer classes.

Instance Variables
	buffer  <Buffer> holds written elements

'
!


!PositionWriteStream methodsFor:'accessing'!

insert: anInteger from: aSequenceableCollection at: startIndex
	^buffer insert: anInteger from: aSequenceableCollection at: startIndex
!

write: anInteger from: aSequenceableCollection at: startIndex

	| toFlush bufferFlush |
	(buffer hasFixedWriteSpace not or: [buffer writeSize >= anInteger ]) ifTrue: [
		buffer write: anInteger from: aSequenceableCollection at: startIndex.
		^anInteger ].
	toFlush := buffer readSize + anInteger - buffer cacheSize.
	bufferFlush := toFlush min: buffer readSize.
	destination write: bufferFlush from: buffer.
	(toFlush > bufferFlush) ifTrue: [
		toFlush := toFlush - bufferFlush.
		destination write: toFlush from: aSequenceableCollection at: startIndex ].
	buffer write: anInteger - toFlush from: aSequenceableCollection at: startIndex + toFlush.
	^anInteger
! !

!PositionWriteStream methodsFor:'initialize-release'!

buffer

	^buffer
!

buffer: aBuffer

	buffer recycle.
	buffer := aBuffer
!

close
	super close.
	buffer recycle.
	buffer := nil
!

contentsSpecies
	^destination contentsSpecies
!

flush
	buffer ifNil: [^self].
	destination write: buffer.
	buffer clear
!

on: aDestination
	buffer := Buffer new: DefaultBufferSize class: aDestination contentsSpecies.
	super on: aDestination
! !

!PositionWriteStream methodsFor:'printing'!

streamingPrintOn: aStream
	super streamingPrintOn: aStream.
	aStream
		write: ' buffered: ';
		print: buffer writeSize.
	buffer writeSize isZero ifTrue: [^self].
	aStream
		cr; tab;
		print: buffer contentsPast
! !

!PositionWriteStream methodsFor:'seeking'!

++ anInteger
	| skipped |
	anInteger < 0 ifTrue: [ ^self -- anInteger negated ].
	skipped := buffer writeSkip: anInteger.
	skipped = anInteger ifTrue: [^anInteger].
	[destination ++ (anInteger - skipped)] on: Incomplete do: [:incomplete |
		(Incomplete count: incomplete count + skipped) raise].
	^anInteger
!

-- anInteger
	| skipped |
	anInteger < 0 ifTrue: [ ^self ++ anInteger negated ].
	skipped := (buffer writeSkip: anInteger negated) negated.
	skipped = anInteger ifTrue: [^anInteger].
	(Incomplete count: skipped) raise
!

available
	^buffer writeSize
!

length
	^buffer activeSize
!

position
	^buffer writePosition
!

position: aPosition
	| startPosition delta |
	aPosition < 0 ifTrue: [Incomplete zero raise].
	startPosition := buffer writePosition.
	delta := aPosition - startPosition.
	^[      self ++ delta. aPosition
	] on: Incomplete do: [ :ex |
		(Incomplete count: startPosition + ex count) raise ]
! !

!PositionWriteStream methodsFor:'testing'!

isPositionable
	^true
! !

!PositionWriteStream methodsFor:'transforming'!

positioning
	^self
! !

!PositionWriteStream class methodsFor:'documentation'!

version_SVN
    ^ '$Id$'
! !