/* ObjID.java --
   Copyright (c) 1996, 1997, 1998, 1999, 2004  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
 
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.rmi.server;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Serializable;

public final class ObjID implements Serializable
{
static final long serialVersionUID = -6386392263968365220L;

private static long next = 0x8000000000000000L;
private static final Object lock = ObjID.class;

public static final int REGISTRY_ID = 0;
public static final int ACTIVATOR_ID = 1;
public static final int DGC_ID = 2;

private long objNum;
private UID space;

public ObjID() {
	synchronized (lock) {
		objNum = next++;
	}
	space = new UID();
}

public ObjID(int num) {
	objNum = (long)num;
	space = new UID((short)0);
}

public void write(ObjectOutput out) throws IOException {
	DataOutput dout = (DataOutput)out;
	dout.writeLong(objNum);
	space.write(dout);
}

public static ObjID read(ObjectInput in) throws IOException {
	DataInput din = (DataInput)in;
	ObjID id = new ObjID();
	id.objNum = din.readLong();
	id.space = UID.read(din);
	return (id);
}

public int hashCode() {
	return ((int)objNum);
}

public boolean equals(Object obj) {
	if (obj instanceof ObjID && this.objNum == ((ObjID)obj).objNum) {
		return (true);
	}
	return (false);
}

public String toString() {
	return ("[objNum: " + objNum + ", " + space + "]");
}

}
