From VisualWorks®, 7.5 of April 3, 2007 on April 3, 2007 at 1:28:33 pm (Dialog confirm: 'You are filing-in a Parcel source file!\\While this is possible it will not have\the same effect as loading the parcel.\None of the Parcel''s prerequisites will\be loaded and none of its load actions\will be performed.\\Are you sure you want to file-in?' withCRs) ifFalse: [self error: 'Parcel file-in abandoned. Choose terminate or close.'] <name>ASN1</name> <environment>Smalltalk</environment> <private>false</private> <imports> private Smalltalk.* </imports> <category>ASN1</category> <attributes> <package>ASN1-Support</package> </attributes> <comment> ASN1
ASN1 is the namespace for constants and classes involved in the implementation of ASN.1 elements, types, parsers, encoders, and decoders.
</comment> <class> <name>Imported</name> <environment>ASN1</environment> <super>Core.Object</super> <private>false</private> none value <imports></imports> <category>ASN1</category> <attributes> <package>ASN1-Support</package> </attributes> </class> <comment> ASN1.Imported
Imported is the abstract superclass of those types, native to ASN.1, that have been explicitly imported into VisualWorks because of their special semantics. Note that the Imported hierarchy is functionally distinct from the Asn1Type hierarchy. The latter is used to represent those characteristics of foreign types relevant to encoding and decoding. The classes in the Imported hierarchy, in contrast, may be the end result of decoding, usually have a determinate encoding, and otherwise function like application classes. Instance Variables: value <Object> the Smalltalk object wrapped in the special semantics of the imported type
</comment> <class> <name>BitString</name> <environment>ASN1</environment> <super>ASN1.Imported</super> <private>false</private> none unused <imports></imports> <category>ASN1</category> <attributes> <package>ASN1-Support</package> </attributes> </class> <comment> ASN1.BitString
Asn1BitString is an imported type that implements the ASN.1 semantics for a bit string with a specified number of unused bits. The inherited 'value' instVar is expected to contain a ByteArray. Instance Variables: unused <Integer> the number of bits considered to be 'unused' in the ByteArray value
</comment> <class> <name>Asn1Warning</name> <environment>ASN1</environment> <super>Core.Warning</super> <private>false</private> none <imports></imports> <category>ASN1</category> <attributes> <package>ASN1-Support</package> </attributes> </class> <comment> ASN1.Asn1Warning
Abstract superclass of all ASN.1 warnings.
</comment> <class> <name>Asn1Error</name> <environment>ASN1</environment> <super>Core.Error</super> <private>false</private> none <imports></imports> <category>ASN1</category> <attributes> <package>ASN1-Support</package> </attributes> </class> <comment> ASN1.Asn1Error
Asn1Exception is an abstract class. It is the superclass of all ASN.1-specific exceptions.
</comment> <class> <name>TypeRealizationError</name> <environment>ASN1</environment> <super>ASN1.Asn1Error</super> <private>false</private> none <imports></imports> <category>ASN1</category> <attributes> <package>ASN1-Support</package> </attributes> </class> <comment> ASN1.TypeRealizationError
An Asn1ExcTypeRealization is raised when a constraint or semantic violation is noted in the realization of an Asn1Type as an imported type.
</comment> <class> <name>SMIConflict</name> <environment>ASN1</environment> <super>ASN1.Asn1Error</super> <private>false</private> none <imports></imports> <category>ASN1</category> <attributes> <package>ASN1-Support</package> </attributes> </class> <comment> ASN1.SMIConflict
An Asn1ExcSMIConflict is raised when in inconsistency is noted during an attempt to update a tree of SMINodes.
</comment> <class> <name>SMIUnknownPath</name> <environment>ASN1</environment> <super>ASN1.Asn1Error</super> <private>false</private> none <imports></imports> <category>ASN1</category> <attributes> <package>ASN1-Support</package> </attributes> </class> <comment> ASN1.SMIUnknownPath
An Asn1ExcSMIPathUnknown is raised when a specified path cannot be found in a tree of SMINodes.
</comment> <class> <name>Encoding</name> <environment>ASN1</environment> <super>Core.Object</super> <private>false</private> none source headerStart bodyStart bodyStop <imports></imports> <category>ASN1</category> <attributes> <package>ASN1-Support</package> </attributes> </class> <comment> ASN1.Encoding
An Asn1Encoding is used to store the encoding of some decoded element. Within some 'source' ByteArray' it retains offsets to the beginning of the encoding header (contianing the tag(s) and the length), the beginning of the encoding body, and the end of the encoding body. Instance Variables: bodyStart <Integer> the beginning of the encoding's 'body' bodyStop <Integer> the end of the encoding's 'body' headerStart <Integer> the beginning of the encoding's 'header' source <ByteArray> description of source
</comment> <class> <name>SMINode</name> <environment>ASN1</environment> <super>Core.Object</super> <private>false</private> none children integer oid parent symbol type value root <imports></imports> <category>ASN1</category> <attributes> <package>ASN1-Support</package> </attributes> </class> <comment> ASN1.SMINode
An SMINode represents a node in a 'structure of manangement information' (SMI) as defined in RFC 1155 (Structure of Management Information) and expanded in RFC 1212 (Concise MIB Definitions). In the context of an ASN.1 implementation, this class is used to derive the symbolic names associated with ASN.1 OBJECT_IDENTIFIERS. It has a more extensive use in the implementation of the SNMP protocol, and some of the declared instVars look forward to its use in that context. Instance Variables: children <Dictionary> the children of the SMINode integer <Object> the integer associated with the SMINode oid <Asn1OID | UndefinedObject> the Asn1OID associated with the SMINode parent <SMINode | UndefinedObject> the parent of the SMINode symbol <Symbol> the name associated with the SMINode type <Asn1Type | UndefinedObject> the type of the SMINode's value value <Object | UndefinedObject> the value of the SMINode Class Instance Variables: root <SMINode> the default root node
</comment> <class> <name>OIDError</name> <environment>ASN1</environment> <super>ASN1.Asn1Error</super> <private>false</private> none <imports></imports> <category>ASN1-Support</category> <attributes> <package>ASN1-Support</package> </attributes> </class> <comment> ASN1.OIDError
Signals errors related to ObjectIdentifiers, i.e conversion errors, invalid OIDs, etc.
</comment> <class> <name>Module</name> <environment>ASN1</environment> <super>Core.Object</super> <private>false</private> none name oid definitions exports imports tagging extensibility <imports></imports> <category>ASN1</category> <attributes> <package>ASN1-Support</package> </attributes> </class> <comment> ASN1.Module
A module gathers related type definitions into a single identifiable entity. It also serves as a context within witch the name lookups are performed. A module can import entities from other modules and can itself export its own entities. Modules allow to reuse definitions among different applications. Instance Variables: name <Symbol> module name oid <Asn1OID> a module can be identified with a globally unique OID definitions <Dictionary key: Symbol value: Asn1Type> the contained definitions exports <Set of: Asn1Type> exported definitions imports <Dictionary key: Symbol value: Asn1Type> imported definitions tagging <Symbol> the tagging mode of the module (#explicit | #implicit | #automatic) ' extensibility <Boolean> is extensibility of constructed types implied ? 'EXTENSIBILITY IMPLIED'
</comment> <class> <name>Entity</name> <environment>ASN1</environment> <super>Core.Object</super> <private>false</private> none symbol module <imports></imports> <category>ASN1</category> <attributes> <package>ASN1-Support</package> </attributes> </class> <comment> ASN1.Entity
This is an abstract superclass of all ASN.1 entities like types, values, information classes, information objects, etc. All entities have a name and are defined in an ASN.1 module. Instance Variables: symbol <Symbol> the name of the type, presumed to be unique module <Asn1Module> the module that the type belongs to
</comment> <class> <name>ObjectIdentifier</name> <environment>ASN1</environment> <super>ASN1.Imported</super> <private>false</private> none encoding <imports></imports> <category>ASN1</category> <attributes> <package>ASN1-Support</package> </attributes> </class> <comment> ASN1.ObjectIdentifier
An Asn1OID is the Smalltalk representation of an ASN.1 OBJECT_IDENTIFIER. ASN.1 OBJECT_IDENTIFIERs are guaranteed to frequently recur in any sustained interoperation, and, in protocols like SNMP, constitute a significant fraction of the marshaling budget. So, an Asn1OID always retains its original encoding to minimize marshaling time, and its representation is as close as possible to its bare encoding in order to push that minimization. Instance Variables: encoding <ByteArray | Asn1Encoding> the encoding of the OID Shared Variables: BEREncodingCache <Dictionary> the cache of encodings used to optimize marshaling of OIDs
</comment> <class> <name>SMIInvalidPath</name> <environment>ASN1</environment> <super>ASN1.Asn1Error</super> <private>false</private> none <imports></imports> <category>ASN1</category> <attributes> <package>ASN1-Support</package> </attributes> </class> <comment> ASN1.SMIInvalidPath
An Asn1ExcSMIPathSpecification is raised when an error is detected in the specification of a path in a tree of SMINodes.
</comment> <class> <name>TypeRedefinition</name> <environment>ASN1</environment> <super>ASN1.Asn1Warning</super> <private>false</private> none <imports></imports> <category>ASN1</category> <attributes> <package>ASN1-Support</package> </attributes> </class> <comment> ASN1.TypeRedefinition
Raised when and existing type is being redefined
</comment> <class> <name>Struct</name> <environment>ASN1</environment> <super>Protocols.Struct</super> <private>false</private> objects encoding <imports></imports> <category>ASN1-Support</category> <attributes> <package>ASN1-Support</package> </attributes> </class> <comment> ASN1.Struct
Instances of this class are used as results of decoding of ASN.1 SEQUENCEs and SETs (unless they are mapped to specific Smalltalk classes). Note that two structs with equal set of elements are equal even if their particular element order doesn't match. This is to support the diverse set of ASN.1 encodings. Instance Variables: encoding <Encoding> an ASN.1 encoding of the Struct
</comment> <name>BitMasksTerminal</name> <environment>ASN1</environment> <private>false</private> <constant>false</constant> <category>bit masks</category> <attributes> <package>ASN1-Support</package> </attributes> <name>BEREncodingCache</name> <environment>ASN1.ObjectIdentifier</environment> <private>false</private> <constant>false</constant> <category>encoding caches</category> <attributes> <package>ASN1-Support</package> </attributes> <methods> ASN1.Imported <category>comparing</category>
= anObject ^( anObject class == self class ) and: [ anObject value = self value ]
hash ^value hash
</methods> <methods> ASN1.Imported <category>accessing</category>
value ^value
value: anObject value := anObject
</methods> <methods> ASN1.Imported class <category>instance creation</category>
value: anObject "((( Asn1ImportedTOC value: ( OrderedCollection with: 1 with: 2 ) )))" ^( self new ) value: anObject; yourself
</methods> <methods> ASN1.BitString <category>accessing</category>
bitAt: anInteger "Test the value of the bit at given index (1-based indexing). anInteger <Integer> index of the bit to query, one based ^<Boolean> true if set, false if cleared Note that within each byte the bits are ordered from the most significant bit to the least significant. So bit (0) of a bit string is actually the most significant bit of the first byte, bit (9) is the most significant bit of second byte, etc. ((self unused: 0 bytes: #[64 1]) bitAt: 8) = false ((self unused: 0 bytes: #[64 1]) bitAt: 2) = true ((self unused: 0 bytes: #[64 1]) bitAt: 16) = true ((self unused: 0 bytes: #[64 1]) bitAt: 9) = false " | slot mask | slot := (anInteger - 1 bitShift: -3) + 1. slot > value size ifTrue: [^false]. mask := 2**(7 - (anInteger - 1 bitAnd: 7)). ^((value at: slot) bitAnd: mask) ~~ 0.
bitAt: anInteger put: aBoolean "Set the value of the bit at index anInteger (1-based indexing). anInteger <Integer> index of the bit to set, one based aBoolean <Boolean> set to 1 if true, set to 0 if false ^<Boolean> Note that within each byte the bits are ordered from the most significant bit to the least significant. So bit (0) of a bit string is actually the most significant bit of the first byte, bit (9) is the most significant bit of second byte, etc. (((self unused: 0 bytes: #[64 1] copy) bitAt: 8 put: true; yourself) bitAt: 8) = true (((self unused: 0 bytes: #[64 1] copy) bitAt: 8 put: true; yourself) bitAt: 7) = false (((self unused: 0 bytes: #[64 1] copy) bitAt: 8 put: true; yourself) bitAt: 2) = true (((self unused: 0 bytes: #[65 1] copy) bitAt: 2 put: false; yourself) bitAt: 2) = false (((self unused: 0 bytes: #[65 1] copy) bitAt: 2 put: false; yourself) bitAt: 8) = true (((self unused: 0 bytes: #[65 1] copy) bitAt: 2 put: false; yourself) bitAt: 7) = false " | slot mask bits | slot := (anInteger - 1 bitShift: -3) + 1. mask := 2**(7- (anInteger - 1 bitAnd: 7)). bits := value at: slot. value at: slot put: ( aBoolean ifTrue: [bits bitOr: mask] ifFalse: [bits bitAnd: (255 bitXor: mask)] ). ^aBoolean
bytes ^value
bytes: aByteArray self value: aByteArray
unused ^unused
unused: anInteger unused := anInteger
</methods> <methods> ASN1.BitString <category>comparing</category>
= anObject ^( anObject class == self class ) and: [ anObject value = self value and: [ anObject unused == self unused ] ]
hash ^( value hash bitShift: 7 ) bitXor: unused hash
</methods> <methods> ASN1.BitString <category>testing</category>
isEmpty ^( unused == 0 ) and: [ value = #[] ]
</methods> <methods> ASN1.BitString <category>printing</category>
printOn: aStream aStream nextPutAll: self class name; nextPut: $(; nextPutAll: value size printString; nextPut: $/; nextPutAll: unused printString; nextPut: $/; nextPutAll: value first printString; nextPutAll: '...'; nextPutAll: value last printString; nextPut: $)
</methods> <methods> ASN1.BitString class <category>instance creation</category>
empty ^( self new ) unused: 0; value: #[]; yourself
unused: anInteger bytes: aByteArray | n | n := ( self new ) unused: anInteger; value: aByteArray; yourself. self validate: n. ^n
</methods> <methods> ASN1.BitString class <category>class initialization</category>
initialize self initializeASN1BitMasks.
initializeASN1BitMasks "((( self initializeASN1BitMasks )))" ASN1.BitMasksTerminal := #( 02r00000000 02r00000001 02r00000011 02r00000111 02r00001111 02r00011111 02r00111111 02r01111111 02r11111111 )
</methods> <methods> ASN1.BitString class <category>validation</category>
validate: anAsn1ImportedBitString "... ensures that 'unused' is in the valid range and that the unused bits are '0', in accord with the stronger, DER requirement. (BER allows '1's among the unused bits.)" | uu vu vl mc | uu := anAsn1ImportedBitString unused. ( ( uu >= 0 ) and: [ uu <= 7 ] ) ifFalse: [ ^TypeRealizationError raiseSignal: (#UnusedBitsError << #asn1 >> 'The number of unused bits must be between zero and seven!') ]. ( ( vu := anAsn1ImportedBitString value ) ~= #[] ) ifTrue: [ vl := vu last. mc := vl maskClear: ( ASN1.BitMasksTerminal at: ( uu + 1 ) ). ( vl = mc ) ifFalse: [ ^TypeRealizationError raiseSignal: (#UnusedBitsMustBeZero << #asn1 >> 'Unused bits must be zero!') ] ]
</methods> <methods> ASN1.Encoding <category>accessing</category>
bodyStart ^bodyStart
bodyStart: anInteger bodyStart := anInteger
bodyStop ^bodyStop
bodyStop: anInteger bodyStop := anInteger
headerStart ^headerStart
headerStart: anInteger headerStart := anInteger
source ^source
source: aByteArray source := aByteArray
</methods> <methods> ASN1.Encoding <category>printing</category>
printOn: aStream aStream nextPut: $<; print: headerStart; nextPut: $(; print: bodyStart; nextPut: $); print: bodyStop; nextPut: $>
</methods> <methods> ASN1.Encoding <category>api</category>
bodyEncoding ^source copyFrom: bodyStart to: bodyStop
fullEncoding ^source copyFrom: headerStart to: bodyStop
headerEncoding ^source copyFrom: headerStart to: bodyStart - 1
size ^bodyStop - headerStart + 1
writeOn: aMarshaler aMarshaler next: self size putAll: source startingAt: headerStart.
</methods> <methods> ASN1.Encoding class <category>instance creation</category>
source: aByteArray ^( self basicNew ) source: aByteArray; yourself
with: aByteArray ^(self source: aByteArray) headerStart: 1; bodyStop: aByteArray size; yourself
</methods> <methods> ASN1.SMINode <category>adding</category>
addNode: anSMINode "... answers anSMINode or an exception." | old | old := children at: anSMINode integer ifAbsent: []. ^( old == nil ) ifTrue: [ self privateAddNode: anSMINode ] ifFalse: [ self privateReviseNode: old with: anSMINode ]
addNode: anSMINode atPath: anArray "... the path should include the 'integer' of the node as its last element." ( anSMINode integer ~~ anArray last ) ifTrue: [ ^self smiPathAndNodeConflict ]. ^self privateReviseNode: ( self addPath: anArray ) with: anSMINode
addNodes: aCollection aCollection do: [ :x | self addNode: x ]
addPath: anArray "... expects an Array of Integers, and instantiates the path, treating the receiver as the root." "... answers the leaf." | leaf | self privateCheckPathSpecification: anArray. leaf := self. anArray do: [ :n | leaf := leaf at: n ifAbsent: [ ( SMINode integer: n ) parent: leaf ] ]. ^leaf
atPath: anArray setSymbol: aSymbol ^( self addPath: anArray ) symbol: aSymbol
setSymbol: aSymbol atPath: anArray ^( self addPath: anArray ) symbol: aSymbol
</methods> <methods> ASN1.SMINode <category>printing</category>
printOn: aStream aStream nextPutAll: self class name; nextPut: $(; nextPut: Character space. self printStandardFormatOn: aStream. aStream nextPut: Character space; nextPut: $).
printStandardFormatOn: aStream "... makes allowances for the evil of a missing 'integer'." aStream nextPutAll: ( ( symbol ~~ nil ) ifTrue: [ symbol asString ] ifFalse: [ self class unknownSymbolString ] ); nextPut: Character space; nextPut: $(; nextPutAll: ( ( integer ~~ nil ) ifTrue: [ integer printString ] ifFalse: [ self class unknownIntegerString ] ); nextPut: $)
</methods> <methods> ASN1.SMINode <category>class initialization</category>
decodeFromTriplets: anArray "... called by the alternative, class-side initialization protocol." | cc | self integer: (anArray at: 1); symbol: (anArray at: 2). cc := ( ( anArray at: 3 ) collect: [ :x | self class decodeFromTriplets: x ] ). ( cc isEmpty not ) ifTrue: [ self addNodes: cc ].
</methods> <methods> ASN1.SMINode <category>accessing - derived</category>
alphabeticSymbol ^( ( symbol ~~ nil ) ifTrue: [ symbol ] ifFalse: [ self class unknownSymbolString asSymbol ] )
fullAlphabeticSymbol | oc str | oc := OrderedCollection new: 11. self ascendWithBlock: [ :x | oc addFirst: x symbolPreferredAsString ]. str := WriteStream on: ( String new: 64 ). oc do: [ :x | str nextPutAll: x ] separatedBy: [ str nextPut: $. ]. ^str contents asSymbol
fullAlphabeticSymbolAtPath: anArray | oc str | oc := OrderedCollection new: anArray size. self descendPath: anArray withBlock: [ :x | oc add: x symbolPreferredAsString ]. str := WriteStream on: ( String new: 64 ). oc do: [ :x | str nextPutAll: x ] separatedBy: [ str nextPut: $. ]. ^str contents asSymbol
integerPreferred ^( integer ~~ nil ) ifTrue: [ integer ] ifFalse: [ symbol ]
nodeSymbol ^( ( symbol ~~ nil ) ifTrue: [ symbol ] ifFalse: [ self class unknownSymbolString asSymbol ] )
numericSymbol ^( ( symbol ~~ nil ) ifTrue: [ symbol ] ifFalse: [ self class unknownSymbolString asSymbol ] )
symbolPreferred ^( symbol ~~ nil ) ifTrue: [ symbol ] ifFalse: [ integer ]
symbolPreferredAsString ^( symbol ~~ nil ) ifTrue: [ symbol asString ] ifFalse: [ integer printString]
</methods> <methods> ASN1.SMINode <category>accessing</category>
children ^children
children: aDictionary children := aDictionary
integer ^integer
integer: anInteger self privateReviseParentKeyFrom: integer to: anInteger. integer := anInteger.
oid ^oid
oid: anAsn1OID oid := anAsn1OID
parent ^parent
parent: anSMINode ( parent ~~ nil ) ifTrue: [ parent privateRemoveNode: self ]. parent := anSMINode. ( anSMINode ~~ nil ) ifTrue: [ anSMINode privateAddNode: self ]
symbol ^symbol
symbol: aSymbol | s | s := ( aSymbol == nil ) ifTrue: [ nil ] ifFalse: [ aSymbol asSymbol ]. self privateReviseParentKeyFrom: symbol to: s. symbol := s
type ^type
type: anObject type := anObject
value ^value
value: anObject value := anObject
</methods> <methods> ASN1.SMINode <category>private</category>
privateAddNode: anSMINode ( anSMINode integer ~~ nil ) ifTrue: [ children at: anSMINode integer put: anSMINode ]. ( anSMINode symbol ~~ nil ) ifTrue: [ children at: anSMINode symbol put: anSMINode ]. ^anSMINode
privateCheckChildren: aDictionary1 againstChildren: aDictionary2 " ... checks size and key membership only." | k1 k2 | ( aDictionary1 size == aDictionary2 size ) ifFalse: [ ^self smiChildConflict ]. k1 := aDictionary1 keys. k2 := aDictionary2 keys. k1 do: [ :k | ( k2 includes: k ) ifFalse: [ ^self smiChildConflict ] ]. ^true
privateCheckPathSpecification: anArray anArray do: [ :x | ( x isKindOf: Integer ) ifFalse: [ ^self smiPathSpecification ] ]
privateRemoveNode: anSMINode | b1 b2 | b1 := b2 := false. children removeKey: anSMINode integer ifAbsent: [ b1 := true ]. children removeKey: anSMINode symbol ifAbsent: [ b2 := true ]. ^( b1 & b2 ) ifTrue: [ self smiPathUnknown ] ifFalse: [ anSMINode ]
privateReplaceNode: anSMINode1 with: anSMINode2 "... dangerous, as it does not preserve the existing node's children." self privateRemoveNode: anSMINode1. ^self privateAddNode: anSMINode2
privateReviseNode: anSMINode1 with: anSMINode2 "... preserves the existing node's children, and warns if there is a conflict." | children1 children2 | children1 := anSMINode1 children. children2 := anSMINode2 children. ( children2 isEmpty or: [ self privateCheckChildren: children1 againstChildren: children2 ] ) ifTrue: [ anSMINode2 children: children1 ]. self privateRemoveNode: anSMINode1. ^self privateAddNode: anSMINode2
privateReviseParentKeyFrom: anIntegerOrSymbol1 to: anIntegerOrSymbol2 "... should handle possible 'nil' values." ( parent ~~ nil ) ifTrue: [ ( anIntegerOrSymbol1 ~~ nil ) ifTrue: [ parent children removeKey: anIntegerOrSymbol1 ifAbsent: [] ]. ( anIntegerOrSymbol2 ~~ nil ) ifTrue: [ parent children at: anIntegerOrSymbol2 put: self ] ]
</methods> <methods> ASN1.SMINode <category>initialize-release</category>
initialize children := Dictionary new: 3
</methods> <methods> ASN1.SMINode <category>removing</category>
removeLeafNodeAtPath: anArray "... answers an exception or the removed node." "The Array may contain a mix of Integers and Symbols." | leaf | leaf := self. anArray do: [ :n | leaf := leaf at: n ifAbsent: [ ^self smiPathUnknown ] ]. leaf parent privateRemoveNode: leaf. ^leaf
removeNode: anSMINode ^self privateRemoveNode: anSMINode
</methods> <methods> ASN1.SMINode <category>accessing - traversal</category>
ascendWithBlock: aBlockClosure ( integer ~~ self class rootInteger ) ifTrue: [ aBlockClosure value: self. parent ascendWithBlock: aBlockClosure ]
at: anIntegerOrSymbol ^children at: anIntegerOrSymbol ifAbsent: []
at: anIntegerOrSymbol ifAbsent: aBlockClosure ^children at: anIntegerOrSymbol ifAbsent: aBlockClosure
atAsn1OID: anAsn1OID ^self root atPath: anAsn1OID value
atPath: anArray "... expects an Array of Integers." "... answers the leaf or nil, treating the receiver as the root of the path." | leaf | self privateCheckPathSpecification: anArray. leaf := self. anArray do: [ :n | leaf := leaf at: n ifAbsent: [ ^nil ] ]. ^leaf
descendPath: anArray withBlock: aBlockClosure | leaf | leaf := self. self privateCheckPathSpecification: anArray. anArray do: [ :n | leaf := leaf at: n ifAbsent: [ ^self smiPathUnknown ]. aBlockClosure value: leaf ].
</methods> <methods> ASN1.SMINode <category>accessing - root</category>
root "((( SMINode root )))" ^self class root
</methods> <methods> ASN1.SMINode <category>utility</category>
smiChildConflict ^SMIConflict raiseSignal: (#SMIChildConflict << #asn1 >> 'There is an existing node with different children.')
smiPathAndNodeConflict ^SMIConflict raiseSignal: (#SMIPathAndNodeConflict << #asn1 >> 'The node''s integer index does not match the last element in the path.')
smiPathSpecification ^SMIInvalidPath raiseSignal: (#SMIPathSpecificationError << #asn1 >> 'SMI path specifications must contain only Integers.')
smiPathUnknown ^SMIUnknownPath raiseSignal: (#SMIPathUnknown << #asn1 >> 'The indicated SMI node was not found.')
</methods> <methods> ASN1.SMINode class <category>instance creation</category>
integer: anInteger ^self integer: anInteger parent: nil symbol: nil
integer: anInteger parent: anSMINode ^self integer: anInteger parent: anSMINode symbol: nil
integer: anInteger parent: anSMINode symbol: aSymbol ^( super new initialize ) integer: anInteger; parent: anSMINode; symbol: aSymbol; yourself
integer: anInteger symbol: aSymbol ^self integer: anInteger parent: nil symbol: aSymbol
new "... a gesture to discourage the creation of SMINodes without a value for 'integer'." ^self shouldNotImplement
</methods> <methods> ASN1.SMINode class <category>class initialization</category>
decodeFromTriplets: anArray "... unused." "... a alternative initalization method." ^( self basicNew initialize ) decodeFromTriplets: anArray
defaultRootData "... unused." "... included to exemplify the alternative initialization strategy." "... invoked thus: self root: ( self decodeFromTriplets: self defaultRootData ) " ^Array with: self rootInteger with: self rootSymbol with: #( #( 1 #iso #( #( 3 #org #( #( 6 #dod #( #( 1 #internet #( #( 1 #directory #() ) #( 2 #mgmt #( #( 1 #'mib-2' #( #( 1 #system #( #( 1 #sysDescr #() ) #( 2 #sysObjectID #() ) #( 3 #sysUpTime #() ) #( 4 #sysContact #() ) #( 5 #sysName #() ) #( 6 #sysLocation #() ) #( 7 #sysServices #() ) ) ) #( 2 #interfaces #() ) #( 3 #at #() ) #( 4 #ip #() ) #( 5 #icmp () ) #( 6 #tcp #() ) #( 7 #udp #() ) #( 8 #egp #() ) #( 11 #snmp #() ) ) ) ) ) #( 3 #experimental #() ) #( 4 #private #() ) ) ) ) ) ) ) ) ) #( 0 #itu #() ) #( 2 #'joint-iso-itu' #( #( 5 #ds #( #( 1 #module #( #( 7 #authFrame #( #( 3 #x509 #() ) ) ) ) ) ) ) ) ) )
initialize "((( SMINode initialize )))" self initializeRoot.
initializeRoot SMINode root: ( SMINode integer: self rootInteger symbol: self rootSymbol ). ( SMINode root ) atPath: #( 0 ) setSymbol: 'itu-t'; atPath: #( 0 0 ) setSymbol: 'recommendation'; atPath: #( 0 1 ) setSymbol: 'question'; atPath: #( 0 2 ) setSymbol: 'administration'; atPath: #( 0 3 ) setSymbol: 'network-operator'; atPath: #( 0 4 ) setSymbol: 'identified-organization'; atPath: #( 0 5 ) setSymbol: 'r-recommendation'; atPath: #( 0 9 ) setSymbol: 'data'; atPath: #( 1 ) setSymbol: 'iso'; atPath: #( 1 0 ) setSymbol: 'standard'; atPath: #( 1 1 ) setSymbol: 'registration-authority'; atPath: #( 1 2 ) setSymbol: 'member-body'; atPath: #( 1 3 ) setSymbol: 'identified-organization'; atPath: #( 1 2 840 ) setSymbol: 'us'; atPath: #( 1 3 6 ) setSymbol: 'dod'; atPath: #( 1 3 6 1 ) setSymbol: 'internet'; atPath: #( 1 3 6 1 1 ) setSymbol: 'directory'; atPath: #( 1 3 6 1 2 ) setSymbol: 'mgmt'; atPath: #( 1 3 6 1 3 ) setSymbol: 'experimental'; atPath: #( 1 3 6 1 4 ) setSymbol: 'private'; atPath: #( 1 3 6 1 5 ) setSymbol: 'security'; atPath: #( 1 3 6 1 6 ) setSymbol: 'snmpV2'; atPath: #( 1 3 6 1 7 ) setSymbol: 'mail'; atPath: #( 1 3 6 1 7 ) setSymbol: 'features'; atPath: #( 1 3 6 1 2 1 ) setSymbol: 'mib-2'; atPath: #( 1 3 6 1 2 2 ) setSymbol: 'pib'; atPath: #( 1 3 6 1 2 9 ) setSymbol: 'http'; atPath: #( 1 3 6 1 2 148 ) setSymbol: 'ipMIB'; atPath: #( 1 3 6 1 2 1 1 ) setSymbol: 'system'; atPath: #( 1 3 6 1 2 1 2 ) setSymbol: 'interface'; atPath: #( 1 3 6 1 2 1 3 ) setSymbol: 'at'; atPath: #( 1 3 6 1 2 1 4 ) setSymbol: 'ip'; atPath: #( 1 3 6 1 2 1 5 ) setSymbol: 'icmp'; atPath: #( 1 3 6 1 2 1 6 ) setSymbol: 'tcp'; atPath: #( 1 3 6 1 2 1 7 ) setSymbol: 'udp'; atPath: #( 1 3 6 1 2 1 8 ) setSymbol: 'egp'; atPath: #( 1 3 6 1 2 1 9 ) setSymbol: 'cmot'; atPath: #( 1 3 6 1 2 1 10 ) setSymbol: 'transmission'; atPath: #( 1 3 6 1 2 1 1 1 ) setSymbol: 'sysDescr'; atPath: #( 1 3 6 1 2 1 1 2 ) setSymbol: 'sysObjectID'; atPath: #( 1 3 6 1 2 1 1 3 ) setSymbol: 'sysUpTime'; atPath: #( 1 3 6 1 2 1 1 4 ) setSymbol: 'sysContact'; atPath: #( 1 3 6 1 2 1 1 5 ) setSymbol: 'sysName'; atPath: #( 1 3 6 1 2 1 1 6 ) setSymbol: 'sysLocation'; atPath: #( 1 3 6 1 2 1 1 7 ) setSymbol: 'sysServices'; atPath: #( 1 3 14 ) setSymbol: 'oiw'; atPath: #( 2 ) setSymbol: 'joint-iso-itu-t'; atPath: #( 2 0 ) setSymbol: 'presentations'; atPath: #( 2 1 ) setSymbol: 'asn1'; atPath: #( 2 2 ) setSymbol: 'association-control'; atPath: #( 2 3 ) setSymbol: 'reliable-transfer'; atPath: #( 2 4 ) setSymbol: 'remote-operations'; atPath: #( 2 5 ) setSymbol: 'ds'; atPath: #( 2 5 8 ) setSymbol: 'algorithm'; atPath: #( 2 5 8 1 ) setSymbol: 'encryptionAlgorithm'; atPath: #( 2 5 8 1 1 ) setSymbol: 'rsa'; atPath: #( 2 5 8 2 ) setSymbol: 'hashAlgorithm'; atPath: #( 2 5 8 3 ) setSymbol: 'signatureAlgorithm'; yourself
initializeRootAlternative "((( SMINode initializeRootAlternative )))" self root: ( self decodeFromTriplets: self defaultRootData )
</methods> <methods> ASN1.SMINode class <category>utility</category>
rootInteger "Zero is not allowed as the index of a substantive SMI node. We use it for the root." ^0
rootSymbol ^#'<root>'
unknownIntegerString ^'?'
unknownSymbolString ^'<unknown>'
</methods> <methods> ASN1.SMINode class <category>accessing</category>
root "((( SMINode root )))" ^root
root: anSMINode root := anSMINode
</methods> <methods> ASN1.Module <category>accessing</category>
add: aType | old | old := self find: aType symbol ifAbsent: [ nil ]. (old isNil or: [ old isTypeReference ]) ifFalse: [ TypeRedefinition new messageText: ( #RedefiningType1s2s << #asn1 >> 'An already existing ASN1 type <1s>.<2s> is being redefined!' expandMacrosWith: (old module name ifNil: ['nil']) with: old name); parameter: aType; raise ]. aType setModule: self. old ifNotNil: [ old oneWayBecome: aType ]. ^self addToDefinitions: aType
definitions ^definitions
exports ^exports
extensibility ^extensibility
imports ^imports
name ^name
oid ^oid
remove: aType self removeFromDefinitions: aType. aType setModule: nil. ^aType
tagging ^tagging
</methods> <methods> ASN1.Module <category>services</category>
find: aSymbol ifAbsent: aBlock ^definitions at: aSymbol ifAbsent: aBlock
register: aType ^self add: aType
unregister: aType ^self remove: aType
</methods> <methods> ASN1.Module <category>private</category>
addToDefinitions: aType ^definitions at: aType symbol put: aType
removeFromDefinitions: aType ^definitions removeKey: aType symbol
</methods> <methods> ASN1.Module <category>initialize-release</category>
initialize definitions := Dictionary new. extensibility := false. tagging := #explicit
name: aSymbol name := aSymbol
oid: anObject oid := anObject
</methods> <methods> ASN1.Module class <category>instance creation</category>
new ^super new initialize
new: aSymbol ^self new name: aSymbol
new: aSymbol oid: anOID ^self new name: aSymbol; oid: anOID
</methods> <methods> ASN1.Entity <category>accessing</category>
module ^module
module: aModule aModule add: self. self setModule: aModule.
name ^self symbol
name: aSymbol self symbol: aSymbol
setModule: aModule module := aModule
symbol ^symbol
symbol: aSymbol "... do ensure that it will be aSymbol." symbol := aSymbol ifNotNil: [ :sym | sym asSymbol ]
</methods> <methods> ASN1.Entity <category>testing</category>
isTypeReference ^false
</methods> <methods> ASN1.Entity <category>private</category>
typeFrom: aTypeSpec "Turn an acceptable form of type specification into the real type instance. aTypeSpect <Symbol | Asn1Type> ^<Asn1Type> " ^module ifNil: [ aTypeSpec isBehavior ifTrue: [ aTypeSpec new ] ifFalse: [ aTypeSpec ] ] ifNotNil: [ module typeFrom: aTypeSpec ]
</methods> <methods> ASN1.Entity <category>comparing</category>
equals: anObject "Implements 'structural equivalence' in the spirit of 'type compatibility' described in the ASN.1 semantic model (Dubuisson p.121)." ^anObject class == self class
</methods> <methods> ASN1.Entity class <category>instance creation</category>
name: aSymbol ^self new name: aSymbol; yourself
name: aSymbol in: aModule ^aModule register: (self name: aSymbol)
symbol: aSymbol ^self name: aSymbol
symbol: aSymbol in: aModule ^self name: aSymbol in: aModule
</methods> <methods> ASN1.ObjectIdentifier <category>printing</category>
printIntegersOn: aStream self value do: [ :x | aStream nextPutAll: x printString ] separatedBy: [ aStream nextPut: $. ]
printOn: aStream aStream nextPutAll: 'OID:'. self leafSymbol ifNotNil: [ :sym | aStream nextPutAll: sym; nextPut: $/ ]. self printIntegersOn: aStream
</methods> <methods> ASN1.ObjectIdentifier <category>accessing</category>
encoding ^encoding
encoding: aByteArray encoding := aByteArray
</methods> <methods> ASN1.ObjectIdentifier <category>other representations</category>
alphabeticSymbol ^SMINode root fullAlphabeticSymbolAtPath: value.
leafSymbol ^( SMINode root atAsn1OID: self ) ifNotNil: [ :node | node symbol ]
numericSymbol | str | str := WriteStream on: ( String new: ( value size * 2 ) ). self printIntegersOn: str. ^str contents asSymbol
</methods> <methods> ASN1.ObjectIdentifier <category>converting</category>
asAsn1OID ^self
</methods> <methods> ASN1.ObjectIdentifier class <category>class initialization</category>
initialize self initializeBEREncodingCache
initializeBEREncodingCache BEREncodingCache := Dictionary new: 1024.
resetBEREncodingCache "((( Asn1ImportedOID resetBEREncodingCache )))" self initializeBEREncodingCache
</methods> <methods> ASN1.ObjectIdentifier class <category>instance management</category>
new ^self shouldNotImplement
value: integers "Convert an array of integers into an OID. Preserve object identity at creation. integers <Array of: Integer> ^<ObjectIdentifier> " ( integers isEmpty or: [ integers anySatisfy: [ :x | x isInteger not or: [ x < 0 ] ] ] ) ifTrue: [ self cannotConvert: integers ]. ^( self findOIDValue: integers ) ifNil: [ | oid | oid := super new value: integers; yourself. self addOID: oid. oid ].
</methods> <methods> ASN1.ObjectIdentifier class <category>private</category>
addOID: anAsn1ImportedOID BEREncodingCache at: anAsn1ImportedOID value put: anAsn1ImportedOID
berEncodingCache "((( Asn1ImportedOID berEncodingCache )))" ^BEREncodingCache
cannotConvert: integers OIDError raiseWith: (Array with: integers) errorPattern: #Asn1OIDConversionError1p << #security >> '<1p> cannot be converted to an OID!'
findOIDValue: anArray ^BEREncodingCache at: anArray ifAbsent: []
removeOID: anAsn1ImportedOID BEREncodingCache removeKey: anAsn1ImportedOID value
</methods> <methods> ASN1.TypeRedefinition class <category>initialize-release</category>
initialize notifierString := #TypeRedefinition << #asn1 >> 'An ASN.1 entity is being redefined!'
</methods> <methods> ASN1.Struct <category>printing</category>
fullPrintOn: aStream self fullPrintOn: aStream offset: 1
fullPrintOn: aStream offset: offset self printNameOn: aStream. aStream nextPutAll: ' {'. self associationsDo: [ :elem | aStream cr; tab: offset; nextPutAll: elem key; nextPutAll: ': '. (elem value respondsTo: #fullPrintOn:offset:) ifTrue: [ elem value fullPrintOn: aStream offset: offset + 1 ] ifFalse: [ elem value printOn: aStream ] ]. aStream nextPutAll: ' }'.
fullPrintString | aStream | aStream := WriteStream on: (String new: 16). self fullPrintOn: aStream offset: 1. ^aStream contents
printNameOn: aStream ( name notNil ) ifTrue: [ aStream nextPutAll: name; space ]
printOn: aStream self shortPrintOn: aStream
shortPrintOn: aStream self printNameOn: aStream. aStream nextPut: ${. self associationsDo: [ :elem | aStream nextPutAll: elem key; space. (elem value respondsTo: #shortPrintOn:) ifTrue: [ elem value shortPrintOn: aStream ] ifFalse: [ elem value printOn: aStream ] ] separatedBy: [ aStream nextPutAll: ', ' ]. aStream nextPut: $}.
</methods> <methods> ASN1.Struct <category>comparing</category>
contentsEquals: aStruct "Anwer true if the receiver and aStruct contain the same key/values disregarding order." self structSize == aStruct structSize ifFalse: [ ^false ]. self keysAndValuesDo: [ :key :value | ( aStruct at: key ifAbsent: [ ^false ] ) = value ifFalse: [ ^false ] ]. ^true
</methods> <methods> ASN1.Struct <category>accessing</category>
accessKeys | keys | keys := OrderedCollection new. 1 to: lastIndex do: [ :i | keys add: (self basicAt: i) key ]. ^keys
associations | oc | oc := OrderedCollection new. 1 to: lastIndex do: [ :i | oc add: (self basicAt: i) ]. ^oc
_encoding ^encoding
_encoding: anEncoding encoding := anEncoding
</methods> <methods> Core.Collection <category>printing</category>
fullPrintOn: aStream offset: offset | tooMany | tooMany := aStream position + self maxPrint. aStream print: self class; nextPutAll: ' ('. self do: [:element | aStream cr; tab: offset. ( aStream position > tooMany ) ifTrue: [ aStream nextPutAll: (#etc << #dialogs >> '...etc...') asString, ')'. ^self ]. ( element respondsTo: #fullPrintOn:offset:) ifTrue: [ element fullPrintOn: aStream offset: offset + 1 ] ifFalse: [ element printOn: aStream ] ] separatedBy: [ aStream space ]. aStream nextPut: $)
</methods> <methods> Core.String <category>printing</category>
fullPrintOn: aStream offset: offset aStream nextPut: $'. 1 to: self size do: [:i | (aStream nextPut: (self at: i)) == $' ifTrue: [aStream nextPut: $']]. "embedded quotes get doubled" aStream nextPut: $'
</methods> <methods> Core.ByteArray <category>printing</category>
fullPrintOn: aStream offset: offset | printSize | printSize := self size. printSize > self maxPrintElements ifTrue: [printSize := self maxPrintElements]. aStream nextPutAll: '#['. (1 to: printSize) do: [:index | (self at: index) printOn: aStream] separatedBy: [aStream space]. printSize < self size ifTrue: [aStream nextPutAll: (#etc << #dialogs >> '...etc...') asString]. aStream nextPut: $]
</methods> <methods> Core.Array <category>converting</category>
asAsn1OID "Convert array of integers into an Asn1OID instance. #(2 5 29 37) asAsn1OID " ^ASN1.ObjectIdentifier value: self
</methods> <methods> Core.CharacterArray <category>converting</category>
asAsn1OID "Convert dotted OID notation into an Asn1OID instance. '2.5.29.37' asAsn1OID " ( self isEmpty or: [ self anySatisfy: [ :c | ('0123456789.' includes: c) not ] ] ) ifTrue: [ ^ASN1.ObjectIdentifier cannotConvert: self ]. ^ASN1.ObjectIdentifier value: ( (self tokensBasedOn: $.) collect: [ :token | Number readFrom: token readStream ] ) asArray
</methods> <initialize> ASN1.BitString </initialize> <initialize> ASN1.SMINode </initialize> <initialize> ASN1.ObjectIdentifier </initialize> <initialize> ASN1.TypeRedefinition </initialize> "Imported Classes:" self error: 'Attempting to file-in parcel imports. Choose terminate or close' <class> <name>Struct</name> <environment>Protocols</environment> <super>Protocols.ProtoObject</super> <private>false</private> objects name lastIndex <imports></imports> <category>Protocols-Common</category> <attributes> <package>Protocols-Common</package> </attributes> </class> <class> <name>Object</name> <environment>Core</environment> <super></super> <private>false</private> none <imports></imports> <category>Kernel-Objects</category> <attributes> <package>Kernel-Objects</package> </attributes> </class> <class> <name>Warning</name> <environment>Core</environment> <super>Core.Exception</super> <private>false</private> none <imports></imports> <category>Kernel-Exception Handling</category> <attributes> <package>Kernel-Exception Handling</package> </attributes> </class> <class> <name>Collection</name> <environment>Core</environment> <super>Core.Object</super> <private>false</private> none <imports></imports> <category>Collections-Abstract</category> <attributes> <package>Collections-Abstract</package> </attributes> </class> <class> <name>CharacterArray</name> <environment>Core</environment> <super>Core.ArrayedCollection</super> <private>false</private> none <imports></imports> <category>Collections-Text</category> <attributes> <package>Collections-Text</package> </attributes> </class> <class> <name>ByteArray</name> <environment>Core</environment> <super>Core.IntegerArray</super> <private>false</private> bytes <imports></imports> <category>Collections-Arrayed</category> <attributes> <package>Collections-Arrayed</package> </attributes> </class> <class> <name>Array</name> <environment>Core</environment> <super>Core.ArrayedCollection</super> <private>false</private> objects <imports></imports> <category>Collections-Arrayed</category> <attributes> <package>Collections-Arrayed</package> </attributes> </class> <class> <name>String</name> <environment>Core</environment> <super>Core.CharacterArray</super> <private>false</private> none <imports></imports> <category>Collections-Text</category> <attributes> <package>Collections-Text</package> </attributes> </class> <class> <name>Error</name> <environment>Core</environment> <super>Core.Exception</super> <private>false</private> none <imports></imports> <category>Kernel-Exception Handling</category> <attributes> <package>Kernel-Exception Handling</package> </attributes> </class>