UninterpretedBytes.st
changeset 3459 6cb151c3950c
parent 3447 4009e251544b
child 3936 dd8cd28d4a9b
equal deleted inserted replaced
3458:084d1511cd2a 3459:6cb151c3950c
   183 
   183 
   184     "Modified: / 23.4.1996 / 15:56:25 / cg"
   184     "Modified: / 23.4.1996 / 15:56:25 / cg"
   185     "Modified: / 5.3.1998 / 14:56:22 / stefan"
   185     "Modified: / 5.3.1998 / 14:56:22 / stefan"
   186 ! !
   186 ! !
   187 
   187 
   188 !UninterpretedBytes methodsFor:'accessing'!
   188 !UninterpretedBytes methodsFor:'accessing-bytes'!
   189 
   189 
   190 byteAt:index
   190 byteAt:index
   191     "return the byte at index. 
   191     "return the byte at index. 
   192      For ByteArray, this is the same as basicAt:; 
   192      For ByteArray, this is the same as basicAt:; 
   193      however, for strings or symbols, this returns a numeric byteValue
   193      however, for strings or symbols, this returns a numeric byteValue
   200     "set the byte at index. For ByteArray, this is the same as basicAt:put:.
   200     "set the byte at index. For ByteArray, this is the same as basicAt:put:.
   201      However, for Strings, this expects a byteValue to be stored."
   201      However, for Strings, this expects a byteValue to be stored."
   202 
   202 
   203     ^ self subclassResponsibility
   203     ^ self subclassResponsibility
   204 !
   204 !
       
   205 
       
   206 signedByteAt:index
       
   207     "return the byte at index as a signed 8 bit value.
       
   208      The index is a smalltalk index (i.e. 1-based).
       
   209      This may be worth a primitive."
       
   210 
       
   211     ^ (self at:index) signExtendedByteValue
       
   212 
       
   213     "
       
   214      |b|
       
   215      b := ByteArray new:2.
       
   216      b at:1 put:16rFF.
       
   217      b at:2 put:16r7F.
       
   218      b signedByteAt:1  
       
   219     "
       
   220 
       
   221     "Modified: 1.7.1996 / 21:13:53 / cg"
       
   222 !
       
   223 
       
   224 signedByteAt:index put:aSignedByteValue
       
   225     "return the byte at index as a signed 8 bit value.
       
   226      The index is a smalltalk index (i.e. 1-based).
       
   227      Return the signedByteValue argument.
       
   228      This may be worth a primitive."
       
   229 
       
   230     |b "{ Class: SmallInteger }"|
       
   231 
       
   232     aSignedByteValue >= 0 ifTrue:[
       
   233 	b := aSignedByteValue
       
   234     ] ifFalse:[
       
   235 	b := 16r100 + aSignedByteValue
       
   236     ].
       
   237     self at:index put:b.
       
   238     ^ aSignedByteValue
       
   239 
       
   240     "
       
   241      |b|
       
   242      b := ByteArray new:2.
       
   243      b signedByteAt:1 put:-1.
       
   244      b at:1   
       
   245     "
       
   246 
       
   247     "Modified: 1.7.1996 / 21:12:37 / cg"
       
   248 ! !
       
   249 
       
   250 !UninterpretedBytes methodsFor:'accessing-floats & doubles'!
   205 
   251 
   206 doubleAt:index
   252 doubleAt:index
   207     "return the 8-bytes starting at index as a Float.
   253     "return the 8-bytes starting at index as a Float.
   208      The index is a smalltalk index (i.e. 1-based).
   254      The index is a smalltalk index (i.e. 1-based).
   209      Notice, that (currently) ST/X Floats are what Doubles are in ST-80.
   255      Notice, that (currently) ST/X Floats are what Doubles are in ST-80.
   348 
   394 
   349     "Created: / 15.5.1998 / 17:22:27 / cg"
   395     "Created: / 15.5.1998 / 17:22:27 / cg"
   350     "Modified: / 15.5.1998 / 17:26:29 / cg"
   396     "Modified: / 15.5.1998 / 17:26:29 / cg"
   351 !
   397 !
   352 
   398 
       
   399 floatAt:index
       
   400     "return the 4-bytes starting at index as a ShortFloat.
       
   401      The index is a smalltalk index (i.e. 1-based).
       
   402      Notice, that (currently) ST/X Floats are what Doubles are in ST-80;
       
   403      therefore this method reads a 4-byte float from the byteArray and returns
       
   404      a float object which keeps an 8-byte double internally.
       
   405      Notice also, that the bytes are expected to be in this machines
       
   406      float representation and order - if the bytearray originated from another
       
   407      machine, some conversion is usually needed."
       
   408 
       
   409     |newFloat|
       
   410 
       
   411 %{
       
   412     /*
       
   413      * handle the most common cases fast ...
       
   414      */
       
   415     if (__isSmallInteger(index)) {
       
   416         char *cp;
       
   417         int sz;
       
   418 
       
   419         __fetchBytePointerAndSize__(self, &cp, &sz);
       
   420         if (cp) {
       
   421             unsigned INT idx = ((unsigned INT)__intVal(index)) - 1;
       
   422 
       
   423             if ((idx+(sizeof(float)-1)) < sz) {
       
   424                 cp += idx;
       
   425                 /*
       
   426                  * aligned
       
   427                  */
       
   428                 if (((INT)cp & (sizeof(float)-1)) == 0) {
       
   429                     float fVal = ((float *)cp)[0];
       
   430 		    OBJ f;
       
   431 
       
   432 		    __qMKSFLOAT(f, fVal);
       
   433                     RETURN (f);
       
   434                 }
       
   435             }
       
   436         }
       
   437     }
       
   438 %}.
       
   439 
       
   440     newFloat := ShortFloat basicNew.
       
   441     1 to:4 do:[:destIndex|
       
   442         newFloat basicAt:destIndex put:(self at:index - 1 + destIndex)
       
   443     ].
       
   444     ^ newFloat.
       
   445 !
       
   446 
       
   447 floatAt:index MSB:msb
       
   448     "return the 4-bytes starting at index as a ShortFloat.
       
   449      The index is a smalltalk index (i.e. 1-based).
       
   450      Notice, that (currently) ST/X Floats are what Doubles are in ST-80;
       
   451      therefore this method reads a 4-byte float from the byteArray and returns
       
   452      a float object which keeps an 8-byte double internally.
       
   453      Notice also, that the bytes are expected to be in this machines
       
   454      float representation and order - if the bytearray originated from another
       
   455      machine, some conversion is usually needed."
       
   456 
       
   457     |newFloat|
       
   458 
       
   459     msb == UninterpretedBytes isBigEndian ifTrue:[
       
   460         ^ self floatAt:index
       
   461     ].
       
   462 
       
   463     newFloat := ShortFloat basicNew.
       
   464     1 to:4 do:[:destIndex|
       
   465         newFloat basicAt:(5-destIndex) put:(self at:index - 1 + destIndex)
       
   466     ].
       
   467     ^ newFloat.
       
   468 
       
   469     "Modified: / 15.5.1998 / 17:20:19 / cg"
       
   470     "Created: / 15.5.1998 / 17:20:35 / cg"
       
   471 !
       
   472 
       
   473 floatAt:index put:aFloat
       
   474     "store the 4 bytes of value of the argument, aFloat into the receiver
       
   475      starting at index.
       
   476      The index is a smalltalk index (i.e. 1-based).
       
   477      Notice, that (currently) ST/X Floats are what Doubles are in ST-80.
       
   478      Notice also, that the bytes are expected to be in this machines
       
   479      float representation - if the bytearray originated from another
       
   480      machine, some conversion is usually needed."
       
   481 
       
   482     |sflt|
       
   483 
       
   484     sflt := aFloat asShortFloat.
       
   485 %{
       
   486     /*
       
   487      * handle the most common cases fast ...
       
   488      */
       
   489     if (__isSmallInteger(index) && __isShortFloat(sflt)) {
       
   490         char *cp;
       
   491         int sz;
       
   492 
       
   493         __fetchBytePointerAndSize__(self, &cp, &sz);
       
   494         if (cp) {
       
   495             unsigned INT idx = ((unsigned INT)__intVal(index)) - 1;
       
   496 
       
   497             if ((idx+(sizeof(float)-1)) < sz) {
       
   498                 cp += idx;
       
   499                 /*
       
   500                  * aligned
       
   501                  */
       
   502                 if (((INT)cp & (sizeof(float)-1)) == 0) {
       
   503                     ((float *)cp)[0] = __shortFloatVal(sflt);
       
   504 
       
   505                     RETURN (aFloat);
       
   506                 }
       
   507             }
       
   508         }
       
   509     }
       
   510 %}.
       
   511 
       
   512     1 to:4 do:[:srcIndex|
       
   513         self at:index - 1 + srcIndex put:(sflt basicAt:srcIndex)
       
   514     ].
       
   515     ^ aFloat
       
   516 !
       
   517 
       
   518 floatAt:index put:aFloat MSB:msb
       
   519     "store the 4 bytes of value of the argument, aFloat into the receiver
       
   520      starting at index.
       
   521      The index is a smalltalk index (i.e. 1-based).
       
   522      Notice, that (currently) ST/X Floats are what Doubles are in ST-80.
       
   523      Notice also, that the bytes are expected to be in this machines
       
   524      float representation - if the bytearray originated from another
       
   525      machine, some conversion is usually needed."
       
   526 
       
   527     |sflt|
       
   528 
       
   529     msb == UninterpretedBytes isBigEndian ifTrue:[
       
   530         ^ self floatAt:index put:aFloat
       
   531     ].
       
   532 
       
   533     sflt := aFloat asShortFloat.
       
   534     1 to:4 do:[:srcIndex|
       
   535         self at:index - 1 + srcIndex put:(sflt basicAt:(5-srcIndex))
       
   536     ].
       
   537     ^ aFloat
       
   538 
       
   539     "Created: / 15.5.1998 / 17:20:41 / cg"
       
   540 !
       
   541 
       
   542 ieeeDoubleAt:index
       
   543     "retrieve the 8 bytes starting at index as a float.
       
   544      The index is a smalltalk index (i.e. 1-based).
       
   545      The 8 bytes are assumed to be in IEEE floating point single precision
       
   546      number format."
       
   547 
       
   548     "
       
   549      currently, we assume that the machines native number format is already
       
   550      IEEE format - we need some more code here whenever ST/X is ported
       
   551      to an IBM 370 or old VAX etc.
       
   552      To date, all supported systems use IEEE float numbers, so there should be
       
   553      no problem.
       
   554     "
       
   555     self isIEEEFormat ifFalse:[self error:'unsupported operation'].
       
   556 
       
   557     ^ self doubleAt:index
       
   558 
       
   559     "Created: / 5.3.1998 / 10:50:03 / stefan"
       
   560 !
       
   561 
       
   562 ieeeDoubleAt:index put:aFloat
       
   563     "store the value of the argument, aFloat into the receiver
       
   564      The index is a smalltalk index (i.e. 1-based).
       
   565      starting at index. Storage is in IEEE floating point double precision format.
       
   566      (i.e. 8 bytes are stored)."
       
   567 
       
   568     "
       
   569      currently, we assume that the machines native number format is already
       
   570      IEEE format - we need some more code here whenever ST/X is ported
       
   571      to an IBM 370 or old VAX etc.
       
   572      To date, all supported systems use IEEE float numbers, so there should be
       
   573      no problem.
       
   574     "
       
   575     self isIEEEFormat ifFalse:[self error:'unsupported operation'].
       
   576 
       
   577     ^ self doubleAt:index put:aFloat
       
   578 
       
   579     "Created: / 5.3.1998 / 10:50:26 / stefan"
       
   580 !
       
   581 
       
   582 ieeeFloatAt:index
       
   583     "retrieve the 4 bytes starting at index as a float.
       
   584      The index is a smalltalk index (i.e. 1-based).
       
   585      The 4 bytes are assumed to be in IEEE floating point single precision
       
   586      number format."
       
   587 
       
   588     "
       
   589      currently, we assume that the machines native number format is already
       
   590      IEEE format - we need some more code here whenever ST/X is ported
       
   591      to an IBM 370 or old VAX etc.
       
   592      To date, all supported systems use IEEE float numbers, so there should be
       
   593      no problem.
       
   594     "
       
   595     self isIEEEFormat ifFalse:[self error:'unsupported operation'].
       
   596 
       
   597     ^ self floatAt:index
       
   598 
       
   599     "Created: / 5.3.1998 / 10:50:45 / stefan"
       
   600 !
       
   601 
       
   602 ieeeFloatAt:index put:aFloat
       
   603     "store the value of the argument, aFloat into the receiver
       
   604      starting at index, which is a smalltalk index (i.e. 1-based). 
       
   605      Storage is in IEEE floating point single precision format.
       
   606      (i.e. 4 bytes are stored). Since ST/X floats are really doubles, the low-
       
   607      order 4 bytes of the precision is lost."
       
   608 
       
   609     "
       
   610      currently, we assume that the machines native number format is already
       
   611      IEEE format - we need some more code here whenever ST/X is ported
       
   612      to an IBM 370 or old VAX etc.
       
   613      To date, all supported systems use IEEE float numbers, so there should be
       
   614      no problem.
       
   615     "
       
   616     self isIEEEFormat ifFalse:[self error:'unsupported operation'].
       
   617 
       
   618     ^ self floatAt:index put:aFloat
       
   619 
       
   620     "Created: / 5.3.1998 / 10:51:11 / stefan"
       
   621 ! !
       
   622 
       
   623 !UninterpretedBytes methodsFor:'accessing-longlongs'!
       
   624 
       
   625 longLongAt:index
       
   626     "return the 8-bytes starting at index as a signed Integer.
       
   627      The index is a smalltalk index (i.e. 1-based).
       
   628      The value is retrieved in the machines natural byte order.
       
   629      This may be worth a primitive."
       
   630 
       
   631     |w|
       
   632 
       
   633     w := self unsignedLongLongAt:index bigEndian:IsBigEndian.
       
   634     (w > (16r7FFFFFFFFFFFFFFF)) ifTrue:[
       
   635         ^ w - (16r10000000000000000)
       
   636     ].
       
   637     ^ w
       
   638 
       
   639     "
       
   640      |b|
       
   641      b := ByteArray new:4.
       
   642      b unsignedLongLongAt:1 put:16rFFFFFFFFFFFFFFFF.
       
   643      (b longLongAt:1)    
       
   644     "
       
   645 
       
   646     "Modified: / 1.7.1996 / 21:11:28 / cg"
       
   647     "Created: / 5.3.1998 / 14:40:05 / stefan"
       
   648     "Modified: / 5.3.1998 / 14:58:32 / stefan"
       
   649 !
       
   650 
       
   651 longLongAt:index bigEndian:msb
       
   652     "return the 8-bytes starting at index as a signed Integer.
       
   653      The index is a smalltalk index (i.e. 1-based).
       
   654      The value is retrieved in the given byte order.
       
   655      This may be worth a primitive."
       
   656 
       
   657     |w|
       
   658 
       
   659     w := self unsignedLongLongAt:index bigEndian:msb.
       
   660     (w > (16r7FFFFFFFFFFFFFFF)) ifTrue:[
       
   661         ^ w - (16r10000000000000000)
       
   662     ].
       
   663     ^ w
       
   664 
       
   665     "
       
   666      |b|
       
   667      b := ByteArray new:4.
       
   668      b unsignedLongLongAt:1 put:16rFFFFFFFFFFFFFFFF.
       
   669      (b longLongAt:1 msb:true)    
       
   670     "
       
   671 
       
   672     "Modified: / 5.3.1998 / 12:06:28 / stefan"
       
   673     "Created: / 5.3.1998 / 14:40:54 / stefan"
       
   674     "Modified: / 9.5.1998 / 01:10:59 / cg"
       
   675 !
       
   676 
       
   677 longLongAt:byteIndex put:anInteger
       
   678     "store a signed longLong (64bit) integer.
       
   679      The index is a smalltalk index (i.e. 1-based).
       
   680      Same as #signedQuadWordAt:put: - for ST80 compatibility."
       
   681 
       
   682     ^ self signedQuadWordAt:byteIndex put:anInteger
       
   683 
       
   684     "Modified: / 3.4.1998 / 13:33:14 / cg"
       
   685     "Created: / 3.4.1998 / 13:34:22 / cg"
       
   686 !
       
   687 
       
   688 longLongAt:byteIndex put:anInteger bigEndian:msb
       
   689     "store a signed longLong (64bit) integer.
       
   690      The index is a smalltalk index (i.e. 1-based).
       
   691      Same as #signedQuadWordAt:put: - for ST80 compatibility."
       
   692 
       
   693     |v|
       
   694 
       
   695     v := anInteger.
       
   696     anInteger < 0 ifTrue:[
       
   697         v := v + 16r10000000000000000
       
   698     ].
       
   699     ^ self unsignedLongLongAt:byteIndex put:v bigEndian:msb
       
   700 
       
   701     "Created: / 9.5.1998 / 01:10:24 / cg"
       
   702     "Modified: / 9.5.1998 / 01:13:34 / cg"
       
   703 !
       
   704 
       
   705 quadWordAt:index MSB:msb
       
   706     "return the 8-bytes starting at index as an (unsigned) Integer.
       
   707      The index is a smalltalk index (i.e. 1-based).
       
   708      Depending on msb, the value is retrieved MSB or LSB-first."
       
   709 
       
   710     |l 
       
   711      bIdx  "{ Class: SmallInteger }"
       
   712      delta "{ Class: SmallInteger }"|
       
   713 
       
   714     l := LargeInteger basicNew numberOfDigits:8.
       
   715     msb ifTrue:[
       
   716 	bIdx := index + 7.
       
   717 	delta := -1
       
   718     ] ifFalse:[
       
   719 	bIdx := index.
       
   720 	delta := 1
       
   721     ].
       
   722     1 to:8 do:[:i |
       
   723 	l digitAt:i put:(self basicAt:bIdx).
       
   724 	bIdx := bIdx + delta
       
   725     ].
       
   726     ^ l compressed
       
   727 
       
   728     "
       
   729      |b|
       
   730 
       
   731      b := ByteArray withAll:#(1 2 3 4 5 6 7 8).
       
   732      (b quadWordAt:1 MSB:false) printStringRadix:16  
       
   733     "
       
   734 
       
   735     "Modified: 5.11.1996 / 14:06:21 / cg"
       
   736 !
       
   737 
       
   738 quadWordAt:index put:anInteger MSB:msb
       
   739     "set the 8-bytes starting at index from the (unsigned) Integer value.
       
   740      The index is a smalltalk index (i.e. 1-based).
       
   741      The value must be in the range 0 to 16rFFFFFFFFFFFFFFFF.
       
   742      Depending on msb, the value is stored MSB-first or LSB-first."
       
   743 
       
   744     |bIdx  "{ Class: SmallInteger }"
       
   745      delta "{ Class: SmallInteger }"|
       
   746 
       
   747     ((anInteger < 0) or:[anInteger > 16rFFFFFFFFFFFFFFFF]) ifTrue:[
       
   748 	^ self elementBoundsError
       
   749     ].
       
   750 
       
   751     msb ifTrue:[
       
   752 	bIdx := index + 7.
       
   753 	delta := -1
       
   754     ] ifFalse:[
       
   755 	bIdx := index.
       
   756 	delta := 1
       
   757     ].
       
   758     1 to:8 do:[:i |
       
   759 	self basicAt:bIdx put:(anInteger digitAt:i).
       
   760 	bIdx := bIdx + delta.
       
   761     ].
       
   762     ^ anInteger
       
   763 
       
   764     "
       
   765      |b|
       
   766      b := ByteArray new:8.
       
   767      b quadWordAtIndex:1 put:16r0807060504030201 MSB:false.
       
   768      b inspect
       
   769     "
       
   770 !
       
   771 
       
   772 unsignedLongLongAt:index bigEndian:msb
       
   773     "return the 8-bytes starting at index as an (unsigned) Integer.
       
   774      The index is a smalltalk index (i.e. 1-based).
       
   775      Depending on msb, the value is retrieved MSB or LSB-first."
       
   776 
       
   777     |l 
       
   778      bIdx  "{ Class: SmallInteger }"
       
   779      delta "{ Class: SmallInteger }"|
       
   780 
       
   781     l := LargeInteger basicNew numberOfDigits:8.
       
   782     msb ifTrue:[
       
   783         bIdx := index + 7.
       
   784         delta := -1
       
   785     ] ifFalse:[
       
   786         bIdx := index.
       
   787         delta := 1
       
   788     ].
       
   789     1 to:8 do:[:i |
       
   790         l digitAt:i put:(self basicAt:bIdx).
       
   791         bIdx := bIdx + delta
       
   792     ].
       
   793     ^ l compressed
       
   794 
       
   795     "
       
   796      |b|
       
   797 
       
   798      b := ByteArray withAll:#(1 2 3 4 5 6 7 8).
       
   799      (b unsignedLongLongAt:1 bigEndian:false) printStringRadix:16  
       
   800     "
       
   801 
       
   802     "Modified: / 5.11.1996 / 14:06:21 / cg"
       
   803     "Modified: / 5.3.1998 / 14:04:44 / stefan"
       
   804 !
       
   805 
       
   806 unsignedLongLongAt:index put:anInteger
       
   807     "set the 8-bytes starting at index from the (unsigned) Integer value.
       
   808      The index is a smalltalk index (i.e. 1-based).
       
   809      The value must be in the range 0 to 16rFFFFFFFFFFFFFFFF.
       
   810      The value is stored in natural byte order."
       
   811 
       
   812     ^ self unsignedLongLongAt:index put:anInteger bigEndian:IsBigEndian
       
   813 
       
   814     "Created: / 5.3.1998 / 14:44:00 / stefan"
       
   815     "Modified: / 5.3.1998 / 15:02:32 / stefan"
       
   816 !
       
   817 
       
   818 unsignedLongLongAt:index put:anInteger bigEndian:msb
       
   819     "set the 8-bytes starting at index from the (unsigned) Integer value.
       
   820      The index is a smalltalk index (i.e. 1-based).
       
   821      The value must be in the range 0 to 16rFFFFFFFFFFFFFFFF.
       
   822      Depending on msb, the value is stored MSB-first or LSB-first."
       
   823 
       
   824     |bIdx  "{ Class: SmallInteger }"
       
   825      delta "{ Class: SmallInteger }"|
       
   826 
       
   827     ((anInteger < 0) or:[anInteger > 16rFFFFFFFFFFFFFFFF]) ifTrue:[
       
   828         ^ self elementBoundsError
       
   829     ].
       
   830 
       
   831     msb ifTrue:[
       
   832         bIdx := index + 7.
       
   833         delta := -1
       
   834     ] ifFalse:[
       
   835         bIdx := index.
       
   836         delta := 1
       
   837     ].
       
   838     1 to:8 do:[:i |
       
   839         self basicAt:bIdx put:(anInteger digitAt:i).
       
   840         bIdx := bIdx + delta.
       
   841     ].
       
   842     ^ anInteger
       
   843 
       
   844     "
       
   845      |b|
       
   846      b := ByteArray new:8.
       
   847      b unsignedLongLongAt:1 put:16r0807060504030201 bigEndian:false.
       
   848      b inspect
       
   849     "
       
   850 
       
   851     "Created: / 5.3.1998 / 14:06:02 / stefan"
       
   852 ! !
       
   853 
       
   854 !UninterpretedBytes methodsFor:'accessing-longs'!
       
   855 
   353 doubleWordAt:index
   856 doubleWordAt:index
   354     "return the 4-bytes starting at index as an (unsigned) Integer.
   857     "return the 4-bytes starting at index as an (unsigned) Integer.
   355      The index is a smalltalk index (i.e. 1-based).
   858      The index is a smalltalk index (i.e. 1-based).
   356      The value is retrieved in the machines natural byte order.
   859      The value is retrieved in the machines natural byte order.
   357      Subclasses may redefine this for better performance.
   860      Subclasses may redefine this for better performance.
   547      (i.e. indices are 1, 2, ...)"
  1050      (i.e. indices are 1, 2, ...)"
   548 
  1051 
   549     ^ self doubleWordAt:(index - 1 * 4 + 1) put:value MSB:msb
  1052     ^ self doubleWordAt:(index - 1 * 4 + 1) put:value MSB:msb
   550 
  1053 
   551     "Created: / 21.1.1998 / 17:44:19 / cg"
  1054     "Created: / 21.1.1998 / 17:44:19 / cg"
   552 !
       
   553 
       
   554 floatAt:index
       
   555     "return the 4-bytes starting at index as a ShortFloat.
       
   556      The index is a smalltalk index (i.e. 1-based).
       
   557      Notice, that (currently) ST/X Floats are what Doubles are in ST-80;
       
   558      therefore this method reads a 4-byte float from the byteArray and returns
       
   559      a float object which keeps an 8-byte double internally.
       
   560      Notice also, that the bytes are expected to be in this machines
       
   561      float representation and order - if the bytearray originated from another
       
   562      machine, some conversion is usually needed."
       
   563 
       
   564     |newFloat|
       
   565 
       
   566 %{
       
   567     /*
       
   568      * handle the most common cases fast ...
       
   569      */
       
   570     if (__isSmallInteger(index)) {
       
   571         char *cp;
       
   572         int sz;
       
   573 
       
   574         __fetchBytePointerAndSize__(self, &cp, &sz);
       
   575         if (cp) {
       
   576             unsigned INT idx = ((unsigned INT)__intVal(index)) - 1;
       
   577 
       
   578             if ((idx+(sizeof(float)-1)) < sz) {
       
   579                 cp += idx;
       
   580                 /*
       
   581                  * aligned
       
   582                  */
       
   583                 if (((INT)cp & (sizeof(float)-1)) == 0) {
       
   584                     float fVal = ((float *)cp)[0];
       
   585 		    OBJ f;
       
   586 
       
   587 		    __qMKSFLOAT(f, fVal);
       
   588                     RETURN (f);
       
   589                 }
       
   590             }
       
   591         }
       
   592     }
       
   593 %}.
       
   594 
       
   595     newFloat := ShortFloat basicNew.
       
   596     1 to:4 do:[:destIndex|
       
   597         newFloat basicAt:destIndex put:(self at:index - 1 + destIndex)
       
   598     ].
       
   599     ^ newFloat.
       
   600 !
       
   601 
       
   602 floatAt:index MSB:msb
       
   603     "return the 4-bytes starting at index as a ShortFloat.
       
   604      The index is a smalltalk index (i.e. 1-based).
       
   605      Notice, that (currently) ST/X Floats are what Doubles are in ST-80;
       
   606      therefore this method reads a 4-byte float from the byteArray and returns
       
   607      a float object which keeps an 8-byte double internally.
       
   608      Notice also, that the bytes are expected to be in this machines
       
   609      float representation and order - if the bytearray originated from another
       
   610      machine, some conversion is usually needed."
       
   611 
       
   612     |newFloat|
       
   613 
       
   614     msb == UninterpretedBytes isBigEndian ifTrue:[
       
   615         ^ self floatAt:index
       
   616     ].
       
   617 
       
   618     newFloat := ShortFloat basicNew.
       
   619     1 to:4 do:[:destIndex|
       
   620         newFloat basicAt:(5-destIndex) put:(self at:index - 1 + destIndex)
       
   621     ].
       
   622     ^ newFloat.
       
   623 
       
   624     "Modified: / 15.5.1998 / 17:20:19 / cg"
       
   625     "Created: / 15.5.1998 / 17:20:35 / cg"
       
   626 !
       
   627 
       
   628 floatAt:index put:aFloat
       
   629     "store the 4 bytes of value of the argument, aFloat into the receiver
       
   630      starting at index.
       
   631      The index is a smalltalk index (i.e. 1-based).
       
   632      Notice, that (currently) ST/X Floats are what Doubles are in ST-80.
       
   633      Notice also, that the bytes are expected to be in this machines
       
   634      float representation - if the bytearray originated from another
       
   635      machine, some conversion is usually needed."
       
   636 
       
   637     |sflt|
       
   638 
       
   639     sflt := aFloat asShortFloat.
       
   640 %{
       
   641     /*
       
   642      * handle the most common cases fast ...
       
   643      */
       
   644     if (__isSmallInteger(index) && __isShortFloat(sflt)) {
       
   645         char *cp;
       
   646         int sz;
       
   647 
       
   648         __fetchBytePointerAndSize__(self, &cp, &sz);
       
   649         if (cp) {
       
   650             unsigned INT idx = ((unsigned INT)__intVal(index)) - 1;
       
   651 
       
   652             if ((idx+(sizeof(float)-1)) < sz) {
       
   653                 cp += idx;
       
   654                 /*
       
   655                  * aligned
       
   656                  */
       
   657                 if (((INT)cp & (sizeof(float)-1)) == 0) {
       
   658                     ((float *)cp)[0] = __shortFloatVal(sflt);
       
   659 
       
   660                     RETURN (aFloat);
       
   661                 }
       
   662             }
       
   663         }
       
   664     }
       
   665 %}.
       
   666 
       
   667     1 to:4 do:[:srcIndex|
       
   668         self at:index - 1 + srcIndex put:(sflt basicAt:srcIndex)
       
   669     ].
       
   670     ^ aFloat
       
   671 !
       
   672 
       
   673 floatAt:index put:aFloat MSB:msb
       
   674     "store the 4 bytes of value of the argument, aFloat into the receiver
       
   675      starting at index.
       
   676      The index is a smalltalk index (i.e. 1-based).
       
   677      Notice, that (currently) ST/X Floats are what Doubles are in ST-80.
       
   678      Notice also, that the bytes are expected to be in this machines
       
   679      float representation - if the bytearray originated from another
       
   680      machine, some conversion is usually needed."
       
   681 
       
   682     |sflt|
       
   683 
       
   684     msb == UninterpretedBytes isBigEndian ifTrue:[
       
   685         ^ self floatAt:index put:aFloat
       
   686     ].
       
   687 
       
   688     sflt := aFloat asShortFloat.
       
   689     1 to:4 do:[:srcIndex|
       
   690         self at:index - 1 + srcIndex put:(sflt basicAt:(5-srcIndex))
       
   691     ].
       
   692     ^ aFloat
       
   693 
       
   694     "Created: / 15.5.1998 / 17:20:41 / cg"
       
   695 !
       
   696 
       
   697 ieeeDoubleAt:index
       
   698     "retrieve the 8 bytes starting at index as a float.
       
   699      The index is a smalltalk index (i.e. 1-based).
       
   700      The 8 bytes are assumed to be in IEEE floating point single precision
       
   701      number format."
       
   702 
       
   703     "
       
   704      currently, we assume that the machines native number format is already
       
   705      IEEE format - we need some more code here whenever ST/X is ported
       
   706      to an IBM 370 or old VAX etc.
       
   707      To date, all supported systems use IEEE float numbers, so there should be
       
   708      no problem.
       
   709     "
       
   710     self isIEEEFormat ifFalse:[self error:'unsupported operation'].
       
   711 
       
   712     ^ self doubleAt:index
       
   713 
       
   714     "Created: / 5.3.1998 / 10:50:03 / stefan"
       
   715 !
       
   716 
       
   717 ieeeDoubleAt:index put:aFloat
       
   718     "store the value of the argument, aFloat into the receiver
       
   719      The index is a smalltalk index (i.e. 1-based).
       
   720      starting at index. Storage is in IEEE floating point double precision format.
       
   721      (i.e. 8 bytes are stored)."
       
   722 
       
   723     "
       
   724      currently, we assume that the machines native number format is already
       
   725      IEEE format - we need some more code here whenever ST/X is ported
       
   726      to an IBM 370 or old VAX etc.
       
   727      To date, all supported systems use IEEE float numbers, so there should be
       
   728      no problem.
       
   729     "
       
   730     self isIEEEFormat ifFalse:[self error:'unsupported operation'].
       
   731 
       
   732     ^ self doubleAt:index put:aFloat
       
   733 
       
   734     "Created: / 5.3.1998 / 10:50:26 / stefan"
       
   735 !
       
   736 
       
   737 ieeeFloatAt:index
       
   738     "retrieve the 4 bytes starting at index as a float.
       
   739      The index is a smalltalk index (i.e. 1-based).
       
   740      The 4 bytes are assumed to be in IEEE floating point single precision
       
   741      number format."
       
   742 
       
   743     "
       
   744      currently, we assume that the machines native number format is already
       
   745      IEEE format - we need some more code here whenever ST/X is ported
       
   746      to an IBM 370 or old VAX etc.
       
   747      To date, all supported systems use IEEE float numbers, so there should be
       
   748      no problem.
       
   749     "
       
   750     self isIEEEFormat ifFalse:[self error:'unsupported operation'].
       
   751 
       
   752     ^ self floatAt:index
       
   753 
       
   754     "Created: / 5.3.1998 / 10:50:45 / stefan"
       
   755 !
       
   756 
       
   757 ieeeFloatAt:index put:aFloat
       
   758     "store the value of the argument, aFloat into the receiver
       
   759      starting at index, which is a smalltalk index (i.e. 1-based). 
       
   760      Storage is in IEEE floating point single precision format.
       
   761      (i.e. 4 bytes are stored). Since ST/X floats are really doubles, the low-
       
   762      order 4 bytes of the precision is lost."
       
   763 
       
   764     "
       
   765      currently, we assume that the machines native number format is already
       
   766      IEEE format - we need some more code here whenever ST/X is ported
       
   767      to an IBM 370 or old VAX etc.
       
   768      To date, all supported systems use IEEE float numbers, so there should be
       
   769      no problem.
       
   770     "
       
   771     self isIEEEFormat ifFalse:[self error:'unsupported operation'].
       
   772 
       
   773     ^ self floatAt:index put:aFloat
       
   774 
       
   775     "Created: / 5.3.1998 / 10:51:11 / stefan"
       
   776 !
  1055 !
   777 
  1056 
   778 longAt:index
  1057 longAt:index
   779     "return the 4-bytes starting at index as a signed Integer.
  1058     "return the 4-bytes starting at index as a signed Integer.
   780      The index is a smalltalk index (i.e. 1-based).
  1059      The index is a smalltalk index (i.e. 1-based).
   930 
  1209 
   931     "Created: / 9.5.1998 / 01:10:24 / cg"
  1210     "Created: / 9.5.1998 / 01:10:24 / cg"
   932     "Modified: / 9.5.1998 / 01:13:34 / cg"
  1211     "Modified: / 9.5.1998 / 01:13:34 / cg"
   933 !
  1212 !
   934 
  1213 
   935 longLongAt:index
       
   936     "return the 8-bytes starting at index as a signed Integer.
       
   937      The index is a smalltalk index (i.e. 1-based).
       
   938      The value is retrieved in the machines natural byte order.
       
   939      This may be worth a primitive."
       
   940 
       
   941     |w|
       
   942 
       
   943     w := self unsignedLongLongAt:index bigEndian:IsBigEndian.
       
   944     (w > (16r7FFFFFFFFFFFFFFF)) ifTrue:[
       
   945         ^ w - (16r10000000000000000)
       
   946     ].
       
   947     ^ w
       
   948 
       
   949     "
       
   950      |b|
       
   951      b := ByteArray new:4.
       
   952      b unsignedLongLongAt:1 put:16rFFFFFFFFFFFFFFFF.
       
   953      (b longLongAt:1)    
       
   954     "
       
   955 
       
   956     "Modified: / 1.7.1996 / 21:11:28 / cg"
       
   957     "Created: / 5.3.1998 / 14:40:05 / stefan"
       
   958     "Modified: / 5.3.1998 / 14:58:32 / stefan"
       
   959 !
       
   960 
       
   961 longLongAt:index bigEndian:msb
       
   962     "return the 8-bytes starting at index as a signed Integer.
       
   963      The index is a smalltalk index (i.e. 1-based).
       
   964      The value is retrieved in the given byte order.
       
   965      This may be worth a primitive."
       
   966 
       
   967     |w|
       
   968 
       
   969     w := self unsignedLongLongAt:index bigEndian:msb.
       
   970     (w > (16r7FFFFFFFFFFFFFFF)) ifTrue:[
       
   971         ^ w - (16r10000000000000000)
       
   972     ].
       
   973     ^ w
       
   974 
       
   975     "
       
   976      |b|
       
   977      b := ByteArray new:4.
       
   978      b unsignedLongLongAt:1 put:16rFFFFFFFFFFFFFFFF.
       
   979      (b longLongAt:1 msb:true)    
       
   980     "
       
   981 
       
   982     "Modified: / 5.3.1998 / 12:06:28 / stefan"
       
   983     "Created: / 5.3.1998 / 14:40:54 / stefan"
       
   984     "Modified: / 9.5.1998 / 01:10:59 / cg"
       
   985 !
       
   986 
       
   987 longLongAt:byteIndex put:anInteger
       
   988     "store a signed longLong (64bit) integer.
       
   989      The index is a smalltalk index (i.e. 1-based).
       
   990      Same as #signedQuadWordAt:put: - for ST80 compatibility."
       
   991 
       
   992     ^ self signedQuadWordAt:byteIndex put:anInteger
       
   993 
       
   994     "Modified: / 3.4.1998 / 13:33:14 / cg"
       
   995     "Created: / 3.4.1998 / 13:34:22 / cg"
       
   996 !
       
   997 
       
   998 longLongAt:byteIndex put:anInteger bigEndian:msb
       
   999     "store a signed longLong (64bit) integer.
       
  1000      The index is a smalltalk index (i.e. 1-based).
       
  1001      Same as #signedQuadWordAt:put: - for ST80 compatibility."
       
  1002 
       
  1003     |v|
       
  1004 
       
  1005     v := anInteger.
       
  1006     anInteger < 0 ifTrue:[
       
  1007         v := v + 16r10000000000000000
       
  1008     ].
       
  1009     ^ self unsignedLongLongAt:byteIndex put:v bigEndian:msb
       
  1010 
       
  1011     "Created: / 9.5.1998 / 01:10:24 / cg"
       
  1012     "Modified: / 9.5.1998 / 01:13:34 / cg"
       
  1013 !
       
  1014 
       
  1015 quadWordAt:index MSB:msb
       
  1016     "return the 8-bytes starting at index as an (unsigned) Integer.
       
  1017      The index is a smalltalk index (i.e. 1-based).
       
  1018      Depending on msb, the value is retrieved MSB or LSB-first."
       
  1019 
       
  1020     |l 
       
  1021      bIdx  "{ Class: SmallInteger }"
       
  1022      delta "{ Class: SmallInteger }"|
       
  1023 
       
  1024     l := LargeInteger basicNew numberOfDigits:8.
       
  1025     msb ifTrue:[
       
  1026 	bIdx := index + 7.
       
  1027 	delta := -1
       
  1028     ] ifFalse:[
       
  1029 	bIdx := index.
       
  1030 	delta := 1
       
  1031     ].
       
  1032     1 to:8 do:[:i |
       
  1033 	l digitAt:i put:(self basicAt:bIdx).
       
  1034 	bIdx := bIdx + delta
       
  1035     ].
       
  1036     ^ l compressed
       
  1037 
       
  1038     "
       
  1039      |b|
       
  1040 
       
  1041      b := ByteArray withAll:#(1 2 3 4 5 6 7 8).
       
  1042      (b quadWordAt:1 MSB:false) printStringRadix:16  
       
  1043     "
       
  1044 
       
  1045     "Modified: 5.11.1996 / 14:06:21 / cg"
       
  1046 !
       
  1047 
       
  1048 quadWordAt:index put:anInteger MSB:msb
       
  1049     "set the 8-bytes starting at index from the (unsigned) Integer value.
       
  1050      The index is a smalltalk index (i.e. 1-based).
       
  1051      The value must be in the range 0 to 16rFFFFFFFFFFFFFFFF.
       
  1052      Depending on msb, the value is stored MSB-first or LSB-first."
       
  1053 
       
  1054     |bIdx  "{ Class: SmallInteger }"
       
  1055      delta "{ Class: SmallInteger }"|
       
  1056 
       
  1057     ((anInteger < 0) or:[anInteger > 16rFFFFFFFFFFFFFFFF]) ifTrue:[
       
  1058 	^ self elementBoundsError
       
  1059     ].
       
  1060 
       
  1061     msb ifTrue:[
       
  1062 	bIdx := index + 7.
       
  1063 	delta := -1
       
  1064     ] ifFalse:[
       
  1065 	bIdx := index.
       
  1066 	delta := 1
       
  1067     ].
       
  1068     1 to:8 do:[:i |
       
  1069 	self basicAt:bIdx put:(anInteger digitAt:i).
       
  1070 	bIdx := bIdx + delta.
       
  1071     ].
       
  1072     ^ anInteger
       
  1073 
       
  1074     "
       
  1075      |b|
       
  1076      b := ByteArray new:8.
       
  1077      b quadWordAtIndex:1 put:16r0807060504030201 MSB:false.
       
  1078      b inspect
       
  1079     "
       
  1080 !
       
  1081 
       
  1082 shortAt:index
       
  1083     "return the 2-bytes starting at index as a signed Integer.
       
  1084      The index is a smalltalk index (i.e. 1-based).
       
  1085      The value is retrieved in the machines natural byte order.
       
  1086      This may be worth a primitive.
       
  1087      This is the ST80 equivalent of #signedWordAt:"
       
  1088 
       
  1089     ^ (self unsignedShortAt:index) signExtendedShortValue
       
  1090 
       
  1091     "
       
  1092      |b|
       
  1093      b := ByteArray new:2.
       
  1094      b unsignedShortAt:1 put:16rFFFF.
       
  1095      b shortAt:1  
       
  1096     "
       
  1097 
       
  1098     "Modified: / 1.7.1996 / 21:14:38 / cg"
       
  1099     "Created: / 5.3.1998 / 10:59:57 / stefan"
       
  1100     "Modified: / 5.3.1998 / 23:39:38 / stefan"
       
  1101 !
       
  1102 
       
  1103 shortAt:index bigEndian:msb
       
  1104     "return the 2-bytes starting at index as a signed Integer.
       
  1105      The index is a smalltalk index (i.e. 1-based).
       
  1106      The value is retrieved MSB-first, if the msb-arg is true;
       
  1107      LSB-first otherwise.
       
  1108      This is the ST80 equivalent of #signedWordAt:"
       
  1109 
       
  1110     ^ (self unsignedShortAt:index bigEndian:msb) signExtendedShortValue
       
  1111 
       
  1112     "
       
  1113      |b|
       
  1114      b := ByteArray new:2.
       
  1115      b unsignedShortAt:1 put:16rFFFF.
       
  1116      b shortAt:1  
       
  1117     "
       
  1118 
       
  1119     "Modified: / 1.7.1996 / 21:14:38 / cg"
       
  1120     "Created: / 5.3.1998 / 23:41:21 / stefan"
       
  1121 !
       
  1122 
       
  1123 shortAt:index put:value
       
  1124     "set the 2-bytes starting at index from the signed Integer value.
       
  1125      The index is a smalltalk index (i.e. 1-based).
       
  1126      The stored value must be in the range -32768 .. +32676.
       
  1127      The value is stored in the machines natural byteorder.
       
  1128      This may be worth a primitive.
       
  1129      This is the ST80 equivalent of #signedWordAt:put:"
       
  1130 
       
  1131 
       
  1132     |v|
       
  1133 
       
  1134     value >= 0 ifTrue:[
       
  1135         v := value
       
  1136     ] ifFalse:[
       
  1137         v := 16r10000 + value
       
  1138     ].
       
  1139     self unsignedShortAt:index put:v.
       
  1140     ^ value
       
  1141 
       
  1142     "
       
  1143      |b|
       
  1144      b := ByteArray new:6.
       
  1145      b shortAt:1 put:-1.
       
  1146      b shortAt:3 put:-2.
       
  1147      b shortAt:5 put:0.
       
  1148      b inspect
       
  1149     "
       
  1150 
       
  1151     "Modified: / 1.7.1996 / 21:12:07 / cg"
       
  1152     "Created: / 5.3.1998 / 11:02:05 / stefan"
       
  1153 !
       
  1154 
       
  1155 signedByteAt:index
       
  1156     "return the byte at index as a signed 8 bit value.
       
  1157      The index is a smalltalk index (i.e. 1-based).
       
  1158      This may be worth a primitive."
       
  1159 
       
  1160     ^ (self at:index) signExtendedByteValue
       
  1161 
       
  1162     "
       
  1163      |b|
       
  1164      b := ByteArray new:2.
       
  1165      b at:1 put:16rFF.
       
  1166      b at:2 put:16r7F.
       
  1167      b signedByteAt:1  
       
  1168     "
       
  1169 
       
  1170     "Modified: 1.7.1996 / 21:13:53 / cg"
       
  1171 !
       
  1172 
       
  1173 signedByteAt:index put:aSignedByteValue
       
  1174     "return the byte at index as a signed 8 bit value.
       
  1175      The index is a smalltalk index (i.e. 1-based).
       
  1176      Return the signedByteValue argument.
       
  1177      This may be worth a primitive."
       
  1178 
       
  1179     |b "{ Class: SmallInteger }"|
       
  1180 
       
  1181     aSignedByteValue >= 0 ifTrue:[
       
  1182 	b := aSignedByteValue
       
  1183     ] ifFalse:[
       
  1184 	b := 16r100 + aSignedByteValue
       
  1185     ].
       
  1186     self at:index put:b.
       
  1187     ^ aSignedByteValue
       
  1188 
       
  1189     "
       
  1190      |b|
       
  1191      b := ByteArray new:2.
       
  1192      b signedByteAt:1 put:-1.
       
  1193      b at:1   
       
  1194     "
       
  1195 
       
  1196     "Modified: 1.7.1996 / 21:12:37 / cg"
       
  1197 !
       
  1198 
       
  1199 signedDoubleWordAt:index
  1214 signedDoubleWordAt:index
  1200     "return the 4-bytes starting at index as a signed Integer.
  1215     "return the 4-bytes starting at index as a signed Integer.
  1201      The index is a smalltalk index (i.e. 1-based).
  1216      The index is a smalltalk index (i.e. 1-based).
  1202      The value is retrieved in the machines natural byte order.
  1217      The value is retrieved in the machines natural byte order.
  1203      This may be worth a primitive."
  1218      This may be worth a primitive."
  1292      b signedDoubleWordAt:1 put:-1.
  1307      b signedDoubleWordAt:1 put:-1.
  1293      (b doubleWordAt:1) printStringRadix:16   
  1308      (b doubleWordAt:1) printStringRadix:16   
  1294     "
  1309     "
  1295 
  1310 
  1296     "Modified: 1.7.1996 / 21:11:46 / cg"
  1311     "Modified: 1.7.1996 / 21:11:46 / cg"
  1297 !
       
  1298 
       
  1299 signedWordAt:index
       
  1300     "return the 2-bytes starting at index as a signed Integer.
       
  1301      The index is a smalltalk index (i.e. 1-based).
       
  1302      The value is retrieved in the machines natural byte order.
       
  1303      This may be worth a primitive."
       
  1304 
       
  1305     ^ (self wordAt:index) signExtendedShortValue
       
  1306 
       
  1307     "
       
  1308      |b|
       
  1309      b := ByteArray new:2.
       
  1310      b wordAt:1 put:16rFFFF.
       
  1311      b signedWordAt:1  
       
  1312     "
       
  1313 
       
  1314     "Modified: 1.7.1996 / 21:14:38 / cg"
       
  1315 !
       
  1316 
       
  1317 signedWordAt:index MSB:msb
       
  1318     "return the 2-bytes starting at index as a signed Integer.
       
  1319      The index is a smalltalk index (i.e. 1-based).
       
  1320      The value is retrieved MSB-first if the msb-arg is true,
       
  1321      LSB-first otherwise.
       
  1322      This may be worth a primitive."
       
  1323 
       
  1324     ^ (self wordAt:index MSB:msb) signExtendedShortValue
       
  1325 
       
  1326     "
       
  1327      |b|
       
  1328      b := ByteArray new:2.
       
  1329      b wordAt:1 put:16r0080.
       
  1330      b signedWordAt:1 MSB:true.  
       
  1331      b signedWordAt:1 MSB:false.  
       
  1332     "
       
  1333 
       
  1334     "Modified: 1.7.1996 / 21:15:57 / cg"
       
  1335 !
       
  1336 
       
  1337 signedWordAt:index put:value
       
  1338     "set the 2-bytes starting at index from the signed Integer value.
       
  1339      The index is a smalltalk index (i.e. 1-based).
       
  1340      The stored value must be in the range -32768 .. +32676.
       
  1341      The value is stored in the machines natural byteorder.
       
  1342      This may be worth a primitive.
       
  1343      This is the ST80 equivalent of #signedWordAt:put:"
       
  1344 
       
  1345 
       
  1346     |v|
       
  1347 
       
  1348     value >= 0 ifTrue:[
       
  1349         v := value
       
  1350     ] ifFalse:[
       
  1351         v := 16r10000 + value
       
  1352     ].
       
  1353     self unsignedShortAt:index put:v.
       
  1354     ^ value
       
  1355 
       
  1356     "
       
  1357      |b|
       
  1358      b := ByteArray new:6.
       
  1359      b shortAt:1 put:-1.
       
  1360      b shortAt:3 put:-2.
       
  1361      b shortAt:5 put:0.
       
  1362      b inspect
       
  1363     "
       
  1364 
       
  1365     "Modified: / 1.7.1996 / 21:12:07 / cg"
       
  1366     "Modified: / 5.3.1998 / 11:01:30 / stefan"
       
  1367 !
       
  1368 
       
  1369 signedWordAt:index put:value MSB:msb
       
  1370     "set the 2-bytes starting at index from the signed Integer value.
       
  1371      The index is a smalltalk index (i.e. 1-based).
       
  1372      The stored value must be in the range -32768 .. +32676.
       
  1373      The value is stored MSB-first, if the msb-arg is true;
       
  1374      LSB-first otherwise.
       
  1375      This may be worth a primitive."
       
  1376 
       
  1377     |v|
       
  1378 
       
  1379     value >= 0 ifTrue:[
       
  1380 	v := value
       
  1381     ] ifFalse:[
       
  1382 	v := 16r10000 + value
       
  1383     ].
       
  1384     self wordAt:index put:v MSB:msb.
       
  1385     ^ value
       
  1386 
       
  1387     "
       
  1388      |b|
       
  1389      b := ByteArray new:4.
       
  1390      b signedWordAt:1 put:-1.
       
  1391      b signedWordAt:3 put:-2.
       
  1392      b inspect
       
  1393     "
       
  1394 
       
  1395     "Modified: 1.7.1996 / 21:12:13 / cg"
       
  1396 !
       
  1397 
       
  1398 stringAt:index
       
  1399     "return a string starting at index up to the 0-byte.
       
  1400      The index is a smalltalk index (i.e. 1-based)."
       
  1401 
       
  1402     |stream i "{ Class: SmallInteger }" c|
       
  1403 
       
  1404     stream := WriteStream on:''.
       
  1405     i := index.
       
  1406     [(c := self basicAt:i) ~~ 0] whileTrue:[
       
  1407         stream nextPut:(Character value:c).
       
  1408         i := i + 1.
       
  1409     ].
       
  1410     ^ stream contents
       
  1411 
       
  1412     "Created: / 21.1.1998 / 17:44:50 / cg"
       
  1413 !
       
  1414 
       
  1415 stringAt:index put:aString
       
  1416     "copy aString to the externalBytes, starting at index up to
       
  1417      (and including) the 0-byte.
       
  1418      The index is a smalltalk index (i.e. 1-based)."
       
  1419 
       
  1420     |i "{ Class: SmallInteger }"|
       
  1421 
       
  1422     i := index.
       
  1423     aString do:[:aChar |
       
  1424         self basicAt:i put:aChar asciiValue.
       
  1425         i := i + 1.
       
  1426     ].
       
  1427     self basicAt:i put:0.
       
  1428     ^ aString
       
  1429 
       
  1430     "
       
  1431      |bytes|
       
  1432 
       
  1433      bytes := ExternalBytes new:10.
       
  1434      bytes stringAt:1 put:'hello'.
       
  1435      1 to:bytes size do:[:i |
       
  1436         Transcript showCR:(bytes at:i)
       
  1437      ]
       
  1438     "
       
  1439 
       
  1440     "Created: / 21.1.1998 / 17:45:02 / cg"
       
  1441 !
       
  1442 
       
  1443 stringAt:index size:maxSize
       
  1444     "return a string starting at index up to maxSize, or a 0-byte.
       
  1445      The index is a smalltalk index (i.e. 1-based)."
       
  1446 
       
  1447     |stream c i "{ Class: SmallInteger }"|
       
  1448 
       
  1449     stream := WriteStream on:(String new:maxSize).
       
  1450     i := index.
       
  1451     [(i <= maxSize)
       
  1452      and:[(c := self basicAt:i) ~~ 0]] whileTrue:[
       
  1453         stream nextPut:(Character value:c).
       
  1454         i := i + 1.
       
  1455     ].
       
  1456     ^ stream contents
       
  1457 
       
  1458     "Modified: / 21.1.1998 / 17:45:23 / cg"
       
  1459 !
  1312 !
  1460 
  1313 
  1461 unsignedLongAt:index
  1314 unsignedLongAt:index
  1462     "return the 4-bytes starting at index as an (unsigned) Integer.
  1315     "return the 4-bytes starting at index as an (unsigned) Integer.
  1463      The index is a smalltalk index (i.e. 1-based).
  1316      The index is a smalltalk index (i.e. 1-based).
  1579     "
  1432     "
  1580 
  1433 
  1581     "Modified: / 21.1.1998 / 17:43:34 / cg"
  1434     "Modified: / 21.1.1998 / 17:43:34 / cg"
  1582     "Created: / 5.3.1998 / 11:43:53 / stefan"
  1435     "Created: / 5.3.1998 / 11:43:53 / stefan"
  1583     "Modified: / 5.3.1998 / 11:47:30 / stefan"
  1436     "Modified: / 5.3.1998 / 11:47:30 / stefan"
  1584 !
  1437 ! !
  1585 
  1438 
  1586 unsignedLongLongAt:index bigEndian:msb
  1439 !UninterpretedBytes methodsFor:'accessing-shorts'!
  1587     "return the 8-bytes starting at index as an (unsigned) Integer.
  1440 
  1588      The index is a smalltalk index (i.e. 1-based).
  1441 shortAt:index
  1589      Depending on msb, the value is retrieved MSB or LSB-first."
  1442     "return the 2-bytes starting at index as a signed Integer.
  1590 
  1443      The index is a smalltalk index (i.e. 1-based).
  1591     |l 
  1444      The value is retrieved in the machines natural byte order.
  1592      bIdx  "{ Class: SmallInteger }"
  1445      This may be worth a primitive.
  1593      delta "{ Class: SmallInteger }"|
  1446      This is the ST80 equivalent of #signedWordAt:"
  1594 
  1447 
  1595     l := LargeInteger basicNew numberOfDigits:8.
  1448     ^ (self unsignedShortAt:index) signExtendedShortValue
  1596     msb ifTrue:[
  1449 
  1597         bIdx := index + 7.
  1450     "
  1598         delta := -1
  1451      |b|
       
  1452      b := ByteArray new:2.
       
  1453      b unsignedShortAt:1 put:16rFFFF.
       
  1454      b shortAt:1  
       
  1455     "
       
  1456 
       
  1457     "Modified: / 1.7.1996 / 21:14:38 / cg"
       
  1458     "Created: / 5.3.1998 / 10:59:57 / stefan"
       
  1459     "Modified: / 5.3.1998 / 23:39:38 / stefan"
       
  1460 !
       
  1461 
       
  1462 shortAt:index bigEndian:msb
       
  1463     "return the 2-bytes starting at index as a signed Integer.
       
  1464      The index is a smalltalk index (i.e. 1-based).
       
  1465      The value is retrieved MSB-first, if the msb-arg is true;
       
  1466      LSB-first otherwise.
       
  1467      This is the ST80 equivalent of #signedWordAt:"
       
  1468 
       
  1469     ^ (self unsignedShortAt:index bigEndian:msb) signExtendedShortValue
       
  1470 
       
  1471     "
       
  1472      |b|
       
  1473      b := ByteArray new:2.
       
  1474      b unsignedShortAt:1 put:16rFFFF.
       
  1475      b shortAt:1  
       
  1476     "
       
  1477 
       
  1478     "Modified: / 1.7.1996 / 21:14:38 / cg"
       
  1479     "Created: / 5.3.1998 / 23:41:21 / stefan"
       
  1480 !
       
  1481 
       
  1482 shortAt:index put:value
       
  1483     "set the 2-bytes starting at index from the signed Integer value.
       
  1484      The index is a smalltalk index (i.e. 1-based).
       
  1485      The stored value must be in the range -32768 .. +32676.
       
  1486      The value is stored in the machines natural byteorder.
       
  1487      This may be worth a primitive.
       
  1488      This is the ST80 equivalent of #signedWordAt:put:"
       
  1489 
       
  1490 
       
  1491     |v|
       
  1492 
       
  1493     value >= 0 ifTrue:[
       
  1494         v := value
  1599     ] ifFalse:[
  1495     ] ifFalse:[
  1600         bIdx := index.
  1496         v := 16r10000 + value
  1601         delta := 1
  1497     ].
  1602     ].
  1498     self unsignedShortAt:index put:v.
  1603     1 to:8 do:[:i |
  1499     ^ value
  1604         l digitAt:i put:(self basicAt:bIdx).
  1500 
  1605         bIdx := bIdx + delta
  1501     "
  1606     ].
  1502      |b|
  1607     ^ l compressed
  1503      b := ByteArray new:6.
  1608 
  1504      b shortAt:1 put:-1.
  1609     "
  1505      b shortAt:3 put:-2.
  1610      |b|
  1506      b shortAt:5 put:0.
  1611 
  1507      b inspect
  1612      b := ByteArray withAll:#(1 2 3 4 5 6 7 8).
  1508     "
  1613      (b unsignedLongLongAt:1 bigEndian:false) printStringRadix:16  
  1509 
  1614     "
  1510     "Modified: / 1.7.1996 / 21:12:07 / cg"
  1615 
  1511     "Created: / 5.3.1998 / 11:02:05 / stefan"
  1616     "Modified: / 5.11.1996 / 14:06:21 / cg"
  1512 !
  1617     "Modified: / 5.3.1998 / 14:04:44 / stefan"
  1513 
  1618 !
  1514 signedWordAt:index
  1619 
  1515     "return the 2-bytes starting at index as a signed Integer.
  1620 unsignedLongLongAt:index put:anInteger
  1516      The index is a smalltalk index (i.e. 1-based).
  1621     "set the 8-bytes starting at index from the (unsigned) Integer value.
  1517      The value is retrieved in the machines natural byte order.
  1622      The index is a smalltalk index (i.e. 1-based).
  1518      This may be worth a primitive."
  1623      The value must be in the range 0 to 16rFFFFFFFFFFFFFFFF.
  1519 
  1624      The value is stored in natural byte order."
  1520     ^ (self wordAt:index) signExtendedShortValue
  1625 
  1521 
  1626     ^ self unsignedLongLongAt:index put:anInteger bigEndian:IsBigEndian
  1522     "
  1627 
  1523      |b|
  1628     "Created: / 5.3.1998 / 14:44:00 / stefan"
  1524      b := ByteArray new:2.
  1629     "Modified: / 5.3.1998 / 15:02:32 / stefan"
  1525      b wordAt:1 put:16rFFFF.
  1630 !
  1526      b signedWordAt:1  
  1631 
  1527     "
  1632 unsignedLongLongAt:index put:anInteger bigEndian:msb
  1528 
  1633     "set the 8-bytes starting at index from the (unsigned) Integer value.
  1529     "Modified: 1.7.1996 / 21:14:38 / cg"
  1634      The index is a smalltalk index (i.e. 1-based).
  1530 !
  1635      The value must be in the range 0 to 16rFFFFFFFFFFFFFFFF.
  1531 
  1636      Depending on msb, the value is stored MSB-first or LSB-first."
  1532 signedWordAt:index MSB:msb
  1637 
  1533     "return the 2-bytes starting at index as a signed Integer.
  1638     |bIdx  "{ Class: SmallInteger }"
  1534      The index is a smalltalk index (i.e. 1-based).
  1639      delta "{ Class: SmallInteger }"|
  1535      The value is retrieved MSB-first if the msb-arg is true,
  1640 
  1536      LSB-first otherwise.
  1641     ((anInteger < 0) or:[anInteger > 16rFFFFFFFFFFFFFFFF]) ifTrue:[
  1537      This may be worth a primitive."
  1642         ^ self elementBoundsError
  1538 
  1643     ].
  1539     ^ (self wordAt:index MSB:msb) signExtendedShortValue
  1644 
  1540 
  1645     msb ifTrue:[
  1541     "
  1646         bIdx := index + 7.
  1542      |b|
  1647         delta := -1
  1543      b := ByteArray new:2.
       
  1544      b wordAt:1 put:16r0080.
       
  1545      b signedWordAt:1 MSB:true.  
       
  1546      b signedWordAt:1 MSB:false.  
       
  1547     "
       
  1548 
       
  1549     "Modified: 1.7.1996 / 21:15:57 / cg"
       
  1550 !
       
  1551 
       
  1552 signedWordAt:index put:value
       
  1553     "set the 2-bytes starting at index from the signed Integer value.
       
  1554      The index is a smalltalk index (i.e. 1-based).
       
  1555      The stored value must be in the range -32768 .. +32676.
       
  1556      The value is stored in the machines natural byteorder.
       
  1557      This may be worth a primitive.
       
  1558      This is the ST80 equivalent of #signedWordAt:put:"
       
  1559 
       
  1560 
       
  1561     |v|
       
  1562 
       
  1563     value >= 0 ifTrue:[
       
  1564         v := value
  1648     ] ifFalse:[
  1565     ] ifFalse:[
  1649         bIdx := index.
  1566         v := 16r10000 + value
  1650         delta := 1
  1567     ].
  1651     ].
  1568     self unsignedShortAt:index put:v.
  1652     1 to:8 do:[:i |
  1569     ^ value
  1653         self basicAt:bIdx put:(anInteger digitAt:i).
  1570 
  1654         bIdx := bIdx + delta.
  1571     "
  1655     ].
  1572      |b|
  1656     ^ anInteger
  1573      b := ByteArray new:6.
  1657 
  1574      b shortAt:1 put:-1.
  1658     "
  1575      b shortAt:3 put:-2.
  1659      |b|
  1576      b shortAt:5 put:0.
  1660      b := ByteArray new:8.
       
  1661      b unsignedLongLongAt:1 put:16r0807060504030201 bigEndian:false.
       
  1662      b inspect
  1577      b inspect
  1663     "
  1578     "
  1664 
  1579 
  1665     "Created: / 5.3.1998 / 14:06:02 / stefan"
  1580     "Modified: / 1.7.1996 / 21:12:07 / cg"
       
  1581     "Modified: / 5.3.1998 / 11:01:30 / stefan"
       
  1582 !
       
  1583 
       
  1584 signedWordAt:index put:value MSB:msb
       
  1585     "set the 2-bytes starting at index from the signed Integer value.
       
  1586      The index is a smalltalk index (i.e. 1-based).
       
  1587      The stored value must be in the range -32768 .. +32676.
       
  1588      The value is stored MSB-first, if the msb-arg is true;
       
  1589      LSB-first otherwise.
       
  1590      This may be worth a primitive."
       
  1591 
       
  1592     |v|
       
  1593 
       
  1594     value >= 0 ifTrue:[
       
  1595 	v := value
       
  1596     ] ifFalse:[
       
  1597 	v := 16r10000 + value
       
  1598     ].
       
  1599     self wordAt:index put:v MSB:msb.
       
  1600     ^ value
       
  1601 
       
  1602     "
       
  1603      |b|
       
  1604      b := ByteArray new:4.
       
  1605      b signedWordAt:1 put:-1.
       
  1606      b signedWordAt:3 put:-2.
       
  1607      b inspect
       
  1608     "
       
  1609 
       
  1610     "Modified: 1.7.1996 / 21:12:13 / cg"
  1666 !
  1611 !
  1667 
  1612 
  1668 unsignedShortAt:index
  1613 unsignedShortAt:index
  1669     "return the 2-bytes starting at index as an (unsigned) Integer.
  1614     "return the 2-bytes starting at index as an (unsigned) Integer.
  1670      The index is a smalltalk index (i.e. 1-based).
  1615      The index is a smalltalk index (i.e. 1-based).
  1893      (i.e. indices are 1, 2, ...)"
  1838      (i.e. indices are 1, 2, ...)"
  1894 
  1839 
  1895     ^ self wordAt:(index - 1 * 2 + 1) put:value MSB:msb
  1840     ^ self wordAt:(index - 1 * 2 + 1) put:value MSB:msb
  1896 
  1841 
  1897     "Created: / 21.1.1998 / 17:48:38 / cg"
  1842     "Created: / 21.1.1998 / 17:48:38 / cg"
       
  1843 ! !
       
  1844 
       
  1845 !UninterpretedBytes methodsFor:'accessing-strings'!
       
  1846 
       
  1847 stringAt:index
       
  1848     "return a string starting at index up to the 0-byte.
       
  1849      The index is a smalltalk index (i.e. 1-based)."
       
  1850 
       
  1851     |stream i "{ Class: SmallInteger }" c|
       
  1852 
       
  1853     stream := WriteStream on:''.
       
  1854     i := index.
       
  1855     [(c := self basicAt:i) ~~ 0] whileTrue:[
       
  1856         stream nextPut:(Character value:c).
       
  1857         i := i + 1.
       
  1858     ].
       
  1859     ^ stream contents
       
  1860 
       
  1861     "Created: / 21.1.1998 / 17:44:50 / cg"
       
  1862 !
       
  1863 
       
  1864 stringAt:index put:aString
       
  1865     "copy aString to the externalBytes, starting at index up to
       
  1866      (and including) the 0-byte.
       
  1867      The index is a smalltalk index (i.e. 1-based)."
       
  1868 
       
  1869     |i "{ Class: SmallInteger }"|
       
  1870 
       
  1871     i := index.
       
  1872     aString do:[:aChar |
       
  1873         self basicAt:i put:aChar asciiValue.
       
  1874         i := i + 1.
       
  1875     ].
       
  1876     self basicAt:i put:0.
       
  1877     ^ aString
       
  1878 
       
  1879     "
       
  1880      |bytes|
       
  1881 
       
  1882      bytes := ExternalBytes new:10.
       
  1883      bytes stringAt:1 put:'hello'.
       
  1884      1 to:bytes size do:[:i |
       
  1885         Transcript showCR:(bytes at:i)
       
  1886      ]
       
  1887     "
       
  1888 
       
  1889     "Created: / 21.1.1998 / 17:45:02 / cg"
       
  1890 !
       
  1891 
       
  1892 stringAt:index size:maxSize
       
  1893     "return a string starting at index up to maxSize, or a 0-byte.
       
  1894      The index is a smalltalk index (i.e. 1-based)."
       
  1895 
       
  1896     |stream c i "{ Class: SmallInteger }"|
       
  1897 
       
  1898     stream := WriteStream on:(String new:maxSize).
       
  1899     i := index.
       
  1900     [(i <= maxSize)
       
  1901      and:[(c := self basicAt:i) ~~ 0]] whileTrue:[
       
  1902         stream nextPut:(Character value:c).
       
  1903         i := i + 1.
       
  1904     ].
       
  1905     ^ stream contents
       
  1906 
       
  1907     "Modified: / 21.1.1998 / 17:45:23 / cg"
  1898 !
  1908 !
  1899 
  1909 
  1900 zeroByteStringAt:index maximumSize:count
  1910 zeroByteStringAt:index maximumSize:count
  1901     "extract a zeroByte-delimited string, given initial index and
  1911     "extract a zeroByte-delimited string, given initial index and
  1902      maximum number of characters (bytes).
  1912      maximum number of characters (bytes).
  1942 ! !
  1952 ! !
  1943 
  1953 
  1944 !UninterpretedBytes class methodsFor:'documentation'!
  1954 !UninterpretedBytes class methodsFor:'documentation'!
  1945 
  1955 
  1946 version
  1956 version
  1947     ^ '$Header: /cvs/stx/stx/libbasic/UninterpretedBytes.st,v 1.29 1998-05-15 15:26:45 cg Exp $'
  1957     ^ '$Header: /cvs/stx/stx/libbasic/UninterpretedBytes.st,v 1.30 1998-05-18 12:20:27 cg Exp $'
  1948 ! !
  1958 ! !
  1949 UninterpretedBytes initialize!
  1959 UninterpretedBytes initialize!