IPSocketAddress.st
author Claus Gittinger <cg@exept.de>
Wed, 16 Jul 2003 18:44:37 +0200
changeset 1281 6df4f8f211e3
parent 1273 03afdf3f895e
child 1333 d9ebcc42524c
permissions -rw-r--r--
fixed anyHost

"
 COPYRIGHT (c) 1995 by Claus Gittinger
	      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:libbasic2' }"

SocketAddress variableByteSubclass:#IPSocketAddress
	instanceVariableNames:''
	classVariableNames:''
	poolDictionaries:''
	category:'OS-Sockets'
!

IPSocketAddress class instanceVariableNames:'addrCache nameCache'

"
 No other class instance variables are inherited by this class.
"
!

!IPSocketAddress class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 1995 by Claus Gittinger
	      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
"
    Instances of IPSocketAddress represent tcp/ip-domain socket addresses.
    These consist of an ip address (4 bytes) and a port number.

    ST-80 compatibility class.
    This may be required when existing code has to be ported to ST/X;
    however, it may not be complete and more protocol may be added in the future.
    The code here was created when public domain code (Manchester) had to
    be ported to ST/X and missing classes/methods were encountered, and code added
    by reasoning 'what the original class could probably do there'.

    This is an additional goody class; therefore:

    THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTOR ``AS IS'' AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTOR BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    SUCH DAMAGE.
"
! !

!IPSocketAddress class methodsFor:'instance creation'!

hostName:name serviceName:portNrOrName type:socketTypeSymbol
    "get a new instance given a hostname, port or service and type.
     Redefined to cache the result of the name-lookup."

    |addrBytes sa|

    portNrOrName isString ifTrue:[
        ^ super hostName:name serviceName:portNrOrName type:socketTypeSymbol
    ].

    addrBytes := self addressCacheAt:name.
    addrBytes notNil ifTrue:[
        sa := self hostAddress:addrBytes.
        portNrOrName notNil ifTrue:[
            sa port:portNrOrName.
        ].
    ] ifFalse:[
        sa := super hostName:name serviceName:portNrOrName type:socketTypeSymbol.

        self addressCacheAt:name put:(sa hostAddress).
    ].
    ^ sa

    "
     SocketAddress hostName:'localhost' serviceName:10 type:#stream
     IPSocketAddress hostName:'localhost' serviceName:'echo' type:#datagram 
     IPSocketAddress hostName:'localhost' serviceName:'echo' type:nil
    "
! !

!IPSocketAddress class methodsFor:'addressing'!

anyAddress
    "return the anonymous addresses bytes"

    ^ #[0 0 0 0]
!

anyPort
    "return the anon port number"

    ^ 0
!

broadcastAddress
    "return the broadcast address"

    ^ #[255 255 255 255]
!

firstUnreservedPort
    "return the first unreserved port number"

    ^ 1024
!

local
    "return IN_ADDR_ANY, the address matching any local address"

    ^ #[127 0 0 1]
!

maxPort
    "return the maximum port number"

    ^ 16rffff
!

thisHost
    "return the bytes of IN_ADDR_ANY, the address matching any local address"

    ^ #[0 0 0 0]
! !

!IPSocketAddress class methodsFor:'caching'!

addressCacheAt:aHostName
    addrCache notNil ifTrue:[
        ^ addrCache at:aHostName ifAbsent:nil.
    ].
    ^ nil
!

addressCacheAt:aName put:aHostAddress
    (addrCache isNil or:[addrCache size > 30]) ifTrue:[
        addrCache := Dictionary new.
    ].
    
    addrCache at:aName put:aHostAddress.
!

flushAddressCache
    addrCache := nil

    "
     self flushAddressCache
    "
!

flushNameCache
    nameCache := Dictionary new.
!

nameCacheAt:aHostAddress
    nameCache notNil ifTrue:[
        ^ nameCache at:aHostAddress ifAbsent:nil.
    ].
    ^ nil
!

nameCacheAt:aHostAddress put:aName
    (nameCache isNil or:[nameCache size > 30]) ifTrue:[
        nameCache := Dictionary new.
    ].
    
    nameCache at:aHostAddress put:aName.
! !

!IPSocketAddress class methodsFor:'queries'!

domainSymbol

    ^ #'AF_INET'
!

obsoleteDomainSymbol
    ^ #inet
!

vwDomainSymbol
    ^ #afInet
! !

!IPSocketAddress methodsFor:'accessing'!

hostAddress
    ^ (ByteArray new:4) replaceFrom:1 to:4 with:self startingAt:5
!

hostAddress:aByteArray
    ^ self replaceFrom:5 to:8 with:aByteArray startingAt:1
!

port
    ^ self unsignedShortAt:3 bigEndian:true
!

port:aPortNr
    self unsignedShortAt:3 put:aPortNr bigEndian:true
! !

!IPSocketAddress methodsFor:'obsolete'!

address
    ^ self hostAddress
!

portOrName
    ^ self port
! !

!IPSocketAddress methodsFor:'printing & storing'!

printOn:aStream
    "append a user printed representation of the receiver to aStream.
     The format is suitable for a human - not meant to be read back."

    |port i1 i2|

    i1 := self adrBytesStart.
    i2 := i1 + self numAdrBytes - 1.
    i1 to:i2 do:[:i | 
        i ~~ i1 ifTrue:[
            aStream nextPut:$.
        ].
        (self at:i) printOn:aStream
    ].
    (port := self port) ~~ 0 ifTrue:[
        aStream nextPut:$:.
        port printOn:aStream.
    ].
! !

!IPSocketAddress methodsFor:'private'!

adrBytesStart
    ^ 5
!

numAdrBytes
    ^ 4
! !

!IPSocketAddress methodsFor:'queries'!

hostName
    |addr name|

    addr := self hostAddress.

    name := self class nameCacheAt:addr.
    name notNil ifTrue:[^ name].

    name := super hostName.
    name notNil ifTrue:[
        self class nameCacheAt:addr put:name.
    ].
    ^ name
! !

!IPSocketAddress class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libbasic2/IPSocketAddress.st,v 1.23 2003-07-16 16:44:33 cg Exp $'
! !