#FEATURE
authorClaus Gittinger <cg@exept.de>
Fri, 11 Mar 2016 17:16:10 +0100
changeset 19345 e2526c51d771
parent 19344 7ca957505652
child 19346 8863a07310e9
#FEATURE class: UninterpretedBytes added: #pointerValueAt:
UninterpretedBytes.st
--- a/UninterpretedBytes.st	Fri Mar 11 16:58:26 2016 +0100
+++ b/UninterpretedBytes.st	Fri Mar 11 17:16:10 2016 +0100
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
 "
  COPYRIGHT (c) 1993 by Claus Gittinger
 	      All Rights Reserved
@@ -467,6 +469,7 @@
     "Modified: / 5.3.1998 / 14:56:22 / stefan"
 ! !
 
+
 !UninterpretedBytes methodsFor:'Compatibility-Squeak'!
 
 copyFromByteArray:aByteArray
@@ -2014,6 +2017,65 @@
     "Created: / 5.3.1998 / 10:57:18 / stefan"
 !
 
+pointerValueAt:index
+    "get a pointer starting at index as Integer.
+     The index is a smalltalk index (i.e. 1-based).
+     Only aligned accesses are allowed."
+
+%{
+    if (__isSmallInteger(index)) {
+        unsigned char *cp;
+        INT sz;
+
+        __fetchBytePointerAndSize__(self, &cp, &sz);
+        if (cp) {
+            unsigned INT idx = ((unsigned INT)__smallIntegerVal(index)) - 1;
+            char *pointer;
+
+            if ((idx+(sizeof(pointer)-1)) < sz) {
+                cp += idx;
+                /*
+                 * aligned
+                 */
+                if (((INT)cp & (sizeof(pointer)-1)) == 0) {
+                    pointer = ((char **)cp)[0];
+                    RETURN (__MKUINT((INT)(pointer)));
+                } else {
+#if 0
+                    printf("cp UNALIGNED (%"_lx_")\n", (INT)cp);
+#endif
+                }
+            } else {
+#if 0
+                printf("idx(%"_ld_")+(sizeof(pointer)-1) (%d) >= sz (%"_ld_")\n",
+                        idx, (int)(sizeof(pointer)-1), sz);
+#endif
+            }
+        } else {
+#if 0
+            printf("cp is NULL\n");
+#endif
+        }
+    } else {
+#if 0
+        printf("bad index\n");
+#endif
+    }
+bad:;
+%}.
+
+    self primitiveFailed.
+
+    "
+     |b|
+     b := ByteArray new:(ExternalAddress pointerSize).
+     b pointerAt:1 put:(ExternalAddress newAddress:16r12345678).
+     Transcript showCR:((b unsignedLongAt:1) printStringRadix:16).
+     Transcript showCR:((b pointerAt:1)).
+     Transcript showCR:((b pointerValueAt:1)).
+    "
+!
+
 signedDoubleWordAt:index
     "return the 4-bytes starting at index as a signed Integer.
      The index is a smalltalk index (i.e. 1-based).