aboutsummaryrefslogtreecommitdiffstats
path: root/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBitstr.java
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
committerErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
commit84adefa331c4159d432d22840663c38f155cd4c1 (patch)
treebff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBitstr.java
downloadotp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz
otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2
otp-84adefa331c4159d432d22840663c38f155cd4c1.zip
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBitstr.java')
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBitstr.java285
1 files changed, 285 insertions, 0 deletions
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBitstr.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBitstr.java
new file mode 100644
index 0000000000..97897fe182
--- /dev/null
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangBitstr.java
@@ -0,0 +1,285 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2007-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+package com.ericsson.otp.erlang;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+
+/**
+ * Provides a Java representation of Erlang bitstrs. An Erlang bitstr is an
+ * Erlang binary with a length not an integral number of bytes (8-bit). Anything
+ * can be represented as a sequence of bytes can be made into an Erlang bitstr.
+ */
+public class OtpErlangBitstr extends OtpErlangObject implements Serializable,
+ Cloneable {
+ // don't change this!
+ static final long serialVersionUID = -3781009633593609217L;
+
+ protected byte[] bin;
+ protected int pad_bits;
+
+ /**
+ * Create a bitstr from a byte array
+ *
+ * @param bin
+ * the array of bytes from which to create the bitstr.
+ */
+ public OtpErlangBitstr(final byte[] bin) {
+ this.bin = new byte[bin.length];
+ System.arraycopy(bin, 0, this.bin, 0, bin.length);
+ pad_bits = 0;
+ }
+
+ /**
+ * Create a bitstr with pad bits from a byte array.
+ *
+ * @param bin
+ * the array of bytes from which to create the bitstr.
+ * @param pad_bits
+ * the number of unused bits in the low end of the last byte.
+ */
+ public OtpErlangBitstr(final byte[] bin, final int pad_bits) {
+ this.bin = new byte[bin.length];
+ System.arraycopy(bin, 0, this.bin, 0, bin.length);
+ this.pad_bits = pad_bits;
+
+ check_bitstr(this.bin, this.pad_bits);
+ }
+
+ private void check_bitstr(final byte[] bin, final int pad_bits) {
+ if (pad_bits < 0 || 7 < pad_bits) {
+ throw new java.lang.IllegalArgumentException(
+ "Padding must be in range 0..7");
+ }
+ if (pad_bits != 0 && bin.length == 0) {
+ throw new java.lang.IllegalArgumentException(
+ "Padding on zero length bitstr");
+ }
+ if (bin.length != 0) {
+ // Make sure padding is zero
+ bin[bin.length - 1] &= ~((1 << pad_bits) - 1);
+ }
+ }
+
+ /**
+ * Create a bitstr from a stream containing a bitstr encoded in Erlang
+ * external format.
+ *
+ * @param buf
+ * the stream containing the encoded bitstr.
+ *
+ * @exception OtpErlangDecodeException
+ * if the buffer does not contain a valid external
+ * representation of an Erlang bitstr.
+ */
+ public OtpErlangBitstr(final OtpInputStream buf)
+ throws OtpErlangDecodeException {
+ final int pbs[] = { 0 }; // This is ugly just to get a value-result
+ // parameter
+ bin = buf.read_bitstr(pbs);
+ pad_bits = pbs[0];
+
+ check_bitstr(bin, pad_bits);
+ }
+
+ /**
+ * Create a bitstr from an arbitrary Java Object. The object must implement
+ * java.io.Serializable or java.io.Externalizable.
+ *
+ * @param o
+ * the object to serialize and create this bitstr from.
+ */
+ public OtpErlangBitstr(final Object o) {
+ try {
+ bin = toByteArray(o);
+ pad_bits = 0;
+ } catch (final IOException e) {
+ throw new java.lang.IllegalArgumentException(
+ "Object must implement Serializable");
+ }
+ }
+
+ private static byte[] toByteArray(final Object o)
+ throws java.io.IOException {
+
+ if (o == null) {
+ return null;
+ }
+
+ /* need to synchronize use of the shared baos */
+ final java.io.ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ final java.io.ObjectOutputStream oos = new java.io.ObjectOutputStream(
+ baos);
+
+ oos.writeObject(o);
+ oos.flush();
+
+ return baos.toByteArray();
+ }
+
+ private static Object fromByteArray(final byte[] buf) {
+ if (buf == null) {
+ return null;
+ }
+
+ try {
+ final java.io.ByteArrayInputStream bais = new java.io.ByteArrayInputStream(
+ buf);
+ final java.io.ObjectInputStream ois = new java.io.ObjectInputStream(
+ bais);
+ return ois.readObject();
+ } catch (final java.lang.ClassNotFoundException e) {
+ } catch (final java.io.IOException e) {
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the byte array from a bitstr, padded with zero bits in the little end
+ * of the last byte.
+ *
+ * @return the byte array containing the bytes for this bitstr.
+ */
+ public byte[] binaryValue() {
+ return bin;
+ }
+
+ /**
+ * Get the size in whole bytes of the bitstr, rest bits in the last byte not
+ * counted.
+ *
+ * @return the number of bytes contained in the bintstr.
+ */
+ public int size() {
+ if (pad_bits == 0) {
+ return bin.length;
+ }
+ if (bin.length == 0) {
+ throw new java.lang.IllegalStateException("Impossible length");
+ }
+ return bin.length - 1;
+ }
+
+ /**
+ * Get the number of pad bits in the last byte of the bitstr. The pad bits
+ * are zero and in the little end.
+ *
+ * @return the number of pad bits in the bitstr.
+ */
+ public int pad_bits() {
+ return pad_bits;
+ }
+
+ /**
+ * Get the java Object from the bitstr. If the bitstr contains a serialized
+ * Java object, then this method will recreate the object.
+ *
+ *
+ * @return the java Object represented by this bitstr, or null if the bitstr
+ * does not represent a Java Object.
+ */
+ public Object getObject() {
+ if (pad_bits != 0) {
+ return null;
+ }
+ return fromByteArray(bin);
+ }
+
+ /**
+ * Get the string representation of this bitstr object. A bitstr is printed
+ * as #Bin&lt;N&gt;, where N is the number of bytes contained in the object
+ * or #bin&lt;N-M&gt; if there are M pad bits.
+ *
+ * @return the Erlang string representation of this bitstr.
+ */
+ @Override
+ public String toString() {
+ if (pad_bits == 0) {
+ return "#Bin<" + bin.length + ">";
+ }
+ if (bin.length == 0) {
+ throw new java.lang.IllegalStateException("Impossible length");
+ }
+ return "#Bin<" + bin.length + "-" + pad_bits + ">";
+ }
+
+ /**
+ * Convert this bitstr to the equivalent Erlang external representation.
+ *
+ * @param buf
+ * an output stream to which the encoded bitstr should be
+ * written.
+ */
+ @Override
+ public void encode(final OtpOutputStream buf) {
+ buf.write_bitstr(bin, pad_bits);
+ }
+
+ /**
+ * Determine if two bitstrs are equal. Bitstrs are equal if they have the
+ * same byte length and tail length, and the array of bytes is identical.
+ *
+ * @param o
+ * the bitstr to compare to.
+ *
+ * @return true if the bitstrs contain the same bits, false otherwise.
+ */
+ @Override
+ public boolean equals(final Object o) {
+ if (!(o instanceof OtpErlangBitstr)) {
+ return false;
+ }
+
+ final OtpErlangBitstr that = (OtpErlangBitstr) o;
+ if (pad_bits != that.pad_bits) {
+ return false;
+ }
+
+ final int len = bin.length;
+ if (len != that.bin.length) {
+ return false;
+ }
+
+ for (int i = 0; i < len; i++) {
+ if (bin[i] != that.bin[i]) {
+ return false; // early exit
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ protected int doHashCode() {
+ OtpErlangObject.Hash hash = new OtpErlangObject.Hash(15);
+ hash.combine(bin);
+ hash.combine(pad_bits);
+ return hash.valueOf();
+ }
+
+ @Override
+ public Object clone() {
+ final OtpErlangBitstr that = (OtpErlangBitstr) super.clone();
+ that.bin = bin.clone();
+ that.pad_bits = pad_bits;
+ return that;
+ }
+}