"{ 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$'
! !