1 4 package com.tc.net.protocol.delivery; 5 6 import com.tc.bytes.TCByteBuffer; 7 import com.tc.net.protocol.AbstractTCNetworkHeader; 8 import com.tc.net.protocol.TCProtocolException; 9 10 13 class OOOProtocolMessageHeader extends AbstractTCNetworkHeader { 14 15 private static final short TYPE_ACK_REQUEST = 1; 16 private static final short TYPE_ACK = 2; 17 private static final short TYPE_SEND = 3; 18 19 private static final short VERSION = 1; 20 21 private static final int MAGIC_NUM = 0xBBBBBBBB; 22 private static final int MAGIC_NUM_OFFSET = 0; 23 private static final int MAGIC_NUM_LENGTH = 4; 24 25 private static final int VERSION_OFFSET = MAGIC_NUM_OFFSET + MAGIC_NUM_LENGTH; 26 private static final int VERSION_LENGTH = 1; 27 28 private static final int TYPE_OFFSET = VERSION_OFFSET + VERSION_LENGTH; 29 private static final int TYPE_LENGTH = 1; 30 31 private static final int SEQUENCE_OFFSET = TYPE_OFFSET + TYPE_LENGTH; 32 private static final int SEQUENCE_LENGTH = 8; 33 34 static final int HEADER_LENGTH; 35 36 static { 37 int tmp = MAGIC_NUM_LENGTH + VERSION_LENGTH + TYPE_LENGTH + SEQUENCE_LENGTH; 38 HEADER_LENGTH = tmp + (tmp % 4); 40 } 41 42 private OOOProtocolMessageHeader(short version, short type, long sequence) { 43 super(HEADER_LENGTH, HEADER_LENGTH); 44 putValues(version, type, sequence); 45 try { 46 validate(); 47 } catch (TCProtocolException e) { 48 throw new InternalError (); 49 } 50 } 51 52 private OOOProtocolMessageHeader(TCByteBuffer buffer) { 53 super(buffer, HEADER_LENGTH, HEADER_LENGTH); 54 } 55 56 public int getHeaderByteLength() { 57 return HEADER_LENGTH; 58 } 59 60 private void putValues(short version, short type, long sequence) { 61 data.putInt(MAGIC_NUM_OFFSET, MAGIC_NUM); 62 data.putUbyte(VERSION_OFFSET, version); 63 data.putUbyte(TYPE_OFFSET, type); 64 data.putLong(SEQUENCE_OFFSET, sequence); 65 } 66 67 protected void setHeaderLength(short headerLength) { 68 throw new UnsupportedOperationException ("These messages are fixed length."); 69 } 70 71 public void validate() throws TCProtocolException { 72 int magic = getMagicNumber(); 73 if (magic != MAGIC_NUM) { 74 throw new TCProtocolException("Bad magic number: " + magic + " != " + MAGIC_NUM); 75 } 76 77 short version = getVersion(); 78 if (getVersion() != VERSION) { throw new TCProtocolException("Reported version " + version 79 + " is not equal to supported version: " + VERSION); } 80 short type = getType(); 81 if (!isValidType(type)) { throw new TCProtocolException("Unknown message type: " + type); } 82 83 final boolean ack = isAck(); 84 final boolean ackReq = isAckRequest(); 85 final boolean send = isSend(); 86 87 if (ack && (ackReq || send)) { throw new TCProtocolException("Invalid type, ack= " + ack + ", ackRe=" + ackReq 88 + ", send=" + send); } 89 } 90 91 public String toString() { 92 StringBuffer buf = new StringBuffer (); 93 94 buf.append("valid: "); 95 try { 96 validate(); 97 buf.append("true"); 98 } catch (TCProtocolException e) { 99 buf.append("false (").append(e.getMessage()).append(")"); 100 } 101 buf.append(", "); 102 103 buf.append("type: "); 104 if (isAck()) { 105 buf.append("ACK ").append(getSequence()); 106 } else if (isAckRequest()) { 107 buf.append("ACK REQ"); 108 } else if (isSend()) { 109 buf.append("SEND " + getSequence()); 110 } else { 111 buf.append("UNKNOWN"); 112 } 113 buf.append('\n'); 114 115 return buf.toString(); 116 } 117 118 private int getMagicNumber() { 119 return data.getInt(MAGIC_NUM_OFFSET); 120 } 121 122 private short getVersion() { 123 return data.getUbyte(VERSION_OFFSET); 124 } 125 126 private short getType() { 127 return data.getUbyte(TYPE_OFFSET); 128 } 129 130 private boolean isValidType(short type) { 131 return type == TYPE_SEND || type == TYPE_ACK_REQUEST || type == TYPE_ACK; 132 } 133 134 long getSequence() { 135 return data.getLong(SEQUENCE_OFFSET); 136 } 137 138 boolean isAckRequest() { 139 return getType() == TYPE_ACK_REQUEST; 140 } 141 142 boolean isAck() { 143 return getType() == TYPE_ACK; 144 } 145 146 boolean isSend() { 147 return getType() == TYPE_SEND; 148 } 149 150 static class ProtocolMessageHeaderFactory { 151 154 OOOProtocolMessageHeader createNewAckRequest() { 155 return new OOOProtocolMessageHeader(VERSION, TYPE_ACK_REQUEST, 0); 156 } 157 158 161 OOOProtocolMessageHeader createNewAck(long sequence) { 162 return new OOOProtocolMessageHeader(VERSION, TYPE_ACK, sequence); 163 } 164 165 168 OOOProtocolMessageHeader createNewSend(long sequence) { 169 return new OOOProtocolMessageHeader(VERSION, TYPE_SEND, sequence); 170 } 171 172 175 OOOProtocolMessageHeader createNewHeader(TCByteBuffer buffer) { 176 return new OOOProtocolMessageHeader(buffer.duplicate().limit(OOOProtocolMessageHeader.HEADER_LENGTH)); 177 } 178 } 179 } | Popular Tags |