package org.jgroups.stack; import org.jgroups.Address; import org.jgroups.Global; import org.jgroups.PhysicalAddress; import org.jgroups.protocols.PingData; import org.jgroups.util.Bits; import org.jgroups.util.SizeStreamable; import org.jgroups.util.Util; import java.io.DataInput; import java.io.DataOutput; import java.util.ArrayList; import java.util.List; /** * Encapsulates data sent between GossipRouter and RouterStub (TCPGOSSIP and TUNNEL) * @author Bela Ban Oct 4 2001 */ public class GossipData implements SizeStreamable { GossipType type; String group; // REGISTER, GET_MBRS and GET_MBRS_RSP Address addr; // REGISTER Address sender; // MESSAGE (original sender of a message (not the GossipRouter!)) PhysicalAddress physical_addr; // REGISTER, GET_MBRS, GET_MBRS_RSP String logical_name; // REGISTER List<PingData> ping_data; // GET_MBRS_RSP byte[] buffer; // MESSAGE int offset; // MESSAGE int length; // MESSAGE public GossipData() { // for streamable } public GossipData(GossipType type) { this.type=type; } public GossipData(GossipType type, String group, Address addr) { this(type); this.group=group; this.addr=addr; } public GossipData(GossipType type, String group, Address addr, List<PingData> ping_data) { this(type, group, addr); this.ping_data=ping_data; } public GossipData(GossipType type, String group, Address addr, List<PingData> ping_data, PhysicalAddress physical_addr) { this(type, group, addr, ping_data); this.physical_addr=physical_addr; } public GossipData(GossipType type, String group, Address addr, String logical_name, PhysicalAddress physical_addr) { this(type, group, addr); this.logical_name=logical_name; this.physical_addr=physical_addr; } public GossipData(GossipType type, String group, Address addr, byte[] buffer) { this(type, group, addr, buffer, 0, buffer.length); } public GossipData(GossipType type, String group, Address addr, byte[] buffer, int offset, int length) { this(type, group, addr); this.buffer=buffer; this.offset=offset; this.length=length; } public GossipType getType() {return type;} public String getGroup() {return group;} public Address getAddress() {return addr;} public Address getSender() {return sender;} public GossipData setSender(Address s) {sender=s; return this;} public String getLogicalName() {return logical_name;} public List<PingData> getPingData() {return ping_data;} public byte[] getBuffer() {return buffer;} public int getOffset() {return offset;} public int getLength() {return length;} public PhysicalAddress getPhysicalAddress() {return physical_addr;} public void setPingData(List<PingData> mbrs) { this.ping_data=mbrs; } public void addPingData(PingData data) { if(ping_data == null) ping_data=new ArrayList<>(); if(data != null) ping_data.add(data); } public String toString() { StringBuilder sb=new StringBuilder(); sb.append(type).append( "(").append("group=").append(group).append(", addr=").append(addr); if(logical_name != null) sb.append(", logical_name=" + logical_name); if(ping_data != null && !ping_data.isEmpty()) sb.append(", ping_data=").append(ping_data); if(physical_addr != null) sb.append(", physical_addr=").append(physical_addr); if(buffer != null) sb.append(", buffer: " + length + " bytes"); sb.append(")"); return sb.toString(); } public int serializedSize() { int retval=Global.BYTE_SIZE; // type if(group != null) retval+=group.length() +2; // group retval+=Global.BYTE_SIZE; // presence for group retval+=Util.size(addr); // addr retval+=Util.size(sender); if(type != GossipType.MESSAGE) { retval+=Global.BYTE_SIZE; // presence byte for logical_name if(logical_name != null) retval+=logical_name.length() +2; retval+=Global.SHORT_SIZE; // ping_data if(ping_data != null) for(PingData data: ping_data) retval+=data.serializedSize(); retval+=Util.size(physical_addr); // physical_addr } retval+=Global.INT_SIZE; // length of buffer if(buffer != null) retval+=length; return retval; } public void writeTo(DataOutput out) throws Exception { out.writeByte(type.ordinal()); Bits.writeString(group, out); Util.writeAddress(addr, out); Util.writeAddress(sender, out); if(type != GossipType.MESSAGE) { Bits.writeString(logical_name, out); out.writeShort(ping_data != null? ping_data.size() : 0); if(ping_data != null) for(PingData data : ping_data) data.writeTo(out); Util.writeAddress(physical_addr, out); } out.writeInt(buffer != null? length : 0); if(buffer != null) out.write(buffer, offset, length); } public void readFrom(DataInput in) throws Exception { readFrom(in, true); } protected void readFrom(DataInput in, boolean read_type) throws Exception { if(read_type) type=GossipType.values()[in.readByte()]; group=Bits.readString(in); addr=Util.readAddress(in); sender=Util.readAddress(in); if(type != GossipType.MESSAGE) { logical_name=Bits.readString(in); short len=in.readShort(); if(len > 0) { ping_data=new ArrayList<>(len); for(int i=0; i < len; i++) { PingData data=new PingData(); data.readFrom(in); ping_data.add(data); } } physical_addr=(PhysicalAddress)Util.readAddress(in); } length=in.readInt(); if(length > 0) { buffer=new byte[length]; in.readFully(buffer, offset=0, length); } } }