UnixFileDescriptorHandle.st
changeset 5415 d13be53ae32c
parent 5413 4e67713bf25a
child 5416 93b5fd7ec357
equal deleted inserted replaced
5414:8557e4e71e51 5415:d13be53ae32c
    13 %}
    13 %}
    14 
    14 
    15 ! !
    15 ! !
    16 
    16 
    17 
    17 
       
    18 !UnixFileDescriptorHandle methodsFor:'input/output'!
       
    19 
       
    20 readBytes:count into:aByteBuffer startingAt:firstIndex
       
    21     "read count bytes into a byte-buffer;
       
    22      Return the number of bytes read (negative on error)"
       
    23 
       
    24 %{
       
    25     unsigned char *extPtr;
       
    26     int nRead = -1;
       
    27     INT fd = (INT)(__externalAddressVal(self));
       
    28     INT cnt, offs;
       
    29     int nInstBytes, objSize;
       
    30 #include <errno.h>
       
    31     if (! __bothSmallInteger(count, firstIndex)) {
       
    32         goto bad;
       
    33     }
       
    34     cnt = __smallIntegerVal(count);
       
    35     offs = __smallIntegerVal(firstIndex) - 1;
       
    36 
       
    37     if (fd < 0) {
       
    38         goto bad;
       
    39     }
       
    40     if (__isExternalBytes(aByteBuffer)) {
       
    41         OBJ sz;
       
    42 
       
    43         nInstBytes = 0;
       
    44         extPtr = (char *)(__externalBytesAddress(aByteBuffer));
       
    45         sz = __externalBytesSize(aByteBuffer);
       
    46         if (__isSmallInteger(sz)) {
       
    47             objSize = __smallIntegerVal(sz);
       
    48         } else {
       
    49             objSize = -1; /* unknown */
       
    50         }
       
    51     } else {
       
    52         OBJ oClass;
       
    53         int nInstVars;
       
    54 
       
    55         oClass = __Class(aByteBuffer);
       
    56         switch (__smallIntegerVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
       
    57             case BYTEARRAY:
       
    58             case WORDARRAY:
       
    59             case LONGARRAY:
       
    60             case SWORDARRAY:
       
    61             case SLONGARRAY:
       
    62             case FLOATARRAY:
       
    63             case DOUBLEARRAY:
       
    64                 break;
       
    65             default:
       
    66                 goto bad;
       
    67         }
       
    68         extPtr = (char *)0;
       
    69         nInstVars = __smallIntegerVal(__ClassInstPtr(oClass)->c_ninstvars);
       
    70         nInstBytes = __OBJS2BYTES__(nInstVars);
       
    71         objSize = __Size(aByteBuffer) - OHDR_SIZE - nInstBytes;
       
    72     }
       
    73     if ((offs >= 0)
       
    74      && (cnt >= 0)
       
    75      && ((objSize == -1) || (objSize >= (cnt + offs)))) {
       
    76         nRead = 0;
       
    77 
       
    78         do {
       
    79             int n;
       
    80 
       
    81             if (extPtr) {
       
    82                 n = read(fd, extPtr+offs, cnt);
       
    83             } else {
       
    84                 char *bp;
       
    85 
       
    86                 /*
       
    87                  * on interrupt, anObject may be moved to another location.
       
    88                  * So we recompute the byte-address here.
       
    89                  */
       
    90                 bp = __ByteArrayInstPtr(aByteBuffer)->ba_element + nInstBytes;
       
    91 
       
    92                 n = read(fd, bp + offs, cnt);
       
    93             }
       
    94             if (n > 0) {
       
    95                 cnt -= n;
       
    96                 offs += n;
       
    97                 nRead += n;
       
    98             } else {
       
    99                 if (n < 0) {
       
   100                     if (errno == EINTR) {
       
   101                         continue;
       
   102                     }
       
   103                     break;
       
   104                 }
       
   105             }
       
   106         } while (cnt > 0);
       
   107 
       
   108         RETURN (__mkSmallInteger(nRead));
       
   109     }
       
   110 bad: ;   
       
   111 %}.
       
   112     ^ self primitiveFailed
       
   113 
       
   114     "
       
   115      |h buff n|
       
   116 
       
   117      h := self basicNew.
       
   118      h setFileDescriptor:0.
       
   119      buff := ByteArray new:10. buff inspect.
       
   120      n := h readBytes:10 into:buff startingAt:1.
       
   121      Transcript show:n; space; showCR:buff.
       
   122     "
       
   123 
       
   124 !
       
   125 
       
   126 writeBytes:count from:aByteBuffer startingAt:firstIndex
       
   127     "write count bytes from a byte-buffer;
       
   128      Return the number of bytes written (negative on error)"
       
   129 
       
   130 %{
       
   131     unsigned char *extPtr;
       
   132     int nWritten = -1;
       
   133     INT fd = (INT)(__externalAddressVal(self));
       
   134     INT cnt, offs;
       
   135     int nInstBytes, objSize;
       
   136 #include <errno.h>
       
   137     if (! __bothSmallInteger(count, firstIndex)) {
       
   138         goto bad;
       
   139     }
       
   140     cnt = __smallIntegerVal(count);
       
   141     offs = __smallIntegerVal(firstIndex) - 1;
       
   142 
       
   143     if (fd < 0) {
       
   144         goto bad;
       
   145     }
       
   146     if (__isExternalBytes(aByteBuffer)) {
       
   147         OBJ sz;
       
   148 
       
   149         nInstBytes = 0;
       
   150         extPtr = (char *)(__externalBytesAddress(aByteBuffer));
       
   151         sz = __externalBytesSize(aByteBuffer);
       
   152         if (__isSmallInteger(sz)) {
       
   153             objSize = __smallIntegerVal(sz);
       
   154         } else {
       
   155             objSize = -1; /* unknown */
       
   156         }
       
   157     } else {
       
   158         OBJ oClass;
       
   159         int nInstVars;
       
   160 
       
   161         oClass = __Class(aByteBuffer);
       
   162         switch (__smallIntegerVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
       
   163             case BYTEARRAY:
       
   164             case WORDARRAY:
       
   165             case LONGARRAY:
       
   166             case SWORDARRAY:
       
   167             case SLONGARRAY:
       
   168             case FLOATARRAY:
       
   169             case DOUBLEARRAY:
       
   170                 break;
       
   171             default:
       
   172                 goto bad;
       
   173         }
       
   174         extPtr = (char *)0;
       
   175         nInstVars = __smallIntegerVal(__ClassInstPtr(oClass)->c_ninstvars);
       
   176         nInstBytes = __OBJS2BYTES__(nInstVars);
       
   177         objSize = __Size(aByteBuffer) - OHDR_SIZE - nInstBytes;
       
   178     }
       
   179     if ((offs >= 0)
       
   180      && (cnt >= 0)
       
   181      && ((objSize == -1) || (objSize >= (cnt + offs)))) {
       
   182         nWritten = 0;
       
   183 
       
   184         do {
       
   185             int n;
       
   186 
       
   187             if (extPtr) {
       
   188                 n = write(fd, extPtr+offs, cnt);
       
   189             } else {
       
   190                 char *bp;
       
   191 
       
   192                 /*
       
   193                  * on interrupt, anObject may be moved to another location.
       
   194                  * So we recompute the byte-address here.
       
   195                  */
       
   196                 bp = __ByteArrayInstPtr(aByteBuffer)->ba_element + nInstBytes;
       
   197 
       
   198                 n = write(fd, bp + offs, cnt);
       
   199             }
       
   200             if (n > 0) {
       
   201                 cnt -= n;
       
   202                 offs += n;
       
   203                 nWritten += n;
       
   204             } else {
       
   205                 if (n < 0) {
       
   206                     if (errno == EINTR) {
       
   207                         continue;
       
   208                     }
       
   209                     break;
       
   210                 }
       
   211             }
       
   212         } while (cnt > 0);
       
   213 
       
   214         RETURN (__mkSmallInteger(nWritten));
       
   215     }
       
   216 bad: ;   
       
   217 %}.
       
   218     ^ self primitiveFailed
       
   219 
       
   220     "
       
   221      |h buff n|
       
   222 
       
   223      h := self basicNew.
       
   224      h setFileDescriptor:1.
       
   225      buff := '12345678901234567890'.
       
   226      n := h writeBytes:10 from:buff startingAt:1.
       
   227     "
       
   228 
       
   229 
       
   230 ! !
       
   231 
       
   232 !UnixFileDescriptorHandle methodsFor:'private accessing'!
       
   233 
       
   234 setFileDescriptor:anInteger
       
   235 
       
   236 %{
       
   237     if (__isSmallInteger(anInteger)) {
       
   238         __externalAddressVal(self) = (OBJ)(__smallIntegerVal(anInteger));
       
   239     }
       
   240 %}
       
   241 
       
   242 
       
   243 ! !
       
   244 
    18 !UnixFileDescriptorHandle methodsFor:'release'!
   245 !UnixFileDescriptorHandle methodsFor:'release'!
    19 
   246 
    20 closeFile
   247 closeFile
    21     "close the underlying file"
   248     "close the underlying file"
    22 
   249 
    32 ! !
   259 ! !
    33 
   260 
    34 !UnixFileDescriptorHandle class methodsFor:'documentation'!
   261 !UnixFileDescriptorHandle class methodsFor:'documentation'!
    35 
   262 
    36 version
   263 version
    37     ^ '$Header: /cvs/stx/stx/libbasic/UnixFileDescriptorHandle.st,v 1.3 2000-06-23 19:43:40 cg Exp $'
   264     ^ '$Header: /cvs/stx/stx/libbasic/UnixFileDescriptorHandle.st,v 1.4 2000-06-24 10:45:31 cg Exp $'
    38 ! !
   265 ! !