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