transforms/Xtreams__InterpretedWriteStream.st
author joe
Tue, 19 Mar 2013 23:58:40 -0400
changeset 116 fa5b4c9f582d
parent 111 44ac233b2f83
permissions -rw-r--r--
- Xtreams::EncodeReadStream class: Xtreams::EncodeReadStream changed: #get #read:into:at: - Xtreams::ASCIIEncoder class: Xtreams::ASCIIEncoder - Xtreams::TransformReadStream class: Xtreams::TransformReadStream - Xtreams::ObjectReadStream class: Xtreams::ObjectReadStream - Xtreams::InterpretedReadStream class: Xtreams::InterpretedReadStream - stx_goodies_xtreams_transforms class: stx_goodies_xtreams_transforms - Xtreams::DuplicateWriteStream class: Xtreams::DuplicateWriteStream - Xtreams::EncodeWriteStream class: Xtreams::EncodeWriteStream changed: #setLineEndCRLF #setLineEndLF - Xtreams::ObjectAnalyseStream class: Xtreams::ObjectAnalyseStream - Xtreams::ObjectWriteStream class: Xtreams::ObjectWriteStream - Xtreams::TransformWriteStream class: Xtreams::TransformWriteStream - Xtreams::CollectReadStream class: Xtreams::CollectReadStream - Xtreams::InterpretedWriteStream class: Xtreams::InterpretedWriteStream - Xtreams::DuplicateReadStream class: Xtreams::DuplicateReadStream - Xtreams::ObjectMarshaler class: Xtreams::ObjectMarshaler - Xtreams::ISO8859L1Encoder class: Xtreams::ISO8859L1Encoder - Xtreams::CollectWriteStream class: Xtreams::CollectWriteStream - Xtreams::MessagePackMarshaler class: Xtreams::MessagePackMarshaler - extensions ...

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

"{ NameSpace: Xtreams }"

WriteStream subclass:#InterpretedWriteStream
	instanceVariableNames:'elementSize cache cacheSize operation contentsSpecies'
	classVariableNames:''
	poolDictionaries:'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_HG

    ^ '$Changeset: <not expanded> $'
!

version_SVN
    ^ '$Id$'
! !