SocketAddress.st
changeset 1164 41a2750af1fa
parent 818 2f8331ad12d4
child 1167 56c172bc5cfe
--- a/SocketAddress.st	Thu Mar 27 14:29:58 2003 +0100
+++ b/SocketAddress.st	Thu Mar 27 14:30:01 2003 +0100
@@ -10,6 +10,8 @@
  hereby transferred.
 "
 
+"{ Package: 'stx:libbasic2' }"
+
 UninterpretedBytes variableByteSubclass:#SocketAddress
 	instanceVariableNames:''
 	classVariableNames:''
@@ -67,17 +69,76 @@
     ^ self new hostAddress:addr port:portNr
 !
 
+hostName:name
+    ^ self hostName:name serviceName:nil type:nil
+!
+
 hostName:name port:portNr
-    ^ self new hostName:name port:portNr
+    ^ self hostName:name serviceName:portNr type:nil
+!
+
+hostName:name serviceName:portNrOrName type:socketTypeSymbol
+
+    |addressInfo serviceName port sa|
+
+    portNrOrName isString ifTrue:[
+        serviceName := portNrOrName
+    ] ifFalse:[
+        port := portNrOrName.
+    ].
+
+    addressInfo := self getAddressInfo:name serviceName:serviceName 
+                 domain:self domainSymbol type:socketTypeSymbol
+                 protocol:nil flags:0.
+
+    sa := addressInfo first socketAddress.
+    addressInfo size > 1 ifTrue:[
+        (addressInfo contains:[:entry| entry socketAddress ~= sa]) ifTrue:[
+            self error:'too many results'
+        ].
+    ].
+    port notNil ifTrue:[
+        sa port:port.
+    ].
+    ^ sa
+
+    "
+     SocketAddress hostName:'localhost' serviceName:10 type:#stream
+     IPSocketAddress hostName:'localhost' serviceName:'echo' type:#datagram 
+     IPSocketAddress hostName:'localhost' serviceName:'echo' type:nil
+    "
 !
 
 new
-    ^ self subclassResponsibility
+    ^ (self new:self socketAddressSize) domainCode:self domainCode
+
+    "
+     IPSocketAddress new
+     IPv6SocketAddress new
+     UDSocketAddress new
+     AppletalkSocketAddress new
+   "
+!
 
+newDomain:domain
+   "answer an new socket address for a given domain"
+
+   ^ (self knownClassFromCode:domain) new
+
+   "
+    self newDomain:#unix
+    self newDomain:#inet
+   "
 ! !
 
 !SocketAddress class methodsFor:'queries'!
 
+domainCode
+    "answer the numerical domain code used in socket addresses"
+
+    ^ OperatingSystem socketAccessor domainCodeOf:self domainSymbol
+!
+
 domainCodeFromName:aNameSymbol
     "this is a compatibility method;
      VW returns the internal unix codes here - however, in ST/X,
@@ -121,34 +182,106 @@
 
 !
 
