AbstractObjectCoder.st
author Claus Gittinger <cg@exept.de>
Tue, 03 Jun 2003 12:36:51 +0200
changeset 7327 ab17eb5f11a6
parent 7265 3b007758ff5b
child 7591 19fa013c1c58
permissions -rw-r--r--
printFormat

"{ Package: 'stx:libbasic' }"

Object subclass:#AbstractObjectCoder
	instanceVariableNames:'aspect'
	classVariableNames:''
	poolDictionaries:''
	category:'System-Storage'
!

!AbstractObjectCoder class methodsFor:'documentation'!

documentation
"
    This class is defines #encodeXXX:with: messages for various kinds of objects.
    Any of these messsages is mapped to #encodeObject:with:.

    When a class redefines #encodeOn:with:, an method has to be defined here, too.

    Subclasses have to define at least #encodeObject:with:

    [author:]
        Stefan Vogel (stefan@zwerg)

    [see also:]
        Object>>encodeOn:with:
"
! !

!AbstractObjectCoder methodsFor:'accessing'!

aspect
    "return the value of the instance variable 'aspect' (automatically generated)"

    ^ aspect
!

aspect:something
    "set the value of the instance variable 'aspect' (automatically generated)"

    aspect := something.
! !

!AbstractObjectCoder methodsFor:'encoding-smalltalk types'!

encodeAbsoluteTime:anAbsoluteTime with:aParameter
    "encode an absolute time value"

    self encodeObject:anAbsoluteTime with:aParameter


!

encodeBehavior:aSymbol with:aParameter
    "encode a class"

    self encodeObject:aSymbol with:aParameter
!

encodeBitArray:aBitArray with:aParameter
    "encode a BitArray"

    self encodeSequenceableCollection:aBitArray with:aParameter
!

encodeBlock:aBlock with:aParameter
    "encoding of blocks is rather difficult and an error by default.
     If your encoder supports this, redefine it there"

    self error:'encoding of blocks is not supported'
!

encodeBoolean:aBoolean with:aParameter
    "encode a Boolean"

    self encodeObject:aBoolean with:aParameter


!

encodeByteArray:aByteArray with:aParameter
    "encode an absolute time value"

    self encodeSequenceableCollection:aByteArray with:aParameter
!

encodeCharacter:aCharacter with:aParameter
    "encode a Character"

    self encodeObject:aCharacter with:aParameter


!

encodeCollection:aCollection with:aParameter
    "encode a Collection"

    self encodeObject:aCollection with:aParameter
!

encodeDictionary:aDictionary with:aParameter
    "encode a Dictionary"

    self encodeCollection:aDictionary with:aParameter
!

encodeFloat:aFloat with:aParameter
    "encode a Float"

    self encodeNumber:aFloat with:aParameter
!

encodeFraction:aFraction with:aParameter
    "encode a Fraction"

    self encodeNumber:aFraction with:aParameter
!

encodeInteger:anInteger with:aParameter
    "encode an Integer"

    self encodeNumber:anInteger with:aParameter
!

encodeInterval:anInterval with:aParameter
    "intervals are a special flavor of sequenceable collection (saving memory)
     We treat it as SequenceableCollection by default.
     Encoders that do a dense representation, redefine this to #encodeObject"

    ^ self encodeSequenceableCollection:anInterval with:aParameter
!

encodeNilWith:aParameter
    "encode a nil"

    self encodeObject:nil with:aParameter


!

encodeNumber:aNumber with:aParameter
    "encode an Integer"

    self encodeObject:aNumber with:aParameter
!

encodeSequencableCollection:aCollection with:aParameter
    "encode a SequenceableCollection.
     This is the wrong spelling but kept foe backward compatibility"

    self encodeCollection:aCollection with:aParameter
!

encodeSequenceableCollection:aCollection with:aParameter
    "encode a SequenceableCollection"

    "send the historic (wrong) selector, for backward compatibility with old subclasses"
    self encodeSequencableCollection:aCollection with:aParameter
!

encodeSet:aCollection with:aParameter
    "encode a Set"

    self encodeCollection:aCollection with:aParameter
!

encodeString:aString with:aParameter
    "encode a String"

    self encodeObject:aString with:aParameter


!

encodeSymbol:aSymbol with:aParameter
    "encode a Symbol"

    self encodeObject:aSymbol with:aParameter


! !

!AbstractObjectCoder methodsFor:'helpers'!

encodeAllInstanceVariablesOf:anObject
    "recursively enumerate anObjects refs, encoding each of the child objects.
     nil childs are not encoded"

    |instVarNames theClass 
     sz "{ Class: SmallInteger }"|

    theClass := anObject class.
    sz := theClass instSize.
    sz ~~ 0 ifTrue:[
        instVarNames := theClass allInstVarNames.
        1 to:sz do:[:i |  |ref|
            ref := anObject instVarAt:i.
            ref notNil ifTrue:[
                ref encodeOn:self with:(instVarNames at:i).
                self nextObject.
            ].
        ].
    ].

    theClass isVariable ifTrue:[
        sz := anObject basicSize.
        sz ~~ 0 ifTrue:[
            1 to:sz do:[:i |
                (anObject basicAt:i) encodeOn:self with:i.   
                self nextObject.
            ]
        ].
    ].
!

encodeChildrenOf:anObject
    "encode all child objects of anObject.
     If aspect is defined, perform aspect to fetch the child objects.
     Otherwise encode all the instance variables"

    |childObjectDescriptors|

    aspect isNil ifTrue:[
        "shortcut -- basic mechanism: encode instance variables by name"
        self encodeAllInstanceVariablesOf:anObject.
        ^ self.
    ].

    childObjectDescriptors := anObject encodingVectorFor:aspect.
    childObjectDescriptors do:[:association|
        association notNil ifTrue:[
            association value encodeOn:self with:association key.
            self nextObject.
        ].
    ].

    "
        XMLStandardCoder new aspect:#encodingVectorForInstanceVariables;
                 encodingOf:('blaKey' -> 'blaValue')

        XMLStandardCoder new aspect:#encodingVectorForInstanceVariables;
                 encodingOf:('blaKey' -> nil)

        XMLStandardCoder new aspect:#encodingVectorForNonNilInstanceVariables;
                 encodingOf:('blaKey' -> nil)

        XMLStandardCoder new aspect:#blaFaselQuall;
                 encodingOf:('blaKey' -> nil)
    "
! !

!AbstractObjectCoder methodsFor:'subclass responsibility'!

encodeObject:anObject with:aParameter
    "encode an object. Subclasses must implement this method"

    self subclassResponsibility


!

nextObject
    "this is sent, when a new Object is going to be encoded.
     Subclasses may redefine this e.g.to output a CR"

    ^ self 
! !

!AbstractObjectCoder class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libbasic/Attic/AbstractObjectCoder.st,v 1.8 2003-05-07 15:14:30 cg Exp $'
! !