From 140002ad8a9895e688220c27737a8caa559993b5 Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Sun, 3 Jun 2007 01:40:07 +0000 Subject: Add adapter for supporting primitive arrays. --- .../carbonado/adapter/PrimitiveArrayAdapter.java | 227 +++++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100644 src/main/java/com/amazon/carbonado/adapter/PrimitiveArrayAdapter.java (limited to 'src/main/java/com/amazon/carbonado/adapter/PrimitiveArrayAdapter.java') diff --git a/src/main/java/com/amazon/carbonado/adapter/PrimitiveArrayAdapter.java b/src/main/java/com/amazon/carbonado/adapter/PrimitiveArrayAdapter.java new file mode 100644 index 0000000..f7b95a4 --- /dev/null +++ b/src/main/java/com/amazon/carbonado/adapter/PrimitiveArrayAdapter.java @@ -0,0 +1,227 @@ +/* + * Copyright 2007 Amazon Technologies, Inc. or its affiliates. + * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks + * of Amazon Technologies, Inc. or its affiliates. All rights reserved. + * + * 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 + * + * http://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 com.amazon.carbonado.adapter; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import java.nio.ByteBuffer; + +/** + * Allows arrays of primitive types to be encoded (big-endian) as byte arrays. + * + * @author Brian S O'Neill + * @since 1.2 + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@AdapterDefinition(storageTypePreferences=byte[].class) +public @interface PrimitiveArrayAdapter { + /** + * Adapter implementation for {@link PrimitiveArrayAdapter}. + */ + public static class Adapter { + /** + * @param type type of object that contains the adapted property + * @param propertyName name of property with adapter + * @param ann specific annotation that binds to this adapter class + */ + public Adapter(Class type, String propertyName, PrimitiveArrayAdapter ann) { + } + + public Adapter() { + } + + public byte[] adaptToByteArray(short[] src) { + if (src == null) { + return null; + } + byte[] dst = new byte[src.length << 1]; + ByteBuffer.wrap(dst).asShortBuffer().put(src); + return dst; + } + + public byte[] adaptToByteArray(char[] src) { + if (src == null) { + return null; + } + byte[] dst = new byte[src.length << 1]; + ByteBuffer.wrap(dst).asCharBuffer().put(src); + return dst; + } + + public byte[] adaptToByteArray(int[] src) { + if (src == null) { + return null; + } + byte[] dst = new byte[src.length << 2]; + ByteBuffer.wrap(dst).asIntBuffer().put(src); + return dst; + } + + public byte[] adaptToByteArray(long[] src) { + if (src == null) { + return null; + } + byte[] dst = new byte[src.length << 3]; + ByteBuffer.wrap(dst).asLongBuffer().put(src); + return dst; + } + + public byte[] adaptToByteArray(float[] src) { + if (src == null) { + return null; + } + byte[] dst = new byte[src.length << 2]; + ByteBuffer.wrap(dst).asFloatBuffer().put(src); + return dst; + } + + public byte[] adaptToByteArray(double[] src) { + if (src == null) { + return null; + } + byte[] dst = new byte[src.length << 3]; + ByteBuffer.wrap(dst).asDoubleBuffer().put(src); + return dst; + } + + /** + * Packs the given boolean array into a byte array, big-endian fashion. + */ + public byte[] adaptToByteArray(boolean[] src) { + if (src == null) { + return null; + } + + int srcLength = src.length; + byte[] dst = new byte[(srcLength + 7) >> 3]; + int dstOffset = 0; + + int i = 0; + while (i + 8 <= srcLength) { + dst[dstOffset++] = (byte) + ((src[i++] ? 0x80 : 0) | + (src[i++] ? 0x40 : 0) | + (src[i++] ? 0x20 : 0) | + (src[i++] ? 0x10 : 0) | + (src[i++] ? 0x08 : 0) | + (src[i++] ? 0x04 : 0) | + (src[i++] ? 0x02 : 0) | + (src[i++] ? 0x01 : 0)); + } + + if (i < srcLength) { + int accum = 0; + while (i < srcLength) { + accum = (accum << 1) | (src[i++] ? 1 : 0); + } + accum <<= 8 - (srcLength & 7); + dst[dstOffset] = (byte) accum; + } + + return dst; + } + + public short[] adaptToShortArray(byte[] src) { + if (src == null) { + return null; + } + short[] dst = new short[(src.length + 1) >> 1]; + ByteBuffer.wrap(src).asShortBuffer().get(dst); + return dst; + } + + public char[] adaptToCharArray(byte[] src) { + if (src == null) { + return null; + } + char[] dst = new char[(src.length + 1) >> 1]; + ByteBuffer.wrap(src).asCharBuffer().get(dst); + return dst; + } + + public int[] adaptToIntArray(byte[] src) { + if (src == null) { + return null; + } + int[] dst = new int[(src.length + 3) >> 2]; + ByteBuffer.wrap(src).asIntBuffer().get(dst); + return dst; + } + + public long[] adaptToLongArray(byte[] src) { + if (src == null) { + return null; + } + long[] dst = new long[(src.length + 7) >> 3]; + ByteBuffer.wrap(src).asLongBuffer().get(dst); + return dst; + } + + public float[] adaptToFloatArray(byte[] src) { + if (src == null) { + return null; + } + float[] dst = new float[(src.length + 3) >> 2]; + ByteBuffer.wrap(src).asFloatBuffer().get(dst); + return dst; + } + + public double[] adaptToDoubleArray(byte[] src) { + if (src == null) { + return null; + } + double[] dst = new double[(src.length + 7) >> 3]; + ByteBuffer.wrap(src).asDoubleBuffer().get(dst); + return dst; + } + + /** + * Unpacks a boolean array from a byte array, big-endian fashion. + */ + public boolean[] adaptToBooleanArray(byte[] src) { + if (src == null) { + return null; + } + + int srcLength = src.length; + boolean[] dst = new boolean[srcLength << 3]; + int dstOffset = 0; + + for (int i=0; i