test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/AttributeBuilder.java
changeset 48826 c4d9d1b08e2e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/AttributeBuilder.java	Fri Sep 08 10:46:46 2017 -0700
@@ -0,0 +1,125 @@
+/*
+ * 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.
+ *
+ * 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 jdk.experimental.bytecode;
+
+/**
+ * Base builder for attribute containing class file entities.
+ *
+ * @param <S> the type of the symbol representation
+ * @param <T> the type of type descriptors representation
+ * @param <E> the type of pool entries
+ * @param <D> the type of this builder
+ */
+ public class AttributeBuilder<S, T, E, D extends AttributeBuilder<S, T, E, D>>
+        extends AbstractBuilder<S, T, E, D> {
+
+     /**
+      * The number of attributes.
+      */
+    protected int nattrs;
+
+    /**
+     * The attributes represented as bytes.
+     */
+    protected GrowableByteBuffer attributes = new GrowableByteBuffer();
+
+    /**
+     * Create an attribute builder.
+     *
+     * @param poolHelper the helper to build the constant pool
+     * @param typeHelper the helper to use to manipulate type descriptors
+     */
+    public AttributeBuilder(PoolHelper<S, T, E> poolHelper, TypeHelper<S, T> typeHelper) {
+        super(poolHelper, typeHelper);
+    }
+
+    /**
+     * Add a class file Attribute.  Defined as:
+     * <pre>
+     * {@code   attribute_info {
+     *     u2 attribute_name_index;
+     *     u4 attribute_length;
+     *     u1 info[attribute_length];
+     *   }}
+     * </pre>
+     *
+     * @param name the attribute name
+     * @param bytes the bytes of the attribute info
+     * @return this builder, for chained calls
+     */
+    public D withAttribute(CharSequence name, byte[] bytes) {
+        attributes.writeChar(poolHelper.putUtf8(name));
+        attributes.writeInt(bytes.length);
+        attributes.writeBytes(bytes);
+        nattrs++;
+        return thisBuilder();
+    }
+
+    /**
+     * Add a class file Attribute, using a writer.  Defined as:
+     * <pre>
+     * {@code   attribute_info {
+     *     u2 attribute_name_index;
+     *     u4 attribute_length;
+     *     u1 info[attribute_length];
+     *   }}
+     * </pre>
+     *
+     * @param <Z> the type of the object representing the attribute
+     * @param name the attribute name
+     * @param attr the representation of the attribute
+     * @param attrWriter the writer which transform the attribute representation into bytes
+     * @return this builder, for chained calls
+     */
+    public <Z> D withAttribute(CharSequence name, Z attr, AttributeWriter<S, T, E, Z> attrWriter) {
+        attributes.writeChar(poolHelper.putUtf8(name));
+        int offset = attributes.offset;
+        attributes.writeInt(0);
+        attrWriter.write(attr, poolHelper, attributes);
+        int len = attributes.offset - offset - 4;
+        attributes.withOffset(offset, buf -> buf.writeInt(len));
+        nattrs++;
+        return thisBuilder();
+    }
+
+     /**
+      * Writer for transforming attribute representations to bytes
+      *
+      * @param <S> the type of symbol representation
+      * @param <T> the type of type descriptors representation
+      * @param <E> the type of pool entries
+      * @param <A> the type of the object representing the attribute
+      */
+    public interface AttributeWriter<S, T, E, A> {
+
+        /**
+         * Write an attribute representation into a byte buffer.
+         *
+         * @param attr the representation of the attribute
+         * @param poolHelper the constant pool helper
+         * @param buf the buffer to collect the bytes
+         */
+        void write(A attr, PoolHelper<S, T, E> poolHelper, GrowableByteBuffer buf);
+    }
+}