ByteArray.st
changeset 249 810798c5c2e5
parent 221 28d5ebaa2a18
child 281 d63a7d2c31a6
equal deleted inserted replaced
248:601b44c71329 249:810798c5c2e5
    19 
    19 
    20 ByteArray comment:'
    20 ByteArray comment:'
    21 COPYRIGHT (c) 1989 by Claus Gittinger
    21 COPYRIGHT (c) 1989 by Claus Gittinger
    22 	      All Rights Reserved
    22 	      All Rights Reserved
    23 
    23 
    24 $Header: /cvs/stx/stx/libbasic/ByteArray.st,v 1.21 1995-02-05 21:28:17 claus Exp $
    24 $Header: /cvs/stx/stx/libbasic/ByteArray.st,v 1.22 1995-02-15 10:21:21 claus Exp $
    25 '!
    25 '!
    26 
    26 
    27 !ByteArray class methodsFor:'documentation'!
    27 !ByteArray class methodsFor:'documentation'!
    28 
    28 
    29 copyright
    29 copyright
    40 "
    40 "
    41 !
    41 !
    42 
    42 
    43 version
    43 version
    44 "
    44 "
    45 $Header: /cvs/stx/stx/libbasic/ByteArray.st,v 1.21 1995-02-05 21:28:17 claus Exp $
    45 $Header: /cvs/stx/stx/libbasic/ByteArray.st,v 1.22 1995-02-15 10:21:21 claus Exp $
    46 "
    46 "
    47 !
    47 !
    48 
    48 
    49 documentation
    49 documentation
    50 "
    50 "
   123     OBJ newobj;
   123     OBJ newobj;
   124     INT instsize, nInstVars, nindexedinstvars;
   124     INT instsize, nInstVars, nindexedinstvars;
   125     REGISTER OBJ *op;
   125     REGISTER OBJ *op;
   126     extern OBJ new();
   126     extern OBJ new();
   127 
   127 
   128     if (_isSmallInteger(anInteger)) {
   128     if (__isSmallInteger(anInteger)) {
   129 	nindexedinstvars = _intVal(anInteger);
   129 	nindexedinstvars = _intVal(anInteger);
   130 	if (nindexedinstvars >= 0) {
   130 	if (nindexedinstvars >= 0) {
   131 /*
   131 	    if (self == ByteArray) {
   132  * not needed - always true
   132 		/*
   133  *          if ((_intVal(_ClassInstPtr(self)->c_flags) & ARRAYMASK) == BYTEARRAY) 
   133 		 * the most common case
   134  */
   134 		 */
   135 	    {
   135 		instsize = OHDR_SIZE + nindexedinstvars;
   136 		if (self == ByteArray) {
   136 		if (_CanDoQuickNew(instsize)) {
       
   137 		    _qCheckedNew(newobj, instsize);
       
   138 		    _InstPtr(newobj)->o_class = self;
       
   139 		    RETURN (newobj );
       
   140 		}
       
   141 	    }
       
   142 	    nInstVars = _intVal(_ClassInstPtr(self)->c_ninstvars);
       
   143 	    instsize = OHDR_SIZE + __OBJS2BYTES__(nInstVars) + nindexedinstvars;
       
   144 	    PROTECT_CONTEXT
       
   145 	    _qNew(newobj, instsize, SENDER);
       
   146 	    UNPROTECT_CONTEXT
       
   147 	    if (newobj) {
       
   148 		_InstPtr(newobj)->o_class = self;
       
   149 		if (nInstVars) {
   137 		    /*
   150 		    /*
   138 		     * the most common case
   151 		     * still have to nil out named instvars ...
   139 		     */
   152 		     */
   140 		    instsize = OHDR_SIZE + nindexedinstvars;
   153 #if defined(FAST_OBJECT_MEMSET4)
   141 		    if (_CanDoQuickNew(instsize)) {
   154 		    memset4(_InstPtr(newobj)->i_instvars, nil, nInstVars);
   142 			_qCheckedNew(newobj, instsize);
   155 #else
   143 			_InstPtr(newobj)->o_class = self;
   156 # if defined(FAST_MEMSET) && !defined(NEGATIVE_ADDRESSES)
   144 			RETURN (newobj );
   157 		    /*
   145 		    }
   158 		     * knowing that nil is 0
       
   159 		     */
       
   160 		    memset(_InstPtr(newobj)->i_instvars, 0, instsize - OHDR_SIZE);
       
   161 # else
       
   162 		    op = _InstPtr(newobj)->i_instvars;
       
   163 		    while (nInstVars--)
       
   164 			*op++ = nil;
       
   165 # endif
       
   166 #endif
   146 		}
   167 		}
   147 		nInstVars = _intVal(_ClassInstPtr(self)->c_ninstvars);
   168 		RETURN ( newobj );
   148 		instsize = OHDR_SIZE + __OBJS2BYTES__(nInstVars) + nindexedinstvars;
       
   149 		PROTECT_CONTEXT
       
   150 		_qNew(newobj, instsize, SENDER);
       
   151 		UNPROTECT_CONTEXT
       
   152 		if (newobj) {
       
   153 		    _InstPtr(newobj)->o_class = self;
       
   154 		    if (nInstVars) {
       
   155 			/*
       
   156 			 * still have to nil out named instvars ...
       
   157 			 */
       
   158 #if defined(FAST_MEMSET) && !defined(NEGATIVE_ADDRESSES)
       
   159 			/*
       
   160 			 * knowing that nil is 0
       
   161 			 */
       
   162 			memset(_InstPtr(newobj)->i_instvars, 0, instsize - OHDR_SIZE);
       
   163 #else
       
   164 			op = _InstPtr(newobj)->i_instvars;
       
   165 			while (nInstVars--)
       
   166 			    *op++ = nil;
       
   167 #endif
       
   168 		    }
       
   169 		    RETURN ( newobj );
       
   170 		}
       
   171 	    }
   169 	    }
   172 	}
   170 	}
   173     }
   171     }
   174 %}
   172 %}
   175 .
   173 .
   185 	 was not kind enough to give some.
   183 	 was not kind enough to give some.
   186 	"
   184 	"
   187 	^ ObjectMemory allocationFailureSignal raise.
   185 	^ ObjectMemory allocationFailureSignal raise.
   188     ].
   186     ].
   189     ^ self basicNew:anInteger
   187     ^ self basicNew:anInteger
   190 
       
   191 ! !
   188 ! !
   192 
   189 
   193 !ByteArray methodsFor:'accessing'!
   190 !ByteArray methodsFor:'accessing'!
   194 
   191 
   195 basicAt:index
   192 basicAt:index
   200 
   197 
   201     REGISTER int indx;
   198     REGISTER int indx;
   202     int nIndex;
   199     int nIndex;
   203     OBJ cls;
   200     OBJ cls;
   204 
   201 
   205     if (_isSmallInteger(index)) {
   202     if (__isSmallInteger(index)) {
   206 	indx = _intVal(index);
   203 	indx = _intVal(index);
   207 
   204 	if (indx > 0) {
   208 	if ((cls = _qClass(self)) != ByteArray)
   205 	    if ((cls = _qClass(self)) != ByteArray)
   209 	    indx += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars));
   206 		indx += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars));
   210 	nIndex = _qSize(self) - OHDR_SIZE;
   207 	    nIndex = __byteArraySize(self);
   211 	if ((indx > 0) && (indx <= nIndex)) {
   208 	    if (indx <= nIndex) {
   212 	    RETURN ( _MKSMALLINT(_ByteArrayInstPtr(self)->ba_element[indx - 1]) );
   209 		RETURN ( _MKSMALLINT(_ByteArrayInstPtr(self)->ba_element[indx - 1]) );
       
   210 	    }
   213 	}
   211 	}
   214     }
   212     }
   215 %}
   213 %}
   216 .
   214 .
   217     ^ super basicAt:index
   215     ^ super basicAt:index
   226     REGISTER int indx;
   224     REGISTER int indx;
   227     int nIndex;
   225     int nIndex;
   228     int val;
   226     int val;
   229     OBJ cls;
   227     OBJ cls;
   230 
   228 
   231     if (_isSmallInteger(index) && _isSmallInteger(value)) {
   229     if (__bothSmallInteger(index, value)) {
   232 	val = _intVal(value);
   230 	val = _intVal(value);
   233 	if ((val & ~0xFF) == 0 /* i.e. (val >= 0) && (val <= 255) */) {
   231 	if ((val & ~0xFF) == 0 /* i.e. (val >= 0) && (val <= 255) */) {
   234 	    indx = _intVal(index);
   232 	    indx = _intVal(index);
       
   233 	    if (indx > 0) {
       
   234 		if ((cls = _qClass(self)) != ByteArray)
       
   235 		    indx += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars));
       
   236 		nIndex = __byteArraySize(self);
       
   237 		if (indx <= nIndex) {
       
   238 		    _ByteArrayInstPtr(self)->ba_element[indx - 1] = val;
       
   239 		    RETURN ( value );
       
   240 		}
       
   241 	    }
       
   242 	}
       
   243     }
       
   244 %}
       
   245 .
       
   246     ^ super basicAt:index put:value
       
   247 !
       
   248 
       
   249 byteAt:index
       
   250     "return the byte at index. 
       
   251      For ByteArray, this is the same as basicAt:; 
       
   252      however, for strings or symbols, this returns a numeric byteValue
       
   253      instead of a character."
       
   254 
       
   255 %{  /* NOCONTEXT */
       
   256 
       
   257     REGISTER int indx;
       
   258     int nIndex;
       
   259     OBJ cls;
       
   260 
       
   261     if (__isSmallInteger(index)) {
       
   262 	indx = _intVal(index);
       
   263 	if (indx > 0) {
   235 	    if ((cls = _qClass(self)) != ByteArray)
   264 	    if ((cls = _qClass(self)) != ByteArray)
   236 		indx += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars));
   265 		indx += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars));
   237 	    nIndex = _qSize(self) - OHDR_SIZE;
   266 	    nIndex = __byteArraySize(self);
   238 	    if ((indx > 0) && (indx <= nIndex)) {
   267 	    if (indx <= nIndex) {
   239 		_ByteArrayInstPtr(self)->ba_element[indx - 1] = val;
   268 		RETURN ( _MKSMALLINT(_ByteArrayInstPtr(self)->ba_element[indx - 1]) );
   240 		RETURN ( value );
   269 	    }
       
   270 	}
       
   271     }
       
   272 %}
       
   273 .
       
   274     ^ (super basicAt:index) asInteger
       
   275 !
       
   276 
       
   277 byteAt:index put:value
       
   278     "set the byte at index. For ByteArray, this is the same as basicAt:put:.
       
   279      However, for Strings, this expects a byteValue to be stored."
       
   280 
       
   281 %{  /* NOCONTEXT */
       
   282 
       
   283     REGISTER int indx;
       
   284     int nIndex;
       
   285     int val;
       
   286     OBJ cls;
       
   287 
       
   288     if (__bothSmallInteger(index, value)) {
       
   289 	val = _intVal(value);
       
   290 	if ((val & ~0xFF) == 0 /* i.e. (val >= 0) && (val <= 255) */) {
       
   291 	    indx = _intVal(index);
       
   292 	    if (indx > 0) {
       
   293 		if ((cls = _qClass(self)) != ByteArray)
       
   294 		    indx += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars));
       
   295 		nIndex = __byteArraySize(self);
       
   296 		if (indx <= nIndex) {
       
   297 		    _ByteArrayInstPtr(self)->ba_element[indx - 1] = val;
       
   298 		    RETURN ( value );
       
   299 		}
   241 	    }
   300 	    }
   242 	}
   301 	}
   243     }
   302     }
   244 %}
   303 %}
   245 .
   304 .
   246     ^ super basicAt:index put:value
   305     ^ super basicAt:index put:value
   247 !
       
   248 
       
   249 byteAt:index
       
   250     "return the byte at index
       
   251      - for ST-80 compatibility"
       
   252 
       
   253     ^ self at:index
       
   254 !
       
   255 
       
   256 byteAt:index put:aByteValuedInteger
       
   257     "return the byte at index
       
   258      - for ST-80 compatibility"
       
   259 
       
   260     ^ self at:index put:aByteValuedInteger
       
   261 !
   306 !
   262 
   307 
   263 wordAt:index
   308 wordAt:index
   264     "return the 2-bytes starting at index as an (unsigned) Integer.
   309     "return the 2-bytes starting at index as an (unsigned) Integer.
   265      The value is retrieved LSB-first (i.e. low 8-bits at lower byte index).
   310      The value is retrieved LSB-first (i.e. low 8-bits at lower byte index).
   268 %{  /* NOCONTEXT */
   313 %{  /* NOCONTEXT */
   269 
   314 
   270     REGISTER int indx;
   315     REGISTER int indx;
   271     int nIndex;
   316     int nIndex;
   272     int val;
   317     int val;
   273 
   318     OBJ cls;
   274     if (_isSmallInteger(index)) {
   319 
       
   320     if (__isSmallInteger(index)) {
   275 	indx = _intVal(index);
   321 	indx = _intVal(index);
   276 	if (_qClass(self) != ByteArray)
   322 	if (indx > 0) {
   277 	    indx += __OBJS2BYTES__(_intVal(_ClassInstPtr(_qClass(self))->c_ninstvars));
   323 	    if ((cls = _qClass(self)) != ByteArray)
   278 	nIndex = _qSize(self) - OHDR_SIZE;
   324 		indx += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars));
   279 	if ((indx > 0) && ((indx+1) <= nIndex)) {
   325 	    nIndex = __byteArraySize(self);
   280 	    val = _ByteArrayInstPtr(self)->ba_element[indx+1-1];
   326 	    if ((indx+1) <= nIndex) {
   281 	    val = (val << 8) + _ByteArrayInstPtr(self)->ba_element[indx-1];
   327 		val = _ByteArrayInstPtr(self)->ba_element[indx+1-1];
   282 	    RETURN ( _MKSMALLINT(val) );
   328 		val = (val << 8) + _ByteArrayInstPtr(self)->ba_element[indx-1];
       
   329 		RETURN ( _MKSMALLINT(val) );
       
   330 	    }
   283 	}
   331 	}
   284     }
   332     }
   285 %}
   333 %}
   286 .
   334 .
   287     ^ ((self at:index+1) * 256) + (self at:index)
   335     ^ ((self at:index+1) * 256) + (self at:index)
   297 %{  /* NOCONTEXT */
   345 %{  /* NOCONTEXT */
   298 
   346 
   299     REGISTER int indx;
   347     REGISTER int indx;
   300     int nIndex;
   348     int nIndex;
   301     int val;
   349     int val;
   302 
   350     OBJ cls;
   303     if (_isSmallInteger(index) && _isSmallInteger(value)) {
   351 
       
   352     if (__bothSmallInteger(index, value)) {
   304 	indx = _intVal(index);
   353 	indx = _intVal(index);
   305 	if (_qClass(self) != ByteArray)
   354 	if (indx > 0) {
   306 	    indx += __OBJS2BYTES__(_intVal(_ClassInstPtr(_qClass(self))->c_ninstvars));
   355 	    if ((cls = _qClass(self)) != ByteArray)
   307 	nIndex = _qSize(self) - OHDR_SIZE;
   356 		indx += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars));
   308 	if ((indx > 0) && ((indx+1) <= nIndex)) {
   357 	    nIndex = __byteArraySize(self);
   309 	    val = _intVal(value);
   358 	    if ((indx+1) <= nIndex) {
   310 	    if ((val >= 0) && (val <= 0xFFFF)) {
   359 		val = _intVal(value);
   311 		_ByteArrayInstPtr(self)->ba_element[indx-1] = val & 0xFF;
   360 		if ((val & ~0xFFFF) == 0 /* i.e. (val >= 0) && (val <= 0xFFFF) */) {
   312 		_ByteArrayInstPtr(self)->ba_element[indx+1-1] = (val>>8) & 0xFF;
   361 		    _ByteArrayInstPtr(self)->ba_element[indx-1] = val & 0xFF;
   313 		RETURN ( value );
   362 		    _ByteArrayInstPtr(self)->ba_element[indx+1-1] = (val>>8) & 0xFF;
       
   363 		    RETURN ( value );
       
   364 		}
   314 	    }
   365 	    }
   315 	}
   366 	}
   316     }
   367     }
   317 %}
   368 %}
   318 .
   369 .
   379 %{  /* NOCONTEXT */
   430 %{  /* NOCONTEXT */
   380 
   431 
   381     REGISTER int indx;
   432     REGISTER int indx;
   382     int nIndex;
   433     int nIndex;
   383     int val;
   434     int val;
   384 
   435     OBJ cls;
   385     if (_isSmallInteger(index)) {
   436 
       
   437     if (__isSmallInteger(index)) {
   386 	indx = _intVal(index);
   438 	indx = _intVal(index);
   387 	if (_qClass(self) != ByteArray)
   439 	if (indx > 0) {
   388 	    indx += __OBJS2BYTES__(_intVal(_ClassInstPtr(_qClass(self))->c_ninstvars));
   440 	    if ((cls = _qClass(self)) != ByteArray)
   389 	nIndex = _qSize(self) - OHDR_SIZE;
   441 		indx += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars));
   390 	if ((indx > 0) && ((indx+3) <= nIndex)) {
   442 	    nIndex = __byteArraySize(self);
   391 	    val = _ByteArrayInstPtr(self)->ba_element[indx+3-1];
   443 	    if ((indx+3) <= nIndex) {
   392 	    val = (val << 8) + _ByteArrayInstPtr(self)->ba_element[indx+2-1];
   444 		val = _ByteArrayInstPtr(self)->ba_element[indx+3-1];
   393 	    val = (val << 8) + _ByteArrayInstPtr(self)->ba_element[indx+1-1];
   445 		val = (val << 8) + _ByteArrayInstPtr(self)->ba_element[indx+2-1];
   394 	    val = (val << 8) + _ByteArrayInstPtr(self)->ba_element[indx-1];
   446 		val = (val << 8) + _ByteArrayInstPtr(self)->ba_element[indx+1-1];
   395 	    if ((val >= 0) && (val <= _MAX_INT)) {
   447 		val = (val << 8) + _ByteArrayInstPtr(self)->ba_element[indx-1];
   396 		RETURN ( _MKSMALLINT(val) );
   448 		if ((val >= 0) && (val <= _MAX_INT)) {
   397 	    }
   449 		    RETURN ( _MKSMALLINT(val) );
   398 	    RETURN ( _MKULARGEINT(val) );
   450 		}
       
   451 		RETURN ( _MKULARGEINT(val) );
       
   452 	    }
   399 	}
   453 	}
   400     }
   454     }
   401     /*
   455     /*
   402      * fall through in case of any error
   456      * fall through in case of any error
   403      * it will be handled in wordAt: finally
   457      * it will be handled in wordAt: finally
   425 %{  /* NOCONTEXT */
   479 %{  /* NOCONTEXT */
   426 
   480 
   427     REGISTER int indx;
   481     REGISTER int indx;
   428     int nIndex;
   482     int nIndex;
   429     int val;
   483     int val;
   430 
   484     OBJ cls;
   431     if (_isSmallInteger(index) && _isSmallInteger(value)) {
   485 
       
   486     if (__bothSmallInteger(index, value)) {
   432 	val = _intVal(value);
   487 	val = _intVal(value);
   433 	if (val >= 0) {
   488 	if (val >= 0) {
   434 	    indx = _intVal(index);
   489 	    indx = _intVal(index);
   435 	    if (_qClass(self) != ByteArray)
   490 	    if (indx > 0) {
   436 		indx += __OBJS2BYTES__(_intVal(_ClassInstPtr(_qClass(self))->c_ninstvars));
   491 		if ((cls = _qClass(self)) != ByteArray)
   437 	    nIndex = _qSize(self) - OHDR_SIZE;
   492 		    indx += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars));
   438 	    if ((indx > 0) && ((indx+3) <= nIndex)) {
   493 		nIndex = _qSize(self) - OHDR_SIZE;
   439 		_ByteArrayInstPtr(self)->ba_element[indx-1] = val & 0xFF;
   494 		if ((indx+3) <= nIndex) {
   440 		val >>= 8;
   495 		    _ByteArrayInstPtr(self)->ba_element[indx-1] = val & 0xFF;
   441 		_ByteArrayInstPtr(self)->ba_element[indx+1-1] = val & 0xFF;
   496 		    val >>= 8;
   442 		val >>= 8;
   497 		    _ByteArrayInstPtr(self)->ba_element[indx+1-1] = val & 0xFF;
   443 		_ByteArrayInstPtr(self)->ba_element[indx+2-1] = val & 0xFF;
   498 		    val >>= 8;
   444 		val >>= 8;
   499 		    _ByteArrayInstPtr(self)->ba_element[indx+2-1] = val & 0xFF;
   445 		_ByteArrayInstPtr(self)->ba_element[indx+3-1] = val & 0xFF;
   500 		    val >>= 8;
   446 		RETURN ( value );
   501 		    _ByteArrayInstPtr(self)->ba_element[indx+3-1] = val & 0xFF;
       
   502 		    RETURN ( value );
       
   503 		}
   447 	    }
   504 	    }
   448 	}
   505 	}
   449     }
   506     }
   450 %}
   507 %}
   451 .
   508 .
   759 %{  /* NOCONTEXT */
   816 %{  /* NOCONTEXT */
   760 
   817 
   761     REGISTER unsigned char *cp;
   818     REGISTER unsigned char *cp;
   762     REGISTER int index, byteValue;
   819     REGISTER int index, byteValue;
   763     REGISTER int len;
   820     REGISTER int len;
   764 
   821     OBJ cls;
   765     if (! _isSmallInteger(aByte)) {
   822 
       
   823     if (! __isSmallInteger(aByte)) {
   766 	/*
   824 	/*
   767 	 * searching for something which cannot be found
   825 	 * searching for something which cannot be found
   768 	 */
   826 	 */
   769 	RETURN ( _MKSMALLINT(0) );
   827 	RETURN ( _MKSMALLINT(0) );
   770     }
   828     }
   776 	 * searching for something which cannot be found
   834 	 * searching for something which cannot be found
   777 	 */
   835 	 */
   778 	RETURN ( _MKSMALLINT(0) );
   836 	RETURN ( _MKSMALLINT(0) );
   779     }
   837     }
   780 
   838 
   781     if (_isSmallInteger(start)) {
   839     if (__isSmallInteger(start)) {
   782 	index = _intVal(start);
   840 	index = _intVal(start);
   783 	len = _qSize(self) - OHDR_SIZE;
   841 	len = __byteArraySize(self);
   784 	cp = &(_ByteArrayInstPtr(self)->ba_element[0]);
   842 	cp = _ByteArrayInstPtr(self)->ba_element;
   785 	if (_qClass(self) != ByteArray) {
   843 	if ((cls = _qClass(self)) != ByteArray) {
   786 	    int nInst;
   844 	    int nInst;
   787 
   845 
   788 	    nInst = __OBJS2BYTES__(_intVal(_ClassInstPtr(_qClass(self))->c_ninstvars));
   846 	    nInst = __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars));
   789 	    cp += nInst;
   847 	    cp += nInst;
   790 	    len -= nInst;
   848 	    len -= nInst;
   791 	}
   849 	}
   792 	cp += index - 1;
   850 	cp += index - 1;
   793 	while (index <= len) {
   851 	while (index <= len) {
   959     REGISTER int count;
  1017     REGISTER int count;
   960     int len, index1, index2, sz;
  1018     int len, index1, index2, sz;
   961     OBJ newByteArray;
  1019     OBJ newByteArray;
   962 
  1020 
   963     if (__isByteArray(self)
  1021     if (__isByteArray(self)
   964      && _isSmallInteger(start)
  1022      && __bothSmallInteger(start, stop)) {
   965      && _isSmallInteger(stop)) {
  1023 	len = __byteArraySize(self);
   966 	len = _byteArraySize(self);
       
   967 	index1 = _intVal(start);
  1024 	index1 = _intVal(start);
   968 	index2 = _intVal(stop);
  1025 	index2 = _intVal(stop);
   969 
  1026 
   970 	if ((index1 <= index2) && (index1 > 0)) {
  1027 	if ((index1 <= index2) && (index1 > 0)) {
   971 	    if (index2 <= len) {
  1028 	    if (index2 <= len) {
  1004     "fill part of the receiver with aNumber.
  1061     "fill part of the receiver with aNumber.
  1005      - reimplemented here for speed"
  1062      - reimplemented here for speed"
  1006 
  1063 
  1007 %{  /* NOCONTEXT */
  1064 %{  /* NOCONTEXT */
  1008 
  1065 
  1009 #ifndef FAST_MEMSET
       
  1010     REGISTER unsigned char *dstp;
  1066     REGISTER unsigned char *dstp;
  1011 #endif
       
  1012     REGISTER int count, value;
  1067     REGISTER int count, value;
  1013     int len, index1, index2, sz;
  1068     int len, index1, index2;
  1014 
  1069     int nInst;
  1015     if (__isByteArray(self)
  1070     OBJ cls;
  1016      && _isSmallInteger(aNumber)
  1071 
  1017      && _isSmallInteger(start)
  1072     if (__isSmallInteger(aNumber)
  1018      && _isSmallInteger(stop)) {
  1073      && __bothSmallInteger(start, stop)) {
  1019 	len = _byteArraySize(self);
  1074 	len = __byteArraySize(self);
  1020 	index1 = _intVal(start);
  1075 	index1 = _intVal(start);
  1021 	index2 = _intVal(stop);
  1076 	index2 = _intVal(stop);
       
  1077 
       
  1078 	dstp = _ByteArrayInstPtr(self)->ba_element + index1 - 1;
       
  1079 	if ((cls = _qClass(self)) != ByteArray) {
       
  1080 	    nInst = __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars));
       
  1081 	    dstp += nInst;
       
  1082 	    len -= nInst;
       
  1083 	}
  1022 
  1084 
  1023 	value = _intVal(aNumber);
  1085 	value = _intVal(aNumber);
  1024 	if ((value >= 0) && (value <= 255)
  1086 	if ((value >= 0) && (value <= 255)
  1025 	 && (index1 <= index2) 
  1087 	 && (index1 <= index2) 
  1026 	 && (index1 > 0)) {
  1088 	 && (index1 > 0)) {
  1027 	    if (index2 <= len) {
  1089 	    if (index2 <= len) {
  1028 		count = index2 - index1 + 1;
  1090 		count = index2 - index1 + 1;
  1029 #ifdef FAST_MEMSET
  1091 #ifdef FAST_MEMSET
  1030 		memset(_ByteArrayInstPtr(self)->ba_element + index1 - 1, count, value);
  1092 		memset(dstp, count, value);
  1031 #else
  1093 #else
  1032 		dstp = _ByteArrayInstPtr(self)->ba_element + index1 - 1;
       
  1033 		while (count--) {
  1094 		while (count--) {
  1034 		    *dstp++ = value;
  1095 		    *dstp++ = value;
  1035 		}
  1096 		}
  1036 #endif
  1097 #endif
  1037 		RETURN (self);
  1098 		RETURN (self);
  1045     "
  1106     "
  1046     ^ super from:start to:stop put:aNumber
  1107     ^ super from:start to:stop put:aNumber
  1047 !
  1108 !
  1048 
  1109 
  1049 replaceFrom:start to:stop with:aCollection startingAt:repStart
  1110 replaceFrom:start to:stop with:aCollection startingAt:repStart
  1050     "reimplemented for speed"
  1111     "replace elements from another collection"
       
  1112 
       
  1113     (aCollection class == self class) ifTrue:[
       
  1114 	^ self replaceBytesFrom:start to:stop with:aCollection startingAt:repStart
       
  1115     ].
       
  1116     ^ super replaceFrom:start to:stop with:aCollection startingAt:repStart
       
  1117 !
       
  1118 
       
  1119 replaceBytesFrom:start to:stop with:aCollection startingAt:repStart
       
  1120     "replace elements from another collection, which must be a ByteArray
       
  1121      or String."
  1051 
  1122 
  1052 %{  /* NOCONTEXT */
  1123 %{  /* NOCONTEXT */
  1053 
  1124 
  1054     int nIndex, repNIndex;
  1125     int nIndex, repNIndex;
  1055     int startIndex, stopIndex;
  1126     int startIndex, stopIndex;
  1056     REGISTER unsigned char *src;
  1127     REGISTER unsigned char *src;
  1057     REGISTER int repStartIndex;
  1128     REGISTER int repStartIndex;
  1058     int repStopIndex, count;
  1129     int repStopIndex, count;
  1059     REGISTER unsigned char *dst;
  1130     REGISTER unsigned char *dst;
  1060 
  1131     OBJ cls;
  1061     if ((_qClass(self) == ByteArray)
  1132     int nInst;
  1062      && (_Class(aCollection) == ByteArray)
  1133 
  1063      && _isSmallInteger(start)
  1134     if (__isBytes(aCollection)
  1064      && _isSmallInteger(stop)
  1135      && __bothSmallInteger(start, stop)
  1065      && _isSmallInteger(repStart)) {
  1136      && __isSmallInteger(repStart)) {
  1066 	startIndex = _intVal(start) - 1;
  1137 	startIndex = _intVal(start) - 1;
  1067 	if (startIndex >= 0) {
  1138 	if (startIndex >= 0) {
  1068 	  nIndex = _qSize(self) - OHDR_SIZE;
  1139 	  dst = (_ByteArrayInstPtr(self)->ba_element) + startIndex;
       
  1140 	  nIndex = __byteArraySize(self);
       
  1141 
       
  1142 	  if ((cls = _qClass(self)) != ByteArray) {
       
  1143 	    nInst = __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars));
       
  1144 	    dst += nInst;
       
  1145 	    nIndex -= nInst;
       
  1146 	  }
       
  1147 
  1069 	  stopIndex = _intVal(stop) - 1;
  1148 	  stopIndex = _intVal(stop) - 1;
  1070 	  count = stopIndex - startIndex + 1;
  1149 	  count = stopIndex - startIndex + 1;
  1071 	  if (count == 0) {
  1150 	  if (count == 0) {
  1072 	      RETURN ( self );
  1151 	      RETURN ( self );
  1073 	  }
  1152 	  }
  1074 	  if ((count > 0) && (stopIndex < nIndex)) {
  1153 	  if ((count > 0) && (stopIndex < nIndex)) {
  1075 	    repStartIndex = _intVal(repStart) - 1;
  1154 	    repStartIndex = _intVal(repStart) - 1;
  1076 	    if (repStartIndex >= 0) {
  1155 	    if (repStartIndex >= 0) {
  1077 	      repNIndex = _qSize(aCollection) - OHDR_SIZE;
  1156 	      repNIndex = _qSize(aCollection) - OHDR_SIZE;
       
  1157 	      src = (_ByteArrayInstPtr(aCollection)->ba_element) + repStartIndex;
       
  1158 	      if ((cls = _qClass(aCollection)) != ByteArray) {
       
  1159 		nInst = __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars));
       
  1160 		src += nInst;
       
  1161 		repNIndex -= nInst;
       
  1162 	      }
       
  1163 
  1078 	      repStopIndex = repStartIndex + (stopIndex - startIndex);
  1164 	      repStopIndex = repStartIndex + (stopIndex - startIndex);
  1079 	      if (repStopIndex < repNIndex) {
  1165 	      if (repStopIndex < repNIndex) {
  1080 		src = &(_ByteArrayInstPtr(aCollection)->ba_element[repStartIndex]);
       
  1081 		dst = &(_ByteArrayInstPtr(self)->ba_element[startIndex]);
       
  1082 
       
  1083 		if (aCollection == self) {
  1166 		if (aCollection == self) {
  1084 		    /* take care of overlapping copy */
  1167 		    /* take care of overlapping copy */
  1085 		    if (src < dst) {
  1168 		    if (src < dst) {
  1086 			/* must do a reverse copy */
  1169 			/* must do a reverse copy */
  1087 			src += count;
  1170 			src += count;
  1121 	  }
  1204 	  }
  1122 	}
  1205 	}
  1123     }
  1206     }
  1124 %}
  1207 %}
  1125 .
  1208 .
  1126     ^ super replaceFrom:start to:stop with:aCollection startingAt:repStart
  1209     ^ super replaceBytesFrom:start to:stop with:aCollection startingAt:repStart
  1127 ! !
  1210 ! !
  1128 
  1211 
  1129 !ByteArray methodsFor:'image manipulation support'!
  1212 !ByteArray methodsFor:'image manipulation support'!
  1130 
  1213 
  1131 invert
  1214 invert
  1138     REGISTER unsigned char *dst;
  1221     REGISTER unsigned char *dst;
  1139     REGISTER unsigned long *ldst;
  1222     REGISTER unsigned long *ldst;
  1140     REGISTER int cnt;
  1223     REGISTER int cnt;
  1141 
  1224 
  1142     if (_qClass(self) == ByteArray) {
  1225     if (_qClass(self) == ByteArray) {
  1143 	cnt = _qSize(self) - OHDR_SIZE;
  1226 	cnt = __byteArraySize(self);
  1144 	dst = _ByteArrayInstPtr(self)->ba_element;
  1227 	dst = _ByteArrayInstPtr(self)->ba_element;
  1145 	if (! ((int)dst & (sizeof(long)-1))) {
  1228 	if (! ((int)dst & (sizeof(long)-1))) {
  1146 	    ldst = (unsigned long *)dst;
  1229 	    ldst = (unsigned long *)dst;
  1147 	    while (cnt >= sizeof(long)) {
  1230 	    while (cnt >= sizeof(long)) {
  1148 		*ldst = ~(*ldst);
  1231 		*ldst = ~(*ldst);
  1169 %{  /* NOCONTEXT */
  1252 %{  /* NOCONTEXT */
  1170 
  1253 
  1171     REGISTER unsigned char *p1, *p2;
  1254     REGISTER unsigned char *p1, *p2;
  1172     REGISTER int cnt;
  1255     REGISTER int cnt;
  1173     REGISTER unsigned t;
  1256     REGISTER unsigned t;
  1174 
  1257     OBJ cls;
  1175     if (_qClass(self) == ByteArray) {
  1258 
  1176 	cnt = _qSize(self) - OHDR_SIZE;
  1259     cnt = __byteArraySize(self);
  1177 	p1 = _ByteArrayInstPtr(self)->ba_element;
  1260     p1 = _ByteArrayInstPtr(self)->ba_element;
  1178 	p2 = _ByteArrayInstPtr(self)->ba_element + cnt - 1;
  1261     if ((cls = _qClass(self)) != ByteArray) {
  1179 	while (cnt > 0) {
  1262 	t = __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars));
  1180 	    t = *p1;
  1263 	p1 += t;
  1181 	    *p1++ = *p2;
  1264 	cnt -= t;
  1182 	    *p2-- = t;
  1265     }
  1183 	    cnt-=2;
  1266     p2 = p1 + cnt - 1;
  1184 	}
  1267     while (cnt > 0) {
  1185 	RETURN ( self );
  1268 	t = *p1;
  1186     }
  1269 	*p1++ = *p2;
  1187 %}
  1270 	*p2-- = t;
  1188 .
  1271 	cnt-=2;
  1189     ^ super reverse
  1272     }
       
  1273     RETURN ( self );
       
  1274 %}
  1190 !
  1275 !
  1191 
  1276 
  1192 expandPixels:nBitsPerPixel width:width height:height into:aByteArray
  1277 expandPixels:nBitsPerPixel width:width height:height into:aByteArray
  1193 			 mapping:aMapByteArray
  1278 			 mapping:aMapByteArray
  1194 
  1279 
  1219     int ncells;
  1304     int ncells;
  1220     unsigned char *map;
  1305     unsigned char *map;
  1221 
  1306 
  1222     if ((_qClass(self) == ByteArray) 
  1307     if ((_qClass(self) == ByteArray) 
  1223      && (_qClass(aByteArray) == ByteArray)
  1308      && (_qClass(aByteArray) == ByteArray)
  1224      && _isSmallInteger(nBitsPerPixel)
  1309      && __isSmallInteger(nBitsPerPixel)
  1225      && _isSmallInteger(height)
  1310      && __bothSmallInteger(height, width)) {
  1226      && _isSmallInteger(width)) {
       
  1227 	if ((aMapByteArray != nil)
  1311 	if ((aMapByteArray != nil)
  1228 	 && (_Class(aMapByteArray) == ByteArray)) {
  1312 	 && (_Class(aMapByteArray) == ByteArray)) {
  1229 	    map = _ByteArrayInstPtr(aMapByteArray)->ba_element;
  1313 	    map = _ByteArrayInstPtr(aMapByteArray)->ba_element;
  1230 	} else {
  1314 	} else {
  1231 	    map = (unsigned char *)0;
  1315 	    map = (unsigned char *)0;
  1265 	bytesPerRow = (w * bitsPerPixel + 7) / 8;
  1349 	bytesPerRow = (w * bitsPerPixel + 7) / 8;
  1266 	shift0 = 8 - bitsPerPixel;
  1350 	shift0 = 8 - bitsPerPixel;
  1267 	srcBytes = bytesPerRow * h;
  1351 	srcBytes = bytesPerRow * h;
  1268 	dstBytes = w * h;
  1352 	dstBytes = w * h;
  1269 
  1353 
  1270 	if (((_qSize(self) - OHDR_SIZE) >= srcBytes)
  1354 	if ((__byteArraySize(self) >= srcBytes)
  1271 	 && ((_qSize(aByteArray) - OHDR_SIZE) >= dstBytes)) {
  1355 	 && (__byteArraySize(aByteArray) >= dstBytes)) {
  1272 	    for (hrun=h; hrun; hrun--) {
  1356 	    for (hrun=h; hrun; hrun--) {
  1273 		srcNext = src + bytesPerRow;
  1357 		srcNext = src + bytesPerRow;
  1274 		shift = shift0;
  1358 		shift = shift0;
  1275 		if (map) {
  1359 		if (map) {
  1276 		    for (wrun=w; wrun; wrun--) {
  1360 		    for (wrun=w; wrun; wrun--) {
  1364     int ncells;
  1448     int ncells;
  1365     unsigned char *map;
  1449     unsigned char *map;
  1366 
  1450 
  1367     if ((_qClass(self) == ByteArray) 
  1451     if ((_qClass(self) == ByteArray) 
  1368      && (_qClass(aByteArray) == ByteArray)
  1452      && (_qClass(aByteArray) == ByteArray)
  1369      && _isSmallInteger(nBitsPerPixel)
  1453      && __isSmallInteger(nBitsPerPixel)
  1370      && _isSmallInteger(height)
  1454      && __bothSmallInteger(height, width)) {
  1371      && _isSmallInteger(width)) {
       
  1372 	if ((aMapByteArray != nil)
  1455 	if ((aMapByteArray != nil)
  1373 	 && (_Class(aMapByteArray) == ByteArray)) {
  1456 	 && (_Class(aMapByteArray) == ByteArray)) {
  1374 	    map = _ByteArrayInstPtr(aMapByteArray)->ba_element;
  1457 	    map = _ByteArrayInstPtr(aMapByteArray)->ba_element;
  1375 	} else {
  1458 	} else {
  1376 	    map = (unsigned char *)0;
  1459 	    map = (unsigned char *)0;
  1408 
  1491 
  1409 	bytesPerRow = (w * bitsPerPixel + 7) / 8;
  1492 	bytesPerRow = (w * bitsPerPixel + 7) / 8;
  1410 	dstBytes = bytesPerRow * h;
  1493 	dstBytes = bytesPerRow * h;
  1411 	srcBytes = w * h;
  1494 	srcBytes = w * h;
  1412 
  1495 
  1413 	if (((_qSize(self) - OHDR_SIZE) >= srcBytes)
  1496 	if ((__byteArraySize(self) >= srcBytes)
  1414 	 && ((_qSize(aByteArray) - OHDR_SIZE) >= dstBytes)) {
  1497 	 && (__byteArraySize(aByteArray) >= dstBytes)) {
  1415 	    for (hrun=h; hrun; hrun--) {
  1498 	    for (hrun=h; hrun; hrun--) {
  1416 		dstNext = dst + bytesPerRow;
  1499 		dstNext = dst + bytesPerRow;
  1417 		bits = 0; shift = 8;
  1500 		bits = 0; shift = 8;
  1418 		if (map) {
  1501 		if (map) {
  1419 		    for (wrun=w; wrun; wrun--) {
  1502 		    for (wrun=w; wrun; wrun--) {