All Downloads are FREE. Search and download functionalities are using the official Maven repository.

hydraql.shaded.fastjson2.util.UnsafeUtils Maven / Gradle / Ivy

package hydraql.shaded.fastjson2.util;

import hydraql.shaded.fastjson2.JSONException;
import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.util.function.BiFunction;

import static hydraql.shaded.fastjson2.util.JDKUtils.JVM_VERSION;

public class UnsafeUtils {
    public static final Unsafe UNSAFE;

    static long STRING_CODER_OFFSET;
    static long STRING_VALUE_OFFSET;

    static {
        Unsafe unsafe = null;
        try {
            Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe");
            theUnsafeField.setAccessible(true);
            unsafe = (Unsafe) theUnsafeField.get(null);
        } catch (Throwable ignored) {
            // ignored
        }
        UNSAFE = unsafe;
    }

    public static long objectFieldOffset(Field field) {
        return UNSAFE.objectFieldOffset(field);
    }

    public static byte getStringCoder(String str) {
        // GraalVM not support
        // Android not support
        if (str == null) {
            throw new NullPointerException();
        }

        if (JVM_VERSION == 8) {
            return 1;
        }

        if (STRING_CODER_OFFSET == 0) {
            try {
                Field fieldCode = String.class.getDeclaredField("coder");
                STRING_CODER_OFFSET = UNSAFE.objectFieldOffset(fieldCode);
            } catch (Exception e) {
                throw new JSONException("unsafe get String.coder error", e);
            }
        }

        return UNSAFE.getByte(str, STRING_CODER_OFFSET);
    }

    public static byte[] getStringValue(String str) {
        // GraalVM not support
        // Android not support
        if (str == null) {
            throw new NullPointerException();
        }

        if (STRING_VALUE_OFFSET == 0) {
            try {
                Field fieldCode = String.class.getDeclaredField("value");
                STRING_VALUE_OFFSET = UNSAFE.objectFieldOffset(fieldCode);
            } catch (Exception e) {
                throw new JSONException("unsafe get String.value error", e);
            }
        }

        return (byte[]) UNSAFE.getObject(str, STRING_VALUE_OFFSET);
    }

    public static final class UnsafeStringCreator
            implements BiFunction {
        final long coderOffset;
        final long valueOffset;

        public UnsafeStringCreator() throws Exception {
            Field fieldCode = String.class.getDeclaredField("coder");
            Field fieldValue = String.class.getDeclaredField("value");

            coderOffset = UNSAFE.objectFieldOffset(fieldCode);
            valueOffset = UNSAFE.objectFieldOffset(fieldValue);
        }

        @Override
        public Object apply(Object value, Object coder) {
            try {
                Object str = UNSAFE.allocateInstance(String.class);
                UNSAFE.putByte(str, coderOffset, ((Byte) coder).byteValue());
                UNSAFE.putObject(str, valueOffset, value);
                return str;
            } catch (Throwable ex) {
                throw new JSONException("create string error");
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy