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

org.nustaq.serialization.util.FSTUtil Maven / Gradle / Ivy

Go to download

A fast java serialization drop in-replacement and some serialization based utils such as Structs and OffHeap Memory.

There is a newer version: 3.0.4-jdk17
Show newest version
/*
 * Copyright 2014 Ruediger Moeller.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.nustaq.serialization.util;

import sun.misc.Unsafe;

import java.io.InputStream;
import java.io.ObjectStreamField;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: ruedi
 * Date: 29.11.12
 * Time: 20:38
 * To change this template use File | Settings | File Templates.
 */
public class FSTUtil {

    static Object[] EmptyObjArray = new Object[10000];
    static ObjectStreamField[] NO_FIELDS = new ObjectStreamField[0];
    public static Unsafe unFlaggedUnsafe = FSTUtil.getUnsafe(); // even if unsafe is disabled, use it for memoffset computation

    static {
        if (unFlaggedUnsafe != null) {
            refoff = unFlaggedUnsafe.arrayBaseOffset(Object[].class);
            bufoff = unFlaggedUnsafe.arrayBaseOffset(byte[].class);
            intoff = unFlaggedUnsafe.arrayBaseOffset(int[].class);
            longoff = unFlaggedUnsafe.arrayBaseOffset(long[].class);
            longscal = unFlaggedUnsafe.arrayIndexScale(long[].class);
            intscal = unFlaggedUnsafe.arrayIndexScale(int[].class);
            chscal = unFlaggedUnsafe.arrayIndexScale(char[].class);
            refscal = unFlaggedUnsafe.arrayIndexScale(Object[].class);
            choff = unFlaggedUnsafe.arrayBaseOffset(char[].class);
            doubleoff = unFlaggedUnsafe.arrayBaseOffset(double[].class);
            doublescal = unFlaggedUnsafe.arrayIndexScale(double[].class);
            floatoff = unFlaggedUnsafe.arrayBaseOffset(float[].class);
            floatscal = unFlaggedUnsafe.arrayIndexScale(float[].class);
        } else {
            refscal = 0;
            refoff = 0;
            longoff = 0;
            longscal = 0;
            bufoff = 0;
            intoff = 0;
            intscal = 0;
            choff = 0;
            chscal = 0;
            doublescal = 0;
            doubleoff = 0;
            floatscal = 0;
            floatoff = 0;
        }
    }

    public final static long refoff;
    public final static long refscal;
    public final static long bufoff;
    public final static long choff;
    public final static long intoff;
    public final static long longoff;
    public final static long doubleoff;
    public final static long floatoff;
    public final static long intscal;
    public final static long longscal;
    public final static long chscal;
    public final static long floatscal;
    public final static long doublescal;

    public static void clear(int[] arr) {
        Arrays.fill(arr, 0);
    }

    public static void clear(Object[] arr) {
        final int arrlen = arr.length;
        clear(arr, arrlen);
    }

    public static void clear(Object[] arr, int arrlen) {
        int count = 0;
        final int length = EmptyObjArray.length;
        while (arrlen - count > length) {
            System.arraycopy(EmptyObjArray, 0, arr, count, length);
            count += length;
        }
        System.arraycopy(EmptyObjArray, 0, arr, count, arrlen - count);
    }

