transforms/Xtreams__InterpretedWriteStream.st
author Jan Vrany <jan.vrany@fit.cvut.cz>
Wed, 01 Feb 2012 00:34:28 +0000
changeset 97 2a7827f4dce2
parent 72 d16c7d84d4a8
child 111 44ac233b2f83
permissions -rw-r--r--
pool name fixes

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

"{ NameSpace: Xtreams }"

WriteStream subclass:#InterpretedWriteStream
	instanceVariableNames:'elementSize cache cacheSize operation contentsSpecies'
	classVariableNames:''
	poolDictionaries:'Xtreams::XtreamsPool'
	category:'Xtreams-Transforms'
!

InterpretedWriteStream comment:'Converts consumed elements into bytes of pre-configured (primitive) CType, e.g. float, long etc. The type of the written elements must match the CType, the underlying destination must be binary.

Instance Variables
	elementSize	<Integer> byte size of elements of the pre-configured CType
	cache	<InterpretedBytes> caches the bytes so that they can be bulk written
	cacheSize	<SmallInteger> how many elements (not bytes) do we want to cache
	operation	<BlockClosure> CType translation primitive used to write into the buffer
	contentsSpecies	<Class> collection type to use to hold collections of elements

'
!


!InterpretedWriteStream class methodsFor:'instance creation'!

on: aWriteStream bytesPerElement: anInteger contentsSpecies: aClass operation: aBlock cacheSize: aSize
	^self new on: aWriteStream bytesPerElement: anInteger contentsSpecies: aClass operation: aBlock cacheSize: aSize
!

on: aWriteStream type: aType cacheSize: aSize
	| interpretation |
	interpretation := InterpretedBytes perform: aType.
	^self on: aWriteStream bytesPerElement: (interpretation at: 1) contentsSpecies: (interpretation at: 2) operation: (interpretation at: 4) cacheSize: aSize
! !

!InterpretedWriteStream methodsFor:'accessing'!

insert: anInteger from: aSequenceableCollection at: startIndex

	| count amount |
	count := 0.
	[count = anInteger] whileFalse: 
		[amount := cacheSize min: anInteger - count.
		0 to: amount - 1 do:  [:index | operation value: cache value: index * elementSize + 1 value: (aSequenceableCollection at: index + startIndex)].
		destination insert: amount * elementSize from: cache at: 1.
		count := count + amount].
	^anInteger
!

put: anObject

	operation value: cache value: 1 value: anObject.
	destination write: elementSize from: cache at: 1.
	^anObject
!

write: anInteger from: aSequenceableCollection at: startIndex

	| count amount |
	count := 0.
	[count = anInteger] whileFalse: 
		[amount := cacheSize min: anInteger - count.
		0 to: amount - 1 do:  [:index | operation value: cache value: index * elementSize + 1 value: (aSequenceableCollection at: count + index + startIndex)].
		destination write: amount * elementSize from: cache at: 1.
		count := count + amount].
	^anInteger
! !

!InterpretedWriteStream methodsFor:'initialize-release'!

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

contentsSpecies
	^contentsSpecies
!

on: aWriteStream bytesPerElement: anInteger contentsSpecies: aClass operation: aBlock cacheSize: aSize
	super on: aWriteStream.
	cacheSize := aSize.
	elementSize := anInteger.
	contentsSpecies := aClass.
	operation := aBlock.
	cache := InterpretedBytes newRecycled: ((elementSize * cacheSize) max: DefaultBufferSize)
! !

!InterpretedWriteStream methodsFor:'seeking'!

++ anInteger

	anInteger < 0 ifTrue: [ ^self -- anInteger negated ].
	[destination ++ anInteger * elementSize]
		on: Incomplete do: [:exception | (Incomplete count: exception count / elementSize) raise].
	^anInteger
!

-- anInteger
	anInteger < 0 ifTrue: [ ^self ++ anInteger negated ].
	[destination -- anInteger * elementSize]
		on: Incomplete do: [:exception | (Incomplete count: exception count / elementSize) raise].
	^anInteger
!

length
	^destination length / elementSize
!

position
	^destination position / elementSize
!

position: aPosition

	^([ destination position: aPosition * elementSize ] on: Incomplete do: [ :ex | ex count ]) // elementSize
! !

!InterpretedWriteStream methodsFor:'testing'!

isPositionable

	^destination isPositionable
! !

!InterpretedWriteStream class methodsFor:'documentation'!

version_SVN
    ^ '$Id$'
! !