Class RpcPacket


  • public class RpcPacket
    extends java.lang.Object
    Describes the format of, and implements a bunch of methods for, Perforce RPC packets as pushed across the wire between Perforce clients and servers.

    Each RPC packet consists of the following elements (as cribbed from the C++ API code and byte-level TCP/IP packet analysis done on p4 server network traffic):

    • a preamble that specifies the length of the rest of the packet (the payload) plus a simple sanity check checksum; the format and semantics of the preamble are given in the class RpcPacketPreamble below.
    • an optional argument argument or results element containing zero or more packet fields (described in the RpcPacketField class Javadoc) used to provide arguments for server-side functions or to provide results from the server. These fields can be interpreted as either text fields or byte fields, according to the RPC function and context.
    • an optional client environment specifier that spells out client state, etc.; this is only sent by a client, and only with the initial user command.
    • a function field, specifying the function this packet is requesting. Functions in this usage can be user functions (initial requests that the Perforce server do something for the end user, e.g. "info"), or client functions (something the Perforce server is asking the client to do, e.g. "client message", a request to send the associated text to the end user), or one of an obscure menagerie of other functions spelled out elsewhere.
    All elements except the preamble are actually serialized arrays of text or byte fields in the format described in the RpcPacketField class. This makes the overall format fairly uniform and relatively straightforward to pick off the wire in most cases.

    Note that the order of individual fields within the overall scheme is theoretically unimportant (with the obvious exception of the preamble, which has to be first), but there may be unknown server dependencies on element order, so we try to closely follow the C++ API's ordering in our implementation.

    Note that RPC packets are not in any way synonymous with TCP packets or any underlying transport layer packet mechanism -- text packets can span TCP packets or several RPC packets can be packed into a single TCP packet, for example.

    • Field Detail

      • DEFAULT_RPC_PACKET_BUFFER_SIZE

        public static final int DEFAULT_RPC_PACKET_BUFFER_SIZE
        See Also:
        Constant Field Values
      • RPC_LENGTH_FIELD_LENGTH

        public static final int RPC_LENGTH_FIELD_LENGTH
        Length in bytes of the RPC packet length fields. This is a very fundamental constant; changing this will probably cause catastrophic P4Java misbehavior.
        See Also:
        Constant Field Values
    • Method Detail

      • encodeInt4

        public static byte[] encodeInt4​(int i)
        Return a four byte array ready for sending across the wire that represents in Perforce standard wire form the integer passed in.

        Used extensively in the Perforce RPC protocol to encode ints before sending them across the wire.

        Parameters:
        i - i
        Returns:
        bytes
      • decodeInt4

        public static int decodeInt4​(byte[] bytes)
        Decode a Java int from the passed-in 4 byte Perforce encoded integer value.

        Used extensively in the Perforce RPC protocol to decode ints coming in off the wire. Note that we have to go to some length to convince Java that we want unsigned byte (it's amazing that Java still doesn't have unsigned integral types...); this helps explain the seemingly-redundant "& 0xFF"'s in the code below.

        Parameters:
        bytes - bytes
        Returns:
        decoded
      • constructRpcPacket

        public static RpcPacket constructRpcPacket​(RpcFunctionSpec funcName,
                                                   java.lang.String realName,
                                                   java.lang.String[] args,
                                                   ExternalEnv env)
        Construct an RPC packet for a user command.
        Parameters:
        funcName - non-null function name
        realName - realName
        args - potentially-null function arguments as a string array
        env - potentially-null command environment
        Returns:
        non-null text packet ready for marshaling (or whatever)
      • constructRpcPacket

        public static RpcPacket constructRpcPacket​(RpcFunctionSpec funcName,
                                                   java.util.Map<java.lang.String,​java.lang.Object> args,
                                                   ExternalEnv env)
        Construct an RPC packet for a user command.
        Parameters:
        funcName - non-null function name
        args - potentially-null function arguments in map form
        env - potentially-null command environment
        Returns:
        non-null text packet ready for marshaling (or whatever)
      • constructRpcPacket

        public static RpcPacket constructRpcPacket​(java.lang.String funcName,
                                                   java.util.Map<java.lang.String,​java.lang.Object> args,
                                                   ExternalEnv env)
        Construct an RPC packet for a user command.
        Parameters:
        funcName - non-null function name
        args - potentially-null function arguments in map form
        env - potentially-null command environment
        Returns:
        non-null text packet ready for marshaling (or whatever)
      • constructRpcPacket

        public static RpcPacket constructRpcPacket​(RpcPacketPreamble preamble,
                                                   byte[] bytes,
                                                   boolean isUnicodeServer,
                                                   java.nio.charset.Charset charset)
        Construct an RPC packet from the passed-in preamble, bytes, and charset.
        Parameters:
        preamble - preamble
        bytes - bytes
        isUnicodeServer - isUnicodeServer
        charset - charset
        Returns:
        RpcPacket
      • constructRpcPacket

        public static RpcPacket constructRpcPacket​(RpcPacketPreamble preamble,
                                                   byte[] bytes,
                                                   boolean isUnicodeServer,
                                                   java.nio.charset.Charset charset,
                                                   RpcPacketFieldRule fieldRule,
                                                   IFilterCallback filterCallback)
        Construct an RPC packet from the passed-in preamble, bytes, charset and fieldRule.
        Parameters:
        preamble - preamble
        bytes - bytes
        isUnicodeServer - isUnicodeServer
        charset - charset
        fieldRule - fieldRule
        filterCallback - filterCallback
        Returns:
        RpcPacket
      • getResultsMap

        public java.util.Map<java.lang.String,​java.lang.Object> getResultsMap()
      • setResultsMap

        public void setResultsMap​(java.util.Map<java.lang.String,​java.lang.Object> resultsMap)
      • getFuncNameString

        public java.lang.String getFuncNameString()
      • setFuncNameString

        public void setFuncNameString​(java.lang.String funcNameString)
      • getPacketLength

        public int getPacketLength()
      • setPacketLength

        public void setPacketLength​(int packetLength)
      • getStrArgs

        public java.lang.String[] getStrArgs()
      • setStrArgs

        public void setStrArgs​(java.lang.String[] strArgs)
      • getMapArgs

        public java.util.Map<java.lang.String,​java.lang.Object> getMapArgs()
      • setMapArgs

        public void setMapArgs​(java.util.Map<java.lang.String,​java.lang.Object> mapArgs)