    public static String toString(Throwable th) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        th.printStackTrace(pw);
        return th.getClass().getSimpleName() + ":" + th.getMessage() + "\n" + sw.toString();
    }

    public static  void rethrow(Throwable exception) throws T {
        throw (T) exception;
    }

    // obsolete
    public static String getPackage(Class clazz) {
        String s = clazz.getName();
        int i = s.lastIndexOf('[');
        if (i >= 0) {
            s = s.substring(i + 2);
        }
        i = s.lastIndexOf('.');
        if (i >= 0) {
            return s.substring(0, i);
        }
        return "";
    }

    public static boolean isPackEq(Class clazz1, Class clazz2) {
        return getPackage(clazz1).equals(getPackage(clazz2));
    }

    public static Method findPrivateMethod(Class clazz, String methName,
                                           Class[] clazzArgs,
                                           Class retClazz) {
        try {
            Method m = clazz.getDeclaredMethod(methName, clazzArgs);
            int modif = m.getModifiers();
            if ((m.getReturnType() == retClazz) && ((modif & Modifier.PRIVATE) != 0) && ((modif & Modifier.STATIC) == 0)) {
                m.setAccessible(true);
                return m;
            }
            return null;
        } catch (NoSuchMethodException ex) {
            return null;
        }
    }

    public static Method findDerivedMethod(Class clazz, String metnam,
                                           Class[] argClzz,
                                           Class retClz) {
        Method m = null;
        Class defCl = clazz;
        while (defCl != null) {
            try {
                m = defCl.getDeclaredMethod(metnam, argClzz);
                break;
            } catch (NoSuchMethodException ex) {
                defCl = defCl.getSuperclass();
            }
        }
        if (m == null) {
            return null;
        }
        if (m.getReturnType() != retClz) {
            return null;
        }
        int mods = m.getModifiers();
        if ((mods & (Modifier.STATIC | Modifier.ABSTRACT)) != 0) {
            return null;
        } else if ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) != 0) {
            m.setAccessible(true);
            return m;
        } else if ((mods & Modifier.PRIVATE) != 0) {
            m.setAccessible(true);
            if (clazz == defCl) {
                return m;
            }
            return null;
        } else {
            m.setAccessible(true);
            if (isPackEq(clazz, defCl)) {
                return m;
            }
            return null;
        }
    }

    public static void printEx(Throwable e) {
        while (e.getCause() != null && e.getCause() != e) {
            e = e.getCause();
        }
        e.printStackTrace();
    }

    public static boolean isPrimitiveArray(Class c) {
        Class componentType = c.getComponentType();
        if (componentType == null) {
            return c.isPrimitive();
        }
        return isPrimitiveArray(c.getComponentType());
    }

    public static Unsafe getUnsafe() {
        try {
            if (unFlaggedUnsafe != null)
                return unFlaggedUnsafe;
            Field f = Unsafe.class.getDeclaredField("theUnsafe");
            f.setAccessible(true);
            return (Unsafe) f.get(null);
        } catch (Exception e) { /* ... */ }
        return null;
    }

    public static int writeSignedVarInt(int value, byte out[], int index) {
        return writeUnsignedVarInt((value << 1) ^ (value >> 31), out, index);
    }

    public static int writeUnsignedVarInt(int value, byte[] out, int index) {
        while ((value & 0xFFFFFF80) != 0L) {
            out[index++] = (byte) ((value & 0x7F) | 0x80);
            value >>>= 7;
        }
        out[index++] = (byte) (value & 0x7F);
        return index;
    }

    public static List getAllFields(List fields, Class type) {
        fields.addAll(Arrays.asList(type.getDeclaredFields()));
        if (type.getSuperclass() != null) {
            fields = getAllFields(fields, type.getSuperclass());
        }
        return fields;
    }

    public static byte[] readAll(InputStream is)
            throws Exception {
        int pos = 0;
        byte[] buffer = new byte[1024];
        while (true) {
            int toRead;
            if (pos >= buffer.length) {
                toRead = buffer.length * 2;
                if (buffer.length < pos + toRead) {
                    buffer = Arrays.copyOf(buffer, pos + toRead);
                }
            } else {
                toRead = buffer.length - pos;
            }
            int byt = is.read(buffer, pos, toRead);
            if (byt < 0) {
                if (pos != buffer.length) {
                    buffer = Arrays.copyOf(buffer, pos);
                }
                break;
            }
            pos += byt;
        }
        return buffer;
    }

    public static int nextPow2(int num) {
        return 1 << (num == 0 ? 0 : 32 - Integer.numberOfLeadingZeros(num - 1));
    }

    public static Class getRealEnumClass(Class enumClass) {
        if (enumClass.isAnonymousClass()) {
            return enumClass.getSuperclass();
        }
        return enumClass;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy