ReadStream.st
changeset 16882 d00fc1a07bf4
parent 16862 3982aa39c337
child 17597 a78c4a2bf366
equal deleted inserted replaced
16881:0971640d795b 16882:d00fc1a07bf4
   159 
   159 
   160     |ret|
   160     |ret|
   161 
   161 
   162 %{  /* NOCONTEXT */
   162 %{  /* NOCONTEXT */
   163 
   163 
   164     REGISTER int pos;
   164     REGISTER INT pos;
   165     unsigned ch;
   165     unsigned ch;
   166     OBJ coll, p, l;
   166     OBJ coll, p, l;
   167 
   167 
   168     coll = __INST(collection);
   168     coll = __INST(collection);
   169     p = __INST(position);
   169     p = __INST(position);
   170     l = __INST(readLimit);
   170     l = __INST(readLimit);
   171 
   171 
   172     if (__isNonNilObject(coll) && __bothSmallInteger(p, l)) {
   172     if (__isNonNilObject(coll) && __bothSmallInteger(p, l)) {
   173 
   173 
   174 	pos = __intVal(p);
   174 	pos = __intVal(p);
   175 	/* make 1-based */
   175 	if (pos >= 0 && pos < __intVal(l)) {
   176 	pos = pos + 1;
       
   177 	if (pos > 0 && pos <= __intVal(l)) {
       
   178 	    OBJ cls, ret;
   176 	    OBJ cls, ret;
   179 
   177 
   180 	    cls = __qClass(coll);
   178 	    cls = __qClass(coll);
   181 	    if (cls == @global(String)) {
   179 	    if (cls == @global(String)) {
   182 		if (pos <= __stringSize(coll)) {
   180 		if (pos < __stringSize(coll)) {
   183 		    ch = __stringVal(coll)[pos-1];
   181 		    ch = __stringVal(coll)[pos];
   184 		    ret = __MKCHARACTER(ch);
   182 		    ret = __MKCHARACTER(ch);
   185 		    __INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1);
   183 		    __INST(position) = __mkSmallInteger(pos+1);
   186 		    RETURN ( ret );
   184 		    RETURN ( ret );
   187 		}
   185 		}
   188 	    } else if (cls == @global(ByteArray)) {
   186 	    } else if (cls == @global(ByteArray)) {
   189 		if (pos <= __byteArraySize(coll)) {
   187 		if (pos < __byteArraySize(coll)) {
   190 		    ch = __ByteArrayInstPtr(coll)->ba_element[pos-1];
   188 		    ch = __ByteArrayInstPtr(coll)->ba_element[pos];
   191 		    ret = __mkSmallInteger(ch);
   189 		    ret = __mkSmallInteger(ch);
   192 		    __INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1);
   190 		    __INST(position) = __mkSmallInteger(pos+1);
   193 		    RETURN ( ret );
   191 		    RETURN ( ret );
   194 		}
   192 		}
   195 	    } else if (cls == @global(Unicode16String)) {
   193 	    } else if (cls == @global(Unicode16String)) {
   196 		if (pos <= __unicode16StringSize(coll)) {
   194 		if (pos < __unicode16StringSize(coll)) {
   197 		    ch = __Unicode16StringInstPtr(coll)->s_element[pos-1];
   195 		    ch = __Unicode16StringInstPtr(coll)->s_element[pos];
   198 		    ret = __MKUCHARACTER(ch);
   196 		    ret = __MKUCHARACTER(ch);
   199 		    __INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1);
   197 		    __INST(position) = __mkSmallInteger(pos+1);
   200 		    RETURN ( ret );
   198 		    RETURN ( ret );
   201 		}
   199 		}
   202 	    } else if (cls == @global(Array)) {
   200 	    } else if (cls == @global(Array)) {
   203 		if (pos <= __arraySize(coll)) {
   201 		if (pos < __arraySize(coll)) {
   204 		    ret = __ArrayInstPtr(coll)->a_element[pos-1];
   202 		    ret = __ArrayInstPtr(coll)->a_element[pos];
   205 		    __INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1);
   203 		    __INST(position) = __mkSmallInteger(pos+1);
   206 		    RETURN ( ret );
   204 		    RETURN ( ret );
   207 		}
   205 		}
   208 	    }
   206 	    }
   209 	}
   207 	}
   210     }
   208     }
   211 %}.
   209 %}.
   212     (position >= readLimit) ifTrue:[^ self pastEndRead].
   210     (position >= readLimit) ifTrue:[^ self pastEndRead].
   213     ret := collection at:(position + 1).
       
   214     position := position + 1.
   211     position := position + 1.
       
   212     ret := collection at:position.
   215     ^ ret
   213     ^ ret
   216 !
   214 !
   217 
   215 
   218 next:count
   216 next:count
   219     "return the next count elements of the stream as aCollection,
   217     "return the next count elements of the stream as aCollection,
   244      Skips any non-alphanumeric chars first.
   242      Skips any non-alphanumeric chars first.
   245      - tuned for speed on String-Streams for faster scanning"
   243      - tuned for speed on String-Streams for faster scanning"
   246 %{
   244 %{
   247     /* speedup, if collection is a string */
   245     /* speedup, if collection is a string */
   248 
   246 
   249     int pos, limit, sz;
   247     INT pos, limit, sz;
   250     int len;
   248     INT len;
   251     char buffer[256];
   249     char buffer[256];
   252     REGISTER unsigned char *cp;
   250     REGISTER unsigned char *cp;
   253     REGISTER unsigned ch;
   251     REGISTER unsigned ch;
   254     OBJ coll, p, l;
   252     OBJ coll, p, l;
   255 
   253 
   315 
   313 
   316     |ret|
   314     |ret|
   317 
   315 
   318 %{  /* NOCONTEXT */
   316 %{  /* NOCONTEXT */
   319 
   317 
   320     REGISTER int pos;
   318     REGISTER INT pos;
   321     unsigned ch;
   319     unsigned ch;
   322     OBJ coll, p, l;
   320     OBJ coll, p, l;
   323 
   321 
   324     coll = __INST(collection);
   322     coll = __INST(collection);
   325     p = __INST(position);
   323     p = __INST(position);
   326     l = __INST(readLimit);
   324     l = __INST(readLimit);
   327 
   325 
   328     if (__isNonNilObject(coll) && __bothSmallInteger(p, l)) {
   326     if (__isNonNilObject(coll) && __bothSmallInteger(p, l)) {
   329 
   327 
   330 	pos = __intVal(p);
   328 	pos = __intVal(p);
   331 	/* make 1-based */
   329 	if (pos >= 0 && pos < __intVal(l)) {
   332 	pos = pos + 1;
       
   333 	if (pos > 0 && pos <= __intVal(l)) {
       
   334 	    OBJ cls, ret;
   330 	    OBJ cls, ret;
   335 
   331 
   336 	    cls = __qClass(coll);
   332 	    cls = __qClass(coll);
   337 	    if (cls == @global(String)) {
   333 	    if (cls == @global(String)) {
   338 		if (pos <= __stringSize(coll)) {
   334 		if (pos < __stringSize(coll)) {
   339 		    ch = __stringVal(coll)[pos-1];
   335 		    ch = __stringVal(coll)[pos];
   340 		    ret = __mkSmallInteger(ch);
   336 		    ret = __mkSmallInteger(ch);
   341 		    __INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1);
   337 		    __INST(position) = __mkSmallInteger(pos+1);
   342 		    RETURN ( ret );
   338 		    RETURN ( ret );
   343 		}
   339 		}
   344 	    } else if (cls == @global(ByteArray)) {
   340 	    } else if (cls == @global(ByteArray)) {
   345 		if (pos <= __byteArraySize(coll)) {
   341 		if (pos < __byteArraySize(coll)) {
   346 		    ch = __ByteArrayInstPtr(coll)->ba_element[pos-1];
   342 		    ch = __ByteArrayInstPtr(coll)->ba_element[pos];
   347 		    ret = __mkSmallInteger(ch);
   343 		    ret = __mkSmallInteger(ch);
   348 		    __INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1);
   344 		    __INST(position) = __mkSmallInteger(pos+1);
   349 		    RETURN ( ret );
   345 		    RETURN ( ret );
   350 		}
   346 		}
   351 	    } else if (cls == @global(Array)) {
   347 	    } else if (cls == @global(Array)) {
   352 		if (pos <= __arraySize(coll)) {
   348 		if (pos < __arraySize(coll)) {
   353 		    ret = __ArrayInstPtr(coll)->a_element[pos-1];
   349 		    ret = __ArrayInstPtr(coll)->a_element[pos];
   354 		    if (!__isSmallInteger(ret) || __intVal(ret) > 255) goto out;
   350 		    if (!__isSmallInteger(ret) || __intVal(ret) > 255) goto out;
   355 		    __INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1);
   351 		    __INST(position) = __mkSmallInteger(pos+1);
   356 		    RETURN ( ret );
   352 		    RETURN ( ret );
   357 		}
   353 		}
   358 	    }
   354 	    }
   359 	}
   355 	}
   360     }
   356     }
   408      Transcript showCR:('n = %1; buffer = <%2>' bindWith:n with:buffer)
   404      Transcript showCR:('n = %1; buffer = <%2>' bindWith:n with:buffer)
   409     "
   405     "
   410 !
   406 !
   411 
   407 
   412 nextDecimalInteger
   408 nextDecimalInteger
   413     "read the next integer in radix 10. dont skip whitespace.
   409     "read the next integer in radix 10.
   414      - tuned for speed on String-Streams for faster scanning"
   410      Does NOT skip initial whitespace.
       
   411      The streams elements should be characters.
       
   412 
       
   413      Be careful - this method returns 0 if not positioned on a digit intitially
       
   414      or if the end of the stream is encountered.
       
   415 
       
   416      Tuned for speed on String-Streams for faster scanning"
   415 
   417 
   416     |value nextOne|
   418     |value nextOne|
   417 %{
   419 %{
   418     int pos, limit, sz;
   420     INT pos, limit, sz;
   419     REGISTER unsigned char *cp;
   421     REGISTER unsigned char *cp;
   420     REGISTER unsigned ch;
   422     REGISTER unsigned ch;
   421     INT val = 0;
   423     INT val = 0;
   422     OBJ coll, p, l;
   424     OBJ coll, p, l;
   423 
   425 
   427 
   429 
   428     if (__isStringLike(coll) && __bothSmallInteger(p, l)) {
   430     if (__isStringLike(coll) && __bothSmallInteger(p, l)) {
   429 
   431 
   430 	pos = __intVal(p);
   432 	pos = __intVal(p);
   431 	/* make 1-based */
   433 	/* make 1-based */
   432 	pos = pos + 1;
   434 	pos++;
   433 	limit = __intVal(l);
   435 	limit = __intVal(l);
   434 	sz = __qSize(coll) - OHDR_SIZE;
   436 	sz = __qSize(coll) - OHDR_SIZE;
   435 	if (sz < limit)
   437 	if (sz < limit)
   436 	    limit = sz;
   438 	    limit = sz;
   437 	cp = __stringVal(coll) + pos - 1;
   439 	cp = __stringVal(coll) + pos - 1;
   444 	    val = val * 10 + (ch - '0');
   446 	    val = val * 10 + (ch - '0');
   445 	    pos++;
   447 	    pos++;
   446 	    if (val > (_MAX_INT / 10)) goto oops;
   448 	    if (val > (_MAX_INT / 10)) goto oops;
   447 	    cp++;
   449 	    cp++;
   448 	}
   450 	}
   449 	pos = pos - 1;
   451 	pos--;
   450 	__INST(position) = __mkSmallInteger(pos);
   452 	__INST(position) = __mkSmallInteger(pos);
   451 	RETURN (__mkSmallInteger(val));
   453 	RETURN (__mkSmallInteger(val));
   452     }
   454     }
   453 oops:
   455 oops:
   454     value = __mkSmallInteger(val);
   456     value = __mkSmallInteger(val);
   473 
   475 
   474     |ret|
   476     |ret|
   475 
   477 
   476 %{  /* NOCONTEXT */
   478 %{  /* NOCONTEXT */
   477 
   479 
   478     REGISTER int pos;
   480     REGISTER INT pos;
   479     unsigned ch;
   481     unsigned ch;
   480     OBJ coll, p, l;
   482     OBJ coll, p, l;
   481 
   483 
   482     coll = __INST(collection);
   484     coll = __INST(collection);
   483     p = __INST(position);
   485     p = __INST(position);
   484     l = __INST(readLimit);
   486     l = __INST(readLimit);
   485 
   487 
   486     if (__isNonNilObject(coll) && __bothSmallInteger(p, l)) {
   488     if (__isNonNilObject(coll) && __bothSmallInteger(p, l)) {
   487 	pos = __intVal(p);
   489 	pos = __intVal(p);
   488 	/* make 1-based */
   490 	if (pos >= 0) {
   489 	pos = pos + 1;
       
   490 	if (pos > 0) {
       
   491 	    OBJ cls, ret;
   491 	    OBJ cls, ret;
   492 
   492 
   493 	    if (pos > __intVal(l)) {
   493 	    if (pos >= __intVal(l)) {
   494 		RETURN(nil);
   494 		RETURN(nil);
   495 	    }
   495 	    }
   496 
   496 
   497 	    cls = __qClass(coll);
   497 	    cls = __qClass(coll);
   498 	    if (cls == @global(String)) {
   498 	    if (cls == @global(String)) {
   499 		if (pos <= __stringSize(coll)) {
   499 		if (pos < __stringSize(coll)) {
   500 		    ch = __stringVal(coll)[pos-1];
   500 		    ch = __stringVal(coll)[pos];
   501 		    ret = __MKCHARACTER(ch);
   501 		    ret = __MKCHARACTER(ch);
   502 		    __INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1);
   502 		    __INST(position) = __mkSmallInteger(pos + 1);
   503 		    RETURN ( ret );
   503 		    RETURN ( ret );
   504 		}
   504 		}
   505 	    } else if (cls == @global(ByteArray)) {
   505 	    } else if (cls == @global(ByteArray)) {
   506 		if (pos <= __byteArraySize(coll)) {
   506 		if (pos < __byteArraySize(coll)) {
   507 		    ch = __ByteArrayInstPtr(coll)->ba_element[pos-1];
   507 		    ch = __ByteArrayInstPtr(coll)->ba_element[pos];
   508 		    ret = __mkSmallInteger(ch);
   508 		    ret = __mkSmallInteger(ch);
   509 		    __INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1);
   509 		    __INST(position) = __mkSmallInteger(pos + 1);
   510 		    RETURN ( ret );
   510 		    RETURN ( ret );
   511 		}
   511 		}
   512 	    } else if (cls == @global(Unicode16String)) {
   512 	    } else if (cls == @global(Unicode16String)) {
   513 		if (pos <= __unicode16StringSize(coll)) {
   513 		if (pos < __unicode16StringSize(coll)) {
   514 		    ch = __Unicode16StringInstPtr(coll)->s_element[pos-1];
   514 		    ch = __Unicode16StringInstPtr(coll)->s_element[pos];
   515 		    ret = __MKUCHARACTER(ch);
   515 		    ret = __MKUCHARACTER(ch);
   516 		    __INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1);
   516 		    __INST(position) = __mkSmallInteger(pos + 1);
   517 		    RETURN ( ret );
   517 		    RETURN ( ret );
   518 		}
   518 		}
   519 	    } else if (cls == @global(Array)) {
   519 	    } else if (cls == @global(Array)) {
   520 		if (pos <= __arraySize(coll)) {
   520 		if (pos < __arraySize(coll)) {
   521 		    ret = __ArrayInstPtr(coll)->a_element[pos-1];
   521 		    ret = __ArrayInstPtr(coll)->a_element[pos];
   522 		    __INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1);
   522 		    __INST(position) = __mkSmallInteger(pos + 1);
   523 		    RETURN ( ret );
   523 		    RETURN ( ret );
   524 		}
   524 		}
   525 	    }
   525 	    }
   526 	}
   526 	}
   527     }
   527     }
   528 %}.
   528 %}.
   529     ret := collection at:(position + 1).
       
   530     position := position + 1.
   529     position := position + 1.
       
   530     ret := collection at:position.
   531     ^ ret
   531     ^ ret
   532 !
   532 !
   533 
   533 
   534 nextPeek
   534 nextPeek
   535     "advance read pointer return the peek element.
   535     "advance read pointer return the peek element.
   542     coll = __INST(collection);
   542     coll = __INST(collection);
   543     p = __INST(position);
   543     p = __INST(position);
   544     l = __INST(readLimit);
   544     l = __INST(readLimit);
   545 
   545 
   546     if (__isStringLike(coll) && __bothSmallInteger(p, l)) {
   546     if (__isStringLike(coll) && __bothSmallInteger(p, l)) {
   547 	REGISTER int pos;
   547 	REGISTER INT pos;
   548 	unsigned ch;
   548 	unsigned ch;
   549 
   549 
   550 	pos = __intVal(p);
   550 	pos = __intVal(p);
   551 	/* make 1-based */
   551 	pos++;
   552 	pos = pos + 1;
       
   553 	if ((pos > 0) && (pos < __intVal(l)) && (pos < __stringSize(coll))) {
   552 	if ((pos > 0) && (pos < __intVal(l)) && (pos < __stringSize(coll))) {
   554 	    pos = pos + 1;
   553 	    ch = __stringVal(coll)[pos];
   555 	    ch = __stringVal(coll)[pos-1];
       
   556 	    pos = pos - 1;
       
   557 	    __INST(position) = __mkSmallInteger(pos);
   554 	    __INST(position) = __mkSmallInteger(pos);
   558 	    RETURN ( __MKCHARACTER(ch) );
   555 	    RETURN ( __MKCHARACTER(ch) );
   559 	}
   556 	}
   560     }
   557     }
   561 %}.
   558 %}.
   570      return nil, if there is no next element.
   567      return nil, if there is no next element.
   571      - tuned for a bit more speed on String/ByteArray/Array-Streams"
   568      - tuned for a bit more speed on String/ByteArray/Array-Streams"
   572 
   569 
   573 %{  /* NOCONTEXT */
   570 %{  /* NOCONTEXT */
   574 
   571 
   575     REGISTER int pos;
   572     REGISTER INT pos;
   576     unsigned ch;
   573     unsigned ch;
   577     OBJ coll;
   574     OBJ coll;
   578     OBJ cls, p, l;
   575     OBJ cls, p, l;
   579 
   576 
   580     coll = __INST(collection);
   577     coll = __INST(collection);
   582     l = __INST(readLimit);
   579     l = __INST(readLimit);
   583 
   580 
   584     if (__isNonNilObject(coll) && __bothSmallInteger(p, l)) {
   581     if (__isNonNilObject(coll) && __bothSmallInteger(p, l)) {
   585 
   582 
   586 	pos = __intVal(p);
   583 	pos = __intVal(p);
   587 	/* make 1-based */
   584 	if ((pos < __intVal(l)) && (pos >= 0)) {
   588 	pos = pos + 1;
       
   589 	if (pos <= __intVal(l) && pos > 0) {
       
   590 	    cls = __qClass(coll);
   585 	    cls = __qClass(coll);
   591 	    if (cls == @global(String)) {
   586 	    if (cls == @global(String)) {
   592 		if (pos <= __stringSize(coll)) {
   587 		if (pos < __stringSize(coll)) {
   593 		    ch = __stringVal(coll)[pos-1];
   588 		    ch = __stringVal(coll)[pos];
   594 		    RETURN ( __MKCHARACTER(ch) );
   589 		    RETURN ( __MKCHARACTER(ch) );
   595 		}
   590 		}
   596 	    } else if (cls == @global(ByteArray)) {
   591 	    } else if (cls == @global(ByteArray)) {
   597 		if (pos <= __byteArraySize(coll)) {
   592 		if (pos < __byteArraySize(coll)) {
   598 		    ch = __ByteArrayInstPtr(coll)->ba_element[pos-1];
   593 		    ch = __ByteArrayInstPtr(coll)->ba_element[pos];
   599 		    RETURN ( __mkSmallInteger(ch) );
   594 		    RETURN ( __mkSmallInteger(ch) );
   600 		}
   595 		}
   601 	    } else if (cls == @global(Array)) {
   596 	    } else if (cls == @global(Array)) {
   602 		if (pos <= __arraySize(coll)) {
   597 		if (pos < __arraySize(coll)) {
   603 		    RETURN ( __ArrayInstPtr(coll)->a_element[pos-1]);
   598 		    RETURN ( __ArrayInstPtr(coll)->a_element[pos]);
   604 		}
   599 		}
   605 	    }
   600 	    }
   606 	}
   601 	}
   607     }
   602     }
   608 %}.
   603 %}.
   617      However, unlike #peek, this does not raise an atEnd-query signal - even
   612      However, unlike #peek, this does not raise an atEnd-query signal - even
   618      if handled. Instead, nil is returned immediately."
   613      if handled. Instead, nil is returned immediately."
   619 
   614 
   620 %{  /* NOCONTEXT */
   615 %{  /* NOCONTEXT */
   621 
   616 
   622     REGISTER int pos;
   617     REGISTER INT pos;
   623     unsigned ch;
   618     unsigned ch;
   624     OBJ coll;
   619     OBJ coll;
   625     OBJ cls, p, l;
   620     OBJ cls, p, l;
   626 
   621 
   627     coll = __INST(collection);
   622     coll = __INST(collection);
   629     l = __INST(readLimit);
   624     l = __INST(readLimit);
   630 
   625 
   631     if (__isNonNilObject(coll) && __bothSmallInteger(p, l)) {
   626     if (__isNonNilObject(coll) && __bothSmallInteger(p, l)) {
   632 
   627 
   633 	pos = __intVal(p);
   628 	pos = __intVal(p);
   634 	/* make 1-based */
   629 	if ((pos < __intVal(l)) && (pos >= 0)) {
   635 	pos = pos + 1;
       
   636 	if (pos <= __intVal(l) && pos > 0) {
       
   637 	    cls = __qClass(coll);
   630 	    cls = __qClass(coll);
   638 	    if (cls == @global(String)) {
   631 	    if (cls == @global(String)) {
   639 		if (pos <= __stringSize(coll)) {
   632 		if (pos < __stringSize(coll)) {
   640 		    ch = __stringVal(coll)[pos-1];
   633 		    ch = __stringVal(coll)[pos];
   641 		    RETURN ( __MKCHARACTER(ch) );
   634 		    RETURN ( __MKCHARACTER(ch) );
   642 		}
   635 		}
   643 		RETURN ( nil );
   636 		RETURN ( nil );
   644 	    } else if (cls == @global(ByteArray)) {
   637 	    } else if (cls == @global(ByteArray)) {
   645 		if (pos <= __byteArraySize(coll)) {
   638 		if (pos < __byteArraySize(coll)) {
   646 		    ch = __ByteArrayInstPtr(coll)->ba_element[pos-1];
   639 		    ch = __ByteArrayInstPtr(coll)->ba_element[pos];
   647 		    RETURN ( __mkSmallInteger(ch) );
   640 		    RETURN ( __mkSmallInteger(ch) );
   648 		}
   641 		}
   649 		RETURN ( nil );
   642 		RETURN ( nil );
   650 	    } else if (cls == @global(Array)) {
   643 	    } else if (cls == @global(Array)) {
   651 		if (pos <= __arraySize(coll)) {
   644 		if (pos < __arraySize(coll)) {
   652 		    RETURN ( __ArrayInstPtr(coll)->a_element[pos-1]);
   645 		    RETURN ( __ArrayInstPtr(coll)->a_element[pos]);
   653 		}
   646 		}
   654 		RETURN ( nil );
   647 		RETURN ( nil );
   655 	    }
   648 	    }
   656 	}
   649 	}
   657     }
   650     }
   673     l = __INST(readLimit);
   666     l = __INST(readLimit);
   674 
   667 
   675     if (__isStringLike(coll) && __bothSmallInteger(p, l)) {
   668     if (__isStringLike(coll) && __bothSmallInteger(p, l)) {
   676 	REGISTER unsigned char *chars;
   669 	REGISTER unsigned char *chars;
   677 	REGISTER unsigned ch;
   670 	REGISTER unsigned ch;
   678 	REGISTER int pos;
   671 	REGISTER INT pos;
   679 	int limit;
   672 	INT limit;
   680 	int sz;
   673 	INT sz;
   681 
   674 
   682 	pos = __intVal(p);
   675 	pos = __intVal(p);
   683 	/* make 1-based */
   676 	/* make 1-based */
   684 	pos = pos + 1;
   677 	pos++;
   685 	if (pos <= 0) {
   678 	if (pos <= 0) {
   686 	    RETURN ( nil );
   679 	    RETURN ( nil );
   687 	}
   680 	}
   688 
   681 
   689 	limit = __intVal(l);
   682 	limit = __intVal(l);
   692 	    limit = sz;
   685 	    limit = sz;
   693 	}
   686 	}
   694 
   687 
   695 	chars = (unsigned char *)(__stringVal(coll) + pos - 1);
   688 	chars = (unsigned char *)(__stringVal(coll) + pos - 1);
   696 	while (pos <= limit) {
   689 	while (pos <= limit) {
   697 	    pos++;
       
   698 	    ch = *chars++;
   690 	    ch = *chars++;
   699 	    if ((ch > 0x20)
   691 	    if ((ch > 0x20)
   700 	     || ((ch != ' ')
   692 	     || ((ch != ' ')
   701 		 && (ch != '\t')
   693 		 && (ch != '\t')
   702 		 && (ch != '\r')
   694 		 && (ch != '\r')
   703 		 && (ch != '\n')
   695 		 && (ch != '\n')
   704 		 && (ch != '\f')
   696 		 && (ch != '\f')
   705 		 && (ch != 0x0B))) {
   697 		 && (ch != 0x0B))) {
   706 		pos = pos - 1;
       
   707 		__INST(position) = __mkSmallInteger(pos-1);
   698 		__INST(position) = __mkSmallInteger(pos-1);
   708 		RETURN ( __MKCHARACTER(ch) );
   699 		RETURN ( __MKCHARACTER(ch) );
   709 	    }
   700 	    }
   710 	}
   701 	    pos++;
   711 	pos = pos - 1;
   702 	}
       
   703 	pos--;
   712 	__INST(position) = __mkSmallInteger(pos);
   704 	__INST(position) = __mkSmallInteger(pos);
   713 	RETURN ( nil );
   705 	RETURN ( nil );
   714     }
   706     }
   715 %}.
   707 %}.
   716     ^ super skipSeparators
   708     ^ super skipSeparators
   738     l = __INST(readLimit);
   730     l = __INST(readLimit);
   739 
   731 
   740     if (__isStringLike(coll) && __bothSmallInteger(p, l)) {
   732     if (__isStringLike(coll) && __bothSmallInteger(p, l)) {
   741 	REGISTER unsigned char *chars;
   733 	REGISTER unsigned char *chars;
   742 	REGISTER unsigned ch;
   734 	REGISTER unsigned ch;
   743 	REGISTER int pos;
   735 	REGISTER INT pos;
   744 	int limit;
   736 	INT limit;
       
   737 	INT sz;
   745 
   738 
   746 	pos = __intVal(p);
   739 	pos = __intVal(p);
   747 	/* make 1-based */
   740 	/* make 1-based */
   748 	pos = pos + 1;
   741 	pos = pos + 1;
   749 	if (pos <= 0) {
   742 	if (pos <= 0) {
   750 	    RETURN ( nil );
   743 	    RETURN ( nil );
   751 	}
   744 	}
   752 
   745 
   753 	limit = __intVal(l);
   746 	limit = __intVal(l);
   754 	if (limit > (__qSize(coll) - OHDR_SIZE))
   747 	sz = __qSize(coll) - OHDR_SIZE;
   755 	    limit = __qSize(coll) - OHDR_SIZE;
   748 	if (limit > sz)
       
   749 	    limit = sz;
   756 
   750 
   757 	chars = (unsigned char *)(__stringVal(coll) + pos - 1);
   751 	chars = (unsigned char *)(__stringVal(coll) + pos - 1);
   758 	while (pos <= limit) {
   752 	while (pos <= limit) {
   759 	    ch = *chars++;
   753 	    ch = *chars++;
   760 	    if (((int)ch > 0x20)
   754 	    if (((int)ch > 0x20)
   762 		 (ch != ' ')
   756 		 (ch != ' ')
   763 		 && (ch != '\t')
   757 		 && (ch != '\t')
   764 		 && (ch != '\f')
   758 		 && (ch != '\f')
   765 		 && (ch != '\b')
   759 		 && (ch != '\b')
   766 		 && (ch != 0x0B))) {
   760 		 && (ch != 0x0B))) {
   767 		pos = pos - 1;
   761 		pos--;
   768 		__INST(position) = __mkSmallInteger(pos);
   762 		__INST(position) = __mkSmallInteger(pos);
   769 		RETURN ( __MKCHARACTER(ch) );
   763 		RETURN ( __MKCHARACTER(ch) );
   770 	    }
   764 	    }
   771 	    pos++;
   765 	    pos++;
   772 	}
   766 	}
   773 	pos = pos - 1;
   767 	pos--;
   774 	__INST(position) = __mkSmallInteger(pos);
   768 	__INST(position) = __mkSmallInteger(pos);
   775 	RETURN ( nil );
   769 	RETURN ( nil );
   776     }
   770     }
   777 %}
   771 %}
   778 .
   772 .
   795 
   789 
   796     if (__isStringLike(coll)
   790     if (__isStringLike(coll)
   797      && __isCharacter(anObject)
   791      && __isCharacter(anObject)
   798      && __bothSmallInteger(p, l)) {
   792      && __bothSmallInteger(p, l)) {
   799 	REGISTER unsigned char *chars;
   793 	REGISTER unsigned char *chars;
   800 	REGISTER int pos, limit;
   794 	REGISTER INT pos, limit;
   801 	unsigned ch;
   795 	unsigned ch;
   802 	int sz;
   796 	INT sz;
   803 
   797 
   804 	ch = __intVal(__characterVal(anObject));
   798 	ch = __intVal(__characterVal(anObject));
   805 	if (ch <= 0xFF) {
   799 	if (ch <= 0xFF) {
   806 	    pos = __intVal(p);
   800 	    pos = __intVal(p);
   807 	    pos = pos + 1;
   801 	    pos = pos + 1;
   815 
   809 
   816 	    chars = (unsigned char *)(__stringVal(coll) + pos - 1);
   810 	    chars = (unsigned char *)(__stringVal(coll) + pos - 1);
   817 	    while (pos < limit) {
   811 	    while (pos < limit) {
   818 		if (*chars == ch) {
   812 		if (*chars == ch) {
   819 		    ch = *++chars;
   813 		    ch = *++chars;
   820 		    pos++;
       
   821 		    pos = pos - 1;
       
   822 		    __INST(position) = __mkSmallInteger(pos);
   814 		    __INST(position) = __mkSmallInteger(pos);
   823 		    RETURN ( self );
   815 		    RETURN ( self );
   824 		}
   816 		}
   825 		chars++;
   817 		chars++;
   826 		pos++;
   818 		pos++;
   827 	    }
   819 	    }
   828 	    pos = pos - 1;
   820 	    __INST(position) = __mkSmallInteger(pos);
   829 	    __INST(position) = __mkSmallInteger(pos+1);
       
   830 	    RETURN ( nil );
   821 	    RETURN ( nil );
   831 	}
   822 	}
   832     }
   823     }
   833 %}.
   824 %}.
   834     ^ super skipThrough:anObject
   825     ^ super skipThrough:anObject
   841     if (__isString(_collection)
   832     if (__isString(_collection)
   842      && __isCharacter(anObject)) {
   833      && __isCharacter(anObject)) {
   843 	unsigned int ch = __intVal(__characterVal(anObject));
   834 	unsigned int ch = __intVal(__characterVal(anObject));
   844 
   835 
   845 	if (ch <= 0xFF) {
   836 	if (ch <= 0xFF) {
   846 	    int _startPos = __intVal(__INST(position));
   837 	    INT _startPos = __intVal(__INST(position));
   847 	    int _endIndex;
   838 	    INT _endIndex;
   848 	    char *startPtr = __stringVal(_collection) + _startPos;
   839 	    char *startPtr = __stringVal(_collection) + _startPos;
   849 	    char *foundPtr;
   840 	    char *foundPtr;
   850 	    OBJ rslt;
   841 	    OBJ rslt;
   851 
   842 	    INT nMax;
       
   843 #ifdef __osx__
       
   844 	    extern char*memchr(char *, int, long);
       
   845 #endif
   852 	    _endIndex = __stringSize(_collection);
   846 	    _endIndex = __stringSize(_collection);
   853 	    if (__isInteger(__INST(readLimit))) {
   847 	    if (__isInteger(__INST(readLimit))) {
   854 		int _readLimit = __intVal(__INST(readLimit));
   848 		int _readLimit = __intVal(__INST(readLimit));
   855 
   849 
   856 		if (_readLimit < _endIndex) _endIndex = _readLimit;
   850 		if (_readLimit < _endIndex) _endIndex = _readLimit;
   857 	    }
   851 	    }
   858 
   852 
   859 	    foundPtr = memchr( startPtr, ch, _endIndex-_startPos);
   853 	    nMax = _endIndex-_startPos;
       
   854 	    foundPtr = memchr( startPtr, ch, (long)nMax);
   860 	    if (foundPtr == 0) {
   855 	    if (foundPtr == 0) {
   861 		// not found
   856 		// not found
   862 		rslt = __MKSTRING_L(startPtr, _endIndex-_startPos);
   857 		rslt = __MKSTRING_L(startPtr, nMax);
   863 		__INST(position) = __mkSmallInteger(_endIndex);
   858 		__INST(position) = __mkSmallInteger(_endIndex);
   864 	    } else {
   859 	    } else {
       
   860 		INT n = foundPtr-startPtr;
       
   861 
   865 		// found at foundPtr
   862 		// found at foundPtr
   866 		rslt = __MKSTRING_L(startPtr, foundPtr-startPtr);
   863 		rslt = __MKSTRING_L(startPtr, n);
   867 		__INST(position) = __mkSmallInteger(_startPos + foundPtr-startPtr + 1);
   864 		__INST(position) = __mkSmallInteger(_startPos + n + 1);
   868 	    }
   865 	    }
   869 	    RETURN (rslt);
   866 	    RETURN (rslt);
   870 	}
   867 	}
   871     }
   868     }
   872 %}.
   869 %}.
   882 ! !
   879 ! !
   883 
   880 
   884 !ReadStream class methodsFor:'documentation'!
   881 !ReadStream class methodsFor:'documentation'!
   885 
   882 
   886 version
   883 version
   887     ^ '$Header: /cvs/stx/stx/libbasic/ReadStream.st,v 1.77 2014-09-26 13:52:50 ca Exp $'
   884     ^ '$Header: /cvs/stx/stx/libbasic/ReadStream.st,v 1.78 2014-10-04 20:33:07 cg Exp $'
   888 !
   885 !
   889 
   886 
   890 version_CVS
   887 version_CVS
   891     ^ '$Header: /cvs/stx/stx/libbasic/ReadStream.st,v 1.77 2014-09-26 13:52:50 ca Exp $'
   888     ^ '$Header: /cvs/stx/stx/libbasic/ReadStream.st,v 1.78 2014-10-04 20:33:07 cg Exp $'
   892 ! !
   889 ! !