added interface to send() and recv()
authorClaus Gittinger <cg@exept.de>
Thu, 26 Oct 2000 18:54:40 +0200
changeset 915 3dc0e3cd838a
parent 914 7db1f3375ac9
child 916 63fddba933d6
added interface to send() and recv()
Socket.st
--- a/Socket.st	Tue Oct 24 19:28:57 2000 +0200
+++ b/Socket.st	Thu Oct 26 18:54:40 2000 +0200
@@ -2207,6 +2207,88 @@
 
 !Socket methodsFor:'datagram transmission'!
 
+receiveBuffer:aDataBuffer start:startIndex for:nBytes
+    "receive data
+     Return the number of bytes received, or a negative number on error.
+     On error, the unix error code is left in the lastErrorNumber
+     instance variable.
+     The thread blocks until data arrives - you may want to wait before
+     receiving, using #readWait or #readWaitWithTimeout:."
+
+
+    |nReceived|
+
+%{
+#ifndef NO_SOCKET
+    OBJ oClass, myDomain;
+    OBJ fp = __INST(filePointer);
+    int nInstVars, nInstBytes, objSize;
+    int sock;
+    int n;
+    char *cp;
+    int flags = 0;
+
+    if (fp != nil) {
+        sock = fileno(__FILEVal(fp));
+
+        oClass = __Class(aDataBuffer);
+        switch (_intVal(_ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
+            case BYTEARRAY:
+            case WORDARRAY:
+            case SWORDARRAY:
+            case LONGARRAY:
+            case SLONGARRAY:
+            case FLOATARRAY:
+            case DOUBLEARRAY:
+                break;
+            default:
+                goto bad;
+        }
+
+        nInstVars = _intVal(_ClassInstPtr(oClass)->c_ninstvars);
+        nInstBytes = OHDR_SIZE + nInstVars * sizeof(OBJ);
+        objSize = _Size(aDataBuffer) - nInstBytes;
+        cp = (char *)__InstPtr(aDataBuffer) + nInstBytes;
+        if (__isSmallInteger(startIndex)) {
+            cp += __intVal(startIndex);
+            objSize -= __intVal(startIndex);
+        }
+        if (__isSmallInteger(nBytes)) {
+            if (__intVal(nBytes) < objSize) {
+                objSize = __intVal(nBytes);
+            }
+        }
+
+        __BEGIN_INTERRUPTABLE__
+        do {
+            n = recv(sock, cp, objSize, flags);
+        } while ((n < 0) && (errno == EINTR));
+        __END_INTERRUPTABLE__
+
+        if (n < 0) {
+            __INST(lastErrorNumber) = __MKSMALLINT(errno);
+        }
+        nReceived = __MKSMALLINT(n);
+    }
+#endif
+bad: ;
+%}.
+    nReceived notNil ifTrue:[
+        nReceived < 0 ifTrue:[
+            'Socket [warning]: ' infoPrint.
+            (OperatingSystem errorTextForNumber:lastErrorNumber) infoPrintCR.
+        ].
+        ^ nReceived
+    ].
+    "
+     arrive here if you try to receive into an invalid buffer
+     (i.e. not ByteArray-like), 
+     or if the addressBuffer is nonNil AND not a ByteArray/String 
+     or if the addressBuffer is nonNil AND too small.
+    "
+    self primitiveFailed
+!
+
 receiveFrom:anAddressBuffer buffer:aDataBuffer
     "receive datagramm data - put address of originating host into
      anAddressBuffer, data into aBuffer. 
@@ -2446,6 +2528,107 @@
     self primitiveFailed
 !
 
+sendBuffer:aDataBuffer start:startIndex for:count flags:flags
+    "send data. 
+     Both must be ByteArray-like. The bytes in the addressBuffer must
+     be a valid address for my domain (i.e. for inet, a 4-byte byteArray).
+     Return the number of bytes transmitted, or a negative number on error.
+     On error, the unix error code is left in the lastErrorNumber
+     instance variable."
+
+    |nReceived portNo|
+
+%{
+#ifndef NO_SOCKET
+    OBJ oClass;
+    OBJ fp = __INST(filePointer);
+    int nInstVars, nInstBytes, objSize;
+    int sock;
+    int n;
+    char *cp;
+    int _flags = 0;
+    int offs, nBytes;
+    unsigned long norder;
+
+    _flags = __longIntVal(flags);
+ 
+    if ((fp != nil) 
+     && __isSmallInteger(startIndex)
+     && __isSmallInteger(count)) {
+        sock = fileno(__FILEVal(fp));
+
+        oClass = __Class(aDataBuffer);
+        switch (_intVal(_ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
+            case BYTEARRAY:
+                offs = __intVal(startIndex) - 1;
+                break;
+            case WORDARRAY:
+            case SWORDARRAY:
+                offs = (__intVal(startIndex) - 1) * 2;
+                break;
+            case LONGARRAY:
+            case SLONGARRAY:
+                offs = (__intVal(startIndex) - 1) * 4;
+                break;
+            case LONGLONGARRAY:
+            case SLONGLONGARRAY:
+                offs = (__intVal(startIndex) - 1) * 8;
+# ifdef __NEED_LONGLONG_ALIGN
+                offs += 4;
+# endif
+            case FLOATARRAY:
+                offs = (__intVal(startIndex) - 1) * sizeof(float);
+                break;
+            case DOUBLEARRAY:
+                offs = (__intVal(startIndex) - 1) * sizeof(double);
+# ifdef __NEED_DOUBLE_ALIGN
+                offs += 4;
+# endif
+                break;
+            default:
+                goto bad;
+        }
+        nBytes = __intVal(count);
+
+        nInstVars = _intVal(_ClassInstPtr(oClass)->c_ninstvars);
+        nInstBytes = OHDR_SIZE + nInstVars * sizeof(OBJ);
+        objSize = __qSize(aDataBuffer) - nInstBytes;
+        cp = (char *)__InstPtr(aDataBuffer) + nInstBytes;
+        cp += offs;
+        if ((offs + nBytes) > objSize) {
+# ifdef DGRAM_DEBUG
+            printf("cut off ...\n");
+# endif
+            nBytes = objSize - offs;
+        }
+
+# ifdef DGRAM_DEBUG
+        printf("sending %d bytes ...", nBytes);
+# endif
+
+        __BEGIN_INTERRUPTABLE__
+        do {
+            n = send(sock, cp, nBytes, _flags);
+        } while ((n < 0) && (errno == EINTR));
+        __END_INTERRUPTABLE__
+
+        if (n < 0) {
+            __INST(lastErrorNumber) = __MKSMALLINT(errno);
+        }
+        RETURN (__MKSMALLINT(n));
+    }
+#endif
+bad: ;
+%}.
+    "
+     arrive here if you try to send from an invalid buffer
+     (i.e. not ByteArray-like), 
+     or if the addressBuffer is nonNil AND not a ByteArray/String 
+     or if the addressBuffer is nonNil AND too small.
+    "
+    self primitiveFailed
+!
+
 sendTo:anAddressBuffer buffer:buffer
     "send datagramm data - fetch address of destination host from
      anAddressBuffer, data from aDataBuffer. 
@@ -4763,5 +4946,5 @@
 !Socket class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic2/Socket.st,v 1.149 2000-08-08 13:31:13 stefan Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic2/Socket.st,v 1.150 2000-10-26 16:54:40 cg Exp $'
 ! !