AbstractObjectCoder.st
author Claus Gittinger <cg@exept.de>
Tue, 03 Feb 2004 16:45:01 +0100
changeset 7866 6624a55c7dd0
parent 7591 19fa013c1c58
child 8255 8630d88f446d
permissions -rw-r--r--
resourceDirectory

"
 COPYRIGHT (c) 2002 by eXept Software AG
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"

"{ Package: 'stx:libbasic' }"

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

!AbstractObjectCoder class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 2002 by eXept Software AG
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
!

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.9 2003-08-29 19:30:02 cg Exp $'
! !