Protocol.java
// Copyright (c) ZeroC, Inc.
package com.zeroc.Ice;
final class Protocol {
/**
* Converts a string to a protocol version.
*
* @param version The string to convert.
* @return The converted protocol version.
*/
static ProtocolVersion stringToProtocolVersion(String version) {
return new ProtocolVersion(stringToMajor(version), stringToMinor(version));
}
/**
* Converts a string to an encoding version.
*
* @param version The string to convert.
* @return The converted encoding version.
*/
static EncodingVersion stringToEncodingVersion(String version) {
return new EncodingVersion(stringToMajor(version), stringToMinor(version));
}
/**
* Converts a protocol version to a string.
*
* @param v The protocol version to convert.
* @return The converted string.
*/
static String protocolVersionToString(ProtocolVersion v) {
return majorMinorToString(v.major, v.minor);
}
/**
* Converts an encoding version to a string.
*
* @param v The encoding version to convert.
* @return The converted string.
*/
static String encodingVersionToString(EncodingVersion v) {
return majorMinorToString(v.major, v.minor);
}
//
// Size of the Ice protocol header
//
// Magic number (4 bytes)
// Protocol version major (Byte)
// Protocol version minor (Byte)
// Encoding version major (Byte)
// Encoding version minor (Byte)
// Message type (Byte)
// Compression status (Byte)
// Message size (Int)
//
public static final int headerSize = 14;
//
// The magic number at the front of each message
//
public static final byte[] magic = {0x49, 0x63, 0x65, 0x50}; // 'I', 'c', 'e', 'P'
//
// The current Ice protocol and Slice encoding version
//
public static final byte protocolMajor = 1;
public static final byte protocolMinor = 0;
public static final byte protocolEncodingMajor = 1;
public static final byte protocolEncodingMinor = 0;
//
// The Ice protocol message types
//
public static final byte requestMsg = 0;
public static final byte requestBatchMsg = 1;
public static final byte replyMsg = 2;
public static final byte validateConnectionMsg = 3;
public static final byte closeConnectionMsg = 4;
public static final byte[] requestHdr = {
Protocol.magic[0],
Protocol.magic[1],
Protocol.magic[2],
Protocol.magic[3],
Protocol.protocolMajor,
Protocol.protocolMinor,
Protocol.protocolEncodingMajor,
Protocol.protocolEncodingMinor,
Protocol.requestMsg,
(byte) 0, // Compression status.
(byte) 0,
(byte) 0,
(byte) 0,
(byte) 0, // Message size (placeholder).
(byte) 0,
(byte) 0,
(byte) 0,
(byte) 0 // Request ID (placeholder).
};
public static final byte[] requestBatchHdr = {
Protocol.magic[0],
Protocol.magic[1],
Protocol.magic[2],
Protocol.magic[3],
Protocol.protocolMajor,
Protocol.protocolMinor,
Protocol.protocolEncodingMajor,
Protocol.protocolEncodingMinor,
Protocol.requestBatchMsg,
0, // Compression status.
(byte) 0,
(byte) 0,
(byte) 0,
(byte) 0, // Message size (placeholder).
(byte) 0,
(byte) 0,
(byte) 0,
(byte) 0 // Number of requests in batch (placeholder).
};
public static final byte[] replyHdr = {
Protocol.magic[0],
Protocol.magic[1],
Protocol.magic[2],
Protocol.magic[3],
Protocol.protocolMajor,
Protocol.protocolMinor,
Protocol.protocolEncodingMajor,
Protocol.protocolEncodingMinor,
Protocol.replyMsg,
(byte) 0, // Compression status.
(byte) 0,
(byte) 0,
(byte) 0,
(byte) 0 // Message size (placeholder).
};
/** The protocol version 1.0. */
public static final ProtocolVersion Protocol_1_0 = new ProtocolVersion(protocolMajor, protocolMinor);
public static final ProtocolVersion currentProtocol = new ProtocolVersion(protocolMajor, protocolMinor);
public static final EncodingVersion currentProtocolEncoding =
new EncodingVersion(protocolEncodingMajor, protocolEncodingMinor);
public static void checkSupportedProtocol(ProtocolVersion v) {
if (!v.equals(currentProtocol)) {
throw new FeatureNotSupportedException(
"Cannot send request using protocol version " + v.major + "." + v.minor);
}
}
public static void checkSupportedProtocolEncoding(EncodingVersion v) {
if (!v.equals(currentProtocolEncoding)) {
throw new MarshalException("This Ice runtime does not support encoding version " + v.major + "." + v.minor);
}
}
public static void checkSupportedEncoding(EncodingVersion v) {
if (v.major != Util.Encoding_1_1.major || v.minor > Util.Encoding_1_1.minor) {
throw new MarshalException("This Ice runtime does not support encoding version " + v.major + "." + v.minor);
}
}
public static boolean isSupported(EncodingVersion version, EncodingVersion supported) {
return version.major == supported.major && version.minor <= supported.minor;
}
public static final int OPTIONAL_END_MARKER = 0xFF;
public static final byte FLAG_HAS_TYPE_ID_STRING = (byte) (1 << 0);
public static final byte FLAG_HAS_TYPE_ID_INDEX = (byte) (1 << 1);
public static final byte FLAG_HAS_TYPE_ID_COMPACT = (byte) (1 << 1 | 1 << 0);
public static final byte FLAG_HAS_OPTIONAL_MEMBERS = (byte) (1 << 2);
public static final byte FLAG_HAS_INDIRECTION_TABLE = (byte) (1 << 3);
public static final byte FLAG_HAS_SLICE_SIZE = (byte) (1 << 4);
public static final byte FLAG_IS_LAST_SLICE = (byte) (1 << 5);
private static byte stringToMajor(String str) {
int pos = str.indexOf('.');
if (pos == -1) {
throw new ParseException("malformed version value in '" + str + "'");
}
String majStr = str.substring(0, pos);
int majVersion;
try {
majVersion = Integer.parseInt(majStr);
} catch (NumberFormatException ex) {
throw new ParseException("invalid version value in '" + str + "'", ex);
}
if (majVersion < 1 || majVersion > 255) {
throw new ParseException("range error in version '" + str + "'");
}
return (byte) majVersion;
}
private static byte stringToMinor(String str) {
int pos = str.indexOf('.');
if (pos == -1) {
throw new ParseException("malformed version value in '" + str + "'");
}
String minStr = str.substring(pos + 1, str.length());
int minVersion;
try {
minVersion = Integer.parseInt(minStr);
} catch (NumberFormatException ex) {
throw new ParseException("invalid version value in '" + str + "'", ex);
}
if (minVersion < 0 || minVersion > 255) {
throw new ParseException("range error in version '" + str + "'");
}
return (byte) minVersion;
}
private static String majorMinorToString(byte major, byte minor) {
StringBuilder str = new StringBuilder();
str.append(major < 0 ? major + 255 : (int) major);
str.append(".");
str.append(minor < 0 ? minor + 255 : (int) minor);
return str.toString();
}
private Protocol() {}
}