UninterpretedBytes.st
changeset 18880 b1b117bdaa9e
parent 18666 aa1bd3d0fb7f
child 18883 765cf9dca720
child 18969 510f79020ae8
--- a/UninterpretedBytes.st	Thu Oct 29 13:32:23 2015 +0100
+++ b/UninterpretedBytes.st	Thu Oct 29 13:33:14 2015 +0100
@@ -1704,6 +1704,115 @@
     "Modified: / 9.5.1998 / 01:13:34 / cg"
 !
 
+nativeIntAt:index
+    "return the 4- or 8-bytes (depending on the native integer/pointer size) starting at index as a signed Integer.
+     The index is a smalltalk index (i.e. 1-based).
+     The value is retrieved in the machines natural byte order,
+     therefore, this should only be used for byte-data which is
+     only used inside this machine."
+
+    |w|
+
+%{
+    /*
+     * handle the most common cases fast ...
+     */
+    if (__isSmallInteger(index)) {
+        unsigned char *cp;
+        INT sz;
+
+        __fetchBytePointerAndSize__(self, &cp, &sz);
+        if (cp) {
+            unsigned INT idx = ((unsigned INT)__intVal(index)) - 1;
+
+            if ((idx+(sizeof(INT)-1)) < sz) {
+                cp += idx;
+#if defined(__i386__)
+                /*
+                 * aligned or not, we dont care (i386 can do both)
+                 */
+                {
+                    INT iVal = ((INT *)cp)[0];
+
+                    RETURN (__MKINT(iVal));
+                }
+#else
+                /*
+                 * aligned
+                 */
+                if (((INT)cp & (sizeof(INT)-1)) == 0) {
+                    INT iVal = ((INT *)cp)[0];
+
+                    RETURN (__MKINT(iVal));
+                }
+#endif
+            }
+        }
+    }
+%}.
+
+    ^ self primitiveFailed.
+
+    "
+     |b|
+     b := ByteArray new:8.
+     b nativeIntAt:1 put:SmallInteger maxVal.
+     b nativeIntAt:1
+    "
+!
+
+nativeIntAt:index put:value
+    "set the 4- or 8-bytes (depending on INT-/pointer size) starting at index from the signed Integer value.
+     The index is a smalltalk index (i.e. 1-based).
+     The value is stored in the machines natural byte order."
+
+    |v|
+
+%{
+    /*
+     * handle the most common cases fast ...
+     */
+    if (__isSmallInteger(index)) {
+        unsigned char *cp;
+        INT sz;
+
+        __fetchBytePointerAndSize__(self, &cp, &sz);
+        if (cp) {
+            unsigned INT idx = ((unsigned INT)__intVal(index)) - 1;
+
+            if ((idx+(sizeof(INT)-1)) < sz) {
+                cp += idx;
+                /*
+                 * aligned
+                 */
+                if (((INT)cp & (sizeof(INT)-1)) == 0) {
+                    INT __v;
+
+                    if (__isSmallInteger(value)) {
+                        // how about a range check?
+                        ((INT *)cp)[0] = (INT)(__intVal(value));
+                        RETURN (value);
+                    }
+                    if ((__v = __signedLongIntVal(value)) != 0) {
+                        // how about a range check?
+                        ((INT *)cp)[0] = (INT)(__v);
+                        RETURN (value);
+                    }
+                }
+            }
+        }
+    }
+%}.
+    ^ self primitiveFailed.
+
+    "
+     |b|
+     b := ByteArray new:8.
+     b nativeIntAt:1 put:SmallInteger maxVal.
+     (b nativeIntAt:1) 
+    "
+!
+
 pointerAt:index
     "get a pointer starting at index as ExternalAddress.
      The index is a smalltalk index (i.e. 1-based).