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 PIDs. PIDs represent Erlang 24 * processes and consist of a nodename and a number of integers. 25 */ 26 public class OtpErlangPid extends OtpErlangObject implements Comparable<Object> { 27 // don't change this! 28 private static final long serialVersionUID = 1664394142301803659L; 29 30 private final int tag; 31 private final String node; 32 private final int id; 33 private final int serial; 34 private final int creation; 35 36 /** 37 * Create a unique Erlang PID belonging to the local node. 38 * 39 * @param self 40 * the local node. 41 * 42 * @deprecated use OtpLocalNode:createPid() instead 43 */ 44 @Deprecated OtpErlangPid(final OtpLocalNode self)45 public OtpErlangPid(final OtpLocalNode self) { 46 final OtpErlangPid p = self.createPid(); 47 48 tag = p.tag; 49 id = p.id; 50 serial = p.serial; 51 creation = p.creation; 52 node = p.node; 53 } 54 55 /** 56 * Create an Erlang PID from a stream containing a PID encoded in Erlang 57 * external format. 58 * 59 * @param buf 60 * the stream containing the encoded PID. 61 * 62 * @exception OtpErlangDecodeException 63 * if the buffer does not contain a valid external 64 * representation of an Erlang PID. 65 */ OtpErlangPid(final OtpInputStream buf)66 public OtpErlangPid(final OtpInputStream buf) 67 throws OtpErlangDecodeException { 68 final OtpErlangPid p = buf.read_pid(); 69 70 tag = p.tag; 71 node = p.node(); 72 id = p.id(); 73 serial = p.serial(); 74 creation = p.creation(); 75 } 76 77 /** 78 * Create an Erlang pid from its components. 79 * 80 * @param node 81 * the nodename. 82 * 83 * @param id 84 * an arbitrary number. Only the low order 15 bits will be used. 85 * 86 * @param serial 87 * another arbitrary number. Only the low order 13 bits will be 88 * used. 89 * 90 * @param creation 91 * yet another arbitrary number. Ony the low order 2 bits will 92 * be used. 93 */ OtpErlangPid(final String node, final int id, final int serial, final int creation)94 public OtpErlangPid(final String node, final int id, final int serial, 95 final int creation) { 96 this(OtpExternal.pidTag, node, id, serial, creation); 97 } 98 99 /** 100 * Create an Erlang pid from its components. 101 * 102 * @param tag 103 * the external format to be compliant with 104 * OtpExternal.pidTag where only a subset of the bits are significant (see other constructor). 105 * OtpExternal.newPidTag where all 32 bits of id,serial and creation are significant. 106 * newPidTag can only be decoded by OTP-19 and newer. 107 * @param node 108 * the nodename. 109 * 110 * @param id 111 * an arbitrary number. 112 * 113 * @param serial 114 * another arbitrary number. 115 * 116 * @param creation 117 * yet another arbitrary number. 118 */ OtpErlangPid(final int tag, final String node, final int id, final int serial, final int creation)119 protected OtpErlangPid(final int tag, final String node, final int id, 120 final int serial, final int creation) { 121 this.tag = tag; 122 this.node = node; 123 if (tag == OtpExternal.pidTag) { 124 this.id = id & 0x7fff; // 15 bits 125 this.serial = serial & 0x1fff; // 13 bits 126 this.creation = creation & 0x03; // 2 bits 127 } 128 else { // allow all 32 bits for newPidTag 129 this.id = id; 130 this.serial = serial; 131 this.creation = creation; 132 } 133 } 134 tag()135 protected int tag() { 136 return tag; 137 } 138 139 /** 140 * Get the serial number from the PID. 141 * 142 * @return the serial number from the PID. 143 */ serial()144 public int serial() { 145 return serial; 146 } 147 148 /** 149 * Get the id number from the PID. 150 * 151 * @return the id number from the PID. 152 */ id()153 public int id() { 154 return id; 155 } 156 157 /** 158 * Get the creation number from the PID. 159 * 160 * @return the creation number from the PID. 161 */ creation()162 public int creation() { 163 return creation; 164 } 165 166 /** 167 * Get the node name from the PID. 168 * 169 * @return the node name from the PID. 170 */ node()171 public String node() { 172 return node; 173 } 174 175 /** 176 * Get the string representation of the PID. Erlang PIDs are printed as 177 * #Pid<node.id.serial> 178 * 179 * @return the string representation of the PID. 180 */ 181 @Override toString()182 public String toString() { 183 return "#Pid<" + node.toString() + "." + id + "." + serial + ">"; 184 } 185 186 /** 187 * Convert this PID to the equivalent Erlang external representation. 188 * 189 * @param buf 190 * an output stream to which the encoded PID should be written. 191 */ 192 @Override encode(final OtpOutputStream buf)193 public void encode(final OtpOutputStream buf) { 194 buf.write_pid(this); 195 } 196 197 /** 198 * Determine if two PIDs are equal. PIDs are equal if their components are 199 * equal. 200 * 201 * @param o 202 * the other PID to compare to. 203 * 204 * @return true if the PIDs are equal, false otherwise. 205 */ 206 @Override equals(final Object o)207 public boolean equals(final Object o) { 208 if (!(o instanceof OtpErlangPid)) { 209 return false; 210 } 211 212 final OtpErlangPid pid = (OtpErlangPid) o; 213 214 return creation == pid.creation && serial == pid.serial && id == pid.id 215 && node.compareTo(pid.node) == 0; 216 } 217 218 @Override doHashCode()219 protected int doHashCode() { 220 final OtpErlangObject.Hash hash = new OtpErlangObject.Hash(5); 221 hash.combine(creation, serial); 222 hash.combine(id, node.hashCode()); 223 return hash.valueOf(); 224 } 225 compareTo(final Object o)226 public int compareTo(final Object o) { 227 if (!(o instanceof OtpErlangPid)) { 228 return -1; 229 } 230 231 final OtpErlangPid pid = (OtpErlangPid) o; 232 if (creation == pid.creation) { 233 if (serial == pid.serial) { 234 if (id == pid.id) { 235 return node.compareTo(pid.node); 236 } 237 return id - pid.id; 238 } 239 return serial - pid.serial; 240 } 241 return creation - pid.creation; 242 } 243 } 244