aboutsummaryrefslogtreecommitdiffstats
path: root/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangAtom.java
diff options
context:
space:
mode:
Diffstat (limited to 'lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangAtom.java')
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangAtom.java284
1 files changed, 284 insertions, 0 deletions
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangAtom.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangAtom.java
new file mode 100644
index 0000000000..4d53447164
--- /dev/null
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangAtom.java
@@ -0,0 +1,284 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2000-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.Serializable;
+
+/**
+ * Provides a Java representation of Erlang atoms. Atoms can be created from
+ * strings whose length is not more than {@link #maxAtomLength maxAtomLength}
+ * characters.
+ */
+public class OtpErlangAtom extends OtpErlangObject implements Serializable,
+ Cloneable {
+ // don't change this!
+ static final long serialVersionUID = -3204386396807876641L;
+
+ /** The maximun allowed length of an atom, in characters */
+ public static final int maxAtomLength = 0xff; // one byte length
+
+ private final String atom;
+
+ /**
+ * Create an atom from the given string.
+ *
+ * @param atom
+ * the string to create the atom from.
+ *
+ * @exception java.lang.IllegalArgumentException
+ * if the string is null or contains more than
+ * {@link #maxAtomLength maxAtomLength} characters.
+ */
+ public OtpErlangAtom(final String atom) {
+ if (atom == null) {
+ throw new java.lang.IllegalArgumentException(
+ "null string value");
+ }
+
+ if (atom.length() > maxAtomLength) {
+ throw new java.lang.IllegalArgumentException("Atom may not exceed "
+ + maxAtomLength + " characters");
+ }
+ this.atom = atom;
+ }
+
+ /**
+ * Create an atom from a stream containing an atom encoded in Erlang
+ * external format.
+ *
+ * @param buf
+ * the stream containing the encoded atom.
+ *
+ * @exception OtpErlangDecodeException
+ * if the buffer does not contain a valid external
+ * representation of an Erlang atom.
+ */
+ public OtpErlangAtom(final OtpInputStream buf)
+ throws OtpErlangDecodeException {
+ atom = buf.read_atom();
+ }
+
+ /**
+ * Create an atom whose value is "true" or "false".
+ */
+ public OtpErlangAtom(final boolean t) {
+ atom = String.valueOf(t);
+ }
+
+ /**
+ * Get the actual string contained in this object.
+ *
+ * @return the raw string contained in this object, without regard to Erlang
+ * quoting rules.
+ *
+ * @see #toString
+ */
+ public String atomValue() {
+ return atom;
+ }
+
+ /**
+ * The boolean value of this atom.
+ *
+ * @return the value of this atom expressed as a boolean value. If the atom
+ * consists of the characters "true" (independent of case) the value
+ * will be true. For any other values, the value will be false.
+ *
+ */
+ public boolean booleanValue() {
+ return Boolean.valueOf(atomValue()).booleanValue();
+ }
+
+ /**
+ * Get the printname of the atom represented by this object. The difference
+ * between this method and {link #atomValue atomValue()} is that the
+ * printname is quoted and escaped where necessary, according to the Erlang
+ * rules for atom naming.
+ *
+ * @return the printname representation of this atom object.
+ *
+ * @see #atomValue
+ */
+ @Override
+ public String toString() {
+ if (atomNeedsQuoting(atom)) {
+ return "'" + escapeSpecialChars(atom) + "'";
+ } else {
+ return atom;
+ }
+ }
+
+ /**
+ * Determine if two atoms are equal.
+ *
+ * @param o
+ * the other object to compare to.
+ *
+ * @return true if the atoms are equal, false otherwise.
+ */
+ @Override
+ public boolean equals(final Object o) {
+
+ if (!(o instanceof OtpErlangAtom)) {
+ return false;
+ }
+
+ final OtpErlangAtom atom = (OtpErlangAtom) o;
+ return this.atom.compareTo(atom.atom) == 0;
+ }
+
+ @Override
+ protected int doHashCode() {
+ return atom.hashCode();
+ }
+
+ /**
+ * Convert this atom to the equivalent Erlang external representation.
+ *
+ * @param buf
+ * an output stream to which the encoded atom should be
+ * written.
+ */
+ @Override
+ public void encode(final OtpOutputStream buf) {
+ buf.write_atom(atom);
+ }
+
+ /* the following four predicates are helpers for the toString() method */
+ private boolean isErlangDigit(final char c) {
+ return c >= '0' && c <= '9';
+ }
+
+ private boolean isErlangUpper(final char c) {
+ return c >= 'A' && c <= 'Z' || c == '_';
+ }
+
+ private boolean isErlangLower(final char c) {
+ return c >= 'a' && c <= 'z';
+ }
+
+ private boolean isErlangLetter(final char c) {
+ return isErlangLower(c) || isErlangUpper(c);
+ }
+
+ // true if the atom should be displayed with quotation marks
+ private boolean atomNeedsQuoting(final String s) {
+ char c;
+
+ if (s.length() == 0) {
+ return true;
+ }
+ if (!isErlangLower(s.charAt(0))) {
+ return true;
+ }
+
+ final int len = s.length();
+ for (int i = 1; i < len; i++) {
+ c = s.charAt(i);
+
+ if (!isErlangLetter(c) && !isErlangDigit(c) && c != '@') {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /*
+ * Get the atom string, with special characters escaped. Note that this
+ * function currently does not consider any characters above 127 to be
+ * printable.
+ */
+ private String escapeSpecialChars(final String s) {
+ char c;
+ final StringBuffer so = new StringBuffer();
+
+ final int len = s.length();
+ for (int i = 0; i < len; i++) {
+ c = s.charAt(i);
+
+ /*
+ * note that some of these escape sequences are unique to Erlang,
+ * which is why the corresponding 'case' values use octal. The
+ * resulting string is, of course, in Erlang format.
+ */
+
+ switch (c) {
+ // some special escape sequences
+ case '\b':
+ so.append("\\b");
+ break;
+
+ case 0177:
+ so.append("\\d");
+ break;
+
+ case 033:
+ so.append("\\e");
+ break;
+
+ case '\f':
+ so.append("\\f");
+ break;
+
+ case '\n':
+ so.append("\\n");
+ break;
+
+ case '\r':
+ so.append("\\r");
+ break;
+
+ case '\t':
+ so.append("\\t");
+ break;
+
+ case 013:
+ so.append("\\v");
+ break;
+
+ case '\\':
+ so.append("\\\\");
+ break;
+
+ case '\'':
+ so.append("\\'");
+ break;
+
+ case '\"':
+ so.append("\\\"");
+ break;
+
+ default:
+ // some other character classes
+ if (c < 027) {
+ // control chars show as "\^@", "\^A" etc
+ so.append("\\^" + (char) ('A' - 1 + c));
+ } else if (c > 126) {
+ // 8-bit chars show as \345 \344 \366 etc
+ so.append("\\" + Integer.toOctalString(c));
+ } else {
+ // character is printable without modification!
+ so.append(c);
+ }
+ }
+ }
+ return new String(so);
+ }
+
+}