+domainSymbol
+    "answer the domain symbol. Subclasses redefine this"
+
+    self == SocketAddress ifTrue:[
+        ^ nil
+    ] ifFalse:[
+        self subclassResponsibility
+    ]
+!
+
+getAddressInfo:hostName serviceName:serviceName domain:domainArg type:typeArg protocol:protoArg flags:flags 
+    "answer an Array of socket addresses for serviceName on hostName
+     Domain, type, protocol may be nil or specify a hint for the socket 
+     addresses to be returned."
+
+    ^ OperatingSystem socketAccessor 
+            getAddressInfo:hostName serviceName:serviceName 
+            domain:domainArg type:typeArg protocol:protoArg flags:flags 
+
+    "
+     self getAddressInfo:'localhost' serviceName:nil 
+            domain:nil type:nil protocol:nil flags:nil
+     self getAddressInfo:'localhost' serviceName:nil 
+            domain:#inet type:#stream protocol:nil flags:nil
+     self getAddressInfo:'localhost' serviceName:nil 
+            domain:#inet type:#stream protocol:#tcp flags:nil
+     self getAddressInfo:'blurb.exept.de' serviceName:nil 
+            domain:#inet type:nil protocol:nil flags:nil
+     self getAddressInfo:'1.2.3.4' serviceName:'6' 
+            domain:#inet type:nil protocol:nil flags:nil
+     self getAddressInfo:'localhost' serviceName:'echo' 
+            domain:#inet6 type:nil protocol:nil flags:nil
+    "
+!
+
+getNameInfo:socketAddress wantHostName:wantHostName wantServiceName:wantServiceName datagram:useDatagram flags:flags 
+    "answer an Array containing the hostName and serviceName
+     in socketAddress. SocketType may be one "
+
+    ^ OperatingSystem socketAccessor
+            getNameInfo:socketAddress wantHostName:wantHostName 
+            wantServiceName:wantServiceName datagram:useDatagram flags:flags 
+    
+    "
+     self getNameInfo:
+         (self getAddressInfo:'localhost' serviceName:'echo' 
+                domain:#inet type:#stream protocol:nil flags:nil) first socketAddress
+         wantHostName:true wantServiceName:true datagram:false flags:0
+    "
+!
+
 knownClassFromCode:code
     "this is a compatibility method;
      VW expects the internal unix codes here - however, in ST/X,
      symbols are expected - keeping the numeric values secret (in Socket)"
 
-    code == #unix      ifTrue:[^ #UDSocketAddress].
-    code == #inet      ifTrue:[^ #IPSocketAddress].
-    code == #inet6     ifTrue:[^ #IPv6SocketAddress].
-    code == #appletalk ifTrue:[^ #AppletalkSocketAddress].
-    code == #DECnet    ifTrue:[^ #DECNetSocketAddress].
-    code == #sna       ifTrue:[^ #SNASocketAddress].
-    code == #xns       ifTrue:[^ #XNSSocketAddress].
-    code == #ccitt     ifTrue:[^ #CCITTSocketAddress].
+    code isInteger ifTrue:[
+        self allSubclassesDo:[:cls|
+            cls domainCode == code ifTrue:[
+                ^ cls
+            ].
+        ].
+    ] ifFalse:[
+        self allSubclassesDo:[:cls|
+            cls domainSymbol == code ifTrue:[
+                ^ cls
+            ].
+        ].
+    ].
+    ^ SocketAddress
 
-    "/
-    "/ could someone tell me which symbols are used in ST-80's SocketAddress class ?
-    "/
-    self error:'no more mimicri implemented yet ...'.
-    ^ #SocketAddress
+    "
+     self knownClassFromCode:#unix
+     self knownClassFromCode:#inet
+     self knownClassFromCode:2
+    "
+!
 
+socketAddressSize
+    "answer the OS specific size of a socket address"
+
+    ^ self subclassResponsibility
 ! !
 
 !SocketAddress methodsFor:'accessing'!
 
+domainCode
+
+    ^ self unsignedShortAt:1
+!
+
+domainCode:anInteger
+
+    self unsignedShortAt:1 put:anInteger
+!
+
 hostAddress:anAddress
-    self replaceBytesFrom:1 to:anAddress size with:anAddress startingAt:1
+    "generic method, subclasses usually redefine this"
 
-
+    self replaceBytesFrom:3 to:anAddress size+2 with:anAddress startingAt:1
 !
 
 hostAddress:addr port:portNr
@@ -161,6 +294,29 @@
 
 ! !
 
+!SocketAddress methodsFor:'printing & storing'!
+
+displayString
+    "redefine form Collection"
+
+    |s|
+
+    s := WriteStream on:''.
+    self printOn:s.
+    ^ s contents.
+! !
+
+!SocketAddress methodsFor:'private'!
+
+fromBytes:aByteArray
+    "Copy the internal representation of a SocketAddress to myself
+
+     This is an internal interface!!"
+
+    self replaceBytesFrom:1 to:aByteArray size 
+         with:aByteArray startingAt:1.
+! !
+
 !SocketAddress methodsFor:'queries'!
 
 address
@@ -168,17 +324,31 @@
 !
 
 hostName
-    ^ self subclassResponsibility
+    ^ (self class getNameInfo:self wantHostName:true 
+                  wantServiceName:false datagram:false flags:0) first
 
-    "Created: 2.11.1995 / 11:17:51 / cg"
+    "
+     (IPSocketAddress hostAddress:#[127 0 0 1] port:7) hostName
+     (IPSocketAddress hostAddress:#[193 141 12 193] port:10) hostName
+    "
 !
 
 portOrName
     ^ self subclassResponsibility
+!
+
+serviceName
+    ^ (self class getNameInfo:self wantHostName:false 
+                  wantServiceName:true datagram:false flags:0) second
+
+    "
+     (IPSocketAddress hostAddress:#[127 0 0 1] port:7) serviceName
+     (IPSocketAddress hostAddress:#[193 141 12 193] port:10) serviceName
+    "
 ! !
 
 !SocketAddress class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic2/SocketAddress.st,v 1.9 1999-09-21 00:27:27 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic2/SocketAddress.st,v 1.10 2003-03-27 13:30:01 stefan Exp $'
 ! !