UninterpretedBytes.st
changeset 19197 641f64b6c686
parent 19196 1db38251aeb2
child 19227 5e949760a4e8
child 19301 21b0b9bf3a74
--- a/UninterpretedBytes.st	Sat Feb 13 12:04:28 2016 +0100
+++ b/UninterpretedBytes.st	Sat Feb 13 12:15:37 2016 +0100
@@ -549,6 +549,62 @@
 
 !UninterpretedBytes methodsFor:'accessing-arbitrary-long ints'!
 
+signedIntegerAt:index length:n bigEndian:bigEndian
+    "return the n-byte signed integer starting at index.
+     With n=1, this returns the single signed byte's value,
+     n=2, a signed short, n=4 a signed int etc.
+     Useful to extract arbitrary long integers"
+
+    |val highByte|
+
+    val := 0.
+    bigEndian ifTrue:[
+        highByte := (self at:index).
+        index to:index+n-1 do:[:i |
+            val := (val<<8) + (self at:i)
+        ]
+    ] ifFalse:[
+        highByte := (self at:index+n-1).
+        index+n-1 to:index by:-1 do:[:i |
+            val := (val<<8) + (self at:i)
+        ]
+    ].
+    (highByte bitTest:16r80) ifTrue:[
+        ^ val - (1 bitShift:(n*8))
+    ].    
+    ^ val
+
+    "
+     |b|
+     b := #[ 16r01 16rFF 16r00 16r04 16r05 ].
+     (b signedIntegerAt:2 length:2 bigEndian:false). ' -> 255 (00FF) '.
+     (b signedIntegerAt:2 length:2 bigEndian:true).  ' -> -256 (FF00) '.   
+
+     b := #[ 16r01 16r00 16rFF 16r04 16r05 ].
+     (b signedIntegerAt:2 length:2 bigEndian:false). ' -> -256 (FF00) '.
+     (b signedIntegerAt:2 length:2 bigEndian:true).  ' -> 255 (00FF) '.   
+
+     b := #[ 16r01 16r7F 16r00 16r04 16r05 ].
+     (b signedIntegerAt:2 length:2 bigEndian:false). ' -> 127 (007F) '.
+     (b signedIntegerAt:2 length:2 bigEndian:true).  ' -> 32512 (7F00) '.      
+    "
+    
+    "
+     |b|
+     b := #[ 16r01 16r02 16r03 16r04 16r05 ].
+     (b signedIntegerAt:2 length:4 bigEndian:false).
+     (b signedIntegerAt:2 length:4 bigEndian:true).
+
+     b := #[ 16r01 16r82 16r03 16r04 16r05 ].
+     (b signedIntegerAt:2 length:4 bigEndian:false).
+     (b signedIntegerAt:2 length:4 bigEndian:true).
+
+     b := #[ 16r01 16r82 16r03 16r04 16r85 ].
+     (b signedIntegerAt:2 length:4 bigEndian:false).
+     (b signedIntegerAt:2 length:4 bigEndian:true).
+    "
+!
+
 unsignedIntegerAt:index length:n bigEndian:bigEndian
     "return the n-byte unsigned integer starting at index.
      With n=1, this returns the single byte's value,