1 /* 2 * %CopyrightBegin% 3 * 4 * Copyright Ericsson AB 2000-2016. All Rights Reserved. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 * %CopyrightEnd% 19 */ 20 package com.ericsson.otp.erlang; 21 22 /** 23 * Provides a Java representation of Erlang ports. 24 */ 25 public class OtpErlangPort extends OtpErlangObject { 26 // don't change this! 27 private static final long serialVersionUID = 4037115468007644704L; 28 29 private final String node; 30 private final long id; 31 private final int creation; 32 33 /* 34 * Create a unique Erlang port belonging to the local node. Since it isn't 35 * meaninful to do so, this constructor is private... 36 * 37 * @param self the local node. 38 * 39 * @deprecated use OtpLocalNode:createPort() instead 40 */ 41 @SuppressWarnings("unused") OtpErlangPort(final OtpSelf self)42 private OtpErlangPort(final OtpSelf self) { 43 final OtpErlangPort p = self.createPort(); 44 45 id = p.id; 46 creation = p.creation; 47 node = p.node; 48 } 49 50 /** 51 * Create an Erlang port from a stream containing a port encoded in Erlang 52 * external format. 53 * 54 * @param buf 55 * the stream containing the encoded port. 56 * 57 * @exception OtpErlangDecodeException 58 * if the buffer does not contain a valid external 59 * representation of an Erlang port. 60 */ OtpErlangPort(final OtpInputStream buf)61 public OtpErlangPort(final OtpInputStream buf) 62 throws OtpErlangDecodeException { 63 final OtpErlangPort p = buf.read_port(); 64 65 node = p.node(); 66 id = p.id(); 67 creation = p.creation(); 68 } 69 70 /** 71 * Create an Erlang port from its components. 72 * 73 * @param node 74 * the nodename. 75 * 76 * @param id 77 * an arbitrary number. Only the low order 28 bits will be used. 78 * 79 * @param creation 80 * another arbitrary number. Only the low order 2 bits will be used. 81 */ OtpErlangPort(final String node, final long id, final int creation)82 public OtpErlangPort(final String node, final long id, final int creation) { 83 this(OtpExternal.portTag, node, id, creation); 84 } 85 86 /** 87 * Create an Erlang port from its components. 88 * 89 * @param tag 90 * the external format to be compliant with. 91 * OtpExternal.portTag where only a subset of the bits are used (see other constructor) 92 * OtpExternal.newPortTag where all 32 bits of id and creation are significant. 93 * newPortTag can only be decoded by OTP-19 and newer. 94 * @param node 95 * the nodename. 96 * 97 * @param id 98 * an arbitrary number. Only the low order 28 bits will be used. 99 * 100 * @param creation 101 * another arbitrary number. 102 */ OtpErlangPort(final int tag, final String node, final long id, final int creation)103 public OtpErlangPort(final int tag, final String node, final long id, 104 final int creation) { 105 this.node = node; 106 if (tag == OtpExternal.portTag) { 107 this.id = id & 0xfffffff; // 28 bits 108 this.creation = creation & 0x3; // 2 bits 109 } 110 else { 111 this.id = id; 112 this.creation = creation; 113 } 114 } 115 tag()116 protected int tag() { 117 return OtpExternal.newPortTag; 118 } 119 120 /** 121 * Get the id number from the port. 122 * 123 * @return the id number from the port. 124 */ id()125 public long id() { 126 return id; 127 } 128 129 /** 130 * Get the creation number from the port. 131 * 132 * @return the creation number from the port. 133 */ creation()134 public int creation() { 135 return creation; 136 } 137 138 /** 139 * Get the node name from the port. 140 * 141 * @return the node name from the port. 142 */ node()143 public String node() { 144 return node; 145 } 146 147 /** 148 * Get the string representation of the port. Erlang ports are printed as 149 * #Port<node.id>. 150 * 151 * @return the string representation of the port. 152 */ 153 @Override toString()154 public String toString() { 155 return "#Port<" + node + "." + id + ">"; 156 } 157 158 /** 159 * Convert this port to the equivalent Erlang external representation. 160 * 161 * @param buf 162 * an output stream to which the encoded port should be written. 163 */ 164 @Override encode(final OtpOutputStream buf)165 public void encode(final OtpOutputStream buf) { 166 buf.write_port(this); 167 } 168 169 /** 170 * Determine if two ports are equal. Ports are equal if their components are 171 * equal. 172 * 173 * @param o 174 * the other port to compare to. 175 * 176 * @return true if the ports are equal, false otherwise. 177 */ 178 @Override equals(final Object o)179 public boolean equals(final Object o) { 180 if (!(o instanceof OtpErlangPort)) { 181 return false; 182 } 183 184 final OtpErlangPort port = (OtpErlangPort) o; 185 186 return creation == port.creation && id == port.id 187 && node.compareTo(port.node) == 0; 188 } 189 190 @Override doHashCode()191 protected int doHashCode() { 192 final OtpErlangObject.Hash hash = new OtpErlangObject.Hash(6); 193 hash.combine(creation); 194 hash.combine(id); 195 hash.combine(node.hashCode()); 196 return hash.valueOf(); 197 } 198 } 199