/* * Copyright 2014-2020 Real Logic Limited. * * 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 org.agrona.agent; import org.agrona.BitUtil; import org.agrona.DirectBuffer; import net.bytebuddy.asm.Advice; /** * Interceptor to be applied when verifying buffer alignment accesses. */ @SuppressWarnings("unused") public class BufferAlignmentInterceptor { abstract static class Verifier { public static void verifyAlignment(final int index, final @Advice.This DirectBuffer buffer, final int alignment) { final int alignmentOffset = (int)(buffer.addressOffset() + index) % alignment; if (0 != alignmentOffset) { throw new BufferAlignmentException( "Unaligned " + alignment + "-byte access (index=" + index + ", offset=" + alignmentOffset + ")"); } } } /** * Verifier for {@code long} types. */ public static final class LongVerifier extends Verifier { @Advice.OnMethodEnter public static void verifyAlignment(final int index, final @Advice.This DirectBuffer buffer) { verifyAlignment(index, buffer, BitUtil.SIZE_OF_LONG); } } /** * Verifier for {@code double} types. */ public static final class DoubleVerifier extends Verifier { @Advice.OnMethodEnter public static void verifyAlignment(final int index, final @Advice.This DirectBuffer buffer) { verifyAlignment(index, buffer, BitUtil.SIZE_OF_DOUBLE); } } /** * Verifier for {@code int} types. */ public static final class IntVerifier extends Verifier { @Advice.OnMethodEnter public static void verifyAlignment(final int index, final @Advice.This DirectBuffer buffer) { verifyAlignment(index, buffer, BitUtil.SIZE_OF_INT); } } /** * Verifier for {@code float} types. */ public static final class FloatVerifier extends Verifier { @Advice.OnMethodEnter public static void verifyAlignment(final int index, final @Advice.This DirectBuffer buffer) { verifyAlignment(index, buffer, BitUtil.SIZE_OF_FLOAT); } } /** * Verifier for {@code short} types. */ public static final class ShortVerifier extends Verifier { @Advice.OnMethodEnter public static void verifyAlignment(final int index, final @Advice.This DirectBuffer buffer) { verifyAlignment(index, buffer, BitUtil.SIZE_OF_SHORT); } } /** * Verifier for {@code char} types. */ public static final class CharVerifier extends Verifier { @Advice.OnMethodEnter public static void verifyAlignment(final int index, final @Advice.This DirectBuffer buffer) { verifyAlignment(index, buffer, BitUtil.SIZE_OF_CHAR); } } }