transforms/Xtreams__ObjectReadStream.st
author Martin Kobetic
Sun, 17 Nov 2013 00:23:18 -0500
changeset 147 bd6be28aa924
parent 111 44ac233b2f83
permissions -rw-r--r--
merging

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

"{ NameSpace: Xtreams }"

ReadStream subclass:#ObjectReadStream
	instanceVariableNames:'marshaler objects nothing uint_16 uint_32 uint_64 int_64 int_8
		int_32 int_16 float_ double_'
	classVariableNames:''
	poolDictionaries:''
	category:'Xtreams-Transforms'
!

ObjectReadStream comment:'Unmarshals objects from binary source, previously marshaled using the same ObjectMarshaler. The bytes must start with marshaler version ID.

Instance Variables
	marshaler	<ObjectMarshaler> performs marshaling of object bodies
	objects	<Array> retains unmarshaled objects for resolution of backward references (to preserve identity)
	longs	<InterpretedReadStream> (internal) for reading of longs
	longlongs	<InterpretedReadStream> (internal) for reading of longlongs
	floats	<InterpretedReadStream> (internal) for reading of floats
	doubles	<InterpretedReadStream> (internal) for reading of doubles
	nothing	<Object> (internal) an object used to occupy empty slots in objects (since nil is potentially valid content)

'
!


!ObjectReadStream class methodsFor:'instance creation'!

on: aDestination
	^self on: aDestination marshaler: ObjectMarshaler new
!

on: aDestination marshaler: aMarshaler
	^self new on: aDestination marshaler: aMarshaler
! !

!ObjectReadStream methodsFor:'accessing'!

get
	| object |
	object := marshaler unmarshal: self.
	self complete.
	^object
!

read: anInteger into: aSequenceableCollection at: startIndex
	| count |
	count := 0.
	[anInteger timesRepeat:
		[aSequenceableCollection at: startIndex + count put: (marshaler unmarshal: self).
		self complete.
		count := count + 1]]
			on: Incomplete do: [:exception |
				self complete.
				(Incomplete on: aSequenceableCollection count: count at: startIndex) raise].
	^anInteger
! !

!ObjectReadStream methodsFor:'initialize-release'!

contentsSpecies
	^Array
!

on: aSource marshaler: aMarshaler
	super on: aSource.
	marshaler := aMarshaler.
	objects := Array with: false with: Transcript.
	nothing := Object new.

	int_8 := aSource interpreting: #signedChar.
	(marshaler configureUnmarshal: aSource)
		ifTrue: [
			int_16 := aSource interpreting: #signedShort_be.
			int_32 := aSource interpreting: #signedLong_be.
			int_64 := aSource interpreting: #signedLonglong_be.
			uint_16 := aSource interpreting: #unsignedShort_be.
			uint_32 := aSource interpreting: #unsignedLong_be.
			uint_64 := aSource interpreting: #unsignedLonglong_be]
		ifFalse: [
			int_16 := aSource interpreting: #signedShort_le.
			int_32 := aSource interpreting: #signedLong_le.
			int_64 := aSource interpreting: #signedLonglong_le.
			uint_16 := aSource interpreting: #unsignedShort_le.
			uint_32 := aSource interpreting: #unsignedLong_le.
			uint_64 := aSource interpreting: #unsignedLonglong_le].
	float_ := aSource interpreting: #float.
	double_ := aSource interpreting: #double
! !

!ObjectReadStream methodsFor:'primitives'!

double
	^double_
!

float
	^float_
!

int16
	^int_16
!

int32
	^int_32
!

int64
	^int_64
!

int8
	^int_8
!

uint16
	^uint_16
!

uint32
	^uint_32
!

uint64
	^uint_64
!

uint8
	^source
! !

!ObjectReadStream methodsFor:'private'!

complete
	1 to: objects size by: 2 do: [:index |
		objects at: index put: false.
		objects at: index + 1 put: nothing].
	objects at: 2 put: Transcript
!

grow: index
	| replacement |
	(replacement := Array new: index)
		replaceFrom: 1 to: objects size with: objects startingAt: 1.
	objects size + 1 to: index by: 2 do: [:i |
		replacement
			at: i put: false;
			at: i + 1 put: nothing].
	objects := replacement
!

nothing
	^nothing
!

objects
	^objects
! !

!ObjectReadStream class methodsFor:'documentation'!

version_HG

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

version_SVN
    ^ '$Id$'
! !