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

jetbrains.exodus.bindings.BindingUtils Maven / Gradle / Ivy

There is a newer version: 9.8.0.76914
Show newest version
/**
 * Copyright 2010 - 2022 JetBrains s.r.o.
 *
 * 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
 *
 * https://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 jetbrains.exodus.bindings;

import jetbrains.exodus.util.ByteArraySizedInputStream;
import jetbrains.exodus.util.UTFUtil;
import org.jetbrains.annotations.NotNull;

import java.io.ByteArrayInputStream;

public class BindingUtils {

    private BindingUtils() {
    }

    public static short readShort(@NotNull final ByteArrayInputStream stream) {
        return (short) (readUnsignedShort(stream) ^ 0x8000);
    }

    public static int readInt(@NotNull final ByteArrayInputStream stream) {
        return (int) (readUnsignedInt(stream) ^ 0x80000000);
    }

    public static long readLong(@NotNull final ByteArrayInputStream stream) {
        return readUnsignedLong(stream) ^ 0x8000000000000000L;
    }

    public static float readUnsignedFloat(@NotNull final ByteArrayInputStream stream) {
        return Float.intBitsToFloat((int) readUnsignedInt(stream));
    }

    public static float readSignedFloat(@NotNull final ByteArrayInputStream stream) {
        final int intValue = (int) readUnsignedInt(stream);
        return Float.intBitsToFloat(intValue ^ (intValue < 0 ? 0x80000000 : 0xffffffff));
    }

    public static double readUnsignedDouble(@NotNull final ByteArrayInputStream stream) {
        return Double.longBitsToDouble(readUnsignedLong(stream));
    }

    public static double readSignedDouble(@NotNull final ByteArrayInputStream stream) {
        final long longValue = readUnsignedLong(stream);
        return Double.longBitsToDouble(longValue ^ (longValue < 0 ? 0x8000000000000000L : 0xffffffffffffffffL));
    }

    public static String readString(@NotNull final ByteArrayInputStream stream) {
        int next = stream.read();
        if (next == UTFUtil.NULL_STRING_UTF_VALUE) {
            next = stream.read();
            if (next == 0) {
                return null;
            }
            throw new IllegalArgumentException();
        }
        if (next == 0) {
            return "";
        }
        if (!(stream instanceof ByteArraySizedInputStream)) {
            throw new IllegalArgumentException("ByteArraySizedInputStream is expected");
        }
        final ByteArraySizedInputStream sizedStream = (ByteArraySizedInputStream) stream;
        final byte[] bytes = sizedStream.toByteArray();
        final char[] chars = new char[sizedStream.size() - 1]; // minus trailing zero
        int i = sizedStream.pos();
        int j = 0;
        do {
            if (next < 128) {
                chars[j++] = (char) next;
            } else {
                final int high = next >> 4;
                if (high == 12 || high == 13) {
                    final int char2 = bytes[i++] & 0xff;
                    if ((char2 & 0xC0) != 0x80) {
                        throw new IllegalArgumentException();
                    }
                    chars[j++] = (char) (((next & 0x1F) << 6) | (char2 & 0x3F));
                } else if (high == 14) {
                    final int char2 = bytes[i] & 0xff;
                    final int char3 = bytes[i + 1] & 0xff;
                    i += 2;
                    if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) {
                        throw new IllegalArgumentException();
                    }
                    chars[j++] = (char) (((next & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F)));
                } else {
                    throw new IllegalArgumentException();
                }
            }
            next = bytes[i++] & 0xff;
        } while (next != 0);
        sizedStream.setPos(i);
        return new String(chars, 0, j);
    }

    private static int readUnsignedShort(@NotNull final ByteArrayInputStream stream) {
        final int c1 = stream.read();
        final int c2 = stream.read();
        if ((c1 | c2) < 0) {
            throw new IndexOutOfBoundsException();
        }
        return ((c1 << 8) | c2);
    }

    private static long readUnsignedInt(@NotNull final ByteArrayInputStream stream) {
        final long c1 = stream.read();
        final long c2 = stream.read();
        final long c3 = stream.read();
        final long c4 = stream.read();
        if ((c1 | c2 | c3 | c4) < 0) {
            throw new IndexOutOfBoundsException();
        }
        return ((c1 << 24) | (c2 << 16) | (c3 << 8) | c4);
    }

    private static long readUnsignedLong(@NotNull final ByteArrayInputStream stream) {
        final long c1 = stream.read();
        final long c2 = stream.read();
        final long c3 = stream.read();
        final long c4 = stream.read();
        final long c5 = stream.read();
        final long c6 = stream.read();
        final long c7 = stream.read();
        final long c8 = stream.read();
        if ((c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8) < 0) {
            throw new IndexOutOfBoundsException();
        }
        return ((c1 << 56) | (c2 << 48) | (c3 << 40) | (c4 << 32) |
                (c5 << 24) | (c6 << 16) | (c7 << 8) | c8);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy