--- a/UnixFileDescriptorHandle.st Sat Jun 24 12:45:06 2000 +0200
+++ b/UnixFileDescriptorHandle.st Sat Jun 24 12:45:31 2000 +0200
@@ -15,6 +15,233 @@
! !
+!UnixFileDescriptorHandle methodsFor:'input/output'!
+
+readBytes:count into:aByteBuffer startingAt:firstIndex
+ "read count bytes into a byte-buffer;
+ Return the number of bytes read (negative on error)"
+
+%{
+ unsigned char *extPtr;
+ int nRead = -1;
+ INT fd = (INT)(__externalAddressVal(self));
+ INT cnt, offs;
+ int nInstBytes, objSize;
+#include <errno.h>
+ if (! __bothSmallInteger(count, firstIndex)) {
+ goto bad;
+ }
+ cnt = __smallIntegerVal(count);
+ offs = __smallIntegerVal(firstIndex) - 1;
+
+ if (fd < 0) {
+ goto bad;
+ }
+ if (__isExternalBytes(aByteBuffer)) {
+ OBJ sz;
+
+ nInstBytes = 0;
+ extPtr = (char *)(__externalBytesAddress(aByteBuffer));
+ sz = __externalBytesSize(aByteBuffer);
+ if (__isSmallInteger(sz)) {
+ objSize = __smallIntegerVal(sz);
+ } else {
+ objSize = -1; /* unknown */
+ }
+ } else {
+ OBJ oClass;
+ int nInstVars;
+
+ oClass = __Class(aByteBuffer);
+ switch (__smallIntegerVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
+ case BYTEARRAY:
+ case WORDARRAY:
+ case LONGARRAY:
+ case SWORDARRAY:
+ case SLONGARRAY:
+ case FLOATARRAY:
+ case DOUBLEARRAY:
+ break;
+ default:
+ goto bad;
+ }
+ extPtr = (char *)0;
+ nInstVars = __smallIntegerVal(__ClassInstPtr(oClass)->c_ninstvars);
+ nInstBytes = __OBJS2BYTES__(nInstVars);
+ objSize = __Size(aByteBuffer) - OHDR_SIZE - nInstBytes;
+ }
+ if ((offs >= 0)
+ && (cnt >= 0)
+ && ((objSize == -1) || (objSize >= (cnt + offs)))) {
+ nRead = 0;
+
+ do {
+ int n;
+
+ if (extPtr) {
+ n = read(fd, extPtr+offs, cnt);
+ } else {
+ char *bp;
+
+ /*
+ * on interrupt, anObject may be moved to another location.
+ * So we recompute the byte-address here.
+ */
+ bp = __ByteArrayInstPtr(aByteBuffer)->ba_element + nInstBytes;
+
+ n = read(fd, bp + offs, cnt);
+ }
+ if (n > 0) {
+ cnt -= n;
+ offs += n;
+ nRead += n;
+ } else {
+ if (n < 0) {
+ if (errno == EINTR) {
+ continue;
+ }
+ break;
+ }
+ }
+ } while (cnt > 0);
+
+ RETURN (__mkSmallInteger(nRead));
+ }
+bad: ;
+%}.
+ ^ self primitiveFailed
+
+ "
+ |h buff n|
+
+ h := self basicNew.
+ h setFileDescriptor:0.
+ buff := ByteArray new:10. buff inspect.
+ n := h readBytes:10 into:buff startingAt:1.
+ Transcript show:n; space; showCR:buff.
+ "
+
+!
+
+writeBytes:count from:aByteBuffer startingAt:firstIndex
+ "write count bytes from a byte-buffer;
+ Return the number of bytes written (negative on error)"
+
+%{
+ unsigned char *extPtr;
+ int nWritten = -1;
+ INT fd = (INT)(__externalAddressVal(self));
+ INT cnt, offs;
+ int nInstBytes, objSize;
+#include <errno.h>
+ if (! __bothSmallInteger(count, firstIndex)) {
+ goto bad;
+ }
+ cnt = __smallIntegerVal(count);
+ offs = __smallIntegerVal(firstIndex) - 1;
+
+ if (fd < 0) {
+ goto bad;
+ }
+ if (__isExternalBytes(aByteBuffer)) {
+ OBJ sz;
+
+ nInstBytes = 0;
+ extPtr = (char *)(__externalBytesAddress(aByteBuffer));
+ sz = __externalBytesSize(aByteBuffer);
+ if (__isSmallInteger(sz)) {
+ objSize = __smallIntegerVal(sz);
+ } else {
+ objSize = -1; /* unknown */
+ }
+ } else {
+ OBJ oClass;
+ int nInstVars;
+
+ oClass = __Class(aByteBuffer);
+ switch (__smallIntegerVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
+ case BYTEARRAY:
+ case WORDARRAY:
+ case LONGARRAY:
+ case SWORDARRAY:
+ case SLONGARRAY:
+ case FLOATARRAY:
+ case DOUBLEARRAY:
+ break;
+ default:
+ goto bad;
+ }
+ extPtr = (char *)0;
+ nInstVars = __smallIntegerVal(__ClassInstPtr(oClass)->c_ninstvars);
+ nInstBytes = __OBJS2BYTES__(nInstVars);
+ objSize = __Size(aByteBuffer) - OHDR_SIZE - nInstBytes;
+ }
+ if ((offs >= 0)
+ && (cnt >= 0)
+ && ((objSize == -1) || (objSize >= (cnt + offs)))) {
+ nWritten = 0;
+
+ do {
+ int n;
+
+ if (extPtr) {
+ n = write(fd, extPtr+offs, cnt);
+ } else {
+ char *bp;
+
+ /*
+ * on interrupt, anObject may be moved to another location.
+ * So we recompute the byte-address here.
+ */
+ bp = __ByteArrayInstPtr(aByteBuffer)->ba_element + nInstBytes;
+
+ n = write(fd, bp + offs, cnt);
+ }
+ if (n > 0) {
+ cnt -= n;
+ offs += n;
+ nWritten += n;
+ } else {
+ if (n < 0) {
+ if (errno == EINTR) {
+ continue;
+ }
+ break;
+ }
+ }
+ } while (cnt > 0);
+
+ RETURN (__mkSmallInteger(nWritten));
+ }
+bad: ;
+%}.
+ ^ self primitiveFailed
+
+ "
+ |h buff n|
+
+ h := self basicNew.
+ h setFileDescriptor:1.
+ buff := '12345678901234567890'.
+ n := h writeBytes:10 from:buff startingAt:1.
+ "
+
+
+! !
+
+!UnixFileDescriptorHandle methodsFor:'private accessing'!
+
+setFileDescriptor:anInteger
+
+%{
+ if (__isSmallInteger(anInteger)) {
+ __externalAddressVal(self) = (OBJ)(__smallIntegerVal(anInteger));
+ }
+%}
+
+
+! !
+
!UnixFileDescriptorHandle methodsFor:'release'!
closeFile
@@ -34,5 +261,5 @@
!UnixFileDescriptorHandle class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/UnixFileDescriptorHandle.st,v 1.3 2000-06-23 19:43:40 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/UnixFileDescriptorHandle.st,v 1.4 2000-06-24 10:45:31 cg Exp $'
! !