dap4/d4servlet/src/main/java/dap4/servlet/SerialWriter.java
static public ByteBuffer
    encodeArray(DapType vtype, Object values, ByteOrder order)
            throws IOException
    {
        TypeSort atomtype = vtype.getAtomicType();
        assert values != null && values.getClass().isArray();
        int count = Array.getLength(values);
        int total = (int) TypeSort.getSize(atomtype) * count;
        ByteBuffer buf = ByteBuffer.allocate(total).order(order);
        switch (atomtype) {
        case Char:
            char[] datac = (char[]) values;
            for(int i = 0; i < datac.length; i++) {
                byte b = (byte) (0xFFL & (long) (datac[i]));
                buf.put(b);
            }
            break;
        case UInt8:
        case Int8:
            byte[] data8 = (byte[]) values;
            buf.put(data8);
            break;
        case Int16:
        case UInt16:
            short[] data16 = (short[]) values;
            buf.asShortBuffer().put(data16);
            buf.position(total); // because we are using asXXXBuffer
            break;
        case Int32:
        case UInt32:
            int[] data32 = (int[]) values;
            buf.asIntBuffer().put(data32);
            buf.position(total); // because we are using asXXXBuffer
            break;
        case Int64:
        case UInt64:
            long[] data64 = (long[]) values;
            buf.asLongBuffer().put(data64);
            buf.position(total); // because we are using asXXXBuffer
            break;
        case Float32:
            float[] dataf = (float[]) values;
            buf.asFloatBuffer().put(dataf);
            buf.position(total); // because we are using asXXXBuffer
            break;
        case Float64:
            double[] datad = (double[]) values;
            buf.asDoubleBuffer().put(datad);
            buf.position(total); // because we are using asXXXBuffer
            break;
        case URL:
        case String:
            // Convert the string to a counted UTF-8 bytestring
            String[] datas = (String[]) values;
            // Pass 1: get total size
            total = 0;
            for(int i = 0; i < datas.length; i++) {
                String content = datas[i];
                byte[] bytes = content.getBytes(DapUtil.UTF8);
                total += (bytes.length + COUNTSIZE);
            }
            buf = ByteBuffer.allocate(total).order(order);
            // Pass 2: write the strings
            for(int i = 0; i < datas.length; i++) {
                String content = datas[i];
                byte[] bytes = content.getBytes(DapUtil.UTF8);
                buf.putLong(bytes.length);
                buf.put(bytes);
            }
            break;

        case Opaque:
            // Unfortunately, Array.get1d does not produce
            // a ByteBuffer[].
            Object[] datao = (Object[]) values;
            // Pass 1: get total size
            total = 0;
            int size = 0;
            for(int i = 0; i < datao.length; i++) {
                ByteBuffer opaquedata = (ByteBuffer) datao[i];
                // the data may be at an offset in the buffer
                size = opaquedata.remaining(); // should be limit - pos
                total += (size + COUNTSIZE);
            }
            buf = ByteBuffer.allocate(total).order(order);
            // Pass 2: write the opaque elements
            for(int i = 0; i < datao.length; i++) {
                ByteBuffer opaquedata = (ByteBuffer) datao[i];
                size = opaquedata.remaining(); // should be limit - pos
                buf.putLong(size);
                int savepos = opaquedata.position();
                buf.put(opaquedata);
                opaquedata.position(savepos);
            }
            break;

        case Enum: // handled by getPrimitiveType() above
            assert false : "Unexpected ENUM type";
        default:
            throw new DapException("Unknown type: " + vtype.getTypeName());
        }
        return buf;
    }
static public ByteBuffer
    encodeArray(DapType vtype, Object values, ByteOrder order)
            throws IOException
    {
        TypeSort atomtype = vtype.getAtomicType();
        assert values != null && values.getClass().isArray();
        int count = Array.getLength(values);
        int total = (int) TypeSort.getSize(atomtype) * count;
        ByteBuffer buf = ByteBuffer.allocate(total).order(order);
        switch (atomtype) {
        case Char:
            char[] datac = (char[]) values;
            for(int i = 0; i < datac.length; i++) {
                byte b = (byte) (0xFFL & (long) (datac[i]));
                buf.put(b);
            }
            break;
        case UInt8:
        case Int8:
            byte[] data8 = (byte[]) values;
            buf.put(data8);
            break;
        case Int16:
        case UInt16:
            short[] data16 = (short[]) values;
            buf.asShortBuffer().put(data16);
            buf.position(total); // because we are using asXXXBuffer
            break;
        case Int32:
        case UInt32:
            int[] data32 = (int[]) values;
            buf.asIntBuffer().put(data32);
            buf.position(total); // because we are using asXXXBuffer
            break;
        case Int64:
        case UInt64:
            long[] data64 = (long[]) values;
            buf.asLongBuffer().put(data64);
            buf.position(total); // because we are using asXXXBuffer
            break;
        case Float32:
            float[] dataf = (float[]) values;
            buf.asFloatBuffer().put(dataf);
            buf.position(total); // because we are using asXXXBuffer
            break;
        case Float64:
            double[] datad = (double[]) values;
            buf.asDoubleBuffer().put(datad);
            buf.position(total); // because we are using asXXXBuffer
            break;
        case URL:
        case String:
            // Convert the string to a counted UTF-8 bytestring
            String[] datas = (String[]) values;
            // Pass 1: get total size
            total = 0;
            for(int i = 0; i < datas.length; i++) {
                String content = datas[i];
                byte[] bytes = content.getBytes(DapUtil.UTF8);
                total += (bytes.length + COUNTSIZE);
            }
            buf = ByteBuffer.allocate(total).order(order);
            // Pass 2: write the strings
            for(int i = 0; i < datas.length; i++) {
                String content = datas[i];
                byte[] bytes = content.getBytes(DapUtil.UTF8);
                buf.putLong(bytes.length);
                buf.put(bytes);
            }
            break;

        case Opaque:
            // Unfortunately, Array.get1d does not produce
            // a ByteBuffer[].
            Object[] datao = (Object[]) values;
            // Pass 1: get total size
            total = 0;
            int size = 0;
            for(int i = 0; i < datao.length; i++) {
                ByteBuffer opaquedata = (ByteBuffer) datao[i];
                // the data may be at an offset in the buffer
                size = opaquedata.remaining(); // should be limit - pos
                total += (size + COUNTSIZE);
            }
            buf = ByteBuffer.allocate(total).order(order);
            // Pass 2: write the opaque elements
            for(int i = 0; i < datao.length; i++) {
                ByteBuffer opaquedata = (ByteBuffer) datao[i];
                size = opaquedata.remaining(); // should be limit - pos
                buf.putLong(size);
                int savepos = opaquedata.position();
                buf.put(opaquedata);
                opaquedata.position(savepos);
            }
            break;

        case Enum: // handled by getPrimitiveType() above
            assert false : "Unexpected ENUM type";
        default:
            throw new DapException("Unknown type: " + vtype.getTypeName());
        }
        return buf;
    }
Encode an array of primitive values.

@param vtype  The type of the object
@param values The value array
@return bytebuffer encoding of the array using the
platform's native encoding.