215 #else |
217 #else |
216 # define OPT_FSEEK(f, pos, whence) /* nothing */ |
218 # define OPT_FSEEK(f, pos, whence) /* nothing */ |
217 #endif |
219 #endif |
218 |
220 |
219 #ifdef WIN32 |
221 #ifdef WIN32 |
220 # ifdef __BORLANDC__ |
222 # define READ(ret, f, cp, n, handleType) { \ |
221 int _rtl_read(); |
223 if (handleType == @symbol(socketHandle)) { \ |
222 int _rtl_write(); |
224 (ret) = __STX_WSA_NOINT_CALL4("recv", recv, (f), (cp), (n), 0); \ |
223 |
|
224 # define READ(ret,f, cp, n, handleType) \ |
|
225 { int __res;\ |
|
226 HANDLE h; \ |
|
227 h = _get_osfhandle(fileno(f)); \ |
|
228 if ((handleType == @symbol(socketFilePointer)) \ |
|
229 || ((handleType == nil) && (ioctlsocket((SOCKET)h,FIONREAD,&__res)==0))) { \ |
|
230 (ret) = __STX_WSA_NOINT_CALL4("recv", recv, h, (cp), (n), 0);\ |
|
231 } else { \ |
225 } else { \ |
232 (ret) = __STX_C_NOINT_CALL3("_rtl_read", _rtl_read, fileno(f), (cp), (n));\ |
226 HANDLE h = _get_osfhandle(fileno(f)); \ |
233 } \ |
227 if (handleType == @symbol(socketFilePointer)) { \ |
234 } |
|
235 |
|
236 # define WRITE(ret,f, cp, n, handleType) \ |
|
237 { int __res;\ |
|
238 HANDLE h; \ |
|
239 h = _get_osfhandle(fileno(f)); \ |
|
240 if ((handleType == @symbol(socketFilePointer)) \ |
|
241 || ((handleType == nil) && (ioctlsocket((SOCKET)h,FIONREAD,&__res)==0))) { \ |
|
242 (ret) = __STX_WSA_NOINT_CALL4("send", send, h, (cp), (n), 0);\ |
|
243 } else { \ |
|
244 (ret) = __STX_C_NOINT_CALL3("_rtl_write", _rtl_write, fileno(f), (cp), (n));\ |
|
245 } \ |
|
246 } |
|
247 |
|
248 # else /* MSC */ |
|
249 |
|
250 # define READ(ret,f, cp, n, handleType) \ |
|
251 { int __res;\ |
|
252 int fd; \ |
|
253 HANDLE h; \ |
|
254 fd = fileno(f); \ |
|
255 if ((handleType == @symbol(socketFileDescriptor)) \ |
|
256 || ((handleType == nil) && (ioctlsocket((SOCKET)fd,FIONREAD,&__res)==0))) { \ |
|
257 (ret) = __STX_WSA_NOINT_CALL4("recv", recv, fd, (cp), (n), 0);\ |
|
258 } else { \ |
|
259 h = _get_osfhandle(fd); \ |
|
260 if ((handleType == @symbol(socketFilePointer)) \ |
|
261 || ((handleType == nil) && (ioctlsocket((SOCKET)h,FIONREAD,&__res)==0))) { \ |
|
262 (ret) = __STX_WSA_NOINT_CALL4("recv", recv, h, (cp), (n), 0);\ |
228 (ret) = __STX_WSA_NOINT_CALL4("recv", recv, h, (cp), (n), 0);\ |
263 } else { \ |
229 } else { \ |
|
230 int __res; \ |
264 (ret) = __STX_API_NOINT_CALL5("ReadFile", ReadFile, h, (cp), (n), &__res, 0);\ |
231 (ret) = __STX_API_NOINT_CALL5("ReadFile", ReadFile, h, (cp), (n), &__res, 0);\ |
265 if (ret) \ |
232 (ret) = (ret) ? __res : -1; \ |
266 ret = __res; \ |
|
267 } \ |
233 } \ |
268 } \ |
234 } \ |
269 } |
235 } |
270 # define WRITE(ret,f, cp, n, handleType) \ |
236 |
271 { int __res;\ |
237 # define WRITE(ret, f, cp, n, handleType) { \ |
272 int fd; \ |
238 if (handleType == @symbol(socketHandle)) { \ |
273 HANDLE h; \ |
239 (ret) = __STX_WSA_NOINT_CALL4("send", send, (f), (cp), (n), 0); \ |
274 fd = fileno(f); \ |
|
275 if ((handleType == @symbol(socketFileDescriptor)) \ |
|
276 || ((handleType == nil) && (ioctlsocket((SOCKET)fd,FIONREAD,&__res)==0))) { \ |
|
277 (ret) = __STX_WSA_NOINT_CALL4("send", send, fd, (cp), (n), 0);\ |
|
278 } else {\ |
240 } else {\ |
279 h = _get_osfhandle(fd); \ |
241 HANDLE h = _get_osfhandle(fileno(f)); \ |
280 if ((handleType == @symbol(socketFilePointer)) \ |
242 if (handleType == @symbol(socketFilePointer)) { \ |
281 || ((handleType == nil) && (ioctlsocket((SOCKET)h,FIONREAD,&__res)==0))) { \ |
|
282 (ret) = __STX_WSA_NOINT_CALL4("send", send, h, (cp), (n), 0);\ |
243 (ret) = __STX_WSA_NOINT_CALL4("send", send, h, (cp), (n), 0);\ |
283 } else {\ |
244 } else {\ |
|
245 int __res; \ |
284 (ret) = __STX_API_NOINT_CALL5("WriteFile", WriteFile, h, (cp), (n), &__res, 0);\ |
246 (ret) = __STX_API_NOINT_CALL5("WriteFile", WriteFile, h, (cp), (n), &__res, 0);\ |
285 if (ret) \ |
247 (ret) = (ret) ? __res : -1; \ |
286 ret = __res; \ |
|
287 } \ |
248 } \ |
288 } \ |
249 } \ |
289 } |
250 } |
290 # endif /* MSC */ |
|
291 |
251 |
292 # define FFLUSH(fp) fflush(fp) |
252 # define FFLUSH(fp) fflush(fp) |
293 # undef STDIO_NEEDS_FSEEK |
253 # undef STDIO_NEEDS_FSEEK |
294 # define FILEPOINTER FILE * |
254 # define FILEPOINTER FILE * |
295 # define FILENO(f) fileno(f) |
255 # define FILENO(f) fileno(f) |
430 OBJ rA = __INST(readAhead); \ |
390 OBJ rA = __INST(readAhead); \ |
431 if (rA != nil) { \ |
391 if (rA != nil) { \ |
432 (buf)[__offs] = __intVal(rA); \ |
392 (buf)[__offs] = __intVal(rA); \ |
433 __INST(readAhead) = nil; \ |
393 __INST(readAhead) = nil; \ |
434 (ret) = 1; \ |
394 (ret) = 1; \ |
435 __offs += (ret); \ |
395 __offs ++; \ |
436 continue; \ |
396 continue; \ |
437 } \ |
397 } \ |
438 CLEAR_ERRNO; \ |
398 CLEAR_ERRNO; \ |
439 { \ |
399 { \ |
440 int res; \ |
400 int res = 0; \ |
441 if ((handleType == @symbol(socketFilePointer)) \ |
401 if ((handleType == @symbol(socketFilePointer) && (ioctlsocket((SOCKET)_get_osfhandle(fileno(f)),FIONREAD,&res), 1)) \ |
442 || ((handleType == nil) && (ioctlsocket((SOCKET)_get_osfhandle(fileno(f)),FIONREAD,&res)==0))) { \ |
402 || (handleType == @symbol(socketHandle) && (ioctlsocket((SOCKET)(f), FIONREAD, &res), 1)) \ |
|
403 || (handleType == @symbol(pipeFilePointer) && (PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0, 0,0,&res,0)), 1)) { \ |
443 if (res > 0) { \ |
404 if (res > 0) { \ |
444 if (res > ((cnt)-__offs)) \ |
405 if (res > ((cnt)-__offs)) \ |
445 res = (cnt)-__offs; \ |
406 res = (cnt)-__offs; \ |
446 READ(ret,f, (buf)+__offs, res, handleType); \ |
407 READ(ret, f, (buf)+__offs, res, handleType); \ |
447 } else { \ |
408 } else { \ |
448 (ret) = 0; \ |
409 (ret) = 0; \ |
|
410 break; \ |
449 } \ |
411 } \ |
450 } else if ((handleType == @symbol(pipeFilePointer)) \ |
|
451 || ((handleType == nil) && (PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0, 0,0,&res,0)))) { \ |
|
452 if (res > 0) { \ |
|
453 if (res > ((cnt)-__offs)) \ |
|
454 res = (cnt)-__offs; \ |
|
455 READ(ret,f, (buf)+__offs, res, handleType); \ |
|
456 } else \ |
|
457 ret = 0; \ |
|
458 } else { \ |
412 } else { \ |
459 READ(ret,f, (buf)+__offs, (cnt)-__offs, handleType); \ |
413 READ(ret, f, (buf)+__offs, (cnt)-__offs, handleType); \ |
460 } \ |
414 } \ |
461 } \ |
415 } \ |
462 if ((ret) < 0) { \ |
416 if ((ret) < 0 && __threadErrno == EINTR) \ |
463 if (__threadErrno == EINTR) { \ |
417 continue; \ |
464 continue; \ |
|
465 } \ |
|
466 break; \ |
|
467 } \ |
|
468 __offs += (ret); \ |
418 __offs += (ret); \ |
469 break; \ |
|
470 } \ |
419 } \ |
471 if (__offs > 0) \ |
420 if (__offs > 0) \ |
472 (ret) = __offs; \ |
421 (ret) = __offs; \ |
473 } \ |
422 } \ |
474 } |
423 } |
575 OBJ rA = __INST(readAhead); \ |
524 OBJ rA = __INST(readAhead); \ |
576 if (rA != nil) { \ |
525 if (rA != nil) { \ |
577 (buf)[__ooffs+__offs] = __intVal(rA);\ |
526 (buf)[__ooffs+__offs] = __intVal(rA);\ |
578 __INST(readAhead) = nil; \ |
527 __INST(readAhead) = nil; \ |
579 (ret) = 1; \ |
528 (ret) = 1; \ |
580 __offs += (ret); \ |
529 __offs++; \ |
581 continue; \ |
530 continue; \ |
582 } \ |
531 } \ |
583 { \ |
532 { \ |
584 int l; \ |
533 int res = 0; \ |
585 int res; \ |
534 int l = (cnt)-__offs; \ |
586 CLEAR_ERRNO; \ |
535 CLEAR_ERRNO; \ |
587 l = (cnt)-__offs; \ |
536 if (l > IO_BUFFER_SIZE) \ |
588 if ( l > IO_BUFFER_SIZE) \ |
|
589 l = IO_BUFFER_SIZE; \ |
537 l = IO_BUFFER_SIZE; \ |
590 if (ioctlsocket((SOCKET)_get_osfhandle(fileno(f)),FIONREAD,&res)==0) { \ |
538 if ((handleType == @symbol(socketFilePointer) && (ioctlsocket((SOCKET)_get_osfhandle(fileno(f)), FIONREAD, &res), 1)) \ |
|
539 || (handleType == @symbol(socketHandle) && (ioctlsocket((SOCKET)(f), FIONREAD, &res), 1)) \ |
|
540 || (handleType == @symbol(pipeFilePointer) && (PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0,0,0,&res,0), 1))) { \ |
591 if (res > 0) { \ |
541 if (res > 0) { \ |
592 if (res > l) \ |
542 if (res > l) res = l; \ |
593 res = l; \ |
543 READ(ret, f, __buf, res, handleType); \ |
594 READ(ret,f, __buf, res, handleType); \ |
|
595 } else { \ |
544 } else { \ |
596 (ret) = 0; \ |
545 (ret) = 0; \ |
|
546 break; \ |
597 } \ |
547 } \ |
598 } else if (PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0, 0,0,&res,0)) { \ |
|
599 if (res > 0) { \ |
|
600 if (res > l) \ |
|
601 res = l; \ |
|
602 READ(ret,f, __buf, res, handleType); \ |
|
603 } else \ |
|
604 (ret) = 0; \ |
|
605 } else { \ |
548 } else { \ |
606 READ(ret,f, __buf, l, handleType); \ |
549 READ(ret, f, __buf, l, handleType); \ |
607 } \ |
550 } \ |
608 if ((ret) < 0 && __threadErrno == EINTR) { \ |
551 if ((ret) < 0 && __threadErrno == EINTR) \ |
609 continue; \ |
552 continue; \ |
610 } \ |
553 } \ |
611 } \ |
554 if ((ret) > 0) { \ |
612 if( (ret) > 0 ) { \ |
555 buf = (char *)(obj); \ |
613 /* refetch */ \ |
556 memcpy((buf)+__ooffs+__offs, __buf, (ret)); \ |
614 buf = (char *)(obj); \ |
557 __offs += (ret); \ |
615 memcpy((buf)+__ooffs+__offs,__buf,(ret)); \ |
558 } else { \ |
616 __offs += (ret); \ |
559 (ret) = 0; \ |
617 } else { \ |
560 } \ |
618 (ret) = 0; \ |
|
619 } \ |
|
620 break; \ |
|
621 } \ |
561 } \ |
622 if (__offs > 0) \ |
562 if (__offs > 0) \ |
623 (ret) = __offs; \ |
563 (ret) = __offs; \ |
624 } \ |
564 } \ |
625 } |
565 } |
1431 if the contents changed in the meantime. |
1371 if the contents changed in the meantime. |
1432 Therefore, it is a good idea to reopen files and check for these things at restart time. |
1372 Therefore, it is a good idea to reopen files and check for these things at restart time. |
1433 |
1373 |
1434 [Instance variables:] |
1374 [Instance variables:] |
1435 |
1375 |
1436 handleType <Symbol> desribes what handle is: |
1376 handleType <Symbol> desribes what handle is: |
1437 win32: #fileHandle, #socketHandle, |
1377 win32: #fileHandle, #socketHandle, |
1438 #socketFileDescriptor |
1378 #filePointer, #socketFilePointer, #pipeFilePointer |
1439 #filePointer, #socketFilePointer, #pipeFilePointer |
1379 unix: #filePointer, #socketFilePointer, #pipeFilePointer |
1440 unix: #filePointer, #socketFilePointer, #pipeFilePointer |
1380 needed for win32, which uses different APIs for the different handles (sigh) |
1441 needed for win32, which uses different APIs for the different handles (sigh) |
1381 handle <Integer> used to be always a filePointer somehow mapped to an integer (FILE* - not the fd); |
1442 handle <Integer> used to be always a filePointer somehow mapped to an integer (FILE* - not the fd); |
1382 now, either a filePointer or a handle (win32) |
1443 now, either a filePointer or a handle (win32) |
1383 mode <Symbol> #readwrite, #readonly or #writeonly |
1444 mode <Symbol> #readwrite, #readonly or #writeonly |
1384 buffered <Boolean> true, if buffered (i.e. collects characters - does |
1445 buffered <Boolean> true, if buffered (i.e. collects characters - does |
1385 not output immediately) |
1446 not output immediately) |
1386 binary <Boolean> true if in binary mode (reads bytes instead of chars) |
1447 binary <Boolean> true if in binary mode (reads bytes instead of chars) |
1387 eolMode <Symbol> one of nil, #cr or #crlf. |
1448 eolMode <Symbol> one of nil, #cr or #crlf. |
1388 determines how lines should be terminated. |
1449 determines how lines should be terminated. |
1389 nil -> newLine (as in Unix); |
1450 nil -> newLine (as in Unix); |
1390 #crlf -> with cr-lf (as in MSDOS) |
1451 #crlf -> with cr-lf (as in MSDOS) |
1391 #cr -> with cr (as in VMS) |
1452 #cr -> with cr (as in VMS) |
1392 hitEOF <Boolean> true, if EOF was reached |
1453 hitEOF <Boolean> true, if EOF was reached |
1393 |
1454 |
1394 lastErrorNumber <Integer> the value of errno (only valid right after the error - |
1455 lastErrorNumber <Integer> the value of errno (only valid right after the error - |
1395 updated with next i/o operation) |
1456 updated with next i/o operation) |
|
1457 |
1396 |
1458 [Class variables:] |
1397 [Class variables:] |
1459 Lobby <Registry> keeps track of used ext-streams (to free up FILE*'s) |
1398 Lobby <Registry> keeps track of used ext-streams (to free up FILE*'s) |
1460 |
1399 |
1461 StreamErrorSignal <Signal> parent of all stream errors (see Stream class) |
1400 StreamErrorSignal <Signal> parent of all stream errors (see Stream class) |
1462 InvalidReadSignal <Signal> raised on read from writeonly stream |
1401 InvalidReadSignal <Signal> raised on read from writeonly stream |
1463 InvalidWriteSignal <Signal> raised on write to readonly stream |
1402 InvalidWriteSignal <Signal> raised on write to readonly stream |
1464 InvalidModeSignal <Signal> raised on text I/O with binary-stream |
1403 InvalidModeSignal <Signal> raised on text I/O with binary-stream |
1465 or binary I/O with text-stream |
1404 or binary I/O with text-stream |
1466 OpenErrorSignal <Signal> raised if open fails |
1405 OpenErrorSignal <Signal> raised if open fails |
1467 StreamNotOpenSignal <Signal> raised on I/O with non-open stream |
1406 StreamNotOpenSignal <Signal> raised on I/O with non-open stream |
1468 |
1407 |
1469 Additional notes: |
1408 Additional notes: |
1470 This class is implemented using the underlying stdio-c library package, which |
1409 This class is implemented using the underlying stdio-c library package, which |
1471 has both advantages and disadvantages: since it is portable (posix defined), porting |
1410 has both advantages and disadvantages: since it is portable (posix defined), porting |
1472 ST/X to non-Unix machines is simplified. The disadvantage is that the stdio library |
1411 ST/X to non-Unix machines is simplified. The disadvantage is that the stdio library |
2126 fileHandle |
2064 fileHandle |
2127 "return the fileHandle of the receiver. |
2065 "return the fileHandle of the receiver. |
2128 Under unix, this is the fileDescriptor; under windows, this is the Handle." |
2066 Under unix, this is the fileDescriptor; under windows, this is the Handle." |
2129 |
2067 |
2130 %{ |
2068 %{ |
2131 OBJ fp; |
2069 OBJ _handle = __INST(handle); |
2132 |
2070 |
2133 if ((__INST(handleType) == nil) |
2071 if (_handle != nil) { |
2134 || (__INST(handleType) == @symbol(filePointer)) |
2072 if ((__INST(handleType) == @symbol(fileHandle)) |
2135 || (__INST(handleType) == @symbol(socketFilePointer)) |
2073 || (__INST(handleType) == @symbol(socketHandle))) { |
2136 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
2074 RETURN (_handle); |
2137 if ((fp = __INST(handle)) != nil) { |
2075 } else if ((__INST(handleType) == nil) |
2138 FILEPOINTER f; |
2076 || (__INST(handleType) == @symbol(filePointer)) |
2139 int fd; |
2077 || (__INST(handleType) == @symbol(socketFilePointer)) |
2140 |
2078 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
2141 f = __FILEVal(fp); |
|
2142 fd = fileno(f); |
|
2143 #ifdef WIN32 |
2079 #ifdef WIN32 |
2144 { |
2080 RETURN(__MKEXTERNALADDRESS(_get_osfhandle(fileno(__FILEVal(_handle))))); |
2145 HANDLE h; |
|
2146 h = _get_osfhandle(fd); |
|
2147 RETURN (__MKEXTERNALADDRESS(h)); |
|
2148 } |
|
2149 #else |
2081 #else |
2150 RETURN ( __MKINT(fileno(f)) ); |
2082 RETURN (__MKINT(fileno(__FILEVal(_handle)))); |
2151 #endif |
2083 #endif |
2152 } |
2084 } |
2153 } |
2085 } |
2154 #ifdef WIN32 |
|
2155 if ((__INST(handleType) == @symbol(fileHandle)) || (__INST(handleType) == @symbol(socketHandle))) { |
|
2156 RETURN (__INST(handle)); |
|
2157 } |
|
2158 #endif |
|
2159 %}. |
2086 %}. |
2160 handle isNil ifTrue:[^ self errorNotOpen]. |
2087 handle isNil ifTrue:[^ self errorNotOpen]. |
2161 ^ self fileHandleOfFile:handle |
2088 ^ handle |
2162 ! |
2089 ! |
2163 |
2090 |
2164 filePointer |
2091 filePointer |
2165 "return the filePointer of the receiver - |
2092 "return the filePointer of the receiver - |
2166 notice: for portability stdio is used; this means you will get |
2093 notice: for portability stdio is used; this means you will get |
2581 |
2512 |
2582 __INST(lastErrorNumber) = nil; |
2513 __INST(lastErrorNumber) = nil; |
2583 if ((__INST(handleType) == nil) |
2514 if ((__INST(handleType) == nil) |
2584 || (__INST(handleType) == @symbol(filePointer)) |
2515 || (__INST(handleType) == @symbol(filePointer)) |
2585 || (__INST(handleType) == @symbol(socketFilePointer)) |
2516 || (__INST(handleType) == @symbol(socketFilePointer)) |
|
2517 || (__INST(handleType) == @symbol(socketHandle)) |
2586 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
2518 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
2587 if (((fp = __INST(handle)) != nil) |
2519 if (((fp = __INST(handle)) != nil) |
2588 && (__INST(mode) != @symbol(writeonly)) |
2520 && (__INST(mode) != @symbol(writeonly)) |
2589 && (__INST(binary) != true) |
2521 && (__INST(binary) != true) |
2590 ) { |
2522 ) { |
2591 f = __FILEVal(fp); |
2523 f = __FILEVal(fp); |
2592 buffer[0] = '\0'; |
2524 buffer[0] = '\0'; |
2593 |
2525 |
2594 _buffered = (__INST(buffered) == true); |
2526 _buffered = (__INST(buffered) == true); |
2595 if (_buffered) { |
2527 if (_buffered) { |
2596 __READING__(f); |
2528 __READING__(f); |
2597 } |
2529 } |
2598 |
2530 |
2599 rslt = nextPtr = buffer; |
2531 rslt = nextPtr = buffer; |
2600 limit = buffer + sizeof(buffer) - 2; |
2532 limit = buffer + sizeof(buffer) - 2; |
2601 |
2533 |
2602 for (;;) { |
2534 for (;;) { |
2603 __READBYTE__(ret, f, nextPtr, _buffered, __INST(handleType)); |
2535 __READBYTE__(ret, f, nextPtr, _buffered, __INST(handleType)); |
2604 if (ret <= 0) { |
2536 if (ret <= 0) { |
2605 if (nextPtr == buffer) |
2537 if (nextPtr == buffer) |
2606 rslt = NULL; |
2538 rslt = NULL; |
2607 if (ret == 0) { |
2539 if (ret == 0) { |
2608 __INST(hitEOF) = true; |
2540 __INST(hitEOF) = true; |
2609 break; |
2541 break; |
2610 } else { |
2542 } else { |
2611 error = __mkSmallInteger(__threadErrno); |
2543 error = __mkSmallInteger(__threadErrno); |
2612 goto err; |
2544 goto err; |
2613 } |
2545 } |
2614 } |
2546 } |
2615 |
2547 |
2616 if (*nextPtr == '\n') { |
2548 if (*nextPtr == '\n') { |
2617 cutOff = 1; |
2549 cutOff = 1; |
2618 *nextPtr = '\0'; |
2550 *nextPtr = '\0'; |
2619 break; |
2551 break; |
2620 } |
2552 } |
2621 if (*nextPtr == '\r') { |
2553 if (*nextPtr == '\r') { |
2622 char peekChar; |
2554 char peekChar; |
2623 |
2555 |
2624 /* |
2556 /* |
2625 * peek ahead for a newLine ... |
2557 * peek ahead for a newLine ... |
2626 */ |
2558 */ |
2627 __READBYTE__(ret, f, &peekChar, _buffered, __INST(handleType)); |
2559 __READBYTE__(ret, f, &peekChar, _buffered, __INST(handleType)); |
2628 if (ret <= 0) { |
2560 if (ret <= 0) { |
2629 cutOff = 1; |
2561 cutOff = 1; |
2630 *nextPtr = '\0'; |
2562 *nextPtr = '\0'; |
2631 if (ret == 0) { |
2563 if (ret == 0) { |
2632 __INST(hitEOF) = true; |
2564 __INST(hitEOF) = true; |
2633 break; |
2565 break; |
2634 } |
2566 } |
2635 error = __mkSmallInteger(__threadErrno); |
2567 error = __mkSmallInteger(__threadErrno); |
2636 goto err; |
2568 goto err; |
2637 } |
2569 } |
2638 |
2570 |
2639 if (peekChar == '\n') { |
2571 if (peekChar == '\n') { |
2640 cutOff = 2; |
2572 cutOff = 2; |
2641 *nextPtr = '\0'; |
2573 *nextPtr = '\0'; |
2642 break; |
2574 break; |
2643 } |
2575 } |
2644 |
2576 |
2645 __UNGETC__(peekChar, f, _buffered); |
2577 __UNGETC__(peekChar, f, _buffered); |
2646 |
2578 |
2647 cutOff = 1; |
2579 cutOff = 1; |
2648 *nextPtr = '\0'; |
2580 *nextPtr = '\0'; |
2649 break; |
2581 break; |
2650 } |
2582 } |
2651 |
2583 |
2652 nextPtr++; |
2584 nextPtr++; |
2653 if (nextPtr >= limit) { |
2585 if (nextPtr >= limit) { |
2654 *nextPtr = '\0'; |
2586 *nextPtr = '\0'; |
2655 lineTooLong = 1; |
2587 lineTooLong = 1; |
2656 if (@global(InfoPrinting) == true) { |
2588 if (@global(InfoPrinting) == true) { |
2657 fprintf(stderr, "ExtStream [warning]: line truncated in nextLine\n"); |
2589 fprintf(stderr, "ExtStream [warning]: line truncated in nextLine\n"); |
2658 } |
2590 } |
2659 break; |
2591 break; |
2660 } |
2592 } |
2661 } |
2593 } |
2662 |
2594 |
2663 if (rslt != NULL) { |
2595 if (rslt != NULL) { |
2664 len = nextPtr-buffer; |
2596 len = nextPtr-buffer; |
2665 |
2597 |
2666 if (__isSmallInteger(__INST(position))) { |
2598 if (__isSmallInteger(__INST(position))) { |
2667 INT np = __intVal(__INST(position)) + len + cutOff; |
2599 INT np = __intVal(__INST(position)) + len + cutOff; |
2668 OBJ t; |
2600 OBJ t; |
2669 |
2601 |
2670 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
2602 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
2671 } else { |
2603 } else { |
2672 __INST(position) = nil; /* i.e. do not know */ |
2604 __INST(position) = nil; /* i.e. do not know */ |
2673 } |
2605 } |
2674 /* remove any EOL character */ |
2606 /* remove any EOL character */ |
2675 if (len != 0) { |
2607 if (len != 0) { |
2676 if (buffer[len-1] == '\n') { |
2608 if (buffer[len-1] == '\n') { |
2677 buffer[--len] = '\0'; |
2609 buffer[--len] = '\0'; |
2678 } |
2610 } |
2679 if ((len != 0) && (buffer[len-1] == '\r')) { |
2611 if ((len != 0) && (buffer[len-1] == '\r')) { |
2680 buffer[--len] = '\0'; |
2612 buffer[--len] = '\0'; |
2681 } |
2613 } |
2682 } |
2614 } |
2683 line = __MKSTRING_L(buffer, len); |
2615 line = __MKSTRING_L(buffer, len); |
2684 if (! lineTooLong) { |
2616 if (! lineTooLong) { |
2685 RETURN ( line ); |
2617 RETURN ( line ); |
2686 } |
2618 } |
2687 } |
2619 } |
2688 } |
2620 } |
2689 } |
2621 } |
2690 err: ; |
2622 err: ; |
2691 %}. |
2623 %}. |
2692 line notNil ifTrue:[ |
2624 line notNil ifTrue:[ |
2693 "/ the line as read is longer than 32k characters (boy - what a line) |
2625 "/ the line as read is longer than 32k characters (boy - what a line) |
2694 "/ The exception could be handled by reading more and returning the |
2626 "/ The exception could be handled by reading more and returning the |
2695 "/ concatenation in your exception handler (the receiver and the partial |
2627 "/ concatenation in your exception handler (the receiver and the partial |
2696 "/ line are passed as parameter) |
2628 "/ line are passed as parameter) |
2697 |
2629 |
2698 LineTooLongErrorSignal isHandled ifTrue:[ |
2630 LineTooLongErrorSignal isHandled ifTrue:[ |
2699 ^ LineTooLongErrorSignal |
2631 ^ LineTooLongErrorSignal |
2700 raiseRequestWith:(Array with:self with:line) |
2632 raiseRequestWith:(Array with:self with:line) |
2701 errorString:('line too long read error') |
2633 errorString:('line too long read error') |
2702 ]. |
2634 ]. |
2703 ^ line , self nextLine |
2635 ^ line , self nextLine |
2704 ]. |
2636 ]. |
2705 |
2637 |
2706 (hitEOF == true) ifTrue:[^ self pastEndRead]. |
2638 (hitEOF == true) ifTrue:[^ self pastEndRead]. |
2707 error notNil ifTrue:[ |
2639 error notNil ifTrue:[ |
2708 lastErrorNumber := error. |
2640 lastErrorNumber := error. |
2709 ^ self readError:error |
2641 ^ self readError:error |
2710 ]. |
2642 ]. |
2711 handle isNil ifTrue:[^ self errorNotOpen]. |
2643 handle isNil ifTrue:[^ self errorNotOpen]. |
2712 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
2644 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
2713 (binary == true) ifTrue:[^ self errorBinary]. |
2645 (binary == true) ifTrue:[^ self errorBinary]. |
2714 ^ super nextLine |
2646 ^ super nextLine |
2728 |
2660 |
2729 __INST(lastErrorNumber) = nil; |
2661 __INST(lastErrorNumber) = nil; |
2730 if ((__INST(handleType) == nil) |
2662 if ((__INST(handleType) == nil) |
2731 || (__INST(handleType) == @symbol(filePointer)) |
2663 || (__INST(handleType) == @symbol(filePointer)) |
2732 || (__INST(handleType) == @symbol(socketFilePointer)) |
2664 || (__INST(handleType) == @symbol(socketFilePointer)) |
|
2665 || (__INST(handleType) == @symbol(socketHandle)) |
2733 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
2666 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
2734 if (((fp = __INST(handle)) != nil) |
2667 if (((fp = __INST(handle)) != nil) |
2735 && (__INST(mode) != @symbol(readonly)) |
2668 && (__INST(mode) != @symbol(readonly)) |
2736 && (__INST(binary) != true) |
2669 && (__INST(binary) != true) |
2737 && __isStringLike(aString) |
2670 && __isStringLike(aString) |
2738 ) { |
2671 ) { |
2739 f = __FILEVal(fp); |
2672 f = __FILEVal(fp); |
2740 len = __stringSize(aString); |
2673 len = __stringSize(aString); |
2741 |
2674 |
2742 if (_buffered = (__INST(buffered) == true)) { |
2675 if (_buffered = (__INST(buffered) == true)) { |
2743 __WRITING__(f) |
2676 __WRITING__(f) |
2744 } |
2677 } |
2745 #ifdef WIN32 |
2678 #ifdef WIN32 |
2746 if ((f == __win32_stdout()) || (f == __win32_stderr())) { |
2679 if ((f == __win32_stdout()) || (f == __win32_stderr())) { |
2747 cnt = __win32_fwrite(__stringVal(aString), 1, len, f); |
2680 cnt = __win32_fwrite(__stringVal(aString), 1, len, f); |
2748 } else |
2681 } else |
2749 #endif |
2682 #endif |
2750 { |
2683 { |
2751 o_offs = (char *)__stringVal(aString)-(char *)aString; |
2684 o_offs = (char *)__stringVal(aString)-(char *)aString; |
2752 __WRITEBYTES_OBJ__(cnt, f, aString, o_offs, len, _buffered, __INST(handleType)); |
2685 __WRITEBYTES_OBJ__(cnt, f, aString, o_offs, len, _buffered, __INST(handleType)); |
2753 } |
2686 } |
2754 if (cnt == len) { |
2687 if (cnt == len) { |
2755 OBJ mode = __INST(eolMode); |
2688 OBJ mode = __INST(eolMode); |
2756 |
2689 |
2757 len1 = len; |
2690 len1 = len; |
2758 |
2691 |
2759 if (mode == @symbol(cr)) { |
2692 if (mode == @symbol(cr)) { |
2760 cp = "\r"; len = 1; |
2693 cp = "\r"; len = 1; |
2761 } else if (mode == @symbol(crlf)) { |
2694 } else if (mode == @symbol(crlf)) { |
2762 cp = "\r\n"; len = 2; |
2695 cp = "\r\n"; len = 2; |
2763 } else { |
2696 } else { |
2764 cp = "\n"; len = 1; |
2697 cp = "\n"; len = 1; |
2765 } |
2698 } |
2766 #ifdef WIN32 |
2699 #ifdef WIN32 |
2767 if ((f == __win32_stdout()) || (f == __win32_stderr())) { |
2700 if ((f == __win32_stdout()) || (f == __win32_stderr())) { |
2768 cnt = __win32_fwrite(cp, 1, len, f); |
2701 cnt = __win32_fwrite(cp, 1, len, f); |
2769 } else |
2702 } else |
2770 #endif |
2703 #endif |
2771 { |
2704 { |
2772 __WRITEBYTES__(cnt, f, cp, len, _buffered, __INST(handleType)); |
2705 __WRITEBYTES__(cnt, f, cp, len, _buffered, __INST(handleType)); |
2773 } |
2706 } |
2774 if (cnt > 0) { |
2707 if (cnt > 0) { |
2775 if (__isSmallInteger(__INST(position))) { |
2708 if (__isSmallInteger(__INST(position))) { |
2776 INT np = __intVal(__INST(position)) + cnt; |
2709 INT np = __intVal(__INST(position)) + cnt; |
2777 OBJ t; |
2710 OBJ t; |
2778 |
2711 |
2779 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
2712 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
2780 } else { |
2713 } else { |
2781 __INST(position) = nil; /* i.e. do not know */ |
2714 __INST(position) = nil; /* i.e. do not know */ |
2782 } |
2715 } |
2783 RETURN ( self ); |
2716 RETURN ( self ); |
2784 } |
2717 } |
2785 } |
2718 } |
2786 error = __mkSmallInteger(__threadErrno); |
2719 error = __mkSmallInteger(__threadErrno); |
2787 } |
2720 } |
2788 } |
2721 } |
2789 %}. |
2722 %}. |
2790 error notNil ifTrue:[ |
2723 error notNil ifTrue:[ |
2791 lastErrorNumber := error. |
2724 lastErrorNumber := error. |
2792 self writeError:error. |
2725 self writeError:error. |
2793 ^ self |
2726 ^ self |
2794 ]. |
2727 ]. |
2795 super nextPutLine:aString. |
2728 super nextPutLine:aString. |
2796 ! |
2729 ! |
2797 |
2730 |
2798 nextPutLinesFrom:aStream upToLineStartingWith:aStringOrNil |
2731 nextPutLinesFrom:aStream upToLineStartingWith:aStringOrNil |
2975 a pointer to the data is passed. |
2908 a pointer to the data is passed. |
2976 This allows performing most ioctls |
2909 This allows performing most ioctls |
2977 - however, it might be tricky to setup the buffer. |
2910 - however, it might be tricky to setup the buffer. |
2978 Be careful in what you pass - ST/X cannot validate its correctness." |
2911 Be careful in what you pass - ST/X cannot validate its correctness." |
2979 |
2912 |
|
2913 |error| |
|
2914 |
2980 %{ |
2915 %{ |
2981 #if !defined(MSDOS_LIKE) && !defined(__openVMS__) |
2916 #if !defined(MSDOS_LIKE) && !defined(__openVMS__) |
2982 FILEPOINTER f; |
2917 int fd; |
2983 int ret; |
2918 int ret; |
2984 unsigned int ioNum; |
2919 unsigned int ioNum; |
2985 OBJ fp; |
|
2986 INT ioArg; |
2920 INT ioArg; |
2987 |
2921 OBJ fp = __INST(handle); |
2988 __INST(lastErrorNumber) = nil; |
2922 |
2989 if ((__INST(handleType) == nil) |
2923 if (fp == nil) |
2990 || (__INST(handleType) == @symbol(filePointer)) |
2924 goto out; |
2991 || (__INST(handleType) == @symbol(socketFilePointer)) |
2925 |
2992 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
2926 if (!__isInteger(ioctlNumber) |
2993 if ((fp = __INST(handle)) != nil) { |
2927 || (!__isInteger(arg) |
2994 if (__isInteger(ioctlNumber) |
2928 && (arg != nil) |
2995 && (__isInteger(arg) |
2929 && !__isBytes(arg) |
2996 || (arg == nil) |
2930 && !__isExternalBytesLike(arg) |
2997 || __isBytes(arg) |
2931 && !__isExternalAddress(arg))) { |
2998 || __isExternalBytesLike(arg) |
2932 error = @symbol(badArgument); |
2999 || __isExternalAddress(arg))) { |
2933 goto out; |
3000 f = __FILEVal(fp); |
|
3001 ioNum = __unsignedLongIntVal(ioctlNumber); |
|
3002 |
|
3003 __BEGIN_INTERRUPTABLE__ |
|
3004 do { |
|
3005 __threadErrno = 0; |
|
3006 if (arg == nil) { |
|
3007 ioArg = 0; |
|
3008 } else if (__isSmallInteger(arg)) { |
|
3009 ioArg = __intVal(arg); |
|
3010 } else if (__isInteger(arg)) { |
|
3011 ioArg = __unsignedLongIntVal(arg); |
|
3012 } else if (__isExternalBytesLike(arg)) { |
|
3013 ioArg = (INT)(__externalBytesAddress(arg)); |
|
3014 } else if (__isExternalAddress(arg)) { |
|
3015 ioArg = (INT)(__externalAddressVal(arg)); |
|
3016 } else { |
|
3017 ioArg = (INT)(__ByteArrayInstPtr(arg)->ba_element); |
|
3018 } |
|
3019 ret = ioctl(fileno(f), ioNum, ioArg); |
|
3020 } while (ret < 0 && __threadErrno == EINTR); |
|
3021 __END_INTERRUPTABLE__ |
|
3022 |
|
3023 if (ret >= 0) { |
|
3024 RETURN ( __mkSmallInteger(ret) ); |
|
3025 } |
|
3026 __INST(position) = nil; /* i.e. do not know */ |
|
3027 __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno); |
|
3028 } |
|
3029 } |
|
3030 } |
2934 } |
|
2935 |
|
2936 if (__INST(handleType) == @symbol(socketHandle)) { |
|
2937 fd = __FILEVal(fp); |
|
2938 } else if ((__INST(handleType) == nil) |
|
2939 || (__INST(handleType) == @symbol(filePointer)) |
|
2940 || (__INST(handleType) == @symbol(socketFilePointer)) |
|
2941 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
|
2942 fd = fileno(__FILEVal(fp)); |
|
2943 } else { |
|
2944 error = @symbol(badHandleType); |
|
2945 goto out; |
|
2946 } |
|
2947 |
|
2948 ioNum = __unsignedLongIntVal(ioctlNumber); |
|
2949 |
|
2950 __BEGIN_INTERRUPTABLE__ |
|
2951 do { |
|
2952 __threadErrno = 0; |
|
2953 if (arg == nil) { |
|
2954 ioArg = 0; |
|
2955 } else if (__isSmallInteger(arg)) { |
|
2956 ioArg = __intVal(arg); |
|
2957 } else if (__isInteger(arg)) { |
|
2958 ioArg = __unsignedLongIntVal(arg); |
|
2959 } else if (__isExternalBytesLike(arg)) { |
|
2960 ioArg = (INT)(__externalBytesAddress(arg)); |
|
2961 } else if (__isExternalAddress(arg)) { |
|
2962 ioArg = (INT)(__externalAddressVal(arg)); |
|
2963 } else { |
|
2964 ioArg = (INT)(__ByteArrayInstPtr(arg)->ba_element); |
|
2965 } |
|
2966 ret = ioctl(fd, ioNum, ioArg); |
|
2967 } while (ret < 0 && __threadErrno == EINTR); |
|
2968 __END_INTERRUPTABLE__ |
|
2969 |
|
2970 if (ret >= 0) { |
|
2971 RETURN ( __mkSmallInteger(ret) ); |
|
2972 } |
|
2973 error = __mkSmallInteger(__threadErrno); |
3031 #endif |
2974 #endif |
|
2975 |
|
2976 out:; |
3032 %}. |
2977 %}. |
3033 lastErrorNumber notNil ifTrue:[^ self ioError]. |
2978 error notNil ifTrue:[ |
|
2979 lastErrorNumber := error. |
|
2980 ^ self ioError:error. |
|
2981 ]. |
3034 handle isNil ifTrue:[^ self errorNotOpen]. |
2982 handle isNil ifTrue:[^ self errorNotOpen]. |
3035 " |
2983 |
3036 argument is not an integer |
2984 "/ the system does not support ioctl (MSDOS or VMS) |
3037 " |
|
3038 (ioctlNumber isMemberOf:SmallInteger) ifFalse:[^ self primitiveFailed]. |
|
3039 " |
|
3040 the system does not support ioctl (MSDOS or VMS) |
|
3041 " |
|
3042 ^ self errorUnsupportedOperation |
2985 ^ self errorUnsupportedOperation |
3043 ! |
2986 ! |
3044 |
2987 |
3045 reset |
2988 reset |
3046 "set the read position to the beginning of the collection" |
2989 "set the read position to the beginning of the collection" |
3061 |
3004 |
3062 self flush. |
3005 self flush. |
3063 |
3006 |
3064 %{ |
3007 %{ |
3065 #if !defined(__openVMS__) |
3008 #if !defined(__openVMS__) |
3066 FILEPOINTER f; |
3009 int fd; |
3067 int ret; |
3010 int ret; |
3068 OBJ fp; |
3011 OBJ fp = __INST(handle); |
3069 |
3012 |
3070 __INST(lastErrorNumber) = nil; |
3013 if (fp == nil) |
3071 if ((__INST(handleType) == nil) |
3014 goto out; |
3072 || (__INST(handleType) == @symbol(filePointer)) |
3015 |
3073 || (__INST(handleType) == @symbol(socketFilePointer)) |
3016 if (__INST(handleType) == @symbol(socketHandle)) { |
3074 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
3017 fd = __FILEVal(fp); |
3075 if ((fp = __INST(handle)) != nil) { |
3018 } else if ((__INST(handleType) == nil) |
3076 f = __FILEVal(fp); |
3019 || (__INST(handleType) == @symbol(filePointer)) |
|
3020 || (__INST(handleType) == @symbol(socketFilePointer)) |
|
3021 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
|
3022 fd = fileno(__FILEVal(fp)); |
|
3023 } else { |
|
3024 error = @symbol(badHandleType); |
|
3025 goto out; |
|
3026 } |
|
3027 |
3077 #ifdef WIN32 |
3028 #ifdef WIN32 |
3078 __threadErrno = 0; |
3029 __threadErrno = 0; |
3079 ret = __STX_API_NOINT_CALL1( "FlushFileBuffers", FlushFileBuffers, _get_osfhandle(fileno(f))); |
3030 ret = __STX_API_NOINT_CALL1( "FlushFileBuffers", FlushFileBuffers, _get_osfhandle(fd)); |
3080 if (ret) { |
3031 if (ret) { |
3081 RETURN (self); |
3032 RETURN (self); |
3082 } |
3033 } |
3083 #else |
3034 #else |
3084 |
3035 __BEGIN_INTERRUPTABLE__ |
3085 __BEGIN_INTERRUPTABLE__ |
3036 do { |
3086 do { |
3037 ret = fsync(fd); |
3087 ret = fsync(fileno(f)); |
3038 } while ((ret < 0) && (__threadErrno == EINTR)); |
3088 } while ((ret < 0) && (__threadErrno == EINTR)); |
3039 __END_INTERRUPTABLE__ |
3089 __END_INTERRUPTABLE__ |
3040 |
3090 |
3041 if (ret >= 0) { |
3091 if (ret >= 0) { |
3042 RETURN (self); |
3092 RETURN (self); |
3043 } |
3093 } |
|
3094 #endif /* ! WIN32 */ |
3044 #endif /* ! WIN32 */ |
3095 error = __mkSmallInteger(__threadErrno); |
3045 error = __mkSmallInteger(__threadErrno); |
3096 } |
|
3097 } |
|
3098 #endif /* ! __openVMS__ */ |
3046 #endif /* ! __openVMS__ */ |
|
3047 out:; |
3099 %}. |
3048 %}. |
3100 error notNil ifTrue:[ |
3049 error notNil ifTrue:[ |
3101 lastErrorNumber := error. |
3050 lastErrorNumber := error. |
3102 self ioError:error. |
3051 self ioError:error. |
3103 ^ self. |
3052 ^ self. |
3104 ]. |
3053 ]. |
3105 handle isNil ifTrue:[self errorNotOpen]. |
3054 handle isNil ifTrue:[self errorNotOpen]. |
3106 |
3055 |
3107 " |
3056 " |
3108 |f| |
3057 |f| |
3109 f := 'x' asFilename writeStream. |
3058 f := 'x' asFilename writeStream. |
3110 f nextPutAll:'hallo'; sync; syncData; close |
3059 f nextPutAll:'hallo'; sync; syncData; close |
3111 " |
3060 " |
3112 ! |
3061 ! |
3113 |
3062 |
3114 syncData |
3063 syncData |
3115 "make sure, that the OS writes cached data to the disk. |
3064 "make sure, that the OS writes cached data to the disk. |
3116 In this case, metadata is only written, if it is |
3065 In this case, metadata is only written, if it is |
3117 required to read the file's data (so metadata will not be written, |
3066 required to read the file's data (so metadata will not be written, |
3118 if only access/modification time has changed)." |
3067 if only access/modification time has changed)." |
3119 |
|
3120 |error| |
3068 |error| |
3121 |
3069 |
3122 self flush. |
3070 self flush. |
3123 |
3071 |
3124 %{ |
3072 %{ |
3125 #if defined(HAS_FDATASYNC) |
3073 #if !defined(__openVMS__) |
|
3074 int fd; |
3126 int ret; |
3075 int ret; |
3127 |
3076 OBJ fp = __INST(handle); |
3128 __INST(lastErrorNumber) = nil; |
3077 |
3129 if ((__INST(handleType) == nil) |
3078 if (fp == nil) |
3130 || (__INST(handleType) == @symbol(filePointer)) |
3079 goto out; |
3131 || (__INST(handleType) == @symbol(socketFilePointer)) |
3080 |
3132 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
3081 if (__INST(handleType) == @symbol(socketHandle)) { |
3133 OBJ fp; |
3082 fd = __FILEVal(fp); |
3134 FILEPOINTER f; |
3083 } else if ((__INST(handleType) == nil) |
3135 |
3084 || (__INST(handleType) == @symbol(filePointer)) |
3136 if ((fp = __INST(handle)) != nil) { |
3085 || (__INST(handleType) == @symbol(socketFilePointer)) |
3137 f = __FILEVal(fp); |
3086 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
|
3087 fd = fileno(__FILEVal(fp)); |
|
3088 } else { |
|
3089 error = @symbol(badHandleType); |
|
3090 goto out; |
|
3091 } |
|
3092 |
3138 #ifdef WIN32 |
3093 #ifdef WIN32 |
3139 __threadErrno = 0; |
3094 __threadErrno = 0; |
3140 ret = __STX_API_NOINT_CALL1( "FlushFileBuffers", FlushFileBuffers, _get_osfhandle(fileno(f))); |
3095 ret = __STX_API_NOINT_CALL1( "FlushFileBuffers", FlushFileBuffers, _get_osfhandle(fd)); |
3141 if (ret) { |
3096 if (ret) { |
3142 RETURN (self); |
3097 RETURN (self); |
3143 } |
3098 } |
3144 #else |
3099 #else |
3145 |
3100 __BEGIN_INTERRUPTABLE__ |
3146 __BEGIN_INTERRUPTABLE__ |
3101 do { |
3147 do { |
3102 ret = fdatasync(fd); |
3148 ret = fdatasync(fileno(f)); |
3103 } while ((ret < 0) && (__threadErrno == EINTR)); |
3149 } while ((ret < 0) && (__threadErrno == EINTR)); |
3104 __END_INTERRUPTABLE__ |
3150 __END_INTERRUPTABLE__ |
3105 |
3151 |
3106 if (ret >= 0) { |
3152 if (ret >= 0) { |
3107 RETURN (self); |
3153 RETURN (self); |
3108 } |
3154 } |
|
3155 #endif /* ! WIN32 */ |
3109 #endif /* ! WIN32 */ |
3156 error = __mkSmallInteger(__threadErrno); |
3110 error = __mkSmallInteger(__threadErrno); |
3157 } |
|
3158 } |
|
3159 #endif /* ! __openVMS__ */ |
3111 #endif /* ! __openVMS__ */ |
|
3112 out:; |
3160 %}. |
3113 %}. |
|
3114 |
3161 error notNil ifTrue:[ |
3115 error notNil ifTrue:[ |
3162 lastErrorNumber := error. |
3116 lastErrorNumber := error. |
3163 self ioError:error. |
3117 self ioError:error. |
3164 ^ self. |
3118 ^ self. |
3165 ]. |
3119 ]. |
3166 handle isNil ifTrue:[^ self errorNotOpen]. |
3120 handle isNil ifTrue:[^ self errorNotOpen]. |
3167 |
3121 |
3168 "if notdef HAS_DATASYNC, fall back" |
3122 "if notdef HAS_DATASYNC, fall back" |
3169 self sync. |
3123 self sync. |
3170 |
3124 |
3171 " |
3125 " |
3172 |f| |
3126 |f| |
3173 f := 'x' asFilename writeStream. |
3127 f := 'x' asFilename writeStream. |
3174 f nextPutAll:'hallo'; sync; syncData; close |
3128 f nextPutAll:'hallo'; sync; syncData; close |
3175 " |
|
3176 ! |
|
3177 |
|
3178 truncateTo:newSize |
|
3179 "truncate the underlying OS file to newSize. |
|
3180 Warning: this may not be implemented on all platforms." |
|
3181 |
|
3182 %{ |
|
3183 #ifdef HAS_FTRUNCATE |
|
3184 FILEPOINTER f; |
|
3185 OBJ fp; |
|
3186 off_t truncateSize; |
|
3187 |
|
3188 if ((__INST(handleType) == nil) |
|
3189 || (__INST(handleType) == @symbol(filePointer)) |
|
3190 || (__INST(handleType) == @symbol(socketFilePointer)) |
|
3191 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
|
3192 if (((fp = __INST(handle)) != nil) |
|
3193 && (__INST(mode) != @symbol(readonly))) { |
|
3194 if (__isSmallInteger(newSize)) { |
|
3195 truncateSize = __intVal(newSize); |
|
3196 if (truncateSize < 0) { |
|
3197 goto getOutOfHere; |
|
3198 } |
|
3199 } else { |
|
3200 truncateSize = __signedLongIntVal(newSize); |
|
3201 if (truncateSize < 0) { |
|
3202 goto getOutOfHere; |
|
3203 } |
|
3204 if (truncateSize == 0) { |
|
3205 if (sizeof(truncateSize) == 8) { |
|
3206 if (__signedLong64IntVal(newSize, &truncateSize) == 0 || truncateSize < 0) { |
|
3207 goto getOutOfHere; |
|
3208 } |
|
3209 } else { |
|
3210 goto getOutOfHere; |
|
3211 } |
|
3212 } |
|
3213 } |
|
3214 |
|
3215 f = __FILEVal(fp); |
|
3216 |
|
3217 if (__INST(buffered) == true) { |
|
3218 __READING__(f) |
|
3219 #ifdef WIN32 |
|
3220 if ((dst == __win32_stdout()) || (dst == __win32_stderr())) { |
|
3221 win32_fflush(f); |
|
3222 } else |
|
3223 #endif |
|
3224 { |
|
3225 FFLUSH(f); |
|
3226 } |
|
3227 OPT_FSEEK(f, 0L, SEEK_END); /* needed in stdio */ |
|
3228 } |
|
3229 ftruncate(fileno(f), truncateSize); |
|
3230 RETURN (self); |
|
3231 } |
|
3232 } |
|
3233 getOutOfHere: ; |
|
3234 #endif |
|
3235 %}. |
|
3236 handle isNil ifTrue:[self errorNotOpen. ^ self]. |
|
3237 (mode == #readonly) ifTrue:[self errorReadOnly. ^ self]. |
|
3238 newSize < 0 ifTrue:[ |
|
3239 self error:'wrong arg'. |
|
3240 ]. |
|
3241 self errorUnsupportedOperation |
|
3242 |
|
3243 " |
|
3244 |s| |
|
3245 |
|
3246 s := 'test' asFilename writeStream. |
|
3247 s next:1000 put:$a. |
|
3248 s truncateTo:100. |
|
3249 s close. |
|
3250 |
|
3251 ('test' asFilename fileSize) printNL |
|
3252 " |
3129 " |
3253 ! ! |
3130 ! ! |
3254 |
3131 |
3255 !ExternalStream methodsFor:'non homogenous reading'! |
3132 !ExternalStream methodsFor:'non homogenous reading'! |
3256 |
3133 |
3351 |
3229 |
3352 __INST(lastErrorNumber) = nil; |
3230 __INST(lastErrorNumber) = nil; |
3353 if ((__INST(handleType) == nil) |
3231 if ((__INST(handleType) == nil) |
3354 || (__INST(handleType) == @symbol(filePointer)) |
3232 || (__INST(handleType) == @symbol(filePointer)) |
3355 || (__INST(handleType) == @symbol(socketFilePointer)) |
3233 || (__INST(handleType) == @symbol(socketFilePointer)) |
|
3234 || (__INST(handleType) == @symbol(socketHandle)) |
3356 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
3235 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
3357 if (((fp = __INST(handle)) != nil) |
3236 if (((fp = __INST(handle)) != nil) |
3358 && (__INST(mode) != @symbol(writeonly)) |
3237 && (__INST(mode) != @symbol(writeonly)) |
3359 && __bothSmallInteger(count, start) |
3238 && __bothSmallInteger(count, start) |
3360 ) { |
3239 ) { |
3361 f = __FILEVal(fp); |
3240 f = __FILEVal(fp); |
3362 |
3241 |
3363 cnt = __intVal(count); |
3242 cnt = __intVal(count); |
3364 offs = __intVal(start) - 1; |
3243 offs = __intVal(start) - 1; |
3365 |
3244 |
3366 if (__isExternalBytesLike(anObject)) { |
3245 if (__isExternalBytesLike(anObject)) { |
3367 OBJ sz; |
3246 OBJ sz; |
3368 |
3247 |
3369 nInstBytes = 0; |
3248 nInstBytes = 0; |
3370 extPtr = (char *)(__externalBytesAddress(anObject)); |
3249 extPtr = (char *)(__externalBytesAddress(anObject)); |
3371 if (extPtr == NULL) goto bad; |
3250 if (extPtr == NULL) goto bad; |
3372 sz = __externalBytesSize(anObject); |
3251 sz = __externalBytesSize(anObject); |
3373 if (__isSmallInteger(sz)) { |
3252 if (__isSmallInteger(sz)) { |
3374 objSize = __intVal(sz); |
3253 objSize = __intVal(sz); |
3375 } else { |
3254 } else { |
3376 objSize = 0; /* unknown */ |
3255 objSize = 0; /* unknown */ |
3377 } |
3256 } |
3378 } else { |
3257 } else { |
3379 OBJ oClass = __Class(anObject); |
3258 OBJ oClass = __Class(anObject); |
3380 int nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars); |
3259 int nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars); |
3381 |
3260 |
3382 nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars); |
3261 nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars); |
3383 |
3262 |
3384 switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) { |
3263 switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) { |
3385 case BYTEARRAY: |
3264 case BYTEARRAY: |
3386 case WORDARRAY: |
3265 case WORDARRAY: |
3387 case LONGARRAY: |
3266 case LONGARRAY: |
3388 case SWORDARRAY: |
3267 case SWORDARRAY: |
3389 case SLONGARRAY: |
3268 case SLONGARRAY: |
3390 case FLOATARRAY: |
3269 case FLOATARRAY: |
3391 break; |
3270 break; |
3392 case DOUBLEARRAY: |
3271 case DOUBLEARRAY: |
3393 #ifdef __NEED_DOUBLE_ALIGN |
3272 #ifdef __NEED_DOUBLE_ALIGN |
3394 nInstBytes = (nInstBytes-1+__DOUBLE_ALIGN) &~ (__DOUBLE_ALIGN-1); |
3273 nInstBytes = (nInstBytes-1+__DOUBLE_ALIGN) &~ (__DOUBLE_ALIGN-1); |
3395 #endif |
3274 #endif |
3396 break; |
3275 break; |
3397 case LONGLONGARRAY: |
3276 case LONGLONGARRAY: |
3398 case SLONGLONGARRAY: |
3277 case SLONGLONGARRAY: |
3399 #ifdef __NEED_LONGLONG_ALIGN |
3278 #ifdef __NEED_LONGLONG_ALIGN |
3400 nInstBytes = (nInstBytes-1+__LONGLONG_ALIGN) &~ (__LONGLONG_ALIGN-1); |
3279 nInstBytes = (nInstBytes-1+__LONGLONG_ALIGN) &~ (__LONGLONG_ALIGN-1); |
3401 #endif |
3280 #endif |
3402 break; |
3281 break; |
3403 default: |
3282 default: |
3404 goto bad; |
3283 goto bad; |
3405 } |
3284 } |
3406 extPtr = (char *)0; |
3285 extPtr = (char *)0; |
3407 objSize = __Size(anObject) - nInstBytes; |
3286 objSize = __Size(anObject) - nInstBytes; |
3408 } |
3287 } |
3409 |
3288 |
3410 if ((offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs))) { |
3289 if ((offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs))) { |
3411 _buffered = (__INST(buffered) == true); |
3290 _buffered = (__INST(buffered) == true); |
3412 if (_buffered) { |
3291 if (_buffered) { |
3413 __READING__(f); |
3292 __READING__(f); |
3414 } |
3293 } |
3415 |
3294 |
3416 if (extPtr) { |
3295 if (extPtr) { |
3417 __READAVAILBYTES__(ret, f, extPtr+offs, cnt, _buffered, __INST(handleType)); |
3296 __READAVAILBYTES__(ret, f, extPtr+offs, cnt, _buffered, __INST(handleType)); |
3418 } else { |
3297 } else { |
3419 /* |
3298 /* |
3420 * on interrupt, anObject may be moved to another location. |
3299 * on interrupt, anObject may be moved to another location. |
3421 * So we pass (char *)__InstPtr(anObject) + nInstBytes + offs to the macro __READ_BYTES__, |
3300 * So we pass (char *)__InstPtr(anObject) + nInstBytes + offs to the macro __READ_BYTES__, |
3422 * to get a new address. |
3301 * to get a new address. |
3423 */ |
3302 */ |
3424 offs += nInstBytes; |
3303 offs += nInstBytes; |
3425 __READAVAILBYTES_OBJ__(ret, f, anObject, offs, cnt, _buffered, __INST(handleType)); |
3304 __READAVAILBYTES_OBJ__(ret, f, anObject, offs, cnt, _buffered, __INST(handleType)); |
3426 } |
3305 } |
3427 /* 0 is NOT an EOF condition here ... */ |
3306 /* 0 is NOT an EOF condition here ... */ |
3428 if (ret >= 0) { |
3307 if (ret >= 0) { |
3429 if (__isSmallInteger(__INST(position))) { |
3308 if (__isSmallInteger(__INST(position))) { |
3430 INT np = __intVal(__INST(position)) + ret; |
3309 INT np = __intVal(__INST(position)) + ret; |
3431 OBJ t; |
3310 OBJ t; |
3432 |
3311 |
3433 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
3312 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
3434 } else { |
3313 } else { |
3435 __INST(position) = nil; /* i.e. do not know */ |
3314 __INST(position) = nil; /* i.e. do not know */ |
3436 } |
3315 } |
3437 RETURN (__mkSmallInteger(ret)); |
3316 RETURN (__mkSmallInteger(ret)); |
3438 } |
3317 } |
3439 __INST(position) = nil; |
3318 __INST(position) = nil; |
3440 error = __mkSmallInteger(__threadErrno); |
3319 error = __mkSmallInteger(__threadErrno); |
3441 } |
3320 } |
3442 } |
3321 } |
3443 } |
3322 } |
3444 bad: ; |
3323 bad: ; |
3445 %}. |
3324 %}. |
3446 (hitEOF and:[self pastEndRead isNil]) ifTrue:[^ 0]. |
3325 (hitEOF and:[self pastEndRead isNil]) ifTrue:[^ 0]. |
3447 error notNil ifTrue:[ |
3326 error notNil ifTrue:[ |
3448 lastErrorNumber := error. |
3327 lastErrorNumber := error. |
3449 ^ self readError:error |
3328 ^ self readError:error |
3450 ]. |
3329 ]. |
3451 handle isNil ifTrue:[^ self errorNotOpen]. |
3330 handle isNil ifTrue:[^ self errorNotOpen]. |
3452 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
3331 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
3453 " |
3332 " |
3454 count not integer or arg not bit-like (String, ByteArray etc) |
3333 count not integer or arg not bit-like (String, ByteArray etc) |
3470 |
3349 |
3471 __INST(lastErrorNumber) = nil; |
3350 __INST(lastErrorNumber) = nil; |
3472 if ((__INST(handleType) == nil) |
3351 if ((__INST(handleType) == nil) |
3473 || (__INST(handleType) == @symbol(filePointer)) |
3352 || (__INST(handleType) == @symbol(filePointer)) |
3474 || (__INST(handleType) == @symbol(socketFilePointer)) |
3353 || (__INST(handleType) == @symbol(socketFilePointer)) |
|
3354 || (__INST(handleType) == @symbol(socketHandle)) |
3475 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
3355 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
3476 if (((fp = __INST(handle)) != nil) |
3356 if (((fp = __INST(handle)) != nil) |
3477 && (__INST(mode) != @symbol(writeonly))) { |
3357 && (__INST(mode) != @symbol(writeonly))) { |
3478 f = __FILEVal(fp); |
3358 f = __FILEVal(fp); |
3479 |
3359 |
3480 _buffered = (__INST(buffered) == true); |
3360 _buffered = (__INST(buffered) == true); |
3481 if (_buffered) { |
3361 if (_buffered) { |
3482 __READING__(f) |
3362 __READING__(f) |
3483 } |
3363 } |
3484 __READBYTE__(ret, f, &byte, _buffered, __INST(handleType)); |
3364 __READBYTE__(ret, f, &byte, _buffered, __INST(handleType)); |
3485 if (ret > 0) { |
3365 if (ret > 0) { |
3486 if (__isSmallInteger(__INST(position))) { |
3366 if (__isSmallInteger(__INST(position))) { |
3487 INT np = __intVal(__INST(position)) + 1; |
3367 INT np = __intVal(__INST(position)) + 1; |
3488 OBJ t; |
3368 OBJ t; |
3489 |
3369 |
3490 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
3370 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
3491 } else { |
3371 } else { |
3492 __INST(position) = nil; /* i.e. do not know */ |
3372 __INST(position) = nil; /* i.e. do not know */ |
3493 } |
3373 } |
3494 RETURN (__mkSmallInteger(byte)); |
3374 RETURN (__mkSmallInteger(byte)); |
3495 } |
3375 } |
3496 |
3376 |
3497 if (ret == 0) { |
3377 if (ret == 0) { |
3498 __INST(hitEOF) = true; |
3378 __INST(hitEOF) = true; |
3499 } else /* ret < 0 */ { |
3379 } else /* ret < 0 */ { |
3500 __INST(position) = nil; |
3380 __INST(position) = nil; |
3501 error = __mkSmallInteger(__threadErrno); |
3381 error = __mkSmallInteger(__threadErrno); |
3502 } |
3382 } |
3503 } |
3383 } |
3504 } |
3384 } |
3505 %}. |
3385 %}. |
3506 hitEOF ifTrue:[^ self pastEndRead]. |
3386 hitEOF ifTrue:[^ self pastEndRead]. |
3507 error notNil ifTrue:[ |
3387 error notNil ifTrue:[ |
3508 lastErrorNumber := error. |
3388 lastErrorNumber := error. |
3509 ^ self readError:error |
3389 ^ self readError:error |
3510 ]. |
3390 ]. |
3511 handle isNil ifTrue:[^ self errorNotOpen]. |
3391 handle isNil ifTrue:[^ self errorNotOpen]. |
3512 ^ self errorWriteOnly |
3392 ^ self errorWriteOnly |
3513 ! |
3393 ! |
3514 |
3394 |
3547 |
3427 |
3548 __INST(lastErrorNumber) = nil; |
3428 __INST(lastErrorNumber) = nil; |
3549 if ((__INST(handleType) == nil) |
3429 if ((__INST(handleType) == nil) |
3550 || (__INST(handleType) == @symbol(filePointer)) |
3430 || (__INST(handleType) == @symbol(filePointer)) |
3551 || (__INST(handleType) == @symbol(socketFilePointer)) |
3431 || (__INST(handleType) == @symbol(socketFilePointer)) |
|
3432 || (__INST(handleType) == @symbol(socketHandle)) |
3552 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
3433 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
3553 if (((fp = __INST(handle)) != nil) |
3434 if (((fp = __INST(handle)) != nil) |
3554 && (__INST(mode) != @symbol(writeonly)) |
3435 && (__INST(mode) != @symbol(writeonly)) |
3555 && __bothSmallInteger(count, start) |
3436 && __bothSmallInteger(count, start) |
3556 ) { |
3437 ) { |
3557 f = __FILEVal(fp); |
3438 f = __FILEVal(fp); |
3558 |
3439 |
3559 cnt = __intVal(count); |
3440 cnt = __intVal(count); |
3560 offs = __intVal(start) - 1; |
3441 offs = __intVal(start) - 1; |
3561 |
3442 |
3562 if (__isExternalBytesLike(anObject)) { |
3443 if (__isExternalBytesLike(anObject)) { |
3563 OBJ sz; |
3444 OBJ sz; |
3564 |
3445 |
3565 nInstBytes = 0; |
3446 nInstBytes = 0; |
3566 extPtr = (char *)(__externalBytesAddress(anObject)); |
3447 extPtr = (char *)(__externalBytesAddress(anObject)); |
3567 if (extPtr == NULL) goto bad; |
3448 if (extPtr == NULL) goto bad; |
3568 sz = __externalBytesSize(anObject); |
3449 sz = __externalBytesSize(anObject); |
3569 if (__isSmallInteger(sz)) { |
3450 if (__isSmallInteger(sz)) { |
3570 objSize = __intVal(sz); |
3451 objSize = __intVal(sz); |
3571 } else { |
3452 } else { |
3572 objSize = 0; /* unknown */ |
3453 objSize = 0; /* unknown */ |
3573 } |
3454 } |
3574 } else { |
3455 } else { |
3575 OBJ oClass = __Class(anObject); |
3456 OBJ oClass = __Class(anObject); |
3576 int nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars); |
3457 int nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars); |
3577 |
3458 |
3578 nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars); |
3459 nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars); |
3579 switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) { |
3460 switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) { |
3580 case BYTEARRAY: |
3461 case BYTEARRAY: |
3581 case WORDARRAY: |
3462 case WORDARRAY: |
3582 case LONGARRAY: |
3463 case LONGARRAY: |
3583 case SWORDARRAY: |
3464 case SWORDARRAY: |
3584 case SLONGARRAY: |
3465 case SLONGARRAY: |
3585 case FLOATARRAY: |
3466 case FLOATARRAY: |
3586 break; |
3467 break; |
3587 case DOUBLEARRAY: |
3468 case DOUBLEARRAY: |
3588 #ifdef __NEED_DOUBLE_ALIGN |
3469 #ifdef __NEED_DOUBLE_ALIGN |
3589 nInstBytes = (nInstBytes-1+__DOUBLE_ALIGN) &~ (__DOUBLE_ALIGN-1); |
3470 nInstBytes = (nInstBytes-1+__DOUBLE_ALIGN) &~ (__DOUBLE_ALIGN-1); |
3590 #endif |
3471 #endif |
3591 break; |
3472 break; |
3592 case LONGLONGARRAY: |
3473 case LONGLONGARRAY: |
3593 case SLONGLONGARRAY: |
3474 case SLONGLONGARRAY: |
3594 #ifdef __NEED_LONGLONG_ALIGN |
3475 #ifdef __NEED_LONGLONG_ALIGN |
3595 nInstBytes = (nInstBytes-1+__LONGLONG_ALIGN) &~ (__LONGLONG_ALIGN-1); |
3476 nInstBytes = (nInstBytes-1+__LONGLONG_ALIGN) &~ (__LONGLONG_ALIGN-1); |
3596 #endif |
3477 #endif |
3597 break; |
3478 break; |
3598 default: |
3479 default: |
3599 goto bad; |
3480 goto bad; |
3600 } |
3481 } |
3601 extPtr = (char *)0; |
3482 extPtr = (char *)0; |
3602 objSize = __Size(anObject) - nInstBytes; |
3483 objSize = __Size(anObject) - nInstBytes; |
3603 } |
3484 } |
3604 if ((offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs))) { |
3485 if ((offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs))) { |
3605 _buffered = (__INST(buffered) == true); |
3486 _buffered = (__INST(buffered) == true); |
3606 if (_buffered) { |
3487 if (_buffered) { |
3607 __READING__(f); |
3488 __READING__(f); |
3608 } |
3489 } |
3609 |
3490 |
3610 if (extPtr) { |
3491 if (extPtr) { |
3611 __READBYTES__(ret, f, extPtr+offs, cnt, _buffered, __INST(handleType)); |
3492 __READBYTES__(ret, f, extPtr+offs, cnt, _buffered, __INST(handleType)); |
3612 } else { |
3493 } else { |
3613 /* |
3494 /* |
3614 * on interrupt, anObject may be moved to another location. |
3495 * on interrupt, anObject may be moved to another location. |
3615 * So we pass anObject, and the offset to the __READBYTES_OBJ__ macro. |
3496 * So we pass anObject, and the offset to the __READBYTES_OBJ__ macro. |
3616 */ |
3497 */ |
3617 offs += nInstBytes; |
3498 offs += nInstBytes; |
3618 __READBYTES_OBJ__(ret, f, anObject, offs, cnt, _buffered, __INST(handleType)); |
3499 __READBYTES_OBJ__(ret, f, anObject, offs, cnt, _buffered, __INST(handleType)); |
3619 } |
3500 } |
3620 |
3501 |
3621 if (ret > 0) { |
3502 if (ret > 0) { |
3622 if (__isSmallInteger(__INST(position))) { |
3503 if (__isSmallInteger(__INST(position))) { |
3623 INT np = __intVal(__INST(position)) + ret; |
3504 INT np = __intVal(__INST(position)) + ret; |
3624 OBJ t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
3505 OBJ t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
3625 } else { |
3506 } else { |
3626 __INST(position) = nil; /* i.e. do not know */ |
3507 __INST(position) = nil; /* i.e. do not know */ |
3627 } |
3508 } |
3628 RETURN (__mkSmallInteger(ret)); |
3509 RETURN (__mkSmallInteger(ret)); |
3629 } |
3510 } |
3630 if (ret == 0) { |
3511 if (ret == 0) { |
3631 __INST(hitEOF) = true; |
3512 __INST(hitEOF) = true; |
3632 } else /* ret < 0 */ { |
3513 } else /* ret < 0 */ { |
3633 __INST(position) = nil; |
3514 __INST(position) = nil; |
3634 error = __mkSmallInteger(__threadErrno); |
3515 error = __mkSmallInteger(__threadErrno); |
3635 } |
3516 } |
3636 } |
3517 } |
3637 } |
3518 } |
3638 } |
3519 } |
3639 bad: ; |
3520 bad: ; |
3640 %}. |
3521 %}. |
3641 (hitEOF and:[self pastEndRead isNil]) ifTrue:[^ 0]. |
3522 (hitEOF and:[self pastEndRead isNil]) ifTrue:[^ 0]. |
3642 error notNil ifTrue:[ |
3523 error notNil ifTrue:[ |
3643 lastErrorNumber := error. |
3524 lastErrorNumber := error. |
3644 ^ self readError:error |
3525 ^ self readError:error |
3645 ]. |
3526 ]. |
3646 handle isNil ifTrue:[^ self errorNotOpen]. |
3527 handle isNil ifTrue:[^ self errorNotOpen]. |
3647 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
3528 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
3648 " |
3529 " |
3649 count not integer or arg not bit-like (String, ByteArray etc) |
3530 count not integer or arg not bit-like (String, ByteArray etc) |
3673 |
3554 |
3674 __INST(lastErrorNumber) = nil; |
3555 __INST(lastErrorNumber) = nil; |
3675 if ((__INST(handleType) == nil) |
3556 if ((__INST(handleType) == nil) |
3676 || (__INST(handleType) == @symbol(filePointer)) |
3557 || (__INST(handleType) == @symbol(filePointer)) |
3677 || (__INST(handleType) == @symbol(socketFilePointer)) |
3558 || (__INST(handleType) == @symbol(socketFilePointer)) |
|
3559 || (__INST(handleType) == @symbol(socketHandle)) |
3678 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
3560 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
3679 if (((fp = __INST(handle)) != nil) |
3561 if (((fp = __INST(handle)) != nil) |
3680 && (__INST(mode) != @symbol(writeonly)) |
3562 && (__INST(mode) != @symbol(writeonly)) |
3681 ) { |
3563 ) { |
3682 FILEPOINTER f; |
3564 FILEPOINTER f; |
3683 int ret, _buffered; |
3565 int ret, _buffered; |
3684 int value; |
3566 int value; |
3685 union { |
3567 union { |
3686 unsigned char buffer[4]; |
3568 unsigned char buffer[4]; |
3687 int intVal; |
3569 int intVal; |
3688 } u; |
3570 } u; |
3689 |
3571 |
3690 f = __FILEVal(fp); |
3572 f = __FILEVal(fp); |
3691 _buffered = (__INST(buffered) == true); |
3573 _buffered = (__INST(buffered) == true); |
3692 if (_buffered) { |
3574 if (_buffered) { |
3693 __READING__(f) |
3575 __READING__(f) |
3694 } |
3576 } |
3695 __READBYTES__(ret, f, u.buffer, 4, _buffered, __INST(handleType)); |
3577 __READBYTES__(ret, f, u.buffer, 4, _buffered, __INST(handleType)); |
3696 |
3578 |
3697 if (ret == 4) { |
3579 if (ret == 4) { |
3698 if (__isSmallInteger(__INST(position))) { |
3580 if (__isSmallInteger(__INST(position))) { |
3699 INT np = __intVal(__INST(position)) + 4; |
3581 INT np = __intVal(__INST(position)) + 4; |
3700 OBJ t; |
3582 OBJ t; |
3701 |
3583 |
3702 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
3584 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
3703 } else { |
3585 } else { |
3704 __INST(position) = nil; /* i.e. do not know */ |
3586 __INST(position) = nil; /* i.e. do not know */ |
3705 } |
3587 } |
3706 if (msbFlag == true) { |
3588 if (msbFlag == true) { |
3707 #if defined(__MSBFIRST__) |
3589 #if defined(__MSBFIRST__) |
3708 value = u.intVal; |
3590 value = u.intVal; |
3709 #else |
3591 #else |
3710 value = (u.buffer[0] & 0xFF); |
3592 value = (u.buffer[0] & 0xFF); |
3711 value = (value << 8) | (u.buffer[1] & 0xFF); |
3593 value = (value << 8) | (u.buffer[1] & 0xFF); |
3712 value = (value << 8) | (u.buffer[2] & 0xFF); |
3594 value = (value << 8) | (u.buffer[2] & 0xFF); |
3713 value = (value << 8) | (u.buffer[3] & 0xFF); |
3595 value = (value << 8) | (u.buffer[3] & 0xFF); |
3714 #endif |
3596 #endif |
3715 } else { |
3597 } else { |
3716 #if defined(__LSBFIRST__) |
3598 #if defined(__LSBFIRST__) |
3717 value = u.intVal; |
3599 value = u.intVal; |
3718 #else |
3600 #else |
3719 value = (u.buffer[3] & 0xFF); |
3601 value = (u.buffer[3] & 0xFF); |
3720 value = (value << 8) | (u.buffer[2] & 0xFF); |
3602 value = (value << 8) | (u.buffer[2] & 0xFF); |
3721 value = (value << 8) | (u.buffer[1] & 0xFF); |
3603 value = (value << 8) | (u.buffer[1] & 0xFF); |
3722 value = (value << 8) | (u.buffer[0] & 0xFF); |
3604 value = (value << 8) | (u.buffer[0] & 0xFF); |
3723 #endif |
3605 #endif |
3724 } |
3606 } |
3725 #if __POINTER_SIZE__ == 8 |
3607 #if __POINTER_SIZE__ == 8 |
3726 RETURN ( __mkSmallInteger(value)); |
3608 RETURN ( __mkSmallInteger(value)); |
3727 #else |
3609 #else |
3728 if ((value >= _MIN_INT) && (value <= _MAX_INT)) { |
3610 if ((value >= _MIN_INT) && (value <= _MAX_INT)) { |
3729 RETURN ( __mkSmallInteger(value)); |
3611 RETURN ( __mkSmallInteger(value)); |
3730 } |
3612 } |
3731 RETURN ( __MKLARGEINT(value) ); |
3613 RETURN ( __MKLARGEINT(value) ); |
3732 #endif |
3614 #endif |
3733 } |
3615 } |
3734 |
3616 |
3735 if (ret < 0) { |
3617 if (ret < 0) { |
3736 __INST(position) = nil; |
3618 __INST(position) = nil; |
3737 error = __mkSmallInteger(__threadErrno); |
3619 error = __mkSmallInteger(__threadErrno); |
3738 } else /* ret == 0 */ { |
3620 } else /* ret == 0 */ { |
3739 __INST(hitEOF) = true; |
3621 __INST(hitEOF) = true; |
3740 } |
3622 } |
3741 } |
3623 } |
3742 } |
3624 } |
3743 %}. |
3625 %}. |
3744 hitEOF ifTrue:[^ self pastEndRead]. |
3626 hitEOF ifTrue:[^ self pastEndRead]. |
3745 handle isNil ifTrue:[^ self errorNotOpen]. |
3627 handle isNil ifTrue:[^ self errorNotOpen]. |
3746 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
3628 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
3761 |
3643 |
3762 __INST(lastErrorNumber) = nil; |
3644 __INST(lastErrorNumber) = nil; |
3763 if ((__INST(handleType) == nil) |
3645 if ((__INST(handleType) == nil) |
3764 || (__INST(handleType) == @symbol(filePointer)) |
3646 || (__INST(handleType) == @symbol(filePointer)) |
3765 || (__INST(handleType) == @symbol(socketFilePointer)) |
3647 || (__INST(handleType) == @symbol(socketFilePointer)) |
|
3648 || (__INST(handleType) == @symbol(socketHandle)) |
3766 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
3649 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
3767 if (((fp = __INST(handle)) != nil) |
3650 if (((fp = __INST(handle)) != nil) |
3768 && (__INST(mode) != @symbol(writeonly)) |
3651 && (__INST(mode) != @symbol(writeonly)) |
3769 ) { |
3652 ) { |
3770 FILEPOINTER f; |
3653 FILEPOINTER f; |
3771 int ret, _buffered; |
3654 int ret, _buffered; |
3772 short value; |
3655 short value; |
3773 union { |
3656 union { |
3774 unsigned char buffer[2]; |
3657 unsigned char buffer[2]; |
3775 short shortVal; |
3658 short shortVal; |
3776 } u; |
3659 } u; |
3777 |
3660 |
3778 f = __FILEVal(fp); |
3661 f = __FILEVal(fp); |
3779 _buffered = (__INST(buffered) == true); |
3662 _buffered = (__INST(buffered) == true); |
3780 if (_buffered) { |
3663 if (_buffered) { |
3781 __READING__(f) |
3664 __READING__(f) |
3782 } |
3665 } |
3783 __READBYTES__(ret, f, u.buffer, 2, _buffered, __INST(handleType)); |
3666 __READBYTES__(ret, f, u.buffer, 2, _buffered, __INST(handleType)); |
3784 |
3667 |
3785 if (ret == 2) { |
3668 if (ret == 2) { |
3786 if (__isSmallInteger(__INST(position))) { |
3669 if (__isSmallInteger(__INST(position))) { |
3787 INT np = __intVal(__INST(position)) + 2; |
3670 INT np = __intVal(__INST(position)) + 2; |
3788 OBJ t; |
3671 OBJ t; |
3789 |
3672 |
3790 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
3673 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
3791 } else { |
3674 } else { |
3792 __INST(position) = nil; /* i.e. do not know */ |
3675 __INST(position) = nil; /* i.e. do not know */ |
3793 } |
3676 } |
3794 if (msbFlag == true) { |
3677 if (msbFlag == true) { |
3795 #if defined(__MSBFIRST__) |
3678 #if defined(__MSBFIRST__) |
3796 value = u.shortVal; |
3679 value = u.shortVal; |
3797 #else |
3680 #else |
3798 value = ((u.buffer[0] & 0xFF) << 8) | (u.buffer[1] & 0xFF); |
3681 value = ((u.buffer[0] & 0xFF) << 8) | (u.buffer[1] & 0xFF); |
3799 #endif |
3682 #endif |
3800 } else { |
3683 } else { |
3801 #if defined(__LSBFIRST__) |
3684 #if defined(__LSBFIRST__) |
3802 value = u.shortVal; |
3685 value = u.shortVal; |
3803 #else |
3686 #else |
3804 value = ((u.buffer[1] & 0xFF) << 8) | (u.buffer[0] & 0xFF); |
3687 value = ((u.buffer[1] & 0xFF) << 8) | (u.buffer[0] & 0xFF); |
3805 #endif |
3688 #endif |
3806 } |
3689 } |
3807 RETURN (__mkSmallInteger(value)); |
3690 RETURN (__mkSmallInteger(value)); |
3808 } |
3691 } |
3809 |
3692 |
3810 if (ret < 0) { |
3693 if (ret < 0) { |
3811 __INST(position) = nil; /* i.e. do not know */ |
3694 __INST(position) = nil; /* i.e. do not know */ |
3812 error = __mkSmallInteger(__threadErrno); |
3695 error = __mkSmallInteger(__threadErrno); |
3813 } else /* ret == 0 */ { |
3696 } else /* ret == 0 */ { |
3814 __INST(hitEOF) = true; |
3697 __INST(hitEOF) = true; |
3815 } |
3698 } |
3816 } |
3699 } |
3817 } |
3700 } |
3818 %}. |
3701 %}. |
3819 hitEOF ifTrue:[^ self pastEndRead]. |
3702 hitEOF ifTrue:[^ self pastEndRead]. |
3820 handle isNil ifTrue:[^ self errorNotOpen]. |
3703 handle isNil ifTrue:[^ self errorNotOpen]. |
3821 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
3704 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
3837 |
3720 |
3838 __INST(lastErrorNumber) = nil; |
3721 __INST(lastErrorNumber) = nil; |
3839 if ((__INST(handleType) == nil) |
3722 if ((__INST(handleType) == nil) |
3840 || (__INST(handleType) == @symbol(filePointer)) |
3723 || (__INST(handleType) == @symbol(filePointer)) |
3841 || (__INST(handleType) == @symbol(socketFilePointer)) |
3724 || (__INST(handleType) == @symbol(socketFilePointer)) |
|
3725 || (__INST(handleType) == @symbol(socketHandle)) |
3842 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
3726 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
3843 if (((fp = __INST(handle)) != nil) |
3727 if (((fp = __INST(handle)) != nil) |
3844 && (__INST(mode) != @symbol(writeonly)) |
3728 && (__INST(mode) != @symbol(writeonly)) |
3845 ) { |
3729 ) { |
3846 FILEPOINTER f; |
3730 FILEPOINTER f; |
3847 int ret, _buffered; |
3731 int ret, _buffered; |
3848 unsigned INT value; |
3732 unsigned INT value; |
3849 union { |
3733 union { |
3850 unsigned char buffer[4]; |
3734 unsigned char buffer[4]; |
3851 unsigned int intVal; |
3735 unsigned int intVal; |
3852 } u; |
3736 } u; |
3853 |
3737 |
3854 f = __FILEVal(fp); |
3738 f = __FILEVal(fp); |
3855 _buffered = (__INST(buffered) == true); |
3739 _buffered = (__INST(buffered) == true); |
3856 if (_buffered) { |
3740 if (_buffered) { |
3857 __READING__(f) |
3741 __READING__(f) |
3858 } |
3742 } |
3859 __READBYTES__(ret, f, u.buffer, 4, _buffered, __INST(handleType)); |
3743 __READBYTES__(ret, f, u.buffer, 4, _buffered, __INST(handleType)); |
3860 |
3744 |
3861 if (ret == 4) { |
3745 if (ret == 4) { |
3862 if (__isSmallInteger(__INST(position))) { |
3746 if (__isSmallInteger(__INST(position))) { |
3863 INT np = __intVal(__INST(position)) + 4; |
3747 INT np = __intVal(__INST(position)) + 4; |
3864 OBJ t; |
3748 OBJ t; |
3865 |
3749 |
3866 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
3750 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
3867 } else { |
3751 } else { |
3868 __INST(position) = nil; /* i.e. do not know */ |
3752 __INST(position) = nil; /* i.e. do not know */ |
3869 } |
3753 } |
3870 if (msbFlag == true) { |
3754 if (msbFlag == true) { |
3871 #if defined(__MSBFIRST__) |
3755 #if defined(__MSBFIRST__) |
3872 value = u.intVal; |
3756 value = u.intVal; |
3873 #else |
3757 #else |
3874 value = u.buffer[0]; |
3758 value = u.buffer[0]; |
3875 value = (value << 8) | u.buffer[1]; |
3759 value = (value << 8) | u.buffer[1]; |
3876 value = (value << 8) | u.buffer[2]; |
3760 value = (value << 8) | u.buffer[2]; |
3877 value = (value << 8) | u.buffer[3]; |
3761 value = (value << 8) | u.buffer[3]; |
3878 #endif |
3762 #endif |
3879 } else { |
3763 } else { |
3880 #if defined(__LSBFIRST__) |
3764 #if defined(__LSBFIRST__) |
3881 value = u.intVal; |
3765 value = u.intVal; |
3882 #else |
3766 #else |
3883 value = u.buffer[3]; |
3767 value = u.buffer[3]; |
3884 value = (value << 8) | u.buffer[2]; |
3768 value = (value << 8) | u.buffer[2]; |
3885 value = (value << 8) | u.buffer[1]; |
3769 value = (value << 8) | u.buffer[1]; |
3886 value = (value << 8) | u.buffer[0]; |
3770 value = (value << 8) | u.buffer[0]; |
3887 #endif |
3771 #endif |
3888 } |
3772 } |
3889 #if __POINTER_SIZE__ == 8 |
3773 #if __POINTER_SIZE__ == 8 |
3890 value &= 0xFFFFFFFF; |
3774 value &= 0xFFFFFFFF; |
3891 RETURN (__mkSmallInteger(value)); |
3775 RETURN (__mkSmallInteger(value)); |
3892 #else |
3776 #else |
3893 if (value <= _MAX_INT) { |
3777 if (value <= _MAX_INT) { |
3894 RETURN (__mkSmallInteger(value)); |
3778 RETURN (__mkSmallInteger(value)); |
3895 } |
3779 } |
3896 RETURN (__MKULARGEINT(value) ); |
3780 RETURN (__MKULARGEINT(value) ); |
3897 #endif |
3781 #endif |
3898 } |
3782 } |
3899 |
3783 |
3900 if (ret < 0) { |
3784 if (ret < 0) { |
3901 __INST(position) = nil; /* i.e. do not know */ |
3785 __INST(position) = nil; /* i.e. do not know */ |
3902 error = __mkSmallInteger(__threadErrno); |
3786 error = __mkSmallInteger(__threadErrno); |
3903 } else /* ret == 0 */ { |
3787 } else /* ret == 0 */ { |
3904 __INST(hitEOF) = true; |
3788 __INST(hitEOF) = true; |
3905 } |
3789 } |
3906 } |
3790 } |
3907 } |
3791 } |
3908 %}. |
3792 %}. |
3909 hitEOF ifTrue:[^ self pastEndRead]. |
3793 hitEOF ifTrue:[^ self pastEndRead]. |
3910 handle isNil ifTrue:[^ self errorNotOpen]. |
3794 handle isNil ifTrue:[^ self errorNotOpen]. |
3911 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
3795 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
3926 |
3810 |
3927 __INST(lastErrorNumber) = nil; |
3811 __INST(lastErrorNumber) = nil; |
3928 if ((__INST(handleType) == nil) |
3812 if ((__INST(handleType) == nil) |
3929 || (__INST(handleType) == @symbol(filePointer)) |
3813 || (__INST(handleType) == @symbol(filePointer)) |
3930 || (__INST(handleType) == @symbol(socketFilePointer)) |
3814 || (__INST(handleType) == @symbol(socketFilePointer)) |
|
3815 || (__INST(handleType) == @symbol(socketHandle)) |
3931 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
3816 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
3932 if (((fp = __INST(handle)) != nil) |
3817 if (((fp = __INST(handle)) != nil) |
3933 && (__INST(mode) != @symbol(writeonly)) |
3818 && (__INST(mode) != @symbol(writeonly)) |
3934 ) { |
3819 ) { |
3935 FILEPOINTER f; |
3820 FILEPOINTER f; |
3936 int ret, _buffered; |
3821 int ret, _buffered; |
3937 unsigned int value; |
3822 unsigned int value; |
3938 union { |
3823 union { |
3939 unsigned char buffer[2]; |
3824 unsigned char buffer[2]; |
3940 unsigned short shortVal; |
3825 unsigned short shortVal; |
3941 } u; |
3826 } u; |
3942 |
3827 |
3943 f = __FILEVal(fp); |
3828 f = __FILEVal(fp); |
3944 _buffered = (__INST(buffered) == true); |
3829 _buffered = (__INST(buffered) == true); |
3945 if (_buffered) { |
3830 if (_buffered) { |
3946 __READING__(f) |
3831 __READING__(f) |
3947 } |
3832 } |
3948 __READBYTES__(ret, f, u.buffer, 2, _buffered, __INST(handleType)); |
3833 __READBYTES__(ret, f, u.buffer, 2, _buffered, __INST(handleType)); |
3949 |
3834 |
3950 if (ret == 2) { |
3835 if (ret == 2) { |
3951 if (__isSmallInteger(__INST(position))) { |
3836 if (__isSmallInteger(__INST(position))) { |
3952 INT np = __intVal(__INST(position)) + 2; |
3837 INT np = __intVal(__INST(position)) + 2; |
3953 OBJ t; |
3838 OBJ t; |
3954 |
3839 |
3955 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
3840 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
3956 } else { |
3841 } else { |
3957 __INST(position) = nil; /* i.e. do not know */ |
3842 __INST(position) = nil; /* i.e. do not know */ |
3958 } |
3843 } |
3959 if (msbFlag == true) { |
3844 if (msbFlag == true) { |
3960 #if defined(__MSBFIRST__) |
3845 #if defined(__MSBFIRST__) |
3961 value = u.shortVal; |
3846 value = u.shortVal; |
3962 #else |
3847 #else |
3963 value = (u.buffer[0] << 8) | u.buffer[1]; |
3848 value = (u.buffer[0] << 8) | u.buffer[1]; |
3964 #endif |
3849 #endif |
3965 } else { |
3850 } else { |
3966 #if defined(__LSBFIRST__) |
3851 #if defined(__LSBFIRST__) |
3967 value = u.shortVal; |
3852 value = u.shortVal; |
3968 #else |
3853 #else |
3969 value = (u.buffer[1] << 8) | u.buffer[0]; |
3854 value = (u.buffer[1] << 8) | u.buffer[0]; |
3970 #endif |
3855 #endif |
3971 } |
3856 } |
3972 RETURN (__mkSmallInteger(value)); |
3857 RETURN (__mkSmallInteger(value)); |
3973 } |
3858 } |
3974 |
3859 |
3975 if (ret < 0) { |
3860 if (ret < 0) { |
3976 __INST(position) = nil; /* i.e. do not know */ |
3861 __INST(position) = nil; /* i.e. do not know */ |
3977 error = __mkSmallInteger(__threadErrno); |
3862 error = __mkSmallInteger(__threadErrno); |
3978 } else /* ret == 0 */ { |
3863 } else /* ret == 0 */ { |
3979 __INST(hitEOF) = true; |
3864 __INST(hitEOF) = true; |
3980 } |
3865 } |
3981 } |
3866 } |
3982 } |
3867 } |
3983 %}. |
3868 %}. |
3984 hitEOF ifTrue:[^ self pastEndRead]. |
3869 hitEOF ifTrue:[^ self pastEndRead]. |
3985 handle isNil ifTrue:[^ self errorNotOpen]. |
3870 handle isNil ifTrue:[^ self errorNotOpen]. |
3986 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
3871 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
4020 |
3905 |
4021 __INST(lastErrorNumber) = nil; |
3906 __INST(lastErrorNumber) = nil; |
4022 if ((__INST(handleType) == nil) |
3907 if ((__INST(handleType) == nil) |
4023 || (__INST(handleType) == @symbol(filePointer)) |
3908 || (__INST(handleType) == @symbol(filePointer)) |
4024 || (__INST(handleType) == @symbol(socketFilePointer)) |
3909 || (__INST(handleType) == @symbol(socketFilePointer)) |
|
3910 || (__INST(handleType) == @symbol(socketHandle)) |
4025 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
3911 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
4026 if (((fp = __INST(handle)) != nil) |
3912 if (((fp = __INST(handle)) != nil) |
4027 && (__INST(mode) != @symbol(readonly)) |
3913 && (__INST(mode) != @symbol(readonly)) |
4028 && __isSmallInteger(aByteValue) |
3914 && __isSmallInteger(aByteValue) |
4029 |
3915 |
4030 ) { |
3916 ) { |
4031 c = __intVal(aByteValue); |
3917 c = __intVal(aByteValue); |
4032 f = __FILEVal(fp); |
3918 f = __FILEVal(fp); |
4033 if (_buffered = (__INST(buffered) == true)) { |
3919 if (_buffered = (__INST(buffered) == true)) { |
4034 __WRITING__(f) |
3920 __WRITING__(f) |
4035 } |
3921 } |
4036 #ifdef WIN32 |
3922 #ifdef WIN32 |
4037 if ((f == __win32_stdout()) || (f == __win32_stderr())) { |
3923 if ((f == __win32_stdout()) || (f == __win32_stderr())) { |
4038 cnt = __win32_fwrite(&c, 1, 1, f); |
3924 cnt = __win32_fwrite(&c, 1, 1, f); |
4039 } else |
3925 } else |
4040 #endif |
3926 #endif |
4041 { |
3927 { |
4042 __WRITEBYTE__(cnt, f, &c, _buffered, __INST(handleType)); |
3928 __WRITEBYTE__(cnt, f, &c, _buffered, __INST(handleType)); |
4043 } |
3929 } |
4044 if (cnt == 1) { |
3930 if (cnt == 1) { |
4045 if (__isSmallInteger(__INST(position))) { |
3931 if (__isSmallInteger(__INST(position))) { |
4046 INT np = __intVal(__INST(position)) + 1; |
3932 INT np = __intVal(__INST(position)) + 1; |
4047 OBJ t; |
3933 OBJ t; |
4048 |
3934 |
4049 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
3935 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
4050 } else { |
3936 } else { |
4051 __INST(position) = nil; /* i.e. do not know */ |
3937 __INST(position) = nil; /* i.e. do not know */ |
4052 } |
3938 } |
4053 RETURN (self); |
3939 RETURN (self); |
4054 } |
3940 } |
4055 if (cnt < 0) { |
3941 if (cnt < 0) { |
4056 __INST(position) = nil; /* i.e. do not know */ |
3942 __INST(position) = nil; /* i.e. do not know */ |
4057 } |
3943 } |
4058 error = __mkSmallInteger(__threadErrno); |
3944 error = __mkSmallInteger(__threadErrno); |
4059 } |
3945 } |
4060 } |
3946 } |
4061 %}. |
3947 %}. |
4062 handle isNil ifTrue:[self errorNotOpen. ^ self]. |
3948 handle isNil ifTrue:[self errorNotOpen. ^ self]. |
4063 (mode == #readonly) ifTrue:[self errorReadOnly. ^ self]. |
3949 (mode == #readonly) ifTrue:[self errorReadOnly. ^ self]. |
4064 lastErrorNumber := error. |
3950 lastErrorNumber := error. |
4089 |
3975 |
4090 __INST(lastErrorNumber) = nil; |
3976 __INST(lastErrorNumber) = nil; |
4091 if ((__INST(handleType) == nil) |
3977 if ((__INST(handleType) == nil) |
4092 || (__INST(handleType) == @symbol(filePointer)) |
3978 || (__INST(handleType) == @symbol(filePointer)) |
4093 || (__INST(handleType) == @symbol(socketFilePointer)) |
3979 || (__INST(handleType) == @symbol(socketFilePointer)) |
|
3980 || (__INST(handleType) == @symbol(socketHandle)) |
4094 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
3981 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
4095 if (((fp = __INST(handle)) != nil) |
3982 if (((fp = __INST(handle)) != nil) |
4096 && (__INST(mode) != @symbol(readonly)) |
3983 && (__INST(mode) != @symbol(readonly)) |
4097 && __bothSmallInteger(count, start) |
3984 && __bothSmallInteger(count, start) |
4098 ) { |
3985 ) { |
4099 len = __intVal(count); |
3986 len = __intVal(count); |
4100 offs = __intVal(start) - 1; |
3987 offs = __intVal(start) - 1; |
4101 f = __FILEVal(fp); |
3988 f = __FILEVal(fp); |
4102 |
3989 |
4103 if (__isExternalBytesLike(anObject)) { |
3990 if (__isExternalBytesLike(anObject)) { |
4104 OBJ sz; |
3991 OBJ sz; |
4105 |
3992 |
4106 nInstBytes = 0; |
3993 nInstBytes = 0; |
4107 extPtr = (char *)__externalBytesAddress(anObject); |
3994 extPtr = (char *)__externalBytesAddress(anObject); |
4108 if (extPtr == NULL) goto bad; |
3995 if (extPtr == NULL) goto bad; |
4109 sz = __externalBytesSize(anObject); |
3996 sz = __externalBytesSize(anObject); |
4110 if (__isSmallInteger(sz)) { |
3997 if (__isSmallInteger(sz)) { |
4111 objSize = __intVal(sz); |
3998 objSize = __intVal(sz); |
4112 } else { |
3999 } else { |
4113 objSize = 0; /* unknown */ |
4000 objSize = 0; /* unknown */ |
4114 } |
4001 } |
4115 } else { |
4002 } else { |
4116 OBJ oClass = __Class(anObject); |
4003 OBJ oClass = __Class(anObject); |
4117 int nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars); |
4004 int nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars); |
4118 |
4005 |
4119 nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars); |
4006 nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars); |
4120 switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) { |
4007 switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) { |
4121 case BYTEARRAY: |
4008 case BYTEARRAY: |
4122 case WORDARRAY: |
4009 case WORDARRAY: |
4123 case LONGARRAY: |
4010 case LONGARRAY: |
4124 case SWORDARRAY: |
4011 case SWORDARRAY: |
4125 case SLONGARRAY: |
4012 case SLONGARRAY: |
4126 case FLOATARRAY: |
4013 case FLOATARRAY: |
4127 break; |
4014 break; |
4128 case DOUBLEARRAY: |
4015 case DOUBLEARRAY: |
4129 #ifdef __NEED_DOUBLE_ALIGN |
4016 #ifdef __NEED_DOUBLE_ALIGN |
4130 nInstBytes = (nInstBytes-1+__DOUBLE_ALIGN) &~ (__DOUBLE_ALIGN-1); |
4017 nInstBytes = (nInstBytes-1+__DOUBLE_ALIGN) &~ (__DOUBLE_ALIGN-1); |
4131 #endif |
4018 #endif |
4132 break; |
4019 break; |
4133 case LONGLONGARRAY: |
4020 case LONGLONGARRAY: |
4134 case SLONGLONGARRAY: |
4021 case SLONGLONGARRAY: |
4135 #ifdef __NEED_LONGLONG_ALIGN |
4022 #ifdef __NEED_LONGLONG_ALIGN |
4136 nInstBytes = (nInstBytes-1+__LONGLONG_ALIGN) &~ (__LONGLONG_ALIGN-1); |
4023 nInstBytes = (nInstBytes-1+__LONGLONG_ALIGN) &~ (__LONGLONG_ALIGN-1); |
4137 #endif |
4024 #endif |
4138 break; |
4025 break; |
4139 default: |
4026 default: |
4140 goto bad; |
4027 goto bad; |
4141 } |
4028 } |
4142 extPtr = (char *)0; |
4029 extPtr = (char *)0; |
4143 objSize = __Size(anObject) - nInstBytes; |
4030 objSize = __Size(anObject) - nInstBytes; |
4144 } |
4031 } |
4145 if ( (offs >= 0) && (len >= 0) && (objSize >= (len + offs)) ) { |
4032 if ( (offs >= 0) && (len >= 0) && (objSize >= (len + offs)) ) { |
4146 if (_buffered = (__INST(buffered) == true)) { |
4033 if (_buffered = (__INST(buffered) == true)) { |
4147 __WRITING__(f) |
4034 __WRITING__(f) |
4148 } |
4035 } |
4149 |
4036 |
4150 if (extPtr) { |
4037 if (extPtr) { |
4151 __WRITEBYTES__(cnt, f, extPtr+offs, len, _buffered, __INST(handleType)); |
4038 __WRITEBYTES__(cnt, f, extPtr+offs, len, _buffered, __INST(handleType)); |
4152 } else { |
4039 } else { |
4153 /* |
4040 /* |
4154 * on interrupt, anObject may be moved to another location. |
4041 * on interrupt, anObject may be moved to another location. |
4155 * So we pass anObject, and the offset to the __WRITEBYTES_OBJ__ macro. |
4042 * So we pass anObject, and the offset to the __WRITEBYTES_OBJ__ macro. |
4156 */ |
4043 */ |
4157 offs += nInstBytes; |
4044 offs += nInstBytes; |
4158 __WRITEBYTES_OBJ__(cnt, f, anObject, offs, len, _buffered, __INST(handleType)); |
4045 __WRITEBYTES_OBJ__(cnt, f, anObject, offs, len, _buffered, __INST(handleType)); |
4159 } |
4046 } |
4160 |
4047 |
4161 if (cnt >= 0) { |
4048 if (cnt >= 0) { |
4162 if (__isSmallInteger(__INST(position))) { |
4049 if (__isSmallInteger(__INST(position))) { |
4163 INT np = __intVal(__INST(position)) + cnt; |
4050 INT np = __intVal(__INST(position)) + cnt; |
4164 OBJ t; |
4051 OBJ t; |
4165 |
4052 |
4166 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
4053 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
4167 } else { |
4054 } else { |
4168 __INST(position) = nil; /* i.e. do not know */ |
4055 __INST(position) = nil; /* i.e. do not know */ |
4169 } |
4056 } |
4170 RETURN ( __mkSmallInteger(cnt) ); |
4057 RETURN ( __mkSmallInteger(cnt) ); |
4171 } else /* cnt < 0 */ { |
4058 } else /* cnt < 0 */ { |
4172 if ( |
4059 if ( |
4173 #ifdef EWOULDBLOCK |
4060 #ifdef EWOULDBLOCK |
4174 (__threadErrno == EWOULDBLOCK) || |
4061 (__threadErrno == EWOULDBLOCK) || |
4175 #endif |
4062 #endif |
4176 (__threadErrno == EAGAIN) |
4063 (__threadErrno == EAGAIN) |
4177 ) { |
4064 ) { |
4178 RETURN ( __mkSmallInteger(0) ); |
4065 RETURN ( __mkSmallInteger(0) ); |
4179 } |
4066 } |
4180 __INST(position) = nil; /* i.e. do not know */ |
4067 __INST(position) = nil; /* i.e. do not know */ |
4181 error = __mkSmallInteger(__threadErrno); |
4068 error = __mkSmallInteger(__threadErrno); |
4182 } |
4069 } |
4183 } |
4070 } |
4184 } |
4071 } |
4185 } |
4072 } |
4186 bad: ; |
4073 bad: ; |
4187 %}. |
4074 %}. |
4188 error notNil ifTrue:[ |
4075 error notNil ifTrue:[ |
4189 lastErrorNumber := error. |
4076 lastErrorNumber := error. |
4190 self writeError:error. |
4077 self writeError:error. |
4191 ^ self |
4078 ^ self |
4192 ]. |
4079 ]. |
4193 handle isNil ifTrue:[^ self errorNotOpen]. |
4080 handle isNil ifTrue:[^ self errorNotOpen]. |
4194 (mode == #readonly) ifTrue:[^ self errorReadOnly]. |
4081 (mode == #readonly) ifTrue:[^ self errorReadOnly]. |
4195 ^ self primitiveFailed |
4082 ^ self primitiveFailed |
4196 ! |
4083 ! |
4204 |error| |
4091 |error| |
4205 |
4092 |
4206 %{ |
4093 %{ |
4207 int num; |
4094 int num; |
4208 union { |
4095 union { |
4209 char bytes[4]; |
4096 char bytes[4]; |
4210 int intVal; |
4097 int intVal; |
4211 } u; |
4098 } u; |
4212 FILEPOINTER f; |
4099 FILEPOINTER f; |
4213 int cnt, _buffered; |
4100 int cnt, _buffered; |
4214 OBJ fp; |
4101 OBJ fp; |
4215 |
4102 |
4216 __INST(lastErrorNumber) = nil; |
4103 __INST(lastErrorNumber) = nil; |
4217 if (__isSmallInteger(aNumber)) { |
4104 if (__isSmallInteger(aNumber)) { |
4218 num = __intVal(aNumber); |
4105 num = __intVal(aNumber); |
4219 } else { |
4106 } else { |
4220 #if __POINTER_SIZE__ == 8 |
4107 #if __POINTER_SIZE__ == 8 |
4221 goto badArg; |
4108 goto badArg; |
4222 #else |
4109 #else |
4223 num = __longIntVal(aNumber); |
4110 num = __longIntVal(aNumber); |
4224 if (num == 0) { |
4111 if (num == 0) { |
4225 num = __signedLongIntVal(aNumber); |
4112 num = __signedLongIntVal(aNumber); |
4226 if (num == 0) { |
4113 if (num == 0) { |
4227 /* bad arg or out-of-range integer |
4114 /* bad arg or out-of-range integer |
4228 * (handled by the fallBack code) |
4115 * (handled by the fallBack code) |
4229 */ |
4116 */ |
4230 goto badArg; |
4117 goto badArg; |
4231 } |
4118 } |
4232 } |
4119 } |
4233 #endif |
4120 #endif |
4234 } |
4121 } |
4235 |
4122 |
4236 if ((__INST(handleType) == nil) |
4123 if ((__INST(handleType) == nil) |
4237 || (__INST(handleType) == @symbol(filePointer)) |
4124 || (__INST(handleType) == @symbol(filePointer)) |
4238 || (__INST(handleType) == @symbol(socketFilePointer)) |
4125 || (__INST(handleType) == @symbol(socketFilePointer)) |
|
4126 || (__INST(handleType) == @symbol(socketHandle)) |
4239 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
4127 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
4240 if (((fp = __INST(handle)) != nil) |
4128 if (((fp = __INST(handle)) != nil) |
4241 && (__INST(mode) != @symbol(readonly)) |
4129 && (__INST(mode) != @symbol(readonly)) |
4242 ) { |
4130 ) { |
4243 if (msbFlag == true) { |
4131 if (msbFlag == true) { |
4244 #if defined(__MSBFIRST__) |
4132 #if defined(__MSBFIRST__) |
4245 u.intVal = num; |
4133 u.intVal = num; |
4246 #else |
4134 #else |
4247 u.bytes[0] = (num >> 24) & 0xFF; |
4135 u.bytes[0] = (num >> 24) & 0xFF; |
4248 u.bytes[1] = (num >> 16) & 0xFF; |
4136 u.bytes[1] = (num >> 16) & 0xFF; |
4249 u.bytes[2] = (num >> 8) & 0xFF; |
4137 u.bytes[2] = (num >> 8) & 0xFF; |
4250 u.bytes[3] = num & 0xFF; |
4138 u.bytes[3] = num & 0xFF; |
4251 #endif |
4139 #endif |
4252 } else { |
4140 } else { |
4253 #if defined(__LSBFIRST__) |
4141 #if defined(__LSBFIRST__) |
4254 u.intVal = num; |
4142 u.intVal = num; |
4255 #else |
4143 #else |
4256 u.bytes[3] = (num >> 24) & 0xFF; |
4144 u.bytes[3] = (num >> 24) & 0xFF; |
4257 u.bytes[2] = (num >> 16) & 0xFF; |
4145 u.bytes[2] = (num >> 16) & 0xFF; |
4258 u.bytes[1] = (num >> 8) & 0xFF; |
4146 u.bytes[1] = (num >> 8) & 0xFF; |
4259 u.bytes[0] = num & 0xFF; |
4147 u.bytes[0] = num & 0xFF; |
4260 #endif |
4148 #endif |
4261 } |
4149 } |
4262 |
4150 |
4263 f = __FILEVal(fp); |
4151 f = __FILEVal(fp); |
4264 if (_buffered = (__INST(buffered) == true)) { |
4152 if (_buffered = (__INST(buffered) == true)) { |
4265 __WRITING__(f) |
4153 __WRITING__(f) |
4266 } |
4154 } |
4267 __WRITEBYTES__(cnt, f, u.bytes, 4, _buffered, __INST(handleType)); |
4155 __WRITEBYTES__(cnt, f, u.bytes, 4, _buffered, __INST(handleType)); |
4268 |
4156 |
4269 if (cnt == 4) { |
4157 if (cnt == 4) { |
4270 if (__isSmallInteger(__INST(position))) { |
4158 if (__isSmallInteger(__INST(position))) { |
4271 INT np = __intVal(__INST(position)) + 4; |
4159 INT np = __intVal(__INST(position)) + 4; |
4272 OBJ t; |
4160 OBJ t; |
4273 |
4161 |
4274 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
4162 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
4275 } else { |
4163 } else { |
4276 __INST(position) = nil; /* i.e. do not know */ |
4164 __INST(position) = nil; /* i.e. do not know */ |
4277 } |
4165 } |
4278 RETURN ( self ); |
4166 RETURN ( self ); |
4279 } |
4167 } |
4280 __INST(position) = nil; /* i.e. do not know */ |
4168 __INST(position) = nil; /* i.e. do not know */ |
4281 error = __mkSmallInteger(__threadErrno); |
4169 error = __mkSmallInteger(__threadErrno); |
4282 } |
4170 } |
4283 } |
4171 } |
4284 badArg: ; |
4172 badArg: ; |
4285 %}. |
4173 %}. |
4286 handle isNil ifTrue:[self errorNotOpen. ^ self]. |
4174 handle isNil ifTrue:[self errorNotOpen. ^ self]. |
4287 (mode == #readonly) ifTrue:[self errorReadOnly. ^ self]. |
4175 (mode == #readonly) ifTrue:[self errorReadOnly. ^ self]. |
4288 error notNil ifTrue:[ |
4176 error notNil ifTrue:[ |
4289 lastErrorNumber := error. |
4177 lastErrorNumber := error. |
4290 self writeError:error. |
4178 self writeError:error. |
4291 ^ self |
4179 ^ self |
4292 ]. |
4180 ]. |
4293 |
4181 |
4294 aNumber isInteger ifTrue:[ |
4182 aNumber isInteger ifTrue:[ |
4295 ^ super nextPutLong:aNumber MSB:msbFlag |
4183 ^ super nextPutLong:aNumber MSB:msbFlag |
4296 ]. |
4184 ]. |
4297 self argumentMustBeInteger |
4185 self argumentMustBeInteger |
4298 ! |
4186 ! |
4299 |
4187 |
4300 nextPutShort:anIntegerOrCharacter MSB:msbFlag |
4188 nextPutShort:anIntegerOrCharacter MSB:msbFlag |
4305 |
4193 |
4306 |error| |
4194 |error| |
4307 %{ |
4195 %{ |
4308 int num; |
4196 int num; |
4309 union { |
4197 union { |
4310 char bytes[2]; |
4198 char bytes[2]; |
4311 short shortVal; |
4199 short shortVal; |
4312 } u; |
4200 } u; |
4313 |
4201 |
4314 FILEPOINTER f; |
4202 FILEPOINTER f; |
4315 int cnt, _buffered; |
4203 int cnt, _buffered; |
4316 OBJ fp; |
4204 OBJ fp; |
4317 |
4205 |
4318 __INST(lastErrorNumber) = nil; |
4206 __INST(lastErrorNumber) = nil; |
4319 if ((__INST(handleType) == nil) |
4207 if ((__INST(handleType) == nil) |
4320 || (__INST(handleType) == @symbol(filePointer)) |
4208 || (__INST(handleType) == @symbol(filePointer)) |
4321 || (__INST(handleType) == @symbol(socketFilePointer)) |
4209 || (__INST(handleType) == @symbol(socketFilePointer)) |
|
4210 || (__INST(handleType) == @symbol(socketHandle)) |
4322 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
4211 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
4323 if (((fp = __INST(handle)) != nil) |
4212 if (((fp = __INST(handle)) != nil) |
4324 && (__INST(mode) != @symbol(readonly)) |
4213 && (__INST(mode) != @symbol(readonly)) |
4325 ) { |
4214 ) { |
4326 if (__isSmallInteger(anIntegerOrCharacter)) { |
4215 if (__isSmallInteger(anIntegerOrCharacter)) { |
4327 num = __intVal(anIntegerOrCharacter); |
4216 num = __intVal(anIntegerOrCharacter); |
4328 } else if (__isCharacter(anIntegerOrCharacter)) { |
4217 } else if (__isCharacter(anIntegerOrCharacter)) { |
4329 num = __smallIntegerVal(__characterVal(anIntegerOrCharacter)); |
4218 num = __smallIntegerVal(__characterVal(anIntegerOrCharacter)); |
4330 } else |
4219 } else |
4331 goto out; |
4220 goto out; |
4332 |
4221 |
4333 if (msbFlag == true) { |
4222 if (msbFlag == true) { |
4334 #if defined(__MSBFIRST__) |
4223 #if defined(__MSBFIRST__) |
4335 u.shortVal = num; |
4224 u.shortVal = num; |
4336 #else |
4225 #else |
4337 u.bytes[0] = (num >> 8) & 0xFF; |
4226 u.bytes[0] = (num >> 8) & 0xFF; |
4338 u.bytes[1] = num & 0xFF; |
4227 u.bytes[1] = num & 0xFF; |
4339 #endif |
4228 #endif |
4340 } else { |
4229 } else { |
4341 #if defined(__LSBFIRST__) |
4230 #if defined(__LSBFIRST__) |
4342 u.shortVal = num; |
4231 u.shortVal = num; |
4343 #else |
4232 #else |
4344 u.bytes[1] = (num >> 8) & 0xFF; |
4233 u.bytes[1] = (num >> 8) & 0xFF; |
4345 u.bytes[0] = num & 0xFF; |
4234 u.bytes[0] = num & 0xFF; |
4346 #endif |
4235 #endif |
4347 } |
4236 } |
4348 |
4237 |
4349 f = __FILEVal(fp); |
4238 f = __FILEVal(fp); |
4350 if (_buffered = (__INST(buffered) == true)) { |
4239 if (_buffered = (__INST(buffered) == true)) { |
4351 __WRITING__(f) |
4240 __WRITING__(f) |
4352 } |
4241 } |
4353 __WRITEBYTES__(cnt, f, u.bytes, 2, _buffered, __INST(handleType)); |
4242 __WRITEBYTES__(cnt, f, u.bytes, 2, _buffered, __INST(handleType)); |
4354 |
4243 |
4355 if (cnt == 2) { |
4244 if (cnt == 2) { |
4356 if (__isSmallInteger(__INST(position))) { |
4245 if (__isSmallInteger(__INST(position))) { |
4357 INT np = __intVal(__INST(position)) + 2; |
4246 INT np = __intVal(__INST(position)) + 2; |
4358 OBJ t; |
4247 OBJ t; |
4359 |
4248 |
4360 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
4249 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
4361 } else { |
4250 } else { |
4362 __INST(position) = nil; /* i.e. do not know */ |
4251 __INST(position) = nil; /* i.e. do not know */ |
4363 } |
4252 } |
4364 RETURN ( self ); |
4253 RETURN ( self ); |
4365 } |
4254 } |
4366 __INST(position) = nil; /* i.e. do not know */ |
4255 __INST(position) = nil; /* i.e. do not know */ |
4367 error = __mkSmallInteger(__threadErrno); |
4256 error = __mkSmallInteger(__threadErrno); |
4368 } |
4257 } |
4369 } |
4258 } |
4370 out:; |
4259 out:; |
4371 %}. |
4260 %}. |
4372 error notNil ifTrue:[ |
4261 error notNil ifTrue:[ |
4373 lastErrorNumber := error. |
4262 lastErrorNumber := error. |
4374 self writeError:error. |
4263 self writeError:error. |
4375 ^ self |
4264 ^ self |
4376 ]. |
4265 ]. |
4377 handle isNil ifTrue:[self errorNotOpen. ^ self]. |
4266 handle isNil ifTrue:[self errorNotOpen. ^ self]. |
4378 (mode == #readonly) ifTrue:[self errorReadOnly. ^ self]. |
4267 (mode == #readonly) ifTrue:[self errorReadOnly. ^ self]. |
4379 self argumentMustBeInteger |
4268 self argumentMustBeInteger |
4380 ! ! |
4269 ! ! |
4411 "low level close - may be redefined in subclasses |
4300 "low level close - may be redefined in subclasses |
4412 Don't send this message, send #close instead" |
4301 Don't send this message, send #close instead" |
4413 |
4302 |
4414 |fp error| |
4303 |fp error| |
4415 |
4304 |
|
4305 fp := handle. |
|
4306 |
4416 %{ |
4307 %{ |
4417 if ((__INST(handleType) == nil) |
4308 int rslt; |
4418 || (__INST(handleType) == @symbol(filePointer)) |
4309 |
4419 || (__INST(handleType) == @symbol(socketFilePointer)) |
4310 if (fp == nil) { |
4420 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
4311 error = @symbol(errorNotOpen); |
4421 if ((fp = __INST(handle)) == nil) { |
4312 goto out; |
4422 error = @symbol(errorNotOpen); |
4313 } |
4423 } else { |
4314 |
4424 FILEPOINTER f = __FILEVal(fp); |
4315 if (__INST(handleType) == @symbol(socketHandle)) { |
4425 int rslt; |
4316 SOCKET sock = __FILEVal(fp); |
4426 |
4317 |
4427 // whether the fclose() will be successful or not - the handle is invalid now! |
4318 if (@global(FileOpenTrace) == true) { |
4428 __INST(handle) = nil; |
4319 fprintf(stderr, "close socket [ExternalStream] %"_lx_"\n", sock); |
4429 |
4320 } |
4430 if (@global(FileOpenTrace) == true) { |
4321 |
4431 fprintf(stderr, "fclose [ExternalStream] %"_lx_"\n", (INT)f); |
4322 // whether the close() will be successful or not - the handle is invalid now! |
4432 } |
4323 __INST(handle) = nil; |
|
4324 do { |
4433 #ifdef WIN32 |
4325 #ifdef WIN32 |
4434 if (__INST(mode) != @symbol(readonly) && __INST(buffered) != false) { |
4326 rslt = __STX_WSA_NOINT_CALL1("closesocket", closesocket, sock); |
4435 // do a fflush() first, so that fclose() doesn't block |
4327 #else |
4436 // we suspect, that EINTR causes problems in fclose() |
4328 rslt = close(sock); |
4437 do { |
4329 #endif |
4438 __threadErrno = 0; |
4330 } while((rslt < 0) && (__threadErrno == EINTR)); |
4439 rslt = __STX_C_CALL1("fflush", fflush, f); |
4331 } else if ((__INST(handleType) == nil) |
4440 } while((rslt < 0) && (__threadErrno == EINTR)); |
4332 || (__INST(handleType) == @symbol(filePointer)) |
4441 } |
4333 || (__INST(handleType) == @symbol(socketFilePointer)) |
|
4334 || (__INST(handleType) == @symbol(pipeFilePointer))) |
|
4335 { |
|
4336 FILEPOINTER f = __FILEVal(fp); |
|
4337 |
|
4338 if (@global(FileOpenTrace) == true) { |
|
4339 fprintf(stderr, "fclose [ExternalStream] %"_lx_"\n", f); |
|
4340 } |
|
4341 // whether the close() will be successful or not - the handle is invalid now! |
|
4342 __INST(handle) = nil; |
|
4343 |
|
4344 #ifdef WIN32 |
|
4345 if (__INST(mode) != @symbol(readonly) && __INST(buffered) != false) { |
|
4346 // do a fflush() first, so that fclose() doesn't block |
|
4347 // we suspect, that EINTR causes problems in fclose() |
4442 do { |
4348 do { |
4443 __threadErrno = 0; |
4349 __threadErrno = 0; |
4444 rslt = __STX_C_NOINT_CALL1("fclose", fclose, f); |
4350 rslt = __STX_C_CALL1("fflush", fflush, f); |
4445 } while((rslt < 0) && (__threadErrno == EINTR)); |
4351 } while((rslt < 0) && (__threadErrno == EINTR)); |
|
4352 } |
|
4353 do { |
|
4354 __threadErrno = 0; |
|
4355 rslt = __STX_C_NOINT_CALL1("fclose", fclose, f); |
|
4356 } while((rslt < 0) && (__threadErrno == EINTR)); |
4446 #else |
4357 #else |
4447 __BEGIN_INTERRUPTABLE__ |
4358 __BEGIN_INTERRUPTABLE__ |
4448 rslt = fclose(f); |
4359 rslt = fclose(f); |
4449 __END_INTERRUPTABLE__ |
4360 __END_INTERRUPTABLE__ |
4450 #endif |
4361 #endif |
4451 if (rslt < 0) { |
4362 } else { |
4452 error = __mkSmallInteger(__threadErrno); |
4363 error = @symbol(badHandleType); |
4453 goto out; |
4364 goto out; |
4454 } |
|
4455 } |
|
4456 RETURN (self); |
|
4457 } |
4365 } |
|
4366 |
|
4367 if (rslt < 0) { |
|
4368 error = __mkSmallInteger(__threadErrno); |
|
4369 goto out; |
|
4370 } |
|
4371 RETURN (self); |
|
4372 |
4458 out:; |
4373 out:; |
4459 %}. |
4374 %}. |
4460 |
4375 |
4461 error notNil ifTrue:[ |
4376 error notNil ifTrue:[ |
4462 error == #errorNotOpen ifTrue:[ |
4377 error == #errorNotOpen ifTrue:[ |
4759 self setAccessor:#socketHandle to:something |
4674 self setAccessor:#socketHandle to:something |
4760 ! ! |
4675 ! ! |
4761 |
4676 |
4762 !ExternalStream methodsFor:'queries'! |
4677 !ExternalStream methodsFor:'queries'! |
4763 |
4678 |
4764 isBinary |
4679 nextError |
4765 "return true, if the stream is in binary (as opposed to text-) mode. |
4680 "return the error by trying to read something. |
4766 The default when created is false." |
4681 Should only be used, when we know, that a read operation |
4767 |
4682 will return an error (otherwise a character may be lost). |
4768 ^ binary |
4683 Return an integer (error number), 0 (EOF) or nil (no error)" |
4769 ! |
4684 |
4770 |
4685 %{ /*NOCONTEXT*/ |
4771 isBlocking |
4686 FILEPOINTER f; |
4772 "return true, if O_NONBLOCK is NOT set in the fileDescriptor (probably UNIX specific)" |
4687 int ret, _buffered; |
|
4688 OBJ fp; |
|
4689 unsigned char ch; |
|
4690 |
|
4691 if ((__INST(handleType) == nil) |
|
4692 || (__INST(handleType) == @symbol(filePointer)) |
|
4693 || (__INST(handleType) == @symbol(socketFilePointer)) |
|
4694 || (__INST(handleType) == @symbol(socketHandle)) |
|
4695 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
|
4696 if (((fp = __INST(handle)) != nil) |
|
4697 && (__INST(mode) != @symbol(writeonly)) |
|
4698 ) { |
|
4699 f = __FILEVal(fp); |
|
4700 |
|
4701 _buffered = (__INST(buffered) == true); |
|
4702 if (_buffered) { |
|
4703 __READING__(f) |
|
4704 } |
|
4705 __READBYTE__(ret, f, &ch, _buffered, __INST(handleType)); |
|
4706 |
|
4707 if (ret > 0) { |
|
4708 RETURN(nil) |
|
4709 } |
|
4710 if (ret < 0) { |
|
4711 RETURN(__mkSmallInteger(__threadErrno)); |
|
4712 } else /* ret == 0 */ { |
|
4713 RETURN(__mkSmallInteger(0)); /* EOF */ |
|
4714 } |
|
4715 } |
|
4716 } |
|
4717 %}. |
|
4718 ! |
|
4719 |
|
4720 numAvailable |
|
4721 "return the number of bytes available for reading" |
|
4722 |
|
4723 |fd| |
4773 |
4724 |
4774 handle isNil ifTrue:[^ self errorNotOpen]. |
4725 handle isNil ifTrue:[^ self errorNotOpen]. |
4775 ^ OperatingSystem isBlockingOn:self fileDescriptor |
4726 mode == #writeonly ifTrue:[^ self errorWriteOnly]. |
4776 ! |
4727 fd := self fileDescriptor. |
4777 |
4728 |
4778 isExternalStream |
4729 %{ |
4779 "return true, if the receiver is some kind of externalStream; |
4730 #ifdef WIN32 |
4780 true is returned here - the method redefined from Object." |
4731 int res = 1; |
4781 |
4732 int success = 0; |
4782 ^ true |
4733 |
4783 ! |
4734 if (__INST(handleType) == @symbol(socketHandle)) { |
4784 |
4735 success = ioctlsocket((SOCKET)__externalAddressVal(fd), FIONREAD, &res) == 0; |
4785 isOpen |
4736 } else if (__INST(handleType) == @symbol(socketFilePointer)) { |
4786 "return true, if this stream is open" |
4737 success = ioctlsocket((SOCKET)_get_osfhandle(__intVal(fd)), FIONREAD, &res) == 0; |
4787 |
4738 } else if (__INST(handleType) == @symbol(pipeFilePointer)) { |
4788 ^ handle notNil |
4739 success = PeekNamedPipe((HANDLE)_get_osfhandle(__intVal(fd)),0,0,0,&res,0); |
4789 ! |
4740 } |
4790 |
4741 if (success) { |
4791 isReadable |
4742 if (__INST(readAhead) != nil) res++; |
4792 "return true, if this stream can be read from" |
4743 RETURN(__mkSmallInteger(res)); |
4793 |
4744 } |
4794 ^ (mode ~~ #writeonly) |
4745 #endif |
4795 ! |
4746 %}. |
4796 |
4747 |
4797 isWritable |
4748 ^ (readAhead notNil or:[OperatingSystem readCheck:fd]) ifTrue:[1] ifFalse:[0]. |
4798 "return true, if this stream can be written to" |
4749 |
4799 |
4750 "Created: / 4.2.1998 / 16:56:01 / cg" |
4800 ^ (mode ~~ #readonly) |
4751 "Modified: / 4.2.1998 / 17:31:11 / cg" |
4801 ! ! |
4752 ! ! |
4802 |
4753 |
4803 !ExternalStream methodsFor:'reading'! |
4754 !ExternalStream methodsFor:'reading'! |
4804 |
4755 |
4805 next |
4756 next |
4817 |
4768 |
4818 __INST(lastErrorNumber) = nil; |
4769 __INST(lastErrorNumber) = nil; |
4819 if ((__INST(handleType) == nil) |
4770 if ((__INST(handleType) == nil) |
4820 || (__INST(handleType) == @symbol(filePointer)) |
4771 || (__INST(handleType) == @symbol(filePointer)) |
4821 || (__INST(handleType) == @symbol(socketFilePointer)) |
4772 || (__INST(handleType) == @symbol(socketFilePointer)) |
|
4773 || (__INST(handleType) == @symbol(socketHandle)) |
4822 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
4774 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
4823 if (((fp = __INST(handle)) != nil) |
4775 if (((fp = __INST(handle)) != nil) |
4824 && (__INST(mode) != @symbol(writeonly)) |
4776 && (__INST(mode) != @symbol(writeonly)) |
4825 ) { |
4777 ) { |
4826 f = __FILEVal(fp); |
4778 f = __FILEVal(fp); |
4827 |
4779 |
4828 _buffered = (__INST(buffered) == true); |
4780 _buffered = (__INST(buffered) == true); |
4829 if (_buffered) { |
4781 if (_buffered) { |
4830 __READING__(f) |
4782 __READING__(f) |
4831 } |
4783 } |
4832 __READBYTE__(ret, f, &ch, _buffered, __INST(handleType)); |
4784 __READBYTE__(ret, f, &ch, _buffered, __INST(handleType)); |
4833 |
4785 |
4834 if (ret > 0) { |
4786 if (ret > 0) { |
4835 pos = __INST(position); |
4787 pos = __INST(position); |
4836 if (__isSmallInteger(pos)) { |
4788 if (__isSmallInteger(pos)) { |
4837 OBJ t; |
4789 OBJ t; |
4838 |
4790 |
4839 t = __MKINT(__intVal(pos) + 1); __INST(position) = t; __STORE(self, t); |
4791 t = __MKINT(__intVal(pos) + 1); __INST(position) = t; __STORE(self, t); |
4840 } else { |
4792 } else { |
4841 __INST(position) = nil; /* i.e. do not know */ |
4793 __INST(position) = nil; /* i.e. do not know */ |
4842 } |
4794 } |
4843 if (__INST(binary) == true) { |
4795 if (__INST(binary) == true) { |
4844 RETURN ( __mkSmallInteger(ch) ); |
4796 RETURN ( __mkSmallInteger(ch) ); |
4845 } |
4797 } |
4846 RETURN ( __MKCHARACTER(ch) ); |
4798 RETURN ( __MKCHARACTER(ch) ); |
4847 } |
4799 } |
4848 |
4800 |
4849 __INST(position) = nil; |
4801 __INST(position) = nil; |
4850 if (ret < 0) { |
4802 if (ret < 0) { |
4851 error = __mkSmallInteger(__threadErrno); |
4803 error = __mkSmallInteger(__threadErrno); |
4852 } else /* ret == 0 */ { |
4804 } else /* ret == 0 */ { |
4853 __INST(hitEOF) = true; |
4805 __INST(hitEOF) = true; |
4854 } |
4806 } |
4855 } |
4807 } |
4856 } |
4808 } |
4857 %}. |
4809 %}. |
4858 hitEOF == true ifTrue:[^ self pastEndRead]. |
4810 hitEOF == true ifTrue:[^ self pastEndRead]. |
4859 error notNil ifTrue:[ |
4811 error notNil ifTrue:[ |
4860 lastErrorNumber := error. |
4812 lastErrorNumber := error. |
4861 ^ self readError:error |
4813 ^ self readError:error |
4862 ]. |
4814 ]. |
4863 handle isNil ifTrue:[^ self errorNotOpen]. |
4815 handle isNil ifTrue:[^ self errorNotOpen]. |
4864 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
4816 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
4865 |
4817 |
4866 readAhead notNil ifTrue:[ |
4818 readAhead notNil ifTrue:[ |
4867 c := readAhead. |
4819 c := readAhead. |
4868 readAhead := nil. |
4820 readAhead := nil. |
4869 ^ c. |
4821 ^ c. |
4870 ]. |
4822 ]. |
4871 c := self nextByteFromFile:handle. |
4823 c := self nextByteFromFile:handle. |
4872 c isNil ifTrue:[ |
4824 c isNil ifTrue:[ |
4873 ^ self pastEndRead. |
4825 ^ self pastEndRead. |
4874 ]. |
4826 ]. |
4875 binary == true ifTrue:[ |
4827 binary == true ifTrue:[ |
4876 ^ c |
4828 ^ c |
4877 ]. |
4829 ]. |
4878 ^ Character value:c |
4830 ^ Character value:c |
4879 ! |
4831 ! |
4880 |
4832 |
4881 next:count |
4833 next:count |
4917 |
4869 |
4918 __INST(lastErrorNumber) = nil; |
4870 __INST(lastErrorNumber) = nil; |
4919 if ((__INST(handleType) == nil) |
4871 if ((__INST(handleType) == nil) |
4920 || (__INST(handleType) == @symbol(filePointer)) |
4872 || (__INST(handleType) == @symbol(filePointer)) |
4921 || (__INST(handleType) == @symbol(socketFilePointer)) |
4873 || (__INST(handleType) == @symbol(socketFilePointer)) |
|
4874 || (__INST(handleType) == @symbol(socketHandle)) |
4922 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
4875 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
4923 if (((fp = __INST(handle)) != nil) |
4876 if (((fp = __INST(handle)) != nil) |
4924 && (__INST(mode) != @symbol(writeonly)) |
4877 && (__INST(mode) != @symbol(writeonly)) |
4925 ) { |
4878 ) { |
4926 f = __FILEVal(fp); |
4879 f = __FILEVal(fp); |
4927 |
4880 |
4928 _buffered = (__INST(buffered) == true); |
4881 _buffered = (__INST(buffered) == true); |
4929 if (_buffered) { |
4882 if (_buffered) { |
4930 __READING__(f) |
4883 __READING__(f) |
4931 } |
4884 } |
4932 __READBYTE__(ret, f, &ch, _buffered, __INST(handleType)); |
4885 __READBYTE__(ret, f, &ch, _buffered, __INST(handleType)); |
4933 |
4886 |
4934 if (ret > 0) { |
4887 if (ret > 0) { |
4935 pos = __INST(position); |
4888 pos = __INST(position); |
4936 if (__isSmallInteger(pos)) { |
4889 if (__isSmallInteger(pos)) { |
4937 OBJ t; |
4890 OBJ t; |
4938 |
4891 |
4939 t = __MKINT(__intVal(pos) + 1); __INST(position) = t; __STORE(self, t); |
4892 t = __MKINT(__intVal(pos) + 1); __INST(position) = t; __STORE(self, t); |
4940 } else { |
4893 } else { |
4941 __INST(position) = nil; /* i.e. do not know */ |
4894 __INST(position) = nil; /* i.e. do not know */ |
4942 } |
4895 } |
4943 if (__INST(binary) == true) { |
4896 if (__INST(binary) == true) { |
4944 RETURN ( __mkSmallInteger(ch) ); |
4897 RETURN ( __mkSmallInteger(ch) ); |
4945 } |
4898 } |
4946 RETURN ( __MKCHARACTER(ch) ); |
4899 RETURN ( __MKCHARACTER(ch) ); |
4947 } |
4900 } |
4948 |
4901 |
4949 __INST(position) = nil; |
4902 __INST(position) = nil; |
4950 if (ret < 0) { |
4903 if (ret < 0) { |
4951 error = __mkSmallInteger(__threadErrno); |
4904 error = __mkSmallInteger(__threadErrno); |
4952 } else /* ret == 0 */ { |
4905 } else /* ret == 0 */ { |
4953 __INST(hitEOF) = true; |
4906 __INST(hitEOF) = true; |
4954 } |
4907 } |
4955 } |
4908 } |
4956 } |
4909 } |
4957 %}. |
4910 %}. |
4958 hitEOF == true ifTrue:[^ nil]. |
4911 hitEOF == true ifTrue:[^ nil]. |
4959 error notNil ifTrue:[ |
4912 error notNil ifTrue:[ |
4960 lastErrorNumber := error. |
4913 lastErrorNumber := error. |
4961 ^ self readError:error. |
4914 ^ self readError:error. |
4962 ]. |
4915 ]. |
4963 handle isNil ifTrue:[^ self errorNotOpen]. |
4916 handle isNil ifTrue:[^ self errorNotOpen]. |
4964 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
4917 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
4965 |
4918 |
4966 readAhead notNil ifTrue:[ |
4919 readAhead notNil ifTrue:[ |
4967 c := readAhead. |
4920 c := readAhead. |
4968 readAhead := nil. |
4921 readAhead := nil. |
4969 ^ c. |
4922 ^ c. |
4970 ]. |
4923 ]. |
4971 c := self nextByteFromFile:handle. |
4924 c := self nextByteFromFile:handle. |
4972 c isNil ifTrue:[ |
4925 c isNil ifTrue:[ |
4973 ^ nil. |
4926 ^ nil. |
4974 ]. |
4927 ]. |
4975 binary == true ifTrue:[ |
4928 binary == true ifTrue:[ |
4976 ^ c |
4929 ^ c |
4977 ]. |
4930 ]. |
4978 ^ Character value:c |
4931 ^ Character value:c |
4979 ! |
4932 ! |
4980 |
4933 |
4981 peek |
4934 peek |
4991 int ret, _buffered; |
4944 int ret, _buffered; |
4992 OBJ fp; |
4945 OBJ fp; |
4993 OBJ ra; |
4946 OBJ ra; |
4994 |
4947 |
4995 if ((ra = __INST(readAhead)) != nil) { |
4948 if ((ra = __INST(readAhead)) != nil) { |
4996 if (__INST(binary) == true) { |
4949 if (__INST(binary) == true) { |
4997 RETURN ( ra ); |
4950 RETURN ( ra ); |
4998 } |
4951 } |
4999 c = __intVal(ra); |
4952 c = __intVal(ra); |
5000 RETURN ( __MKCHARACTER(c) ); |
4953 RETURN ( __MKCHARACTER(c) ); |
5001 } |
4954 } |
5002 |
4955 |
5003 __INST(lastErrorNumber) = nil; |
4956 __INST(lastErrorNumber) = nil; |
5004 |
4957 |
5005 if ((__INST(handleType) == nil) |
4958 if ((__INST(handleType) == nil) |
5006 || (__INST(handleType) == @symbol(filePointer)) |
4959 || (__INST(handleType) == @symbol(filePointer)) |
5007 || (__INST(handleType) == @symbol(socketFilePointer)) |
4960 || (__INST(handleType) == @symbol(socketFilePointer)) |
|
4961 || (__INST(handleType) == @symbol(socketHandle)) |
5008 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
4962 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
5009 if (((fp = __INST(handle)) != nil) |
4963 if (((fp = __INST(handle)) != nil) |
5010 && (__INST(mode) != @symbol(writeonly)) |
4964 && (__INST(mode) != @symbol(writeonly)) |
5011 ) { |
4965 ) { |
5012 f = __FILEVal(fp); |
4966 f = __FILEVal(fp); |
5013 _buffered = (__INST(buffered) == true); |
4967 _buffered = (__INST(buffered) == true); |
5014 if (_buffered) { |
4968 if (_buffered) { |
5015 __READING__(f) |
4969 __READING__(f) |
5016 } |
4970 } |
5017 __READBYTE__(ret, f, &c, _buffered, __INST(handleType)); |
4971 __READBYTE__(ret, f, &c, _buffered, __INST(handleType)); |
5018 |
4972 |
5019 if (ret > 0) { |
4973 if (ret > 0) { |
5020 __UNGETC__(c, f, _buffered); |
4974 __UNGETC__(c, f, _buffered); |
5021 |
4975 |
5022 if (__INST(binary) == true) { |
4976 if (__INST(binary) == true) { |
5023 RETURN ( __mkSmallInteger(c) ); |
4977 RETURN ( __mkSmallInteger(c) ); |
5024 } |
4978 } |
5025 RETURN ( __MKCHARACTER(c) ); |
4979 RETURN ( __MKCHARACTER(c) ); |
5026 } |
4980 } |
5027 if (ret < 0) { |
4981 if (ret < 0) { |
5028 error = __mkSmallInteger(__threadErrno); |
4982 error = __mkSmallInteger(__threadErrno); |
5029 } else /* ret == 0 */ { |
4983 } else /* ret == 0 */ { |
5030 __INST(hitEOF) = true; |
4984 __INST(hitEOF) = true; |
5031 } |
4985 } |
5032 } |
4986 } |
5033 } |
4987 } |
5034 %}. |
4988 %}. |
5035 hitEOF == true ifTrue:[^ self pastEndRead]. |
4989 hitEOF == true ifTrue:[^ self pastEndRead]. |
5036 error notNil ifTrue:[ |
4990 error notNil ifTrue:[ |
5037 lastErrorNumber := error. |
4991 lastErrorNumber := error. |
5038 ^ self readError:error. |
4992 ^ self readError:error. |
5039 ]. |
4993 ]. |
5040 handle isNil ifTrue:[^ self errorNotOpen]. |
4994 handle isNil ifTrue:[^ self errorNotOpen]. |
5041 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
4995 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
5042 |
4996 |
5043 readAhead isNil ifTrue:[ |
4997 readAhead isNil ifTrue:[ |
5044 readAhead := self nextOrNil. |
4998 readAhead := self nextOrNil. |
5045 readAhead isNil ifTrue:[ |
4999 readAhead isNil ifTrue:[ |
5046 ^ self pastEndRead. |
5000 ^ self pastEndRead. |
5047 ]. |
5001 ]. |
5048 ]. |
5002 ]. |
5049 ^ readAhead |
5003 ^ readAhead |
5050 ! |
5004 ! |
5051 |
5005 |
5052 peekOrNil |
5006 peekOrNil |
5062 int ret, _buffered; |
5016 int ret, _buffered; |
5063 OBJ fp; |
5017 OBJ fp; |
5064 OBJ ra; |
5018 OBJ ra; |
5065 |
5019 |
5066 if ((ra = __INST(readAhead)) != nil) { |
5020 if ((ra = __INST(readAhead)) != nil) { |
5067 if (__INST(binary) == true) { |
5021 if (__INST(binary) == true) { |
5068 RETURN ( ra ); |
5022 RETURN ( ra ); |
5069 } |
5023 } |
5070 c = __intVal(ra); |
5024 c = __intVal(ra); |
5071 RETURN ( __MKCHARACTER(c) ); |
5025 RETURN ( __MKCHARACTER(c) ); |
5072 } |
5026 } |
5073 |
5027 |
5074 __INST(lastErrorNumber) = nil; |
5028 __INST(lastErrorNumber) = nil; |
5075 |
5029 |
5076 if ((__INST(handleType) == nil) |
5030 if ((__INST(handleType) == nil) |
5077 || (__INST(handleType) == @symbol(filePointer)) |
5031 || (__INST(handleType) == @symbol(filePointer)) |
5078 || (__INST(handleType) == @symbol(socketFilePointer)) |
5032 || (__INST(handleType) == @symbol(socketFilePointer)) |
|
5033 || (__INST(handleType) == @symbol(socketHandle)) |
5079 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
5034 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
5080 if (((fp = __INST(handle)) != nil) |
5035 if (((fp = __INST(handle)) != nil) |
5081 && (__INST(mode) != @symbol(writeonly)) |
5036 && (__INST(mode) != @symbol(writeonly)) |
5082 ) { |
5037 ) { |
5083 f = __FILEVal(fp); |
5038 f = __FILEVal(fp); |
5084 _buffered = (__INST(buffered) == true); |
5039 _buffered = (__INST(buffered) == true); |
5085 if (_buffered) { |
5040 if (_buffered) { |
5086 __READING__(f) |
5041 __READING__(f) |
5087 } |
5042 } |
5088 __READBYTE__(ret, f, &c, _buffered, __INST(handleType)); |
5043 __READBYTE__(ret, f, &c, _buffered, __INST(handleType)); |
5089 |
5044 |
5090 if (ret > 0) { |
5045 if (ret > 0) { |
5091 __UNGETC__(c, f, _buffered); |
5046 __UNGETC__(c, f, _buffered); |
5092 |
5047 |
5093 if (__INST(binary) == true) { |
5048 if (__INST(binary) == true) { |
5094 RETURN ( __mkSmallInteger(c) ); |
5049 RETURN ( __mkSmallInteger(c) ); |
5095 } |
5050 } |
5096 RETURN ( __MKCHARACTER(c) ); |
5051 RETURN ( __MKCHARACTER(c) ); |
5097 } |
5052 } |
5098 if (ret < 0) { |
5053 if (ret < 0) { |
5099 error = __mkSmallInteger(__threadErrno); |
5054 error = __mkSmallInteger(__threadErrno); |
5100 } else /* ret == 0 */ { |
5055 } else /* ret == 0 */ { |
5101 __INST(hitEOF) = true; |
5056 __INST(hitEOF) = true; |
5102 } |
5057 } |
5103 } |
5058 } |
5104 } |
5059 } |
5105 %}. |
5060 %}. |
5106 hitEOF == true ifTrue:[^ nil]. |
5061 hitEOF == true ifTrue:[^ nil]. |
5107 error notNil ifTrue:[ |
5062 error notNil ifTrue:[ |
5108 lastErrorNumber := error. |
5063 lastErrorNumber := error. |
5109 ^ self readError:error. |
5064 ^ self readError:error. |
5110 ]. |
5065 ]. |
5111 handle isNil ifTrue:[^ self errorNotOpen]. |
5066 handle isNil ifTrue:[^ self errorNotOpen]. |
5112 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
5067 (mode == #writeonly) ifTrue:[^ self errorWriteOnly]. |
5113 |
5068 |
5114 readAhead isNil ifTrue:[ |
5069 readAhead isNil ifTrue:[ |
5115 readAhead := self nextOrNil. |
5070 readAhead := self nextOrNil. |
5116 ]. |
5071 ]. |
5117 ^ readAhead |
5072 ^ readAhead |
5118 ! |
5073 ! |
5119 |
5074 |
5120 upToEnd |
5075 upToEnd |
5176 OBJ fp, pos, lim; |
5131 OBJ fp, pos, lim; |
5177 char c; |
5132 char c; |
5178 int ret, _buffered; |
5133 int ret, _buffered; |
5179 |
5134 |
5180 if (__INST(hitEOF) == true) { |
5135 if (__INST(hitEOF) == true) { |
5181 RETURN (true); |
5136 RETURN (true); |
5182 } |
5137 } |
5183 pos = __INST(position); |
5138 pos = __INST(position); |
5184 lim = __INST(readLimit); |
5139 lim = __INST(readLimit); |
5185 if (lim != nil) { |
5140 if (lim != nil) { |
5186 off_t _pos, _readLimit; |
5141 off_t _pos, _readLimit; |
5187 |
5142 |
5188 _pos = __signedLongIntVal(pos); |
5143 _pos = __signedLongIntVal(pos); |
5189 _pos = _pos - __intVal( @global(PositionableStream:ZeroPosition)) + 1; |
5144 _pos = _pos - __intVal( @global(PositionableStream:ZeroPosition)) + 1; |
5190 _readLimit = __signedLongIntVal(lim); |
5145 _readLimit = __signedLongIntVal(lim); |
5191 if (_pos > _readLimit) { |
5146 if (_pos > _readLimit) { |
5192 RETURN (true); |
5147 RETURN (true); |
5193 } |
5148 } |
5194 } |
5149 } |
5195 |
5150 |
5196 __INST(lastErrorNumber) = nil; |
5151 __INST(lastErrorNumber) = nil; |
5197 |
5152 |
5198 if ((__INST(handleType) == nil) |
5153 if ((__INST(handleType) == nil) |
5199 || (__INST(handleType) == @symbol(filePointer)) |
5154 || (__INST(handleType) == @symbol(filePointer)) |
5200 || (__INST(handleType) == @symbol(socketFilePointer)) |
5155 || (__INST(handleType) == @symbol(socketFilePointer)) |
|
5156 || (__INST(handleType) == @symbol(socketHandle)) |
5201 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
5157 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
5202 if ((fp = __INST(handle)) != nil) { |
5158 if ((fp = __INST(handle)) != nil) { |
5203 f = __FILEVal(fp); |
5159 f = __FILEVal(fp); |
5204 if (_buffered = (__INST(buffered) == true)) { |
5160 if (_buffered = (__INST(buffered) == true)) { |
5205 __READING__(f); |
5161 __READING__(f); |
5206 } else { |
5162 } else { |
5207 if (__INST(readAhead) != nil) { |
5163 if (__INST(readAhead) != nil) { |
5208 RETURN (false); |
5164 RETURN (false); |
5209 } |
5165 } |
5210 } |
5166 } |
5211 |
5167 |
5212 /* |
5168 /* |
5213 * read ahead ... |
5169 * read ahead ... |
5214 */ |
5170 */ |
5215 do { |
5171 do { |
5216 #ifdef WIN32 |
5172 #ifdef WIN32 |
5217 # if 1 |
5173 # if 1 |
5218 __READBYTE__(ret, f, &c, _buffered, __INST(handleType)); |
5174 __READBYTE__(ret, f, &c, _buffered, __INST(handleType)); |
5219 |
5175 |
5220 # else |
5176 # else |
5221 __BEGIN_INTERRUPTABLE__ |
5177 __BEGIN_INTERRUPTABLE__ |
5222 __READBYTE__(ret, f, &c, _buffered, __INST(handleType)); |
5178 __READBYTE__(ret, f, &c, _buffered, __INST(handleType)); |
5223 __END_INTERRUPTABLE__ |
5179 __END_INTERRUPTABLE__ |
5224 # endif |
5180 # endif |
5225 #else /* not WIN32 */ |
5181 #else /* not WIN32 */ |
5226 __BEGIN_INTERRUPTABLE__ |
5182 __BEGIN_INTERRUPTABLE__ |
5227 __READBYTE__(ret, f, &c, _buffered, __INST(handleType)); |
5183 __READBYTE__(ret, f, &c, _buffered, __INST(handleType)); |
5228 __END_INTERRUPTABLE__ |
5184 __END_INTERRUPTABLE__ |
5229 #endif |
5185 #endif |
5230 } while ((ret < 0) && (__threadErrno == EINTR)); |
5186 } while ((ret < 0) && (__threadErrno == EINTR)); |
5231 |
5187 |
5232 #if defined(WIN32) && defined(EPIPE) |
5188 #if defined(WIN32) && defined(EPIPE) |
5233 if (ret < 0) { |
5189 if (ret < 0) { |
5234 if (__threadErrno == EPIPE) { |
5190 if (__threadErrno == EPIPE) { |
5235 ret = 0; |
5191 ret = 0; |
5236 __threadErrno = 0; |
5192 __threadErrno = 0; |
5237 } |
5193 } |
5238 if (__threadErrno == 0) { |
5194 if (__threadErrno == 0) { |
5239 ret = 0; /* how comes ? */ |
5195 ret = 0; /* how comes ? */ |
5240 } |
5196 } |
5241 } |
5197 } |
5242 #endif |
5198 #endif |
5243 if (ret > 0) { |
5199 if (ret > 0) { |
5244 __UNGETC__(c&0xff, f, _buffered); |
5200 __UNGETC__(c&0xff, f, _buffered); |
5245 RETURN (false); |
5201 RETURN (false); |
5246 } |
5202 } |
5247 |
5203 |
5248 if (ret == 0) { |
5204 if (ret == 0) { |
5249 __INST(hitEOF) = true; |
5205 __INST(hitEOF) = true; |
5250 RETURN (true); |
5206 RETURN (true); |
5251 } |
5207 } |
5252 |
5208 |
5253 /* ret < 0 */ |
5209 /* ret < 0 */ |
5254 __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno); |
5210 __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno); |
5255 } |
5211 } |
5256 } |
5212 } |
5257 %}. |
5213 %}. |
5258 lastErrorNumber notNil ifTrue:[^ self readError]. |
5214 lastErrorNumber notNil ifTrue:[^ self readError]. |
5259 handle isNil ifTrue:[^ self errorNotOpen]. |
5215 handle isNil ifTrue:[^ self errorNotOpen]. |
5260 mode == #writeonly ifTrue:[^ self errorWriteOnly]. |
5216 mode == #writeonly ifTrue:[^ self errorWriteOnly]. |
5261 readAhead notNil ifTrue:[^ false]. |
5217 readAhead notNil ifTrue:[^ false]. |
5262 |
5218 |
5263 "/ migration support |
5219 "/ migration support |
5264 ^ self |
5220 ^ self |
5265 atEndFile:handle |
5221 atEndFile:handle |
5266 |
5222 |
5267 "Modified: / 30.10.1998 / 20:16:06 / cg" |
5223 "Modified: / 30.10.1998 / 20:16:06 / cg" |
5268 ! |
5224 ! |
5269 |
5225 |
5270 canReadWithoutBlocking |
5226 canReadWithoutBlocking |
5271 "return true, if any data is available for reading (i.e. |
5227 "return true, if any data is available for reading (i.e. |
5272 a read operation will not block the smalltalk process), false otherwise." |
5228 a read operation will not block the smalltalk process), false otherwise. |
5273 |
5229 We know, that error conditions do not block, so return true for errors." |
5274 |fd| |
5230 |
5275 |
5231 ^ readAhead notNil |
5276 readAhead notNil ifTrue:[^ true]. |
5232 or:[handle isNil] |
5277 handle isNil ifTrue:[^ self errorNotOpen]. |
5233 or:[mode == #writeonly |
5278 mode == #writeonly ifTrue:[^ self errorWriteOnly]. |
5234 or:[OperatingSystem readCheck:self fileDescriptor]] |
5279 |
|
5280 fd := self fileDescriptor. |
|
5281 ^ OperatingSystem readCheck:fd |
|
5282 |
5235 |
5283 " |
5236 " |
5284 |pipe| |
5237 |pipe| |
5285 |
5238 |
5286 pipe := PipeStream readingFrom:'(sleep 10; echo hello)'. |
5239 pipe := PipeStream readingFrom:'(sleep 10; echo hello)'. |
5295 "Modified: 25.9.1997 / 13:08:45 / stefan" |
5248 "Modified: 25.9.1997 / 13:08:45 / stefan" |
5296 ! |
5249 ! |
5297 |
5250 |
5298 canWriteWithoutBlocking |
5251 canWriteWithoutBlocking |
5299 "return true, if data can be written into the stream |
5252 "return true, if data can be written into the stream |
5300 (i.e. a write operation will not block the smalltalk process)." |
5253 (i.e. a write operation will not block the smalltalk process). |
5301 |
5254 We know, that error conditions do not block, so return true for errors." |
5302 |fd| |
5255 |
5303 |
5256 ^ handle isNil |
5304 handle isNil ifTrue:[^ self errorNotOpen]. |
5257 or:[mode == #readonly |
5305 mode == #readonly ifTrue:[^ self errorReadOnly]. |
5258 or:[OperatingSystem writeCheck:self fileDescriptor]] |
5306 |
|
5307 fd := self fileDescriptor. |
|
5308 ^ OperatingSystem writeCheck:fd |
|
5309 ! |
5259 ! |
5310 |
5260 |
5311 gotErrorOrEOF |
5261 gotErrorOrEOF |
5312 "answerv true, if amn error or eof has been occured on the stream" |
5262 "answerv true, if amn error or eof has been occured on the stream" |
5313 |
5263 |
5314 ^ hitEOF == true or:[lastErrorNumber notNil] |
5264 ^ hitEOF == true or:[lastErrorNumber notNil] |
5315 ! |
5265 ! |
5316 |
5266 |
5317 nextError |
5267 isBinary |
5318 "return the error by trying to read something. |
5268 "return true, if the stream is in binary (as opposed to text-) mode. |
5319 Should only be used, when we know, that a read operation |
5269 The default when created is false." |
5320 will return an error (otherwise a character may be lost). |
5270 |
5321 Return an integer (error number), 0 (EOF) or nil (no error)" |
5271 ^ binary |
5322 |
5272 ! |
5323 %{ /*NOCONTEXT*/ |
5273 |
5324 FILEPOINTER f; |
5274 isBlocking |
5325 int ret, _buffered; |
5275 "return true, if O_NONBLOCK is NOT set in the fileDescriptor (probably UNIX specific)" |
5326 OBJ fp; |
|
5327 unsigned char ch; |
|
5328 |
|
5329 if ((__INST(handleType) == nil) |
|
5330 || (__INST(handleType) == @symbol(filePointer)) |
|
5331 || (__INST(handleType) == @symbol(socketFilePointer)) |
|
5332 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
|
5333 if (((fp = __INST(handle)) != nil) |
|
5334 && (__INST(mode) != @symbol(writeonly)) |
|
5335 ) { |
|
5336 f = __FILEVal(fp); |
|
5337 |
|
5338 _buffered = (__INST(buffered) == true); |
|
5339 if (_buffered) { |
|
5340 __READING__(f) |
|
5341 } |
|
5342 __READBYTE__(ret, f, &ch, _buffered, __INST(handleType)); |
|
5343 |
|
5344 if (ret > 0) { |
|
5345 RETURN(nil) |
|
5346 } |
|
5347 if (ret < 0) { |
|
5348 RETURN(__mkSmallInteger(__threadErrno)); |
|
5349 } else /* ret == 0 */ { |
|
5350 RETURN(__mkSmallInteger(0)); /* EOF */ |
|
5351 } |
|
5352 } |
|
5353 } |
|
5354 %}. |
|
5355 ! |
|
5356 |
|
5357 numAvailable |
|
5358 "return the number of bytes available for reading" |
|
5359 |
|
5360 |fd| |
|
5361 |
5276 |
5362 handle isNil ifTrue:[^ self errorNotOpen]. |
5277 handle isNil ifTrue:[^ self errorNotOpen]. |
5363 mode == #writeonly ifTrue:[^ self errorWriteOnly]. |
5278 ^ OperatingSystem isBlockingOn:self fileDescriptor |
5364 |
5279 ! |
5365 fd := self fileDescriptor. |
5280 |
5366 ^ OperatingSystem numAvailableForReadOn:fd. |
5281 isExternalStream |
5367 |
5282 "return true, if the receiver is some kind of externalStream; |
5368 "/ self atEnd ifTrue:[^ 0]. |
5283 true is returned here - the method redefined from Object." |
5369 "/ self canReadWithoutBlocking ifTrue:[ |
5284 |
5370 "/ ^ 1 |
5285 ^ true |
5371 "/ ]. |
5286 ! |
5372 "/ ^ 0 |
5287 |
5373 |
5288 isOpen |
5374 "Created: / 4.2.1998 / 16:56:01 / cg" |
5289 "return true, if this stream is open" |
5375 "Modified: / 4.2.1998 / 17:31:11 / cg" |
5290 |
|
5291 ^ handle notNil |
|
5292 ! |
|
5293 |
|
5294 isReadable |
|
5295 "return true, if this stream can be read from" |
|
5296 |
|
5297 ^ (mode ~~ #writeonly) |
|
5298 ! |
|
5299 |
|
5300 isWritable |
|
5301 "return true, if this stream can be written to" |
|
5302 |
|
5303 ^ (mode ~~ #readonly) |
5376 ! ! |
5304 ! ! |
5377 |
5305 |
5378 !ExternalStream methodsFor:'waiting for I/O'! |
5306 !ExternalStream methodsFor:'waiting for I/O'! |
5379 |
5307 |
5380 canBeSelected |
5308 canBeSelected |
5514 OBJ fp; |
5442 OBJ fp; |
5515 char *cp; |
5443 char *cp; |
5516 |
5444 |
5517 if ((__INST(handleType) == nil) |
5445 if ((__INST(handleType) == nil) |
5518 || (__INST(handleType) == @symbol(filePointer)) |
5446 || (__INST(handleType) == @symbol(filePointer)) |
|
5447 || (__INST(handleType) == @symbol(socketHandle)) |
5519 || (__INST(handleType) == @symbol(socketFilePointer)) |
5448 || (__INST(handleType) == @symbol(socketFilePointer)) |
5520 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
5449 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
5521 __INST(lastErrorNumber) = nil; |
5450 __INST(lastErrorNumber) = nil; |
5522 if (((fp = __INST(handle)) != nil) |
5451 if (((fp = __INST(handle)) != nil) |
5523 && (__INST(mode) != @symbol(readonly)) |
5452 && (__INST(mode) != @symbol(readonly)) |
5524 && (__INST(binary) != true) |
5453 && (__INST(binary) != true) |
5525 ) { |
5454 ) { |
5526 f = __FILEVal(fp); |
5455 f = __FILEVal(fp); |
5527 |
5456 |
5528 if (_buffered = (__INST(buffered) == true)) { |
5457 if (_buffered = (__INST(buffered) == true)) { |
5529 __WRITING__(f) |
5458 __WRITING__(f) |
5530 } |
5459 } |
5531 { |
5460 { |
5532 OBJ mode = __INST(eolMode); |
5461 OBJ mode = __INST(eolMode); |
5533 |
5462 |
5534 if (mode == @symbol(cr)) { |
5463 if (mode == @symbol(cr)) { |
5535 cp = "\r"; len = 1; |
5464 cp = "\r"; len = 1; |
5536 } else if (mode == @symbol(crlf)) { |
5465 } else if (mode == @symbol(crlf)) { |
5537 cp = "\r\n"; len = 2; |
5466 cp = "\r\n"; len = 2; |
5538 } else { |
5467 } else { |
5539 cp = "\n"; len = 1; |
5468 cp = "\n"; len = 1; |
5540 } |
5469 } |
5541 } |
5470 } |
5542 #ifdef WIN32 |
5471 #ifdef WIN32 |
5543 if ((f == __win32_stdout()) || (f == __win32_stderr())) { |
5472 if ((f == __win32_stdout()) || (f == __win32_stderr())) { |
5544 cnt = __win32_fwrite(cp, 1, len, f); |
5473 cnt = __win32_fwrite(cp, 1, len, f); |
5545 } else |
5474 } else |
5546 #endif |
5475 #endif |
5547 { |
5476 { |
5548 __WRITEBYTES__(cnt, f, cp, len, _buffered, __INST(handleType)); |
5477 __WRITEBYTES__(cnt, f, cp, len, _buffered, __INST(handleType)); |
5549 } |
5478 } |
5550 if (cnt == len) { |
5479 if (cnt == len) { |
5551 if (__isSmallInteger(__INST(position))) { |
5480 if (__isSmallInteger(__INST(position))) { |
5552 INT np = __intVal(__INST(position)) + len; |
5481 INT np = __intVal(__INST(position)) + len; |
5553 OBJ t; |
5482 OBJ t; |
5554 |
5483 |
5555 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
5484 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
5556 } else { |
5485 } else { |
5557 __INST(position) = nil; /* i.e: dont know */ |
5486 __INST(position) = nil; /* i.e: dont know */ |
5558 } |
5487 } |
5559 RETURN ( self ); |
5488 RETURN ( self ); |
5560 } |
5489 } |
5561 __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno); |
5490 __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno); |
5562 } |
5491 } |
5563 } |
5492 } |
5564 %}. |
5493 %}. |
5565 lastErrorNumber notNil ifTrue:[self writeError. ^ self]. |
5494 lastErrorNumber notNil ifTrue:[self writeError. ^ self]. |
5566 handle isNil ifTrue:[self errorNotOpen. ^ self]. |
5495 handle isNil ifTrue:[self errorNotOpen. ^ self]. |
5567 (mode == #readonly) ifTrue:[self errorReadOnly. ^ self]. |
5496 (mode == #readonly) ifTrue:[self errorReadOnly. ^ self]. |
5626 |
5555 |
5627 __INST(lastErrorNumber) = nil; |
5556 __INST(lastErrorNumber) = nil; |
5628 if ((__INST(handleType) == nil) |
5557 if ((__INST(handleType) == nil) |
5629 || (__INST(handleType) == @symbol(filePointer)) |
5558 || (__INST(handleType) == @symbol(filePointer)) |
5630 || (__INST(handleType) == @symbol(socketFilePointer)) |
5559 || (__INST(handleType) == @symbol(socketFilePointer)) |
|
5560 || (__INST(handleType) == @symbol(socketHandle)) |
5631 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
5561 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
5632 if (((fp = __INST(handle)) != nil) |
5562 if (((fp = __INST(handle)) != nil) |
5633 && (__INST(mode) != @symbol(readonly)) |
5563 && (__INST(mode) != @symbol(readonly)) |
5634 ) { |
5564 ) { |
5635 if (__INST(binary) != true) { |
5565 if (__INST(binary) != true) { |
5636 if (__isCharacter(aCharacter)) { |
5566 if (__isCharacter(aCharacter)) { |
5637 codePoint = __intVal(__characterVal(aCharacter)); |
5567 codePoint = __intVal(__characterVal(aCharacter)); |
5638 if (codePoint <= 0xFF) { |
5568 if (codePoint <= 0xFF) { |
5639 c = codePoint; |
5569 c = codePoint; |
5640 doWrite: |
5570 doWrite: |
5641 f = __FILEVal(fp); |
5571 f = __FILEVal(fp); |
5642 if (! f) { |
5572 if (! f) { |
5643 fprintf(stderr, "oops - fileHandle is NULL in nextPut:\n"); |
5573 fprintf(stderr, "oops - fileHandle is NULL in nextPut:\n"); |
5644 __INST(handle) = nil; |
5574 __INST(handle) = nil; |
5645 goto out; |
5575 goto out; |
5646 } |
5576 } |
5647 |
5577 |
5648 if (_buffered = (__INST(buffered) == true)) { |
5578 if (_buffered = (__INST(buffered) == true)) { |
5649 __WRITING__(f) |
5579 __WRITING__(f) |
5650 } |
5580 } |
5651 #ifdef WIN32 |
5581 #ifdef WIN32 |
5652 if ((f == __win32_stdout()) || (f == __win32_stderr())) { |
5582 if ((f == __win32_stdout()) || (f == __win32_stderr())) { |
5653 cnt = __win32_fwrite(&c, 1, 1, f); |
5583 cnt = __win32_fwrite(&c, 1, 1, f); |
5654 } else |
5584 } else |
5655 #endif |
5585 #endif |
5656 __WRITEBYTE__(cnt, f, &c, _buffered, __INST(handleType)); |
5586 __WRITEBYTE__(cnt, f, &c, _buffered, __INST(handleType)); |
5657 if (cnt == 1) { |
5587 if (cnt == 1) { |
5658 if (__isSmallInteger(__INST(position))) { |
5588 if (__isSmallInteger(__INST(position))) { |
5659 INT np = __intVal(__INST(position)) + 1; |
5589 INT np = __intVal(__INST(position)) + 1; |
5660 OBJ t; |
5590 OBJ t; |
5661 |
5591 |
5662 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
5592 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
5663 } else { |
5593 } else { |
5664 __INST(position) = nil; /* i.e. do not know */ |
5594 __INST(position) = nil; /* i.e. do not know */ |
5665 } |
5595 } |
5666 RETURN ( self ); |
5596 RETURN ( self ); |
5667 } |
5597 } |
5668 error = __mkSmallInteger(__threadErrno); |
5598 error = __mkSmallInteger(__threadErrno); |
5669 } |
5599 } |
5670 } |
5600 } |
5671 } else { |
5601 } else { |
5672 if (__isSmallInteger(aCharacter)) { |
5602 if (__isSmallInteger(aCharacter)) { |
5673 c = __intVal(aCharacter); |
5603 c = __intVal(aCharacter); |
5674 goto doWrite; |
5604 goto doWrite; |
5675 } |
5605 } |
5676 } |
5606 } |
5677 } |
5607 } |
5678 } |
5608 } |
5679 out: ; |
5609 out: ; |
5680 %}. |
5610 %}. |
5681 error notNil ifTrue:[ |
5611 error notNil ifTrue:[ |
5682 lastErrorNumber := error. |
5612 lastErrorNumber := error. |
5683 self writeError:error. |
5613 self writeError:error. |
5684 ^ self |
5614 ^ self |
5685 ]. |
5615 ]. |
5686 handle isNil ifTrue:[self errorNotOpen. ^ self]. |
5616 handle isNil ifTrue:[self errorNotOpen. ^ self]. |
5687 (mode == #readonly) ifTrue:[self errorReadOnly. ^ self]. |
5617 (mode == #readonly) ifTrue:[self errorReadOnly. ^ self]. |
5688 binary == true ifFalse:[ |
5618 binary == true ifFalse:[ |
5689 (aCharacter isCharacter not |
5619 (aCharacter isCharacter not |
5690 or:[aCharacter codePoint > 16rFF]) ifTrue:[ |
5620 or:[aCharacter codePoint > 16rFF]) ifTrue:[ |
5691 self argumentMustBeCharacter. |
5621 self argumentMustBeCharacter. |
5692 ^ self. |
5622 ^ self. |
5693 ]. |
5623 ]. |
5694 ] ifTrue:[ |
5624 ] ifTrue:[ |
5695 aCharacter isInteger ifFalse:[ |
5625 aCharacter isInteger ifFalse:[ |
5696 self argumentMustBeInteger. |
5626 self argumentMustBeInteger. |
5697 ^ self. |
5627 ^ self. |
5698 ]. |
5628 ]. |
5699 ]. |
5629 ]. |
5700 "/ migration support |
5630 "/ migration support |
5701 self |
5631 self |
5702 nextPutByte:aCharacter asInteger |
5632 nextPutByte:aCharacter asInteger |
5703 toFile:handle |
5633 toFile:handle |
5704 ! |
5634 ! |
5705 |
5635 |
5706 nextPutAll:aCollection |
5636 nextPutAll:aCollection |
5707 "write all elements of the argument, aCollection. |
5637 "write all elements of the argument, aCollection. |
5708 Reimplemented for speed when writing strings or byteArrays. |
5638 Reimplemented for speed when writing strings or byteArrays. |
5719 __INST(lastErrorNumber) = nil; |
5649 __INST(lastErrorNumber) = nil; |
5720 |
5650 |
5721 if ((__INST(handleType) == nil) |
5651 if ((__INST(handleType) == nil) |
5722 || (__INST(handleType) == @symbol(filePointer)) |
5652 || (__INST(handleType) == @symbol(filePointer)) |
5723 || (__INST(handleType) == @symbol(socketFilePointer)) |
5653 || (__INST(handleType) == @symbol(socketFilePointer)) |
|
5654 || (__INST(handleType) == @symbol(socketHandle)) |
5724 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
5655 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
5725 if (((fp = __INST(handle)) != nil) |
5656 if (((fp = __INST(handle)) != nil) |
5726 && (__INST(mode) != @symbol(readonly)) |
5657 && (__INST(mode) != @symbol(readonly)) |
5727 ) { |
5658 ) { |
5728 f = __FILEVal(fp); |
5659 f = __FILEVal(fp); |
5729 if (! f) { |
5660 if (! f) { |
5730 fprintf(stderr, "oops - fileHandle is NULL in nextPutAll:\n"); |
5661 fprintf(stderr, "oops - fileHandle is NULL in nextPutAll:\n"); |
5731 __INST(handle) = nil; |
5662 __INST(handle) = nil; |
5732 goto out; |
5663 goto out; |
5733 } |
5664 } |
5734 if (_buffered = (__INST(buffered) == true)) { |
5665 if (_buffered = (__INST(buffered) == true)) { |
5735 __WRITING__(f) |
5666 __WRITING__(f) |
5736 } |
5667 } |
5737 |
5668 |
5738 if (__isStringLike(aCollection)) { |
5669 if (__isStringLike(aCollection)) { |
5739 len = __stringSize(aCollection); |
5670 len = __stringSize(aCollection); |
5740 #ifdef WIN32 |
5671 #ifdef WIN32 |
5741 if ((f == __win32_stdout()) || (f == __win32_stderr())) { |
5672 if ((f == __win32_stdout()) || (f == __win32_stderr())) { |
5742 cnt = __win32_fwrite(__stringVal(aCollection), 1, len, f); |
5673 cnt = __win32_fwrite(__stringVal(aCollection), 1, len, f); |
5743 } else |
5674 } else |
5744 #endif |
5675 #endif |
5745 { |
5676 { |
5746 o_offs = (char *)__stringVal(aCollection)-(char *)__InstPtr(aCollection); |
5677 o_offs = (char *)__stringVal(aCollection)-(char *)__InstPtr(aCollection); |
5747 __WRITEBYTES_OBJ__(cnt, f, aCollection, o_offs, len, _buffered, __INST(handleType)); |
5678 __WRITEBYTES_OBJ__(cnt, f, aCollection, o_offs, len, _buffered, __INST(handleType)); |
5748 } |
5679 } |
5749 } else { |
5680 } else { |
5750 if (__INST(binary) == true) { |
5681 if (__INST(binary) == true) { |
5751 INT offs; |
5682 INT offs; |
5752 |
5683 |
5753 if (__isByteArrayLike(aCollection)) { |
5684 if (__isByteArrayLike(aCollection)) { |
5754 offs = 0; |
5685 offs = 0; |
5755 len = __byteArraySize(aCollection); |
5686 len = __byteArraySize(aCollection); |
5756 } else if (__isBytes(aCollection)) { |
5687 } else if (__isBytes(aCollection)) { |
5757 offs = __OBJS2BYTES__(__intVal(__ClassInstPtr(__qClass(aCollection))->c_ninstvars)); |
5688 offs = __OBJS2BYTES__(__intVal(__ClassInstPtr(__qClass(aCollection))->c_ninstvars)); |
5758 len = __byteArraySize(aCollection) - offs; |
5689 len = __byteArraySize(aCollection) - offs; |
5759 } else |
5690 } else |
5760 goto out; |
5691 goto out; |
5761 #ifdef WIN32 |
5692 #ifdef WIN32 |
5762 if ((f == __win32_stdout()) || (f == __win32_stderr())) { |
5693 if ((f == __win32_stdout()) || (f == __win32_stderr())) { |
5763 cnt = __win32_fwrite(__stringVal(aCollection), 1, len, f); |
5694 cnt = __win32_fwrite(__stringVal(aCollection), 1, len, f); |
5764 } else |
5695 } else |
5765 #endif |
5696 #endif |
5766 { |
5697 { |
5767 o_offs = (char *)(__ByteArrayInstPtr(aCollection)->ba_element) - (char *)__InstPtr(aCollection); |
5698 o_offs = (char *)(__ByteArrayInstPtr(aCollection)->ba_element) - (char *)__InstPtr(aCollection); |
5768 o_offs += offs; |
5699 o_offs += offs; |
5769 __WRITEBYTES_OBJ__(cnt, f, aCollection, o_offs, len, _buffered, __INST(handleType)); |
5700 __WRITEBYTES_OBJ__(cnt, f, aCollection, o_offs, len, _buffered, __INST(handleType)); |
5770 } |
5701 } |
5771 } else |
5702 } else |
5772 goto out; |
5703 goto out; |
5773 } |
5704 } |
5774 |
5705 |
5775 if (cnt == len) { |
5706 if (cnt == len) { |
5776 if (__isSmallInteger(__INST(position))) { |
5707 if (__isSmallInteger(__INST(position))) { |
5777 INT np = __intVal(__INST(position)) + len; |
5708 INT np = __intVal(__INST(position)) + len; |
5778 OBJ t; |
5709 OBJ t; |
5779 |
5710 |
5780 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
5711 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
5781 } else { |
5712 } else { |
5782 __INST(position) = nil; /* i.e. do not know */ |
5713 __INST(position) = nil; /* i.e. do not know */ |
5783 } |
5714 } |
5784 RETURN (self); |
5715 RETURN (self); |
5785 } |
5716 } |
5786 error = __mkSmallInteger(__threadErrno); |
5717 error = __mkSmallInteger(__threadErrno); |
5787 } |
5718 } |
5788 } |
5719 } |
5789 out: ; |
5720 out: ; |
5790 %}. |
5721 %}. |
5791 error notNil ifTrue:[ |
5722 error notNil ifTrue:[ |
5792 lastErrorNumber := error. |
5723 lastErrorNumber := error. |
5793 self writeError:error. |
5724 self writeError:error. |
5794 ^ self |
5725 ^ self |
5795 ]. |
5726 ]. |
5796 handle isNil ifTrue:[self errorNotOpen. ^ self]. |
5727 handle isNil ifTrue:[self errorNotOpen. ^ self]. |
5797 (mode == #readonly) ifTrue:[self errorReadOnly. ^ self]. |
5728 (mode == #readonly) ifTrue:[self errorReadOnly. ^ self]. |
5798 |
5729 |
5799 ^ super nextPutAll:aCollection |
5730 ^ super nextPutAll:aCollection |
5814 |
5745 |
5815 __INST(lastErrorNumber) = nil; |
5746 __INST(lastErrorNumber) = nil; |
5816 if ((__INST(handleType) == nil) |
5747 if ((__INST(handleType) == nil) |
5817 || (__INST(handleType) == @symbol(filePointer)) |
5748 || (__INST(handleType) == @symbol(filePointer)) |
5818 || (__INST(handleType) == @symbol(socketFilePointer)) |
5749 || (__INST(handleType) == @symbol(socketFilePointer)) |
|
5750 || (__INST(handleType) == @symbol(socketHandle)) |
5819 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
5751 || (__INST(handleType) == @symbol(pipeFilePointer))) { |
5820 if (((fp = __INST(handle)) != nil) |
5752 if (((fp = __INST(handle)) != nil) |
5821 && (__INST(mode) != @symbol(readonly)) |
5753 && (__INST(mode) != @symbol(readonly)) |
5822 && __bothSmallInteger(start, stop) |
5754 && __bothSmallInteger(start, stop) |
5823 ) { |
5755 ) { |
5824 f = __FILEVal(fp); |
5756 f = __FILEVal(fp); |
5825 if (_buffered = (__INST(buffered) == true)) { |
5757 if (_buffered = (__INST(buffered) == true)) { |
5826 __WRITING__(f) |
5758 __WRITING__(f) |
5827 } |
5759 } |
5828 iStart = __intVal(start); |
5760 iStart = __intVal(start); |
5829 iStop = __intVal(stop); |
5761 iStop = __intVal(stop); |
5830 if ((iStart < 1) || (iStop < iStart)) { |
5762 if ((iStart < 1) || (iStop < iStart)) { |
5831 RETURN(self); |
5763 RETURN(self); |
5832 } |
5764 } |
5833 if (__isStringLike(aCollection)) { |
5765 if (__isStringLike(aCollection)) { |
5834 len = __stringSize(aCollection); |
5766 len = __stringSize(aCollection); |
5835 if (iStop > len) { |
5767 if (iStop > len) { |
5836 RETURN(self); |
5768 RETURN(self); |
5837 } |
5769 } |
5838 if (iStop > len) |
5770 if (iStop > len) |
5839 iStop = len; |
5771 iStop = len; |
5840 len = iStop - iStart + 1; |
5772 len = iStop - iStart + 1; |
5841 #ifdef WIN32 |
5773 #ifdef WIN32 |
5842 if ((f == __win32_stdout()) || (f == __win32_stderr())) { |
5774 if ((f == __win32_stdout()) || (f == __win32_stderr())) { |
5843 cnt = __win32_fwrite(__stringVal(aCollection)+iStart-1, 1, len, f); |
5775 cnt = __win32_fwrite(__stringVal(aCollection)+iStart-1, 1, len, f); |
5844 } else |
5776 } else |
5845 #endif |
5777 #endif |
5846 { |
5778 { |
5847 o_offs = (char *)__stringVal(aCollection)-(char *)__InstPtr(aCollection); |
5779 o_offs = (char *)__stringVal(aCollection)-(char *)__InstPtr(aCollection); |
5848 __WRITEBYTES_OBJ__(cnt, f, aCollection, o_offs+iStart-1, len, _buffered, __INST(handleType)); |
5780 __WRITEBYTES_OBJ__(cnt, f, aCollection, o_offs+iStart-1, len, _buffered, __INST(handleType)); |
5849 } |
5781 } |
5850 } else { |
5782 } else { |
5851 if (__INST(binary) == true) { |
5783 if (__INST(binary) == true) { |
5852 int offs; |
5784 int offs; |
5853 |
5785 |
5854 if (__isByteArrayLike(aCollection)) { |
5786 if (__isByteArrayLike(aCollection)) { |
5855 offs = 0; |
5787 offs = 0; |
5856 len = __byteArraySize(aCollection); |
5788 len = __byteArraySize(aCollection); |
5857 } else if (__isBytes(aCollection)) { |
5789 } else if (__isBytes(aCollection)) { |
5858 offs = __OBJS2BYTES__(__intVal(__ClassInstPtr(__qClass(aCollection))->c_ninstvars)); |
5790 offs = __OBJS2BYTES__(__intVal(__ClassInstPtr(__qClass(aCollection))->c_ninstvars)); |
5859 len = __byteArraySize(aCollection) - offs; |
5791 len = __byteArraySize(aCollection) - offs; |
5860 } else |
5792 } else |
5861 goto out; |
5793 goto out; |
5862 |
5794 |
5863 if (iStop > len) { |
5795 if (iStop > len) { |
5864 RETURN(self); |
5796 RETURN(self); |
5865 } |
5797 } |
5866 if (iStop > len) |
5798 if (iStop > len) |
5867 iStop = len; |
5799 iStop = len; |
5868 len = iStop - iStart + 1; |
5800 len = iStop - iStart + 1; |
5869 offs += iStart - 1; |
5801 offs += iStart - 1; |
5870 #ifdef WIN32 |
5802 #ifdef WIN32 |
5871 if ((f == __win32_stdout()) || (f == __win32_stderr())) { |
5803 if ((f == __win32_stdout()) || (f == __win32_stderr())) { |
5872 cnt = __win32_fwrite(__stringVal(aCollection)+iStart-1, 1, len, f); |
5804 cnt = __win32_fwrite(__stringVal(aCollection)+iStart-1, 1, len, f); |
5873 } else |
5805 } else |
5874 #endif |
5806 #endif |
5875 { |
5807 { |
5876 o_offs = (char *)(__ByteArrayInstPtr(aCollection)->ba_element)-(char *)__InstPtr(aCollection); |
5808 o_offs = (char *)(__ByteArrayInstPtr(aCollection)->ba_element)-(char *)__InstPtr(aCollection); |
5877 __WRITEBYTES_OBJ__(cnt, f, aCollection, o_offs+offs, len, _buffered, __INST(handleType)); |
5809 __WRITEBYTES_OBJ__(cnt, f, aCollection, o_offs+offs, len, _buffered, __INST(handleType)); |
5878 } |
5810 } |
5879 } else |
5811 } else |
5880 goto out; |
5812 goto out; |
5881 } |
5813 } |
5882 if (cnt == len) { |
5814 if (cnt == len) { |
5883 if (__isSmallInteger(__INST(position))) { |
5815 if (__isSmallInteger(__INST(position))) { |
5884 INT np = __intVal(__INST(position)) + len; |
5816 INT np = __intVal(__INST(position)) + len; |
5885 OBJ t; |
5817 OBJ t; |
5886 |
5818 |
5887 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
5819 t = __MKINT(np); __INST(position) = t; __STORE(self, t); |
5888 } else { |
5820 } else { |
5889 __INST(position) = nil; /* i.e. do not know */ |
5821 __INST(position) = nil; /* i.e. do not know */ |
5890 } |
5822 } |
5891 RETURN (self); |
5823 RETURN (self); |
5892 } |
5824 } |
5893 error = __mkSmallInteger(__threadErrno); |
5825 error = __mkSmallInteger(__threadErrno); |
5894 } |
5826 } |
5895 } |
5827 } |
5896 out: ; |
5828 out: ; |
5897 %}. |
5829 %}. |
5898 error notNil ifTrue:[ |
5830 error notNil ifTrue:[ |
5899 lastErrorNumber := error. |
5831 lastErrorNumber := error. |
5900 self writeError:error. |
5832 self writeError:error. |
5901 ^ self |
5833 ^ self |
5902 ]. |
5834 ]. |
5903 ^ super nextPutAll:aCollection startingAt:start to:stop |
5835 ^ super nextPutAll:aCollection startingAt:start to:stop |
5904 ! |
5836 ! |
5905 |
5837 |
5906 nextPutAllUnicode:aString |
5838 nextPutAllUnicode:aString |