/* * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.api.interop; /** * This class represents {@link Message#KEY_INFO key info} bit flags. Use this class as a utility to * get or set the bit flags when dealing with {@link Message#KEY_INFO} message. * <p> * The bit flags have following meaning: * <ul style="list-style-type: none;"> * <li>0. bit: Existence of the key</li> * <li>1. bit: Readability of the key ({@link Message#READ} is supported)</li> * <li>2. bit: Writability of the key ({@link Message#WRITE} is supported)</li> * <li>3. bit: Invocability of the key ({@link Message#createInvoke(int)} is supported)</li> * <li>4. bit: Internal attribute of the key (see an internal argument to {@link Message#KEYS})</li> * </ul> * <p> * When a readable or writable flag is <code>true</code>, it does not necessarily guarantee that * subsequent {@link Message#READ} or {@link Message#WRITE} message will succeed. Read or write can * fail due to some momentary bad state. An object field is expected not to be readable resp. * writable when it's known that the field can not be read (e.g. a bean property without a getter) * resp. can not be written to (e.g. a bean property without a setter). The same applies to * invocable flag and {@link Message#createInvoke(int) invoke} message. * <p> * When the key does not exist (0. bit is zero), then all other bits must be zero as well. * * @since 0.26 */ public final class KeyInfo { private static final int READABLE = 1 << 1; private static final int WRITABLE = 1 << 2; private static final int INVOCABLE = 1 << 3; private static final int INTERNAL = 1 << 4; private KeyInfo() { } /** * Create a new bit flags builder. The builder is reusable and builds key info of existing keys * only. Use <code>0</code> directly to inform about a non-existing key. * * @since 0.26 */ public static Builder newBuilder() { return new KeyInfo().new Builder(); } /** * Test if the bits represent an existing key. * * @since 0.26 */ public static boolean isExisting(int infoBits) { return (infoBits & 1) != 0; } /** * Test if readable flag is on. * * @since 0.26 */ public static boolean isReadable(int infoBits) { return (infoBits & READABLE) != 0; } /** * Test if writable flag is on. * * @since 0.26 */ public static boolean isWritable(int infoBits) { return (infoBits & WRITABLE) != 0; } /** * Test if invocable flag is on. * * @since 0.26 */ public static boolean isInvocable(int infoBits) { return (infoBits & INVOCABLE) != 0; } /** * Test if internal flag is on. * * @since 0.26 */ public static boolean isInternal(int infoBits) { return (infoBits & INTERNAL) != 0; } /** * A builder of bit flags. An instance of this class can be reused for multiple key info bits * {@link #build() creation}. * * @since 0.26 */ public final class Builder { private int infoBits; private Builder() { infoBits = 1; } /** * Set readability flag. * * @since 0.26 */ public Builder setReadable(boolean readable) { setBit(1, readable); return this; } /** * Set writability flag. * * @since 0.26 */ public Builder setWritable(boolean readable) { setBit(2, readable); return this; } /** * Set invocability flag. * * @since 0.26 */ public Builder setInvocable(boolean readable) { setBit(3, readable); return this; } /** * Set internal attribute flag. * * @since 0.26 */ public Builder setInternal(boolean readable) { setBit(4, readable); return this; } /** * Get the current bit flags of this builder in an integer value. * * @since 0.26 */ public int build() { return infoBits; } private void setBit(int b, boolean value) { int v = value ? 1 : 0; infoBits = infoBits & ~(1 << b) | (v << b); } } }